File indexing completed on 2024-04-21 04:54:22
0001 /* 0002 * This file is part of WorkMan, the civilized CD player library 0003 * Copyright (C) 1991-1997 by Steven Grimm <koreth@midwinter.com> 0004 * Copyright (C) by Dirk Försterling <milliByte@DeathsDoor.com> 0005 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public 0017 * License along with this library; if not, write to the Free 0018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0019 * 0020 * 0021 * HP/UX-specific drive control routines. 0022 */ 0023 0024 #if defined(hpux) || defined(__hpux) 0025 0026 #include <errno.h> 0027 #include <stdio.h> 0028 #include <fcntl.h> 0029 #include <ustat.h> 0030 #include <unistd.h> 0031 #include <sys/types.h> 0032 #include <sys/param.h> 0033 #include <sys/stat.h> 0034 0035 #include "include/wm_config.h" 0036 0037 /* 0038 * this is for glibc 2.x which the ust structure in 0039 * ustat.h not stat.h 0040 */ 0041 #ifdef __GLIBC__ 0042 #include <sys/ustat.h> 0043 #endif 0044 0045 #include <sys/time.h> 0046 #include <sys/scsi.h> 0047 0048 #include "include/wm_struct.h" 0049 #include "include/wm_helpers.h" 0050 #include "include/wm_cdtext.h" 0051 0052 #define WM_MSG_CLASS WM_MSG_CLASS_PLATFORM 0053 0054 void *malloc(); 0055 char *strchr(); 0056 0057 int min_volume = 0; 0058 int max_volume = 255; 0059 0060 /*--------------------------------------------------------* 0061 * Initialize the drive. A no-op for the generic driver. 0062 *--------------------------------------------------------*/ 0063 int 0064 gen_init( struct wm_drive *d ) 0065 { 0066 return 0; 0067 } /* gen_init() */ 0068 0069 0070 /*-------------------------------------------------------------* 0071 * Open the CD and figure out which kind of drive is attached. 0072 *-------------------------------------------------------------*/ 0073 int 0074 gen_open( struct wm_drive *d ) 0075 { 0076 int flag = 1; 0077 0078 if (d->fd >= 0) { /* Device already open? */ 0079 wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "gen_open(): [device is open (fd=%d)]\n", d->fd); 0080 return 0; 0081 } 0082 0083 0084 d->fd = open(d->cd_device, O_RDWR); 0085 if (d->fd < 0) { 0086 if (errno == EACCES) { 0087 return -EACCES; 0088 } else if (errno != EINTR) { 0089 return -6; 0090 } 0091 0092 /* No CD in drive. */ 0093 return 1; 0094 } 0095 0096 /* Prepare the device to receive raw SCSI commands. */ 0097 if (ioctl(d->fd, SIOC_CMD_MODE, &flag) < 0) { 0098 fprintf(stderr, "%s: SIOC_CMD_MODE: true: %s\n", 0099 d->cd_device, strerror(errno)); 0100 /*exit(1);*/ 0101 } 0102 0103 /* Default drive is the HP one, which might not respond to INQUIRY */ 0104 strcpy(d->vendor, "TOSHIBA"); 0105 strcpy(d->model, "XM-3301"); 0106 d->rev[0] = '\0'; 0107 0108 return 0; 0109 } /* gen_open() */ 0110 0111 /*----------------------------------* 0112 * Send a SCSI command out the bus. 0113 *----------------------------------*/ 0114 int 0115 gen_scsi( struct wm_drive *d, unsigned char *cdb, int cdblen, 0116 void *retbuf, int retbuflen, int getreply ) 0117 { 0118 #ifdef SIOC_IO 0119 struct sctl_io cmd; 0120 0121 memset(&cmd, 0, sizeof(cmd)); 0122 cmd.cdb_length = cdblen; 0123 cmd.data = retbuf; 0124 cmd.data_length = retbuflen; 0125 cmd.max_msecs = 1000; 0126 cmd.flags = getreply ? SCTL_READ : 0; 0127 memcpy(cmd.cdb, cdb, cdblen); 0128 0129 return ioctl(d->fd, SIOC_IO, &cmd); 0130 #else 0131 /* this code, for pre-9.0, is BROKEN! ugh. */ 0132 char reply_buf[12]; 0133 struct scsi_cmd_parms cmd; 0134 0135 memset(&cmd, 0, sizeof(cmd)); 0136 cmd.clock_ticks = 500; 0137 cmd.cmd_mode = 1; 0138 cmd.cmd_type = cdblen; 0139 memcpy(cmd.command, cdb, cdblen); 0140 if (ioctl(d->fd, SIOC_SET_CMD, &cmd) < 0) 0141 return -1; 0142 0143 if (! retbuf || ! retbuflen) 0144 read(d->fd, reply_buf, sizeof(reply_buf)); 0145 else if (getreply) { 0146 if (read(d->fd, retbuf, retbuflen) < 0) 0147 return -1; 0148 } else if (write(d->fd, retbuf, retbuflen) < 0) 0149 return -1; 0150 0151 return 0; 0152 #endif 0153 } /* gen_scsi() */ 0154 0155 int 0156 gen_close( struct wm_drive *d ) 0157 { 0158 if(d->fd != -1) { 0159 wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "closing the device\n"); 0160 close(d->fd); 0161 d->fd = -1; 0162 } 0163 return 0; 0164 } 0165 0166 /*--------------------------------------------------------------------------* 0167 * Get the current status of the drive: the current play mode, the absolute 0168 * position from start of disc (in frames), and the current track and index 0169 * numbers if the CD is playing or paused. 0170 *--------------------------------------------------------------------------*/ 0171 int 0172 gen_get_drive_status( struct wm_drive *d, int oldmode, int *mode, 0173 int *pos, int *track, int *index ) 0174 { 0175 return wm_scsi2_get_drive_status(d, oldmode, mode, pos, track, index); 0176 } /* gen_get_drive_status() */ 0177 0178 /*-------------------------------------* 0179 * Get the number of tracks on the CD. 0180 *-------------------------------------*/ 0181 int 0182 gen_get_trackcount(struct wm_drive *d, int *tracks ) 0183 { 0184 return wm_scsi2_get_trackcount(d, tracks); 0185 } /* gen_get_trackcount() */ 0186 0187 /*---------------------------------------------------------* 0188 * Get the start time and mode (data or audio) of a track. 0189 *---------------------------------------------------------*/ 0190 int 0191 gen_get_trackinfo( struct wm_drive *d, int *track, int *data, int *startframe) 0192 { 0193 return wm_scsi2_get_trackinfo(d, track, data, startframe); 0194 } /* gen_get_trackinfo() */ 0195 0196 /*-------------------------------------* 0197 * Get the number of frames on the CD. 0198 *-------------------------------------*/ 0199 int gen_get_cdlen(struct wm_drive *d, int *frames) 0200 { 0201 return wm_scsi2_get_cdlen(d, frames); 0202 } /* gen_get_cdlen() */ 0203 0204 /*------------------------------------------------------------* 0205 * Play the CD from one position to another (both in frames.) 0206 *------------------------------------------------------------*/ 0207 int 0208 gen_play( struct wm_drive *d, int start, int end ) 0209 { 0210 return wm_scsi2_play(d, start, end); 0211 } /* gen_play() */ 0212 0213 /*---------------* 0214 * Pause the CD. 0215 *---------------*/ 0216 int 0217 gen_pause( struct wm_drive *d ) 0218 { 0219 return wm_scsi2_pause(d); 0220 } /* gen_pause() */ 0221 0222 /*-------------------------------------------------* 0223 * Resume playing the CD (assuming it was paused.) 0224 *-------------------------------------------------*/ 0225 int 0226 gen_resume( struct wm_drive *d ) 0227 { 0228 return wm_scsi2_resume(d); 0229 } /* gen_resume() */ 0230 0231 /*--------------* 0232 * Stop the CD. 0233 *--------------*/ 0234 int 0235 gen_stop( struct wm_drive *d ) 0236 { 0237 return wm_scsi2_stop(d); 0238 } /* gen_stop() */ 0239 0240 0241 /*----------------------------------------* 0242 * Eject the current CD, if there is one. 0243 *----------------------------------------*/ 0244 int 0245 gen_eject( struct wm_drive *d ) 0246 { 0247 struct stat stbuf; 0248 struct ustat ust; 0249 0250 if (fstat(d->fd, &stbuf) != 0) 0251 return -2; 0252 0253 /* Is this a mounted filesystem? */ 0254 if (ustat(stbuf.st_rdev, &ust) == 0) 0255 return -3; 0256 0257 return wm_scsi2_eject(d); 0258 } /* gen_eject() */ 0259 0260 /*----------------------------------------* 0261 * Close the CD tray 0262 *----------------------------------------*/ 0263 int 0264 gen_closetray(struct wm_drive *d) 0265 { 0266 return wm_scsi2_closetray(d); 0267 } /* gen_closetray() */ 0268 0269 0270 /*---------------------------------------------------------------------* 0271 * Set the volume level for the left and right channels. Their values 0272 * range from 0 to 100. 0273 *---------------------------------------------------------------------*/ 0274 int 0275 gen_set_volume( struct wm_drive *d, int left, int right ) 0276 { 0277 return wm_scsi2_set_volume(d, left, right); 0278 } /* gen_set_volume() */ 0279 0280 /*---------------------------------------------------------------------* 0281 * Read the initial volume from the drive, if available. Each channel 0282 * ranges from 0 to 100, with -1 indicating data not available. 0283 *---------------------------------------------------------------------*/ 0284 int 0285 gen_get_volume( struct wm_drive *d, int *left, int *right ) 0286 { 0287 return wm_scsi2_get_volume(d, left, right); 0288 } /* gen_get_volume() */ 0289 0290 #endif 0291 0292