Skip site navigation (1)Skip section navigation (2)
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>