ref: aa2a222868f993d893b1448461292e95940f3aca
parent: 50899042baa76832eeead4ab35fe0d49c4dd0b85
author: Steven M. Schultz <[email protected]>
date: Thu Dec 19 10:29:53 EST 2002
* ./src/bsdi_ioctl.c, ./src/bsdi_dvd.h: updated the bsdi libdvd with Steven M. Schultz's latest changes.
--- a/src/bsdi_dvd.h
+++ b/src/bsdi_dvd.h
@@ -1,3 +1,7 @@
+/*
+ * $Id: bsdi_dvd.h,v 1.3 2002/12/19 15:29:53 sam Exp $
+*/
+
#ifndef _DVD_H_
#define _DVD_H_
@@ -224,6 +228,7 @@
#define CDROMEJECT 0x5309 /* Ejects the cdrom media */
#define CDROMCLOSETRAY 0x5319 /* Reverse of CDROMEJECT */
#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */
+#define CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */
#define CDROMREADMODE2 0x530c /* Read CDROM mode 2 data (2336 Bytes) */
#define CDROMREADMODE1 0x530d /* Read CDROM mode 1 data (2048 Bytes) */
#define CDROMREADRAW 0x5314 /* read data in raw mode (2352 bytes) */
@@ -244,6 +249,9 @@
#define CDROM_LBA 0x01 /* logical block: first frame is #0 */
#define CDROM_MSF 0x02 /* minute-second-frame: binary. not bcd here!*/
+/* bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl) */
+#define CDROM_DATA_TRACK 0x04
+
/* The leadout track is always 0xAA, regardless of # of tracks on disc */
#define CDROM_LEADOUT 0xAA
@@ -254,6 +262,17 @@
#define CDS_DRIVE_NOT_READY 3
#define CDS_DISC_OK 4
+/*
+ * Return values for CDROM_DISC_STATUS ioctl.
+ * Can also return CDS_NO_INFO and CDS_NO_DISC from above
+*/
+#define CDS_AUDIO 100
+#define CDS_DATA_1 101
+#define CDS_DATA_2 102
+#define CDS_XA_2_1 103
+#define CDS_XA_2_2 104
+#define CDS_MIXED 105
+
/* For compile compatibility only - we don't support changers */
#define CDSL_NONE ((int) (~0U>>1)-1)
#define CDSL_CURRENT ((int) (~0U>>1))
@@ -312,4 +331,14 @@
__u8 block_length_med;
__u8 block_length_lo;
};
+
+typedef struct
+{
+ int data;
+ int audio;
+ int cdi;
+ int xa;
+ int error;
+} tracktype;
+
#endif /* _DVD_H_ */
--- a/src/bsdi_ioctl.c
+++ b/src/bsdi_ioctl.c
@@ -49,8 +49,9 @@
static int scsi_cmd(int, cgc_t *);
static int cdrom_ioctl(int, u_long, void *);
static int cdrom_tray_move(int, int);
+static void cdrom_count_tracks(int, tracktype *);
static int dvd_ioctl(int, u_long, void *);
-static int debug;
+static int debug = 0;
void dvd_cdrom_debug(int flag)
{
@@ -72,9 +73,11 @@
case CDROMREADTOCENTRY:
case CDROMEJECT:
case CDROMREADRAW:
+ case CDROMREADMODE1:
case CDROMREADMODE2:
case CDROMCLOSETRAY:
case CDROM_DRIVE_STATUS:
+ case CDROM_DISC_STATUS:
return(cdrom_ioctl(fd, cmd, arg));
default:
return(ioctl(fd, cmd, arg));
@@ -401,7 +404,7 @@
static int scsi_cmd(int fd, cgc_t *cgc)
{
- int scsistatus, cdblen;
+ int i, scsistatus, cdblen;
unsigned char *cp;
struct scsi_user_cdb suc;
@@ -427,12 +430,14 @@
if (scsistatus && debug)
{
cp = suc.suc_sus.sus_sense;
- fprintf(stderr,"scsistatus = %x cmd = %x\n",
- scsistatus, cgc->cdb[0]);
- fprintf(stderr, "sense %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
- cp[0], cp[1], cp[2], cp[3], cp[4], cp[5],
- cp[6], cp[7], cp[8], cp[9], cp[10], cp[11],
- cp[12], cp[13], cp[14], cp[15]);
+ fprintf(stderr,"scsistatus = %x cdb =",
+ scsistatus);
+ for (i = 0; i < cdblen; i++)
+ fprintf(stderr, " %x", cgc->cdb[i]);
+ fprintf(stderr, "\nsense =");
+ for (i = 0; i < 16; i++)
+ fprintf(stderr, " %x", cp[i]);
+ fprintf(stderr, "\n");
}
if (cgc->sus)
bcopy(&suc.suc_sus, cgc->sus, sizeof (struct scsi_user_sense));
@@ -456,7 +461,7 @@
errno = ret;
return(ret ? -1 : 0);
case DVD_AUTH:
- ret = dvd_do_auth (fd, (dvd_authinfo *)arg);
+ ret = dvd_do_auth(fd, (dvd_authinfo *)arg);
if (ret)
errno = ret;
return(ret ? -1 : 0);
@@ -596,11 +601,35 @@
* This sucks but emulates the expected behaviour. Instead of the return
* value being the actual status a success/fail indicator should have been
* returned and the 3rd arg to the ioctl should have been an 'int *' to update
- * with the actual status.
+ * with the actual status. Both the drive and disc status ioctl calls are
+ * similarily braindamaged.
*/
case CDROM_DRIVE_STATUS:
+ return(CDS_NO_INFO); /* XXX */
+ case CDROM_DISC_STATUS:
+ {
+ tracktype tracks;
+ int cnt;
+
+ cdrom_count_tracks(fd, &tracks);
+ if (tracks.error)
+ return(tracks.error);
+ if (tracks.audio > 0)
+ {
+ cnt = tracks.data + tracks.cdi + tracks.xa;
+ if (cnt == 0)
+ return(CDS_AUDIO);
+ else
+ return(CDS_MIXED);
+ }
+ if (tracks.cdi)
+ return(CDS_XA_2_2);
+ if (tracks.xa)
+ return(CDS_XA_2_1);
+ if (tracks.data)
+ return(CDS_DATA_1);
return(CDS_NO_INFO);
- break;
+ }
}
errno = ret;
return(ret ? -1 : 0);
@@ -657,6 +686,49 @@
cgc->cdb[9] = 0x10;
}
return(scsi_cmd(fd, cgc));
+ }
+
+static void cdrom_count_tracks(int fd, tracktype *tracks)
+ {
+ struct cdrom_tochdr header;
+ struct cdrom_tocentry entry;
+ int ret, i;
+
+ bzero(tracks, sizeof (*tracks));
+ ret = cdrom_ioctl(fd, CDROMREADTOCHDR, &header);
+/*
+ * This whole business is a crock anyhow so we don't bother distinguishing
+ * between no media, drive not ready, etc and on any error just say we have
+ * no info.
+*/
+ if (ret)
+ {
+ tracks->error = CDS_NO_INFO;
+ return;
+ }
+
+ entry.cdte_format = CDROM_MSF;
+ for (i = header.cdth_trk0; i <= header.cdth_trk1; i++)
+ {
+ entry.cdte_track = i;
+ if (cdrom_ioctl(fd, CDROMREADTOCENTRY, &entry))
+ {
+ tracks->error = CDS_NO_INFO;
+ return;
+ }
+ if (entry.cdte_ctrl & CDROM_DATA_TRACK)
+ {
+ if (entry.cdte_format == 0x10)
+ tracks->cdi++;
+ else if (entry.cdte_format == 0x20)
+ tracks->xa++;
+ else
+ tracks->data++;
+ }
+ else
+ tracks->audio++;
+ }
+ return;
}
static int cdrom_tray_move(int fd, int flag)