34
32
#include <stdlib.h>
36
34
#include <unistd.h>
38
35
#include <string.h>
39
36
#include <sys/types.h>
40
37
#include <sys/param.h>
41
38
#include <sys/socket.h>
42
39
#include <sys/stat.h>
43
40
#include <sys/wait.h>
41
/* Try to get around bug #29274 */
42
#include <linux/version.h>
44
/* this breaks the build on ia64 and s390 for example.
45
sys/types.h is already included and should provide __u64.
46
please tell where we really need this and let's try to find
47
a working #if case for everyone ... adrian@suse.de */
48
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,50)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,21) && LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
50
typedef unsigned long long __u64;
45
54
#include "include/wm_config.h"
46
55
#include "include/wm_struct.h"
119
142
wmcd_open( struct wm_drive *d )
122
static int warned = 0;
124
145
char vendor[32], model[32], rev[32];
126
if (cd_device == NULL)
127
cd_device = DEFAULT_CD_DEVICE;
130
if (d->fd >= 0) /* Device already open? */
147
if (d->cd_device == NULL)
148
d->cd_device = DEFAULT_CD_DEVICE;
151
if (d->fd >= 0) { /* Device already open? */
132
152
/* wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "wmcd_open(): [device is open (fd=%d)]\n", d->fd);*/
156
fd = open(d->cd_device, O_RDONLY | O_NONBLOCK);
157
wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "wmcd_open(): device=%s fd=%d\n", d->cd_device, fd);
136
fd = open(cd_device, O_RDONLY | O_NONBLOCK);
144
/* Hack proposed by Carey Evans, introduced by Debian maintainer :
145
* treat EIO like ENXIO since some Linux drives do never return ENXIO
146
* ENOMEDIUM is returned by Kernel 2.2.x unified drivers.
148
else if ((errno != ENXIO) && (errno != EIO) && (errno != ENOMEDIUM))
153
/* No CD in drive. */
158
#ifdef LINUX_SCSI_PASSTHROUGH
162
/* Now fill in the relevant parts of the wm_drive structure. */
166
* See if we can do digital audio.
168
#if defined(BUILD_CDDA)
169
if(d->cdda && gen_cdda_init(d)) {
170
wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "wmcd_open(): failed in gen_cdda_init\n");
159
176
/* Can we figure out the drive type? */
160
retval = wm_scsi_get_drive_type(d, vendor, model, rev);
161
if (retval == WM_ERR_SCSI_INQUIRY_FAILED)
162
wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "wmcd_open(): After failed inquiry\n");
165
*d = *(find_drive_struct(vendor, model, rev));
166
wm_drive_settype(vendor, model, rev);
177
if (wm_scsi_get_drive_type(d, vendor, model, rev)) {
178
wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "wmcd_open(): inquiry failed\n");
179
strcpy(vendor, "Generic");
180
strcpy(model, "drive type");
184
if(find_drive_struct(vendor, model, rev) < 0) {
189
if(d->proto->gen_init)
190
return (d->proto->gen_init)(d);
171
193
} /* wmcd_open() */
328
359
* numbers if the CD is playing or paused.
329
360
*--------------------------------------------------------------------------*/
331
gen_get_drive_status( struct wm_drive *d, enum wm_cd_modes oldmode,
332
enum wm_cd_modes *mode, int *pos, int *track, int *index )
362
gen_get_drive_status( struct wm_drive *d, int oldmode,
363
int *mode, int *pos, int *track, int *ind )
334
struct cdrom_subchnl sc;
365
struct cdrom_subchnl sc;
336
368
#ifdef SBPCD_HACK
337
369
static int prevpos = 0;
340
/* If we can't get status, the CD is ejected, so default to that. */
341
*mode = WM_CDM_EJECTED;
343
373
/* Is the device open? */
346
switch (wmcd_open(d))
376
if(ret < 0) /* error */
381
*mode = WM_CDM_UNKNOWN;
356
386
/* Try to get rid of the door locking */
357
387
/* Don't care about return value. If it */
358
388
/* works - fine. If not - ... */
359
ioctl( d->fd, CDROM_LOCKDOOR, 0 );
389
ioctl(d->fd, CDROM_LOCKDOOR, 0);
391
*mode = WM_CDM_UNKNOWN;
361
393
sc.cdsc_format = CDROM_MSF;
363
if (ioctl(d->fd, CDROMSUBCHNL, &sc))
395
#if defined(BUILD_CDDA)
397
if(!cdda_get_drive_status(d, oldmode, mode, pos, track, ind)) {
398
if(*mode == WM_CDM_STOPPED)
399
*mode = WM_CDM_UNKNOWN; /* dont believe */
403
if(!ioctl(d->fd, CDROMSUBCHNL, &sc)) {
404
switch (sc.cdsc_audiostatus) {
405
case CDROM_AUDIO_PLAY:
406
*mode = WM_CDM_PLAYING;
407
*track = sc.cdsc_trk;
409
*pos = sc.cdsc_absaddr.msf.minute * 60 * 75 +
410
sc.cdsc_absaddr.msf.second * 75 +
411
sc.cdsc_absaddr.msf.frame;
413
if( *pos < prevpos ) {
414
if( (prevpos - *pos) < 75 ) {
415
*mode = WM_CDM_TRACK_DONE;
423
case CDROM_AUDIO_PAUSED:
424
if (oldmode == WM_CDM_PLAYING || oldmode == WM_CDM_PAUSED) {
425
*mode = WM_CDM_PAUSED;
426
*track = sc.cdsc_trk;
428
*pos = sc.cdsc_absaddr.msf.minute * 60 * 75 +
429
sc.cdsc_absaddr.msf.second * 75 +
430
sc.cdsc_absaddr.msf.frame;
432
*mode = WM_CDM_STOPPED;
435
case CDROM_AUDIO_NO_STATUS:
436
*mode = WM_CDM_STOPPED;
439
case CDROM_AUDIO_COMPLETED:
440
*mode = WM_CDM_TRACK_DONE; /* waiting for next track. */
443
case CDROM_AUDIO_INVALID: /**/
445
*mode = WM_CDM_UNKNOWN;
366
switch (sc.cdsc_audiostatus) {
367
case CDROM_AUDIO_PLAY:
368
*mode = WM_CDM_PLAYING;
369
*track = sc.cdsc_trk;
370
*index = sc.cdsc_ind;
371
*pos = sc.cdsc_absaddr.msf.minute * 60 * 75 +
372
sc.cdsc_absaddr.msf.second * 75 +
373
sc.cdsc_absaddr.msf.frame;
377
if( (prevpos - *pos) < 75 )
379
*mode = WM_CDM_TRACK_DONE;
387
case CDROM_AUDIO_PAUSED:
388
case CDROM_AUDIO_NO_STATUS:
389
case CDROM_AUDIO_INVALID: /**/
390
if (oldmode == WM_CDM_PLAYING || oldmode == WM_CDM_PAUSED)
392
*mode = WM_CDM_PAUSED;
393
*track = sc.cdsc_trk;
394
*index = sc.cdsc_ind;
395
*pos = sc.cdsc_absaddr.msf.minute * 60 * 75 +
396
sc.cdsc_absaddr.msf.second * 75 +
397
sc.cdsc_absaddr.msf.frame;
450
if(WM_CDS_NO_DISC(*mode)) {
451
/* verify status of drive */
452
ret = ioctl(d->fd, CDROM_DRIVE_STATUS, 0/* slot */);
453
if(ret == CDS_DISC_OK)
454
ret = ioctl(d->fd, CDROM_DISC_STATUS, 0);
457
*mode = WM_CDM_NO_DISC;
460
*mode = WM_CDM_EJECTED;
400
464
*mode = WM_CDM_STOPPED;
403
case CDROM_AUDIO_COMPLETED:
404
*mode = WM_CDM_TRACK_DONE; /* waiting for next track. */
408
*mode = WM_CDM_UNKNOWN;
466
case CDS_DRIVE_NOT_READY:
473
*mode = WM_CDM_UNKNOWN;
413
478
} /* gen_get_drive_status */
476
543
msf.cdmsf_sec1 = (end % (60*75)) / 75;
477
544
msf.cdmsf_frame1 = end % 75;
479
if (ioctl(d->fd, CDROMPLAYMSF, &msf))
481
if (ioctl(d->fd, CDROMSTART))
483
if (ioctl(d->fd, CDROMPLAYMSF, &msf))
546
if (ioctl(d->fd, CDROMPLAYMSF, &msf)) {
547
if (ioctl(d->fd, CDROMSTART))
549
if (ioctl(d->fd, CDROMPLAYMSF, &msf))
488
554
* I hope no drive gets really confused after CDROMSTART
656
723
#ifdef CURVED_VOLUME
657
724
return ((max * max - (max - vol) * (max - vol)) *
658
(max_volume - min_volume) / (max * max) + min_volume);
725
(max_volume - min_volume) / (max * max) + min_volume);
660
727
return ((vol * (max_volume - min_volume)) / max + min_volume);
662
729
} /* scale_volume() */
732
unscale_volume( int vol, int max )
735
/* FIXME do it simpler */
736
int tmp = (((max_volume - min_volume - vol) * max * max) - (vol + min_volume));
737
return max - sqrt((tmp/(max_volume - min_volume)));
739
return (((vol - min_volume) * max) / (max_volume - min_volume));
741
} /* unscale_volume() */
664
743
/*---------------------------------------------------------------------*
665
744
* Set the volume level for the left and right channels. Their values
666
745
* range from 0 to 100.
680
761
return (ioctl(d->fd, CDROMVOLCTRL, &v));
681
762
} /* gen_set_volume() */
764
/*---------------------------------------------------------------------*
765
* Read the volume from the drive, if available. Each channel
766
* ranges from 0 to 100, with -1 indicating data not available.
767
*---------------------------------------------------------------------*/
769
gen_get_volume( struct wm_drive *d, int *left, int *right )
771
struct cdrom_volctrl v;
773
CDDARETURN(d) cdda_get_volume(d, left, right);
775
#if defined(CDROMVOLREAD)
776
if(!ioctl(d->fd, CDROMVOLREAD, &v)) {
777
*left = unscale_volume((v.channel0 + v.channel2)/2, 100);
778
*right = unscale_volume((v.channel1 + v.channel3)/2, 100);
781
/* Suns, HPs, Linux, NEWS can't read the volume; oh well */
785
} /* gen_get_volume() */
683
787
/*------------------------------------------------------------------------*
684
788
* gen_get_cdtext(drive, buffer, lenght)
696
800
return wm_scsi_get_cdtext(d, pp_buffer, p_buffer_lenght);
697
801
} /* gen_get_cdtext() */
699
/*---------------------------------------------------------------------*
700
* Read the initial volume from the drive, if available. Each channel
701
* ranges from 0 to 100, with -1 indicating data not available.
702
*---------------------------------------------------------------------*/
704
gen_get_volume( struct wm_drive *d, int *left, int *right )
706
#if defined(BUILD_CDDA) && defined(WMCDDA_DONE) /* { */
707
struct cdda_block blk;
711
write(cdda_slave, "G", 1);
713
read(cdda_slave, &blk, sizeof(blk));
715
*left = *right = (blk.volume * 100 + 254) / 255;
717
if (blk.balance < 110)
719
*right = (((blk.volume * blk.balance + 127) / 128) *
721
} else if (blk.balance > 146) {
722
*left = (((blk.volume * (255 - blk.balance) +
723
127) / 128) * 100 + 254) / 255;
728
/* Suns, HPs, Linux, NEWS can't read the volume; oh well */
732
} /* gen_get_volume() */
734
/*-------------------------------------------------------*
740
*-------------------------------------------------------*/
742
#ifdef BUILD_CDDA /* { */
745
* Try to initialize the CDDA slave. Returns 0 on error.
748
cdda_init( struct wm_drive *d )
750
#if defined(WMCDDA_DONE) /* { */
756
fprintf( stderr, "slave okay\n" );
758
if (socketpair(AF_UNIX, SOCK_STREAM, 0, slavefds))
760
perror("socketpair");
764
fprintf( stderr, "going to fork\n" );
768
dup2(slavefds[1], 1);
769
dup2(slavefds[1], 0);
772
/* Try the default path first. */
773
execl(cddaslave_path, cddaslave_path, cd_device, NULL);
774
/* Search $PATH if that didn't work. */
775
execlp("cddaslave", "cddaslave", cd_device, NULL);
776
perror(cddaslave_path);
787
cdda_slave = slavefds[0];
789
if (!get_ack(cdda_slave))
791
fprintf( stderr, "get_ack failed\n" );
798
#else /* BUILD_CDDA only } { */
800
* If we're not building CDDA support, don't even bother trying.
807
* Wait for an acknowledgement from the CDDA slave.
812
#if defined(WMCDDA_DONE) /* { */
813
struct cdda_block blk;
816
if (read(fd, &blk, sizeof(blk)) <= 0)
820
} while (blk.status != WMCDDA_ACK);
826
* Turn off the CDDA slave.
829
cdda_kill( struct wm_drive *d )
833
write(cdda_slave, "Q", 1);
843
* Tell the CDDA slave to set the play direction.
846
gen_set_direction( int newdir )
848
unsigned char buf[2];
854
write(cdda_slave, buf, 2);
860
* Tell the CDDA slave to set the play speed.
863
gen_set_speed( int speed )
865
unsigned char buf[2];
871
write(cdda_slave, buf, 2);
874
} /* gen_set_speed() */
877
* Tell the CDDA slave to set the loudness level.
880
gen_set_loudness( int loud )
882
unsigned char buf[2];
888
write(cdda_slave, buf, 2);
891
} /* gen_set_loudness() */
894
* Tell the CDDA slave to start (or stop) saving to a file.
897
gen_save( char *filename )
901
if (filename == NULL || filename[0] == '\0')
904
len = strlen(filename);
905
write(cdda_slave, "F", 1);
906
write(cdda_slave, &len, sizeof(len));
908
write(cdda_slave, filename, len);
912
#endif /* BUILD_CDDA } */
914
803
#endif /* __linux__ */