2 * $Id: plat_news.c,v 1.7 1999/03/07 08:36:40 dirk Exp $
4 * This file is part of WorkMan, the civilized CD player library
5 * (c) 1991-1997 by Steven Grimm (original author)
6 * (c) by Dirk Försterling (current 'author' = maintainer)
7 * The maintainer can be contacted by his e-mail address:
8 * milliByte@DeathsDoor.com
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the Free
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * Sony NEWS-specific drive control routines.
28 #if defined( __sony_news) || defined(sony_news)
30 static char plat_news_id
[] = "$Id: plat_news.c,v 1.7 1999/03/07 08:36:40 dirk Exp $";
37 #include <sys/types.h>
38 #include <sys/param.h>
42 #include "include/wm_config.h"
43 #include "include/wm_struct.h"
45 #define WM_MSG_CLASS WM_MSG_CLASS_PLATFORM
50 extern char *cd_device
;
51 extern int intermittent_dev
;
57 * Initialize the drive. A no-op for the generic driver.
67 * Get the number of tracks on the CD.
70 gen_get_trackcount(d
, tracks
)
74 struct CD_Capacity cc
;
76 if (CD_GetCapacity(d
->fd
, &cc
))
79 *tracks
= cc
.etrack
- 1;
84 * Get the start time and mode (data or audio) of a track.
87 gen_get_trackinfo(d
, track
, data
, startframe
)
89 int track
, *data
, *startframe
;
91 struct CD_TOCinfo hdr
;
92 struct CD_TOCdata ent
;
97 if (CD_ReadTOC(d
->fd
, &hdr
))
100 *data
= (ent
.control
& 4) ? 1 : 0;
101 *startframe
= ent
.baddr
;
107 * Get the number of frames on the CD.
110 gen_get_cdlen(d
, frames
)
116 if ((d
->get_trackcount
)(d
, &tmp
))
119 return (gen_get_trackinfo(d
, tmp
+ 1, &tmp
, frames
));
123 * Get the current status of the drive: the current play mode, the absolute
124 * position from start of disc (in frames), and the current track and index
125 * numbers if the CD is playing or paused.
128 gen_get_drive_status(d
, oldmode
, mode
, pos
, track
, index
)
130 enum wm_cd_modes oldmode
, *mode
;
131 int *pos
, *track
, *index
;
135 /* If we can't get status, the CD is ejected, so default to that. */
136 *mode
= WM_CDM_EJECTED
;
138 /* Is the device open? */
141 switch (wmcd_open(d
)) {
150 /* Disc is ejected. Close the device. */
151 if (CD_GetStatus(d
->fd
, &sc
))
167 if (oldmode
== WM_CDM_PLAYING
|| oldmode
== WM_CDM_PAUSED
)
169 *mode
= WM_CDM_PAUSED
;
175 *mode
= WM_CDM_STOPPED
;
179 if (oldmode
== WM_CDM_PLAYING
)
181 *mode
= WM_CDM_TRACK_DONE
; /* waiting for next track. */
187 *mode
= WM_CDM_STOPPED
;
195 * Set the volume level for the left and right channels. Their values
196 * range from 0 to 100.
199 gen_set_volume(d
, left
, right
)
203 /* NEWS can't adjust volume! */
220 * Resume playing the CD (assuming it was paused.)
244 * Play the CD from one position to another (both in frames.)
247 gen_play(d
, start
, end
)
251 struct CD_PlayAddr msf
;
253 msf
.addrmode
= CD_MSF
;
254 msf
.addr
.msf
.startmsf
.min
= start
/ (60*75);
255 msf
.addr
.msf
.startmsf
.sec
= (start
% (60*75)) / 75;
256 msf
.addr
.msf
.startmsf
.frame
= start
% 75;
257 msf
.addr
.msf
.endmsf
.min
= end
/ (60*75);
258 msf
.addr
.msf
.endmsf
.sec
= (end
% (60*75)) / 75;
259 msf
.addr
.msf
.endmsf
.frame
= end
% 75;
261 if (CD_Play(d
->fd
, &msf
))
263 printf("wm_cd_play_chunk(%d,%d)\n",start
,end
);
264 printf("msf = %d:%d:%d %d:%d:%d\n",
265 msf
.addr
.msf
.startmsf
.min
,
266 msf
.addr
.msf
.startmsf
.sec
,
267 msf
.addr
.msf
.startmsf
.frame
,
268 msf
.addr
.msf
.endmsf
.min
,
269 msf
.addr
.msf
.endmsf
.sec
,
270 msf
.addr
.msf
.endmsf
.frame
);
279 * Eject the current CD, if there is one.
288 if (fstat(d
->fd
, &stbuf
) != 0)
291 /* Is this a mounted filesystem? */
292 if (ustat(stbuf
.st_rdev
, &ust
) == 0)
295 if (CD_AutoEject(d
->fd
))
298 /* Close the device if it needs to vanish. */
299 if (intermittent_dev
)
308 /*----------------------------------------*
311 * Please edit and send changes to
312 * milliByte@DeathsDoor.com
313 *----------------------------------------*/
315 int gen_closetray(struct wm_drive
*d
)
321 return(wmcd_reopen(d
));
326 /* Always succeed if the drive can't close */
328 #endif /* CAN_CLOSE */
329 } /* gen_closetray() */
333 * Close the CD device.
347 * Read the initial volume from the drive, if available. Each channel
348 * ranges from 0 to 100, with -1 indicating data not available.
351 gen_get_volume(d
, left
, right
)
355 /* Suns, HPs, Linux, NEWS can't read the volume; oh well */
362 * Pass SCSI commands to the device.
365 wm_scsi(d
, cdb
, cdblen
, buf
, buflen
, getreply
)
367 unsigned char *cdb
, *buf
;
368 int cdblen
, buflen
, getreply
;
370 /* NEWS can't do SCSI passthrough... or can it? */
375 * Open the CD device and figure out what kind of drive is attached.
382 static int warned
= 0;
383 char vendor
[32] = WM_STR_GENVENDOR
;
384 char model
[32] = WM_STR_GENMODEL
;
385 char rev
[32] = WM_STR_GENREV
;
387 if (d
->fd
>= 0) /* Device already open? */
390 intermittent_dev
= 1;
391 if (cd_device
== NULL
)
392 cd_device
= DEFAULT_CD_DEVICE
;
394 if ((d
->fd
= CD_Open(cd_device
, 0)) < 0)
396 /* Solaris 2.2 volume manager moves links around */
397 if (errno
== ENOENT
&& intermittent_dev
)
404 char realname
[MAXPATHLEN
];
406 if (realpath(cd_device
, realname
) == NULL
)
413 "As root, please run\n\nchmod 666 %s\n\n%s\n", realname
,
414 "to give yourself permission to access the CD-ROM device.");
418 else if (errno
!= EIO
) /* defined at top */
424 /* No CD in drive. */
431 fprintf(stderr
, "Thank you.\n");
434 /* Now fill in the relevant parts of the wm_drive structure. */
437 /* Figure out the drive type, if possible */
438 wm_scsi_get_drive_type(d
, vendor
, model
, rev
);
439 *d
= *(find_drive_struct(vendor
, model
, rev
));
440 wm_drive_settype(vendor
, model
, rev
);
450 * Re-Open the device if it is open.
453 wmcd_reopen( struct wm_drive
*d
)
458 wm_lib_message(WM_MSG_LEVEL_DEBUG
|WM_MSG_CLASS
, "wmcd_reopen ");
459 if (d
->fd
>= 0) /* Device really open? */
461 wm_lib_message(WM_MSG_LEVEL_DEBUG
|WM_MSG_CLASS
, "closes the device and ");
462 status
= close( d
->fd
); /* close it! */
463 /* we know, that the file is closed, do we? */
467 wm_lib_message(WM_MSG_LEVEL_DEBUG
|WM_MSG_CLASS
, "calls wmcd_open()\n");
468 status
= wmcd_open( d
); /* open it as usual */
470 } while ( status
!= 0 );
472 } /* wmcd_reopen() */