diff options
author | marcel <marcel@FreeBSD.org> | 2001-11-18 18:49:07 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2001-11-18 18:49:07 +0000 |
commit | 5b8e92f21c09af736937719daa00160169c0ee53 (patch) | |
tree | fc08ed5b769c0e063896581ed11effe144311cd5 /sys/compat | |
parent | f4ee56456fec1c5aeb68429b91102213a14f3049 (diff) | |
download | FreeBSD-src-5b8e92f21c09af736937719daa00160169c0ee53.zip FreeBSD-src-5b8e92f21c09af736937719daa00160169c0ee53.tar.gz |
Implement DVD-ROM ioctls.
PR: 26955
Submitted by: Boris Nikolaus (email unknown)
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/linux/linux_ioctl.c | 374 | ||||
-rw-r--r-- | sys/compat/linux/linux_ioctl.h | 87 |
2 files changed, 434 insertions, 27 deletions
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 4d129fd..83ee211 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -32,6 +32,7 @@ #include <sys/systm.h> #include <sys/sysproto.h> #include <sys/cdio.h> +#include <sys/dvdio.h> #include <sys/consio.h> #include <sys/ctype.h> #include <sys/disklabel.h> @@ -864,6 +865,131 @@ struct linux_cdrom_subchnl union linux_cdrom_addr cdsc_reladdr; }; +struct l_dvd_layer { + u_char book_version:4; + u_char book_type:4; + u_char min_rate:4; + u_char disc_size:4; + u_char layer_type:4; + u_char track_path:1; + u_char nlayers:2; + u_char track_density:4; + u_char linear_density:4; + u_char bca:1; + u_int32_t start_sector; + u_int32_t end_sector; + u_int32_t end_sector_l0; +}; + +struct l_dvd_physical { + u_char type; + u_char layer_num; + struct l_dvd_layer layer[4]; +}; + +struct l_dvd_copyright { + u_char type; + u_char layer_num; + u_char cpst; + u_char rmi; +}; + +struct l_dvd_disckey { + u_char type; + l_uint agid:2; + u_char value[2048]; +}; + +struct l_dvd_bca { + u_char type; + l_int len; + u_char value[188]; +}; + +struct l_dvd_manufact { + u_char type; + u_char layer_num; + l_int len; + u_char value[2048]; +}; + +typedef union { + u_char type; + struct l_dvd_physical physical; + struct l_dvd_copyright copyright; + struct l_dvd_disckey disckey; + struct l_dvd_bca bca; + struct l_dvd_manufact manufact; +} l_dvd_struct; + +typedef u_char l_dvd_key[5]; +typedef u_char l_dvd_challenge[10]; + +struct l_dvd_lu_send_agid { + u_char type; + l_uint agid:2; +}; + +struct l_dvd_host_send_challenge { + u_char type; + l_uint agid:2; + l_dvd_challenge chal; +}; + +struct l_dvd_send_key { + u_char type; + l_uint agid:2; + l_dvd_key key; +}; + +struct l_dvd_lu_send_challenge { + u_char type; + l_uint agid:2; + l_dvd_challenge chal; +}; + +struct l_dvd_lu_send_title_key { + u_char type; + l_uint agid:2; + l_dvd_key title_key; + l_int lba; + l_uint cpm:1; + l_uint cp_sec:1; + l_uint cgms:2; +}; + +struct l_dvd_lu_send_asf { + u_char type; + l_uint agid:2; + l_uint asf:1; +}; + +struct l_dvd_host_send_rpcstate { + u_char type; + u_char pdrc; +}; + +struct l_dvd_lu_send_rpcstate { + u_char type:2; + u_char vra:3; + u_char ucca:3; + u_char region_mask; + u_char rpc_scheme; +}; + +typedef union { + u_char type; + struct l_dvd_lu_send_agid lsa; + struct l_dvd_host_send_challenge hsc; + struct l_dvd_send_key lsk; + struct l_dvd_lu_send_challenge lsc; + struct l_dvd_send_key hsk; + struct l_dvd_lu_send_title_key lstk; + struct l_dvd_lu_send_asf lsasf; + struct l_dvd_host_send_rpcstate hrpcs; + struct l_dvd_lu_send_rpcstate lrpcs; +} l_dvd_authinfo; + static void bsd_to_linux_msf_lba(u_char af, union msf_lba *bp, union linux_cdrom_addr *lp) { @@ -890,6 +1016,186 @@ set_linux_cdrom_addr(union linux_cdrom_addr *addr, int format, int lba) } static int +linux_to_bsd_dvd_struct(l_dvd_struct *lp, struct dvd_struct *bp) +{ + bp->format = lp->type; + switch (bp->format) { + case DVD_STRUCT_PHYSICAL: + if (bp->layer_num >= 4) + return (EINVAL); + bp->layer_num = lp->physical.layer_num; + break; + case DVD_STRUCT_COPYRIGHT: + bp->layer_num = lp->copyright.layer_num; + break; + case DVD_STRUCT_DISCKEY: + bp->agid = lp->disckey.agid; + break; + case DVD_STRUCT_BCA: + case DVD_STRUCT_MANUFACT: + break; + default: + return (EINVAL); + } + return (0); +} + +static int +bsd_to_linux_dvd_struct(struct dvd_struct *bp, l_dvd_struct *lp) +{ + switch (bp->format) { + case DVD_STRUCT_PHYSICAL: { + struct dvd_layer *blp = (struct dvd_layer *)bp->data; + struct l_dvd_layer *llp = &lp->physical.layer[bp->layer_num]; + memset(llp, 0, sizeof(*llp)); + llp->book_version = blp->book_version; + llp->book_type = blp->book_type; + llp->min_rate = blp->max_rate; + llp->disc_size = blp->disc_size; + llp->layer_type = blp->layer_type; + llp->track_path = blp->track_path; + llp->nlayers = blp->nlayers; + llp->track_density = blp->track_density; + llp->linear_density = blp->linear_density; + llp->bca = blp->bca; + llp->start_sector = blp->start_sector; + llp->end_sector = blp->end_sector; + llp->end_sector_l0 = blp->end_sector_l0; + break; + } + case DVD_STRUCT_COPYRIGHT: + lp->copyright.cpst = bp->cpst; + lp->copyright.rmi = bp->rmi; + break; + case DVD_STRUCT_DISCKEY: + memcpy(lp->disckey.value, bp->data, sizeof(lp->disckey.value)); + break; + case DVD_STRUCT_BCA: + lp->bca.len = bp->length; + memcpy(lp->bca.value, bp->data, sizeof(lp->bca.value)); + break; + case DVD_STRUCT_MANUFACT: + lp->manufact.len = bp->length; + memcpy(lp->manufact.value, bp->data, + sizeof(lp->manufact.value)); + /* lp->manufact.layer_num is unused in linux (redhat 7.0) */ + break; + default: + return (EINVAL); + } + return (0); +} + +static int +linux_to_bsd_dvd_authinfo(l_dvd_authinfo *lp, int *bcode, + struct dvd_authinfo *bp) +{ + switch (lp->type) { + case LINUX_DVD_LU_SEND_AGID: + *bcode = DVDIOCREPORTKEY; + bp->format = DVD_REPORT_AGID; + bp->agid = lp->lsa.agid; + break; + case LINUX_DVD_HOST_SEND_CHALLENGE: + *bcode = DVDIOCSENDKEY; + bp->format = DVD_SEND_CHALLENGE; + bp->agid = lp->hsc.agid; + memcpy(bp->keychal, lp->hsc.chal, 10); + break; + case LINUX_DVD_LU_SEND_KEY1: + *bcode = DVDIOCREPORTKEY; + bp->format = DVD_REPORT_KEY1; + bp->agid = lp->lsk.agid; + break; + case LINUX_DVD_LU_SEND_CHALLENGE: + *bcode = DVDIOCREPORTKEY; + bp->format = DVD_REPORT_CHALLENGE; + bp->agid = lp->lsc.agid; + break; + case LINUX_DVD_HOST_SEND_KEY2: + *bcode = DVDIOCSENDKEY; + bp->format = DVD_SEND_KEY2; + bp->agid = lp->hsk.agid; + memcpy(bp->keychal, lp->hsk.key, 5); + break; + case LINUX_DVD_LU_SEND_TITLE_KEY: + *bcode = DVDIOCREPORTKEY; + bp->format = DVD_REPORT_TITLE_KEY; + bp->agid = lp->lstk.agid; + bp->lba = lp->lstk.lba; + break; + case LINUX_DVD_LU_SEND_ASF: + *bcode = DVDIOCREPORTKEY; + bp->format = DVD_REPORT_ASF; + bp->agid = lp->lsasf.agid; + break; + case LINUX_DVD_INVALIDATE_AGID: + *bcode = DVDIOCREPORTKEY; + bp->format = DVD_INVALIDATE_AGID; + bp->agid = lp->lsa.agid; + break; + case LINUX_DVD_LU_SEND_RPC_STATE: + *bcode = DVDIOCREPORTKEY; + bp->format = DVD_REPORT_RPC; + break; + case LINUX_DVD_HOST_SEND_RPC_STATE: + *bcode = DVDIOCSENDKEY; + bp->format = DVD_SEND_RPC; + bp->region = lp->hrpcs.pdrc; + break; + default: + return (EINVAL); + } + return (0); +} + +static int +bsd_to_linux_dvd_authinfo(struct dvd_authinfo *bp, l_dvd_authinfo *lp) +{ + switch (lp->type) { + case LINUX_DVD_LU_SEND_AGID: + lp->lsa.agid = bp->agid; + break; + case LINUX_DVD_HOST_SEND_CHALLENGE: + lp->type = LINUX_DVD_LU_SEND_KEY1; + break; + case LINUX_DVD_LU_SEND_KEY1: + memcpy(lp->lsk.key, bp->keychal, sizeof(lp->lsk.key)); + break; + case LINUX_DVD_LU_SEND_CHALLENGE: + memcpy(lp->lsc.chal, bp->keychal, sizeof(lp->lsc.chal)); + break; + case LINUX_DVD_HOST_SEND_KEY2: + lp->type = LINUX_DVD_AUTH_ESTABLISHED; + break; + case LINUX_DVD_LU_SEND_TITLE_KEY: + memcpy(lp->lstk.title_key, bp->keychal, + sizeof(lp->lstk.title_key)); + lp->lstk.cpm = bp->cpm; + lp->lstk.cp_sec = bp->cp_sec; + lp->lstk.cgms = bp->cgms; + break; + case LINUX_DVD_LU_SEND_ASF: + lp->lsasf.asf = bp->asf; + break; + case LINUX_DVD_INVALIDATE_AGID: + break; + case LINUX_DVD_LU_SEND_RPC_STATE: + lp->lrpcs.type = bp->reg_type; + lp->lrpcs.vra = bp->vend_rsts; + lp->lrpcs.ucca = bp->user_rsts; + lp->lrpcs.region_mask = bp->region; + lp->lrpcs.rpc_scheme = bp->rpc_scheme; + break; + case LINUX_DVD_HOST_SEND_RPC_STATE: + break; + default: + return (EINVAL); + } + return (0); +} + +static int linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args) { struct file *fp = td->td_proc->p_fd->fd_ofiles[args->fd]; @@ -1009,6 +1315,74 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args) /* LINUX_CDROMREADALL */ /* LINUX_CDROMCLOSETRAY */ /* LINUX_CDROMLOADFROMSLOT */ + /* LINUX_CDROMGETSPINDOWN */ + /* LINUX_CDROMSETSPINDOWN */ + /* LINUX_CDROM_SET_OPTIONS */ + /* LINUX_CDROM_CLEAR_OPTIONS */ + /* LINUX_CDROM_SELECT_SPEED */ + /* LINUX_CDROM_SELECT_DISC */ + /* LINUX_CDROM_MEDIA_CHANGED */ + /* LINUX_CDROM_DRIVE_STATUS */ + /* LINUX_CDROM_DISC_STATUS */ + /* LINUX_CDROM_CHANGER_NSLOTS */ + /* LINUX_CDROM_LOCKDOOR */ + /* LINUX_CDROM_DEBUG */ + /* LINUX_CDROM_GET_CAPABILITY */ + /* LINUX_CDROMAUDIOBUFSIZ */ + + case LINUX_DVD_READ_STRUCT: { + l_dvd_struct lds; + struct dvd_struct bds; + + error = copyin((caddr_t)args->arg, &lds, sizeof(l_dvd_struct)); + if (error) + return (error); + error = linux_to_bsd_dvd_struct(&lds, &bds); + if (error) + return (error); + error = fo_ioctl(fp, DVDIOCREADSTRUCTURE, (caddr_t)&bds, td); + if (error) + return (error); + error = bsd_to_linux_dvd_struct(&bds, &lds); + if (error) + return (error); + return (copyout(&lds, (caddr_t)args->arg, + sizeof(l_dvd_struct))); + } + + /* LINUX_DVD_WRITE_STRUCT */ + + case LINUX_DVD_AUTH: { + l_dvd_authinfo lda; + struct dvd_authinfo bda; + int bcode; + + error = copyin((caddr_t)args->arg, &lda, + sizeof(l_dvd_authinfo)); + if (error) + return (error); + error = linux_to_bsd_dvd_authinfo(&lda, &bcode, &bda); + if (error) + return (error); + error = fo_ioctl(fp, bcode, (caddr_t)&bda, td); + if (error) { + if (lda.type == LINUX_DVD_HOST_SEND_KEY2) { + lda.type = LINUX_DVD_AUTH_FAILURE; + copyout(&lda, (caddr_t)args->arg, + sizeof(l_dvd_authinfo)); + } + return (error); + } + error = bsd_to_linux_dvd_authinfo(&bda, &lda); + if (error) + return (error); + return (copyout(&lda, (caddr_t)args->arg, + sizeof(l_dvd_authinfo))); + } + + /* LINUX_CDROM_SEND_PACKET */ + /* LINUX_CDROM_NEXT_WRITABLE */ + /* LINUX_CDROM_LAST_WRITTEN */ } diff --git a/sys/compat/linux/linux_ioctl.h b/sys/compat/linux/linux_ioctl.h index 76ded6d..59ffed7 100644 --- a/sys/compat/linux/linux_ioctl.h +++ b/sys/compat/linux/linux_ioctl.h @@ -53,39 +53,72 @@ /* * cdrom */ -#define LINUX_CDROMPAUSE 0x5301 -#define LINUX_CDROMRESUME 0x5302 -#define LINUX_CDROMPLAYMSF 0x5303 -#define LINUX_CDROMPLAYTRKIND 0x5304 -#define LINUX_CDROMREADTOCHDR 0x5305 -#define LINUX_CDROMREADTOCENTRY 0x5306 -#define LINUX_CDROMSTOP 0x5307 -#define LINUX_CDROMSTART 0x5308 -#define LINUX_CDROMEJECT 0x5309 -#define LINUX_CDROMVOLCTRL 0x530a -#define LINUX_CDROMSUBCHNL 0x530b -#define LINUX_CDROMREADMODE2 0x530c -#define LINUX_CDROMREADMODE1 0x530d -#define LINUX_CDROMREADAUDIO 0x530e -#define LINUX_CDROMEJECT_SW 0x530f -#define LINUX_CDROMMULTISESSION 0x5310 -#define LINUX_CDROM_GET_UPC 0x5311 -#define LINUX_CDROMRESET 0x5312 -#define LINUX_CDROMVOLREAD 0x5313 -#define LINUX_CDROMREADRAW 0x5314 -#define LINUX_CDROMREADCOOKED 0x5315 -#define LINUX_CDROMSEEK 0x5316 -#define LINUX_CDROMPLAYBLK 0x5317 -#define LINUX_CDROMREADALL 0x5318 -#define LINUX_CDROMCLOSETRAY 0x5319 -#define LINUX_CDROMLOADFROMSLOT 0x531a +#define LINUX_CDROMPAUSE 0x5301 +#define LINUX_CDROMRESUME 0x5302 +#define LINUX_CDROMPLAYMSF 0x5303 +#define LINUX_CDROMPLAYTRKIND 0x5304 +#define LINUX_CDROMREADTOCHDR 0x5305 +#define LINUX_CDROMREADTOCENTRY 0x5306 +#define LINUX_CDROMSTOP 0x5307 +#define LINUX_CDROMSTART 0x5308 +#define LINUX_CDROMEJECT 0x5309 +#define LINUX_CDROMVOLCTRL 0x530a +#define LINUX_CDROMSUBCHNL 0x530b +#define LINUX_CDROMREADMODE2 0x530c +#define LINUX_CDROMREADMODE1 0x530d +#define LINUX_CDROMREADAUDIO 0x530e +#define LINUX_CDROMEJECT_SW 0x530f +#define LINUX_CDROMMULTISESSION 0x5310 +#define LINUX_CDROM_GET_UPC 0x5311 +#define LINUX_CDROMRESET 0x5312 +#define LINUX_CDROMVOLREAD 0x5313 +#define LINUX_CDROMREADRAW 0x5314 +#define LINUX_CDROMREADCOOKED 0x5315 +#define LINUX_CDROMSEEK 0x5316 +#define LINUX_CDROMPLAYBLK 0x5317 +#define LINUX_CDROMREADALL 0x5318 +#define LINUX_CDROMCLOSETRAY 0x5319 +#define LINUX_CDROMLOADFROMSLOT 0x531a +#define LINUX_CDROMGETSPINDOWN 0x531d +#define LINUX_CDROMSETSPINDOWN 0x531e +#define LINUX_CDROM_SET_OPTIONS 0x5320 +#define LINUX_CDROM_CLEAR_OPTIONS 0x5321 +#define LINUX_CDROM_SELECT_SPEED 0x5322 +#define LINUX_CDROM_SELECT_DISC 0x5323 +#define LINUX_CDROM_MEDIA_CHANGED 0x5325 +#define LINUX_CDROM_DRIVE_STATUS 0x5326 +#define LINUX_CDROM_DISC_STATUS 0x5327 +#define LINUX_CDROM_CHANGER_NSLOTS 0x5328 +#define LINUX_CDROM_LOCKDOOR 0x5329 +#define LINUX_CDROM_DEBUG 0x5330 +#define LINUX_CDROM_GET_CAPABILITY 0x5331 +#define LINUX_CDROMAUDIOBUFSIZ 0x5382 +#define LINUX_DVD_READ_STRUCT 0x5390 +#define LINUX_DVD_WRITE_STRUCT 0x5391 +#define LINUX_DVD_AUTH 0x5392 +#define LINUX_CDROM_SEND_PACKET 0x5393 +#define LINUX_CDROM_NEXT_WRITABLE 0x5394 +#define LINUX_CDROM_LAST_WRITTEN 0x5395 #define LINUX_IOCTL_CDROM_MIN LINUX_CDROMPAUSE -#define LINUX_IOCTL_CDROM_MAX LINUX_CDROMLOADFROMSLOT +#define LINUX_IOCTL_CDROM_MAX LINUX_CDROM_LAST_WRITTEN #define LINUX_CDROM_LBA 0x01 #define LINUX_CDROM_MSF 0x02 +#define LINUX_DVD_LU_SEND_AGID 0 +#define LINUX_DVD_HOST_SEND_CHALLENGE 1 +#define LINUX_DVD_LU_SEND_KEY1 2 +#define LINUX_DVD_LU_SEND_CHALLENGE 3 +#define LINUX_DVD_HOST_SEND_KEY2 4 +#define LINUX_DVD_AUTH_ESTABLISHED 5 +#define LINUX_DVD_AUTH_FAILURE 6 +#define LINUX_DVD_LU_SEND_TITLE_KEY 7 +#define LINUX_DVD_LU_SEND_ASF 8 +#define LINUX_DVD_INVALIDATE_AGID 9 +#define LINUX_DVD_LU_SEND_RPC_STATE 10 +#define LINUX_DVD_HOST_SEND_RPC_STATE 11 + /* * console */ |