summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux/linux_ioctl.c
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>1999-08-13 14:44:13 +0000
committermarcel <marcel@FreeBSD.org>1999-08-13 14:44:13 +0000
commita9a84c7c98d514841c9f5353e6d5441c4ed2de62 (patch)
tree5a59089d411271936d97532500b0f0891bb264d2 /sys/compat/linux/linux_ioctl.c
parent8a073373def246df977f4e46302ba3a3a6e2a05f (diff)
downloadFreeBSD-src-a9a84c7c98d514841c9f5353e6d5441c4ed2de62.zip
FreeBSD-src-a9a84c7c98d514841c9f5353e6d5441c4ed2de62.tar.gz
Implementation of the CDROMSUBCHNL ioctl.
Diffstat (limited to 'sys/compat/linux/linux_ioctl.c')
-rw-r--r--sys/compat/linux/linux_ioctl.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index 1c79c6c..da1abdc 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: linux_ioctl.c,v 1.35 1999/07/08 16:15:19 marcel Exp $
+ * $Id: linux_ioctl.c,v 1.36 1999/07/17 08:24:57 marcel Exp $
*/
#include <sys/param.h>
@@ -49,6 +49,7 @@
#include <i386/linux/linux.h>
#include <i386/linux/linux_proto.h>
+#include <i386/linux/linux_util.h>
#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
@@ -484,6 +485,18 @@ struct linux_cdrom_tocentry
u_char cdte_datamode;
};
+struct linux_cdrom_subchnl
+{
+ u_char cdsc_format;
+ u_char cdsc_audiostatus;
+ u_char cdsc_adr:4;
+ u_char cdsc_ctrl:4;
+ u_char cdsc_trk;
+ u_char cdsc_ind;
+ union linux_cdrom_addr cdsc_absaddr;
+ union linux_cdrom_addr cdsc_reladdr;
+};
+
#if 0
static void
linux_to_bsd_msf_lba(u_char address_format,
@@ -512,6 +525,20 @@ bsd_to_linux_msf_lba(u_char address_format,
}
}
+static void
+set_linux_cdrom_addr(union linux_cdrom_addr *addr, int format, int lba)
+{
+ if (format == LINUX_CDROM_MSF) {
+ addr->msf.frame = lba % 75;
+ lba /= 75;
+ lba += 2;
+ addr->msf.second = lba % 60;
+ addr->msf.minute = lba / 60;
+ }
+ else
+ addr->lba = lba;
+}
+
static unsigned dirbits[4] = { IOC_VOID, IOC_OUT, IOC_IN, IOC_INOUT };
#define SETDIR(c) (((c) & ~IOC_DIRMASK) | dirbits[args->cmd >> 30])
@@ -1184,6 +1211,43 @@ linux_ioctl(struct proc *p, struct linux_ioctl_args *args)
return error;
}
+ case LINUX_CDROMSUBCHNL: {
+ caddr_t sg;
+ struct linux_cdrom_subchnl sc;
+ struct ioc_read_subchannel bsdsc;
+ struct cd_sub_channel_info *bsdinfo;
+
+ sg = stackgap_init();
+ bsdinfo = (struct cd_sub_channel_info*)stackgap_alloc(&sg,
+ sizeof(struct cd_sub_channel_info));
+
+ bsdsc.address_format = CD_LBA_FORMAT;
+ bsdsc.data_format = CD_CURRENT_POSITION;
+ bsdsc.data_len = sizeof(struct cd_sub_channel_info);
+ bsdsc.data = bsdinfo;
+ error = (*func)(fp, CDIOCREADSUBCHANNEL, (caddr_t)&bsdsc, p);
+ if (error)
+ return error;
+
+ error = copyin((caddr_t)args->arg, (caddr_t)&sc,
+ sizeof(struct linux_cdrom_subchnl));
+ if (error)
+ return error;
+
+ sc.cdsc_audiostatus = bsdinfo->header.audio_status;
+ sc.cdsc_adr = bsdinfo->what.position.addr_type;
+ sc.cdsc_ctrl = bsdinfo->what.position.control;
+ sc.cdsc_trk = bsdinfo->what.position.track_number;
+ sc.cdsc_ind = bsdinfo->what.position.index_number;
+ set_linux_cdrom_addr(&sc.cdsc_absaddr, sc.cdsc_format,
+ bsdinfo->what.position.absaddr.lba);
+ set_linux_cdrom_addr(&sc.cdsc_reladdr, sc.cdsc_format,
+ bsdinfo->what.position.reladdr.lba);
+ error = copyout((caddr_t)&sc, (caddr_t)args->arg,
+ sizeof(struct linux_cdrom_subchnl));
+ return error;
+ }
+
}
uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n",
OpenPOWER on IntegriCloud