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 2007 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 <string.h> 31 #include <stdio.h> 32 #include <sys/dkio.h> 33 #include <unistd.h> 34 #include <errno.h> 35 #include <libintl.h> 36 #include <sys/time.h> 37 38 #include "mmc.h" 39 #include "util.h" 40 #include "misc_scsi.h" 41 #include "transport.h" 42 #include "main.h" 43 #include "toshiba.h" 44 #include "msgs.h" 45 #include "device.h" 46 47 static int check_track_size(cd_device *dev, int trk_num, 48 struct track_info *tip); 49 static int rtoc_get_trk_sess_num(uchar_t *rtoc, size_t rtoc_len, int trk_num, 50 int *sess_nump); 51 static int rtoc_get_sess_last_trk_num(uchar_t *rtoc, size_t rtoc_len, 52 int sess_num, int *last_trk_nump); 53 static int rtoc_get_sess_leadout_lba(uchar_t *rtoc, size_t rtoc_len, 54 int sess_num, uint32_t *leadout_lba); 55 static rtoc_td_t *get_rtoc_td(rtoc_td_t *begin_tdp, rtoc_td_t *end_tdp, 56 uchar_t adr, uchar_t point); 57 58 uint32_t 59 read_scsi32(void *addr) 60 { 61 uchar_t *ad = (uchar_t *)addr; 62 uint32_t ret; 63 64 ret = ((((uint32_t)ad[0]) << 24) | (((uint32_t)ad[1]) << 16) | 65 (((uint32_t)ad[2]) << 8) | ad[3]); 66 return (ret); 67 } 68 69 uint16_t 70 read_scsi16(void *addr) 71 { 72 uchar_t *ad = (uchar_t *)addr; 73 uint16_t ret; 74 75 ret = ((((uint16_t)ad[0]) << 8) | ad[1]); 76 return (ret); 77 } 78 79 void 80 load_scsi32(void *addr, uint32_t v) 81 { 82 uchar_t *ad = (uchar_t *)addr; 83 84 ad[0] = (uchar_t)(v >> 24); 85 ad[1] = (uchar_t)(v >> 16); 86 ad[2] = (uchar_t)(v >> 8); 87 ad[3] = (uchar_t)v; 88 } 89 90 void 91 load_scsi16(void *addr, uint16_t v) 92 { 93 uchar_t *ad = (uchar_t *)addr; 94 ad[0] = (uchar_t)(v >> 8); 95 ad[1] = (uchar_t)v; 96 } 97 /* 98 * will get the mode page only i.e. will strip off the header. 99 */ 100 int 101 get_mode_page(int fd, int page_no, int pc, int buf_len, uchar_t *buffer) 102 { 103 int ret; 104 uchar_t byte2, *buf; 105 uint_t header_len, page_len, copy_cnt; 106 107 byte2 = (uchar_t)(((pc << 6) & 0xC0) | (page_no & 0x3f)); 108 buf = (uchar_t *)my_zalloc(256); 109 110 /* Ask 254 bytes only to make our IDE driver happy */ 111 ret = mode_sense(fd, byte2, 1, 254, buf); 112 if (ret == 0) { 113 free(buf); 114 return (0); 115 } 116 117 header_len = 8 + read_scsi16(&buf[6]); 118 page_len = buf[header_len + 1] + 2; 119 120 copy_cnt = (page_len > buf_len) ? buf_len : page_len; 121 (void) memcpy(buffer, &buf[header_len], copy_cnt); 122 free(buf); 123 124 return (1); 125 } 126 127 /* 128 * will take care of adding mode header and any extra bytes at the end. 129 */ 130 int 131 set_mode_page(int fd, uchar_t *buffer) 132 { 133 int ret; 134 uchar_t *buf; 135 uint_t total, p_len; 136 137 p_len = buffer[1] + 2; 138 total = p_len + 8; 139 buf = (uchar_t *)my_zalloc(total); 140 141 (void) memcpy(&buf[8], buffer, p_len); 142 if (debug) { 143 int i; 144 145 (void) printf("MODE: ["); 146 for (i = 0; i < p_len; i++) { 147 (void) printf("0x%02x ", (uchar_t)buffer[i]); 148 } 149 150 (void) printf("]\n"); 151 } 152 ret = mode_select(fd, total, buf); 153 free(buf); 154 155 return (ret); 156 } 157 158 /* 159 * Builds track information database for track trackno. If trackno is 160 * -1, builds the database for next blank track. 161 */ 162 int 163 build_track_info(cd_device *dev, int trackno, struct track_info *t_info) 164 { 165 uchar_t *ti; 166 uchar_t toc[20]; /* 2 entries + 4 byte header */ 167 int ret; 168 169 (void) memset(t_info, 0, sizeof (*t_info)); 170 /* 1st try READ TRACK INFORMATION */ 171 ti = (uchar_t *)my_zalloc(TRACK_INFO_SIZE); 172 t_info->ti_track_no = trackno; 173 174 /* Gererate faked information for writing to DVD */ 175 if (device_type != CD_RW) { 176 uint_t bsize; 177 178 t_info->ti_flags = 0x3000; 179 t_info->ti_track_no = 1; 180 t_info->ti_session_no = 1; 181 t_info->ti_track_mode = 0x4; 182 t_info->ti_data_mode = 1; 183 t_info->ti_start_address = 0; 184 185 /* only 1 track on DVD make it max size */ 186 t_info->ti_track_size = read_format_capacity(target->d_fd, 187 &bsize); 188 if (t_info->ti_track_size < MAX_CD_BLKS) { 189 t_info->ti_track_size = MAX_DVD_BLKS; 190 } 191 192 t_info->ti_nwa = 0; 193 t_info->ti_lra = 0; 194 t_info->ti_packet_size = 0x10; 195 t_info->ti_free_blocks = 0; 196 } 197 198 if (read_track_info(dev->d_fd, trackno, ti)) { 199 200 if (debug) 201 (void) printf("using read_track_info for TOC \n"); 202 203 t_info->ti_track_no = ti[2]; 204 t_info->ti_session_no = ti[3]; 205 t_info->ti_flags = (ti[6] >> 4) & 0xf; 206 t_info->ti_flags |= (uint32_t)(ti[5] & 0xf0); 207 t_info->ti_flags |= (uint32_t)(ti[7]) << 8; 208 t_info->ti_flags |= TI_SESSION_NO_VALID | TI_FREE_BLOCKS_VALID; 209 t_info->ti_track_mode = ti[5] & 0xf; 210 if ((ti[6] & 0xf) == 0xf) 211 t_info->ti_data_mode = 0xff; 212 else 213 t_info->ti_data_mode = ti[6] & 0xf; 214 t_info->ti_start_address = read_scsi32(&ti[8]); 215 t_info->ti_nwa = read_scsi32(&ti[12]); 216 t_info->ti_free_blocks = read_scsi32(&ti[16]); 217 t_info->ti_packet_size = read_scsi32(&ti[20]); 218 t_info->ti_track_size = read_scsi32(&ti[24]); 219 t_info->ti_lra = read_scsi32(&ti[28]); 220 free(ti); 221 return (1); 222 } 223 /* READ TRACK INFORMATION not supported, try other options */ 224 free(ti); 225 /* 226 * We can get info for next blank track if READ TRACK INFO is not 227 * supported. 228 */ 229 if (trackno == -1) 230 return (0); 231 232 if (debug) 233 (void) printf("using READ_TOC for TOC\n"); 234 235 /* Try Read TOC */ 236 if (!read_toc(dev->d_fd, 0, trackno, 20, toc)) { 237 return (0); 238 } 239 t_info->ti_start_address = read_scsi32(&toc[8]); 240 t_info->ti_track_mode = toc[5] & 0xf; 241 t_info->ti_track_size = read_scsi32(&toc[16]) - read_scsi32(&toc[8]); 242 t_info->ti_data_mode = get_data_mode(dev->d_fd, read_scsi32(&toc[8])); 243 244 /* Numbers for audio tracks are always in 2K chunks */ 245 if ((dev->d_blksize == 512) && ((t_info->ti_track_mode & 4) == 0)) { 246 t_info->ti_start_address /= 4; 247 t_info->ti_track_size /= 4; 248 } 249 250 /* Now find out the session thing */ 251 ret = read_toc(dev->d_fd, 1, trackno, 12, toc); 252 253 /* 254 * Make sure that the call succeeds and returns the requested 255 * TOC size correctly. 256 */ 257 258 if ((ret == 0) || (toc[1] != 0x0a)) { 259 260 /* For ATAPI drives or old Toshiba drives */ 261 ret = read_toc_as_per_8020(dev->d_fd, 1, trackno, 12, toc); 262 } 263 /* If this goes through well TOC length will always be 0x0a */ 264 if (ret && (toc[1] == 0x0a)) { 265 if (trackno >= toc[6]) { 266 t_info->ti_session_no = toc[3]; 267 t_info->ti_flags |= TI_SESSION_NO_VALID; 268 } 269 /* 270 * This might be the last track of this session. If so, 271 * exclude the leadout and next lead in. 272 */ 273 if (trackno == (toc[6] - 1)) { 274 /* 275 * 1.5 Min leadout + 1 min. leadin + 2 sec. pre-gap. 276 * For 2nd+ leadout it will be 0.5 min. But currently 277 * there is no direct way. And it will not happen 278 * for any normal case. 279 * 280 * 75 frames/sec, 60 sec/min, so leadin gap is 281 * ((1.5 +1)*60 + 2)*75 = 11400 frames (blocks) 282 */ 283 t_info->ti_track_size -= 11400; 284 } 285 } else { 286 if (check_track_size(dev, trackno, t_info) != 1) 287 return (0); 288 } 289 290 return (1); 291 } 292 293 /* 294 * The size of the last track in one of the first N - 1 sessions of an 295 * N-session (N > 1) disc is reported incorrectly by some drives and calculated 296 * incorrectly for others, because a pre-gap/lead-out/lead-in section that ends 297 * a session is erroneously considered part of that track. This function checks 298 * for this corner case, and adjusts the track size if necessary. 299 */ 300 static int 301 check_track_size(cd_device *dev, int trk_num, struct track_info *tip) 302 { 303 size_t raw_toc_len; 304 uchar_t *raw_toc; 305 rtoc_hdr_t hdr; 306 uint32_t sess_leadout_lba; 307 int sess_last_trk_num; 308 int trk_sess_num; 309 uint32_t trk_size; 310 311 /* Request Raw TOC Header for session count. */ 312 if (read_toc(dev->d_fd, FORMAT_RAW_TOC, 1, 313 sizeof (rtoc_hdr_t), (uchar_t *)&hdr) != 1) 314 return (0); 315 316 /* Is this a multi-session medium? */ 317 if (hdr.rh_last_sess_num > hdr.rh_first_sess_num) { 318 /* Yes; request entire Raw TOC. */ 319 raw_toc_len = read_scsi16(&hdr.rh_data_len1) + RTOC_DATA_LEN_SZ; 320 raw_toc = (uchar_t *)my_zalloc(raw_toc_len); 321 322 if (read_toc(dev->d_fd, FORMAT_RAW_TOC, 1, raw_toc_len, raw_toc) 323 != 1) 324 goto fail; 325 326 if (rtoc_get_trk_sess_num(raw_toc, raw_toc_len, trk_num, 327 &trk_sess_num) != 1) 328 goto fail; 329 330 tip->ti_session_no = trk_sess_num; 331 tip->ti_flags |= TI_SESSION_NO_VALID; 332 333 /* Is the track in one of the first N - 1 sessions? */ 334 if (trk_sess_num < hdr.rh_last_sess_num) { 335 if (rtoc_get_sess_last_trk_num(raw_toc, raw_toc_len, 336 trk_sess_num, &sess_last_trk_num) != 1) 337 goto fail; 338 339 /* Is the track the last track in the session? */ 340 if (trk_num == sess_last_trk_num) { 341 if (rtoc_get_sess_leadout_lba(raw_toc, 342 raw_toc_len, trk_sess_num, 343 &sess_leadout_lba) != 1) 344 goto fail; 345 346 trk_size = sess_leadout_lba - 347 tip->ti_start_address; 348 349 /* Fix track size if it was too big. */ 350 if (tip->ti_track_size > trk_size) 351 tip->ti_track_size = trk_size; 352 } 353 } 354 free(raw_toc); 355 } 356 return (1); 357 358 fail: 359 free(raw_toc); 360 return (0); 361 } 362 363 /* 364 * Determine what session number a track is in by parsing the Raw TOC format of 365 * the the READ TOC/PMA/ATIP command response data. 366 */ 367 static int 368 rtoc_get_trk_sess_num(uchar_t *rtoc, size_t rtoc_len, int trk_num, 369 int *sess_nump) 370 { 371 rtoc_td_t *tdp = (rtoc_td_t *)(rtoc + sizeof (rtoc_hdr_t)); 372 rtoc_td_t *last_tdp = (rtoc_td_t *)(rtoc + rtoc_len - 373 sizeof (rtoc_td_t)); 374 375 if ((tdp = get_rtoc_td(tdp, last_tdp, Q_MODE_1, (uchar_t)trk_num)) != 376 NULL) { 377 *sess_nump = tdp->rt_session_num; 378 return (1); 379 } else 380 return (0); 381 } 382 383 /* 384 * Determine the last track number in a specified session number by parsing the 385 * Raw TOC format of the READ TOC/PMA/ATIP command response data. 386 */ 387 static int 388 rtoc_get_sess_last_trk_num(uchar_t *rtoc, size_t rtoc_len, int sess_num, 389 int *last_trk_nump) 390 { 391 rtoc_td_t *tdp = (rtoc_td_t *)(rtoc + sizeof (rtoc_hdr_t)); 392 rtoc_td_t *last_tdp = (rtoc_td_t *)(rtoc + rtoc_len - 393 sizeof (rtoc_td_t)); 394 395 while ((tdp = get_rtoc_td(tdp, last_tdp, Q_MODE_1, 396 POINT_SESS_LAST_TRK)) != NULL) { 397 if (tdp->rt_session_num == sess_num) { 398 *last_trk_nump = tdp->rt_pmin; 399 return (1); 400 } else { 401 ++tdp; 402 } 403 } 404 405 return (0); 406 } 407 408 /* 409 * Determine the starting LBA of the the session leadout by parsing the Raw TOC 410 * format of the READ TOC/PMA/ATIP command response data. 411 */ 412 static int 413 rtoc_get_sess_leadout_lba(uchar_t *rtoc, size_t rtoc_len, int sess_num, 414 uint32_t *leadout_lba) 415 { 416 rtoc_td_t *tdp = (rtoc_td_t *)(rtoc + sizeof (rtoc_hdr_t)); 417 rtoc_td_t *last_tdp = (rtoc_td_t *)(rtoc + rtoc_len - 418 sizeof (rtoc_td_t)); 419 420 while ((tdp = get_rtoc_td(tdp, last_tdp, Q_MODE_1, 421 POINT_LEADOUT_ADDR)) != NULL) { 422 if (tdp->rt_session_num == sess_num) { 423 *leadout_lba = MSF2LBA(tdp->rt_pmin, tdp->rt_psec, 424 tdp->rt_pframe); 425 return (1); 426 } else { 427 ++tdp; 428 } 429 } 430 431 return (0); 432 } 433 434 /* 435 * Search a set of Raw TOC Track Descriptors using <'adr', 'point'> as the 436 * search key. Return a pointer to the first Track Descriptor that matches. 437 */ 438 static rtoc_td_t * 439 get_rtoc_td(rtoc_td_t *begin_tdp, rtoc_td_t *end_tdp, uchar_t adr, 440 uchar_t point) 441 { 442 rtoc_td_t *cur_tdp = begin_tdp; 443 444 while (cur_tdp <= end_tdp) { 445 if ((cur_tdp->rt_adr == adr) && (cur_tdp->rt_point == point)) 446 return (cur_tdp); 447 else 448 cur_tdp++; 449 } 450 451 return (NULL); 452 } 453 454 uchar_t 455 get_data_mode(int fd, uint32_t lba) 456 { 457 int ret; 458 uchar_t *buf; 459 uchar_t mode; 460 461 buf = (uchar_t *)my_zalloc(8); 462 ret = read_header(fd, lba, buf); 463 if (ret == 0) 464 mode = 0xff; 465 else 466 mode = buf[0]; 467 free(buf); 468 return (mode); 469 } 470 471 /* 472 * Set page code 5 for TAO mode. 473 */ 474 int 475 prepare_for_write(cd_device *dev, int track_mode, int test_write, 476 int keep_disc_open) 477 { 478 uchar_t *buf; 479 int no_err; 480 int reset_device; 481 482 if ((write_mode == DAO_MODE) && keep_disc_open) { 483 (void) printf(gettext( 484 "Multi-session is not supported on DVD media\n")); 485 exit(1); 486 } 487 488 if ((write_mode == DAO_MODE) && debug) { 489 (void) printf("Preparing to write in DAO\n"); 490 } 491 492 (void) start_stop(dev->d_fd, 1); 493 /* Some drives do not support this command but still do it */ 494 (void) rezero_unit(dev->d_fd); 495 496 buf = (uchar_t *)my_zalloc(64); 497 498 no_err = get_mode_page(dev->d_fd, 5, 0, 64, buf); 499 if (no_err) 500 no_err = ((buf[1] + 2) > 64) ? 0 : 1; 501 /* 502 * If the device is already in simulation mode and again a 503 * simulation is requested, then set the device in non-simulation 504 * 1st and then take it to simulation mode. This will flush any 505 * previous fake state in the drive. 506 */ 507 if (no_err && test_write && (buf[2] & 0x10)) { 508 reset_device = 1; 509 } else { 510 reset_device = 0; 511 } 512 if (no_err != 0) { 513 buf[0] &= 0x3f; 514 515 /* set TAO or DAO writing mode */ 516 buf[2] = (write_mode == TAO_MODE)?1:2; 517 518 /* set simulation flag */ 519 if (test_write && (!reset_device)) { 520 buf[2] |= 0x10; 521 } else { 522 buf[2] &= ~0x10; 523 } 524 525 /* Turn on HW buffer underrun protection (BUFE) */ 526 if (!test_write) { 527 buf[2] |= 0x40; 528 } 529 530 /* set track mode type */ 531 if (device_type == CD_RW) { 532 buf[3] = track_mode & 0x0f; /* ctrl nibble */ 533 } 534 535 if (keep_disc_open) { 536 buf[3] |= 0xc0; /* Allow more sessions */ 537 } 538 539 /* Select track type (audio or data) */ 540 if (track_mode == TRACK_MODE_DATA) { 541 buf[4] = 8; /* 2048 byte sector */ 542 } else { 543 buf[4] = 0; /* 2352 byte sector */ 544 } 545 buf[7] = buf[8] = 0; 546 547 /* Need to clear these fields for setting into DAO */ 548 if (write_mode == DAO_MODE) 549 buf[5] = buf[15] = 0; 550 551 /* print out mode for detailed log */ 552 if (debug && verbose) { 553 int i; 554 555 (void) printf("setting = [ "); 556 for (i = 0; i < 15; i++) 557 (void) printf("0x%x ", buf[i]); 558 (void) printf("]\n"); 559 } 560 561 no_err = set_mode_page(dev->d_fd, buf); 562 563 if (no_err && reset_device) { 564 /* Turn the test write bit back on */ 565 buf[2] |= 0x10; 566 no_err = set_mode_page(dev->d_fd, buf); 567 } 568 569 /* 570 * Since BUFE is the only optional flag we are 571 * setting we will try to turn it off if the command 572 * fails. 573 */ 574 if (!no_err) { 575 /* 576 * Some old drives may not support HW 577 * buffer underrun protection, try again 578 * after turning it off. 579 */ 580 if (debug) 581 (void) printf("Turning off BUFE\n"); 582 buf[2] &= ~0x40; 583 no_err = set_mode_page(dev->d_fd, buf); 584 } 585 } 586 587 free(buf); 588 return (no_err); 589 } 590 591 /* 592 * Close session. This will write TOC. 593 */ 594 int 595 finalize(cd_device *dev) 596 { 597 uchar_t *di; 598 int count, ret, err; 599 int immediate; 600 int finalize_max; 601 602 /* 603 * For ATAPI devices we will use the immediate mode and will 604 * poll the command for completion so that this command may 605 * not hog the channel. But for SCSI, we will use the treditional 606 * way of issuing the command with a large enough timeout. This 607 * is done because immediate mode was designed for ATAPI and some 608 * SCSI RW drives might not be even tested with it. 609 */ 610 if ((dev->d_inq[2] & 7) != 0) { 611 /* SCSI device */ 612 immediate = 0; 613 } else { 614 /* non-SCSI (e.g ATAPI) device */ 615 immediate = 1; 616 } 617 618 /* We need to close track before close session */ 619 if (device_type == DVD_PLUS) { 620 if (!close_track(dev->d_fd, 0, 0, immediate)) 621 return (0); 622 } 623 624 if (!close_track(dev->d_fd, 0, 1, immediate)) { 625 /* 626 * For DAO mode which we use for DVD-RW, the latest MMC 627 * specification does not mention close_track. Some 628 * newer drives will return an ILLEGAL INSTRUCTION 629 * which we will ignore. We have also found a Panasonic 630 * drive which will return a MEDIA ERROR. It is safe 631 * to ignore both errors as this is not needed for 632 * these drives. 633 * This is kept for older drives which had needed 634 * us to issue close_track to flush the cache fully. 635 * once we are certain these drives have cleared the 636 * market, this can be removed. 637 */ 638 if (device_type == DVD_MINUS) { 639 return (0); 640 } 641 } else { 642 if (!immediate) 643 return (1); 644 } 645 if (immediate) { 646 (void) sleep(10); 647 648 di = (uchar_t *)my_zalloc(DISC_INFO_BLOCK_SIZE); 649 err = 0; 650 651 if (device_type == CD_RW) { 652 /* Finalization should not take more than 6 minutes */ 653 finalize_max = FINALIZE_TIMEOUT; 654 } else { 655 /* some DVD-RW drives take longer than 6 minutes */ 656 finalize_max = FINALIZE_TIMEOUT*2; 657 } 658 659 for (count = 0; count < finalize_max; count++) { 660 ret = read_disc_info(dev->d_fd, di); 661 if (ret != 0) 662 break; 663 if (uscsi_status != 2) 664 err = 1; 665 if (SENSE_KEY(rqbuf) == 2) { 666 /* not ready but not becoming ready */ 667 if (ASC(rqbuf) != 4) 668 err = 1; 669 } else if (SENSE_KEY(rqbuf) == 5) { 670 /* illegal mode for this track */ 671 if (ASC(rqbuf) != 0x64) 672 err = 1; 673 } else { 674 err = 1; 675 } 676 if (err == 1) { 677 if (debug) { 678 (void) printf("Finalization failed\n"); 679 (void) printf("%x %x %x %x\n", 680 uscsi_status, SENSE_KEY(rqbuf), 681 ASC(rqbuf), ASCQ(rqbuf)); 682 } 683 free(di); 684 return (0); 685 } 686 if (uscsi_status == 2) { 687 int i; 688 /* illegal field in command packet */ 689 if (ASC(rqbuf) == 0x24) { 690 /* print it out! */ 691 (void) printf("\n"); 692 for (i = 0; i < 18; i++) 693 (void) printf("%x ", 694 (unsigned)(rqbuf[i])); 695 (void) printf("\n"); 696 } 697 } 698 (void) sleep(5); 699 } 700 free(di); 701 } 702 return (ret); 703 } 704 705 /* 706 * Find out media capacity. 707 */ 708 uint32_t 709 get_last_possible_lba(cd_device *dev) 710 { 711 uchar_t *di; 712 uint32_t cap; 713 714 di = (uchar_t *)my_zalloc(DISC_INFO_BLOCK_SIZE); 715 if (!read_disc_info(dev->d_fd, di)) { 716 free(di); 717 return (0); 718 } 719 720 /* 721 * If we have a DVD+R this field is an LBA. If the media is 722 * a CD-R/W the field is MSF formatted. Otherwise this field 723 * is not valid and will be zero. 724 */ 725 if (device_type == DVD_PLUS) { 726 if (read_scsi32(&di[20]) != 0xffffffff) { 727 cap = read_scsi32(&di[20]); 728 } else { 729 cap = 0; 730 } 731 } else { 732 if ((di[21] != 0) && (di[21] != 0xff)) { 733 cap = MSF2LBA(di[21], di[22], di[23]); 734 } else { 735 cap = 0; 736 } 737 } 738 739 free(di); 740 return (cap); 741 } 742 743 int 744 read_audio_through_read_cd(cd_device *dev, uint_t start_lba, uint_t nblks, 745 uchar_t *buf) 746 { 747 int retry; 748 int ret; 749 750 for (retry = 0; retry < 3; retry++) { 751 ret = read_cd(dev->d_fd, (uint32_t)start_lba, (uint16_t)nblks, 752 1, buf, (uint32_t)(nblks * 2352)); 753 if (ret) 754 break; 755 } 756 return (ret); 757 } 758 759 int 760 eject_media(cd_device *dev) 761 { 762 if (vol_running) { 763 /* If there is a media, try using DKIOCEJECT 1st */ 764 if (check_device(dev, CHECK_NO_MEDIA) == 0) { 765 /* 766 * The check_device() call will issue 767 * a TEST UNIT READY (TUR) and retry many 768 * times when a DVD-R is present. The DKIOCEJECT 769 * ioctl will subsequently fail causing us to 770 * issue the LOAD/UNLOAD SCSI command to the device 771 * with out ejecting the media. Insted of letting 772 * this happen, issue a reset to the device before 773 * issuing the DKIOCEJCET ioctl. 774 */ 775 if (device_type == DVD_MINUS) 776 reset_dev(dev->d_fd); 777 778 if (ioctl(dev->d_fd, DKIOCEJECT, 0) == 0) { 779 return (1); 780 } 781 } 782 } 783 if (load_unload(dev->d_fd, 0) == 0) { 784 /* if eject fails */ 785 if ((uscsi_status == 2) && (ASC(rqbuf) == 0x53)) { 786 /* 787 * check that eject is not blocked on the device 788 */ 789 if (!prevent_allow_mr(dev->d_fd, 1)) 790 return (0); 791 return (load_unload(dev->d_fd, 0)); 792 } 793 return (0); 794 } 795 return (1); 796 } 797 798 /* 799 * Get current Read or Write Speed from Mode Page 0x2a. 800 * 801 * Use the size of the Page to determine which Multimedia Command 802 * set (MMC) is present. Based on the MMC version, get the 803 * specified Read/Write Speed. 804 * 805 * Note that some MMC versions do not necessarily support a 806 * (current) Read or Write Speed. As a result, this function 807 * _can_ return a value of zero. 808 * 809 * The newer standards (reserve and) mark the field(s) as Obsolete, 810 * yet many vendors populate the Obsolete fields with valid values 811 * (assumedly for backward compatibility). This is important, as 812 * a command like GET PERFORMANCE cannot return _the_ speed; it can 813 * only return a Logical-Block-Address-dependent (LBA) speed. Such 814 * values can vary widely between the innermost and outermost Track. 815 * Mode Page 0x2a is the best solution identifying "the current 816 * (nominal) speed". 817 */ 818 static uint16_t 819 cd_speed_get(cd_device *dev, int cmd) 820 { 821 uchar_t *mp2a; 822 uint16_t rate = 0; 823 int offset; 824 uint_t buflen = 254; 825 826 /* 827 * Allocate a buffer acceptably larger than any nominal 828 * Page for Page Code 0x2A. 829 */ 830 mp2a = (uchar_t *)my_zalloc(buflen); 831 if (get_mode_page(dev->d_fd, 0x2A, 0, buflen, mp2a) == 0) 832 goto end; 833 834 /* Determine MMC version based on 'Page Length' field */ 835 switch (mp2a[1]) { 836 case 0x14: /* MMC-1 */ 837 if (debug) 838 (void) printf("Mode Page 2A: MMC-1\n"); 839 840 offset = (cmd == GET_READ_SPEED) ? 14 : 20; 841 rate = read_scsi16(&mp2a[offset]); 842 break; 843 844 845 case 0x18: /* MMC-2 */ 846 if (debug) 847 (void) printf("Mode Page 2A: MMC-2;" 848 " Read and Write Speeds are " 849 "obsolete\n"); 850 851 /* see if "Obsolete" values are valid: */ 852 offset = (cmd == GET_READ_SPEED) ? 14 : 20; 853 rate = read_scsi16(&mp2a[offset]); 854 break; 855 856 default: /* MMC-3 or newer */ 857 if (debug) 858 (void) printf("Mode Page 2A: MMC-3 or" 859 " newer; Read Speed is obsolete.\n"); 860 861 if (cmd == GET_READ_SPEED) { 862 /* this is Obsolete, but try it */ 863 offset = 14; 864 rate = read_scsi16(&mp2a[offset]); 865 } else { 866 /* Write Speed is not obsolete */ 867 offset = 28; 868 rate = read_scsi16(&mp2a[offset]); 869 870 if (rate == 0) { 871 /* 872 * then try an Obsolete field 873 * (but this shouldn't happen!) 874 */ 875 offset = 20; 876 rate = read_scsi16(&mp2a[offset]); 877 } 878 } 879 break; 880 } 881 end: 882 free(mp2a); 883 884 if (debug) 885 (void) printf("cd_speed_get: %s Speed is " 886 "%uX\n", (cmd == GET_READ_SPEED) ? 887 "Read" : "Write", cdrw_bandwidth_to_x(rate)); 888 return (rate); 889 } 890 891 /* 892 * CD speed related functions (ioctl style) for drives which do not support 893 * real time streaming. 894 * 895 * For the SET operations, the SET CD SPEED command needs 896 * both the Read Speed and the Write Speed. Eg, if 897 * we're trying to set the Write Speed (SET_WRITE_SPEED), 898 * then we first need to obtain the current Read Speed. 899 * That speed is specified along with the chosen_speed (the 900 * Write Speed in this case) in the SET CD SPEED command. 901 */ 902 int 903 cd_speed_ctrl(cd_device *dev, int cmd, int speed) 904 { 905 uint16_t rate; 906 907 switch (cmd) { 908 case GET_READ_SPEED: 909 rate = cd_speed_get(dev, GET_READ_SPEED); 910 return (cdrw_bandwidth_to_x(rate)); 911 912 case GET_WRITE_SPEED: 913 rate = cd_speed_get(dev, GET_WRITE_SPEED); 914 return (cdrw_bandwidth_to_x(rate)); 915 916 case SET_READ_SPEED: 917 rate = cd_speed_get(dev, GET_WRITE_SPEED); 918 return (set_cd_speed(dev->d_fd, 919 cdrw_x_to_bandwidth(speed), rate)); 920 break; 921 922 case SET_WRITE_SPEED: 923 rate = cd_speed_get(dev, GET_READ_SPEED); 924 return (set_cd_speed(dev->d_fd, rate, 925 cdrw_x_to_bandwidth(speed))); 926 break; 927 928 default: 929 return (0); 930 } 931 } 932 933 /* 934 * Manage sending of SET STREAMING command using the specified 935 * read_speed and write_speed. 936 * 937 * This function allocates and initializes a Performance 938 * Descriptor, which is sent as part of the SET STREAMING 939 * command. The descriptor is deallocated before function 940 * exit. 941 */ 942 static int 943 do_set_streaming(cd_device *dev, uint_t read_speed, 944 uint_t write_speed) 945 { 946 int ret; 947 uchar_t *str; 948 949 /* Allocate and initialize the Performance Descriptor */ 950 str = (uchar_t *)my_zalloc(SET_STREAM_DATA_LEN); 951 952 /* Read Time (in milliseconds) */ 953 load_scsi32(&str[16], 1000); 954 /* Write Time (in milliseconds) */ 955 load_scsi32(&str[24], 1000); 956 957 /* Read Speed */ 958 load_scsi32(&str[12], (uint32_t)read_speed); 959 /* Write Speed */ 960 load_scsi32(&str[20], (uint32_t)write_speed); 961 962 /* issue SET STREAMING command */ 963 ret = set_streaming(dev->d_fd, str); 964 free(str); 965 966 return (ret); 967 } 968 969 /* 970 * cd speed related functions for drives which support 971 * Real-Time Streaming Feature. 972 * 973 * For the SET operations, the SET STREAMING command needs 974 * both the Read Speed and the Write Speed. Eg, if 975 * we're trying to set the Write Speed (SET_WRITE_SPEED), 976 * then we first need to obtain the current Read Speed. 977 * That speed is specified along with the chosen_speed (the 978 * Write Speed in this case) in the SET STREAMING command. 979 */ 980 int 981 rt_streaming_ctrl(cd_device *dev, int cmd, int speed) 982 { 983 int ret = 0; 984 uint_t rate; 985 986 switch (cmd) { 987 case GET_WRITE_SPEED: 988 rate = cd_speed_get(dev, GET_WRITE_SPEED); 989 ret = (int)cdrw_bandwidth_to_x(rate); 990 break; 991 992 case GET_READ_SPEED: 993 rate = cd_speed_get(dev, GET_READ_SPEED); 994 ret = (int)cdrw_bandwidth_to_x(rate); 995 break; 996 997 case SET_READ_SPEED: { 998 uint_t write_speed = cd_speed_get(dev, GET_WRITE_SPEED); 999 1000 /* set Read Speed using SET STREAMING */ 1001 ret = do_set_streaming(dev, 1002 cdrw_x_to_bandwidth(speed), write_speed); 1003 1004 /* If rt_speed_ctrl fails for any reason use cd_speed_ctrl */ 1005 if (ret == 0) { 1006 if (debug) 1007 (void) printf(" real time speed control" 1008 " failed, using CD speed control\n"); 1009 1010 dev->d_speed_ctrl = cd_speed_ctrl; 1011 ret = dev->d_speed_ctrl(dev, cmd, speed); 1012 } 1013 break; 1014 } 1015 1016 case SET_WRITE_SPEED: { 1017 uint_t read_speed = cd_speed_get(dev, GET_READ_SPEED); 1018 1019 /* set Write Speed using SET STREAMING */ 1020 ret = do_set_streaming(dev, read_speed, 1021 cdrw_x_to_bandwidth(speed)); 1022 1023 /* If rt_speed_ctrl fails for any reason use cd_speed_ctrl */ 1024 if (ret == 0) { 1025 if (debug) 1026 (void) printf(" real time speed control" 1027 " failed, using CD speed control\n"); 1028 1029 dev->d_speed_ctrl = cd_speed_ctrl; 1030 ret = dev->d_speed_ctrl(dev, cmd, speed); 1031 } 1032 break; 1033 } 1034 1035 default: 1036 break; 1037 } 1038 1039 return (ret); 1040 } 1041 1042 /* 1043 * Initialize device for track-at-once mode of writing. All of the data will 1044 * need to be written to the track without interruption. 1045 * This initialized TAO by setting page code 5 and speed. 1046 */ 1047 void 1048 write_init(int mode) 1049 { 1050 (void) printf(gettext("Initializing device")); 1051 if (simulation) 1052 (void) printf(gettext("(Simulation mode)")); 1053 print_n_flush("..."); 1054 1055 get_media_type(target->d_fd); 1056 1057 /* DVD- requires DAO mode */ 1058 if (device_type == DVD_MINUS) { 1059 write_mode = DAO_MODE; 1060 } 1061 1062 /* DVD+ and DVD- have no support for AUDIO, bail out */ 1063 if ((mode == TRACK_MODE_AUDIO) && (device_type != CD_RW)) { 1064 err_msg(gettext("Audio mode is only supported for CD media\n")); 1065 exit(1); 1066 } 1067 if (simulation && 1068 check_device(target, CHECK_MEDIA_IS_NOT_BLANK) && 1069 !check_device(target, CHECK_MEDIA_IS_NOT_ERASABLE) && 1070 device_type != DVD_PLUS_W) { 1071 /* 1072 * If we were in simulation mode, and media wasn't blank, 1073 * but medium was erasable, then cdrw goes to erase the 1074 * contents of the media after the simulation writing in order 1075 * to cleanup the ghost TOC (see write_fini() calls blank()). 1076 * This is bad because it removes existing data if media was 1077 * multi-session. Therefore, we no longer allow simulation 1078 * writing if such condition is met. we don't blank the DVD+RW 1079 * media, so DVD+RWs are fine. 1080 */ 1081 err_msg(gettext( 1082 "Cannot perform simulation for non-blank media\n")); 1083 exit(1); 1084 } 1085 1086 if (!prepare_for_write(target, mode, simulation, keep_disc_open)) { 1087 /* l10n_NOTE : 'failed' as in Initializing device...failed */ 1088 (void) printf(gettext("failed.\n")); 1089 err_msg(gettext("Cannot initialize device for write\n")); 1090 exit(1); 1091 } 1092 /* l10n_NOTE : 'done' as in "Initializing device...done" */ 1093 (void) printf(gettext("done.\n")); 1094 1095 /* if speed change option was used (-p) then try to set the speed */ 1096 if (requested_speed != 0) { 1097 if (verbose) 1098 (void) printf(gettext("Trying to set speed to %dX.\n"), 1099 requested_speed); 1100 if (target->d_speed_ctrl(target, SET_WRITE_SPEED, 1101 requested_speed) == 0) { 1102 err_msg(gettext("Unable to set speed.\n")); 1103 exit(1); 1104 } 1105 if (verbose) { 1106 int speed; 1107 speed = target->d_speed_ctrl(target, 1108 GET_WRITE_SPEED, 0); 1109 if (speed == requested_speed) { 1110 (void) printf(gettext("Speed set to %dX.\n"), 1111 speed); 1112 } else if (speed == 0) { 1113 (void) printf(gettext("Could not obtain " 1114 "current Write Speed.\n")); 1115 } else { 1116 (void) printf( 1117 gettext("Speed set to closest approximation " 1118 "of %dX allowed by device (%dX).\n"), 1119 requested_speed, speed); 1120 } 1121 } 1122 } 1123 } 1124 1125 void 1126 write_fini(void) 1127 { 1128 print_n_flush(gettext("Finalizing (Can take several minutes)...")); 1129 /* Some drives don't like this while in test write mode */ 1130 if (!simulation) { 1131 if (!finalize(target)) { 1132 /* 1133 * It is possible that the drive is busy writing the 1134 * buffered portion. So do not get upset yet. 1135 */ 1136 (void) sleep(10); 1137 if (!finalize(target)) { 1138 if (debug) { 1139 (void) printf("status %x, %x/%x/%x\n", 1140 uscsi_status, SENSE_KEY(rqbuf), 1141 ASC(rqbuf), ASCQ(rqbuf)); 1142 } 1143 1144 /* 1145 * Different vendor drives return different 1146 * sense error info for CLOSE SESSION command. 1147 * The Panasonic drive that we are using is 1148 * one such drive. 1149 */ 1150 if (device_type == DVD_MINUS) { 1151 if (verbose) { 1152 (void) printf( 1153 "skipping finalizing\n"); 1154 } 1155 } else { 1156 1157 /* l10n_NOTE : 'failed' as in finishing up...failed */ 1158 (void) printf(gettext("failed.\n")); 1159 1160 err_msg(gettext( 1161 "Could not finalize the disc.\n")); 1162 exit(1); 1163 } 1164 1165 1166 } 1167 } 1168 if (vol_running) { 1169 (void) eject_media(target); 1170 } 1171 } else if (check_device(target, CHECK_MEDIA_IS_NOT_BLANK)) { 1172 /* 1173 * Some drives such as the pioneer A04 will retain a 1174 * ghost TOC after a simulation write is done. The 1175 * media will actually be blank, but the drive will 1176 * report a TOC. There is currently no other way to 1177 * re-initialize the media other than ejecting or 1178 * to ask the drive to clear the leadout. The laser 1179 * is currently off so nothing is written to the 1180 * media (on a good behaving drive). 1181 * NOTE that a device reset does not work to make 1182 * the drive re-initialize the media. 1183 */ 1184 1185 blanking_type = "clear_ghost"; 1186 blank(); 1187 1188 } 1189 /* l10n_NOTE : 'done' as in "Finishing up...done" */ 1190 (void) printf(gettext("done.\n")); 1191 } 1192