NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/38204: Linux CDROMREADRAW ioctl is not emulated



>Number:         38204
>Category:       kern
>Synopsis:       Linux CDROMREADRAW ioctl is not emulated
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Mar 09 11:20:00 +0000 2008
>Originator:     Sergey Svishchev
>Release:        4.0
>Organization:
>Environment:
>Description:
Linux provides CDROMREADRAW ioctl to read data from CD in raw mode (2352 
bytes).  ePSXe (Sony Playstation emulator, Linux binary is available) uses it 
to run games from original discs.
>How-To-Repeat:

>Fix:
--- sys/compat/linux/common/linux_cdrom.c       12 Jun 2006 00:42:18 -0000      
1.20
+++ sys/compat/linux/common/linux_cdrom.c       9 Mar 2008 11:02:49 -0000
@@ -45,6 +45,7 @@
 #include <sys/proc.h>
 #include <sys/cdio.h>
 #include <sys/dvdio.h>
+#include <sys/scsiio.h>
 #include <sys/malloc.h>
 
 #include <sys/sa.h>
@@ -71,6 +72,7 @@
  * XXX from dev/scsipi/cd.c
  */
 #define MAXTRACK 99
+#define RAW_SECTOR 2352
 
 static int
 bsd_to_linux_msf_lba(unsigned address_format, union msf_lba *bml,
@@ -101,7 +103,7 @@
        } */ *uap;
        register_t *retval;
 {
-       int error, idata;
+       int error, idata, rrlba;
        u_long com, ncom;
        caddr_t sg;
        struct file *fp;
@@ -142,6 +144,7 @@
                struct cd_sub_channel_info tt_info;
                struct ioc_read_subchannel tt_subchannel;
                struct ioc_vol tt_vol;
+               struct scsireq tt_sc;
        } *u2;
 
 #define        t_blocks u2->tt_blocks
@@ -153,6 +156,7 @@
 #define        t_info u2->tt_info
 #define        t_subchannel u2->tt_subchannel
 #define        t_vol u2->tt_vol
+#define        t_sc u2->tt_sc
 
        struct cd_toc_entry *entry;
        struct cd_sub_channel_info *info;
@@ -469,6 +473,32 @@
                error = copyout(&dai, SCARG(uap, data), sizeof dai);
                break;
 
+       case LINUX_CDROMREADRAW:
+               error = copyin(SCARG(uap, data), &l_msf, sizeof l_msf);
+               if (error)
+                       break;
+
+               rrlba = (((l_msf.cdmsf_min0 * 60) + l_msf.cdmsf_sec0) * 75 + 
l_msf.cdmsf_frame0) - 150;
+
+               memset(&t_sc, 0, sizeof(t_sc));
+               t_sc.cmd[0] = 0xBE;     /* READ CD */
+               t_sc.cmd[1] = 0;        /* don't check sector type */
+               t_sc.cmd[2] = (rrlba >> 24) & 0xff;
+               t_sc.cmd[3] = (rrlba >> 16) & 0xff;
+               t_sc.cmd[4] = (rrlba >>  8) & 0xff;
+               t_sc.cmd[5] =  rrlba      & 0xff;
+               t_sc.cmd[8] = 1;        /* 1 sector */
+               t_sc.cmd[9] = 0xF8;     /* everything */
+               t_sc.cmdlen = 12;
+               t_sc.databuf = (caddr_t) SCARG(uap, data);
+               t_sc.datalen = RAW_SECTOR;
+               t_sc.senselen = 0;
+               t_sc.flags = SCCMD_READ;
+               t_sc.timeout = 15;      /* XXX */
+
+               error = ioctlf(fp, SCIOCCOMMAND, (caddr_t)&t_sc, l);
+               break;
+
 
        default:
                DPRINTF(("linux_ioctl: unimplemented ioctl %08lx\n", com));
--- sys/compat/linux/common/linux_cdrom.h       11 Dec 2005 12:20:19 -0000      
1.7
+++ sys/compat/linux/common/linux_cdrom.h       24 Feb 2008 23:41:49 -0000
@@ -56,6 +56,7 @@
 #define LINUX_CDROMMULTISESSION        0x5310  /* (struct 
linux_cdrom_multisession) */
 #define LINUX_CDROMRESET       0x5312
 #define LINUX_CDROMVOLREAD     0x5313  /* (struct linux_cdrom_volctrl) */
+#define LINUX_CDROMREADRAW     0x5314  /* (struct linux_cdrom_msf) */
 #define LINUX_CDROMPLAYBLK     0x5317  /* (struct linux_cdrom_blk) */
 #define LINUX_CDROMCLOSETRAY   0x5319  /* */
 #define LINUX_CDROM_SET_OPTIONS        0x5320  /* int */



Home | Main Index | Thread Index | Old Index