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 MFC after: 1 week
This commit is contained in:
parent
0096926b7e
commit
b01bf72b6e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=240981
@ -225,6 +225,49 @@ struct pci_io_old {
|
|||||||
u_int32_t pi_data; /* data to write or result of read */
|
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 PCIOCGETCONF_OLD _IOWR('p', 1, struct pci_conf_io)
|
||||||
#define PCIOCREAD_OLD _IOWR('p', 2, struct pci_io_old)
|
#define PCIOCREAD_OLD _IOWR('p', 2, struct pci_io_old)
|
||||||
#define PCIOCWRITE_OLD _IOWR('p', 3, struct pci_io_old)
|
#define PCIOCWRITE_OLD _IOWR('p', 3, struct pci_io_old)
|
||||||
@ -295,6 +338,69 @@ pci_conf_match_old(struct pci_match_conf_old *matches, int num_matches,
|
|||||||
return(1);
|
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
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -313,13 +419,21 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
size_t confsz, iolen, pbufsz;
|
size_t confsz, iolen, pbufsz;
|
||||||
int error, ionum, i, num_patterns;
|
int error, ionum, i, num_patterns;
|
||||||
#ifdef PRE7_COMPAT
|
#ifdef PRE7_COMPAT
|
||||||
|
#ifdef COMPAT_FREEBSD32
|
||||||
|
struct pci_conf_io32 *cio32;
|
||||||
|
#endif
|
||||||
struct pci_conf_old conf_old;
|
struct pci_conf_old conf_old;
|
||||||
|
struct pci_conf_old32 conf_old32;
|
||||||
struct pci_io iodata;
|
struct pci_io iodata;
|
||||||
struct pci_io_old *io_old;
|
struct pci_io_old *io_old;
|
||||||
struct pci_match_conf_old *pattern_buf_old;
|
struct pci_match_conf_old *pattern_buf_old;
|
||||||
|
struct pci_match_conf_old32 *pattern_buf_old32;
|
||||||
|
|
||||||
|
cio = NULL;
|
||||||
|
cio32 = NULL;
|
||||||
io_old = NULL;
|
io_old = NULL;
|
||||||
pattern_buf_old = NULL;
|
pattern_buf_old = NULL;
|
||||||
|
pattern_buf_old32 = NULL;
|
||||||
|
|
||||||
if (!(flag & FWRITE) && cmd != PCIOCGETBAR &&
|
if (!(flag & FWRITE) && cmd != PCIOCGETBAR &&
|
||||||
cmd != PCIOCGETCONF && cmd != PCIOCGETCONF_OLD)
|
cmd != PCIOCGETCONF && cmd != PCIOCGETCONF_OLD)
|
||||||
@ -331,11 +445,27 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
|
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
#ifdef PRE7_COMPAT
|
#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:
|
case PCIOCGETCONF_OLD:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
#endif
|
#endif
|
||||||
case PCIOCGETCONF:
|
case PCIOCGETCONF:
|
||||||
cio = (struct pci_conf_io *)data;
|
if (cio == NULL)
|
||||||
|
cio = (struct pci_conf_io *)data;
|
||||||
|
|
||||||
pattern_buf = NULL;
|
pattern_buf = NULL;
|
||||||
num_patterns = 0;
|
num_patterns = 0;
|
||||||
@ -353,7 +483,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
&& (cio->generation != pci_generation)){
|
&& (cio->generation != pci_generation)){
|
||||||
cio->status = PCI_GETCONF_LIST_CHANGED;
|
cio->status = PCI_GETCONF_LIST_CHANGED;
|
||||||
error = 0;
|
error = 0;
|
||||||
break;
|
goto getconfexit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -363,7 +493,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
if (cio->offset >= pci_numdevs) {
|
if (cio->offset >= pci_numdevs) {
|
||||||
cio->status = PCI_GETCONF_LAST_DEVICE;
|
cio->status = PCI_GETCONF_LAST_DEVICE;
|
||||||
error = 0;
|
error = 0;
|
||||||
break;
|
goto getconfexit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the head of the device queue */
|
/* get the head of the device queue */
|
||||||
@ -376,6 +506,11 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
* didn't specify a multiple of that size.
|
* didn't specify a multiple of that size.
|
||||||
*/
|
*/
|
||||||
#ifdef PRE7_COMPAT
|
#ifdef PRE7_COMPAT
|
||||||
|
#ifdef COMPAT_FREEBSD32
|
||||||
|
if (cmd == PCIOCGETCONF_OLD32)
|
||||||
|
confsz = sizeof(struct pci_conf_old32);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if (cmd == PCIOCGETCONF_OLD)
|
if (cmd == PCIOCGETCONF_OLD)
|
||||||
confsz = sizeof(struct pci_conf_old);
|
confsz = sizeof(struct pci_conf_old);
|
||||||
else
|
else
|
||||||
@ -410,6 +545,11 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
* updated their kernel but not their userland.
|
* updated their kernel but not their userland.
|
||||||
*/
|
*/
|
||||||
#ifdef PRE7_COMPAT
|
#ifdef PRE7_COMPAT
|
||||||
|
#ifdef COMPAT_FREEBSD32
|
||||||
|
if (cmd == PCIOCGETCONF_OLD32)
|
||||||
|
pbufsz = sizeof(struct pci_match_conf_old32);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if (cmd == PCIOCGETCONF_OLD)
|
if (cmd == PCIOCGETCONF_OLD)
|
||||||
pbufsz = sizeof(struct pci_match_conf_old);
|
pbufsz = sizeof(struct pci_match_conf_old);
|
||||||
else
|
else
|
||||||
@ -419,13 +559,19 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
/* The user made a mistake, return an error. */
|
/* The user made a mistake, return an error. */
|
||||||
cio->status = PCI_GETCONF_ERROR;
|
cio->status = PCI_GETCONF_ERROR;
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
break;
|
goto getconfexit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a buffer to hold the patterns.
|
* Allocate a buffer to hold the patterns.
|
||||||
*/
|
*/
|
||||||
#ifdef PRE7_COMPAT
|
#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) {
|
if (cmd == PCIOCGETCONF_OLD) {
|
||||||
pattern_buf_old = malloc(cio->pat_buf_len,
|
pattern_buf_old = malloc(cio->pat_buf_len,
|
||||||
M_TEMP, M_WAITOK);
|
M_TEMP, M_WAITOK);
|
||||||
@ -451,7 +597,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
*/
|
*/
|
||||||
cio->status = PCI_GETCONF_ERROR;
|
cio->status = PCI_GETCONF_ERROR;
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
break;
|
goto getconfexit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -483,7 +629,11 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PRE7_COMPAT
|
#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 ||
|
(pattern_buf_old == NULL ||
|
||||||
pci_conf_match_old(pattern_buf_old, num_patterns,
|
pci_conf_match_old(pattern_buf_old, num_patterns,
|
||||||
&dinfo->conf) == 0)) ||
|
&dinfo->conf) == 0)) ||
|
||||||
@ -508,6 +658,38 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef PRE7_COMPAT
|
#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) {
|
if (cmd == PCIOCGETCONF_OLD) {
|
||||||
conf_old.pc_sel.pc_bus =
|
conf_old.pc_sel.pc_bus =
|
||||||
dinfo->conf.pc_sel.pc_bus;
|
dinfo->conf.pc_sel.pc_bus;
|
||||||
@ -574,9 +756,22 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
|
|||||||
cio->status = PCI_GETCONF_MORE_DEVS;
|
cio->status = PCI_GETCONF_MORE_DEVS;
|
||||||
|
|
||||||
getconfexit:
|
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)
|
if (pattern_buf != NULL)
|
||||||
free(pattern_buf, M_TEMP);
|
free(pattern_buf, M_TEMP);
|
||||||
#ifdef PRE7_COMPAT
|
#ifdef PRE7_COMPAT
|
||||||
|
if (pattern_buf_old32 != NULL)
|
||||||
|
free(pattern_buf_old32, M_TEMP);
|
||||||
if (pattern_buf_old != NULL)
|
if (pattern_buf_old != NULL)
|
||||||
free(pattern_buf_old, M_TEMP);
|
free(pattern_buf_old, M_TEMP);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user