diff --git a/sys/dev/ic/isp_netbsd.c b/sys/dev/ic/isp_netbsd.c new file mode 100644 index 000000000000..3697b7ca3e78 --- /dev/null +++ b/sys/dev/ic/isp_netbsd.c @@ -0,0 +1,189 @@ +/* $NetBSD: isp_netbsd.c,v 1.1 1998/07/15 19:44:04 mjacob Exp $ */ +/* $Id: isp_netbsd.c,v 1.1 1998/07/15 19:44:04 mjacob Exp $ */ +/* + * Platform (NetBSD) dependent common attachment code for Qlogic adapters. + * + *--------------------------------------- + * Copyright (c) 1997, 1998 by Matthew Jacob + * NASA/Ames Research Center + * All rights reserved. + *--------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The author may be reached via electronic communications at + * + * mjacob@nas.nasa.gov + * mjacob@feral.com + * + * or, via United States Postal Address + * + * Matthew Jacob + * Feral Software + * 2339 3rd Street + * Suite 24 + * San Francisco, CA, 94107 + */ +/* + * $Log: isp_netbsd.c,v $ + * Revision 1.1 1998/07/15 19:44:04 mjacob + * NetBSD OS specific routines and definitions. + * + * Revision 1.5 1998/07/15 19:35:35 mjacob + * checkpoint + * + * Revision 1.4 1998/06/12 19:48:24 mjacob + * checkpoint + * + * Revision 1.3 1998/04/15 17:40:25 mjacob + * oops + * + * Revision 1.2 1998/04/14 17:31:49 mjacob + * fix headers + * + */ + +#include + +static void ispminphys __P((struct buf *)); +static int32_t ispcmd __P((ISP_SCSI_XFER_T *)); + +static struct scsipi_adapter isp_switch = { + ispcmd, ispminphys, 0, 0 +}; + +static struct scsipi_device isp_dev = { NULL, NULL, NULL, NULL }; +static int isp_poll __P((struct ispsoftc *, ISP_SCSI_XFER_T *, int)); + +/* + * Complete attachment of hardware, include subdevices. + */ +void +isp_attach(isp) + struct ispsoftc *isp; +{ + 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_switch; + + if (isp->isp_type & ISP_HA_FC) { + isp->isp_osinfo._link.scsipi_scsi.max_target = MAX_FC_TARG-1; + isp->isp_osinfo._link.openings = + RQUEST_QUEUE_LEN / (MAX_FC_TARG-1); + isp->isp_osinfo._link.scsipi_scsi.adapter_target = 0xff; + } else { + isp->isp_osinfo._link.openings = + RQUEST_QUEUE_LEN / (MAX_TARGETS-1); + isp->isp_osinfo._link.scsipi_scsi.max_target = MAX_TARGETS-1; + isp->isp_osinfo._link.scsipi_scsi.adapter_target = + ((sdparam *)isp->isp_param)->isp_initiator_id; + } + if (isp->isp_osinfo._link.openings < 2) + isp->isp_osinfo._link.openings = 2; + isp->isp_osinfo._link.type = BUS_SCSI; + config_found((void *)isp, &isp->isp_osinfo._link, scsiprint); +} + +/* + * minphys our xfers + * + * Unfortunately, the buffer pointer describes the target device- not the + * adapter device, so we can't use the pointer to find out what kind of + * adapter we are and adjust accordingly. + */ + +static void +ispminphys(bp) + struct buf *bp; +{ + /* + * XX: Only the 1020 has a 24 bit limit. + */ + if (bp->b_bcount >= (1 << 24)) { + bp->b_bcount = (1 << 24); + } + minphys(bp); +} + +static int +ispcmd(xs) + ISP_SCSI_XFER_T *xs; +{ + struct ispsoftc *isp; + int r; + ISP_LOCKVAL_DECL; + + isp = XS_ISP(xs); + ISP_LOCK(isp); + r = ispscsicmd(xs); + if (r != CMD_QUEUED || (xs->flags & SCSI_POLL) == 0) { + ISP_UNLOCK(isp); + return (r); + } + + /* + * 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) { + isp->isp_nactive--; + if (isp->isp_nactive < 0) + isp->isp_nactive = 0; + if (XS_NOERR(xs)) { + isp_lostcmd(isp, xs); + XS_SETERR(xs, HBA_BOTCH); + } + } + } + ISP_UNLOCK(isp); + return (CMD_COMPLETE); +} + +static int +isp_poll(isp, xs, mswait) + struct ispsoftc *isp; + ISP_SCSI_XFER_T *xs; + int mswait; +{ + + while (mswait) { + /* Try the interrupt handling routine */ + (void)isp_intr((void *)isp); + + /* See if the xs is now done */ + if (XS_IS_CMD_DONE(xs)) { + return (0); + } + SYS_DELAY(1000); /* wait one millisecond */ + mswait--; + } + return (1); +} diff --git a/sys/dev/ic/isp_netbsd.h b/sys/dev/ic/isp_netbsd.h new file mode 100644 index 000000000000..3962953f7dfa --- /dev/null +++ b/sys/dev/ic/isp_netbsd.h @@ -0,0 +1,160 @@ +/* $NetBSD: isp_netbsd.h,v 1.1 1998/07/15 19:44:04 mjacob Exp $ */ +/* $Id: isp_netbsd.h,v 1.1 1998/07/15 19:44:04 mjacob Exp $ */ +/* + * NetBSD Specific definitions for the Qlogic ISP Host Adapter + * + *--------------------------------------- + * Copyright (c) 1997, 1998 by Matthew Jacob + * NASA/Ames Research Center + * All rights reserved. + *--------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef _ISP_NETBSD_H +#define _ISP_NETBSD_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#define ISP_VERSION_STRING "Version 0.94 Wed Jul 15 12:04:59 PDT 1998" + +#define ISP_SCSI_XFER_T struct scsipi_xfer +struct isposinfo { + struct device _dev; + struct scsipi_link _link; +}; +#define MAXISPREQUEST 256 + +#include +#include +#include + +#define PRINTF printf +#define IDPRINTF(lev, x) if (isp->isp_dblev >= lev) printf x +#ifdef SCSIDEBUG +#define DFLT_DBLEVEL 2 +#else +#define DFLT_DBLEVEL 1 +#endif + +#define ISP_LOCKVAL_DECL int isp_spl_save +#define ISP_LOCK(x) isp_spl_save = splbio() +#define ISP_UNLOCK(x) (void) splx(isp_spl_save) +#define ISP_ILOCK ISP_LOCK +#define ISP_IUNLOCK ISP_UNLOCK + + +#define XS_NULL(xs) xs == NULL || xs->sc_link == NULL +#define XS_ISP(xs) (xs)->sc_link->adapter_softc +#define XS_LUN(xs) (xs)->sc_link->scsipi_scsi.lun +#define XS_TGT(xs) (xs)->sc_link->scsipi_scsi.target +#define XS_RESID(xs) (xs)->resid +#define XS_XFRLEN(xs) (xs)->datalen +#define XS_CDBLEN(xs) (xs)->cmdlen +#define XS_CDBP(xs) (xs)->cmd +#define XS_STS(xs) (xs)->status +#define XS_TIME(xs) (xs)->timeout +#define XS_SNSP(xs) (&(xs)->sense.scsi_sense) +#define XS_SNSLEN(xs) (sizeof (xs)->sense.scsi_sense) +#define XS_SNSKEY(xs) ((xs)->sense.scsi_sense.flags) + +#define HBA_NOERROR XS_NOERROR +#define HBA_BOTCH XS_DRIVER_STUFFUP +#define HBA_CMDTIMEOUT XS_TIMEOUT +#define HBA_SELTIMEOUT XS_SELTIMEOUT +#define HBA_TGTBSY XS_BUSY +#define HBA_BUSRESET XS_DRIVER_STUFFUP +#define HBA_ABORTED XS_DRIVER_STUFFUP +#define HBA_DATAOVR XS_DRIVER_STUFFUP +#define HBA_ARQFAIL XS_DRIVER_STUFFUP + +#define XS_SNS_IS_VALID(xs) (xs)->error = XS_SENSE +#define XS_IS_SNS_VALID(xs) ((xs)->error == XS_SENSE) + +#define XS_INITERR(xs) (xs)->error = 0 +#define XS_SETERR(xs, v) (xs)->error = v +#define XS_ERR(xs) (xs)->error +#define XS_NOERR(xs) (xs)->error == XS_NOERROR + +#define XS_CMD_DONE(xs) (xs)->flags |= ITSDONE, scsipi_done(xs) +#define XS_IS_CMD_DONE(xs) (((xs)->flags & ITSDONE) != 0) + +/* + * We use whether or not we're a polled command to decide about tagging. + */ +#define XS_CANTAG(xs) (((xs)->flags & SCSI_POLL) != 0) + +/* + * This is our default tag (ordered). + */ +#define XS_KINDOF_TAG(xs) \ + (((xs)->flags & SCSI_URGENT)? REQFLAG_HTAG : REQFLAG_OTAG) + +#define CMD_COMPLETE COMPLETE +#define CMD_EAGAIN TRY_AGAIN_LATER +#define CMD_QUEUED SUCCESSFULLY_QUEUED + + + +#define isp_name isp_osinfo._dev.dv_xname + + +#define SYS_DELAY(x) delay(x) + +#define WATCH_INTERVAL 30 +#define START_WATCHDOG(f, s) \ + timeout(f, s, WATCH_INTERVAL * hz), s->isp_dogactive = 1 + +#define RESTART_WATCHDOG(f, s) START_WATCHDOG(f, s) +#define STOP_WATCHDOG(f, s) untimeout(f, s), s->isp_dogactive = 0 + + +extern void isp_attach __P((struct ispsoftc *)); + +#endif /* _ISP_NETBSD_H */