Spring MegaChange #1.

----

Make a device for each ISP- really usable only with devfs and add an ioctl
entry point (this can be used to (re)set debug levels, reset the HBA,
rescan the fabric, issue lips, etc).

----

Add in a kernel thread for Fibre Channel cards. The purpose of this
thread is to be woken up to clean up after Fibre Channel events
block things.  Basically, any FC event that casts doubt on the
location or identify of FC devices blocks the queues. When, and
if, we get the PORT DATABASE CHANGED or NAME SERVER DATABASE CHANGED
async event, we activate the kthread which will then, in full thread
context, re-evaluate the local loop and/or the fabric. When it's
satisfied that things are stable, it can then release the blocked
queues and let commands flow again.

The prior mechanism was a lazy evaluation. That is, the next command
to come down the pipe after change events would pay the full price
for re-evaluation. And if this was done off of a softcall, it really
could hang up the system.

These changes brings the FreeBSD port more in line with the Solaris,
Linux and NetBSD ports. It also, more importantly, gets us being
more proactive about topology changes which could then be reflected
upwards to CAM so that the periph driver can be informed sooner
rather than later when things arrive or depart.

---

Add in the (correct) usage of locking macros- we now have lock transition
macros which allow us to transition from holding the CAM lock (Giant)
and grabbing the softc lock and vice versa. Switch over to having this
HBA do real locking. Some folks claim this won't be a win. They're right.
But you have to start somewhere, and this will begin to teach us how
to DTRT for HBAs, etc.

--

Start putting in prototype 2300 support.  Add back in LIP
and Loop Reset as async events that each platform will handle.
Add in another int_bogus instrumentation point.

Do some more substantial target mode cleanups.

MFC after:	8 weeks
This commit is contained in:
Matt Jacob 2001-05-28 21:20:43 +00:00
parent 266aa94283
commit 5d57194434
9 changed files with 565 additions and 255 deletions

View file

@ -212,6 +212,9 @@ isp_reset(struct ispsoftc *isp)
case ISP_HA_FC_2200:
revname = "2200";
break;
case ISP_HA_FC_2300:
revname = "2300";
break;
default:
break;
}
@ -505,7 +508,7 @@ again:
#endif
} else {
ISP_WRITE(isp, RISC_MTR2100, 0x1212);
if (IS_2200(isp)) {
if (IS_2200(isp) || IS_2300(isp)) {
ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
}
}
@ -1135,7 +1138,7 @@ isp_fibre_init(struct ispsoftc *isp)
* Right now we just set extended options to prefer point-to-point
* over loop based upon some soft config options.
*/
if (IS_2200(isp)) {
if (IS_2200(isp) || IS_2300(isp)) {
icbp->icb_fwoptions |= ICBOPT_EXTENDED;
/*
* Prefer or force Point-To-Point instead Loop?
@ -1412,7 +1415,7 @@ isp_fclink_test(struct ispsoftc *isp, int usdelay)
return (-1);
}
fcp->isp_loopid = mbs.param[1];
if (IS_2200(isp)) {
if (IS_2200(isp) || IS_2300(isp)) {
int topo = (int) mbs.param[6];
if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
topo = TOPO_PTP_STUB;
@ -1728,7 +1731,7 @@ isp_pdb_sync(struct ispsoftc *isp)
mbs.param[1] = loopid << 8;
mbs.param[2] = portid >> 16;
mbs.param[3] = portid & 0xffff;
if (IS_2200(isp)) {
if (IS_2200(isp) || IS_2300(isp)) {
/* only issue a PLOGI if not logged in */
mbs.param[1] |= 0x1;
}
@ -2260,7 +2263,6 @@ isp_start(XS_T *xs)
XS_INITERR(xs);
isp = XS_ISP(xs);
/*
* Check to make sure we're supporting initiator role.
*/
@ -2949,6 +2951,7 @@ isp_intr(void *arg)
isp_prt(isp, ISP_LOGDEBUG2,
"bogus intr- isr %x (%x) iptr %x optr %x",
isr, junk, iptr, optr);
isp->isp_intbogus++;
}
while (optr != iptr) {
@ -3336,7 +3339,7 @@ isp_parse_async(struct ispsoftc *isp, int mbox)
FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
isp->isp_sendmarker = 1;
isp_mark_getpdb_all(isp);
isp_prt(isp, ISP_LOGINFO, "LIP occurred");
isp_async(isp, ISPASYNC_LIP, NULL);
#ifdef ISP_TARGET_MODE
isp_target_async(isp, bus, mbox);
#endif
@ -3369,7 +3372,7 @@ isp_parse_async(struct ispsoftc *isp, int mbox)
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_NIL;
isp_mark_getpdb_all(isp);
isp_prt(isp, ISP_LOGINFO, "Loop RESET");
isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
#ifdef ISP_TARGET_MODE
isp_target_async(isp, bus, mbox);
#endif

File diff suppressed because it is too large Load diff

View file

@ -33,12 +33,7 @@
/*
* We're not ready for primetime yet
*/
#if 0
#if ((ISP_PLATFORM_VERSION_MAJOR * 10) + ISP_PLATFORM_VERSION_MINOR) >= 54
#define ISP_SMPLOCK 1
#endif
#endif
#include <sys/param.h>
#include <sys/param.h>
@ -48,6 +43,7 @@
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/proc.h>
#include <sys/bus.h>
@ -70,6 +66,8 @@
#include "opt_ddb.h"
#include "opt_isp.h"
#define HANDLE_LOOPSTATE_IN_OUTER_LAYERS 1
typedef void ispfwfunc __P((int, int, int, const u_int16_t **));
#ifdef ISP_TARGET_MODE
@ -104,12 +102,9 @@ struct isposinfo {
u_int8_t simqfrozen;
u_int8_t drain;
u_int8_t intsok;
#ifdef ISP_SMPLOCK
struct mtx lock;
#else
volatile u_int32_t islocked;
int splsaved;
#endif
struct cv kthread_cv;
struct proc *kproc;
#ifdef ISP_TARGET_MODE
#define TM_WANTED 0x80
#define TM_BUSY 0x40
@ -122,19 +117,26 @@ struct isposinfo {
#endif
};
#define isp_lock isp_osinfo.lock
/*
* Locking macros...
*/
#ifdef ISP_SMPLOCK
#define ISP_LOCK(x) mtx_lock(&(x)->isp_osinfo.lock)
#define ISP_UNLOCK(x) mtx_unlock(&(x)->isp_osinfo.lock)
#define ISP_LOCK(x) mtx_lock(&(x)->isp_lock)
#define ISP_UNLOCK(x) mtx_unlock(&(x)->isp_lock)
#define ISPLOCK_2_CAMLOCK(isp) \
mtx_unlock(&(isp)->isp_lock); mtx_lock(&Giant)
#define CAMLOCK_2_ISPLOCK(isp) \
mtx_unlock(&Giant); mtx_lock(&(isp)->isp_lock)
#else
#define ISP_LOCK isp_lock
#define ISP_UNLOCK isp_unlock
#define ISP_LOCK(x)
#define ISP_UNLOCK(x)
#define ISPLOCK_2_CAMLOCK(x)
#define CAMLOCK_2_ISPLOCK(x)
#endif
/*
* Required Macros/Defines
*/
@ -319,30 +321,6 @@ extern void isp_uninit(struct ispsoftc *);
/*
* Platform specific inline functions
*/
#ifndef ISP_SMPLOCK
static INLINE void isp_lock(struct ispsoftc *);
static INLINE void
isp_lock(struct ispsoftc *isp)
{
int s = splcam();
if (isp->isp_osinfo.islocked++ == 0) {
isp->isp_osinfo.splsaved = s;
} else {
splx(s);
}
}
static INLINE void isp_unlock(struct ispsoftc *);
static INLINE void
isp_unlock(struct ispsoftc *isp)
{
if (isp->isp_osinfo.islocked) {
if (--isp->isp_osinfo.islocked == 0) {
splx(isp->isp_osinfo.splsaved);
}
}
}
#endif
static INLINE void isp_mbox_wait_complete(struct ispsoftc *);
static INLINE void
@ -352,7 +330,7 @@ isp_mbox_wait_complete(struct ispsoftc *isp)
isp->isp_osinfo.mboxwaiting = 1;
#ifdef ISP_SMPLOCK
(void) msleep(&isp->isp_osinfo.mboxwaiting,
&isp->isp_osinfo.lock, PRIBIO, "isp_mboxwaiting", 10 * hz);
&isp->isp_lock, PRIBIO, "isp_mboxwaiting", 10 * hz);
#else
(void) tsleep(&isp->isp_osinfo.mboxwaiting, PRIBIO,
"isp_mboxwaiting", 10 * hz);

76
sys/dev/isp/isp_ioctl.h Normal file
View file

@ -0,0 +1,76 @@
/* $FreeBSD$ */
/*
* Copyright (c) 2001 by Matthew Jacob
*
* 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, 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.
*
* Alternatively, this software may be distributed under the terms of the
* the GNU Public License ("GPL", Library, Version 2).
*
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 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.
*
* Matthew Jacob <mjacob@feral.com)
*
*/
/*
* ioctl definitions for Qlogic FC/SCSI HBA driver
*/
#define ISP_IOC (021) /* 'Ctrl-Q' */
/*
* This ioctl sets/retrieves the debugging level for this hba instance.
* Note that this is not a simple integer level- see ispvar.h for definitions.
*
* The arguments is a pointer to an integer with the new debugging level.
* The old value is written into this argument.
*/
#define ISP_SDBLEV _IOWR(ISP_IOC, 0, int)
/*
* This ioctl resets the HBA. Use with caution.
*/
#define ISP_RESETHBA _IO(ISP_IOC, 1)
/*
* This ioctl performs a fibre chanel rescan.
*/
#define ISP_FC_RESCAN _IO(ISP_IOC, 2)
/*
* Initiate a LIP
*/
#define ISP_FC_LIP _IO(ISP_IOC, 3)
/*
* Return the Port Database structure for the named device, or ENODEV if none.
* Caller fills in virtual loopid (0..255), aka 'target'. The driver returns
* ENODEV (if nothing valid there) or the actual loopid (for local loop devices
* only), 24 bit Port ID and Node and Port WWNs.
*/
struct isp_fc_device {
u_int32_t loopid; /* 0..255 */
u_int32_t portid; /* 24 bit Port ID */
u_int64_t node_wwn;
u_int64_t port_wwn;
};
#define ISP_FC_GETDINFO _IOWR(ISP_IOC, 4, struct isp_fc_device)

View file

@ -304,9 +304,7 @@ isp_pci_attach(device_t dev)
struct ispmdvec *mdvp;
bus_size_t lim;
char *sptr;
#ifdef ISP_SMPLOCK
int locksetup = 0;
#endif
/*
* Figure out if we're supposed to skip this one.
@ -611,23 +609,19 @@ isp_pci_attach(device_t dev)
(void) resource_int_value(device_get_name(dev), device_get_unit(dev),
"debug", &isp_debug);
#ifdef ISP_SMPLOCK
/* Make sure the lock is set up. */
mtx_init(&isp->isp_osinfo.lock, "isp", MTX_DEF);
locksetup++;
if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_MPSAFE | INTR_ENTROPY,
isp_pci_intr, isp, &pcs->ih)) {
device_printf(dev, "could not setup interrupt\n");
goto bad;
}
#ifdef ISP_SMPLOCK
#define INTR_FLAGS INTR_TYPE_CAM | INTR_MPSAFE | INTR_ENTROPY
#else
if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_ENTROPY,
isp_pci_intr, isp, &pcs->ih)) {
#define INTR_FLAGS INTR_TYPE_CAM | INTR_ENTROPY
#endif
if (bus_setup_intr(dev, irq, INTR_FLAGS, isp_pci_intr, isp, &pcs->ih)) {
device_printf(dev, "could not setup interrupt\n");
goto bad;
}
#endif
/*
* Set up logging levels.
@ -674,11 +668,9 @@ bad:
(void) bus_teardown_intr(dev, irq, pcs->ih);
}
#ifdef ISP_SMPLOCK
if (locksetup && isp) {
mtx_destroy(&isp->isp_osinfo.lock);
}
#endif
if (irq) {
(void) bus_release_resource(dev, SYS_RES_IRQ, iqd, irq);
@ -1280,7 +1272,7 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
u_int16_t scsi_status, send_status, send_sense, handle;
u_int32_t totxfr, datalen;
u_int8_t sense[QLTM_SENSELEN];
int nctios;
int nctios, j;
mp = (mush_t *) arg;
if (error) {
@ -1309,9 +1301,9 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
*/
cto->ct_flags |= CT2_NO_DATA;
if (cto->ct_resid > 0)
cto->ct_flags |= CT2_DATA_UNDER;
cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
else if (cto->ct_resid < 0)
cto->ct_flags |= CT2_DATA_OVER;
cto->rsp.m1.ct_scsi_status |= CT2_DATA_OVER;
cto->ct_seg_count = 0;
cto->ct_reloff = 0;
ISP_TDQE(mp->isp, "dma2_tgt_fc[no data]", *mp->iptrp, cto);
@ -1351,9 +1343,10 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
handle = cto->ct_syshandle;
cto->ct_syshandle = 0;
send_status = (cto->ct_flags & CT2_SENDSTATUS) != 0;
if ((send_status = (cto->ct_flags & CT2_SENDSTATUS)) != 0) {
cto->ct_flags &= ~CT2_SENDSTATUS;
if (send_status) {
cto->ct_flags &= ~(CT2_SENDSTATUS|CT2_CCINCR);
/*
* Preserve residual, which is actually the total count.
@ -1385,7 +1378,7 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
totxfr = cto->ct_resid = 0;
cto->rsp.m0.ct_scsi_status = 0;
bzero(&cto->rsp, sizeof (cto->rsp));
MEMZERO(&cto->rsp, sizeof (cto->rsp));
pci = (struct isp_pcisoftc *)mp->isp;
dp = &pci->dmaps[isp_handle_index(handle)];
@ -1456,8 +1449,13 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
cto->ct_header.rqs_seqno = 1;
if (send_status) {
/*
* Get 'real' residual and set flags based
* on it.
*/
cto->ct_resid = datalen - totxfr;
if (send_sense) {
bcopy(sense, cto->rsp.m1.ct_resp,
MEMCPY(cto->rsp.m1.ct_resp, sense,
QLTM_SENSELEN);
cto->rsp.m1.ct_senselen =
QLTM_SENSELEN;
@ -1466,21 +1464,26 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
scsi_status;
cto->ct_flags &= CT2_FLAG_MMASK;
cto->ct_flags |= CT2_FLAG_MODE1 |
CT2_NO_DATA| CT2_SENDSTATUS;
CT2_NO_DATA | CT2_SENDSTATUS |
CT2_CCINCR;
if (cto->ct_resid > 0)
cto->rsp.m1.ct_scsi_status |=
CT2_DATA_UNDER;
else if (cto->ct_resid < 0)
cto->rsp.m1.ct_scsi_status |=
CT2_DATA_OVER;
} else {
cto->rsp.m0.ct_scsi_status =
scsi_status;
cto->ct_flags |= CT2_SENDSTATUS;
cto->ct_flags |=
CT2_SENDSTATUS | CT2_CCINCR;
if (cto->ct_resid > 0)
cto->rsp.m0.ct_scsi_status |=
CT2_DATA_UNDER;
else if (cto->ct_resid < 0)
cto->rsp.m0.ct_scsi_status |=
CT2_DATA_OVER;
}
/*
* Get 'real' residual and set flags based
* on it.
*/
cto->ct_resid = datalen - totxfr;
if (cto->ct_resid > 0)
cto->ct_flags |= CT2_DATA_UNDER;
else if (cto->ct_resid < 0)
cto->ct_flags |= CT2_DATA_OVER;
}
ISP_TDQE(mp->isp, "last dma2_tgt_fc", *mp->iptrp, cto);
isp_prt(mp->isp, ISP_LOGTDEBUG1,
@ -1509,6 +1512,7 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
*/
cto = (ct2_entry_t *)
ISP_QUEUE_ENTRY(mp->isp->isp_rquest, *mp->iptrp);
j = *mp->iptrp;
*mp->iptrp =
ISP_NXT_QENTRY(*mp->iptrp, RQUEST_QUEUE_LEN(isp));
if (*mp->iptrp == mp->optr) {
@ -1540,8 +1544,9 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
* just finished filling out.
*/
cto->ct_reloff += octo->rsp.m0.ct_xfrlen;
bzero(&cto->rsp, sizeof (cto->rsp));
ISP_SWIZ_CTIO2(isp, cto, cto);
MEMZERO(&cto->rsp, sizeof (cto->rsp));
ISP_SWIZ_CTIO2(isp, octo, octo);
ISP_ADD_REQUEST(mp->isp, j);
}
}
}

View file

@ -266,7 +266,7 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
*/
int
isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
u_int32_t opaque)
int cmd_cnt, int inot_cnt, u_int32_t opaque)
{
lun_entry_t el;
u_int16_t iptr, optr;
@ -277,8 +277,8 @@ isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
if (IS_DUALBUS(isp)) {
el.le_rsvd = (bus & 0x1) << 7;
}
el.le_cmd_count = DFLT_CMD_CNT;
el.le_in_count = DFLT_INOTIFY;
el.le_cmd_count = cmd_cnt;
el.le_in_count = inot_cnt;
if (cmd == RQSTYPE_ENABLE_LUN) {
if (IS_SCSI(isp)) {
el.le_flags = LUN_TQAE|LUN_DISAD;
@ -438,7 +438,7 @@ isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
}
if (aep->at_datalen) {
cto->ct_resid = aep->at_datalen;
cto->ct_flags |= CT2_DATA_UNDER;
cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
}
if ((sts & 0xff) == SCSI_CHECK && (sts & ECMD_SVALID)) {
cto->rsp.m1.ct_resp[0] = 0xf0;
@ -447,7 +447,7 @@ isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
cto->rsp.m1.ct_senselen = 16;
cto->ct_flags |= CT2_SNSLEN_VALID;
cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
}
cto->ct_syshandle = hdl;
} else {
@ -958,16 +958,7 @@ isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
case CT_NOACK:
if (fmsg == NULL)
fmsg = "unacknowledged Immediate Notify pending";
isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
#if 0
if (status & SENSEVALID) {
bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET),
(caddr_t) &cdp->cd_sensedata,
sizeof(scsi_sense_t));
cdp->cd_flags |= CDF_SENSEVALID;
}
#endif
break;
default:
isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
@ -997,11 +988,11 @@ isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
}
} else {
/*
* Final CTIO completed. Release DMA resources and
* notify platform dependent layers.
*/
if (ct->ct_flags & CT_DATAMASK) {
/*
* Final CTIO completed. Release DMA resources and
* notify platform dependent layers.
*/
if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
ISP_DMAFREE(isp, xs, ct->ct_syshandle);
}
isp_prt(isp, pl, "final CTIO complete");
@ -1028,6 +1019,11 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
}
switch(ct->ct_status & ~QLTM_SVALID) {
case CT_BUS_ERROR:
isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
/* FALL Through */
case CT_DATA_OVER:
case CT_DATA_UNDER:
case CT_OK:
/*
* There are generally 2 possibilities as to why we'd get
@ -1040,19 +1036,18 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
case CT_BDR_MSG:
/*
* Bus Device Reset message received or the SCSI Bus has
* been Reset; the firmware has gone to Bus Free.
* Target Reset function received.
*
* The firmware generates an async mailbox interupt to
* notify us of this and returns outstanding CTIOs with this
* status. These CTIOs are handled in that same way as
* CT_ABORTED ones, so just fall through here.
*/
fmsg = "Bus Device Reset";
fmsg = "TARGET RESET Task Management Function Received";
/*FALLTHROUGH*/
case CT_RESET:
if (fmsg == NULL)
fmsg = "Bus Reset";
fmsg = "LIP Reset";
/*FALLTHROUGH*/
case CT_ABORTED:
/*
@ -1061,7 +1056,7 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
* set, then sends us an Immediate Notify entry.
*/
if (fmsg == NULL)
fmsg = "ABORT TASK sent by Initiator";
fmsg = "ABORT Task Management Function Received";
isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg);
break;
@ -1073,38 +1068,18 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data directiond");
break;
case CT_NOPATH:
/*
* CTIO rejected by the firmware due "no path for the
* nondisconnecting nexus specified". This means that
* we tried to access the bus while a non-disconnecting
* command is in process.
*/
isp_prt(isp, ISP_LOGERR,
"Firmware rejected CTIO2 for bad nexus %d->%d",
ct->ct_iid, ct->ct_lun);
break;
case CT_RSELTMO:
fmsg = "Reselection";
fmsg = "failure to reconnect to initiator";
/*FALLTHROUGH*/
case CT_TIMEOUT:
if (fmsg == NULL)
fmsg = "Command";
fmsg = "command";
isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
break;
case CT_ERR:
fmsg = "Completed with Error";
/*FALLTHROUGH*/
case CT_PHASE_ERROR: /* Bus phase sequence error */
if (fmsg == NULL)
fmsg = "Phase Sequence Error";
/*FALLTHROUGH*/
case CT_TERMINATED:
if (fmsg == NULL)
fmsg = "terminated by TERMINATE TRANSFER";
/*FALLTHROUGH*/
case CT_LOGOUT:
if (fmsg == NULL)
fmsg = "Port Logout";
@ -1112,19 +1087,13 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
case CT_PORTNOTAVAIL:
if (fmsg == NULL)
fmsg = "Port not available";
case CT_PORTCHANGED:
if (fmsg == NULL)
fmsg = "Port Changed";
case CT_NOACK:
if (fmsg == NULL)
fmsg = "unacknowledged Immediate Notify pending";
isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
#if 0
if (status & SENSEVALID) {
bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET),
(caddr_t) &cdp->cd_sensedata,
sizeof(scsi_sense_t));
cdp->cd_flags |= CDF_SENSEVALID;
}
#endif
break;
case CT_INVRXID:
@ -1164,6 +1133,9 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
}
} else {
if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
ISP_DMAFREE(isp, xs, ct->ct_syshandle);
}
if (ct->ct_flags & CT_SENDSTATUS) {
/*
* Sent status and command complete.
@ -1180,7 +1152,6 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
* notify platform dependent layers.
*/
isp_prt(isp, pl, "data CTIO complete");
ISP_DMAFREE(isp, xs, ct->ct_syshandle);
}
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
/*

View file

@ -361,13 +361,16 @@ typedef struct {
#define CT_INVAL 0x06 /* request for disabled lun */
#define CT_NOPATH 0x07 /* invalid ITL nexus */
#define CT_INVRXID 0x08 /* (FC only) Invalid RX_ID */
#define CT_DATA_OVER 0x09 /* (FC only) Data Overrun */
#define CT_RSELTMO 0x0A /* reselection timeout after 2 tries */
#define CT_TIMEOUT 0x0B /* timed out */
#define CT_RESET 0x0E /* SCSI Bus Reset occurred */
#define CT_PARITY 0x0F /* Uncorrectable Parity Error */
#define CT_BUS_ERROR 0x10 /* (FC Only) DMA PCI Error */
#define CT_PANIC 0x13 /* Unrecoverable Error */
#define CT_PHASE_ERROR 0x14 /* Bus phase sequence error */
#define CT_BDR_MSG 0x17 /* Bus Device Reset msg received */
#define CT_DATA_UNDER 0x15 /* (FC only) Data Underrun */
#define CT_TERMINATED 0x19 /* due to Terminate Transfer mbox cmd */
#define CT_PORTNOTAVAIL 0x28 /* port not available */
#define CT_LOGOUT 0x29 /* port logout */
@ -682,10 +685,11 @@ int isp_target_notify(struct ispsoftc *, void *, u_int16_t *);
/*
* Enable/Disable/Modify a logical unit.
* (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt, opaque)
*/
#define DFLT_CMD_CNT 32 /* XX */
#define DFLT_INOTIFY (4)
int isp_lun_cmd(struct ispsoftc *, int, int, int, int, u_int32_t);
#define DFLT_CMND_CNT 32
#define DFLT_INOT_CNT 4
int isp_lun_cmd(struct ispsoftc *, int, int, int, int, int, int, u_int32_t);
/*
* General request queue 'put' routine for target mode entries.

View file

@ -223,11 +223,12 @@ typedef struct tmd_cmd {
u_int8_t cd_reserved[_TMD_PAD_LEN];
} tmd_cmd_t;
#define CDFL_BUSY 0x01 /* this command is not on a free list */
#define CDFL_SNSVALID 0x01 /* sense data (from f/w) valid */
#define CDFL_NODISC 0x02 /* disconnects disabled */
#define CDFL_SENTSENSE 0x04 /* last action sent sense data */
#define CDFL_SENTSTATUS 0x08 /* last action sent status */
#define CDFL_ERROR 0x10 /* last action ended in error */
#define CDFL_BUSY 0x40 /* this command is not on a free list */
#define CDFL_PRIVATE_0 0x80 /* private layer flags */
#define CDFH_SNSVALID 0x01 /* sense data valid */

View file

@ -469,6 +469,7 @@ typedef struct ispsoftc {
#define ISP_HA_FC 0xf0
#define ISP_HA_FC_2100 0x10
#define ISP_HA_FC_2200 0x20
#define ISP_HA_FC_2300 0x30
#define IS_SCSI(isp) (isp->isp_type & ISP_HA_SCSI)
#define IS_1240(isp) (isp->isp_type == ISP_HA_SCSI_1240)
@ -481,9 +482,13 @@ typedef struct ispsoftc {
#define IS_ULTRA2(isp) (IS_1080(isp) || IS_1280(isp) || IS_12160(isp))
#define IS_ULTRA3(isp) (IS_12160(isp))
#define IS_FC(isp) (isp->isp_type & ISP_HA_FC)
#define IS_2100(isp) (isp->isp_type == ISP_HA_FC_2100)
#define IS_2200(isp) (isp->isp_type == ISP_HA_FC_2200)
#define IS_FC(isp) ((isp)->isp_type & ISP_HA_FC)
#define IS_2100(isp) ((isp)->isp_type == ISP_HA_FC_2100)
#define IS_2200(isp) ((isp)->isp_type == ISP_HA_FC_2200)
#define IS_2300(isp) ((isp)->isp_type == ISP_HA_FC_2300)
/* 2300 Support isn't ready yet */
#define ISP_DISABLE_2300_SUPPORT 1
/*
* DMA cookie macros
@ -628,6 +633,8 @@ typedef enum {
ISPASYNC_BUS_RESET, /* Bus Was Reset */
ISPASYNC_LOOP_DOWN, /* FC Loop Down */
ISPASYNC_LOOP_UP, /* FC Loop Up */
ISPASYNC_LIP, /* LIP Received */
ISPASYNC_LOOP_RESET, /* Loop Reset Received */
ISPASYNC_CHANGE_NOTIFY, /* FC Change Notification */
ISPASYNC_FABRIC_DEV, /* FC Fabric Device Arrival */
ISPASYNC_PROMENADE, /* FC Objects coming && going */
@ -780,7 +787,6 @@ void isp_prt(struct ispsoftc *, int level, const char *, ...);
* ISP_SWIZZLE_SNS_REQ
* ISP_UNSWIZZLE_SNS_RSP
* ISP_SWIZZLE_NVRAM_WORD
*
*
*/
#endif /* _ISPVAR_H */