1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <sys/types.h>
31 #include <libintl.h>
32
33 #include "transport.h"
34 #include "toshiba.h"
35 #include "device.h"
36 #include "misc_scsi.h"
37 #include "util.h"
38 #include "main.h"
39 #include "msgs.h"
40 #include "mmc.h"
41
42 static int speed_tbl[4] = { 1, 2, 12, 4 };
43 static uchar_t rev_speed_tbl[16] = { 0, 0, 1, 0, 3, 0, 0, 0, 0,
44 0, 0, 0, 2, 0, 0, 0 };
45
46 /*
47 * These are commands for using older Sun Toshiba drives. These
48 * commands are needed for reading CD TOC and audio extraction
49 * and changing speeds (used for audio extraction).
50 */
51
52 int
read_toc_as_per_8020(int fd,int format,int trackno,int buflen,uchar_t * buf)53 read_toc_as_per_8020(int fd, int format, int trackno, int buflen, uchar_t *buf)
54 {
55 struct uscsi_cmd *scmd;
56
57 scmd = get_uscsi_cmd();
58 scmd->uscsi_flags = USCSI_READ|USCSI_SILENT;
59 scmd->uscsi_timeout = 60;
60 scmd->uscsi_cdb[0] = READ_TOC_CMD;
61 scmd->uscsi_cdb[6] = trackno;
62 scmd->uscsi_cdb[8] = buflen & 0xff;
63 scmd->uscsi_cdb[7] = (buflen >> 8) & 0xff;
64 scmd->uscsi_cdb[9] = (format << 6) & 0xc0;
65 scmd->uscsi_cdblen = 10;
66 scmd->uscsi_bufaddr = (char *)buf;
67 scmd->uscsi_buflen = buflen;
68 if (uscsi(fd, scmd) < 0)
69 return (0);
70 return (1);
71 }
72
73 int
toshiba_read_audio(cd_device * target,uint_t start_blk,uint_t nblk,uchar_t * buf)74 toshiba_read_audio(cd_device *target, uint_t start_blk, uint_t nblk,
75 uchar_t *buf)
76 {
77 struct uscsi_cmd *scmd;
78 int ret, retry;
79
80 scmd = get_uscsi_cmd();
81 scmd->uscsi_flags = USCSI_READ|USCSI_SILENT;
82 scmd->uscsi_timeout = 60;
83 ((uchar_t *)scmd->uscsi_cdb)[0] = READ_AUDIO_CMD;
84 scmd->uscsi_cdb[5] = start_blk & 0xff;
85 scmd->uscsi_cdb[4] = (start_blk >> 8) & 0xff;
86 scmd->uscsi_cdb[3] = (start_blk >> 16) & 0xff;
87 scmd->uscsi_cdb[2] = (start_blk >> 24) & 0xff;
88 scmd->uscsi_cdb[9] = nblk & 0xff;
89 scmd->uscsi_cdb[8] = (nblk >> 8) & 0xff;
90 scmd->uscsi_cdb[7] = (nblk >> 16) & 0xff;
91 scmd->uscsi_cdb[6] = (nblk >> 24) & 0xff;
92 scmd->uscsi_cdblen = 12;
93 scmd->uscsi_bufaddr = (char *)buf;
94 scmd->uscsi_buflen = nblk*2352;
95
96 for (retry = 0; retry < 3; retry++) {
97 ret = uscsi(target->d_fd, scmd);
98 if (ret >= 0)
99 break;
100 }
101
102 if (ret < 0)
103 return (0);
104 return (1);
105 }
106
107 int
toshiba_speed_ctrl(cd_device * dev,int cmd,int speed)108 toshiba_speed_ctrl(cd_device *dev, int cmd, int speed)
109 {
110 uchar_t *mpage;
111 struct uscsi_cmd *scmd;
112 int ret;
113
114 if ((cmd == GET_WRITE_SPEED) || (cmd == SET_WRITE_SPEED)) {
115 if (debug) {
116 (void) printf("toshiba_speed_ctrl: WRONG CMD %d\n",
117 cmd);
118 }
119 return (0);
120 }
121
122 if (cmd == SET_READ_SPEED) {
123 if (dev->d_cap & DEV_CAP_SETTING_SPEED_NOT_ALLOWED) {
124 if (verbose)
125 err_msg(gettext(
126 "Cannot set speed on this device.\n"));
127 return (0);
128 }
129 if (speed == 32) {
130 if (strncmp("SUN32XCD",
131 (const char *)&dev->d_inq[24], 8) == 0)
132 return (1);
133 }
134 if ((speed != 1) && (speed != 2) && (speed != 4) &&
135 (speed != 12)) {
136 if (verbose)
137 err_msg(gettext(
138 "%dx speed is not supported by the device.\n"));
139 return (0);
140 }
141 }
142
143 ret = 0;
144 mpage = (uchar_t *)my_zalloc(16);
145 scmd = get_uscsi_cmd();
146 scmd->uscsi_flags = USCSI_READ|USCSI_SILENT;
147 scmd->uscsi_timeout = 60;
148 scmd->uscsi_cdblen = 6;
149 scmd->uscsi_bufaddr = (char *)mpage;
150 scmd->uscsi_buflen = 16;
151 /* 6 byte mode sense for older drives */
152 scmd->uscsi_cdb[0] = MODE_SENSE_6_CMD;
153 scmd->uscsi_cdb[2] = 0x31;
154 scmd->uscsi_cdb[4] = 16;
155 if (uscsi(dev->d_fd, scmd) < 0)
156 goto end_speed_ctrl;
157 if (cmd == GET_READ_SPEED) {
158 ret = speed_tbl[mpage[14] & 0x3];
159 goto end_speed_ctrl;
160 }
161 if (cmd == SET_READ_SPEED) {
162 (void) memset(mpage, 0, 9);
163 mpage[3] = 8;
164 mpage[12] = 0x31;
165 mpage[13] = 2;
166 mpage[14] = rev_speed_tbl[speed];
167 scmd = get_uscsi_cmd();
168 scmd->uscsi_flags = USCSI_WRITE|USCSI_SILENT;
169 scmd->uscsi_timeout = 60;
170 scmd->uscsi_cdblen = 6;
171 scmd->uscsi_bufaddr = (char *)mpage;
172 scmd->uscsi_buflen = 16;
173 /* 6 byte mode sense command for older drives */
174 scmd->uscsi_cdb[0] = MODE_SELECT_6_CMD;
175 scmd->uscsi_cdb[1] = 0x10;
176 scmd->uscsi_cdb[4] = 16;
177 if (uscsi(dev->d_fd, scmd) < 0)
178 goto end_speed_ctrl;
179 ret = 1;
180 }
181 end_speed_ctrl:
182 free(mpage);
183 return (ret);
184 }
185