Fix up the COMPAT_FREEBSD32 ioctl logic for mps(4).
Reviewed by: ken
This commit is contained in:
parent
e0f0e66dfe
commit
5ef9804274
@ -103,44 +103,4 @@ struct mps_usr_command {
|
||||
#define MPSIO_RAID_ACTION _IOWR('M', 205, struct mps_raid_action)
|
||||
#define MPSIO_MPS_COMMAND _IOWR('M', 210, struct mps_usr_command)
|
||||
|
||||
#if defined(__amd64__)
|
||||
struct mps_cfg_page_req32 {
|
||||
MPI2_CONFIG_PAGE_HEADER header;
|
||||
uint32_t page_address;
|
||||
uint32_t buf;
|
||||
int len;
|
||||
uint16_t ioc_status;
|
||||
};
|
||||
|
||||
struct mps_ext_cfg_page_req32 {
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER header;
|
||||
uint32_t page_address;
|
||||
uint32_t buf;
|
||||
int len;
|
||||
uint16_t ioc_status;
|
||||
};
|
||||
|
||||
struct mps_raid_action32 {
|
||||
uint8_t action;
|
||||
uint8_t volume_bus;
|
||||
uint8_t volume_id;
|
||||
uint8_t phys_disk_num;
|
||||
uint32_t action_data_word;
|
||||
uint32_t buf;
|
||||
int len;
|
||||
uint32_t volume_status;
|
||||
uint32_t action_data[4];
|
||||
uint16_t action_status;
|
||||
uint16_t ioc_status;
|
||||
uint8_t write;
|
||||
};
|
||||
|
||||
#define MPSIO_READ_CFG_HEADER32 _IOWR('M', 100, struct mps_cfg_page_req32)
|
||||
#define MPSIO_READ_CFG_PAGE32 _IOWR('M', 101, struct mps_cfg_page_req32)
|
||||
#define MPSIO_READ_EXT_CFG_HEADER32 _IOWR('M', 102, struct mps_ext_cfg_page_req32)
|
||||
#define MPSIO_READ_EXT_CFG_PAGE32 _IOWR('M', 103, struct mps_ext_cfg_page_req32)
|
||||
#define MPSIO_WRITE_CFG_PAGE32 _IOWR('M', 104, struct mps_cfg_page_req32)
|
||||
#define MPSIO_RAID_ACTION32 _IOWR('M', 105, struct mps_raid_action32)
|
||||
#endif
|
||||
|
||||
#endif /* !_MPS_IOCTL_H_ */
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_compat.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -47,6 +49,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sysent.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
@ -64,14 +68,14 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
static d_open_t mps_open;
|
||||
static d_close_t mps_close;
|
||||
static d_ioctl_t mps_ioctl;
|
||||
static d_ioctl_t mps_ioctl_devsw;
|
||||
|
||||
static struct cdevsw mps_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_flags = 0,
|
||||
.d_open = mps_open,
|
||||
.d_close = mps_close,
|
||||
.d_ioctl = mps_ioctl,
|
||||
.d_ioctl = mps_ioctl_devsw,
|
||||
.d_name = "mps",
|
||||
};
|
||||
|
||||
@ -424,25 +428,14 @@ mps_user_command(struct mps_softc *sc, struct mps_usr_command *cmd)
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef __amd64__
|
||||
#define PTRIN(p) ((void *)(uintptr_t)(p))
|
||||
#define PTROUT(v) ((u_int32_t)(uintptr_t)(v))
|
||||
#endif
|
||||
|
||||
static int
|
||||
mps_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag,
|
||||
mps_ioctl(struct cdev *dev, u_long cmd, void *arg, int flag,
|
||||
struct thread *td)
|
||||
{
|
||||
struct mps_softc *sc;
|
||||
struct mps_cfg_page_req *page_req;
|
||||
struct mps_ext_cfg_page_req *ext_page_req;
|
||||
void *mps_page;
|
||||
#ifdef __amd64__
|
||||
struct mps_cfg_page_req32 *page_req32;
|
||||
struct mps_cfg_page_req page_req_swab;
|
||||
struct mps_ext_cfg_page_req32 *ext_page_req32;
|
||||
struct mps_ext_cfg_page_req ext_page_req_swab;
|
||||
#endif
|
||||
int error;
|
||||
|
||||
mps_page = NULL;
|
||||
@ -450,47 +443,12 @@ mps_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag,
|
||||
page_req = (void *)arg;
|
||||
ext_page_req = (void *)arg;
|
||||
|
||||
#ifdef __amd64__
|
||||
/* Convert 32-bit structs to native ones. */
|
||||
page_req32 = (void *)arg;
|
||||
ext_page_req32 = (void *)arg;
|
||||
switch (cmd) {
|
||||
case MPSIO_READ_CFG_HEADER32:
|
||||
case MPSIO_READ_CFG_PAGE32:
|
||||
case MPSIO_WRITE_CFG_PAGE32:
|
||||
page_req = &page_req_swab;
|
||||
page_req->header = page_req32->header;
|
||||
page_req->page_address = page_req32->page_address;
|
||||
page_req->buf = PTRIN(page_req32->buf);
|
||||
page_req->len = page_req32->len;
|
||||
page_req->ioc_status = page_req32->ioc_status;
|
||||
break;
|
||||
case MPSIO_READ_EXT_CFG_HEADER32:
|
||||
case MPSIO_READ_EXT_CFG_PAGE32:
|
||||
ext_page_req = &ext_page_req_swab;
|
||||
ext_page_req->header = ext_page_req32->header;
|
||||
ext_page_req->page_address = ext_page_req32->page_address;
|
||||
ext_page_req->buf = PTRIN(ext_page_req32->buf);
|
||||
ext_page_req->len = ext_page_req32->len;
|
||||
ext_page_req->ioc_status = ext_page_req32->ioc_status;
|
||||
break;
|
||||
default:
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
#ifdef __amd64__
|
||||
case MPSIO_READ_CFG_HEADER32:
|
||||
#endif
|
||||
case MPSIO_READ_CFG_HEADER:
|
||||
mps_lock(sc);
|
||||
error = mps_user_read_cfg_header(sc, page_req);
|
||||
mps_unlock(sc);
|
||||
break;
|
||||
#ifdef __amd64__
|
||||
case MPSIO_READ_CFG_PAGE32:
|
||||
#endif
|
||||
case MPSIO_READ_CFG_PAGE:
|
||||
mps_page = malloc(page_req->len, M_MPSUSER, M_WAITOK | M_ZERO);
|
||||
error = copyin(page_req->buf, mps_page,
|
||||
@ -504,17 +462,11 @@ mps_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag,
|
||||
break;
|
||||
error = copyout(mps_page, page_req->buf, page_req->len);
|
||||
break;
|
||||
#ifdef __amd64__
|
||||
case MPSIO_READ_EXT_CFG_HEADER32:
|
||||
#endif
|
||||
case MPSIO_READ_EXT_CFG_HEADER:
|
||||
mps_lock(sc);
|
||||
error = mps_user_read_extcfg_header(sc, ext_page_req);
|
||||
mps_unlock(sc);
|
||||
break;
|
||||
#ifdef __amd64__
|
||||
case MPSIO_READ_EXT_CFG_PAGE32:
|
||||
#endif
|
||||
case MPSIO_READ_EXT_CFG_PAGE:
|
||||
mps_page = malloc(ext_page_req->len, M_MPSUSER, M_WAITOK|M_ZERO);
|
||||
error = copyin(ext_page_req->buf, mps_page,
|
||||
@ -528,9 +480,6 @@ mps_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag,
|
||||
break;
|
||||
error = copyout(mps_page, ext_page_req->buf, ext_page_req->len);
|
||||
break;
|
||||
#ifdef __amd64__
|
||||
case MPSIO_WRITE_CFG_PAGE32:
|
||||
#endif
|
||||
case MPSIO_WRITE_CFG_PAGE:
|
||||
mps_page = malloc(page_req->len, M_MPSUSER, M_WAITOK|M_ZERO);
|
||||
error = copyin(page_req->buf, mps_page, page_req->len);
|
||||
@ -551,33 +500,207 @@ mps_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag,
|
||||
if (mps_page != NULL)
|
||||
free(mps_page, M_MPSUSER);
|
||||
|
||||
if (error)
|
||||
return (error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifdef __amd64__
|
||||
/* Convert native structs to 32-bit ones. */
|
||||
switch (cmd) {
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
|
||||
/* Macros from compat/freebsd32/freebsd32.h */
|
||||
#define PTRIN(v) (void *)(uintptr_t)(v)
|
||||
#define PTROUT(v) (uint32_t)(uintptr_t)(v)
|
||||
|
||||
#define CP(src,dst,fld) do { (dst).fld = (src).fld; } while (0)
|
||||
#define PTRIN_CP(src,dst,fld) \
|
||||
do { (dst).fld = PTRIN((src).fld); } while (0)
|
||||
#define PTROUT_CP(src,dst,fld) \
|
||||
do { (dst).fld = PTROUT((src).fld); } while (0)
|
||||
|
||||
struct mps_cfg_page_req32 {
|
||||
MPI2_CONFIG_PAGE_HEADER header;
|
||||
uint32_t page_address;
|
||||
uint32_t buf;
|
||||
int len;
|
||||
uint16_t ioc_status;
|
||||
};
|
||||
|
||||
struct mps_ext_cfg_page_req32 {
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER header;
|
||||
uint32_t page_address;
|
||||
uint32_t buf;
|
||||
int len;
|
||||
uint16_t ioc_status;
|
||||
};
|
||||
|
||||
struct mps_raid_action32 {
|
||||
uint8_t action;
|
||||
uint8_t volume_bus;
|
||||
uint8_t volume_id;
|
||||
uint8_t phys_disk_num;
|
||||
uint32_t action_data_word;
|
||||
uint32_t buf;
|
||||
int len;
|
||||
uint32_t volume_status;
|
||||
uint32_t action_data[4];
|
||||
uint16_t action_status;
|
||||
uint16_t ioc_status;
|
||||
uint8_t write;
|
||||
};
|
||||
|
||||
struct mps_usr_command32 {
|
||||
uint32_t req;
|
||||
uint32_t req_len;
|
||||
uint32_t rpl;
|
||||
uint32_t rpl_len;
|
||||
uint32_t buf;
|
||||
int len;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
#define MPSIO_READ_CFG_HEADER32 _IOWR('M', 200, struct mps_cfg_page_req32)
|
||||
#define MPSIO_READ_CFG_PAGE32 _IOWR('M', 201, struct mps_cfg_page_req32)
|
||||
#define MPSIO_READ_EXT_CFG_HEADER32 _IOWR('M', 202, struct mps_ext_cfg_page_req32)
|
||||
#define MPSIO_READ_EXT_CFG_PAGE32 _IOWR('M', 203, struct mps_ext_cfg_page_req32)
|
||||
#define MPSIO_WRITE_CFG_PAGE32 _IOWR('M', 204, struct mps_cfg_page_req32)
|
||||
#define MPSIO_RAID_ACTION32 _IOWR('M', 205, struct mps_raid_action32)
|
||||
#define MPSIO_MPS_COMMAND32 _IOWR('M', 210, struct mps_usr_command32)
|
||||
|
||||
static int
|
||||
mps_ioctl32(struct cdev *dev, u_long cmd32, void *_arg, int flag,
|
||||
struct thread *td)
|
||||
{
|
||||
struct mps_cfg_page_req32 *page32 = _arg;
|
||||
struct mps_ext_cfg_page_req32 *ext32 = _arg;
|
||||
struct mps_raid_action32 *raid32 = _arg;
|
||||
struct mps_usr_command32 *user32 = _arg;
|
||||
union {
|
||||
struct mps_cfg_page_req page;
|
||||
struct mps_ext_cfg_page_req ext;
|
||||
struct mps_raid_action raid;
|
||||
struct mps_usr_command user;
|
||||
} arg;
|
||||
u_long cmd;
|
||||
int error;
|
||||
|
||||
switch (cmd32) {
|
||||
case MPSIO_READ_CFG_HEADER32:
|
||||
case MPSIO_READ_CFG_PAGE32:
|
||||
case MPSIO_WRITE_CFG_PAGE32:
|
||||
page_req32->header = page_req->header;
|
||||
page_req32->page_address = page_req->page_address;
|
||||
page_req32->buf = PTROUT(page_req->buf);
|
||||
page_req32->len = page_req->len;
|
||||
page_req32->ioc_status = page_req->ioc_status;
|
||||
if (cmd32 == MPSIO_READ_CFG_HEADER32)
|
||||
cmd = MPSIO_READ_CFG_HEADER;
|
||||
else if (cmd32 == MPSIO_READ_CFG_PAGE32)
|
||||
cmd = MPSIO_READ_CFG_PAGE;
|
||||
else
|
||||
cmd = MPSIO_WRITE_CFG_PAGE;
|
||||
CP(*page32, arg.page, header);
|
||||
CP(*page32, arg.page, page_address);
|
||||
PTRIN_CP(*page32, arg.page, buf);
|
||||
CP(*page32, arg.page, len);
|
||||
CP(*page32, arg.page, ioc_status);
|
||||
break;
|
||||
|
||||
case MPSIO_READ_EXT_CFG_HEADER32:
|
||||
case MPSIO_READ_EXT_CFG_PAGE32:
|
||||
ext_page_req32->header = ext_page_req->header;
|
||||
ext_page_req32->page_address = ext_page_req->page_address;
|
||||
ext_page_req32->buf = PTROUT(ext_page_req->buf);
|
||||
ext_page_req32->len = ext_page_req->len;
|
||||
ext_page_req32->ioc_status = ext_page_req->ioc_status;
|
||||
case MPSIO_READ_EXT_CFG_PAGE32:
|
||||
if (cmd32 == MPSIO_READ_EXT_CFG_HEADER32)
|
||||
cmd = MPSIO_READ_EXT_CFG_HEADER;
|
||||
else
|
||||
cmd = MPSIO_READ_EXT_CFG_PAGE;
|
||||
CP(*ext32, arg.ext, header);
|
||||
CP(*ext32, arg.ext, page_address);
|
||||
PTRIN_CP(*ext32, arg.ext, buf);
|
||||
CP(*ext32, arg.ext, len);
|
||||
CP(*ext32, arg.ext, ioc_status);
|
||||
break;
|
||||
|
||||
case MPSIO_RAID_ACTION32:
|
||||
cmd = MPSIO_RAID_ACTION;
|
||||
CP(*raid32, arg.raid, action);
|
||||
CP(*raid32, arg.raid, volume_bus);
|
||||
CP(*raid32, arg.raid, volume_id);
|
||||
CP(*raid32, arg.raid, phys_disk_num);
|
||||
CP(*raid32, arg.raid, action_data_word);
|
||||
PTRIN_CP(*raid32, arg.raid, buf);
|
||||
CP(*raid32, arg.raid, len);
|
||||
CP(*raid32, arg.raid, volume_status);
|
||||
bcopy(raid32->action_data, arg.raid.action_data,
|
||||
sizeof arg.raid.action_data);
|
||||
CP(*raid32, arg.raid, ioc_status);
|
||||
CP(*raid32, arg.raid, write);
|
||||
break;
|
||||
|
||||
case MPSIO_MPS_COMMAND32:
|
||||
cmd = MPSIO_MPS_COMMAND;
|
||||
PTRIN_CP(*user32, arg.user, req);
|
||||
CP(*user32, arg.user, req_len);
|
||||
PTRIN_CP(*user32, arg.user, rpl);
|
||||
CP(*user32, arg.user, rpl_len);
|
||||
PTRIN_CP(*user32, arg.user, buf);
|
||||
CP(*user32, arg.user, len);
|
||||
CP(*user32, arg.user, flags);
|
||||
break;
|
||||
default:
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
error = mps_ioctl(dev, cmd, &arg, flag, td);
|
||||
if (error == 0 && (cmd32 & IOC_OUT) != 0) {
|
||||
switch (cmd32) {
|
||||
case MPSIO_READ_CFG_HEADER32:
|
||||
case MPSIO_READ_CFG_PAGE32:
|
||||
case MPSIO_WRITE_CFG_PAGE32:
|
||||
CP(arg.page, *page32, header);
|
||||
CP(arg.page, *page32, page_address);
|
||||
PTROUT_CP(arg.page, *page32, buf);
|
||||
CP(arg.page, *page32, len);
|
||||
CP(arg.page, *page32, ioc_status);
|
||||
break;
|
||||
|
||||
case MPSIO_READ_EXT_CFG_HEADER32:
|
||||
case MPSIO_READ_EXT_CFG_PAGE32:
|
||||
CP(arg.ext, *ext32, header);
|
||||
CP(arg.ext, *ext32, page_address);
|
||||
PTROUT_CP(arg.ext, *ext32, buf);
|
||||
CP(arg.ext, *ext32, len);
|
||||
CP(arg.ext, *ext32, ioc_status);
|
||||
break;
|
||||
|
||||
case MPSIO_RAID_ACTION32:
|
||||
CP(arg.raid, *raid32, action);
|
||||
CP(arg.raid, *raid32, volume_bus);
|
||||
CP(arg.raid, *raid32, volume_id);
|
||||
CP(arg.raid, *raid32, phys_disk_num);
|
||||
CP(arg.raid, *raid32, action_data_word);
|
||||
PTROUT_CP(arg.raid, *raid32, buf);
|
||||
CP(arg.raid, *raid32, len);
|
||||
CP(arg.raid, *raid32, volume_status);
|
||||
bcopy(arg.raid.action_data, raid32->action_data,
|
||||
sizeof arg.raid.action_data);
|
||||
CP(arg.raid, *raid32, ioc_status);
|
||||
CP(arg.raid, *raid32, write);
|
||||
break;
|
||||
|
||||
case MPSIO_MPS_COMMAND32:
|
||||
PTROUT_CP(arg.user, *user32, req);
|
||||
CP(arg.user, *user32, req_len);
|
||||
PTROUT_CP(arg.user, *user32, rpl);
|
||||
CP(arg.user, *user32, rpl_len);
|
||||
PTROUT_CP(arg.user, *user32, buf);
|
||||
CP(arg.user, *user32, len);
|
||||
CP(arg.user, *user32, flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
#endif /* COMPAT_FREEBSD32 */
|
||||
|
||||
static int
|
||||
mps_ioctl_devsw(struct cdev *dev, u_long com, caddr_t arg, int flag,
|
||||
struct thread *td)
|
||||
{
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
if (SV_CURPROC_FLAG(SV_ILP32))
|
||||
return (mps_ioctl32(dev, com, arg, flag, td));
|
||||
#endif
|
||||
return (mps_ioctl(dev, com, arg, flag, td));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user