svn commit: r303881 - in head: share/man/man4 sys/dev/pci

John Baldwin jhb at FreeBSD.org
Tue Aug 9 17:57:12 UTC 2016


Author: jhb
Date: Tue Aug  9 17:57:11 2016
New Revision: 303881
URL: https://svnweb.freebsd.org/changeset/base/303881

Log:
  Reliably return PCI_GETCONF_LAST_DEVICE from PCIOCGETCONF.
  
  Previously the loop in PCIIOCGETCONF would terminate as soon as it
  found enough matches.  Now it will continue iterating through the
  PCI device list and only terminate if it finds another matching device
  for which it has no room to store a conf structure.  This means that
  PCI_GETCONF_LAST_DEVICE is reliably returned when the number of
  matching devices is equal to the number of slots in the matches
  buffer.  For example, if a program requests the conf structure for a
  single PCI function with a specified domain/bus/slot/function it will
  now get PCI_GETCONF_LAST_DEVICE instead of PCI_GETCONF_MORE_DEVS.
  
  While here, simplify the loop conditional a bit more by explicitly
  breaking out of the loop if copyout() fails and removing a redundant
  i < pci_numdevs check.
  
  Reviewed by:	vangyzen, imp
  MFC after:	1 month
  Sponsored by:	Chelsio Communications
  Differential Revision:	https://reviews.freebsd.org/D7445

Modified:
  head/share/man/man4/pci.4
  head/sys/dev/pci/pci_user.c

Modified: head/share/man/man4/pci.4
==============================================================================
--- head/share/man/man4/pci.4	Tue Aug  9 17:49:42 2016	(r303880)
+++ head/share/man/man4/pci.4	Tue Aug  9 17:57:11 2016	(r303881)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 3, 2008
+.Dd August 9, 2016
 .Dt PCI 4
 .Os
 .Sh NAME
@@ -229,7 +229,8 @@ The status tells the user the dispositio
 The possible status values are:
 .Bl -ohang
 .It PCI_GETCONF_LAST_DEVICE
-This means that there are no more devices in the PCI device list after the
+This means that there are no more devices in the PCI device list matching
+the specified criteria after the
 ones returned in the
 .Va matches
 buffer.
@@ -245,9 +246,7 @@ and
 to zero to start over at the beginning of the list.
 .It PCI_GETCONF_MORE_DEVS
 This tells the user that his buffer was not large enough to hold all of the
-remaining devices in the device list that possibly match his criteria.
-It is possible for this status to be returned, even when none of the remaining
-devices in the list would match the user's criteria.
+remaining devices in the device list that match his criteria.
 .It PCI_GETCONF_ERROR
 This indicates a general error while servicing the user's request.
 If the

Modified: head/sys/dev/pci/pci_user.c
==============================================================================
--- head/sys/dev/pci/pci_user.c	Tue Aug  9 17:49:42 2016	(r303880)
+++ head/sys/dev/pci/pci_user.c	Tue Aug  9 17:57:11 2016	(r303881)
@@ -708,10 +708,9 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
 		 * Go through the list of devices and copy out the devices
 		 * that match the user's criteria.
 		 */
-		for (cio->num_matches = 0, error = 0, i = 0,
+		for (cio->num_matches = 0, i = 0,
 				 dinfo = STAILQ_FIRST(devlist_head);
-		     (dinfo != NULL) && (cio->num_matches < ionum) &&
-				 (error == 0) && (i < pci_numdevs);
+		     dinfo != NULL;
 		     dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
 
 			if (i < cio->offset)
@@ -833,11 +832,12 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
 				} else
 #endif /* PRE7_COMPAT */
 					confdata = &dinfo->conf;
-				/* Only if we can copy it out do we count it. */
-				if (!(error = copyout(confdata,
+				error = copyout(confdata,
 				    (caddr_t)cio->matches +
-				    confsz * cio->num_matches, confsz)))
-					cio->num_matches++;
+				    confsz * cio->num_matches, confsz);
+				if (error)
+					break;
+				cio->num_matches++;
 			}
 		}
 


More information about the svn-src-head mailing list