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