summaryrefslogtreecommitdiffstats
path: root/sys/dev/aac/aac.c
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/dev/aac/aac.c
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/dev/aac/aac.c')
-rw-r--r--sys/dev/aac/aac.c39
1 files changed, 31 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.
*/
OpenPOWER on IntegriCloud