summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2014-04-22 08:48:51 +0000
committerdlg <dlg@openbsd.org>2014-04-22 08:48:51 +0000
commite4be0aa51bb721c507a964667780c03cb084fbea (patch)
treef9be7814bff69e642c19950bee5804b7324be07d
parenteffectively use emult_realloc, okay guenther@ (diff)
downloadwireguard-openbsd-e4be0aa51bb721c507a964667780c03cb084fbea.tar.xz
wireguard-openbsd-e4be0aa51bb721c507a964667780c03cb084fbea.zip
move vscsi from using scsi_req_probe and scsi_req_detach to using
the newly minted scsi_probe and scsi_detach respectively from a task it runs itself. the probe and detach ioctls requests work the same before and after this change, but this paves the way for vscsi being able to report the status of these requests back to userland. discussed with claudio@ tested with current iscsid and an md3200i
-rw-r--r--sys/dev/vscsi.c76
1 files changed, 68 insertions, 8 deletions
diff --git a/sys/dev/vscsi.c b/sys/dev/vscsi.c
index 16250ea1158..13497a2b272 100644
--- a/sys/dev/vscsi.c
+++ b/sys/dev/vscsi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vscsi.c,v 1.28 2014/01/22 01:21:33 dlg Exp $ */
+/* $OpenBSD: vscsi.c,v 1.29 2014/04/22 08:48:51 dlg Exp $ */
/*
* Copyright (c) 2008 David Gwynne <dlg@openbsd.org>
@@ -27,6 +27,7 @@
#include <sys/queue.h>
#include <sys/rwlock.h>
#include <sys/pool.h>
+#include <sys/task.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/selinfo.h>
@@ -106,7 +107,9 @@ struct scsi_adapter vscsi_switch = {
int vscsi_i2t(struct vscsi_softc *, struct vscsi_ioc_i2t *);
int vscsi_data(struct vscsi_softc *, struct vscsi_ioc_data *, int);
int vscsi_t2i(struct vscsi_softc *, struct vscsi_ioc_t2i *);
-
+int vscsi_devevent(struct vscsi_softc *, u_long,
+ struct vscsi_ioc_devevent *);
+void vscsi_devevent_task(void *, void *);
void vscsi_done(struct vscsi_softc *, struct vscsi_ccb *);
void * vscsi_ccb_get(void *);
@@ -292,7 +295,6 @@ int
vscsiioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
{
struct vscsi_softc *sc = DEV2SC(dev);
- struct vscsi_ioc_devevent *de = (struct vscsi_ioc_devevent *)addr;
int read = 0;
int err = 0;
@@ -317,12 +319,9 @@ vscsiioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
case VSCSI_REQPROBE:
- err = scsi_req_probe(sc->sc_scsibus, de->target, de->lun);
- break;
-
case VSCSI_REQDETACH:
- err = scsi_req_detach(sc->sc_scsibus, de->target, de->lun,
- DETACH_FORCE);
+ err = vscsi_devevent(sc, cmd,
+ (struct vscsi_ioc_devevent *)addr);
break;
default:
@@ -473,6 +472,67 @@ vscsi_t2i(struct vscsi_softc *sc, struct vscsi_ioc_t2i *t2i)
return (rv);
}
+struct vscsi_devevent_task {
+ struct task t;
+ struct vscsi_ioc_devevent de;
+ u_long cmd;
+};
+
+int
+vscsi_devevent(struct vscsi_softc *sc, u_long cmd,
+ struct vscsi_ioc_devevent *de)
+{
+ struct vscsi_devevent_task *dt;
+
+ dt = malloc(sizeof(*dt), M_TEMP, M_WAITOK | M_CANFAIL);
+ if (dt == NULL)
+ return (ENOMEM);
+
+ task_set(&dt->t, vscsi_devevent_task, sc, dt);
+ dt->de = *de;
+ dt->cmd = cmd;
+
+ device_ref(&sc->sc_dev);
+ task_add(systq, &dt->t);
+
+ return (0);
+}
+
+void
+vscsi_devevent_task(void *xsc, void *xdt)
+{
+ struct vscsi_softc *sc = xsc;
+ struct vscsi_devevent_task *dt = xdt;
+ int state;
+
+ mtx_enter(&sc->sc_state_mtx);
+ state = sc->sc_state;
+ mtx_leave(&sc->sc_state_mtx);
+
+ if (state != VSCSI_S_RUNNING)
+ goto gone;
+
+ switch (dt->cmd) {
+ case VSCSI_REQPROBE:
+ scsi_probe(sc->sc_scsibus, dt->de.target, dt->de.lun);
+ break;
+ case VSCSI_REQDETACH:
+ scsi_detach(sc->sc_scsibus, dt->de.target, dt->de.lun,
+ DETACH_FORCE);
+ break;
+#ifdef DIAGNOSTIC
+ default:
+ panic("unexpected vscsi_devevent cmd");
+ /* NOTREACHED */
+ }
+#endif
+
+gone:
+ device_unref(&sc->sc_dev);
+
+ free(dt, M_TEMP);
+}
+
int
vscsipoll(dev_t dev, int events, struct proc *p)
{