svn commit: r213702 - head/sys/dev/mps

Matthew D Fleming mdf at FreeBSD.org
Mon Oct 11 21:26:24 UTC 2010


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));
 }


More information about the svn-src-head mailing list