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 <stdio.h> 33 #include <sys/dkio.h> 34 #include <unistd.h> 35 #include <errno.h> 36 #include <libintl.h> 37 #include <sys/time.h> 38 39 #include "mmc.h" 40 #include "util.h" 41 #include "misc_scsi.h" 42 #include "transport.h" 43 #include "main.h" 44 #include "toshiba.h" 45 #include "msgs.h" 46 47 uint32_t 48 read_scsi32(void *addr) 49 { 50 uchar_t *ad = (uchar_t *)addr; 51 uint32_t ret; 52 53 ret = ((((uint32_t)ad[0]) << 24) | (((uint32_t)ad[1]) << 16) | 54 (((uint32_t)ad[2]) << 8) | ad[3]); 55 return (ret); 56 } 57 58 uint16_t 59 read_scsi16(void *addr) 60 { 61 uchar_t *ad = (uchar_t *)addr; 62 uint16_t ret; 63 64 ret = ((((uint16_t)ad[0]) << 8) | ad[1]); 65 return (ret); 66 } 67 68 void 69 load_scsi32(void *addr, uint32_t v) 70 { 71 uchar_t *ad = (uchar_t *)addr; 72 73 ad[0] = (uchar_t)(v >> 24); 74 ad[1] = (uchar_t)(v >> 16); 75 ad[2] = (uchar_t)(v >> 8); 76 ad[3] = (uchar_t)v; 77 } 78 79 void 80 load_scsi16(void *addr, uint16_t v) 81 { 82 uchar_t *ad = (uchar_t *)addr; 83 ad[0] = (uchar_t)(v >> 8); 84 ad[1] = (uchar_t)v; 85 } 86 /* 87 * will get the mode page only i.e. will strip off the header. 88 */ 89 int 90 get_mode_page(int fd, int page_no, int pc, int buf_len, uchar_t *buffer) 91 { 92 int ret; 93 uchar_t byte2, *buf; 94 uint_t header_len, page_len, copy_cnt; 95 96 byte2 = (uchar_t)(((pc << 6) & 0xC0) | (page_no & 0x3f)); 97 buf = (uchar_t *)my_zalloc(256); 98 99 /* Ask 254 bytes only to make our IDE driver happy */ 100 ret = mode_sense(fd, byte2, 1, 254, buf); 101 if (ret == 0) { 102 free(buf); 103 return (0); 104 } 105 106 header_len = 8 + read_scsi16(&buf[6]); 107 page_len = buf[header_len + 1] + 2; 108 109 copy_cnt = (page_len > buf_len) ? buf_len : page_len; 110 (void) memcpy(buffer, &buf[header_len], copy_cnt); 111 free(buf); 112 113 return (1); 114 } 115 116 /* 117 * will take care of adding mode header and any extra bytes at the end. 118 */ 119 int 120 set_mode_page(int fd, uchar_t *buffer) 121 { 122 int ret; 123 uchar_t *buf; 124 uint_t total, p_len; 125 126 p_len = buffer[1] + 2; 127 total = p_len + 8; 128 buf = (uchar_t *)my_zalloc(total); 129 130 (void) memcpy(&buf[8], buffer, p_len); 131 if (debug) { 132 int i; 133 134 (void) printf("MODE: ["); 135 for (i = 0; i < p_len; i++) { 136 (void) printf("0x%02x ", (uchar_t)buffer[i]); 137 } 138 139 (void) printf("]\n"); 140 } 141 ret = mode_select(fd, total, buf); 142 free(buf); 143 144 return (ret); 145 } 146 147 /* 148 * Builds track information database for track trackno. If trackno is 149 * -1, builds the database for next blank track. 150 */ 151 int 152 build_track_info(cd_device *dev, int trackno, struct track_info *t_info) 153 { 154 uchar_t *ti; 155 uchar_t toc[20]; /* 2 entries + 4 byte header */ 156 int ret; 157 158 (void) memset(t_info, 0, sizeof (*t_info)); 159 /* 1st try READ TRACK INFORMATION */ 160 ti = (uchar_t *)my_zalloc(TRACK_INFO_SIZE); 161 t_info->ti_track_no = trackno; 162 163 /* Gererate faked information for writing to DVD */ 164 if (device_type != CD_RW) { 165 uint_t bsize; 166 167 t_info->ti_flags = 0x3000; 168 t_info->ti_track_no = 1; 169 t_info->ti_session_no = 1; 170 t_info->ti_track_mode = 0x4; 171 t_info->ti_data_mode = 1; 172 t_info->ti_start_address = 0; 173 174 /* only 1 track on DVD make it max size */ 175 t_info->ti_track_size = read_format_capacity(target->d_fd, 176 &bsize); 177 if (t_info->ti_track_size < MAX_CD_BLKS) { 178 t_info->ti_track_size = MAX_DVD_BLKS; 179 } 180 181 t_info->ti_nwa = 0; 182 t_info->ti_lra = 0; 183 t_info->ti_packet_size = 0x10; 184 t_info->ti_free_blocks = 0; 185 } 186 187 if (read_track_info(dev->d_fd, trackno, ti)) { 188 189 if (debug) 190 (void) printf("using read_track_info for TOC \n"); 191 192 t_info->ti_track_no = ti[2]; 193 t_info->ti_session_no = ti[3]; 194 t_info->ti_flags = (ti[6] >> 4) & 0xf; 195 t_info->ti_flags |= (uint32_t)(ti[5] & 0xf0); 196 t_info->ti_flags |= (uint32_t)(ti[7]) << 8; 197 t_info->ti_flags |= TI_SESSION_NO_VALID | TI_FREE_BLOCKS_VALID; 198 t_info->ti_track_mode = ti[5] & 0xf; 199 if ((ti[6] & 0xf) == 0xf) 200 t_info->ti_data_mode = 0xff; 201 else 202 t_info->ti_data_mode = ti[6] & 0xf; 203 t_info->ti_start_address = read_scsi32(&ti[8]); 204 t_info->ti_nwa = read_scsi32(&ti[12]); 205 t_info->ti_free_blocks = read_scsi32(&ti[16]); 206 t_info->ti_packet_size = read_scsi32(&ti[20]); 207 t_info->ti_track_size = read_scsi32(&ti[24]); 208 t_info->ti_lra = read_scsi32(&ti[28]); 209 free(ti); 210 return (1); 211 } 212 /* READ TRACK INFORMATION not supported, try other options */ 213 free(ti); 214 /* 215 * We can get info for next blank track if READ TRACK INFO is not 216 * supported. 217 */ 218 if (trackno == -1) 219 return (0); 220 221 if (debug) 222 (void) printf("using READ_TOC for TOC\n"); 223 224 /* Try Read TOC */ 225 if (!read_toc(dev->d_fd, 0, trackno, 20, toc)) { 226 return (0); 227 } 228 t_info->ti_start_address = read_scsi32(&toc[8]); 229 t_info->ti_track_mode = toc[5] & 0xf; 230 t_info->ti_track_size = read_scsi32(&toc[16]) - read_scsi32(&toc[8]); 231 t_info->ti_data_mode = get_data_mode(dev->d_fd, read_scsi32(&toc[8])); 232 233 /* Numbers for audio tracks are always in 2K chunks */ 234 if ((dev->d_blksize == 512) && ((t_info->ti_track_mode & 4) == 0)) { 235 t_info->ti_start_address /= 4; 236 t_info->ti_track_size /= 4; 237 } 238 239 /* Now find out the session thing */ 240 ret = read_toc(dev->d_fd, 1, trackno, 12, toc); 241 242 /* 243 * Make sure that the call succeeds and returns the requested 244 * TOC size correctly. 245 */ 246 247 if ((ret == 0) || (toc[1] != 0x0a)) { 248 249 /* For ATAPI drives or old Toshiba drives */ 250 ret = read_toc_as_per_8020(dev->d_fd, 1, trackno, 12, toc); 251 } 252 /* If this goes through well TOC length will always be 0x0a */ 253 if (ret && (toc[1] == 0x0a)) { 254 if (trackno >= toc[6]) { 255 t_info->ti_session_no = toc[3]; 256 t_info->ti_flags |= TI_SESSION_NO_VALID; 257 } 258 /* 259 * This might be the last track of this session. If so, 260 * exclude the leadout and next lead in. 261 */ 262 if (trackno == (toc[6] - 1)) { 263 /* 264 * 1.5 Min leadout + 1 min. leadin + 2 sec. pre-gap. 265 * For 2nd+ leadout it will be 0.5 min. But currently 266 * there is no direct way. And it will not happen 267 * for any normal case. 268 * 269 * 75 frames/sec, 60 sec/min, so leadin gap is 270 * ((1.5 +1)*60 + 2)*75 = 11400 frames (blocks) 271 */ 272 t_info->ti_track_size -= 11400; 273 } 274 } 275 return (1); 276 } 277 278 uchar_t 279 get_data_mode(int fd, uint32_t lba) 280 { 281 int ret; 282 uchar_t *buf; 283 uchar_t mode; 284 285 buf = (uchar_t *)my_zalloc(8); 286 ret = read_header(fd, lba, buf); 287 if (ret == 0) 288 mode = 0xff; 289 else 290 mode = buf[0]; 291 free(buf); 292 return (mode); 293 } 294 295 /* 296 * Set page code 5 for TAO mode. 297 */ 298 int 299 prepare_for_write(cd_device *dev, int track_mode, int test_write, 300 int keep_disc_open) 301 { 302 uchar_t *buf; 303 int no_err; 304 int reset_device; 305 306 if ((write_mode == DAO_MODE) && keep_disc_open) { 307 (void) printf(gettext( 308 "Multi-session is not supported on DVD media\n")); 309 exit(1); 310 } 311 312 if ((write_mode == DAO_MODE) && debug) { 313 (void) printf("Preparing to write in DAO\n"); 314 } 315 316 (void) start_stop(dev->d_fd, 1); 317 /* Some drives do not support this command but still do it */ 318 (void) rezero_unit(dev->d_fd); 319 320 buf = (uchar_t *)my_zalloc(64); 321 322 no_err = get_mode_page(dev->d_fd, 5, 0, 64, buf); 323 if (no_err) 324 no_err = ((buf[1] + 2) > 64) ? 0 : 1; 325 /* 326 * If the device is already in simulation mode and again a 327 * simulation is requested, then set the device in non-simulation 328 * 1st and then take it to simulation mode. This will flush any 329 * previous fake state in the drive. 330 */ 331 if (no_err && test_write && (buf[2] & 0x10)) { 332 reset_device = 1; 333 } else { 334 reset_device = 0; 335 } 336 if (no_err != 0) { 337 buf[0] &= 0x3f; 338 339 /* set TAO or DAO writing mode */ 340 buf[2] = (write_mode == TAO_MODE)?1:2; 341 342 /* set simulation flag */ 343 if (test_write && (!reset_device)) { 344 buf[2] |= 0x10; 345 } else { 346 buf[2] &= ~0x10; 347 } 348 349 /* Turn on HW buffer underrun protection (BUFE) */ 350 if (!test_write) { 351 buf[2] |= 0x40; 352 } 353 354 /* set track mode type */ 355 if (device_type == CD_RW) { 356 buf[3] = track_mode & 0x0f; /* ctrl nibble */ 357 } else { 358 buf[3] = 5; /* always 5 for DVD */ 359 } 360 361 if (keep_disc_open) { 362 buf[3] |= 0xc0; /* Allow more sessions */ 363 } 364 365 /* Select track type (audio or data) */ 366 if (track_mode == TRACK_MODE_DATA) { 367 buf[4] = 8; /* 2048 byte sector */ 368 } else { 369 buf[4] = 0; /* 2352 byte sector */ 370 } 371 buf[7] = buf[8] = 0; 372 373 /* Need to clear these fields for setting into DAO */ 374 if (write_mode == DAO_MODE) 375 buf[5] = buf[15] = 0; 376 377 /* print out mode for detailed log */ 378 if (debug && verbose) { 379 int i; 380 381 (void) printf("setting = [ "); 382 for (i = 0; i < 15; i++) 383 (void) printf("0x%x ", buf[i]); 384 (void) printf("]\n"); 385 } 386 387 no_err = set_mode_page(dev->d_fd, buf); 388 389 if (no_err && reset_device) { 390 /* Turn the test write bit back on */ 391 buf[2] |= 0x10; 392 no_err = set_mode_page(dev->d_fd, buf); 393 } 394 395 /* 396 * Since BUFE is the only optional flag we are 397 * setting we will try to turn it off if the command 398 * fails. 399 */ 400 if (!no_err) { 401 /* 402 * Some old drives may not support HW 403 * buffer underrun protection, try again 404 * after turning it off. 405 */ 406 if (debug) 407 (void) printf("Turning off BUFE\n"); 408 buf[2] &= ~0x40; 409 no_err = set_mode_page(dev->d_fd, buf); 410 } 411 } 412 413 free(buf); 414 return (no_err); 415 } 416 417 /* 418 * Close session. This will write TOC. 419 */ 420 int 421 finalize(cd_device *dev) 422 { 423 uchar_t *di; 424 int count, ret, err; 425 int immediate; 426 int finalize_max; 427 428 /* 429 * For ATAPI devices we will use the immediate mode and will 430 * poll the command for completion so that this command may 431 * not hog the channel. But for SCSI, we will use the treditional 432 * way of issuing the command with a large enough timeout. This 433 * is done because immediate mode was designed for ATAPI and some 434 * SCSI RW drives might not be even tested with it. 435 */ 436 if ((dev->d_inq[2] & 7) != 0) { 437 /* SCSI device */ 438 immediate = 0; 439 } else { 440 /* non-SCSI (e.g ATAPI) device */ 441 immediate = 1; 442 } 443 444 /* We need to close track before close session */ 445 if (device_type == DVD_PLUS) { 446 if (!close_track(dev->d_fd, 0, 0, immediate)) 447 return (0); 448 } 449 450 if (!close_track(dev->d_fd, 0, 1, immediate)) { 451 /* 452 * For DVD-RW close track is not well defined 453 * some drives dont like it, others want us 454 * to close track before closing the session. 455 * NOTE that for MMC specification it is not mandatory 456 * to support close track. 457 */ 458 if (device_type == DVD_MINUS) { 459 if (!close_track(dev->d_fd, 1, 0, immediate)) { 460 return (0); 461 } else { 462 /* command is already done */ 463 if (!immediate) 464 return (1); 465 } 466 } else { 467 return (0); 468 } 469 } else { 470 if (!immediate) 471 return (1); 472 } 473 if (immediate) { 474 (void) sleep(10); 475 476 di = (uchar_t *)my_zalloc(DISC_INFO_BLOCK_SIZE); 477 err = 0; 478 479 if (device_type == CD_RW) { 480 /* Finalization should not take more than 6 minutes */ 481 finalize_max = FINALIZE_TIMEOUT; 482 } else { 483 /* some DVD-RW drives take longer than 6 minutes */ 484 finalize_max = FINALIZE_TIMEOUT*2; 485 } 486 487 for (count = 0; count < finalize_max; count++) { 488 ret = read_disc_info(dev->d_fd, di); 489 if (ret != 0) 490 break; 491 if (uscsi_status != 2) 492 err = 1; 493 if (SENSE_KEY(rqbuf) == 2) { 494 /* not ready but not becoming ready */ 495 if (ASC(rqbuf) != 4) 496 err = 1; 497 } else if (SENSE_KEY(rqbuf) == 5) { 498 /* illegal mode for this track */ 499 if (ASC(rqbuf) != 0x64) 500 err = 1; 501 } else { 502 err = 1; 503 } 504 if (err == 1) { 505 if (debug) { 506 (void) printf("Finalization failed\n"); 507 (void) printf("%x %x %x %x\n", 508 uscsi_status, SENSE_KEY(rqbuf), 509 ASC(rqbuf), ASCQ(rqbuf)); 510 } 511 free(di); 512 return (0); 513 } 514 if (uscsi_status == 2) { 515 int i; 516 /* illegal field in command packet */ 517 if (ASC(rqbuf) == 0x24) { 518 /* print it out! */ 519 (void) printf("\n"); 520 for (i = 0; i < 18; i++) 521 (void) printf("%x ", 522 (unsigned)(rqbuf[i])); 523 (void) printf("\n"); 524 } 525 } 526 (void) sleep(5); 527 } 528 free(di); 529 } 530 return (ret); 531 } 532 533 /* 534 * Find out media capacity. 535 */ 536 int 537 get_last_possible_lba(cd_device *dev) 538 { 539 uchar_t *di; 540 int cap; 541 542 di = (uchar_t *)my_zalloc(DISC_INFO_BLOCK_SIZE); 543 if (!read_disc_info(dev->d_fd, di)) { 544 free(di); 545 return (0); 546 } 547 if ((di[21] != 0) && (di[21] != 0xff)) { 548 cap = ((di[21] * 60) + di[22]) * 75; 549 } else { 550 cap = 0; 551 } 552 553 free(di); 554 return (cap); 555 } 556 557 int 558 read_audio_through_read_cd(cd_device *dev, uint_t start_lba, uint_t nblks, 559 uchar_t *buf) 560 { 561 int retry; 562 int ret; 563 564 for (retry = 0; retry < 3; retry++) { 565 ret = read_cd(dev->d_fd, (uint32_t)start_lba, (uint16_t)nblks, 566 1, buf, (uint32_t)(nblks * 2352)); 567 if (ret) 568 break; 569 } 570 return (ret); 571 } 572 573 int 574 eject_media(cd_device *dev) 575 { 576 if (vol_running) { 577 /* If there is a media, try using DKIOCEJECT 1st */ 578 if (check_device(dev, CHECK_NO_MEDIA) == 0) { 579 if (ioctl(dev->d_fd, DKIOCEJECT, 0) == 0) { 580 return (1); 581 } 582 } 583 } 584 if (load_unload(dev->d_fd, 0) == 0) { 585 /* if eject fails */ 586 if ((uscsi_status == 2) && (ASC(rqbuf) == 0x53)) { 587 /* 588 * check that eject is not blocked on the device 589 */ 590 if (!prevent_allow_mr(dev->d_fd, 1)) 591 return (0); 592 return (load_unload(dev->d_fd, 0)); 593 } 594 return (0); 595 } 596 return (1); 597 } 598 599 /* 600 * Get CD speed from Page code 2A. since GET PERFORMANCE is not supported 601 * (which is already checked before) this mode page *will* have the speed. 602 */ 603 static uint16_t 604 i_cd_speed_read(cd_device *dev, int cmd) 605 { 606 uchar_t *mp2a; 607 uint16_t rate; 608 609 mp2a = (uchar_t *)my_zalloc(PAGE_CODE_2A_SIZE); 610 if (get_mode_page(dev->d_fd, 0x2A, 0, PAGE_CODE_2A_SIZE, 611 mp2a) == 0) { 612 rate = 0; 613 } else { 614 if (cmd == GET_READ_SPEED) { 615 rate = ((uint16_t)mp2a[14] << 8) | mp2a[15]; 616 } else { 617 rate = ((uint16_t)mp2a[20] << 8) | mp2a[21]; 618 } 619 } 620 free(mp2a); 621 return (rate); 622 } 623 624 /* 625 * CD speed related functions (ioctl style) for drives which do not support 626 * real time streaming. 627 */ 628 int 629 cd_speed_ctrl(cd_device *dev, int cmd, int speed) 630 { 631 uint16_t rate; 632 633 if ((cmd == GET_READ_SPEED) || (cmd == GET_WRITE_SPEED)) 634 return (XFER_RATE_TO_SPEED(i_cd_speed_read(dev, cmd))); 635 if (cmd == SET_READ_SPEED) { 636 rate = i_cd_speed_read(dev, GET_WRITE_SPEED); 637 return (set_cd_speed(dev->d_fd, SPEED_TO_XFER_RATE(speed), 638 rate)); 639 } 640 if (cmd == SET_WRITE_SPEED) { 641 rate = i_cd_speed_read(dev, GET_READ_SPEED); 642 return (set_cd_speed(dev->d_fd, rate, 643 SPEED_TO_XFER_RATE(speed))); 644 } 645 return (0); 646 } 647 648 /* 649 * cd speed related functions for drives which support RT-streaming 650 */ 651 int 652 rt_streaming_ctrl(cd_device *dev, int cmd, int speed) 653 { 654 uchar_t *perf, *str; 655 int write_perf; 656 int ret; 657 uint16_t perf_got; 658 659 write_perf = 0; 660 if ((cmd == GET_WRITE_SPEED) || (cmd == SET_READ_SPEED)) 661 write_perf = 1; 662 perf = (uchar_t *)my_zalloc(GET_PERF_DATA_LEN); 663 if (!get_performance(dev->d_fd, write_perf, perf)) { 664 ret = 0; 665 goto end_rsc; 666 } 667 perf_got = (uint16_t)read_scsi32(&perf[20]); 668 if ((cmd == GET_READ_SPEED) || (cmd == GET_WRITE_SPEED)) { 669 ret = XFER_RATE_TO_SPEED(perf_got); 670 goto end_rsc; 671 } 672 str = (uchar_t *)my_zalloc(SET_STREAM_DATA_LEN); 673 (void) memcpy(&str[8], &perf[16], 4); 674 load_scsi32(&str[16], 1000); 675 load_scsi32(&str[24], 1000); 676 if (cmd == SET_WRITE_SPEED) { 677 load_scsi32(&str[12], (uint32_t)perf_got); 678 load_scsi32(&str[20], (uint32_t)SPEED_TO_XFER_RATE(speed)); 679 } else { 680 load_scsi32(&str[20], (uint32_t)perf_got); 681 load_scsi32(&str[12], (uint32_t)SPEED_TO_XFER_RATE(speed)); 682 } 683 ret = set_streaming(dev->d_fd, str); 684 free(str); 685 686 /* If rt_speed_ctrl fails for any reason use cd_speed_ctrl */ 687 if (ret == 0) { 688 if (debug) 689 (void) printf(" real time speed control" 690 " failed, using CD speed control\n"); 691 692 dev->d_speed_ctrl = cd_speed_ctrl; 693 ret = dev->d_speed_ctrl(dev, cmd, speed); 694 } 695 696 end_rsc: 697 free(perf); 698 return (ret); 699 } 700 701 /* 702 * Initialize device for track-at-once mode of writing. All of the data will 703 * need to be written to the track without interruption. 704 * This initialized TAO by setting page code 5 and speed. 705 */ 706 void 707 write_init(int mode) 708 { 709 (void) printf(gettext("Initializing device")); 710 if (simulation) 711 (void) printf(gettext("(Simulation mode)")); 712 print_n_flush("..."); 713 714 get_media_type(target->d_fd); 715 716 /* DVD- requires DAO mode */ 717 if (device_type == DVD_MINUS) { 718 write_mode = DAO_MODE; 719 } 720 721 /* For debug, print out device config information */ 722 if (debug) { 723 int i; 724 uchar_t cap[80]; 725 726 if (get_configuration(target->d_fd, 0, 80, cap)) 727 (void) printf("Drive profile = "); 728 for (i = 10; i < 70; i += 8) 729 (void) printf(" 0x%x", cap[i]); 730 (void) printf("\n"); 731 } 732 733 /* DVD+ and DVD- have no support for AUDIO, bail out */ 734 if ((mode == TRACK_MODE_AUDIO) && (device_type != CD_RW)) { 735 err_msg(gettext("Audio mode is only supported for CD media\n")); 736 exit(1); 737 } 738 739 if (!prepare_for_write(target, mode, simulation, keep_disc_open)) { 740 /* l10n_NOTE : 'failed' as in Initializing device...failed */ 741 (void) printf(gettext("failed.\n")); 742 err_msg(gettext("Cannot initialize device for write\n")); 743 exit(1); 744 } 745 /* l10n_NOTE : 'done' as in "Initializing device...done" */ 746 (void) printf(gettext("done.\n")); 747 748 /* if speed change option was used (-p) then try to set the speed */ 749 if (requested_speed != 0) { 750 if (verbose) 751 (void) printf(gettext("Trying to set speed to %dX.\n"), 752 requested_speed); 753 if (target->d_speed_ctrl(target, SET_WRITE_SPEED, 754 requested_speed) == 0) { 755 err_msg(gettext("Unable to set speed.\n")); 756 exit(1); 757 } 758 if (verbose) { 759 int speed; 760 speed = target->d_speed_ctrl(target, 761 GET_WRITE_SPEED, 0); 762 if (speed == requested_speed) { 763 (void) printf(gettext("Speed set to %dX.\n"), 764 speed); 765 } else { 766 (void) printf( 767 gettext("Speed set to closest approximation " 768 "of %dX allowed by device (%dX).\n"), 769 requested_speed, speed); 770 } 771 } 772 } 773 } 774 775 void 776 write_fini(void) 777 { 778 print_n_flush(gettext("Finalizing (Can take several minutes)...")); 779 /* Some drives don't like this while in test write mode */ 780 if (!simulation) { 781 if (!finalize(target)) { 782 /* 783 * It is possible that the drive is busy writing the 784 * buffered portion. So do not get upset yet. 785 */ 786 (void) sleep(10); 787 if (!finalize(target)) { 788 if (debug) { 789 (void) printf("status %x, %x/%x/%x\n", 790 uscsi_status, SENSE_KEY(rqbuf), 791 ASC(rqbuf), ASCQ(rqbuf)); 792 } 793 794 if ((device_type == DVD_MINUS) && 795 (SENSE_KEY(rqbuf) == 5)) { 796 797 if (verbose) { 798 (void) printf( 799 "skipping finalizing\n"); 800 } 801 } else { 802 803 /* l10n_NOTE : 'failed' as in finishing up...failed */ 804 (void) printf(gettext("failed.\n")); 805 806 err_msg(gettext( 807 "Could not finalize the disc.\n")); 808 exit(1); 809 } 810 811 812 } 813 } 814 if (vol_running) { 815 (void) eject_media(target); 816 } 817 } else if (check_device(target, CHECK_MEDIA_IS_NOT_BLANK)) { 818 /* 819 * Some drives such as the pioneer A04 will retain a 820 * ghost TOC after a simulation write is done. The 821 * media will actually be blank, but the drive will 822 * report a TOC. There is currently no other way to 823 * re-initialize the media other than ejecting or 824 * to ask the drive to clear the leadout. The laser 825 * is currently off so nothing is written to the 826 * media (on a good behaving drive). 827 * NOTE that a device reset does not work to make 828 * the drive re-initialize the media. 829 */ 830 831 if (!vol_running) { 832 blanking_type = "clear"; 833 blank(); 834 } 835 836 } 837 /* l10n_NOTE : 'done' as in "Finishing up...done" */ 838 (void) printf(gettext("done.\n")); 839 } 840