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 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <string.h> 31 #include <stdlib.h> 32 #include <sys/types.h> 33 #include <libintl.h> 34 35 #include "transport.h" 36 #include "toshiba.h" 37 #include "device.h" 38 #include "misc_scsi.h" 39 #include "util.h" 40 #include "main.h" 41 #include "msgs.h" 42 #include "mmc.h" 43 44 static int speed_tbl[4] = { 1, 2, 12, 4 }; 45 static uchar_t rev_speed_tbl[16] = { 0, 0, 1, 0, 3, 0, 0, 0, 0, 46 0, 0, 0, 2, 0, 0, 0 }; 47 48 /* 49 * These are commands for using older Sun Toshiba drives. These 50 * commands are needed for reading CD TOC and audio extraction 51 * and changing speeds (used for audio extraction). 52 */ 53 54 int 55 read_toc_as_per_8020(int fd, int format, int trackno, int buflen, uchar_t *buf) 56 { 57 struct uscsi_cmd *scmd; 58 59 scmd = get_uscsi_cmd(); 60 scmd->uscsi_flags = USCSI_READ|USCSI_SILENT; 61 scmd->uscsi_timeout = 60; 62 scmd->uscsi_cdb[0] = READ_TOC_CMD; 63 scmd->uscsi_cdb[6] = trackno; 64 scmd->uscsi_cdb[8] = buflen & 0xff; 65 scmd->uscsi_cdb[7] = (buflen >> 8) & 0xff; 66 scmd->uscsi_cdb[9] = (format << 6) & 0xc0; 67 scmd->uscsi_cdblen = 10; 68 scmd->uscsi_bufaddr = (char *)buf; 69 scmd->uscsi_buflen = buflen; 70 if (uscsi(fd, scmd) < 0) 71 return (0); 72 return (1); 73 } 74 75 int 76 toshiba_read_audio(cd_device *target, uint_t start_blk, uint_t nblk, 77 uchar_t *buf) 78 { 79 struct uscsi_cmd *scmd; 80 int ret, retry; 81 82 scmd = get_uscsi_cmd(); 83 scmd->uscsi_flags = USCSI_READ|USCSI_SILENT; 84 scmd->uscsi_timeout = 60; 85 ((uchar_t *)scmd->uscsi_cdb)[0] = READ_AUDIO_CMD; 86 scmd->uscsi_cdb[5] = start_blk & 0xff; 87 scmd->uscsi_cdb[4] = (start_blk >> 8) & 0xff; 88 scmd->uscsi_cdb[3] = (start_blk >> 16) & 0xff; 89 scmd->uscsi_cdb[2] = (start_blk >> 24) & 0xff; 90 scmd->uscsi_cdb[9] = nblk & 0xff; 91 scmd->uscsi_cdb[8] = (nblk >> 8) & 0xff; 92 scmd->uscsi_cdb[7] = (nblk >> 16) & 0xff; 93 scmd->uscsi_cdb[6] = (nblk >> 24) & 0xff; 94 scmd->uscsi_cdblen = 12; 95 scmd->uscsi_bufaddr = (char *)buf; 96 scmd->uscsi_buflen = nblk*2352; 97 98 for (retry = 0; retry < 3; retry++) { 99 ret = uscsi(target->d_fd, scmd); 100 if (ret >= 0) 101 break; 102 } 103 104 if (ret < 0) 105 return (0); 106 return (1); 107 } 108 109 int 110 toshiba_speed_ctrl(cd_device *dev, int cmd, int speed) 111 { 112 uchar_t *mpage; 113 struct uscsi_cmd *scmd; 114 int ret; 115 116 if ((cmd == GET_WRITE_SPEED) || (cmd == SET_WRITE_SPEED)) { 117 if (debug) { 118 (void) printf("toshiba_speed_ctrl: WRONG CMD %d\n", 119 cmd); 120 } 121 return (0); 122 } 123 124 if (cmd == SET_READ_SPEED) { 125 if (dev->d_cap & DEV_CAP_SETTING_SPEED_NOT_ALLOWED) { 126 if (verbose) 127 err_msg(gettext( 128 "Cannot set speed on this device.\n")); 129 return (0); 130 } 131 if (speed == 32) { 132 if (strncmp("SUN32XCD", 133 (const char *)&dev->d_inq[24], 8) == 0) 134 return (1); 135 } 136 if ((speed != 1) && (speed != 2) && (speed != 4) && 137 (speed != 12)) { 138 if (verbose) 139 err_msg(gettext( 140 "%dx speed is not supported by the device.\n")); 141 return (0); 142 } 143 } 144 145 ret = 0; 146 mpage = (uchar_t *)my_zalloc(16); 147 scmd = get_uscsi_cmd(); 148 scmd->uscsi_flags = USCSI_READ|USCSI_SILENT; 149 scmd->uscsi_timeout = 60; 150 scmd->uscsi_cdblen = 6; 151 scmd->uscsi_bufaddr = (char *)mpage; 152 scmd->uscsi_buflen = 16; 153 /* 6 byte mode sense for older drives */ 154 scmd->uscsi_cdb[0] = MODE_SENSE_6_CMD; 155 scmd->uscsi_cdb[2] = 0x31; 156 scmd->uscsi_cdb[4] = 16; 157 if (uscsi(dev->d_fd, scmd) < 0) 158 goto end_speed_ctrl; 159 if (cmd == GET_READ_SPEED) { 160 ret = speed_tbl[mpage[14] & 0x3]; 161 goto end_speed_ctrl; 162 } 163 if (cmd == SET_READ_SPEED) { 164 (void) memset(mpage, 0, 9); 165 mpage[3] = 8; 166 mpage[12] = 0x31; 167 mpage[13] = 2; 168 mpage[14] = rev_speed_tbl[speed]; 169 scmd = get_uscsi_cmd(); 170 scmd->uscsi_flags = USCSI_WRITE|USCSI_SILENT; 171 scmd->uscsi_timeout = 60; 172 scmd->uscsi_cdblen = 6; 173 scmd->uscsi_bufaddr = (char *)mpage; 174 scmd->uscsi_buflen = 16; 175 /* 6 byte mode sense command for older drives */ 176 scmd->uscsi_cdb[0] = MODE_SELECT_6_CMD; 177 scmd->uscsi_cdb[1] = 0x10; 178 scmd->uscsi_cdb[4] = 16; 179 if (uscsi(dev->d_fd, scmd) < 0) 180 goto end_speed_ctrl; 181 ret = 1; 182 } 183 end_speed_ctrl: 184 free(mpage); 185 return (ret); 186 } 187