Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Add in an ioctl entry point so scsictl mediated b...
details: https://anonhg.NetBSD.org/src/rev/759087f18a1a
branches: trunk
changeset: 477181:759087f18a1a
user: mjacob <mjacob%NetBSD.org@localhost>
date: Thu Oct 14 02:31:11 1999 +0000
description:
Add in an ioctl entry point so scsictl mediated bus resets will work.
Redo how we start commands- do a 'slow' start function which then
looks to see when we're done the configuration process at which point
it *then* enables sync/wide mode. Set the max openings amount to the
true max openings- not a synthetic. Add a timeout driven command requeue
function so that Loop Down events well freeze things until a later point
in time where they might be restarted.
diffstat:
sys/dev/ic/isp_netbsd.c | 351 +++++++++++++++++++++++++++++++----------------
1 files changed, 228 insertions(+), 123 deletions(-)
diffs (truncated from 540 to 300 lines):
diff -r 9dd0e0cf36e5 -r 759087f18a1a sys/dev/ic/isp_netbsd.c
--- a/sys/dev/ic/isp_netbsd.c Thu Oct 14 02:27:12 1999 +0000
+++ b/sys/dev/ic/isp_netbsd.c Thu Oct 14 02:31:11 1999 +0000
@@ -1,5 +1,4 @@
-/* $NetBSD: isp_netbsd.c,v 1.16 1999/09/30 23:06:18 thorpej Exp $ */
-/* release_6_5_99 */
+/* $NetBSD: isp_netbsd.c,v 1.17 1999/10/14 02:31:11 mjacob Exp $ */
/*
* Platform (NetBSD) dependent common attachment code for Qlogic adapters.
* Matthew Jacob <mjacob%nas.nasa.gov@localhost>
@@ -32,18 +31,20 @@
*/
#include <dev/ic/isp_netbsd.h>
+#include <sys/scsiio.h>
static void ispminphys __P((struct buf *));
+static int32_t ispcmd_slow __P((ISP_SCSI_XFER_T *));
static int32_t ispcmd __P((ISP_SCSI_XFER_T *));
+static int
+ispioctl __P((struct scsipi_link *, u_long, caddr_t, int, struct proc *));
static struct scsipi_device isp_dev = { NULL, NULL, NULL, NULL };
static int isp_poll __P((struct ispsoftc *, ISP_SCSI_XFER_T *, int));
static void isp_watch __P((void *));
+static void isp_command_requeue __P((void *));
static void isp_internal_restart __P((void *));
-#define FC_OPENINGS RQUEST_QUEUE_LEN / (MAX_FC_TARG-1)
-#define PI_OPENINGS RQUEST_QUEUE_LEN / (MAX_TARGETS-1)
-
/*
* Complete attachment of hardware, include subdevices.
*/
@@ -52,14 +53,15 @@
struct ispsoftc *isp;
{
- isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
isp->isp_osinfo._adapter.scsipi_minphys = ispminphys;
+ isp->isp_osinfo._adapter.scsipi_ioctl = ispioctl;
isp->isp_state = ISP_RUNSTATE;
isp->isp_osinfo._link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
isp->isp_osinfo._link.adapter_softc = isp;
isp->isp_osinfo._link.device = &isp_dev;
isp->isp_osinfo._link.adapter = &isp->isp_osinfo._adapter;
+ isp->isp_osinfo._link.openings = isp->isp_maxcmds;
TAILQ_INIT(&isp->isp_osinfo.waitq);
if (IS_FC(isp)) {
@@ -67,6 +69,7 @@
* Give it another chance here to come alive...
*/
fcparam *fcp = isp->isp_param;
+ isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
if (fcp->isp_fwstate != FW_READY) {
(void) isp_control(isp, ISPCTL_FCLINK_TEST, NULL);
}
@@ -79,12 +82,11 @@
#else
isp->isp_osinfo._link.scsipi_scsi.max_lun = 15;
#endif
- isp->isp_osinfo._link.openings = FC_OPENINGS;
isp->isp_osinfo._link.scsipi_scsi.adapter_target =
((fcparam *)isp->isp_param)->isp_loopid;
} else {
sdparam *sdp = isp->isp_param;
- isp->isp_osinfo._link.openings = PI_OPENINGS;
+ isp->isp_osinfo._adapter.scsipi_cmd = ispcmd_slow;
isp->isp_osinfo._link.scsipi_scsi.max_target = MAX_TARGETS-1;
if (isp->isp_bustype == ISP_BT_SBUS) {
isp->isp_osinfo._link.scsipi_scsi.max_lun = 7;
@@ -101,6 +103,8 @@
}
isp->isp_osinfo._link.scsipi_scsi.adapter_target =
sdp->isp_initiator_id;
+ isp->isp_osinfo.discovered[0] = 1 << sdp->isp_initiator_id;
+ isp->isp_osinfo.discovered[1] = 1 << sdp->isp_initiator_id;
if (IS_12X0(isp)) {
isp->isp_osinfo._link_b = isp->isp_osinfo._link;
sdp++;
@@ -109,15 +113,12 @@
isp->isp_osinfo._link_b.scsipi_scsi.channel = 1;
}
}
- if (isp->isp_osinfo._link.openings < 2)
- isp->isp_osinfo._link.openings = 2;
isp->isp_osinfo._link.type = BUS_SCSI;
/*
* Send a SCSI Bus Reset (used to be done as part of attach,
* but now left to the OS outer layers).
*/
-
if (IS_SCSI(isp)) {
int bus = 0;
(void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
@@ -132,7 +133,7 @@
* Start the watchdog.
*/
isp->isp_dogactive = 1;
- timeout(isp_watch, isp, 30 * hz);
+ timeout(isp_watch, isp, WATCH_INTERVAL * hz);
/*
* And attach children (if any).
@@ -164,44 +165,86 @@
minphys(bp);
}
-static int
+static int32_t
+ispcmd_slow(xs)
+ ISP_SCSI_XFER_T *xs;
+{
+ /*
+ * Have we completed discovery for this adapter?
+ */
+ if ((xs->xs_control & XS_CTL_DISCOVERY) == 0) {
+ struct ispsoftc *isp = XS_ISP(xs);
+ sdparam *sdp = isp->isp_param;
+ int s = splbio();
+ int chan = XS_CHANNEL(xs), chmax = IS_12X0(isp)? 2 : 1;
+ u_int16_t f = DPARM_DEFAULT;
+
+ sdp += chan;
+ if (xs->sc_link->quirks & SDEV_NOSYNC) {
+ f ^= DPARM_SYNC;
+ }
+ if (xs->sc_link->quirks & SDEV_NOWIDE) {
+ f ^= DPARM_WIDE;
+ }
+ if (xs->sc_link->quirks & SDEV_NOTAG) {
+ f ^= DPARM_TQING;
+ }
+ sdp->isp_devparam[XS_TGT(xs)].dev_flags = f;
+ sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
+ isp->isp_osinfo.discovered[chan] |= (1 << XS_TGT(xs));
+ f = 0xffff ^ (1 << sdp->isp_initiator_id);
+ for (chan = 0; chan < chmax; chan++) {
+ if (isp->isp_osinfo.discovered[chan] == f)
+ break;
+ }
+ if (chan == chmax) {
+ isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
+ isp->isp_update = 1;
+ if (IS_12X0(isp))
+ isp->isp_update |= 2;
+ }
+ (void) splx(s);
+ }
+ return (ispcmd(xs));
+}
+
+static int
+ispioctl(sc_link, cmd, addr, flag, p)
+ struct scsipi_link *sc_link;
+ u_long cmd;
+ caddr_t addr;
+ int flag;
+ struct proc *p;
+{
+ struct ispsoftc *isp = sc_link->adapter_softc;
+ int s, chan, retval = ENOTTY;
+
+ switch (cmd) {
+ case SCBUSIORESET:
+ chan = sc_link->scsipi_scsi.channel;
+ s = splbio();
+ if (isp_control(isp, ISPCTL_RESET_BUS, &chan))
+ retval = EIO;
+ else
+ retval = 0;
+ (void) splx(s);
+ break;
+ default:
+ break;
+ }
+ return (retval);
+}
+
+
+static int32_t
ispcmd(xs)
ISP_SCSI_XFER_T *xs;
{
struct ispsoftc *isp;
- int result;
- int s;
+ int result, s;
isp = XS_ISP(xs);
s = splbio();
- /*
- * This is less efficient than I would like in that the
- * majority of cases will have to do some pointer deferences
- * to find out that things don't need to be updated.
- */
-#if 0 /* XXX THORPEJ */
- if ((xs->xs_control & XS_CTL_DISCOVERY) == 0 &&
- (isp->isp_type & ISP_HA_SCSI)) {
- sdparam *sdp = isp->isp_param;
- sdp += XS_CHANNEL(xs);
- if (sdp->isp_devparam[XS_TGT(xs)].dev_flags !=
- sdp->isp_devparam[XS_TGT(xs)].cur_dflags) {
- u_int16_t f = DPARM_WIDE|DPARM_SYNC|DPARM_TQING;
- if (xs->sc_link->quirks & SDEV_NOSYNC)
- f &= ~DPARM_SYNC;
- if (xs->sc_link->quirks & SDEV_NOWIDE)
- f &= ~DPARM_WIDE;
- if (xs->sc_link->quirks & SDEV_NOTAG)
- f &= ~DPARM_TQING;
- sdp->isp_devparam[XS_TGT(xs)].dev_flags &=
- ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING);
- sdp->isp_devparam[XS_TGT(xs)].dev_flags |= f;
- sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
- isp->isp_update |= (1 << XS_CHANNEL(xs));
- }
- }
-#endif /* XXX THORPEJ */
-
if (isp->isp_state < ISP_RUNSTATE) {
DISABLE_INTS(isp);
isp_init(isp);
@@ -209,7 +252,7 @@
ENABLE_INTS(isp);
(void) splx(s);
XS_SETERR(xs, HBA_BOTCH);
- return (CMD_COMPLETE);
+ return (COMPLETE);
}
isp->isp_state = ISP_RUNSTATE;
ENABLE_INTS(isp);
@@ -218,7 +261,6 @@
/*
* Check for queue blockage...
*/
-
if (isp->isp_osinfo.blocked) {
if (xs->xs_control & XS_CTL_POLL) {
xs->error = XS_DRIVER_STUFFUP;
@@ -227,37 +269,70 @@
}
TAILQ_INSERT_TAIL(&isp->isp_osinfo.waitq, xs, adapter_q);
splx(s);
- return (CMD_QUEUED);
+ return (SUCCESSFULLY_QUEUED);
}
-
DISABLE_INTS(isp);
result = ispscsicmd(xs);
ENABLE_INTS(isp);
- if (result != CMD_QUEUED || (xs->xs_control & XS_CTL_POLL) == 0) {
+
+ if ((xs->xs_control & XS_CTL_POLL) == 0) {
+ switch (result) {
+ case CMD_QUEUED:
+ result = SUCCESSFULLY_QUEUED;
+ break;
+ case CMD_EAGAIN:
+ result = TRY_AGAIN_LATER;
+ break;
+ case CMD_RQLATER:
+ result = SUCCESSFULLY_QUEUED;
+ timeout(isp_command_requeue, xs, hz);
+ break;
+ case CMD_COMPLETE:
+ result = COMPLETE;
+ break;
+ }
(void) splx(s);
return (result);
}
+ switch (result) {
+ case CMD_QUEUED:
+ result = SUCCESSFULLY_QUEUED;
+ break;
+ case CMD_RQLATER:
+ case CMD_EAGAIN:
+ if (XS_NOERR(xs)) {
+ xs->error = XS_DRIVER_STUFFUP;
+ }
+ result = TRY_AGAIN_LATER;
+ break;
+ case CMD_COMPLETE:
+ result = COMPLETE;
+ break;
+
+ }
/*
* If we can't use interrupts, poll on completion.
*/
- if (isp_poll(isp, xs, XS_TIME(xs))) {
- /*
- * If no other error occurred but we didn't finish,
- * something bad happened.
- */
- if (XS_IS_CMD_DONE(xs) == 0) {
Home |
Main Index |
Thread Index |
Old Index