kern/139271: commit references a PR

dfilter service dfilter at FreeBSD.ORG
Fri Jul 12 18:10:03 UTC 2013


The following reply was made to PR kern/139271; it has been noted by GNATS.

From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:  
Subject: Re: kern/139271: commit references a PR
Date: Fri, 12 Jul 2013 18:02:24 +0000 (UTC)

 Author: marius
 Date: Fri Jul 12 18:02:10 2013
 New Revision: 253278
 URL: http://svnweb.freebsd.org/changeset/base/253278
 
 Log:
   MFC: r240981, r240990, r240992, r244695
   
   Add 32-bit ABI compat shims. Those are necessary for i386 binary-only
   tools like sysutils/hpacucli (HP P4xx RAID controller management
   suite) working on amd64 systems.
   
   PR:		139271
   Submitted by:	Kazumi MORINAGA, Eugene Grosbein
   Approved by:	re (kib)
 
 Modified:
   stable/9/sys/dev/pci/pci_user.c
 Directory Properties:
   stable/9/sys/   (props changed)
   stable/9/sys/dev/   (props changed)
 
 Modified: stable/9/sys/dev/pci/pci_user.c
 ==============================================================================
 --- stable/9/sys/dev/pci/pci_user.c	Fri Jul 12 17:37:05 2013	(r253277)
 +++ stable/9/sys/dev/pci/pci_user.c	Fri Jul 12 18:02:10 2013	(r253278)
 @@ -225,6 +225,51 @@ struct pci_io_old {
  	u_int32_t	pi_data;	/* data to write or result of read */
  };
  
 +#ifdef COMPAT_FREEBSD32
 +struct pci_conf_old32 {
 +	struct pcisel_old pc_sel;	/* bus+slot+function */
 +	uint8_t		pc_hdr;		/* PCI header type */
 +	uint16_t	pc_subvendor;	/* card vendor ID */
 +	uint16_t	pc_subdevice;	/* card device ID, assigned by
 +					   card vendor */
 +	uint16_t	pc_vendor;	/* chip vendor ID */
 +	uint16_t	pc_device;	/* chip device ID, assigned by
 +					   chip vendor */
 +	uint8_t		pc_class;	/* chip PCI class */
 +	uint8_t		pc_subclass;	/* chip PCI subclass */
 +	uint8_t		pc_progif;	/* chip PCI programming interface */
 +	uint8_t		pc_revid;	/* chip revision ID */
 +	char		pd_name[PCI_MAXNAMELEN + 1]; /* device name */
 +	uint32_t	pd_unit;	/* device unit number (u_long) */
 +};
 +
 +struct pci_match_conf_old32 {
 +	struct pcisel_old pc_sel;	/* bus+slot+function */
 +	char		pd_name[PCI_MAXNAMELEN + 1]; /* device name */
 +	uint32_t	pd_unit;	/* Unit number (u_long) */
 +	uint16_t	pc_vendor;	/* PCI Vendor ID */
 +	uint16_t	pc_device;	/* PCI Device ID */
 +	uint8_t		pc_class;	/* PCI class */
 +	pci_getconf_flags_old flags;	/* Matching expression */
 +};
 +
 +struct pci_conf_io32 {
 +	uint32_t	pat_buf_len;	/* pattern buffer length */
 +	uint32_t	num_patterns;	/* number of patterns */
 +	uint32_t	patterns;	/* pattern buffer
 +					   (struct pci_match_conf_old32 *) */
 +	uint32_t	match_buf_len;	/* match buffer length */
 +	uint32_t	num_matches;	/* number of matches returned */
 +	uint32_t	matches;	/* match buffer
 +					   (struct pci_conf_old32 *) */
 +	uint32_t	offset;		/* offset into device list */
 +	uint32_t	generation;	/* device list generation */
 +	pci_getconf_status status;	/* request status */
 +};
 +
 +#define	PCIOCGETCONF_OLD32	_IOWR('p', 1, struct pci_conf_io32)
 +#endif	/* COMPAT_FREEBSD32 */
 +
  #define	PCIOCGETCONF_OLD	_IOWR('p', 1, struct pci_conf_io)
  #define	PCIOCREAD_OLD		_IOWR('p', 2, struct pci_io_old)
  #define	PCIOCWRITE_OLD		_IOWR('p', 3, struct pci_io_old)
 @@ -295,7 +340,71 @@ pci_conf_match_old(struct pci_match_conf
  	return(1);
  }
  
 -#endif
 +#ifdef COMPAT_FREEBSD32
 +static int
 +pci_conf_match_old32(struct pci_match_conf_old32 *matches, int num_matches,
 +    struct pci_conf *match_buf)
 +{
 +	int i;
 +
 +	if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0))
 +		return(1);
 +
 +	for (i = 0; i < num_matches; i++) {
 +		if (match_buf->pc_sel.pc_domain != 0)
 +			continue;
 +
 +		/*
 +		 * I'm not sure why someone would do this...but...
 +		 */
 +		if (matches[i].flags == PCI_GETCONF_NO_MATCH_OLD)
 +			continue;
 +
 +		/*
 +		 * Look at each of the match flags.  If it's set, do the
 +		 * comparison.  If the comparison fails, we don't have a
 +		 * match, go on to the next item if there is one.
 +		 */
 +		if (((matches[i].flags & PCI_GETCONF_MATCH_BUS_OLD) != 0) &&
 +		    (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus))
 +			continue;
 +
 +		if (((matches[i].flags & PCI_GETCONF_MATCH_DEV_OLD) != 0) &&
 +		    (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev))
 +			continue;
 +
 +		if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC_OLD) != 0) &&
 +		    (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func))
 +			continue;
 +
 +		if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR_OLD) != 0) &&
 +		    (match_buf->pc_vendor != matches[i].pc_vendor))
 +			continue;
 +
 +		if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE_OLD) != 0) &&
 +		    (match_buf->pc_device != matches[i].pc_device))
 +			continue;
 +
 +		if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS_OLD) != 0) &&
 +		    (match_buf->pc_class != matches[i].pc_class))
 +			continue;
 +
 +		if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT_OLD) != 0) &&
 +		    ((u_int32_t)match_buf->pd_unit != matches[i].pd_unit))
 +			continue;
 +
 +		if (((matches[i].flags & PCI_GETCONF_MATCH_NAME_OLD) != 0) &&
 +		    (strncmp(matches[i].pd_name, match_buf->pd_name,
 +		    sizeof(match_buf->pd_name)) != 0))
 +			continue;
 +
 +		return (0);
 +	}
 +
 +	return (1);
 +}
 +#endif	/* COMPAT_FREEBSD32 */
 +#endif	/* PRE7_COMPAT */
  
  static int
  pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
 @@ -304,7 +413,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  	void *confdata;
  	const char *name;
  	struct devlist *devlist_head;
 -	struct pci_conf_io *cio;
 +	struct pci_conf_io *cio = NULL;
  	struct pci_devinfo *dinfo;
  	struct pci_io *io;
  	struct pci_bar_io *bio;
 @@ -313,13 +422,17 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  	size_t confsz, iolen, pbufsz;
  	int error, ionum, i, num_patterns;
  #ifdef PRE7_COMPAT
 +#ifdef COMPAT_FREEBSD32
 +	struct pci_conf_io32 *cio32 = NULL;
 +	struct pci_conf_old32 conf_old32;
 +	struct pci_match_conf_old32 *pattern_buf_old32 = NULL;
 +#endif
  	struct pci_conf_old conf_old;
  	struct pci_io iodata;
  	struct pci_io_old *io_old;
 -	struct pci_match_conf_old *pattern_buf_old;
 +	struct pci_match_conf_old *pattern_buf_old = NULL;
  
  	io_old = NULL;
 -	pattern_buf_old = NULL;
  
  	if (!(flag & FWRITE) && cmd != PCIOCGETBAR &&
  	    cmd != PCIOCGETCONF && cmd != PCIOCGETCONF_OLD)
 @@ -331,11 +444,36 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  
  	switch(cmd) {
  #ifdef PRE7_COMPAT
 +#ifdef COMPAT_FREEBSD32
 +       case PCIOCGETCONF_OLD32:
 +               cio32 = (struct pci_conf_io32 *)data;
 +               cio = malloc(sizeof(struct pci_conf_io), M_TEMP, M_WAITOK);
 +               cio->pat_buf_len = cio32->pat_buf_len;
 +               cio->num_patterns = cio32->num_patterns;
 +               cio->patterns = (void *)(uintptr_t)cio32->patterns;
 +               cio->match_buf_len = cio32->match_buf_len;
 +               cio->num_matches = cio32->num_matches;
 +               cio->matches = (void *)(uintptr_t)cio32->matches;
 +               cio->offset = cio32->offset;
 +               cio->generation = cio32->generation;
 +               cio->status = cio32->status;
 +               cio32->num_matches = 0;
 +               break;
 +#endif
  	case PCIOCGETCONF_OLD:
 -		/* FALLTHROUGH */
  #endif
  	case PCIOCGETCONF:
  		cio = (struct pci_conf_io *)data;
 +	}
 +
 +	switch(cmd) {
 +#ifdef PRE7_COMPAT
 +#ifdef COMPAT_FREEBSD32
 +	case PCIOCGETCONF_OLD32:
 +#endif
 +	case PCIOCGETCONF_OLD:
 +#endif
 +	case PCIOCGETCONF:
  
  		pattern_buf = NULL;
  		num_patterns = 0;
 @@ -353,7 +491,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  		 && (cio->generation != pci_generation)){
  			cio->status = PCI_GETCONF_LIST_CHANGED;
  			error = 0;
 -			break;
 +			goto getconfexit;
  		}
  
  		/*
 @@ -363,7 +501,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  		if (cio->offset >= pci_numdevs) {
  			cio->status = PCI_GETCONF_LAST_DEVICE;
  			error = 0;
 -			break;
 +			goto getconfexit;
  		}
  
  		/* get the head of the device queue */
 @@ -376,6 +514,11 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  		 * didn't specify a multiple of that size.
  		 */
  #ifdef PRE7_COMPAT
 +#ifdef COMPAT_FREEBSD32
 +		if (cmd == PCIOCGETCONF_OLD32)
 +			confsz = sizeof(struct pci_conf_old32);
 +		else
 +#endif
  		if (cmd == PCIOCGETCONF_OLD)
  			confsz = sizeof(struct pci_conf_old);
  		else
 @@ -410,6 +553,11 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  			 * updated their kernel but not their userland.
  			 */
  #ifdef PRE7_COMPAT
 +#ifdef COMPAT_FREEBSD32
 +			if (cmd == PCIOCGETCONF_OLD32)
 +				pbufsz = sizeof(struct pci_match_conf_old32);
 +			else
 +#endif
  			if (cmd == PCIOCGETCONF_OLD)
  				pbufsz = sizeof(struct pci_match_conf_old);
  			else
 @@ -419,20 +567,28 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  				/* The user made a mistake, return an error. */
  				cio->status = PCI_GETCONF_ERROR;
  				error = EINVAL;
 -				break;
 +				goto getconfexit;
  			}
  
  			/*
  			 * Allocate a buffer to hold the patterns.
  			 */
  #ifdef PRE7_COMPAT
 +#ifdef COMPAT_FREEBSD32
 +			if (cmd == PCIOCGETCONF_OLD32) {
 +				pattern_buf_old32 = malloc(cio->pat_buf_len,
 +				    M_TEMP, M_WAITOK);
 +				error = copyin(cio->patterns,
 +				    pattern_buf_old32, cio->pat_buf_len);
 +			} else
 +#endif /* COMPAT_FREEBSD32 */
  			if (cmd == PCIOCGETCONF_OLD) {
  				pattern_buf_old = malloc(cio->pat_buf_len,
  				    M_TEMP, M_WAITOK);
  				error = copyin(cio->patterns,
  				    pattern_buf_old, cio->pat_buf_len);
  			} else
 -#endif
 +#endif /* PRE7_COMPAT */
  			{
  				pattern_buf = malloc(cio->pat_buf_len, M_TEMP,
  				    M_WAITOK);
 @@ -451,7 +607,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  			 */
  			cio->status = PCI_GETCONF_ERROR;
  			error = EINVAL;
 -			break;
 +                       goto getconfexit;
  		}
  
  		/*
 @@ -483,7 +639,14 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  			}
  
  #ifdef PRE7_COMPAT
 -			if ((cmd == PCIOCGETCONF_OLD &&
 +			if (
 +#ifdef COMPAT_FREEBSD32
 +			    (cmd == PCIOCGETCONF_OLD32 &&
 +			    (pattern_buf_old32 == NULL ||
 +			    pci_conf_match_old32(pattern_buf_old32,
 +			    num_patterns, &dinfo->conf) == 0)) ||
 +#endif
 +			    (cmd == PCIOCGETCONF_OLD &&
  			    (pattern_buf_old == NULL ||
  			    pci_conf_match_old(pattern_buf_old, num_patterns,
  			    &dinfo->conf) == 0)) ||
 @@ -508,6 +671,40 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  					break;
  
  #ifdef PRE7_COMPAT
 +#ifdef COMPAT_FREEBSD32
 +				if (cmd == PCIOCGETCONF_OLD32) {
 +					conf_old32.pc_sel.pc_bus =
 +					    dinfo->conf.pc_sel.pc_bus;
 +					conf_old32.pc_sel.pc_dev =
 +					    dinfo->conf.pc_sel.pc_dev;
 +					conf_old32.pc_sel.pc_func =
 +					    dinfo->conf.pc_sel.pc_func;
 +					conf_old32.pc_hdr = dinfo->conf.pc_hdr;
 +					conf_old32.pc_subvendor =
 +					    dinfo->conf.pc_subvendor;
 +					conf_old32.pc_subdevice =
 +					    dinfo->conf.pc_subdevice;
 +					conf_old32.pc_vendor =
 +					    dinfo->conf.pc_vendor;
 +					conf_old32.pc_device =
 +					    dinfo->conf.pc_device;
 +					conf_old32.pc_class =
 +					    dinfo->conf.pc_class;
 +					conf_old32.pc_subclass =
 +					    dinfo->conf.pc_subclass;
 +					conf_old32.pc_progif =
 +					    dinfo->conf.pc_progif;
 +					conf_old32.pc_revid =
 +					    dinfo->conf.pc_revid;
 +					strncpy(conf_old32.pd_name,
 +					    dinfo->conf.pd_name,
 +					    sizeof(conf_old32.pd_name));
 +					conf_old32.pd_name[PCI_MAXNAMELEN] = 0;
 +					conf_old32.pd_unit =
 +					    (uint32_t)dinfo->conf.pd_unit;
 +					confdata = &conf_old32;
 +				} else
 +#endif /* COMPAT_FREEBSD32 */
  				if (cmd == PCIOCGETCONF_OLD) {
  					conf_old.pc_sel.pc_bus =
  					    dinfo->conf.pc_sel.pc_bus;
 @@ -540,7 +737,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  					    dinfo->conf.pd_unit;
  					confdata = &conf_old;
  				} else
 -#endif
 +#endif /* PRE7_COMPAT */
  					confdata = &dinfo->conf;
  				/* Only if we can copy it out do we count it. */
  				if (!(error = copyout(confdata,
 @@ -574,12 +771,23 @@ pci_ioctl(struct cdev *dev, u_long cmd, 
  			cio->status = PCI_GETCONF_MORE_DEVS;
  
  getconfexit:
 -		if (pattern_buf != NULL)
 -			free(pattern_buf, M_TEMP);
  #ifdef PRE7_COMPAT
 +#ifdef COMPAT_FREEBSD32
 +		if (cmd == PCIOCGETCONF_OLD32) {
 +			cio32->status = cio->status;
 +			cio32->generation = cio->generation;
 +			cio32->offset = cio->offset;
 +			cio32->num_matches = cio->num_matches;
 +			free(cio, M_TEMP);
 +		}
 +		if (pattern_buf_old32 != NULL)
 +			free(pattern_buf_old32, M_TEMP);
 +#endif
  		if (pattern_buf_old != NULL)
  			free(pattern_buf_old, M_TEMP);
  #endif
 +		if (pattern_buf != NULL)
 +			free(pattern_buf, M_TEMP);
  
  		break;
  
 _______________________________________________
 svn-src-all at freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
 


More information about the freebsd-bugs mailing list