1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-24 11:29:10 +00:00

Update QLogic ISP support for CAM. Add preliminary target mode support.

Submitted by:	Matthew Jacob <mjacob@feral.com>
This commit is contained in:
Justin T. Gibbs 1998-09-15 08:42:56 +00:00
parent 83cf1450a1
commit 478f8a9685
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=39235
8 changed files with 14059 additions and 2960 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
/* $Id: isp_freebsd.c,v 1.1 1998/04/22 17:54:50 mjacob Exp $ */ /* $Id: isp_freebsd.c,v 1.11 1998/09/14 23:22:12 mjacob Exp $ */
/* /*
* Platform (FreeBSD) dependent common attachment code for Qlogic adapters. * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
* *
@ -35,15 +35,501 @@
*/ */
#include <dev/isp/isp_freebsd.h> #include <dev/isp/isp_freebsd.h>
#ifdef SCSI_CAM
static void isp_async __P((void *, u_int32_t, struct cam_path *, void *));
static void isp_poll __P((struct cam_sim *));
static void isp_action __P((struct cam_sim *, union ccb *));
void
isp_attach(isp)
struct ispsoftc *isp;
{
struct ccb_setasync csa;
struct cam_devq *devq;
/*
* Create the device queue for our SIM.
*/
devq = cam_simq_alloc(MAXISPREQUEST);
if (devq == NULL) {
return;
}
/*
* Construct our SIM entry
*/
isp->isp_sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
isp->isp_unit, 1, MAXISPREQUEST, devq);
if (isp->isp_sim == NULL) {
cam_simq_free(devq);
return;
}
if (xpt_bus_register(isp->isp_sim, 0) != CAM_SUCCESS) {
cam_sim_free(isp->isp_sim, TRUE);
return;
}
if (xpt_create_path(&isp->isp_path, NULL, cam_sim_path(isp->isp_sim),
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(isp->isp_sim));
cam_sim_free(isp->isp_sim, TRUE);
return;
}
xpt_setup_ccb(&csa.ccb_h, isp->isp_path, 5);
csa.ccb_h.func_code = XPT_SASYNC_CB;
csa.event_enable = AC_LOST_DEVICE;
csa.callback = isp_async;
csa.callback_arg = isp->isp_sim;
xpt_action((union ccb *)&csa);
/*
* Set base transfer capabilities for Fibre Channel.
* Technically not correct because we don't know
* what media we're running on top of- but we'll
* look good if we always say 100MB/s.
*/
if (isp->isp_type & ISP_HA_FC) {
isp->isp_sim->base_transfer_speed = 100000;
}
isp->isp_state = ISP_RUNSTATE;
}
static void
isp_async(cbarg, code, path, arg)
void *cbarg;
u_int32_t code;
struct cam_path *path;
void *arg;
{
struct cam_sim *sim;
struct ispsoftc *isp;
sim = (struct cam_sim *)cbarg;
isp = (struct ispsoftc *) cam_sim_softc(sim);
switch (code) {
case AC_LOST_DEVICE:
if (isp->isp_type & ISP_HA_SCSI) {
u_int16_t oflags, nflags;
sdparam *sdp = isp->isp_param;
int s, tgt = xpt_path_target_id(path);
nflags = DPARM_SAFE_DFLT;
if (isp->isp_fwrev >= ISP_FW_REV(7, 55)) {
nflags |= DPARM_NARROW | DPARM_ASYNC;
}
oflags = sdp->isp_devparam[tgt].dev_flags;
sdp->isp_devparam[tgt].dev_flags = nflags;
sdp->isp_devparam[tgt].dev_update = 1;
s = splcam();
(void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL);
(void) splx(s);
sdp->isp_devparam[tgt].dev_flags = oflags;
}
break;
default:
break;
}
}
static void
isp_poll(sim)
struct cam_sim *sim;
{
isp_intr((struct ispsoftc *) cam_sim_softc(sim));
}
static void
isp_action(sim, ccb)
struct cam_sim *sim;
union ccb *ccb;
{
int s, tgt, error;
struct ispsoftc *isp;
struct ccb_trans_settings *cts, set;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
isp = (struct ispsoftc *)cam_sim_softc(sim);
ccb->ccb_h.sim_priv.entries[0].field = 0;
ccb->ccb_h.sim_priv.entries[1].ptr = isp;
IDPRINTF(4, ("%s: isp_action code %x\n", isp->isp_name,
ccb->ccb_h.func_code));
switch (ccb->ccb_h.func_code) {
case XPT_SCSI_IO: /* Execute the requested I/O operation */
/*
* Do a couple of preliminary checks...
*/
if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
ccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(ccb);
break;
}
}
if (isp->isp_type & ISP_HA_SCSI) {
if (ccb->ccb_h.target_id > (MAX_TARGETS-1)) {
ccb->ccb_h.status = CAM_PATH_INVALID;
} else if (isp->isp_fwrev >= ISP_FW_REV(7, 55)) {
/*
* Too much breakage.
*/
#if 0
if (ccb->ccb_h.target_lun > 31) {
ccb->ccb_h.status = CAM_PATH_INVALID;
}
#else
if (ccb->ccb_h.target_lun > 7) {
ccb->ccb_h.status = CAM_PATH_INVALID;
}
#endif
} else if (ccb->ccb_h.target_lun > 7) {
ccb->ccb_h.status = CAM_PATH_INVALID;
}
} else {
if (ccb->ccb_h.target_id > (MAX_FC_TARG-1)) {
ccb->ccb_h.status = CAM_PATH_INVALID;
} else if (ccb->ccb_h.target_lun > 15) {
ccb->ccb_h.status = CAM_PATH_INVALID;
}
}
if (ccb->ccb_h.status == CAM_PATH_INVALID) {
printf("%s: invalid tgt/lun (%d.%d) in XPT_SCSI_IO\n",
isp->isp_name, ccb->ccb_h.target_id,
ccb->ccb_h.target_lun);
xpt_done(ccb);
break;
}
s = splcam();
switch (ispscsicmd((ISP_SCSI_XFER_T *) ccb)) {
case CMD_QUEUED:
ccb->ccb_h.status |= CAM_SIM_QUEUED;
break;
case CMD_EAGAIN:
printf("%s: EAGAINed %d.%d\n", isp->isp_name,
ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
printf("%s: %d EAGAIN\n", __FILE__, __LINE__);
xpt_freeze_simq(sim, 1);
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
ccb->ccb_h.status |= CAM_REQUEUE_REQ;
xpt_done(ccb);
break;
case CMD_COMPLETE:
printf("%s: COMPLETEd for %d.%d with cam status 0%x\n",
isp->isp_name, ccb->ccb_h.target_id,
ccb->ccb_h.target_lun, ccb->ccb_h.status);
if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
CAM_REQ_INPROG) {
/* XXX: Cannot Happen */
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
}
xpt_done(ccb);
break;
}
splx(s);
break;
case XPT_EN_LUN: /* Enable LUN as a target */
case XPT_TARGET_IO: /* Execute target I/O request */
case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
ccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(ccb);
break;
case XPT_RESET_DEV: /* BDR the specified SCSI device */
tgt = ccb->ccb_h.target_id;
s = splcam();
error = isp_control(isp, ISPCTL_RESET_DEV, (void *) tgt);
(void) splx(s);
if (error) {
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
} else {
ccb->ccb_h.status = CAM_REQ_CMP;
}
xpt_done(ccb);
break;
case XPT_ABORT: /* Abort the specified CCB */
s = splcam();
error = isp_control(isp, ISPCTL_ABORT_CMD, ccb);
(void) splx(s);
if (error) {
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
} else {
ccb->ccb_h.status = CAM_REQ_CMP;
}
xpt_done(ccb);
break;
case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */
cts = &ccb->cts;
tgt = cts->ccb_h.target_id;
s = splcam();
if (isp->isp_type & ISP_HA_FC) {
; /* nothing to change */
} else {
sdparam *sdp = isp->isp_param;
u_int16_t *dptr;
#if 0
if (cts->flags & CCB_TRANS_CURRENT_SETTINGS)
dptr = &sdp->isp_devparam[tgt].cur_dflags;
else
dptr = &sdp->isp_devparam[tgt].dev_flags;
#else
/*
* We always update (internally) from dev_flags
* so any request to change settings just gets
* vectored to that location.
*/
dptr = &sdp->isp_devparam[tgt].dev_flags;
#endif
/*
* Note that these operations affect the
* the permanent flags (dev_flags)- not
* the current state flags. Then we mark
* things so that the next operation to
* this HBA will cause the update to occur.
*/
if (cts->valid & CCB_TRANS_DISC_VALID) {
if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
*dptr |= DPARM_DISC;
} else {
*dptr &= ~DPARM_DISC;
}
}
if (cts->valid & CCB_TRANS_TQ_VALID) {
if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
*dptr |= DPARM_TQING;
} else {
*dptr &= ~DPARM_TQING;
}
}
if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) {
switch (cts->bus_width) {
case MSG_EXT_WDTR_BUS_16_BIT:
*dptr |= DPARM_WIDE;
break;
default:
*dptr &= ~DPARM_WIDE;
}
}
/*
* Any SYNC RATE of nonzero and SYNC_OFFSET
* of nonzero will cause us to go to the
* selected (from NVRAM) maximum value for
* this device. At a later point, we'll
* allow finer control.
*/
if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) &&
(cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) &&
(cts->sync_offset > 0)) {
*dptr |= DPARM_SYNC;
} else {
*dptr &= ~DPARM_SYNC;
}
IDPRINTF(3, ("%s: target %d new dev_flags 0x%x\n",
isp->isp_name, tgt,
sdp->isp_devparam[tgt].dev_flags));
s = splcam();
sdp->isp_devparam[tgt].dev_update = 1;
isp->isp_update = 1;
(void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL);
(void) splx(s);
}
(void) splx(s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
case XPT_GET_TRAN_SETTINGS:
cts = &ccb->cts;
tgt = cts->ccb_h.target_id;
if (isp->isp_type & ISP_HA_FC) {
/*
* a lot of normal SCSI things don't make sense.
*/
cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
/*
* How do you measure the width of a high
* speed serial bus? Well, in bytes.
*
* Offset and period make no sense, though, so we set
* (above) a 'base' transfer speed to be gigabit.
*/
cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
} else {
sdparam *sdp = isp->isp_param;
u_int16_t dval;
if (cts->flags & CCB_TRANS_CURRENT_SETTINGS)
dval = sdp->isp_devparam[tgt].cur_dflags;
else
dval = sdp->isp_devparam[tgt].dev_flags;
s = splcam();
cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
if (dval & DPARM_DISC) {
cts->flags |= CCB_TRANS_DISC_ENB;
}
if (dval & DPARM_TQING) {
cts->flags |= CCB_TRANS_TAG_ENB;
}
if (dval & DPARM_WIDE) {
cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
} else {
cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
}
cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
if ((dval & DPARM_SYNC) &&
(sdp->isp_devparam[tgt].sync_offset)) {
cts->sync_period =
sdp->isp_devparam[tgt].sync_period;
cts->sync_offset =
sdp->isp_devparam[tgt].sync_offset;
cts->valid |=
CCB_TRANS_SYNC_RATE_VALID |
CCB_TRANS_SYNC_OFFSET_VALID;
}
splx(s);
}
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
case XPT_CALC_GEOMETRY:
{
struct ccb_calc_geometry *ccg;
u_int32_t secs_per_cylinder;
u_int32_t size_mb;
ccg = &ccb->ccg;
if (ccg->block_size == 0) {
printf("%s: %d.%d XPT_CALC_GEOMETRY block size 0?\n",
isp->isp_name, ccg->ccb_h.target_id,
ccg->ccb_h.target_lun);
ccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(ccb);
break;
}
size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size);
if (size_mb > 1024) {
ccg->heads = 255;
ccg->secs_per_track = 63;
} else {
ccg->heads = 64;
ccg->secs_per_track = 32;
}
secs_per_cylinder = ccg->heads * ccg->secs_per_track;
ccg->cylinders = ccg->volume_size / secs_per_cylinder;
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
}
case XPT_RESET_BUS: /* Reset the specified bus */
if (isp->isp_type & ISP_HA_FC) {
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
}
s = splcam();
error = isp_control(isp, ISPCTL_RESET_BUS, NULL);
(void) splx(s);
if (error)
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
else
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
case XPT_TERM_IO: /* Terminate the I/O process */
/* Does this need to be implemented? */
ccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(ccb);
break;
case XPT_PATH_INQ: /* Path routing inquiry */
{
struct ccb_pathinq *cpi = &ccb->cpi;
cpi->version_num = 1;
cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
cpi->target_sprt = 0;
cpi->hba_misc = 0;
cpi->hba_eng_cnt = 0;
if (isp->isp_type & ISP_HA_FC) {
cpi->max_target = MAX_FC_TARG-1;
cpi->initiator_id =
((fcparam *)isp->isp_param)->isp_loopid;
/*
* XXX: actually, this is not right if we have
* XXX: 1.14 F/W and the second level lun addressing
* XXX: in place. It's also probably not right
* XXX: even for 1.13 f/w.
*/
cpi->max_lun = 15;
} else {
cpi->initiator_id =
((sdparam *)isp->isp_param)->isp_initiator_id;
cpi->max_target = MAX_TARGETS-1;
if (isp->isp_fwrev >= ISP_FW_REV(7, 55)) {
/*
* Too much breakage.
*/
#if 0
cpi->max_lun = 31;
#else
cpi->max_lun = 7;
#endif
} else {
cpi->max_lun = 7;
}
}
cpi->bus_id = cam_sim_bus(sim);
strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
cpi->unit_number = cam_sim_unit(sim);
cpi->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
}
default:
ccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(ccb);
break;
}
}
#else
static void ispminphys __P((struct buf *)); static void ispminphys __P((struct buf *));
static u_int32_t isp_adapter_info __P((int)); static u_int32_t isp_adapter_info __P((int));
static int ispcmd __P((ISP_SCSI_XFER_T *));
static struct scsi_adapter isp_switch = { static struct scsi_adapter isp_switch = {
ispscsicmd, ispminphys, 0, 0, isp_adapter_info, "isp", { 0, 0 } ispcmd, ispminphys, 0, 0, isp_adapter_info, "isp", { 0, 0 }
}; };
static struct scsi_device isp_dev = { static struct scsi_device isp_dev = {
NULL, NULL, NULL, NULL, "isp", 0, { 0, 0 } NULL, NULL, NULL, NULL, "isp", 0, { 0, 0 }
}; };
static int isp_poll __P((struct ispsoftc *, ISP_SCSI_XFER_T *, int));
/* /*
* Complete attachment of hardware, include subdevices. * Complete attachment of hardware, include subdevices.
@ -66,19 +552,12 @@ isp_attach(isp)
isp->isp_osinfo._link.device = &isp_dev; isp->isp_osinfo._link.device = &isp_dev;
isp->isp_osinfo._link.flags = 0; isp->isp_osinfo._link.flags = 0;
if (isp->isp_type & ISP_HA_FC) { if (isp->isp_type & ISP_HA_FC) {
isp->isp_osinfo._link.adapter_targ = 0xff; isp->isp_osinfo._link.adapter_targ =
#if 0 ((fcparam *)isp->isp_param)->isp_loopid;
isp->isp_osinfo._link.openings =
RQUEST_QUEUE_LEN(isp) / (MAX_FC_TARG-1);
#endif
scbus->maxtarg = MAX_FC_TARG-1; scbus->maxtarg = MAX_FC_TARG-1;
} else { } else {
isp->isp_osinfo._link.adapter_targ = isp->isp_osinfo._link.adapter_targ =
((sdparam *)isp->isp_param)->isp_initiator_id; ((sdparam *)isp->isp_param)->isp_initiator_id;
#if 0
isp->isp_osinfo._link.openings =
RQUEST_QUEUE_LEN(isp) / (MAX_TARGETS-1);
#endif
scbus->maxtarg = MAX_TARGETS-1; scbus->maxtarg = MAX_TARGETS-1;
} }
/* /*
@ -106,7 +585,7 @@ ispminphys(bp)
struct buf *bp; struct buf *bp;
{ {
/* /*
* XX: Only the 1020 has a 24 bit limit. * Only the 10X0 has a 24 bit limit.
*/ */
if (bp->b_bcount >= (1 << 24)) { if (bp->b_bcount >= (1 << 24)) {
bp->b_bcount = (1 << 24); bp->b_bcount = (1 << 24);
@ -122,3 +601,62 @@ isp_adapter_info(unit)
*/ */
return (2); return (2);
} }
static int
ispcmd(xs)
ISP_SCSI_XFER_T *xs;
{
struct ispsoftc *isp;
int r;
ISP_LOCKVAL_DECL;
isp = XS_ISP(xs);
ISP_LOCK;
r = ispscsicmd(xs);
if (r != CMD_QUEUED || (xs->flags & SCSI_NOMASK) == 0) {
ISP_UNLOCK;
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;
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);
}
#endif

View File

@ -1,5 +1,5 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
/* $Id: isp_freebsd.h,v 1.1 1998/04/22 17:54:52 mjacob Exp $ */ /* $Id: isp_freebsd.h,v 1.12 1998/09/08 01:01:53 mjacob Exp $ */
/* /*
* Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions (non CAM version) * Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions (non CAM version)
*--------------------------------------- *---------------------------------------
@ -35,7 +35,14 @@
#ifndef _ISP_FREEBSD_H #ifndef _ISP_FREEBSD_H
#define _ISP_FREEBSD_H #define _ISP_FREEBSD_H
#include <pci.h> #define ISP_PLATFORM_VERSION_MAJOR 0
#define ISP_PLATFORM_VERSION_MINOR 95
#include "opt_scsi.h"
#ifdef SCSI_CAM
#include <dev/isp/isp_freebsd_cam.h>
#else
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/malloc.h> #include <sys/malloc.h>
@ -43,8 +50,6 @@
#include <sys/proc.h> #include <sys/proc.h>
#include <scsi/scsiconf.h> #include <scsi/scsiconf.h>
#include <scsi/scsi_debug.h>
#include <machine/clock.h> #include <machine/clock.h>
#include <vm/vm.h> #include <vm/vm.h>
#include <vm/vm_param.h> #include <vm/vm_param.h>
@ -52,11 +57,12 @@
#include <sys/kernel.h> #include <sys/kernel.h>
/* /*
* Quick hack fix to get around osreldate.h not being present. * Now that __FreeBSD_version is in sys/param.h, we can
* #include <osreldate.h> * automatically handle pre-3.0 cases.
*/ */
#ifndef __FreeBSD_version #ifndef __FreeBSD_version
#define __FreeBSD_version 300002 #define __FreeBSD_version 226000
#endif #endif
#define ISP_SCSI_XFER_T struct scsi_xfer #define ISP_SCSI_XFER_T struct scsi_xfer
@ -68,6 +74,7 @@ struct isposinfo {
struct callout_handle watchid; struct callout_handle watchid;
#endif #endif
}; };
/* /*
* XXXX: UNTIL WE PUT CODE IN THAT CHECKS RETURNS FROM MALLOC * XXXX: UNTIL WE PUT CODE IN THAT CHECKS RETURNS FROM MALLOC
* XXXX: FOR CONTIGOUS PAGES, WE LIMIT TO PAGE_SIZE THE SIZE * XXXX: FOR CONTIGOUS PAGES, WE LIMIT TO PAGE_SIZE THE SIZE
@ -75,8 +82,6 @@ struct isposinfo {
*/ */
#define MAXISPREQUEST 64 #define MAXISPREQUEST 64
#define ISP_VERSION_STRING \
"Version 0.92 Alpha Fri Apr 17 09:34:03 PDT 1998"
#include <dev/isp/ispreg.h> #include <dev/isp/ispreg.h>
#include <dev/isp/ispvar.h> #include <dev/isp/ispvar.h>
@ -84,19 +89,18 @@ struct isposinfo {
#define PRINTF printf #define PRINTF printf
#define IDPRINTF(lev, x) if (isp->isp_dblev >= lev) printf x #define IDPRINTF(lev, x) if (isp->isp_dblev >= lev) printf x
#ifdef SCSIDEBUG
#define DFLT_DBLEVEL 2
#else
#define DFLT_DBLEVEL 1 #define DFLT_DBLEVEL 1
#endif
#define ISP_LOCKVAL_DECL int isp_spl_save #define ISP_LOCKVAL_DECL int isp_spl_save
#define ISP_UNLOCK (void) splx(isp_spl_save) #define ISP_UNLOCK(isp) (void) splx(isp_spl_save)
#define ISP_LOCK isp_spl_save = splbio() #define ISP_LOCK(isp) isp_spl_save = splbio()
#define ISP_ILOCK(isp) ISP_LOCK(isp)
#define ISP_IUNLOCK(isp) ISP_UNLOCK(isp)
#define IMASK bio_imask #define IMASK bio_imask
#define XS_NULL(xs) xs == NULL || xs->sc_link == NULL #define XS_NULL(xs) xs == NULL || xs->sc_link == NULL
#define XS_ISP(xs) (xs)->sc_link->adapter_softc #define XS_ISP(xs) \
((struct ispsoftc *) (xs)->sc_link->adapter_softc)
#define XS_LUN(xs) (xs)->sc_link->lun #define XS_LUN(xs) (xs)->sc_link->lun
#define XS_TGT(xs) (xs)->sc_link->target #define XS_TGT(xs) (xs)->sc_link->target
#define XS_RESID(xs) (xs)->resid #define XS_RESID(xs) (xs)->resid
@ -116,6 +120,8 @@ struct isposinfo {
#define HBA_TGTBSY XS_BUSY #define HBA_TGTBSY XS_BUSY
#define HBA_BUSRESET XS_DRIVER_STUFFUP #define HBA_BUSRESET XS_DRIVER_STUFFUP
#define HBA_ABORTED 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_SNS_IS_VALID(xs) (xs)->error = XS_SENSE
#define XS_IS_SNS_VALID(xs) ((xs)->error == XS_SENSE) #define XS_IS_SNS_VALID(xs) ((xs)->error == XS_SENSE)
@ -128,7 +134,16 @@ struct isposinfo {
#define XS_CMD_DONE(xs) (xs)->flags |= ITSDONE, scsi_done(xs) #define XS_CMD_DONE(xs) (xs)->flags |= ITSDONE, scsi_done(xs)
#define XS_IS_CMD_DONE(xs) (((xs)->flags & ITSDONE) != 0) #define XS_IS_CMD_DONE(xs) (((xs)->flags & ITSDONE) != 0)
#define XS_POLLDCMD(xs) ((xs)->flags & SCSI_NOMASK) /*
* We decide whether to use tags based upon whether we're polling.
*/
#define XS_CANTAG(xs) (((xs)->flags & SCSI_NOMASK) != 0)
/*
* Our default tag
*/
#define XS_KINDOF_TAG(xs) REQFLAG_OTAG
#define CMD_COMPLETE COMPLETE #define CMD_COMPLETE COMPLETE
#define CMD_EAGAIN TRY_AGAIN_LATER #define CMD_EAGAIN TRY_AGAIN_LATER
@ -157,4 +172,7 @@ struct isposinfo {
#define RESTART_WATCHDOG(f, s) START_WATCHDOG(f, s) #define RESTART_WATCHDOG(f, s) START_WATCHDOG(f, s)
extern void isp_attach __P((struct ispsoftc *)); extern void isp_attach __P((struct ispsoftc *));
#define PVS "Qlogic ISP Driver, FreeBSD Non-Cam"
#endif /* !SCSI_CAM */
#endif /* _ISP_FREEBSD_H */ #endif /* _ISP_FREEBSD_H */

View File

@ -0,0 +1,410 @@
/* $FreeBSD$ */
/* $Id: isp_freebsd_cam.h,v 1.6 1998/09/08 01:01:53 mjacob Exp $ */
/*
* Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions (CAM version)
*---------------------------------------
* 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_FREEBSD_CAM_H
#define _ISP_FREEBSD_CAM_H
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/queue.h>
#include <machine/bus_memio.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/clock.h>
#include <cam/cam.h>
#include <cam/cam_debug.h>
#include <cam/cam_ccb.h>
#include <cam/cam_sim.h>
#include <cam/cam_xpt.h>
#include <cam/cam_xpt_sim.h>
#include <cam/cam_debug.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
#ifndef SCSI_CHECK
#define SCSI_CHECK SCSI_STATUS_CHECK_COND
#endif
#ifndef SCSI_BUSY
#define SCSI_BUSY SCSI_STATUS_BUSY
#endif
#define ISP_SCSI_XFER_T struct ccb_scsiio
struct isposinfo {
char name[8];
int unit;
struct cam_sim *sim;
struct cam_path *path;
struct callout_handle watchid;
};
#define isp_sim isp_osinfo.sim
#define isp_path isp_osinfo.path
#define isp_unit isp_osinfo.unit
#define isp_name isp_osinfo.name
/*
* XXXX: UNTIL WE PUT CODE IN THAT CHECKS RETURNS FROM MALLOC
* XXXX: FOR CONTIGOUS PAGES, WE LIMIT TO PAGE_SIZE THE SIZE
* XXXX: OF MAILBOXES.
*/
#define MAXISPREQUEST 64
#define PVS "Qlogic ISP Driver, FreeBSD CAM"
#include <dev/isp/ispreg.h>
#include <dev/isp/ispvar.h>
#include <dev/isp/ispmbox.h>
#define PRINTF printf
#define IDPRINTF(lev, x) if (isp->isp_dblev >= lev) printf x
#define DFLT_DBLEVEL 2
#define ISP_LOCKVAL_DECL int isp_spl_save
#define ISP_UNLOCK(isp) (void) splx(isp_spl_save)
#define ISP_LOCK(isp) isp_spl_save = splcam()
#define ISP_ILOCK(isp) ISP_LOCK(isp)
#define ISP_IUNLOCK(isp) ISP_UNLOCK(isp)
#define IMASK cam_imask
#define XS_NULL(ccb) ccb == NULL
#define XS_ISP(ccb) ((struct ispsoftc *) (ccb)->ccb_h.spriv_ptr1)
#define XS_LUN(ccb) (ccb)->ccb_h.target_lun
#define XS_TGT(ccb) (ccb)->ccb_h.target_id
#define XS_RESID(ccb) (ccb)->resid
#define XS_XFRLEN(ccb) (ccb)->dxfer_len
#define XS_CDBLEN(ccb) (ccb)->cdb_len
#define XS_CDBP(ccb) ((ccb)->ccb_h.flags & CAM_CDB_POINTER)? \
(ccb)->cdb_io.cdb_ptr : (ccb)->cdb_io.cdb_bytes
#define XS_STS(ccb) (ccb)->scsi_status
#define XS_TIME(ccb) (ccb)->ccb_h.timeout
#define XS_SNSP(ccb) (&(ccb)->sense_data)
#define XS_SNSLEN(ccb) imin((sizeof (ccb)->sense_data), ccb->sense_len)
#define XS_SNSKEY(ccb) ((ccb)->sense_data.flags & 0xf)
/*
* A little tricky- HBA_NOERROR is "in progress" so
* that XS_CMD_DONE can transition this to CAM_REQ_CMP.
*/
#define HBA_NOERROR CAM_REQ_INPROG
#define HBA_BOTCH CAM_UNREC_HBA_ERROR
#define HBA_CMDTIMEOUT CAM_CMD_TIMEOUT
#define HBA_SELTIMEOUT CAM_SEL_TIMEOUT
#define HBA_TGTBSY CAM_SCSI_STATUS_ERROR
#define HBA_BUSRESET CAM_SCSI_BUS_RESET
#define HBA_ABORTED CAM_REQ_ABORTED
#define HBA_DATAOVR CAM_DATA_RUN_ERR
#define HBA_ARQFAIL CAM_AUTOSENSE_FAIL
#define XS_SNS_IS_VALID(ccb) ((ccb)->ccb_h.status |= CAM_AUTOSNS_VALID)
#define XS_IS_SNS_VALID(ccb) (((ccb)->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
#define XS_INITERR(ccb) \
(ccb)->ccb_h.status &= ~CAM_STATUS_MASK, \
(ccb)->ccb_h.status |= CAM_REQ_INPROG, \
(ccb)->ccb_h.spriv_field0 = CAM_REQ_INPROG
#define XS_SETERR(ccb, v) (ccb)->ccb_h.spriv_field0 = v
#define XS_ERR(ccb) (ccb)->ccb_h.spriv_field0
#define XS_NOERR(ccb) \
((ccb)->ccb_h.spriv_field0 == CAM_REQ_INPROG)
#define XS_CMD_DONE(sccb) \
if (XS_NOERR((sccb))) \
XS_SETERR((sccb), CAM_REQ_CMP); \
(sccb)->ccb_h.status &= ~CAM_STATUS_MASK; \
(sccb)->ccb_h.status |= (sccb)->ccb_h.spriv_field0; \
if (((sccb)->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && \
(sccb)->scsi_status != SCSI_STATUS_OK) { \
(sccb)->ccb_h.status &= ~CAM_STATUS_MASK; \
(sccb)->ccb_h.status |= CAM_SCSI_STATUS_ERROR; \
} \
if (((sccb)->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { \
if (((sccb)->ccb_h.status & CAM_DEV_QFRZN) == 0) { \
struct ispsoftc *isp = XS_ISP((sccb)); \
IDPRINTF(3, ("%s: freeze devq %d.%d ccbstat 0x%x\n",\
isp->isp_name, (sccb)->ccb_h.target_id, \
(sccb)->ccb_h.target_lun, (sccb)->ccb_h.status)); \
xpt_freeze_devq((sccb)->ccb_h.path, 1); \
(sccb)->ccb_h.status |= CAM_DEV_QFRZN; \
} \
} \
(sccb)->ccb_h.status &= ~CAM_SIM_QUEUED; \
xpt_done((union ccb *)(sccb))
#define XS_IS_CMD_DONE(ccb) \
(((ccb)->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG)
/*
* Can we tag?
*/
#define XS_CANTAG(ccb) ((ccb)->ccb_h.flags & CAM_TAG_ACTION_VALID)
/*
* And our favorite tag is....
*/
#define XS_KINDOF_TAG(ccb) \
((ccb->tag_action == MSG_SIMPLE_Q_TAG)? REQFLAG_STAG : \
((ccb->tag_action == MSG_HEAD_OF_Q_TAG)? REQFLAG_HTAG : REQFLAG_OTAG))
#define CMD_COMPLETE 0
#define CMD_EAGAIN 1
#define CMD_QUEUED 2
#define SYS_DELAY(x) DELAY(x)
#define WATCH_INTERVAL 30
#define START_WATCHDOG(f, s) \
(s)->isp_osinfo.watchid = timeout(f, s, WATCH_INTERVAL * hz), \
s->isp_dogactive = 1
#define STOP_WATCHDOG(f, s) untimeout(f, s, (s)->isp_osinfo.watchid),\
(s)->isp_dogactive = 0
#define RESTART_WATCHDOG(f, s) START_WATCHDOG(f, s)
extern void isp_attach __P((struct ispsoftc *));
#endif /* _ISP_FREEBSD_CAM_H */
/* $FreeBSD$ */
/* $Id: isp_freebsd_cam.h,v 1.6 1998/09/08 01:01:53 mjacob Exp $ */
/*
* Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions (CAM version)
*---------------------------------------
* 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_FREEBSD_CAM_H
#define _ISP_FREEBSD_CAM_H
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/queue.h>
#include <machine/bus_memio.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/clock.h>
#include <cam/cam.h>
#include <cam/cam_debug.h>
#include <cam/cam_ccb.h>
#include <cam/cam_sim.h>
#include <cam/cam_xpt.h>
#include <cam/cam_xpt_sim.h>
#include <cam/cam_debug.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
#ifndef SCSI_CHECK
#define SCSI_CHECK SCSI_STATUS_CHECK_COND
#endif
#ifndef SCSI_BUSY
#define SCSI_BUSY SCSI_STATUS_BUSY
#endif
#define ISP_SCSI_XFER_T struct ccb_scsiio
struct isposinfo {
char name[8];
int unit;
struct cam_sim *sim;
struct cam_path *path;
struct callout_handle watchid;
};
#define isp_sim isp_osinfo.sim
#define isp_path isp_osinfo.path
#define isp_unit isp_osinfo.unit
#define isp_name isp_osinfo.name
/*
* XXXX: UNTIL WE PUT CODE IN THAT CHECKS RETURNS FROM MALLOC
* XXXX: FOR CONTIGOUS PAGES, WE LIMIT TO PAGE_SIZE THE SIZE
* XXXX: OF MAILBOXES.
*/
#define MAXISPREQUEST 64
#define PVS "Qlogic ISP Driver, FreeBSD CAM"
#include <dev/isp/ispreg.h>
#include <dev/isp/ispvar.h>
#include <dev/isp/ispmbox.h>
#define PRINTF printf
#define IDPRINTF(lev, x) if (isp->isp_dblev >= lev) printf x
#define DFLT_DBLEVEL 2
#define ISP_LOCKVAL_DECL int isp_spl_save
#define ISP_UNLOCK(isp) (void) splx(isp_spl_save)
#define ISP_LOCK(isp) isp_spl_save = splcam()
#define ISP_ILOCK(isp) ISP_LOCK(isp)
#define ISP_IUNLOCK(isp) ISP_UNLOCK(isp)
#define IMASK cam_imask
#define XS_NULL(ccb) ccb == NULL
#define XS_ISP(ccb) ((struct ispsoftc *) (ccb)->ccb_h.spriv_ptr1)
#define XS_LUN(ccb) (ccb)->ccb_h.target_lun
#define XS_TGT(ccb) (ccb)->ccb_h.target_id
#define XS_RESID(ccb) (ccb)->resid
#define XS_XFRLEN(ccb) (ccb)->dxfer_len
#define XS_CDBLEN(ccb) (ccb)->cdb_len
#define XS_CDBP(ccb) ((ccb)->ccb_h.flags & CAM_CDB_POINTER)? \
(ccb)->cdb_io.cdb_ptr : (ccb)->cdb_io.cdb_bytes
#define XS_STS(ccb) (ccb)->scsi_status
#define XS_TIME(ccb) (ccb)->ccb_h.timeout
#define XS_SNSP(ccb) (&(ccb)->sense_data)
#define XS_SNSLEN(ccb) imin((sizeof (ccb)->sense_data), ccb->sense_len)
#define XS_SNSKEY(ccb) ((ccb)->sense_data.flags & 0xf)
/*
* A little tricky- HBA_NOERROR is "in progress" so
* that XS_CMD_DONE can transition this to CAM_REQ_CMP.
*/
#define HBA_NOERROR CAM_REQ_INPROG
#define HBA_BOTCH CAM_UNREC_HBA_ERROR
#define HBA_CMDTIMEOUT CAM_CMD_TIMEOUT
#define HBA_SELTIMEOUT CAM_SEL_TIMEOUT
#define HBA_TGTBSY CAM_SCSI_STATUS_ERROR
#define HBA_BUSRESET CAM_SCSI_BUS_RESET
#define HBA_ABORTED CAM_REQ_ABORTED
#define HBA_DATAOVR CAM_DATA_RUN_ERR
#define HBA_ARQFAIL CAM_AUTOSENSE_FAIL
#define XS_SNS_IS_VALID(ccb) ((ccb)->ccb_h.status |= CAM_AUTOSNS_VALID)
#define XS_IS_SNS_VALID(ccb) (((ccb)->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
#define XS_INITERR(ccb) \
(ccb)->ccb_h.status &= ~CAM_STATUS_MASK, \
(ccb)->ccb_h.status |= CAM_REQ_INPROG, \
(ccb)->ccb_h.spriv_field0 = CAM_REQ_INPROG
#define XS_SETERR(ccb, v) (ccb)->ccb_h.spriv_field0 = v
#define XS_ERR(ccb) (ccb)->ccb_h.spriv_field0
#define XS_NOERR(ccb) \
((ccb)->ccb_h.spriv_field0 == CAM_REQ_INPROG)
#define XS_CMD_DONE(sccb) \
if (XS_NOERR((sccb))) \
XS_SETERR((sccb), CAM_REQ_CMP); \
(sccb)->ccb_h.status &= ~CAM_STATUS_MASK; \
(sccb)->ccb_h.status |= (sccb)->ccb_h.spriv_field0; \
if (((sccb)->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && \
(sccb)->scsi_status != SCSI_STATUS_OK) { \
(sccb)->ccb_h.status &= ~CAM_STATUS_MASK; \
(sccb)->ccb_h.status |= CAM_SCSI_STATUS_ERROR; \
} \
if (((sccb)->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { \
if (((sccb)->ccb_h.status & CAM_DEV_QFRZN) == 0) { \
struct ispsoftc *isp = XS_ISP((sccb)); \
IDPRINTF(3, ("%s: freeze devq %d.%d ccbstat 0x%x\n",\
isp->isp_name, (sccb)->ccb_h.target_id, \
(sccb)->ccb_h.target_lun, (sccb)->ccb_h.status)); \
xpt_freeze_devq((sccb)->ccb_h.path, 1); \
(sccb)->ccb_h.status |= CAM_DEV_QFRZN; \
} \
} \
(sccb)->ccb_h.status &= ~CAM_SIM_QUEUED; \
xpt_done((union ccb *)(sccb))
#define XS_IS_CMD_DONE(ccb) \
(((ccb)->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG)
/*
* Can we tag?
*/
#define XS_CANTAG(ccb) ((ccb)->ccb_h.flags & CAM_TAG_ACTION_VALID)
/*
* And our favorite tag is....
*/
#define XS_KINDOF_TAG(ccb) \
((ccb->tag_action == MSG_SIMPLE_Q_TAG)? REQFLAG_STAG : \
((ccb->tag_action == MSG_HEAD_OF_Q_TAG)? REQFLAG_HTAG : REQFLAG_OTAG))
#define CMD_COMPLETE 0
#define CMD_EAGAIN 1
#define CMD_QUEUED 2
#define SYS_DELAY(x) DELAY(x)
#define WATCH_INTERVAL 30
#define START_WATCHDOG(f, s) \
(s)->isp_osinfo.watchid = timeout(f, s, WATCH_INTERVAL * hz), \
s->isp_dogactive = 1
#define STOP_WATCHDOG(f, s) untimeout(f, s, (s)->isp_osinfo.watchid),\
(s)->isp_dogactive = 0
#define RESTART_WATCHDOG(f, s) START_WATCHDOG(f, s)
extern void isp_attach __P((struct ispsoftc *));
#endif /* _ISP_FREEBSD_CAM_H */

View File

@ -1,6 +1,6 @@
/* $Id: ispmbox.h,v 1.3 1998/04/14 17:51:32 mjacob Exp $ */ /* $Id: ispmbox.h,v 1.7 1998/09/14 23:23:26 mjacob Exp $ */
/* /*
* Mailbox and Command Definitions for for Qlogic ISP SCSI adapters. * Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters.
* *
*--------------------------------------- *---------------------------------------
* Copyright (c) 1997, 1998 by Matthew Jacob * Copyright (c) 1997, 1998 by Matthew Jacob
@ -122,6 +122,9 @@
#define MBOX_CLEAR_TASK_SET 0x67 #define MBOX_CLEAR_TASK_SET 0x67
#define MBOX_ABORT_TASK_SET 0x68 #define MBOX_ABORT_TASK_SET 0x68
#define MBOX_GET_FW_STATE 0x69 #define MBOX_GET_FW_STATE 0x69
#define MBOX_GET_LINK_STATUS 0x6a
#define MBOX_INIT_LIP_RESET 0x6c
#define MBOX_INIT_LIP_LOGIN 0x72
#define ISP2100_SET_PCI_PARAM 0x00ff #define ISP2100_SET_PCI_PARAM 0x00ff
@ -131,6 +134,42 @@ typedef struct {
u_int16_t param[8]; u_int16_t param[8];
} mbreg_t; } mbreg_t;
/*
* Mailbox Command Complete Status Codes
*/
#define MBOX_COMMAND_COMPLETE 0x4000
#define MBOX_INVALID_COMMAND 0x4001
#define MBOX_HOST_INTERFACE_ERROR 0x4002
#define MBOX_TEST_FAILED 0x4003
#define MBOX_COMMAND_ERROR 0x4005
#define MBOX_COMMAND_PARAM_ERROR 0x4006
/*
* Asynchronous event status codes
*/
#define ASYNC_BUS_RESET 0x8001
#define ASYNC_SYSTEM_ERROR 0x8002
#define ASYNC_RQS_XFER_ERR 0x8003
#define ASYNC_RSP_XFER_ERR 0x8004
#define ASYNC_QWAKEUP 0x8005
#define ASYNC_TIMEOUT_RESET 0x8006
#define ASYNC_UNSPEC_TMODE 0x8007
#define ASYNC_EXTMSG_UNDERRUN 0x800A
#define ASYNC_SCAM_INT 0x800B
#define ASYNC_HUNG_SCSI 0x800C
#define ASYNC_KILLED_BUS 0x800D
#define ASYNC_BUS_TRANSIT 0x800E /* LVD -> HVD, eg. */
#define ASYNC_CMD_CMPLT 0x8020
#define ASYNC_CTIO_DONE 0x8021
/* for ISP2100 only */
#define ASYNC_LIP_OCCURRED 0x8010
#define ASYNC_LOOP_UP 0x8011
#define ASYNC_LOOP_DOWN 0x8012
#define ASYNC_LOOP_RESET 0x8013
#define ASYNC_PDB_CHANGED 0x8014 /* Port Database Changed */
#define ASYNC_CHANGE_NOTIFY 0x8015
/* /*
* Command Structure Definitions * Command Structure Definitions
*/ */
@ -161,14 +200,31 @@ typedef struct {
#define RQSFLAG_BADPACKET 0x08 #define RQSFLAG_BADPACKET 0x08
/* RQS entry_type definitions */ /* RQS entry_type definitions */
#define RQSTYPE_REQUEST 1 #define RQSTYPE_REQUEST 0x01
#define RQSTYPE_DATASEG 2 #define RQSTYPE_DATASEG 0x02
#define RQSTYPE_RESPONSE 3 #define RQSTYPE_RESPONSE 0x03
#define RQSTYPE_MARKER 4 #define RQSTYPE_MARKER 0x04
#define RQSTYPE_CMDONLY 5 #define RQSTYPE_CMDONLY 0x05
#define RQSTYPE_T2RQS 17 #define RQSTYPE_ATIO 0x06 /* Target Mode */
#define RQSTYPE_T3RQS 25 #define RQSTYPE_CTIO0 0x07 /* Target Mode */
#define RQSTYPE_T1DSEG 10 #define RQSTYPE_SCAM 0x08
#define RQSTYPE_A64 0x09
#define RQSTYPE_A64_CONT 0x0a
#define RQSTYPE_ENABLE_LUN 0x0b /* Target Mode */
#define RQSTYPE_MODIFY_LUN 0x0c /* Target Mode */
#define RQSTYPE_NOTIFY 0x0d /* Target Mode */
#define RQSTYPE_NOTIFY_ACK 0x0e /* Target Mode */
#define RQSTYPE_CTIO1 0x0f /* Target Mode */
#define RQSTYPE_STATUS_CONT 0x10
#define RQSTYPE_T2RQS 0x11
#define RQSTYPE_T4RQS 0x15
#define RQSTYPE_ATIO2 0x16
#define RQSTYPE_CTIO2 0x17
#define RQSTYPE_CSET0 0x18
#define RQSTYPE_T3RQS 0x19
#define RQSTYPE_CTIO3 0x1f
#define ISP_RQDSEG 4 #define ISP_RQDSEG 4
@ -226,6 +282,13 @@ typedef struct {
#define REQFLAG_DATA_UNKNOWN 0x0060 #define REQFLAG_DATA_UNKNOWN 0x0060
#define REQFLAG_DISARQ 0x0100 #define REQFLAG_DISARQ 0x0100
#define REQFLAG_FRC_ASYNC 0x0200
#define REQFLAG_FRC_SYNC 0x0400
#define REQFLAG_FRC_WIDE 0x0800
#define REQFLAG_NOPARITY 0x1000
#define REQFLAG_STOPQ 0x2000
#define REQFLAG_XTRASNS 0x4000
#define REQFLAG_PRIORITY 0x8000
typedef struct { typedef struct {
isphdr_t req_header; isphdr_t req_header;
@ -320,6 +383,17 @@ typedef struct {
#define RQCS_ID_MSG_FAILED 0x0013 #define RQCS_ID_MSG_FAILED 0x0013
#define RQCS_UNEXP_BUS_FREE 0x0014 #define RQCS_UNEXP_BUS_FREE 0x0014
#define RQCS_DATA_UNDERRUN 0x0015 #define RQCS_DATA_UNDERRUN 0x0015
#define RQCS_XACT_ERR1 0x0018
#define RQCS_XACT_ERR2 0x0019
#define RQCS_XACT_ERR3 0x001A
#define RQCS_BAD_ENTRY 0x001B
#define RQCS_QUEUE_FULL 0x001C
#define RQCS_PHASE_SKIPPED 0x001D
#define RQCS_ARQS_FAILED 0x001E
#define RQCS_WIDE_FAILED 0x001F
#define RQCS_SYNCXFER_FAILED 0x0020
#define RQCS_LVD_BUSERR 0x0021
/* 2100 Only Completion Codes */ /* 2100 Only Completion Codes */
#define RQCS_PORT_UNAVAILABLE 0x0028 #define RQCS_PORT_UNAVAILABLE 0x0028
#define RQCS_PORT_LOGGED_OUT 0x0029 #define RQCS_PORT_LOGGED_OUT 0x0029
@ -349,12 +423,176 @@ typedef struct {
#define RQSTF_TIMEOUT 0x0040 #define RQSTF_TIMEOUT 0x0040
#define RQSTF_NEGOTIATION 0x0080 #define RQSTF_NEGOTIATION 0x0080
/*
* Target Mode Structures
*/
/*
* Used for Enable LUN and Modify Lun types.
* (for FC, pre-1.14 FW layout revision).
*/
typedef struct {
isphdr_t req_header;
u_int32_t req_handle;
#if BYTE_ORDER == BIG_ENDIAN
u_int8_t _reserved0;
u_int8_t req_lun; /* HOST->FW: LUN to enable */
#else
u_int8_t req_lun; /* HOST->FW: LUN to enable */
u_int8_t _reserved0;
#endif
u_int16_t _reserved1[3];
#if BYTE_ORDER == BIG_ENDIAN
u_int8_t _reserved2;
u_int8_t req_status; /* FW->HOST: Status of Request */
u_int8_t req_imcount; /* HOST->FW: Immediate Notify Count */
u_int8_t req_cmdcount; /* HOST->FW: ATIO Count */
#else
u_int8_t req_status; /* FW->HOST: Status of Request */
u_int8_t _reserved2;
u_int8_t req_cmdcount; /* HOST->FW: ATIO Count */
u_int8_t req_imcount; /* HOST->FW: Immediate Notify Count */
#endif
u_int16_t _reserved3;
u_int16_t req_timeout; /* HOST->FW: Lun timeout value */
} isplun_t;
/* inbound status */
#define LUN_OKAY 0x01
#define LUN_ERR 0x04
#define LUN_NOCAP 0x16
#define LUN_ENABLED 0x3e
/* outbound flags */
#define LUN_INCR_CMD 0x0001
#define LUN_DECR_CMD 0x0002
#define LUN_INCR_IMMED 0x0100
#define LUN_DECR_IMMED 0x0200
typedef struct {
isphdr_t req_header;
u_int32_t req_handle;
#if BYTE_ORDER == BIG_ENDIAN
u_int8_t req_initiator;
u_int8_t req_lun;
#else
u_int8_t req_lun;
u_int8_t req_initiator;
#endif
u_int16_t req_flags; /* NOTIFY_ACK only */
u_int16_t _reserved1[2];
u_int16_t req_status;
u_int16_t req_task_flags;
u_int16_t req_sequence;
} ispnotify_t;
#define IN_NOCAP 0x16
#define IN_IDE_RECEIVED 0x33
#define IN_RSRC_UNAVAIL 0x34
#define IN_MSG_RECEIVED 0x36
typedef struct {
isphdr_t req_header;
u_int32_t req_handle;
#if BYTE_ORDER == BIG_ENDIAN
u_int8_t req_initiator;
u_int8_t req_lun;
#else
u_int8_t req_lun;
u_int8_t req_initiator;
#endif
u_int16_t req_rxid;
u_int16_t req_flags;
u_int16_t req_status;
#if BYTE_ORDER == BIG_ENDIAN
u_int8_t req_taskcodes;
u_int8_t _reserved0;
u_int8_t req_execodes;
u_int8_t req_taskflags;
#else
u_int8_t _reserved0;
u_int8_t req_taskcodes;
u_int8_t req_taskflags;
u_int8_t req_execodes;
#endif
u_int8_t req_cdb[16];
u_int32_t req_datalen;
u_int16_t req_scclun;
u_int16_t _reserved1;;
u_int16_t req_scsi_status;
u_int8_t req_sense[18];
} ispatiot2_t;
#define ATIO_PATH_INVALID 0x07
#define ATIO_PHASE_ERROR 0x14
#define ATIO_NOCAP 0x16
#define ATIO_BDR_MSG 0x17
#define ATIO_CDB_RECEIVED 0x3d
#define ATIO_SENSEVALID 0x80
/*
* Continue Target I/O, type 2
*/
typedef struct {
isphdr_t req_header;
u_int32_t req_handle;
#if BYTE_ORDER == BIG_ENDIAN
u_int8_t req_initiator;
u_int8_t req_lun;
#else
u_int8_t req_lun;
u_int8_t req_initiator;
#endif
u_int16_t req_rxid;
u_int16_t req_flags;
u_int16_t req_status;
u_int16_t req_timeout;
u_int16_t req_seg_count; /* data segment count */
u_int8_t req_reloff[4]; /* relative offset */
u_int8_t req_resid[4]; /* residual */
u_int8_t _reserved0[4];
union { /* should be offset 0x20 */
struct {
u_int16_t _reserved0;
u_int16_t req_scsi_status;
u_int32_t req_datalen;
ispds_t req_dataseg[ISP_RQDSEG_T2];
} mode0;
struct {
u_int16_t req_sense_len;
u_int16_t req_scsi_status;
u_int32_t req_response_length;
u_int8_t req_response[26];
} mode1;
struct {
u_int16_t _reserved0[2];
u_int32_t req_datalen;
ispds_t req_fcpiudata;
} mode2;
} req_m;
} ispctiot2_t;
#define CTIO_SEND_STATUS 0x8000
#define CTIO_SEND_DATA 0x0040 /* To initiator */
#define CTIO_RECV_DATA 0x0080
#define CTIO_NODATA 0x00C0
#define CTIO2_SMODE0 0x0000
#define CTIO2_SMODE1 0x0001
#define CTIO2_SMODE2 0x0002
#define CTIO2_RESP_VALID 0x0100
#define CTIO2_STATUS_VALID 0x0200
#define CTIO2_RSPOVERUN 0x0400
#define CTIO2_RSPUNDERUN 0x0800
/* /*
* FC (ISP2100) specific data structures * FC (ISP2100) specific data structures
*/ */
/* /*
* Initialization Control Block * Initialization Control Block
*
* Version One format.
*/ */
typedef struct { typedef struct {
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN
@ -375,9 +613,16 @@ typedef struct {
u_int8_t icb_retry_count; u_int8_t icb_retry_count;
u_int8_t icb_retry_delay; u_int8_t icb_retry_delay;
#endif #endif
u_int16_t icb_nodename[4]; u_int8_t icb_nodename[8];
u_int16_t icb_hardaddr; u_int16_t icb_hardaddr;
u_int16_t _reserved1[5]; #if BYTE_ORDER == BIG_ENDIAN
u_int8_t _reserved1;
u_int8_t icb_iqdevtype;
#else
u_int8_t icb_iqdevtype;
u_int8_t _reserved1;
#endif
u_int8_t icb_portname[8];
u_int16_t icb_rqstout; u_int16_t icb_rqstout;
u_int16_t icb_rspnsin; u_int16_t icb_rspnsin;
u_int16_t icb_rqstqlen; u_int16_t icb_rqstqlen;
@ -385,10 +630,63 @@ typedef struct {
u_int16_t icb_rqstaddr[4]; u_int16_t icb_rqstaddr[4];
u_int16_t icb_respaddr[4]; u_int16_t icb_respaddr[4];
} isp_icb_t; } isp_icb_t;
#define ICB_VERSION1 1
#define ICBOPT_HARD_ADDRESS (1<<0)
#define ICBOPT_FAIRNESS (1<<1)
#define ICBOPT_FULL_DUPLEX (1<<2)
#define ICBOPT_FAST_POST (1<<3)
#define ICBOPT_TGT_ENABLE (1<<4)
#define ICBOPT_INI_DISABLE (1<<5)
#define ICBOPT_INI_ADISC (1<<6)
#define ICBOPT_INI_TGTTYPE (1<<7)
#define ICBOPT_PDBCHANGE_AE (1<<8)
#define ICBOPT_NOLIP (1<<9)
#define ICBOPT_SRCHDOWN (1<<10)
#define ICBOPT_PREVLOOP (1<<11)
#define ICBOPT_STOP_ON_QFULL (1<<12)
#define ICBOPT_FULL_LOGIN (1<<13)
#define ICBOPT_USE_PORTNAME (1<<14)
#define ICB_MIN_FRMLEN 256
#define ICB_MAX_FRMLEN 2112
#define ICB_DFLT_FRMLEN 1024 #define ICB_DFLT_FRMLEN 1024
#define MAKE_NODE_NAME(isp, icbp) \
(icbp)->icb_nodename[0] = 0, (icbp)->icb_nodename[1] = 0x5355,\ #define RQRSP_ADDR0015 0
(icbp)->icb_nodename[2] = 0x4E57, (icbp)->icb_nodename[3] = 0 #define RQRSP_ADDR1631 1
#define RQRSP_ADDR3247 2
#define RQRSP_ADDR4863 3
#if BYTE_ORDER == BIG_ENDIAN
#define ICB_NNM0 6
#define ICB_NNM1 7
#define ICB_NNM2 4
#define ICB_NNM3 5
#define ICB_NNM4 2
#define ICB_NNM5 3
#define ICB_NNM6 0
#define ICB_NNM7 1
#else
#define ICB_NNM0 7
#define ICB_NNM1 6
#define ICB_NNM2 5
#define ICB_NNM3 4
#define ICB_NNM4 3
#define ICB_NNM5 2
#define ICB_NNM6 1
#define ICB_NNM7 0
#endif
#define MAKE_NODE_NAME_FROM_WWN(array, wwn) \
array[ICB_NNM0] = (u_int8_t) ((wwn >> 0) & 0xff), \
array[ICB_NNM1] = (u_int8_t) ((wwn >> 8) & 0xff), \
array[ICB_NNM2] = (u_int8_t) ((wwn >> 16) & 0xff), \
array[ICB_NNM3] = (u_int8_t) ((wwn >> 24) & 0xff), \
array[ICB_NNM4] = (u_int8_t) ((wwn >> 32) & 0xff), \
array[ICB_NNM5] = (u_int8_t) ((wwn >> 40) & 0xff), \
array[ICB_NNM6] = (u_int8_t) ((wwn >> 48) & 0xff), \
array[ICB_NNM7] = (u_int8_t) ((wwn >> 56) & 0xff)
#endif /* _ISPMBOX_H */ #endif /* _ISPMBOX_H */

View File

@ -1,4 +1,4 @@
/* $Id: ispreg.h,v 1.3 1998/04/14 17:51:32 mjacob Exp $ */ /* $Id: ispreg.h,v 1.6 1998/09/08 01:09:46 mjacob Exp $ */
/* /*
* Machine Independent (well, as best as possible) register * Machine Independent (well, as best as possible) register
* definitions for Qlogic ISP SCSI adapters. * definitions for Qlogic ISP SCSI adapters.
@ -196,6 +196,12 @@
#define BIU_SEMA_STATUS 0x0002 /* Semaphore Status Bit */ #define BIU_SEMA_STATUS 0x0002 /* Semaphore Status Bit */
#define BIU_SEMA_LOCK 0x0001 /* Semaphore Lock Bit */ #define BIU_SEMA_LOCK 0x0001 /* Semaphore Lock Bit */
/* NVRAM SEMAPHORE REGISTER */
#define BIU_NVRAM_CLOCK 0x0001
#define BIU_NVRAM_SELECT 0x0002
#define BIU_NVRAM_DATAOUT 0x0004
#define BIU_NVRAM_DATAIN 0x0008
#define ISP_NVRAM_READ 6
/* COMNMAND && DATA DMA CONFIGURATION REGISTER */ /* COMNMAND && DATA DMA CONFIGURATION REGISTER */
#define DMA_ENABLE_SXP_DMA 0x0008 /* Enable SXP to DMA Data */ #define DMA_ENABLE_SXP_DMA 0x0008 /* Enable SXP to DMA Data */
@ -303,31 +309,6 @@
#define NMBOX(isp) \ #define NMBOX(isp) \
(((((isp)->isp_type & ISP_HA_SCSI) >= ISP_HA_SCSI_1040A) || \ (((((isp)->isp_type & ISP_HA_SCSI) >= ISP_HA_SCSI_1040A) || \
((isp)->isp_type & ISP_HA_FC))? 8 : 6) ((isp)->isp_type & ISP_HA_FC))? 8 : 6)
/*
* Mailbox Command Complete Status Codes
*/
#define MBOX_COMMAND_COMPLETE 0x4000
#define MBOX_INVALID_COMMAND 0x4001
#define MBOX_HOST_INTERFACE_ERROR 0x4002
#define MBOX_TEST_FAILED 0x4003
#define MBOX_COMMAND_ERROR 0x4005
#define MBOX_COMMAND_PARAM_ERROR 0x4006
/*
* Asynchronous event status codes
*/
#define ASYNC_BUS_RESET 0x8001
#define ASYNC_SYSTEM_ERROR 0x8002
#define ASYNC_RQS_XFER_ERR 0x8003
#define ASYNC_RSP_XFER_ERR 0x8004
#define ASYNC_QWAKEUP 0x8005
#define ASYNC_TIMEOUT_RESET 0x8006
/* for ISP2100 only */
#define ASYNC_LIP_OCCURRED 0x8010
#define ASYNC_LOOP_UP 0x8011
#define ASYNC_LOOP_DOWN 0x8012
#define ASYNC_LOOP_RESET 0x8013
/* /*
* SXP Block Register Offsets * SXP Block Register Offsets
@ -550,6 +531,10 @@
#define RISC_PSR_ALU_MSB 0x0400 #define RISC_PSR_ALU_MSB 0x0400
#define RISC_PSR_ALU_CARRY 0x0200 #define RISC_PSR_ALU_CARRY 0x0200
#define RISC_PSR_ALU_ZERO 0x0100 #define RISC_PSR_ALU_ZERO 0x0100
#define RISC_PSR_PCI_ULTRA 0x0080
#define RISC_PSR_SBUS_ULTRA 0x0020
#define RISC_PSR_DMA_INT 0x0010 #define RISC_PSR_DMA_INT 0x0010
#define RISC_PSR_SXP_INT 0x0008 #define RISC_PSR_SXP_INT 0x0008
#define RISC_PSR_HOST_INT 0x0004 #define RISC_PSR_HOST_INT 0x0004
@ -586,4 +571,123 @@
#define HCCR_PAUSE 0x0020 /* R : RISC paused */ #define HCCR_PAUSE 0x0020 /* R : RISC paused */
#define PCI_HCCR_BIOS 0x0001 /* W : BIOS enable */ #define PCI_HCCR_BIOS 0x0001 /* W : BIOS enable */
/*
* Qlogic 1XXX NVRAM is an array of 128 bytes.
*
* Some portion of the front of this is for general host adapter properties
* This is followed by an array of per-target parameters, and is tailed off
* with a checksum xor byte at offset 127. For non-byte entities data is
* stored in Little Endian order.
*/
#define ISP_NVRAM_SIZE 128
#define ISPBSMX(c, byte, shift, mask) \
(((c)[(byte)] >> (shift)) & (mask))
#define ISP_NVRAM_VERSION(c) (c)[4]
#define ISP_NVRAM_FIFO_THRESHOLD(c) ISPBSMX(c, 5, 0, 0x03)
#define ISP_NVRAM_BIOS_DISABLE(c) ISPBSMX(c, 5, 2, 0x01)
#define ISP_NVRAM_HBA_ENABLE(c) ISPBSMX(c, 5, 3, 0x01)
#define ISP_NVRAM_INITIATOR_ID(c) ISPBSMX(c, 5, 4, 0x0f)
#define ISP_NVRAM_BUS_RESET_DELAY(c) (c)[6]
#define ISP_NVRAM_BUS_RETRY_COUNT(c) (c)[7]
#define ISP_NVRAM_BUS_RETRY_DELAY(c) (c)[8]
#define ISP_NVRAM_ASYNC_DATA_SETUP_TIME(c) ISPBSMX(c, 9, 0, 0x0f)
#define ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(c) ISPBSMX(c, 9, 4, 0x01)
#define ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(c) ISPBSMX(c, 9, 5, 0x01)
#define ISP_NVRAM_DATA_DMA_BURST_ENABLE(c) ISPBSMX(c, 9, 6, 0x01)
#define ISP_NVRAM_CMD_DMA_BURST_ENABLE(c) ISPBSMX(c, 9, 7, 0x01)
#define ISP_NVRAM_TAG_AGE_LIMIT(c) (c)[10]
#define ISP_NVRAM_LOWTRM_ENABLE(c) ISPBSMX(c, 11, 0, 0x01)
#define ISP_NVRAM_HITRM_ENABLE(c) ISPBSMX(c, 11, 1, 0x01)
#define ISP_NVRAM_PCMC_BURST_ENABLE(c) ISPBSMX(c, 11, 2, 0x01)
#define ISP_NVRAM_ENABLE_60_MHZ(c) ISPBSMX(c, 11, 3, 0x01)
#define ISP_NVRAM_SCSI_RESET_DISABLE(c) ISPBSMX(c, 11, 4, 0x01)
#define ISP_NVRAM_ENABLE_AUTO_TERM(c) ISPBSMX(c, 11, 5, 0x01)
#define ISP_NVRAM_FIFO_THRESHOLD_128(c) ISPBSMX(c, 11, 6, 0x01)
#define ISP_NVRAM_AUTO_TERM_SUPPORT(c) ISPBSMX(c, 11, 7, 0x01)
#define ISP_NVRAM_SELECTION_TIMEOUT(c) (((c)[12]) | ((c)[13] << 8))
#define ISP_NVRAM_MAX_QUEUE_DEPTH(c) (((c)[14]) | ((c)[15] << 8))
#define ISP_NVRAM_SCSI_BUS_SIZE(c) ISPBSMX(c, 16, 0, 0x01)
#define ISP_NVRAM_SCSI_BUS_TYPE(c) ISPBSMX(c, 16, 1, 0x01)
#define ISP_NVRAM_ADAPTER_CLK_SPEED(c) ISPBSMX(c, 16, 2, 0x01)
#define ISP_NVRAM_SOFT_TERM_SUPPORT(c) ISPBSMX(c, 16, 3, 0x01)
#define ISP_NVRAM_FLASH_ONBOARD(c) ISPBSMX(c, 16, 4, 0x01)
#define ISP_NVRAM_FAST_MTTR_ENABLE(c) ISPBSMX(c, 22, 0, 0x01)
#define ISP_NVRAM_TARGOFF 28
#define ISP_NVARM_TARGSIZE 6
#define _IxT(tgt, tidx) \
(ISP_NVRAM_TARGOFF + (ISP_NVARM_TARGSIZE * (tgt)) + (tidx))
#define ISP_NVRAM_TGT_RENEG(c, t) ISPBSMX(c, _IxT(t, 0), 0, 0x01)
#define ISP_NVRAM_TGT_QFRZ(c, t) ISPBSMX(c, _IxT(t, 0), 1, 0x01)
#define ISP_NVRAM_TGT_ARQ(c, t) ISPBSMX(c, _IxT(t, 0), 2, 0x01)
#define ISP_NVRAM_TGT_TQING(c, t) ISPBSMX(c, _IxT(t, 0), 3, 0x01)
#define ISP_NVRAM_TGT_SYNC(c, t) ISPBSMX(c, _IxT(t, 0), 4, 0x01)
#define ISP_NVRAM_TGT_WIDE(c, t) ISPBSMX(c, _IxT(t, 0), 5, 0x01)
#define ISP_NVRAM_TGT_PARITY(c, t) ISPBSMX(c, _IxT(t, 0), 6, 0x01)
#define ISP_NVRAM_TGT_DISC(c, t) ISPBSMX(c, _IxT(t, 0), 7, 0x01)
#define ISP_NVRAM_TGT_EXEC_THROTTLE(c, t) ISPBSMX(c, _IxT(t, 1), 0, 0xff)
#define ISP_NVRAM_TGT_SYNC_PERIOD(c, t) ISPBSMX(c, _IxT(t, 2), 0, 0xff)
#define ISP_NVRAM_TGT_SYNC_OFFSET(c, t) ISPBSMX(c, _IxT(t, 3), 0, 0x0f)
#define ISP_NVRAM_TGT_DEVICE_ENABLE(c, t) ISPBSMX(c, _IxT(t, 3), 4, 0x01)
#define ISP_NVRAM_TGT_LUN_DISABLE(c, t) ISPBSMX(c, _IxT(t, 3), 5, 0x01)
/*
* Qlogic 2XXX NVRAM is an array of 256 bytes.
*
* Some portion of the front of this is for general RISC engine parameters,
* mostly reflecting the state of the last INITIALIZE FIRMWARE mailbox command.
*
* This is followed by some general host adapter parameters, and ends with
* a checksum xor byte at offset 255. For non-byte entities data is stored
* in Little Endian order.
*/
#define ISP2100_NVRAM_SIZE 256
/* ISP_NVRAM_VERSION is in same overall place */
#define ISP2100_NVRAM_RISCVER(c) (c)[6]
#define ISP2100_NVRAM_ENABLE_HARDLOOPID(c) ISPBSMX(c, 8, 0, 0x01)
#define ISP2100_NVRAM_ENABLE_FAIRNESS(c) ISPBSMX(c, 8, 1, 0x01)
#define ISP2100_NVRAM_ENABLE_FULLDUPLEX(c) ISPBSMX(c, 8, 2, 0x01)
#define ISP2100_NVRAM_ENABLE_FAST_POSTING(c) ISPBSMX(c, 8, 3, 0x01)
#define ISP2100_NVRAM_ENABLE_TARGET_MODE(c) ISPBSMX(c, 8, 4, 0x01)
#define ISP2100_NVRAM_ENABLE_INITIATOR_MODE(c) ISPBSMX(c, 8, 5, 0x01)
#define ISP2100_NVRAM_QFRZ(c) ISPBSMX(c, 8, 6, 0x01)
#define ISP2100_NVRAM_MAXFRAMELENGTH(c) (((c)[10]) | ((c)[11] << 8))
#define ISP2100_NVRAM_MAXIOCBALLOCATION(c) (((c)[12]) | ((c)[13] << 8))
#define ISP2100_NVRAM_EXECUTION_THROTTLE(c) (((c)[14]) | ((c)[15] << 8))
#define ISP2100_NVRAM_RETRY_COUNT(c) (c)[16]
#define ISP2100_NVRAM_RETRY_DELAY(c) (c)[17]
#define ISP2100_NVRAM_NODE_NAME(c) ( \
(((u_int64_t)(c)[18]) << 56) | \
(((u_int64_t)(c)[19]) << 48) | \
(((u_int64_t)(c)[20]) << 40) | \
(((u_int64_t)(c)[21]) << 32) | \
(((u_int64_t)(c)[22]) << 24) | \
(((u_int64_t)(c)[23]) << 16) | \
(((u_int64_t)(c)[24]) << 8) | \
(((u_int64_t)(c)[25]) << 0))
#define ISP2100_NVRAM_HARDLOOPID(c) (c)[24]
#define ISP2100_NVRAM_HBA_DISABLE(c) ISPBSMX(c, 70, 0, 0x01)
#define ISP2100_NVRAM_BIOS_DISABLE(c) ISPBSMX(c, 70, 1, 0x01)
#define ISP2100_NVRAM_LUN_DISABLE(c) ISPBSMX(c, 70, 2, 0x01)
#define ISP2100_NVRAM_ENABLE_SELECT_BOOT(c) ISPBSMX(c, 70, 3, 0x01)
#define ISP2100_NVRAM_DISABLE_CODELOAD(c) ISPBSMX(c, 70, 4, 0x01)
#define ISP2100_NVRAM_SET_CACHELINESZ(c) ISPBSMX(c, 70, 5, 0x01)
#define ISP2100_NVRAM_BOOT_NODE_NAME(c) ( \
(((u_int64_t)(c)[72]) << 56) | \
(((u_int64_t)(c)[73]) << 48) | \
(((u_int64_t)(c)[74]) << 40) | \
(((u_int64_t)(c)[75]) << 32) | \
(((u_int64_t)(c)[76]) << 24) | \
(((u_int64_t)(c)[77]) << 16) | \
(((u_int64_t)(c)[78]) << 8) | \
(((u_int64_t)(c)[79]) << 0))
#define ISP2100_NVRAM_BOOT_LUN(c) (c)[80]
#endif /* _ISPREG_H */ #endif /* _ISPREG_H */

View File

@ -1,4 +1,4 @@
/* $Id: ispvar.h,v 1.2 1998/05/01 18:10:50 bde Exp $ */ /* $Id: ispvar.h,v 1.17 1998/09/14 23:22:51 mjacob Exp $ */
/* /*
* Soft Definitions for for Qlogic ISP SCSI adapters. * Soft Definitions for for Qlogic ISP SCSI adapters.
* *
@ -46,6 +46,9 @@
#include <ispmbox.h> #include <ispmbox.h>
#endif #endif
#define ISP_CORE_VERSION_MAJOR 1
#define ISP_CORE_VERSION_MINOR 3
/* /*
* Vector for MD code to provide specific services. * Vector for MD code to provide specific services.
*/ */
@ -73,29 +76,30 @@ struct ispmdvec {
}; };
#define MAX_TARGETS 16 #define MAX_TARGETS 16
#define MAX_LUNS 8
#define MAX_FC_TARG 126 #define MAX_FC_TARG 126
#define RQUEST_QUEUE_LEN(isp) MAXISPREQUEST /* queue length must be a power of two */
#define RESULT_QUEUE_LEN(isp) (MAXISPREQUEST/4)
#define QENTRY_LEN 64 #define QENTRY_LEN 64
#define RQUEST_QUEUE_LEN MAXISPREQUEST
#define RESULT_QUEUE_LEN (MAXISPREQUEST/4)
#define ISP_QUEUE_ENTRY(q, idx) ((q) + ((idx) * QENTRY_LEN)) #define ISP_QUEUE_ENTRY(q, idx) ((q) + ((idx) * QENTRY_LEN))
#define ISP_QUEUE_SIZE(n) ((n) * QENTRY_LEN) #define ISP_QUEUE_SIZE(n) ((n) * QENTRY_LEN)
#define ISP_NXT_QENTRY(idx, qlen) (((idx) + 1) & ((qlen)-1))
#define ISP_QAVAIL(in, out, qlen) \
((in == out)? (qlen - 1) : ((in > out)? \
((qlen - 1) - (in - out)) : (out - in - 1)))
/* /*
* SCSI (as opposed to FC-PH) Specific Host Adapter Parameters * SCSI (as opposed to FC-PH) Specific Host Adapter Parameters
*/ */
typedef struct { typedef struct {
u_int isp_adapter_enabled : 1, u_int isp_req_ack_active_neg : 1,
isp_req_ack_active_neg : 1,
isp_data_line_active_neg: 1, isp_data_line_active_neg: 1,
isp_cmd_dma_burst_enable: 1, isp_cmd_dma_burst_enable: 1,
isp_data_dma_burst_enabl: 1, isp_data_dma_burst_enabl: 1,
isp_fifo_threshold : 2, isp_fifo_threshold : 2,
isp_diffmode : 1, isp_diffmode : 1,
isp_fast_mttr : 1,
isp_initiator_id : 4, isp_initiator_id : 4,
isp_async_data_setup : 4; isp_async_data_setup : 4;
u_int16_t isp_selection_timeout; u_int16_t isp_selection_timeout;
@ -106,26 +110,32 @@ typedef struct {
u_int8_t isp_retry_count; u_int8_t isp_retry_count;
u_int8_t isp_retry_delay; u_int8_t isp_retry_delay;
struct { struct {
u_int8_t dev_flags; /* Device Flags - see below */ u_int dev_update : 1,
u_int8_t exc_throttle; dev_enable : 1,
u_int8_t sync_period; exc_throttle : 7,
u_int sync_offset : 4, sync_offset : 4,
dev_enable : 1; sync_period : 8;
u_int16_t dev_flags; /* persistent device flags */
u_int16_t cur_dflags; /* current device flags */
} isp_devparam[MAX_TARGETS]; } isp_devparam[MAX_TARGETS];
} sdparam; /* scsi device parameters */ } sdparam; /* scsi device parameters */
/* /*
* Device Flags * Device Flags
*/ */
#define DPARM_DISC 0x80 #define DPARM_DISC 0x8000
#define DPARM_PARITY 0x40 #define DPARM_PARITY 0x4000
#define DPARM_WIDE 0x20 #define DPARM_WIDE 0x2000
#define DPARM_SYNC 0x10 #define DPARM_SYNC 0x1000
#define DPARM_TQING 0x08 #define DPARM_TQING 0x0800
#define DPARM_ARQ 0x04 #define DPARM_ARQ 0x0400
#define DPARM_QFRZ 0x02 #define DPARM_QFRZ 0x0200
#define DPARM_RENEG 0x01 #define DPARM_RENEG 0x0100
#define DPARM_DEFAULT (0xff & ~DPARM_QFRZ) #define DPARM_NARROW 0x0080 /* Possibly only available with >= 7.55 fw */
#define DPARM_ASYNC 0x0040 /* Possibly only available with >= 7.55 fw */
#define DPARM_DEFAULT (0xFFFF & ~DPARM_QFRZ)
#define DPARM_SAFE_DFLT (DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING))
#define ISP_20M_SYNCPARMS 0x080c #define ISP_20M_SYNCPARMS 0x080c
#define ISP_10M_SYNCPARMS 0x0c19 #define ISP_10M_SYNCPARMS 0x0c19
@ -138,11 +148,15 @@ typedef struct {
*/ */
typedef struct { typedef struct {
u_int64_t isp_wwn; /* WWN of adapter */ u_int64_t isp_wwn; /* WWN of adapter */
u_int8_t isp_loopid; /* FCAL of this adapter inst */ u_int8_t isp_loopid; /* hard loop id */
u_int8_t isp_retry_count; u_int8_t isp_alpa; /* ALPA */
u_int8_t isp_execthrottle;
u_int8_t isp_retry_delay; u_int8_t isp_retry_delay;
u_int8_t isp_retry_count;
u_int8_t isp_fwstate; /* ISP F/W state */ u_int8_t isp_fwstate; /* ISP F/W state */
u_int16_t isp_maxalloc;
u_int16_t isp_maxfrmlen;
u_int16_t isp_fwoptions;
/* /*
* Scratch DMA mapped in area to fetch Port Database stuff, etc. * Scratch DMA mapped in area to fetch Port Database stuff, etc.
*/ */
@ -197,27 +211,37 @@ struct ispsoftc {
* State, debugging, etc.. * State, debugging, etc..
*/ */
u_int32_t isp_state : 3, u_int : 8,
isp_dogactive : 1,
isp_dblev : 4,
isp_confopts : 8, isp_confopts : 8,
isp_fwrev : 16; : 2,
isp_dblev : 3,
isp_gotdparms : 1,
isp_dogactive : 1,
isp_bustype : 1, /* BUS Implementation */
isp_type : 8; /* HBA Type and Revision */
/* u_int16_t isp_fwrev; /* Running F/W revision */
* Host Adapter Type and Parameters. u_int16_t isp_romfw_rev; /* 'ROM' F/W revision */
* Some parameters nominally stored in NVRAM on card.
*/
void * isp_param; void * isp_param;
u_int8_t isp_type;
int16_t isp_nactive;
/* /*
* Result and Request Queues. * Volatile state
*/ */
volatile u_int
: 19,
isp_state : 3,
isp_sendmarker : 1, /* send a marker entry */
isp_update : 1, /* update paramters */
isp_nactive : 9; /* how many commands active */
/*
* Result and Request Queue indices.
*/
volatile u_int8_t isp_reqodx; /* index of last ISP pickup */
volatile u_int8_t isp_reqidx; /* index of next request */ volatile u_int8_t isp_reqidx; /* index of next request */
volatile u_int8_t isp_residx; /* index of next result */ volatile u_int8_t isp_residx; /* index of next result */
volatile u_int8_t isp_sendmarker; volatile u_int8_t isp_seqno; /* rolling sequence # */
volatile u_int8_t isp_seqno;
/* /*
* Sheer laziness, but it gets us around the problem * Sheer laziness, but it gets us around the problem
@ -228,10 +252,10 @@ struct ispsoftc {
* jeez, so I blow a couple of KB per host adapter... * jeez, so I blow a couple of KB per host adapter...
* and it *is* faster. * and it *is* faster.
*/ */
volatile ISP_SCSI_XFER_T *isp_xflist[MAXISPREQUEST]; volatile ISP_SCSI_XFER_T *isp_xflist[RQUEST_QUEUE_LEN];
/* /*
* request/result queues * request/result queues and dma handles for them.
*/ */
volatile caddr_t isp_rquest; volatile caddr_t isp_rquest;
volatile caddr_t isp_result; volatile caddr_t isp_result;
@ -252,14 +276,24 @@ struct ispsoftc {
*/ */
#define ISP_CFG_NORELOAD 0x80 /* don't download f/w */ #define ISP_CFG_NORELOAD 0x80 /* don't download f/w */
#define ISP_FW_REV(maj, min) ((maj) << 10| (min))
/* /*
* Adapter Types * Bus (implementation) types
*/
#define ISP_BT_PCI 0 /* PCI Implementations */
#define ISP_BT_SBUS 1 /* SBus Implementations */
/*
* Chip Types
*/ */
#define ISP_HA_SCSI 0xf #define ISP_HA_SCSI 0xf
#define ISP_HA_SCSI_UNKNOWN 0x0 #define ISP_HA_SCSI_UNKNOWN 0x1
#define ISP_HA_SCSI_1020 0x1 #define ISP_HA_SCSI_1020 0x2
#define ISP_HA_SCSI_1040A 0x2 #define ISP_HA_SCSI_1020A 0x3
#define ISP_HA_SCSI_1040B 0x3 #define ISP_HA_SCSI_1040 0x4
#define ISP_HA_SCSI_1040A 0x5
#define ISP_HA_SCSI_1040B 0x6
#define ISP_HA_FC 0xf0 #define ISP_HA_FC 0xf0
#define ISP_HA_FC_2100 0x10 #define ISP_HA_FC_2100 0x10
@ -301,18 +335,11 @@ struct ispsoftc {
*/ */
/* /*
* Reset Hardware. * Reset Hardware. Totally. Assumes that you'll follow this with
* a call to isp_init.
*/ */
void isp_reset __P((struct ispsoftc *)); void isp_reset __P((struct ispsoftc *));
/*
* Abort this running command..
*
* Second argument is an index into xflist array.
* All locks must be held already.
*/
int isp_abortcmd __P((struct ispsoftc *, int));
/* /*
* Initialize Hardware to known state * Initialize Hardware to known state
*/ */
@ -323,6 +350,11 @@ void isp_init __P((struct ispsoftc *));
*/ */
void isp_uninit __P((struct ispsoftc *)); void isp_uninit __P((struct ispsoftc *));
/*
* Reset the ISP and call completion for any orphaned commands.
*/
void isp_restart __P((struct ispsoftc *));
/* /*
* Interrupt Service Routine * Interrupt Service Routine
*/ */
@ -336,6 +368,31 @@ void isp_watch __P((void *));
/* /*
* Command Entry Point * Command Entry Point
*/ */
extern int32_t ispscsicmd __P((ISP_SCSI_XFER_T *)); int32_t ispscsicmd __P((ISP_SCSI_XFER_T *));
/*
* Platform Dependent to Internal Control Point
*
* For: Aborting a running command - arg is an ISP_SCSI_XFER_T *
* Resetting a Device - arg is target to reset
* Resetting a BUS - arg is ignored
* Updating parameters - arg is ignored
*
* Second argument is an index into xflist array.
* Assumes all locks must be held already.
*/
typedef enum {
ISPCTL_RESET_BUS,
ISPCTL_RESET_DEV,
ISPCTL_ABORT_CMD,
ISPCTL_UPDATE_PARAMS,
} ispctl_t;
int isp_control __P((struct ispsoftc *, ispctl_t, void *));
/*
* lost command routine (XXXX IN TRANSITION XXXX)
*/
void isp_lostcmd __P((struct ispsoftc *, ISP_SCSI_XFER_T *));
#endif /* _ISPVAR_H */ #endif /* _ISPVAR_H */