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
read_scsi32(void * addr)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
read_scsi16(void * addr)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
load_scsi32(void * addr,uint32_t v)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
load_scsi16(void * addr,uint16_t v)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
get_mode_page(int fd,int page_no,int pc,int buf_len,uchar_t * buffer)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
set_mode_page(int fd,uchar_t * buffer)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
build_track_info(cd_device * dev,int trackno,struct track_info * t_info)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
check_track_size(cd_device * dev,int trk_num,struct track_info * tip)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
rtoc_get_trk_sess_num(uchar_t * rtoc,size_t rtoc_len,int trk_num,int * sess_nump)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
rtoc_get_sess_last_trk_num(uchar_t * rtoc,size_t rtoc_len,int sess_num,int * last_trk_nump)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
rtoc_get_sess_leadout_lba(uchar_t * rtoc,size_t rtoc_len,int sess_num,uint32_t * leadout_lba)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 *
get_rtoc_td(rtoc_td_t * begin_tdp,rtoc_td_t * end_tdp,uchar_t adr,uchar_t point)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
get_data_mode(int fd,uint32_t lba)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
prepare_for_write(cd_device * dev,int track_mode,int test_write,int keep_disc_open)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
finalize(cd_device * dev)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
get_last_possible_lba(cd_device * dev)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
read_audio_through_read_cd(cd_device * dev,uint_t start_lba,uint_t nblks,uchar_t * buf)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
eject_media(cd_device * dev)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
cd_speed_get(cd_device * dev,int cmd)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
cd_speed_ctrl(cd_device * dev,int cmd,int speed)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
do_set_streaming(cd_device * dev,uint_t read_speed,uint_t write_speed)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
rt_streaming_ctrl(cd_device * dev,int cmd,int speed)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
write_init(int mode)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
write_fini(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