| Summary: | Patches to get the DVD-ROM ioctl()s in the Linux emulator. | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Boris Nikolaus <bn> | ||||
| Component: | kern | Assignee: | Marcel Moolenaar <marcel> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 4.3-STABLE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
Responsible Changed From-To: freebsd-bugs->marcel-bugs This is marcel's area now. Responsible Changed From-To: marcel-bugs->marcel Fixed responsible. State Changed From-To: open->closed Patch committed. SOrry for the delay. Thanks! |
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);