Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/scsipi Adn scsipi_target_detach() and scsipi_thread_...
details: https://anonhg.NetBSD.org/src/rev/2b854a342cef
branches: trunk
changeset: 512887:2b854a342cef
user: bouyer <bouyer%NetBSD.org@localhost>
date: Wed Jul 18 20:19:24 2001 +0000
description:
Adn scsipi_target_detach() and scsipi_thread_call_callback() as discussed
on tech-kern. scsipi_target_detach() accept wildcard target/lun as requested.
diffstat:
sys/dev/scsipi/scsiconf.c | 31 ++++------
sys/dev/scsipi/scsipi_base.c | 123 ++++++++++++++++++++++++++++++++++++++----
sys/dev/scsipi/scsipiconf.h | 11 +++-
3 files changed, 132 insertions(+), 33 deletions(-)
diffs (273 lines):
diff -r 56a062f015b8 -r 2b854a342cef sys/dev/scsipi/scsiconf.c
--- a/sys/dev/scsipi/scsiconf.c Wed Jul 18 19:29:40 2001 +0000
+++ b/sys/dev/scsipi/scsiconf.c Wed Jul 18 20:19:24 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: scsiconf.c,v 1.158 2001/06/11 13:58:18 pk Exp $ */
+/* $NetBSD: scsiconf.c,v 1.159 2001/07/18 20:19:24 bouyer Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -257,8 +257,6 @@
{
struct scsibus_softc *sc = (void *) self;
struct scsipi_channel *chan = sc->sc_channel;
- struct scsipi_periph *periph;
- int target, lun, error;
/*
* Shut down the channel.
@@ -268,21 +266,7 @@
/*
* Now detach all of the periphs.
*/
- for (target = 0; target < chan->chan_ntargets; target++) {
- if (target == chan->chan_id)
- continue;
- for (lun = 0; lun < chan->chan_nluns; lun++) {
- periph = scsipi_lookup_periph(chan, target, lun);
- if (periph == NULL)
- continue;
- error = config_detach(periph->periph_dev, flags);
- if (error)
- return (error);
- scsipi_remove_periph(chan, periph);
- free(periph, M_DEVBUF);
- }
- }
- return (0);
+ return scsipi_target_detach(chan, -1, -1, flags);
}
/*
@@ -938,6 +922,7 @@
*/
switch (cmd) {
case SCBUSIOSCAN:
+ case SCBUSIODETACH:
case SCBUSIORESET:
if ((flag & FWRITE) == 0)
return (EBADF);
@@ -953,6 +938,16 @@
break;
}
+ case SCBUSIODETACH:
+ {
+ struct scbusiodetach_args *a =
+ (struct scbusiodetach_args *)addr;
+
+ error = scsipi_target_detach(chan, a->sa_target, a->sa_lun, 0);
+ break;
+ }
+
+
case SCBUSIORESET:
/* FALLTHROUGH */
default:
diff -r 56a062f015b8 -r 2b854a342cef sys/dev/scsipi/scsipi_base.c
--- a/sys/dev/scsipi/scsipi_base.c Wed Jul 18 19:29:40 2001 +0000
+++ b/sys/dev/scsipi/scsipi_base.c Wed Jul 18 20:19:24 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: scsipi_base.c,v 1.50 2001/07/18 18:21:05 thorpej Exp $ */
+/* $NetBSD: scsipi_base.c,v 1.51 2001/07/18 20:19:24 bouyer Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -1947,29 +1947,41 @@
s = splbio();
xs = TAILQ_FIRST(&chan->chan_complete);
if (xs == NULL &&
- (chan->chan_flags & SCSIPI_CHAN_SHUTDOWN) == 0) {
+ (chan->chan_flags &
+ (SCSIPI_CHAN_SHUTDOWN | SCSIPI_CHAN_CALLBACK)) == 0) {
(void) tsleep(&chan->chan_complete, PRIBIO,
"sccomp", 0);
splx(s);
continue;
}
+ if (chan->chan_flags & SCSIPI_CHAN_CALLBACK) {
+ /* call chan_callback from thread context */
+ chan->chan_flags &= ~SCSIPI_CHAN_CALLBACK;
+ chan->chan_callback(chan, chan->chan_callback_arg);
+ splx(s);
+ continue;
+ }
if (chan->chan_flags & SCSIPI_CHAN_SHUTDOWN) {
splx(s);
break;
}
- TAILQ_REMOVE(&chan->chan_complete, xs, channel_q);
- splx(s);
+ if (xs) {
+ TAILQ_REMOVE(&chan->chan_complete, xs, channel_q);
+ splx(s);
+
+ /*
+ * Have an xfer with an error; process it.
+ */
+ (void) scsipi_complete(xs);
- /*
- * Have an xfer with an error; process it.
- */
- (void) scsipi_complete(xs);
-
- /*
- * Kick the queue; keep it running if it was stopped
- * for some reason.
- */
- scsipi_run_queue(chan);
+ /*
+ * Kick the queue; keep it running if it was stopped
+ * for some reason.
+ */
+ scsipi_run_queue(chan);
+ } else {
+ splx(s);
+ }
}
chan->chan_thread = NULL;
@@ -2003,6 +2015,33 @@
}
/*
+ * scsipi_thread_call_callback:
+ *
+ * request to call a callback from the completion thread
+ */
+int
+scsipi_thread_call_callback(chan, callback, arg)
+ struct scsipi_channel *chan;
+ void (*callback) __P((struct scsipi_channel *, void *));
+ void *arg;
+{
+ int s;
+
+ s = splbio();
+ if (chan->chan_flags & SCSIPI_CHAN_CALLBACK) {
+ splx(s);
+ return EBUSY;
+ }
+ scsipi_channel_freeze(chan, 1);
+ chan->chan_callback = callback;
+ chan->chan_callback_arg = arg;
+ chan->chan_flags |= SCSIPI_CHAN_CALLBACK;
+ wakeup(&chan->chan_complete);
+ splx(s);
+ return(0);
+}
+
+/*
* scsipi_async_event:
*
* Handle an asynchronous event from an adapter.
@@ -2271,6 +2310,62 @@
}
}
+/*
+ * scsipi_target_detach:
+ *
+ * detach all periph associated with a I_T
+ * must be called from valid thread context
+ */
+int
+scsipi_target_detach(chan, target, lun, flags)
+ struct scsipi_channel *chan;
+ int target, lun;
+ int flags;
+{
+ struct scsipi_periph *periph;
+ int ctarget, mintarget, maxtarget;
+ int clun, minlun, maxlun;
+ int error;
+
+ if (target == -1) {
+ mintarget = 0;
+ maxtarget = chan->chan_ntargets;
+ } else {
+ if (target == chan->chan_id)
+ return EINVAL;
+ if (target < 0 || target >= chan->chan_ntargets)
+ return EINVAL;
+ mintarget = target;
+ maxtarget = target + 1;
+ }
+
+ if (lun == -1) {
+ minlun = 0;
+ maxlun = chan->chan_nluns;
+ } else {
+ if (lun < 0 || lun >= chan->chan_nluns)
+ return EINVAL;
+ minlun = lun;
+ maxlun = lun + 1;
+ }
+
+ for (ctarget = 0; ctarget < chan->chan_ntargets; ctarget++) {
+ if (ctarget == chan->chan_id)
+ continue;
+
+ for (clun = minlun; clun < maxlun; clun++) {
+ periph = scsipi_lookup_periph(chan, target, clun);
+ if (periph == NULL)
+ continue;
+ error = config_detach(periph->periph_dev, flags);
+ if (error)
+ return (error);
+ scsipi_remove_periph(chan, periph);
+ free(periph, M_DEVBUF);
+ }
+ }
+ return(0);
+}
/*
* scsipi_adapter_addref:
diff -r 56a062f015b8 -r 2b854a342cef sys/dev/scsipi/scsipiconf.h
--- a/sys/dev/scsipi/scsipiconf.h Wed Jul 18 19:29:40 2001 +0000
+++ b/sys/dev/scsipi/scsipiconf.h Wed Jul 18 20:19:24 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: scsipiconf.h,v 1.54 2001/06/26 15:32:02 bouyer Exp $ */
+/* $NetBSD: scsipiconf.h,v 1.55 2001/07/18 20:19:24 bouyer Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -293,6 +293,10 @@
/* Completed (async) jobs. */
struct scsipi_xfer_queue chan_complete;
+
+ /* callback we may have to call from completion thread */
+ void (*chan_callback) __P((struct scsipi_channel *, void *));
+ void *chan_callback_arg;
};
/* chan_flags */
@@ -300,6 +304,7 @@
#define SCSIPI_CHAN_OPENINGS 0x02 /* use chan_openings */
#define SCSIPI_CHAN_CANGROW 0x04 /* channel can grow resources */
#define SCSIPI_CHAN_NOSETTLE 0x08 /* don't wait for devices to settle */
+#define SCSIPI_CHAN_CALLBACK 0x10 /* has to call chan_callback() */
#define SCSIPI_CHAN_MAX_PERIPH(chan) \
(((chan)->chan_flags & SCSIPI_CHAN_OPENINGS) ? \
@@ -641,6 +646,9 @@
void scsipi_print_sense_data __P((struct scsipi_sense_data *, int));
char *scsipi_decode_sense __P((void *, int));
#endif
+int scsipi_thread_call_callback __P((struct scsipi_channel *,
+ void (*callback) __P((struct scsipi_channel *, void *)),
+ void *));
void scsipi_async_event __P((struct scsipi_channel *,
scsipi_async_event_t, void *));
int scsipi_do_ioctl __P((struct scsipi_periph *, dev_t, u_long, caddr_t,
@@ -658,6 +666,7 @@
struct scsipi_periph *));
struct scsipi_periph *scsipi_lookup_periph __P((struct scsipi_channel *,
int, int));
+int scsipi_target_detach __P((struct scsipi_channel *, int, int, int));
int scsipi_adapter_addref __P((struct scsipi_adapter *));
void scsipi_adapter_delref __P((struct scsipi_adapter *));
Home |
Main Index |
Thread Index |
Old Index