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 <string.h> 32 #include <libintl.h> 33 #include <unistd.h> 34 35 #include "msgs.h" 36 #include "mmc.h" 37 #include "util.h" 38 #include "transport.h" 39 #include "main.h" 40 #include "misc_scsi.h" 41 42 /* 43 * This is called recursively once, if an ALL blank succeeds but the 44 * media is not blank we call blank() again to perform a fast blank. 45 * This is a workaround for some drives such as older Toshiba DVD-RW 46 * which has this problem with ALL blanking. 47 */ 48 void 49 blank(void) 50 { 51 int type, invalid; 52 int count, ret; 53 uchar_t *di, *buf; 54 int immediate, err; 55 int silent_pass = 0; 56 invalid = 0; 57 err = 0; 58 59 (void) check_device(target, CHECK_TYPE_NOT_CDROM | CHECK_NO_MEDIA | 60 EXIT_IF_CHECK_FAILED); 61 (void) check_device(target, CHECK_DEVICE_NOT_READY | 62 CHECK_DEVICE_NOT_WRITABLE | EXIT_IF_CHECK_FAILED); 63 64 if (blanking_type == NULL) { 65 invalid = 1; 66 } 67 68 get_media_type(target->d_fd); 69 70 /* 71 * many DVD+RW drives do not allow blanking the media, it is also 72 * not included in the spec, we would just reformat the media prior 73 * to writing. This is not the equivelent to blanking as the media 74 * contains a TOC when formatted. 75 */ 76 if (device_type == DVD_PLUS_W) { 77 err_msg(gettext("Blanking cannot be done on DVD+RW media\n")); 78 exit(1); 79 } 80 81 if (strcmp(blanking_type, "all") == 0) { 82 /* erase the whole disk */ 83 type = ALL; 84 } else if (strcmp(blanking_type, "session") == 0) { 85 /* only erase the last session */ 86 type = SESSION; 87 } else if (strcmp(blanking_type, "fast") == 0) { 88 /* quick blank the TOC on the media */ 89 type = FAST; 90 } else if (strcmp(blanking_type, "leadout") == 0) { 91 /* erase the track tail to unclose the media */ 92 type = LEADOUT; 93 silent_pass = 1; 94 } else if (strcmp(blanking_type, "clear") == 0) { 95 /* 96 * used for drives where "all" blanking fails, 97 * if it fails we follow up with a quick erase of TOC. 98 * This is only called from within this function to do 99 * a second blanking pass. 100 */ 101 type = CLEAR; 102 silent_pass = 1; 103 } else { 104 /* invalid blank type was passed on the command line */ 105 invalid = 1; 106 } 107 108 if (invalid) { 109 err_msg(gettext("Invalid blanking type specified\n")); 110 exit(1); 111 } 112 if ((target->d_inq[2] & 7) != 0) { 113 /* SCSI device */ 114 immediate = 0; 115 } else { 116 /* non-SCSI (e.g ATAPI) device */ 117 immediate = 1; 118 } 119 120 /* we are doing a second pass. We don't want to re-print messsages */ 121 if (!silent_pass) 122 print_n_flush(gettext("Initializing device...")); 123 124 /* Make sure that test write is off */ 125 buf = (uchar_t *)my_zalloc(64); 126 127 /* get mode page for test writing if it fails we cannot turn it off */ 128 if (!get_mode_page(target->d_fd, 5, 0, 64, buf)) { 129 err_msg(gettext("Device not supported\n")); 130 exit(1); 131 } 132 133 buf[2] &= 0xef; 134 135 /* turn laser on */ 136 if (!set_mode_page(target->d_fd, buf)) { 137 err_msg(gettext("Unable to configure device\n")); 138 exit(1); 139 } 140 free(buf); 141 142 /* we are doing a second pass. We don't want to re-print messsages */ 143 if (!silent_pass) { 144 /* l10n_NOTE : 'done' as in "Initializing device...done" */ 145 (void) printf(gettext("done.\n")); 146 147 print_n_flush(gettext( 148 "Blanking the media (Can take several minutes)...")); 149 } 150 if (!blank_disc(target->d_fd, type, immediate)) { 151 err_msg(gettext("Blank command failed\n")); 152 if (debug) 153 (void) printf("%x %x %x %x\n", uscsi_status, 154 SENSE_KEY(rqbuf), ASC(rqbuf), ASCQ(rqbuf)); 155 goto blank_failed; 156 } 157 /* Allow the blanking to start */ 158 (void) sleep(10); 159 160 /* 161 * set ATAPI devices to immediately return from the command and poll 162 * so that we don't hog the channel. 163 */ 164 165 if (immediate) { 166 di = (uchar_t *)my_zalloc(DISC_INFO_BLOCK_SIZE); 167 /* Blanking should not take more than 75 minutes */ 168 for (count = 0; count < (16*60); count++) { 169 ret = read_disc_info(target->d_fd, di); 170 if (ret != 0) 171 break; 172 if (uscsi_status != 2) 173 err = 1; 174 /* not ready but not becoming ready */ 175 if (SENSE_KEY(rqbuf) == 2) { 176 if (ASC(rqbuf) != 4) 177 err = 1; 178 /* illegal mode for this track */ 179 } else if (SENSE_KEY(rqbuf) == 5) { 180 if (ASC(rqbuf) != 0x64) 181 err = 1; 182 } else { 183 err = 1; 184 } 185 if (err == 1) { 186 err_msg(gettext("Blanking operation failed\n")); 187 if (debug) { 188 (void) printf("%x %x %x %x\n", 189 uscsi_status, SENSE_KEY(rqbuf), 190 ASC(rqbuf), ASCQ(rqbuf)); 191 } 192 free(di); 193 goto blank_failed; 194 } 195 (void) sleep(5); 196 } 197 free(di); 198 if (count == (16*60)) { 199 (void) printf(gettext("Blank command timed out.\n")); 200 goto blank_failed; 201 } 202 } 203 /* we are doing a second pass. We don't want to re-print messsages */ 204 if (!silent_pass) { 205 /* l10n_NOTE : 'done' as in "Erasing track 1...done" */ 206 (void) printf(gettext("done.\n")); 207 } 208 209 /* 210 * some cruft left from all blanking, this has been seen on some 211 * newer drives including Toshiba SD-6112 DVD-RW and Sony 510A. 212 * we will do a second pass with a recursive call to blank the 213 * lead-in. 214 */ 215 if (type == ALL) { 216 if ((check_device(target, CHECK_MEDIA_IS_NOT_BLANK)) && 217 (!vol_running)) { 218 blanking_type = "clear"; 219 blank(); 220 exit(0); 221 } 222 } 223 224 /* 225 * We erased part of the leadout for the media to unclose 226 * the disk, we still need to generate an appendable leadout 227 * so that the next track can be written. so do not eject or exit. 228 */ 229 if (silent_pass) 230 return; 231 232 if (vol_running) 233 (void) eject_media(target); 234 exit(0); 235 blank_failed: 236 if ((type != ALL) && !silent_pass) { 237 (void) printf("Try using blanking type 'all'\n"); 238 } 239 if (vol_running) 240 (void) eject_media(target); 241 exit(1); 242 } 243