summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2008-03-20 17:59:19 +0000
committeremaste <emaste@FreeBSD.org>2008-03-20 17:59:19 +0000
commit2d11776afc7a2a29c7c08b84caa777391a53509c (patch)
treefbf5b089d47bbf5e721ae19b72f4e471a45318e9 /sys
parent0b0672cdd02590fd69d201036cee534eeccfed44 (diff)
downloadFreeBSD-src-2d11776afc7a2a29c7c08b84caa777391a53509c.zip
FreeBSD-src-2d11776afc7a2a29c7c08b84caa777391a53509c.tar.gz
Add ioctls FSACTL_SEND_LARGE_FIB, FSACTL_SEND_RAW_SRB,
FSACTL_LNX_SEND_LARGE_FIB, and FSACTL_LNX_SEND_RAW_SRB, and correct size checks on FIBs passed in from userspace. Both changes were obtained from Adaptec's driver build 15317. Adaptec's commandline RAID tool arcconf uses these ioctls when creating a RAID-10 array (and probably other operations too).
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/aac/aac.c39
-rw-r--r--sys/sys/aac_ioctl.h6
2 files changed, 37 insertions, 8 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index ce84273..816c53e 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -213,6 +213,7 @@ static d_close_t aac_close;
static d_ioctl_t aac_ioctl;
static d_poll_t aac_poll;
static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
+static int aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg);
static void aac_handle_aif(struct aac_softc *sc,
struct aac_fib *fib);
static int aac_rev_check(struct aac_softc *sc, caddr_t udata);
@@ -1693,6 +1694,11 @@ aac_check_firmware(struct aac_softc *sc)
sc->aac_max_fib_size = PAGE_SIZE;
sc->aac_max_fibs_alloc = PAGE_SIZE / sc->aac_max_fib_size;
+ if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
+ sc->flags |= AAC_FLAGS_RAW_IO;
+ device_printf(sc->aac_dev, "Enable Raw I/O\n");
+ }
+
return (0);
}
@@ -2887,11 +2893,19 @@ aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
break;
case FSACTL_SENDFIB:
+ case FSACTL_SEND_LARGE_FIB:
arg = *(caddr_t*)arg;
case FSACTL_LNX_SENDFIB:
+ case FSACTL_LNX_SEND_LARGE_FIB:
debug(1, "FSACTL_SENDFIB");
error = aac_ioctl_sendfib(sc, arg);
break;
+ case FSACTL_SEND_RAW_SRB:
+ arg = *(caddr_t*)arg;
+ case FSACTL_LNX_SEND_RAW_SRB:
+ debug(1, "FSACTL_SEND_RAW_SRB");
+ error = aac_ioctl_send_raw_srb(sc, arg);
+ break;
case FSACTL_AIF_THREAD:
case FSACTL_LNX_AIF_THREAD:
debug(1, "FSACTL_AIF_THREAD");
@@ -3035,10 +3049,10 @@ aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
sizeof(struct aac_fib_header))) != 0)
goto out;
size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
- if (size > sizeof(struct aac_fib)) {
- device_printf(sc->aac_dev, "incoming FIB oversized (%d > %zd)\n",
- size, sizeof(struct aac_fib));
- size = sizeof(struct aac_fib);
+ if (size > sc->aac_max_fib_size) {
+ device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
+ size, sc->aac_max_fib_size);
+ size = sc->aac_max_fib_size;
}
if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
goto out;
@@ -3061,10 +3075,10 @@ aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
* Copy the FIB and data back out to the caller.
*/
size = cm->cm_fib->Header.Size;
- if (size > sizeof(struct aac_fib)) {
- device_printf(sc->aac_dev, "outbound FIB oversized (%d > %zd)\n",
- size, sizeof(struct aac_fib));
- size = sizeof(struct aac_fib);
+ if (size > sc->aac_max_fib_size) {
+ device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
+ size, sc->aac_max_fib_size);
+ size = sc->aac_max_fib_size;
}
error = copyout(cm->cm_fib, ufib, size);
@@ -3078,6 +3092,15 @@ out:
}
/*
+ * Send a passthrough FIB supplied from userspace
+ */
+static int
+aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
+{
+ return (EINVAL);
+}
+
+/*
* Handle an AIF sent to us by the controller; queue it for later reference.
* If the queue fills up, then drop the older entries.
*/
diff --git a/sys/sys/aac_ioctl.h b/sys/sys/aac_ioctl.h
index f01cf70..e29e5ad 100644
--- a/sys/sys/aac_ioctl.h
+++ b/sys/sys/aac_ioctl.h
@@ -69,6 +69,8 @@ union aac_statrequest {
#define FSACTL_LNX_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, \
METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSACTL_LNX_SEND_RAW_SRB CTL_CODE(FILE_DEVICE_CONTROLLER, 2067, \
+ METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSACTL_LNX_GET_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, \
METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSACTL_LNX_OPENCLS_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, \
@@ -93,6 +95,8 @@ union aac_statrequest {
METHOD_NEITHER, FILE_ANY_ACCESS)
#define FSACTL_LNX_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, \
METHOD_NEITHER, FILE_ANY_ACCESS)
+#define FSACTL_LNX_SEND_LARGE_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2138, \
+ METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Why these don't follow the previous convention, I don't know */
#define FSACTL_LNX_NULL_IO_TEST 0x43
@@ -116,6 +120,7 @@ union aac_statrequest {
* command number. 9 is used for the odd overflow case.
*/
#define FSACTL_SENDFIB _IO('8', 2)
+#define FSACTL_SEND_RAW_SRB _IO('8', 19)
#define FSACTL_GET_COMM_PERF_DATA _IO('8', 36)
#define FSACTL_OPENCLS_COMM_PERF_DATA _IO('8', 37)
#define FSACTL_OPEN_GET_ADAPTER_FIB _IO('8', 52)
@@ -128,6 +133,7 @@ union aac_statrequest {
#define FSACTL_GET_PCI_INFO _IO('8', 71)
#define FSACTL_FORCE_DELETE_DISK _IO('8', 72)
#define FSACTL_AIF_THREAD _IO('8', 79)
+#define FSACTL_SEND_LARGE_FIB _IO('8', 90)
#define FSACTL_NULL_IO_TEST _IO('8', 67)
#define FSACTL_SIM_IO_TEST _IO('8', 83)
OpenPOWER on IntegriCloud