Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Feb 2012 05:40:10 GMT
From:      Eugene Grosbein <egrosbein@rdtc.ru>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/139271: [pci] [patch] sysutils/hpacucli does not work on the amd64 kernel
Message-ID:  <201202060540.q165eAFL069958@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/139271; it has been noted by GNATS.

From: Eugene Grosbein <egrosbein@rdtc.ru>
To: bug-followup@FreeBSD.ORG
Cc:  
Subject: Re: kern/139271: [pci] [patch] sysutils/hpacucli does not work on
 the amd64 kernel
Date: Mon, 06 Feb 2012 12:36:29 +0700

 This is a multi-part message in MIME format.
 --------------050604090701010107000907
 Content-Type: text/plain; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 
 Hi!
 
 Here is same patch modified for 8.2-STABLE/amd64:
 COMPAT_IA32 replaced with COMPAT_FREEBSD32, no other changes.
 
 Work just fine with my HP SmartArray P400i.
 
 Please commit.
 
 Eugene Grosbein
 
 --------------050604090701010107000907
 Content-Type: text/plain;
  name="pci_user.c.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="pci_user.c.diff"
 
 --- sys/dev/pci/pci_user.c.orig	2009-09-19 16:13:10.000000000 +0800
 +++ sys/dev/pci/pci_user.c	2012-02-04 01:52:50.000000000 +0700
 @@ -225,6 +225,49 @@
  	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 */
 +       u_int8_t        pc_hdr;         /* PCI header type */
 +       u_int16_t       pc_subvendor;   /* card vendor ID */
 +       u_int16_t       pc_subdevice;   /* card device ID, assigned by
 +                                          card vendor */
 +       u_int16_t       pc_vendor;      /* chip vendor ID */
 +       u_int16_t       pc_device;      /* chip device ID, assigned by
 +                                          chip vendor */
 +       u_int8_t        pc_class;       /* chip PCI class */
 +       u_int8_t        pc_subclass;    /* chip PCI subclass */
 +       u_int8_t        pc_progif;      /* chip PCI programming interface */
 +       u_int8_t        pc_revid;       /* chip revision ID */
 +       char            pd_name[PCI_MAXNAMELEN + 1];  /* device name */
 +       u_int32_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 */
 +       u_int32_t               pd_unit;        /* Unit number (u_long) */
 +       u_int16_t               pc_vendor;      /* PCI Vendor ID */
 +       u_int16_t               pc_device;      /* PCI Device ID */
 +       u_int8_t                pc_class;       /* PCI class */
 +       pci_getconf_flags_old   flags;          /* Matching expression */
 +};
 +
 +struct pci_conf_io32 {
 +       u_int32_t               pat_buf_len;    /* pattern buffer length */
 +       u_int32_t               num_patterns;   /* number of patterns */
 +       u_int32_t               patterns;       /* pattern buffer (struct pci_match_conf_old32 *) */
 +       u_int32_t               match_buf_len;  /* match buffer length */
 +       u_int32_t               num_matches;    /* number of matches returned */
 +       u_int32_t               matches;        /* match buffer (struct pci_conf_old32 *) */
 +       u_int32_t               offset;         /* offset into device list */
 +       u_int32_t               generation;     /* device list generation */
 +       pci_getconf_status      status;         /* request status */
 +};
 +
 +#define        PCIOCGETCONF_OLD32      _IOWR('p', 1, struct pci_conf_io32)
 +#endif
 +
  #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,6 +338,69 @@
  	return(1);
  }
  
 +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
  
  static int
 @@ -314,13 +420,21 @@
  	size_t confsz, iolen, pbufsz;
  	int error, ionum, i, num_patterns;
  #ifdef PRE7_COMPAT
 +#ifdef COMPAT_FREEBSD32
 +       struct pci_conf_io32 *cio32;
 +#endif
  	struct pci_conf_old conf_old;
 +       struct pci_conf_old32 conf_old32;
  	struct pci_io iodata;
  	struct pci_io_old *io_old;
  	struct pci_match_conf_old *pattern_buf_old;
 +       struct pci_match_conf_old32 *pattern_buf_old32;
  
 +       cio = NULL;
 +       cio32 = NULL;
  	io_old = NULL;
  	pattern_buf_old = NULL;
 +       pattern_buf_old32 = NULL;
  
  	if (!(flag & FWRITE) && cmd != PCIOCGETBAR &&
  	    cmd != PCIOCGETCONF && cmd != PCIOCGETCONF_OLD)
 @@ -332,11 +446,27 @@
  
  	switch(cmd) {
  #ifdef PRE7_COMPAT
 +       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;
 +               /* FALLTHROUGH */
 +
  	case PCIOCGETCONF_OLD:
  		/* FALLTHROUGH */
  #endif
  	case PCIOCGETCONF:
 -		cio = (struct pci_conf_io *)data;
 +               if (cio == NULL)
 +                       cio = (struct pci_conf_io *)data;
  
  		pattern_buf = NULL;
  		num_patterns = 0;
 @@ -354,7 +484,7 @@
  		 && (cio->generation != pci_generation)){
  			cio->status = PCI_GETCONF_LIST_CHANGED;
  			error = 0;
 -			break;
 +                       goto getconfexit;
  		}
  
  		/*
 @@ -364,7 +494,7 @@
  		if (cio->offset >= pci_numdevs) {
  			cio->status = PCI_GETCONF_LAST_DEVICE;
  			error = 0;
 -			break;
 +                       goto getconfexit;
  		}
  
  		/* get the head of the device queue */
 @@ -377,6 +507,11 @@
  		 * 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
 @@ -411,6 +546,11 @@
  			 * 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
 @@ -420,13 +560,19 @@
  				/* 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
 +                       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
  			if (cmd == PCIOCGETCONF_OLD) {
  				pattern_buf_old = malloc(cio->pat_buf_len,
  				    M_TEMP, M_WAITOK);
 @@ -452,7 +598,7 @@
  			 */
  			cio->status = PCI_GETCONF_ERROR;
  			error = EINVAL;
 -			break;
 +                       goto getconfexit;
  		}
  
  		/*
 @@ -484,7 +630,11 @@
  			}
  
  #ifdef PRE7_COMPAT
 -			if ((cmd == PCIOCGETCONF_OLD &&
 +                       if ((cmd == PCIOCGETCONF_OLD32 &&
 +                           (pattern_buf_old32 == NULL ||
 +                           pci_conf_match_old32(pattern_buf_old32,
 +                           num_patterns, &dinfo->conf) == 0)) ||
 +                           (cmd == PCIOCGETCONF_OLD &&
  			    (pattern_buf_old == NULL ||
  			    pci_conf_match_old(pattern_buf_old, num_patterns,
  			    &dinfo->conf) == 0)) ||
 @@ -509,6 +659,38 @@
  					break;
  
  #ifdef PRE7_COMPAT
 +                               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 =
 +                                           (u_int32_t)dinfo->conf.pd_unit;
 +                                       confdata = &conf_old32;
 +                               } else
  				if (cmd == PCIOCGETCONF_OLD) {
  					conf_old.pc_sel.pc_bus =
  					    dinfo->conf.pc_sel.pc_bus;
 @@ -575,9 +757,22 @@
  			cio->status = PCI_GETCONF_MORE_DEVS;
  
  getconfexit:
 +#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;
 +                       if (cio != NULL)
 +                               free(cio, M_TEMP);
 +               }
 +#endif
 +
  		if (pattern_buf != NULL)
  			free(pattern_buf, M_TEMP);
  #ifdef PRE7_COMPAT
 +               if (pattern_buf_old32 != NULL)
 +                       free(pattern_buf_old32, M_TEMP);
  		if (pattern_buf_old != NULL)
  			free(pattern_buf_old, M_TEMP);
  #endif
 
 --------------050604090701010107000907--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202060540.q165eAFL069958>