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