Bug 26955

Summary: Patches to get the DVD-ROM ioctl()s in the Linux emulator.
Product: Base System Reporter: Boris Nikolaus <bn>
Component: kernAssignee: Marcel Moolenaar <marcel>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.3-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description Boris Nikolaus 2001-04-29 15:10:06 UTC
I've added the missing ioctl()s for DVD-ROM access to the Linux emulator.
Please submit the patches to the cvs tree.

Fix: Here are context-diffs to the latest stable versions of linux_ioctl.c (1.55.2.4)
and linux_ioctl.h (1.4.2.1):



Greetings,
Boris Nikolaus--pkXq7FL0qQvyaTTIDAu9WWp5PMWG3khY8xPBC9VrO8wyU2r1
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

*** linux_ioctl.c.orig	Sat Apr 28 03:08:21 2001
--- linux_ioctl.c	Sun Apr 29 01:39:56 2001
***************
*** 33,38 ****
--- 33,39 ----
  #include <sys/sysproto.h>
  #include <sys/proc.h>
  #include <sys/cdio.h>
+ #include <sys/dvdio.h>
  #include <sys/fcntl.h>
  #include <sys/file.h>
  #include <sys/filedesc.h>
***************
*** 827,832 ****
--- 828,958 ----
  	union linux_cdrom_addr cdsc_reladdr;
  };
  
+ struct linux_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 linux_dvd_physical {
+ 	u_char	type;
+ 	u_char	layer_num;
+ 	struct linux_dvd_layer layer[4];
+ };
+ 
+ struct linux_dvd_copyright {
+ 	u_char	type;
+ 	u_char	layer_num;
+ 	u_char	cpst;
+ 	u_char	rmi;
+ };
+ 
+ struct linux_dvd_disckey {
+     	u_char	type;
+ 	unsigned agid:2;
+ 	u_char	value[2048];
+ };
+ 
+ struct linux_dvd_bca {
+     	u_char	type;
+ 	int	len;
+ 	u_char	value[188];
+ };
+ 
+ struct linux_dvd_manufact {
+ 	u_char	type;
+ 	u_char	layer_num;
+ 	int	len;
+ 	u_char	value[2048];
+ };
+ 
+ typedef union {
+ 	u_char	type;
+ 	struct linux_dvd_physical physical;
+ 	struct linux_dvd_copyright copyright;
+ 	struct linux_dvd_disckey disckey;
+ 	struct linux_dvd_bca bca;
+ 	struct linux_dvd_manufact manufact;
+ } linux_dvd_struct;
+ 
+ typedef u_char linux_dvd_key[5];
+ typedef u_char linux_dvd_challenge[10];
+ 
+ struct linux_dvd_lu_send_agid {
+     	u_char	type;
+ 	unsigned agid:2;
+ };
+ 
+ struct linux_dvd_host_send_challenge {
+ 	u_char	type;
+ 	unsigned agid:2;
+ 	linux_dvd_challenge chal;
+ };
+ 
+ struct linux_dvd_send_key {
+ 	u_char	type;
+ 	unsigned agid:2;
+ 	linux_dvd_key key;
+ };
+ 
+ struct linux_dvd_lu_send_challenge {
+ 	u_char	type;
+ 	unsigned agid:2;
+ 	linux_dvd_challenge chal;
+ };
+ 
+ struct linux_dvd_lu_send_title_key {
+ 	u_char	type;
+ 	unsigned agid:2;
+ 	linux_dvd_key title_key;
+ 	int	lba;
+ 	unsigned cpm:1;
+ 	unsigned cp_sec:1;
+ 	unsigned cgms:2;
+ };
+ 
+ struct linux_dvd_lu_send_asf {
+ 	u_char	type;
+ 	unsigned agid:2;
+ 	unsigned asf:1;
+ };
+ 
+ struct linux_dvd_host_send_rpcstate {
+ 	u_char	type;
+ 	u_char	pdrc;
+ };
+ 
+ struct linux_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 linux_dvd_lu_send_agid		lsa;
+ 	struct linux_dvd_host_send_challenge	hsc;
+ 	struct linux_dvd_send_key		lsk;
+ 	struct linux_dvd_lu_send_challenge	lsc;
+ 	struct linux_dvd_send_key		hsk;
+ 	struct linux_dvd_lu_send_title_key	lstk;
+ 	struct linux_dvd_lu_send_asf		lsasf;
+ 	struct linux_dvd_host_send_rpcstate	hrpcs;
+ 	struct linux_dvd_lu_send_rpcstate	lrpcs;
+ } linux_dvd_authinfo;
+ 
  static void
  bsd_to_linux_msf_lba(u_char af, union msf_lba *bp, union linux_cdrom_addr *lp)
  {
***************
*** 853,858 ****
--- 979,1160 ----
  }
  
  static int
+ linux_to_bsd_dvd_struct(linux_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;
+ 		return 0;
+ 	case DVD_STRUCT_COPYRIGHT:
+ 		bp->layer_num = lp->copyright.layer_num;
+ 		return 0;
+ 	case DVD_STRUCT_DISCKEY:
+ 		bp->agid = lp->disckey.agid;
+ 		return 0;
+ 	case DVD_STRUCT_BCA:
+ 		return 0;
+ 	case DVD_STRUCT_MANUFACT:
+ 		return 0;
+ 	}
+ 	return (ENOIOCTL);
+ }
+ 
+ static int
+ bsd_to_linux_dvd_struct(struct dvd_struct *bp, linux_dvd_struct *lp)
+ {
+ 	switch (bp->format) {
+ 	case DVD_STRUCT_PHYSICAL: {
+ 		struct dvd_layer *blp = (struct dvd_layer *)bp->data;
+ 		struct linux_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;
+ 		return 0;
+ 	}
+ 	case DVD_STRUCT_COPYRIGHT:
+ 		lp->copyright.cpst = bp->cpst;
+ 		lp->copyright.rmi = bp->rmi;
+ 		return 0;
+ 	case DVD_STRUCT_DISCKEY:
+ 		memcpy(lp->disckey.value, bp->data,
+ 		    sizeof(lp->disckey.value));
+ 		return 0;
+ 	case DVD_STRUCT_BCA:
+ 		lp->bca.len = bp->length;
+ 		memcpy(lp->bca.value, bp->data, sizeof(lp->bca.value));
+ 		return 0;
+ 	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) */
+ 		return 0;
+ 	}
+ 	return (ENOIOCTL);
+ }
+ 
+ static int
+ linux_to_bsd_dvd_authinfo(linux_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;
+ 		return 0;
+ 	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);
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_KEY1:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_REPORT_KEY1;
+ 		bp->agid = lp->lsk.agid;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_CHALLENGE:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_REPORT_CHALLENGE;
+ 		bp->agid = lp->lsc.agid;
+ 		return 0;
+ 	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);
+ 		return 0;
+ 	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;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_ASF:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_REPORT_ASF;
+ 		bp->agid = lp->lsasf.agid;
+ 		return 0;
+ 	case LINUX_DVD_INVALIDATE_AGID:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_INVALIDATE_AGID;
+ 		bp->agid = lp->lsa.agid;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_RPC_STATE:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_REPORT_RPC;
+ 		return 0;
+ 	case LINUX_DVD_HOST_SEND_RPC_STATE:
+ 		*bcode = DVDIOCSENDKEY;
+ 		bp->format = DVD_SEND_RPC;
+ 		bp->region = lp->hrpcs.pdrc;
+ 		return 0;
+ 	}
+ 	return (ENOIOCTL);
+ }
+ 
+ static int
+ bsd_to_linux_dvd_authinfo(struct dvd_authinfo *bp,
+ 	linux_dvd_authinfo *lp)
+ {
+ 	switch (lp->type) {
+ 	case LINUX_DVD_LU_SEND_AGID:
+ 		lp->lsa.agid = bp->agid;
+ 		return 0;
+ 	case LINUX_DVD_HOST_SEND_CHALLENGE:
+ 		lp->type = LINUX_DVD_LU_SEND_KEY1;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_KEY1:
+ 		memcpy(lp->lsk.key, bp->keychal, sizeof(lp->lsk.key));
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_CHALLENGE:
+ 		memcpy(lp->lsc.chal, bp->keychal, sizeof(lp->lsc.chal));
+ 		return 0;
+ 	case LINUX_DVD_HOST_SEND_KEY2:
+ 		lp->type = LINUX_DVD_AUTH_ESTABLISHED;
+ 		return 0;
+ 	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;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_ASF:
+ 		lp->lsasf.asf = bp->asf;
+ 		return 0;
+ 	case LINUX_DVD_INVALIDATE_AGID:
+ 		return 0;
+ 	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;
+ 		return 0;
+ 	case LINUX_DVD_HOST_SEND_RPC_STATE:
+ 		return 0;
+ 	}
+ 	return (ENOIOCTL);
+ }
+ 
+ static int
  linux_ioctl_cdrom(struct proc *p, struct linux_ioctl_args *args)
  {
  	struct file *fp = p->p_fd->fd_ofiles[args->fd];
***************
*** 972,978 ****
--- 1274,1348 ----
  	/* 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: {
+ 		linux_dvd_struct lds;
+ 		struct dvd_struct bds;
+ 		error = copyin((caddr_t)args->arg, &lds,
+ 		    sizeof(linux_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, p);
+ 		if (error)
+ 			return (error);
+ 		error = bsd_to_linux_dvd_struct(&bds, &lds);
+ 		if (error)
+ 			return (error);
+ 		error = copyout(&lds, (caddr_t)args->arg,
+ 		    sizeof(linux_dvd_struct));
+ 		return (error);
+ 	}
+ 
+ 	/* LINUX_DVD_WRITE_STRUCT */
+ 
+ 	case LINUX_DVD_AUTH: {
+ 		linux_dvd_authinfo lda;
+ 		struct dvd_authinfo bda;
+ 		int bcode;
+ 		error = copyin((caddr_t)args->arg, &lda,
+ 		    sizeof(linux_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, p);
+ 		if (error) {
+ 			if (lda.type == LINUX_DVD_HOST_SEND_KEY2) {
+ 				lda.type = LINUX_DVD_AUTH_FAILURE;
+ 				copyout(&lda, (caddr_t)args->arg,
+ 				    sizeof(linux_dvd_authinfo));
+ 			}
+ 			return (error);
+ 		}
+ 		error = bsd_to_linux_dvd_authinfo(&bda, &lda);
+ 		if (error)
+ 			return (error);
+ 		error = copyout(&lda, (caddr_t)args->arg,
+ 		    sizeof(linux_dvd_authinfo));
+ 		return (error);
+ 	}
  
+ 	/* LINUX_CDROM_SEND_PACKET */
+ 	/* LINUX_CDROM_NEXT_WRITABLE */
+ 	/* LINUX_CDROM_LAST_WRITTEN */
  	}
  
  	return (ENOIOCTL);
Comment 1 Søren Schmidt freebsd_committer freebsd_triage 2001-05-30 12:01:12 UTC
Responsible Changed
From-To: freebsd-bugs->marcel-bugs

This is marcel's area now.
Comment 2 ru freebsd_committer freebsd_triage 2001-07-03 15:28:01 UTC
Responsible Changed
From-To: marcel-bugs->marcel

Fixed responsible.
Comment 3 Marcel Moolenaar freebsd_committer freebsd_triage 2001-11-18 18:49:47 UTC
State Changed
From-To: open->closed

Patch committed. SOrry for the delay. Thanks!