Date: Mon, 11 Oct 2010 21:26:24 +0000 (UTC) From: Matthew D Fleming <mdf@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r213702 - head/sys/dev/mps Message-ID: <201010112126.o9BLQO8F027953@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mdf Date: Mon Oct 11 21:26:24 2010 New Revision: 213702 URL: http://svn.freebsd.org/changeset/base/213702 Log: Fix up the COMPAT_FREEBSD32 ioctl logic for mps(4). Reviewed by: ken Modified: head/sys/dev/mps/mps_ioctl.h head/sys/dev/mps/mps_user.c Modified: head/sys/dev/mps/mps_ioctl.h ============================================================================== --- head/sys/dev/mps/mps_ioctl.h Mon Oct 11 21:23:07 2010 (r213701) +++ head/sys/dev/mps/mps_ioctl.h Mon Oct 11 21:26:24 2010 (r213702) @@ -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_ */ Modified: head/sys/dev/mps/mps_user.c ============================================================================== --- head/sys/dev/mps/mps_user.c Mon Oct 11 21:23:07 2010 (r213701) +++ head/sys/dev/mps/mps_user.c Mon Oct 11 21:26:24 2010 (r213702) @@ -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 @@ Ret: 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, 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, 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, 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, if (mps_page != NULL) free(mps_page, M_MPSUSER); - if (error) - return (error); + return (error); +} + +#ifdef COMPAT_FREEBSD32 -#ifdef __amd64__ - /* Convert native structs to 32-bit ones. */ - switch (cmd) { +/* 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)); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201010112126.o9BLQO8F027953>