Implement DVD-ROM ioctls.
PR: 26955 Submitted by: Boris Nikolaus (email unknown)
This commit is contained in:
parent
f4ee56456f
commit
5b8e92f21c
@ -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)
|
||||
{
|
||||
@ -889,6 +1015,186 @@ set_linux_cdrom_addr(union linux_cdrom_addr *addr, int format, int lba)
|
||||
addr->lba = 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)
|
||||
{
|
||||
@ -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 */
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user