Date: Sat, 16 Apr 2011 12:43:04 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r220716 - stable/8/sys/compat/freebsd32 Message-ID: <201104161243.p3GCh4kC005433@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sat Apr 16 12:43:04 2011 New Revision: 220716 URL: http://svn.freebsd.org/changeset/base/220716 Log: MFC r220281: Implement compat32 shims for PCIOCGETCONF. Modified: stable/8/sys/compat/freebsd32/freebsd32_ioctl.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/compat/freebsd32/freebsd32_ioctl.c ============================================================================== --- stable/8/sys/compat/freebsd32/freebsd32_ioctl.c Sat Apr 16 12:42:54 2011 (r220715) +++ stable/8/sys/compat/freebsd32/freebsd32_ioctl.c Sat Apr 16 12:43:04 2011 (r220716) @@ -241,6 +241,108 @@ freebsd32_ioctl_memrange(struct thread * return (error); } +static int +freebsd32_ioctl_pciocgetconf(struct thread *td, + struct freebsd32_ioctl_args *uap, struct file *fp) +{ + struct pci_conf_io pci; + struct pci_conf_io32 pci32; + struct pci_match_conf32 pmc32; + struct pci_match_conf32 *pmc32p; + struct pci_match_conf pmc; + struct pci_match_conf *pmcp; + struct pci_conf32 pc32; + struct pci_conf32 *pc32p; + struct pci_conf pc; + struct pci_conf *pcp; + u_int32_t i; + u_int32_t npat_to_convert; + u_int32_t nmatch_to_convert; + vm_offset_t addr; + int error; + + if ((error = copyin(uap->data, &pci32, sizeof(pci32))) != 0) + return (error); + + CP(pci32, pci, num_patterns); + CP(pci32, pci, offset); + CP(pci32, pci, generation); + + npat_to_convert = pci32.pat_buf_len / sizeof(struct pci_match_conf32); + pci.pat_buf_len = npat_to_convert * sizeof(struct pci_match_conf); + pci.patterns = NULL; + nmatch_to_convert = pci32.match_buf_len / sizeof(struct pci_conf32); + pci.match_buf_len = nmatch_to_convert * sizeof(struct pci_conf); + pci.matches = NULL; + + if ((error = copyout_map(td, &addr, pci.pat_buf_len)) != 0) + goto cleanup; + pci.patterns = (struct pci_match_conf *)addr; + if ((error = copyout_map(td, &addr, pci.match_buf_len)) != 0) + goto cleanup; + pci.matches = (struct pci_conf *)addr; + + npat_to_convert = min(npat_to_convert, pci.num_patterns); + + for (i = 0, pmc32p = (struct pci_match_conf32 *)PTRIN(pci32.patterns), + pmcp = pci.patterns; + i < npat_to_convert; i++, pmc32p++, pmcp++) { + if ((error = copyin(pmc32p, &pmc32, sizeof(pmc32))) != 0) + goto cleanup; + CP(pmc32,pmc,pc_sel); + strlcpy(pmc.pd_name, pmc32.pd_name, sizeof(pmc.pd_name)); + CP(pmc32,pmc,pd_unit); + CP(pmc32,pmc,pc_vendor); + CP(pmc32,pmc,pc_device); + CP(pmc32,pmc,pc_class); + CP(pmc32,pmc,flags); + if ((error = copyout(&pmc, pmcp, sizeof(pmc))) != 0) + goto cleanup; + } + + if ((error = fo_ioctl(fp, PCIOCGETCONF, (caddr_t)&pci, + td->td_ucred, td)) != 0) + goto cleanup; + + nmatch_to_convert = min(nmatch_to_convert, pci.num_matches); + + for (i = 0, pcp = pci.matches, + pc32p = (struct pci_conf32 *)PTRIN(pci32.matches); + i < nmatch_to_convert; i++, pcp++, pc32p++) { + if ((error = copyin(pcp, &pc, sizeof(pc))) != 0) + goto cleanup; + CP(pc,pc32,pc_sel); + CP(pc,pc32,pc_hdr); + CP(pc,pc32,pc_subvendor); + CP(pc,pc32,pc_subdevice); + CP(pc,pc32,pc_vendor); + CP(pc,pc32,pc_device); + CP(pc,pc32,pc_class); + CP(pc,pc32,pc_subclass); + CP(pc,pc32,pc_progif); + CP(pc,pc32,pc_revid); + strlcpy(pc32.pd_name, pc.pd_name, sizeof(pc32.pd_name)); + CP(pc,pc32,pd_unit); + if ((error = copyout(&pc32, pc32p, sizeof(pc32))) != 0) + goto cleanup; + } + + CP(pci, pci32, num_matches); + CP(pci, pci32, offset); + CP(pci, pci32, generation); + CP(pci, pci32, status); + + error = copyout(&pci32, uap->data, sizeof(pci32)); + +cleanup: + if (pci.patterns) + copyout_unmap(td, (vm_offset_t)pci.patterns, pci.pat_buf_len); + if (pci.matches) + copyout_unmap(td, (vm_offset_t)pci.matches, pci.match_buf_len); + + return (error); +} + int freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap) { @@ -284,6 +386,10 @@ freebsd32_ioctl(struct thread *td, struc error = freebsd32_ioctl_memrange(td, uap, fp); break; + case PCIOCGETCONF_32: + error = freebsd32_ioctl_pciocgetconf(td, uap, fp); + break; + default: fdrop(fp, td); ap.fd = uap->fd;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104161243.p3GCh4kC005433>