Index: sys/cam/scsi/scsi_cd.c =================================================================== --- sys/cam/scsi/scsi_cd.c +++ sys/cam/scsi/scsi_cd.c @@ -63,8 +63,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -210,6 +212,17 @@ } }; +#ifdef COMPAT_FREEBSD32 +struct ioc_read_toc_entry32 { + u_char address_format; + u_char starting_track; + u_short data_len; + uint32_t data; /* (struct cd_toc_entry *) */ +}; +#define CDIOREADTOCENTRYS_32 \ + _IOC_NEWTYPE(CDIOREADTOCENTRYS, struct ioc_read_toc_entry32) +#endif + static disk_open_t cdopen; static disk_close_t cdclose; static disk_ioctl_t cdioctl; @@ -1272,6 +1285,29 @@ return (-1); } +static struct cd_toc_entry * +te_data_get_ptr(void *irtep, u_long cmd) +{ + union { + struct ioc_read_toc_entry irte; +#ifdef COMPAT_FREEBSD32 + struct ioc_read_toc_entry32 irte32; +#endif + } *irteup; + + irteup = irtep; + switch (IOCPARM_LEN(cmd)) { + case sizeof(irteup->irte): + return (irteup->irte.data); +#ifdef COMPAT_FREEBSD32 + case sizeof(struct ioc_read_toc_entry32): + return ((struct cd_toc_entry *)(uintptr_t)irteup->irte32.data); +#endif + default: + panic("Unhandled ioctl command %ld", cmd); + } +} + static int cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td) { @@ -1587,6 +1623,9 @@ } break; case CDIOREADTOCENTRYS: +#ifdef COMPAT_FREEBSD32 + case CDIOREADTOCENTRYS_32: +#endif { struct cd_tocdata *data; struct cd_toc_single *lead; @@ -1712,7 +1751,8 @@ } cam_periph_unlock(periph); - error = copyout(data->entries, te->data, len); + error = copyout(data->entries, te_data_get_ptr(te, cmd), + len); free(data, M_SCSICD); free(lead, M_SCSICD); } Index: sys/compat/freebsd32/freebsd32_ioctl.h =================================================================== --- sys/compat/freebsd32/freebsd32_ioctl.h +++ sys/compat/freebsd32/freebsd32_ioctl.h @@ -38,13 +38,6 @@ typedef __uint32_t caddr_t32; -struct ioc_read_toc_entry32 { - u_char address_format; - u_char starting_track; - u_short data_len; - uint32_t data; /* struct cd_toc_entry* */ -}; - struct fiodgname_arg32 { int len; caddr_t32 buf; @@ -67,7 +60,6 @@ int pbm_memattr; }; -#define CDIOREADTOCENTRYS_32 _IOWR('c', 5, struct ioc_read_toc_entry32) #define FIODGNAME_32 _IOW('f', 120, struct fiodgname_arg32) #define MEMRANGE_GET32 _IOWR('m', 50, struct mem_range_op32) #define MEMRANGE_SET32 _IOW('m', 51, struct mem_range_op32) Index: sys/compat/freebsd32/freebsd32_ioctl.c =================================================================== --- sys/compat/freebsd32/freebsd32_ioctl.c +++ sys/compat/freebsd32/freebsd32_ioctl.c @@ -56,35 +56,8 @@ #include #include -CTASSERT(sizeof(struct ioc_read_toc_entry32) == 8); CTASSERT(sizeof(struct mem_range_op32) == 12); -static int -freebsd32_ioctl_ioc_read_toc(struct thread *td, - struct freebsd32_ioctl_args *uap, struct file *fp) -{ - struct ioc_read_toc_entry toce; - struct ioc_read_toc_entry32 toce32; - int error; - - if ((error = copyin(uap->data, &toce32, sizeof(toce32)))) - return (error); - CP(toce32, toce, address_format); - CP(toce32, toce, starting_track); - CP(toce32, toce, data_len); - PTRIN_CP(toce32, toce, data); - - if ((error = fo_ioctl(fp, CDIOREADTOCENTRYS, (caddr_t)&toce, - td->td_ucred, td))) { - CP(toce, toce32, address_format); - CP(toce, toce32, starting_track); - CP(toce, toce32, data_len); - PTROUT_CP(toce, toce32, data); - error = copyout(&toce32, uap->data, sizeof(toce32)); - } - return error; -} - static int freebsd32_ioctl_fiodgname(struct thread *td, struct freebsd32_ioctl_args *uap, struct file *fp) @@ -264,10 +237,6 @@ } switch (uap->com) { - case CDIOREADTOCENTRYS_32: - error = freebsd32_ioctl_ioc_read_toc(td, uap, fp); - break; - case FIODGNAME_32: error = freebsd32_ioctl_fiodgname(td, uap, fp); break;