Adn scsipi_target_detach() and scsipi_thread_call_callback() as discussed
on tech-kern. scsipi_target_detach() accept wildcard target/lun as requested.
This commit is contained in:
parent
511c17cad8
commit
f2cacede49
@ -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 @@ scsibusdetach(self, flags)
|
||||
{
|
||||
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 @@ scsibusdetach(self, flags)
|
||||
/*
|
||||
* 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 @@ scsibusioctl(dev, cmd, addr, flag, p)
|
||||
*/
|
||||
switch (cmd) {
|
||||
case SCBUSIOSCAN:
|
||||
case SCBUSIODETACH:
|
||||
case SCBUSIORESET:
|
||||
if ((flag & FWRITE) == 0)
|
||||
return (EBADF);
|
||||
@ -953,6 +938,16 @@ scsibusioctl(dev, cmd, addr, flag, p)
|
||||
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:
|
||||
|
@ -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 @@ scsipi_completion_thread(arg)
|
||||
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;
|
||||
@ -2002,6 +2014,33 @@ scsipi_create_completion_thread(arg)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
@ -2271,6 +2310,62 @@ scsipi_async_event_channel_reset(chan)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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:
|
||||
|
@ -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 @@ struct scsipi_channel {
|
||||
|
||||
/* 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 @@ struct scsipi_channel {
|
||||
#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 __P((struct scsipi_xfer *, int));
|
||||
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 @@ void scsipi_remove_periph __P((struct scsipi_channel *,
|
||||
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 *));
|
||||
|
Loading…
Reference in New Issue
Block a user