comparison src/cdrom/bsdi/SDL_syscdrom.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 92947e3a18db
children e27bdcc80744
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
51 #define FRAMES_PER_SECOND 75 51 #define FRAMES_PER_SECOND 75
52 #define FRAMES_PER_MINUTE (FRAMES_PER_SECOND * 60) 52 #define FRAMES_PER_MINUTE (FRAMES_PER_SECOND * 60)
53 53
54 int 54 int
55 msf_to_frame(int minute, int second, int frame) 55 msf_to_frame(int minute, int second, int frame)
56 { 56 {
57 return(minute * FRAMES_PER_MINUTE + second * FRAMES_PER_SECOND + frame); 57 return (minute * FRAMES_PER_MINUTE + second * FRAMES_PER_SECOND + frame);
58 } 58 }
59 59
60 void 60 void
61 frame_to_msf(int frame, int *minp, int *secp, int *framep) 61 frame_to_msf(int frame, int *minp, int *secp, int *framep)
62 { 62 {
63 *minp = frame / FRAMES_PER_MINUTE; 63 *minp = frame / FRAMES_PER_MINUTE;
64 *secp = (frame % FRAMES_PER_MINUTE) / FRAMES_PER_SECOND; 64 *secp = (frame % FRAMES_PER_MINUTE) / FRAMES_PER_SECOND;
65 *framep = frame % FRAMES_PER_SECOND; 65 *framep = frame % FRAMES_PER_SECOND;
66 } 66 }
67 67
68 /* The maximum number of CD-ROM drives we'll detect */ 68 /* The maximum number of CD-ROM drives we'll detect */
69 #define MAX_DRIVES 16 69 #define MAX_DRIVES 16
70 70
71 /* A list of available CD-ROM drives */ 71 /* A list of available CD-ROM drives */
72 static char *SDL_cdlist[MAX_DRIVES]; 72 static char *SDL_cdlist[MAX_DRIVES];
73 static dev_t SDL_cdmode[MAX_DRIVES]; 73 static dev_t SDL_cdmode[MAX_DRIVES];
74 74
75 /* The system-dependent CD control functions */ 75 /* The system-dependent CD control functions */
76 static const char *SDL_SYS_CDName(int drive); 76 static const char *SDL_SYS_CDName(int drive);
77 static int SDL_SYS_CDOpen(int drive); 77 static int SDL_SYS_CDOpen(int drive);
78 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); 78 static int SDL_SYS_CDGetTOC(SDL_CD * cdrom);
79 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); 79 static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position);
80 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); 80 static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length);
81 static int SDL_SYS_CDPause(SDL_CD *cdrom); 81 static int SDL_SYS_CDPause(SDL_CD * cdrom);
82 static int SDL_SYS_CDResume(SDL_CD *cdrom); 82 static int SDL_SYS_CDResume(SDL_CD * cdrom);
83 static int SDL_SYS_CDStop(SDL_CD *cdrom); 83 static int SDL_SYS_CDStop(SDL_CD * cdrom);
84 static int SDL_SYS_CDEject(SDL_CD *cdrom); 84 static int SDL_SYS_CDEject(SDL_CD * cdrom);
85 static void SDL_SYS_CDClose(SDL_CD *cdrom); 85 static void SDL_SYS_CDClose(SDL_CD * cdrom);
86 86
87 typedef struct scsi_cdb cdb_t; 87 typedef struct scsi_cdb cdb_t;
88 88
89 static int scsi_cmd(int fd, 89 static int
90 struct scsi_cdb *cdb, 90 scsi_cmd(int fd,
91 int cdblen, 91 struct scsi_cdb *cdb,
92 int rw, 92 int cdblen,
93 caddr_t data, 93 int rw, caddr_t data, int datalen, struct scsi_user_cdb *sus)
94 int datalen, 94 {
95 struct scsi_user_cdb *sus) 95 int scsistatus;
96 { 96 unsigned char *cp;
97 int scsistatus; 97 struct scsi_user_cdb suc;
98 unsigned char *cp;
99 struct scsi_user_cdb suc;
100 98
101 /* safety checks */ 99 /* safety checks */
102 if (!cdb) return(-1); 100 if (!cdb)
103 if (rw != SUC_READ && rw != SUC_WRITE) return(-1); 101 return (-1);
104 102 if (rw != SUC_READ && rw != SUC_WRITE)
105 suc.suc_flags = rw; 103 return (-1);
106 suc.suc_cdblen = cdblen; 104
107 bcopy(cdb, suc.suc_cdb, cdblen); 105 suc.suc_flags = rw;
108 suc.suc_datalen = datalen; 106 suc.suc_cdblen = cdblen;
109 suc.suc_data = data; 107 bcopy(cdb, suc.suc_cdb, cdblen);
110 suc.suc_timeout = 10; /* 10 secs max for TUR or SENSE */ 108 suc.suc_datalen = datalen;
111 if (ioctl(fd, SCSIRAWCDB, &suc) == -1) 109 suc.suc_data = data;
112 return(-11); 110 suc.suc_timeout = 10; /* 10 secs max for TUR or SENSE */
113 scsistatus = suc.suc_sus.sus_status; 111 if (ioctl(fd, SCSIRAWCDB, &suc) == -1)
114 cp = suc.suc_sus.sus_sense; 112 return (-11);
113 scsistatus = suc.suc_sus.sus_status;
114 cp = suc.suc_sus.sus_sense;
115 115
116 /* 116 /*
117 * If a place to copy the sense data back to has been provided then the 117 * If a place to copy the sense data back to has been provided then the
118 * caller is responsible for checking the errors and printing any information 118 * caller is responsible for checking the errors and printing any information
119 * out if the status was not successful. 119 * out if the status was not successful.
120 */ 120 */
121 if (scsistatus != 0 && !sus) 121 if (scsistatus != 0 && !sus) {
122 { 122 fprintf(stderr, "scsistatus = %x cmd = %x\n", scsistatus, cdb[0]);
123 fprintf(stderr,"scsistatus = %x cmd = %x\n", 123 fprintf(stderr,
124 scsistatus, cdb[0]); 124 "sense %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
125 fprintf(stderr, "sense %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", 125 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7],
126 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], 126 cp[8], cp[9], cp[10], cp[11], cp[12], cp[13], cp[14], cp[15]);
127 cp[6], cp[7], cp[8], cp[9], cp[10], cp[11], 127 return (1);
128 cp[12], cp[13], cp[14], cp[15]); 128 }
129 return(1); 129 if (sus)
130 } 130 bcopy(&suc, sus, sizeof(struct scsi_user_cdb));
131 if (sus) 131 if (scsistatus)
132 bcopy(&suc, sus, sizeof (struct scsi_user_cdb)); 132 return (1); /* Return non-zero for unsuccessful status */
133 if (scsistatus) 133 return (0);
134 return(1); /* Return non-zero for unsuccessful status */ 134 }
135 return(0);
136 }
137 135
138 /* request vendor brand and model */ 136 /* request vendor brand and model */
139 unsigned char *Inquiry(int fd) 137 unsigned char *
140 { 138 Inquiry(int fd)
141 static struct scsi_cdb6 cdb = 139 {
142 { 140 static struct scsi_cdb6 cdb = {
143 0x12, 141 0x12,
144 0, 0, 0, 142 0, 0, 0,
145 56, 143 56,
146 0 144 0
147 }; 145 };
148 static unsigned char Inqbuffer[56]; 146 static unsigned char Inqbuffer[56];
149 147
150 if (scsi_cmd(fd, (cdb_t *)&cdb, 6, SUC_READ, Inqbuffer, 148 if (scsi_cmd(fd, (cdb_t *) & cdb, 6, SUC_READ, Inqbuffer,
151 sizeof(Inqbuffer), 0)) 149 sizeof(Inqbuffer), 0))
152 return("\377"); 150 return ("\377");
153 return(Inqbuffer); 151 return (Inqbuffer);
154 } 152 }
155 153
156 #define ADD_SENSECODE 12 154 #define ADD_SENSECODE 12
157 #define ADD_SC_QUALIFIER 13 155 #define ADD_SC_QUALIFIER 13
158 156
159 int TestForMedium(int fd) 157 int
160 { 158 TestForMedium(int fd)
161 int sts, asc, ascq; 159 {
162 struct scsi_user_cdb sus; 160 int sts, asc, ascq;
163 static struct scsi_cdb6 cdb = 161 struct scsi_user_cdb sus;
164 { 162 static struct scsi_cdb6 cdb = {
165 CMD_TEST_UNIT_READY, /* command */ 163 CMD_TEST_UNIT_READY, /* command */
166 0, /* reserved */ 164 0, /* reserved */
167 0, /* reserved */ 165 0, /* reserved */
168 0, /* reserved */ 166 0, /* reserved */
169 0, /* reserved */ 167 0, /* reserved */
170 0 /* reserved */ 168 0 /* reserved */
171 }; 169 };
172 170
173 again: sts = scsi_cmd(fd, (cdb_t *)&cdb, 6, SUC_READ, 0, 0, &sus); 171 again:sts = scsi_cmd(fd, (cdb_t *) & cdb, 6, SUC_READ, 0, 0, &sus);
174 asc = sus.suc_sus.sus_sense[ADD_SENSECODE]; 172 asc = sus.suc_sus.sus_sense[ADD_SENSECODE];
175 ascq = sus.suc_sus.sus_sense[ADD_SC_QUALIFIER]; 173 ascq = sus.suc_sus.sus_sense[ADD_SC_QUALIFIER];
176 if (asc == 0x3a && ascq == 0x0) /* no medium */ 174 if (asc == 0x3a && ascq == 0x0) /* no medium */
177 return(0); 175 return (0);
178 if (asc == 0x28 && ascq == 0x0) /* medium changed */ 176 if (asc == 0x28 && ascq == 0x0) /* medium changed */
179 goto again; 177 goto again;
180 if (asc == 0x4 && ascq == 0x1 ) /* coming ready */ 178 if (asc == 0x4 && ascq == 0x1) { /* coming ready */
181 { 179 sleep(2);
182 sleep(2); 180 goto again;
183 goto again; 181 }
184 } 182 return (1);
185 return(1); 183 }
186 }
187 184
188 /* Check a drive to see if it is a CD-ROM */ 185 /* Check a drive to see if it is a CD-ROM */
189 static int CheckDrive(char *drive, struct stat *stbuf) 186 static int
190 { 187 CheckDrive(char *drive, struct stat *stbuf)
191 int is_cd = 0, cdfd; 188 {
192 char *p; 189 int is_cd = 0, cdfd;
193 190 char *p;
194 /* If it doesn't exist, return -1 */ 191
195 if ( stat(drive, stbuf) < 0 ) { 192 /* If it doesn't exist, return -1 */
196 return(-1); 193 if (stat(drive, stbuf) < 0) {
197 } 194 return (-1);
198 195 }
199 /* If it does exist, verify that it's an available CD-ROM */ 196
200 cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); 197 /* If it does exist, verify that it's an available CD-ROM */
201 if ( cdfd >= 0 ) { 198 cdfd = open(drive, (O_RDONLY | O_EXCL | O_NONBLOCK), 0);
202 p = Inquiry(cdfd); 199 if (cdfd >= 0) {
203 if (*p == TYPE_ROM) 200 p = Inquiry(cdfd);
204 is_cd = 1; 201 if (*p == TYPE_ROM)
205 close(cdfd); 202 is_cd = 1;
206 } 203 close(cdfd);
207 return(is_cd); 204 }
205 return (is_cd);
208 } 206 }
209 207
210 /* Add a CD-ROM drive to our list of valid drives */ 208 /* Add a CD-ROM drive to our list of valid drives */
211 static void AddDrive(char *drive, struct stat *stbuf) 209 static void
212 { 210 AddDrive(char *drive, struct stat *stbuf)
213 int i; 211 {
214 212 int i;
215 if ( SDL_numcds < MAX_DRIVES ) { 213
216 /* Check to make sure it's not already in our list. 214 if (SDL_numcds < MAX_DRIVES) {
217 This can happen when we see a drive via symbolic link. 215 /* Check to make sure it's not already in our list.
218 */ 216 This can happen when we see a drive via symbolic link.
219 for ( i=0; i<SDL_numcds; ++i ) { 217 */
220 if ( stbuf->st_rdev == SDL_cdmode[i] ) { 218 for (i = 0; i < SDL_numcds; ++i) {
219 if (stbuf->st_rdev == SDL_cdmode[i]) {
221 #ifdef DEBUG_CDROM 220 #ifdef DEBUG_CDROM
222 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); 221 fprintf(stderr, "Duplicate drive detected: %s == %s\n",
222 drive, SDL_cdlist[i]);
223 #endif 223 #endif
224 return; 224 return;
225 } 225 }
226 } 226 }
227 227
228 /* Add this drive to our list */ 228 /* Add this drive to our list */
229 i = SDL_numcds; 229 i = SDL_numcds;
230 SDL_cdlist[i] = SDL_strdup(drive); 230 SDL_cdlist[i] = SDL_strdup(drive);
231 if ( SDL_cdlist[i] == NULL ) { 231 if (SDL_cdlist[i] == NULL) {
232 SDL_OutOfMemory(); 232 SDL_OutOfMemory();
233 return; 233 return;
234 } 234 }
235 SDL_cdmode[i] = stbuf->st_rdev; 235 SDL_cdmode[i] = stbuf->st_rdev;
236 ++SDL_numcds; 236 ++SDL_numcds;
237 #ifdef DEBUG_CDROM 237 #ifdef DEBUG_CDROM
238 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); 238 fprintf(stderr, "Added CD-ROM drive: %s\n", drive);
239 #endif 239 #endif
240 } 240 }
241 } 241 }
242 242
243 int SDL_SYS_CDInit(void) 243 int
244 { 244 SDL_SYS_CDInit(void)
245 /* checklist: /dev/rsr?c */ 245 {
246 static char *checklist[] = { 246 /* checklist: /dev/rsr?c */
247 "?0 rsr?", NULL 247 static char *checklist[] = {
248 }; 248 "?0 rsr?", NULL
249 char *SDLcdrom; 249 };
250 int i, j, exists; 250 char *SDLcdrom;
251 char drive[32]; 251 int i, j, exists;
252 struct stat stbuf; 252 char drive[32];
253 253 struct stat stbuf;
254 /* Fill in our driver capabilities */ 254
255 SDL_CDcaps.Name = SDL_SYS_CDName; 255 /* Fill in our driver capabilities */
256 SDL_CDcaps.Open = SDL_SYS_CDOpen; 256 SDL_CDcaps.Name = SDL_SYS_CDName;
257 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; 257 SDL_CDcaps.Open = SDL_SYS_CDOpen;
258 SDL_CDcaps.Status = SDL_SYS_CDStatus; 258 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
259 SDL_CDcaps.Play = SDL_SYS_CDPlay; 259 SDL_CDcaps.Status = SDL_SYS_CDStatus;
260 SDL_CDcaps.Pause = SDL_SYS_CDPause; 260 SDL_CDcaps.Play = SDL_SYS_CDPlay;
261 SDL_CDcaps.Resume = SDL_SYS_CDResume; 261 SDL_CDcaps.Pause = SDL_SYS_CDPause;
262 SDL_CDcaps.Stop = SDL_SYS_CDStop; 262 SDL_CDcaps.Resume = SDL_SYS_CDResume;
263 SDL_CDcaps.Eject = SDL_SYS_CDEject; 263 SDL_CDcaps.Stop = SDL_SYS_CDStop;
264 SDL_CDcaps.Close = SDL_SYS_CDClose; 264 SDL_CDcaps.Eject = SDL_SYS_CDEject;
265 265 SDL_CDcaps.Close = SDL_SYS_CDClose;
266 /* Look in the environment for our CD-ROM drive list */ 266
267 SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ 267 /* Look in the environment for our CD-ROM drive list */
268 if ( SDLcdrom != NULL ) { 268 SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */
269 char *cdpath, *delim; 269 if (SDLcdrom != NULL) {
270 size_t len = SDL_strlen(SDLcdrom)+1; 270 char *cdpath, *delim;
271 cdpath = SDL_stack_alloc(char, len); 271 size_t len = SDL_strlen(SDLcdrom) + 1;
272 if ( cdpath != NULL ) { 272 cdpath = SDL_stack_alloc(char, len);
273 SDL_strlcpy(cdpath, SDLcdrom, len); 273 if (cdpath != NULL) {
274 SDLcdrom = cdpath; 274 SDL_strlcpy(cdpath, SDLcdrom, len);
275 do { 275 SDLcdrom = cdpath;
276 delim = SDL_strchr(SDLcdrom, ':'); 276 do {
277 if ( delim ) { 277 delim = SDL_strchr(SDLcdrom, ':');
278 *delim++ = '\0'; 278 if (delim) {
279 } 279 *delim++ = '\0';
280 if ( CheckDrive(SDLcdrom, &stbuf) > 0 ) { 280 }
281 AddDrive(SDLcdrom, &stbuf); 281 if (CheckDrive(SDLcdrom, &stbuf) > 0) {
282 } 282 AddDrive(SDLcdrom, &stbuf);
283 if ( delim ) { 283 }
284 SDLcdrom = delim; 284 if (delim) {
285 } else { 285 SDLcdrom = delim;
286 SDLcdrom = NULL; 286 } else {
287 } 287 SDLcdrom = NULL;
288 } while ( SDLcdrom ); 288 }
289 SDL_stack_free(cdpath); 289 }
290 } 290 while (SDLcdrom);
291 291 SDL_stack_free(cdpath);
292 /* If we found our drives, there's nothing left to do */ 292 }
293 if ( SDL_numcds > 0 ) { 293
294 return(0); 294 /* If we found our drives, there's nothing left to do */
295 } 295 if (SDL_numcds > 0) {
296 } 296 return (0);
297 297 }
298 /* Scan the system for CD-ROM drives */ 298 }
299 for ( i=0; checklist[i]; ++i ) { 299
300 if ( checklist[i][0] == '?' ) { 300 /* Scan the system for CD-ROM drives */
301 char *insert; 301 for (i = 0; checklist[i]; ++i) {
302 exists = 1; 302 if (checklist[i][0] == '?') {
303 for ( j=checklist[i][1]; exists; ++j ) { 303 char *insert;
304 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%sc", &checklist[i][3]); 304 exists = 1;
305 insert = SDL_strchr(drive, '?'); 305 for (j = checklist[i][1]; exists; ++j) {
306 if ( insert != NULL ) { 306 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%sc",
307 *insert = j; 307 &checklist[i][3]);
308 } 308 insert = SDL_strchr(drive, '?');
309 switch (CheckDrive(drive, &stbuf)) { 309 if (insert != NULL) {
310 /* Drive exists and is a CD-ROM */ 310 *insert = j;
311 case 1: 311 }
312 AddDrive(drive, &stbuf); 312 switch (CheckDrive(drive, &stbuf)) {
313 break; 313 /* Drive exists and is a CD-ROM */
314 /* Drive exists, but isn't a CD-ROM */ 314 case 1:
315 case 0: 315 AddDrive(drive, &stbuf);
316 break; 316 break;
317 /* Drive doesn't exist */ 317 /* Drive exists, but isn't a CD-ROM */
318 case -1: 318 case 0:
319 exists = 0; 319 break;
320 break; 320 /* Drive doesn't exist */
321 } 321 case -1:
322 } 322 exists = 0;
323 } else { 323 break;
324 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", checklist[i]); 324 }
325 if ( CheckDrive(drive, &stbuf) > 0 ) { 325 }
326 AddDrive(drive, &stbuf); 326 } else {
327 } 327 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s",
328 } 328 checklist[i]);
329 } 329 if (CheckDrive(drive, &stbuf) > 0) {
330 return(0); 330 AddDrive(drive, &stbuf);
331 } 331 }
332 332 }
333 static const char *SDL_SYS_CDName(int drive) 333 }
334 { 334 return (0);
335 return(SDL_cdlist[drive]); 335 }
336 } 336
337 337 static const char *
338 static int SDL_SYS_CDOpen(int drive) 338 SDL_SYS_CDName(int drive)
339 { 339 {
340 return(open(SDL_cdlist[drive], O_RDONLY | O_NONBLOCK | O_EXCL, 0)); 340 return (SDL_cdlist[drive]);
341 } 341 }
342 342
343 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) 343 static int
344 { 344 SDL_SYS_CDOpen(int drive)
345 u_char cdb[10], buf[4], *p, *toc; 345 {
346 struct scsi_user_cdb sus; 346 return (open(SDL_cdlist[drive], O_RDONLY | O_NONBLOCK | O_EXCL, 0));
347 int i, sts, first_track, last_track, ntracks, toc_size; 347 }
348 348
349 bzero(cdb, sizeof (cdb)); 349 static int
350 cdb[0] = 0x43; /* Read TOC */ 350 SDL_SYS_CDGetTOC(SDL_CD * cdrom)
351 cdb[1] = 0x2; /* MSF */ 351 {
352 cdb[8] = 4; /* size TOC header */ 352 u_char cdb[10], buf[4], *p, *toc;
353 sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, buf, 4, &sus); 353 struct scsi_user_cdb sus;
354 if (sts < 0) 354 int i, sts, first_track, last_track, ntracks, toc_size;
355 return(-1); 355
356 first_track = buf[2]; 356 bzero(cdb, sizeof(cdb));
357 last_track = buf[3]; 357 cdb[0] = 0x43; /* Read TOC */
358 ntracks = last_track - first_track + 1; 358 cdb[1] = 0x2; /* MSF */
359 cdrom->numtracks = ntracks; 359 cdb[8] = 4; /* size TOC header */
360 toc_size = 4 + (ntracks + 1) * 8; 360 sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, buf, 4, &sus);
361 toc = (u_char *)SDL_malloc(toc_size); 361 if (sts < 0)
362 if (toc == NULL) 362 return (-1);
363 return(-1); 363 first_track = buf[2];
364 bzero(cdb, sizeof (cdb)); 364 last_track = buf[3];
365 cdb[0] = 0x43; 365 ntracks = last_track - first_track + 1;
366 cdb[1] = 0x2; 366 cdrom->numtracks = ntracks;
367 cdb[6] = first_track; 367 toc_size = 4 + (ntracks + 1) * 8;
368 cdb[7] = toc_size >> 8; 368 toc = (u_char *) SDL_malloc(toc_size);
369 cdb[8] = toc_size & 0xff; 369 if (toc == NULL)
370 sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, toc, toc_size, 370 return (-1);
371 &sus); 371 bzero(cdb, sizeof(cdb));
372 if (sts < 0) 372 cdb[0] = 0x43;
373 { 373 cdb[1] = 0x2;
374 SDL_free(toc); 374 cdb[6] = first_track;
375 return(-1); 375 cdb[7] = toc_size >> 8;
376 } 376 cdb[8] = toc_size & 0xff;
377 377 sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, toc, toc_size,
378 for (i = 0, p = toc+4; i <= ntracks; i++, p+= 8) 378 &sus);
379 { 379 if (sts < 0) {
380 if (i == ntracks) 380 SDL_free(toc);
381 cdrom->track[i].id = 0xAA; /* Leadout */ 381 return (-1);
382 else 382 }
383 cdrom->track[i].id = first_track + i; 383
384 if (p[1] & 0x20) 384 for (i = 0, p = toc + 4; i <= ntracks; i++, p += 8) {
385 cdrom->track[i].type = SDL_DATA_TRACK; 385 if (i == ntracks)
386 else 386 cdrom->track[i].id = 0xAA; /* Leadout */
387 cdrom->track[i].type = SDL_AUDIO_TRACK; 387 else
388 cdrom->track[i].offset = msf_to_frame(p[5], p[6], p[7]); 388 cdrom->track[i].id = first_track + i;
389 cdrom->track[i].length = 0; 389 if (p[1] & 0x20)
390 if (i > 0) 390 cdrom->track[i].type = SDL_DATA_TRACK;
391 cdrom->track[i-1].length = cdrom->track[i].offset - 391 else
392 cdrom->track[i-1].offset; 392 cdrom->track[i].type = SDL_AUDIO_TRACK;
393 } 393 cdrom->track[i].offset = msf_to_frame(p[5], p[6], p[7]);
394 SDL_free(toc); 394 cdrom->track[i].length = 0;
395 return(0); 395 if (i > 0)
396 } 396 cdrom->track[i - 1].length = cdrom->track[i].offset -
397 cdrom->track[i - 1].offset;
398 }
399 SDL_free(toc);
400 return (0);
401 }
397 402
398 /* Get CD-ROM status */ 403 /* Get CD-ROM status */
399 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) 404 static CDstatus
400 { 405 SDL_SYS_CDStatus(SDL_CD * cdrom, int *position)
401 CDstatus status; 406 {
402 u_char cdb[10], buf[16]; 407 CDstatus status;
403 int sts; 408 u_char cdb[10], buf[16];
404 struct scsi_user_cdb sus; 409 int sts;
405 410 struct scsi_user_cdb sus;
406 bzero(cdb, sizeof (cdb)); 411
407 cdb[0] = 0x42; /* read subq */ 412 bzero(cdb, sizeof(cdb));
408 cdb[1] = 0x2; /* MSF */ 413 cdb[0] = 0x42; /* read subq */
409 cdb[2] = 0x40; /* q channel */ 414 cdb[1] = 0x2; /* MSF */
410 cdb[3] = 1; /* current pos */ 415 cdb[2] = 0x40; /* q channel */
411 cdb[7] = sizeof (buf) >> 8; 416 cdb[3] = 1; /* current pos */
412 cdb[8] = sizeof (buf) & 0xff; 417 cdb[7] = sizeof(buf) >> 8;
413 sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, buf, sizeof (buf), 418 cdb[8] = sizeof(buf) & 0xff;
414 &sus); 419 sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, buf, sizeof(buf),
415 if (sts < 0) 420 &sus);
416 return(-1); 421 if (sts < 0)
417 if (sts) 422 return (-1);
418 { 423 if (sts) {
419 if (TestForMedium(cdrom->id) == 0) 424 if (TestForMedium(cdrom->id) == 0)
420 status = CD_TRAYEMPTY; 425 status = CD_TRAYEMPTY;
421 else 426 else
422 status = CD_ERROR; 427 status = CD_ERROR;
423 } 428 } else {
424 else 429 switch (buf[1]) {
425 { 430 case 0x11:
426 switch (buf[1]) 431 status = CD_PLAYING;
427 { 432 break;
428 case 0x11: 433 case 0x12:
429 status = CD_PLAYING; 434 status = CD_PAUSED;
430 break; 435 break;
431 case 0x12: 436 case 0x13:
432 status = CD_PAUSED; 437 case 0x14:
433 break; 438 case 0x15:
434 case 0x13: 439 status = CD_STOPPED;
435 case 0x14: 440 break;
436 case 0x15: 441 default:
437 status = CD_STOPPED; 442 status = CD_ERROR;
438 break; 443 break;
439 default: 444 }
440 status = CD_ERROR; 445 }
441 break; 446 if (position) {
442 } 447 if (status == CD_PLAYING || (status == CD_PAUSED))
443 } 448 *position = msf_to_frame(buf[9], buf[10], buf[11]);
444 if (position) 449 else
445 { 450 *position = 0;
446 if ( status == CD_PLAYING || (status == CD_PAUSED) ) 451 }
447 *position = msf_to_frame(buf[9], buf[10], buf[11]); 452 return (status);
448 else 453 }
449 *position = 0;
450 }
451 return(status);
452 }
453 454
454 /* Start play */ 455 /* Start play */
455 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) 456 static int
456 { 457 SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length)
457 u_char cdb[10]; 458 {
458 int sts, minute, second, frame, eminute, esecond, eframe; 459 u_char cdb[10];
459 struct scsi_user_cdb sus; 460 int sts, minute, second, frame, eminute, esecond, eframe;
460 461 struct scsi_user_cdb sus;
461 bzero(cdb, sizeof(cdb)); 462
462 cdb[0] = 0x47; /* Play */ 463 bzero(cdb, sizeof(cdb));
463 frame_to_msf(start, &minute, &second, &frame); 464 cdb[0] = 0x47; /* Play */
464 frame_to_msf(start + length, &eminute, &esecond, &eframe); 465 frame_to_msf(start, &minute, &second, &frame);
465 cdb[3] = minute; 466 frame_to_msf(start + length, &eminute, &esecond, &eframe);
466 cdb[4] = second; 467 cdb[3] = minute;
467 cdb[5] = frame; 468 cdb[4] = second;
468 cdb[6] = eminute; 469 cdb[5] = frame;
469 cdb[7] = esecond; 470 cdb[6] = eminute;
470 cdb[8] = eframe; 471 cdb[7] = esecond;
471 sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, 0, 0, &sus); 472 cdb[8] = eframe;
472 return(sts); 473 sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, 0, 0, &sus);
473 } 474 return (sts);
474 475 }
475 static int 476
476 pauseresume(SDL_CD *cdrom, int flag) 477 static int
477 { 478 pauseresume(SDL_CD * cdrom, int flag)
478 u_char cdb[10]; 479 {
479 struct scsi_user_cdb sus; 480 u_char cdb[10];
480 481 struct scsi_user_cdb sus;
481 bzero(cdb, sizeof (cdb)); 482
482 cdb[0] = 0x4b; 483 bzero(cdb, sizeof(cdb));
483 cdb[8] = flag & 0x1; 484 cdb[0] = 0x4b;
484 return(scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, 0, 0, &sus)); 485 cdb[8] = flag & 0x1;
485 } 486 return (scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, 0, 0, &sus));
487 }
486 488
487 /* Pause play */ 489 /* Pause play */
488 static int SDL_SYS_CDPause(SDL_CD *cdrom) 490 static int
489 { 491 SDL_SYS_CDPause(SDL_CD * cdrom)
490 return(pauseresume(cdrom, 0)); 492 {
493 return (pauseresume(cdrom, 0));
491 } 494 }
492 495
493 /* Resume play */ 496 /* Resume play */
494 static int SDL_SYS_CDResume(SDL_CD *cdrom) 497 static int
495 { 498 SDL_SYS_CDResume(SDL_CD * cdrom)
496 return(pauseresume(cdrom, 1)); 499 {
500 return (pauseresume(cdrom, 1));
497 } 501 }
498 502
499 /* Stop play */ 503 /* Stop play */
500 static int SDL_SYS_CDStop(SDL_CD *cdrom) 504 static int
501 { 505 SDL_SYS_CDStop(SDL_CD * cdrom)
502 u_char cdb[6]; 506 {
503 struct scsi_user_cdb sus; 507 u_char cdb[6];
504 508 struct scsi_user_cdb sus;
505 bzero(cdb, sizeof (cdb)); 509
506 cdb[0] = 0x1b; /* stop */ 510 bzero(cdb, sizeof(cdb));
507 cdb[1] = 1; /* immediate */ 511 cdb[0] = 0x1b; /* stop */
508 return(scsi_cmd(cdrom->id, (cdb_t *)cdb, 6, SUC_READ, 0, 0, &sus)); 512 cdb[1] = 1; /* immediate */
513 return (scsi_cmd(cdrom->id, (cdb_t *) cdb, 6, SUC_READ, 0, 0, &sus));
509 } 514 }
510 515
511 /* Eject the CD-ROM */ 516 /* Eject the CD-ROM */
512 static int SDL_SYS_CDEject(SDL_CD *cdrom) 517 static int
513 { 518 SDL_SYS_CDEject(SDL_CD * cdrom)
514 u_char cdb[6]; 519 {
515 struct scsi_user_cdb sus; 520 u_char cdb[6];
516 521 struct scsi_user_cdb sus;
517 bzero(cdb, sizeof (cdb)); 522
518 cdb[0] = 0x1b; /* stop */ 523 bzero(cdb, sizeof(cdb));
519 cdb[1] = 1; /* immediate */ 524 cdb[0] = 0x1b; /* stop */
520 cdb[4] = 2; /* eject */ 525 cdb[1] = 1; /* immediate */
521 return(scsi_cmd(cdrom->id, (cdb_t *)cdb, 6, SUC_READ, 0, 0, &sus)); 526 cdb[4] = 2; /* eject */
527 return (scsi_cmd(cdrom->id, (cdb_t *) cdb, 6, SUC_READ, 0, 0, &sus));
522 } 528 }
523 529
524 /* Close the CD-ROM handle */ 530 /* Close the CD-ROM handle */
525 static void SDL_SYS_CDClose(SDL_CD *cdrom) 531 static void
526 { 532 SDL_SYS_CDClose(SDL_CD * cdrom)
527 close(cdrom->id); 533 {
528 } 534 close(cdrom->id);
529 535 }
530 void SDL_SYS_CDQuit(void) 536
531 { 537 void
532 int i; 538 SDL_SYS_CDQuit(void)
533 539 {
534 if ( SDL_numcds > 0 ) { 540 int i;
535 for ( i=0; i<SDL_numcds; ++i ) { 541
536 SDL_free(SDL_cdlist[i]); 542 if (SDL_numcds > 0) {
537 } 543 for (i = 0; i < SDL_numcds; ++i) {
538 } 544 SDL_free(SDL_cdlist[i]);
539 SDL_numcds = 0; 545 }
546 }
547 SDL_numcds = 0;
540 } 548 }
541 549
542 #endif /* SDL_CDROM_BSDI */ 550 #endif /* SDL_CDROM_BSDI */
551 /* vi: set ts=4 sw=4 expandtab: */