Mercurial > sdl-ios-xcode
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: */ |