mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +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:
parent
83cf1450a1
commit
478f8a9685
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=39235
13183
sys/dev/isp/asm_pci.h
13183
sys/dev/isp/asm_pci.h
File diff suppressed because it is too large
Load Diff
2151
sys/dev/isp/isp.c
2151
sys/dev/isp/isp.c
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/* $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.
|
||||
*
|
||||
@ -35,15 +35,501 @@
|
||||
*/
|
||||
#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 u_int32_t isp_adapter_info __P((int));
|
||||
static int ispcmd __P((ISP_SCSI_XFER_T *));
|
||||
|
||||
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 = {
|
||||
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.
|
||||
@ -66,19 +552,12 @@ isp_attach(isp)
|
||||
isp->isp_osinfo._link.device = &isp_dev;
|
||||
isp->isp_osinfo._link.flags = 0;
|
||||
if (isp->isp_type & ISP_HA_FC) {
|
||||
isp->isp_osinfo._link.adapter_targ = 0xff;
|
||||
#if 0
|
||||
isp->isp_osinfo._link.openings =
|
||||
RQUEST_QUEUE_LEN(isp) / (MAX_FC_TARG-1);
|
||||
#endif
|
||||
isp->isp_osinfo._link.adapter_targ =
|
||||
((fcparam *)isp->isp_param)->isp_loopid;
|
||||
scbus->maxtarg = MAX_FC_TARG-1;
|
||||
} else {
|
||||
isp->isp_osinfo._link.adapter_targ =
|
||||
((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;
|
||||
}
|
||||
/*
|
||||
@ -106,7 +585,7 @@ ispminphys(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)) {
|
||||
bp->b_bcount = (1 << 24);
|
||||
@ -122,3 +601,62 @@ isp_adapter_info(unit)
|
||||
*/
|
||||
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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $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)
|
||||
*---------------------------------------
|
||||
@ -35,7 +35,14 @@
|
||||
#ifndef _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/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
@ -43,8 +50,6 @@
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include <scsi/scsiconf.h>
|
||||
#include <scsi/scsi_debug.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
@ -52,11 +57,12 @@
|
||||
#include <sys/kernel.h>
|
||||
|
||||
/*
|
||||
* Quick hack fix to get around osreldate.h not being present.
|
||||
* #include <osreldate.h>
|
||||
* Now that __FreeBSD_version is in sys/param.h, we can
|
||||
* automatically handle pre-3.0 cases.
|
||||
*/
|
||||
|
||||
#ifndef __FreeBSD_version
|
||||
#define __FreeBSD_version 300002
|
||||
#define __FreeBSD_version 226000
|
||||
#endif
|
||||
|
||||
#define ISP_SCSI_XFER_T struct scsi_xfer
|
||||
@ -68,6 +74,7 @@ struct isposinfo {
|
||||
struct callout_handle watchid;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* XXXX: UNTIL WE PUT CODE IN THAT CHECKS RETURNS FROM MALLOC
|
||||
* XXXX: FOR CONTIGOUS PAGES, WE LIMIT TO PAGE_SIZE THE SIZE
|
||||
@ -75,8 +82,6 @@ struct isposinfo {
|
||||
*/
|
||||
#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/ispvar.h>
|
||||
@ -84,19 +89,18 @@ struct isposinfo {
|
||||
|
||||
#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_UNLOCK (void) splx(isp_spl_save)
|
||||
#define ISP_LOCK isp_spl_save = splbio()
|
||||
#define ISP_UNLOCK(isp) (void) splx(isp_spl_save)
|
||||
#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 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_TGT(xs) (xs)->sc_link->target
|
||||
#define XS_RESID(xs) (xs)->resid
|
||||
@ -116,6 +120,8 @@ struct isposinfo {
|
||||
#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)
|
||||
@ -128,7 +134,16 @@ struct isposinfo {
|
||||
#define XS_CMD_DONE(xs) (xs)->flags |= ITSDONE, scsi_done(xs)
|
||||
#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_EAGAIN TRY_AGAIN_LATER
|
||||
@ -157,4 +172,7 @@ struct isposinfo {
|
||||
#define RESTART_WATCHDOG(f, s) START_WATCHDOG(f, s)
|
||||
extern void isp_attach __P((struct ispsoftc *));
|
||||
|
||||
#define PVS "Qlogic ISP Driver, FreeBSD Non-Cam"
|
||||
|
||||
#endif /* !SCSI_CAM */
|
||||
#endif /* _ISP_FREEBSD_H */
|
||||
|
410
sys/dev/isp/isp_freebsd_cam.h
Normal file
410
sys/dev/isp/isp_freebsd_cam.h
Normal 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 */
|
@ -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
|
||||
@ -122,6 +122,9 @@
|
||||
#define MBOX_CLEAR_TASK_SET 0x67
|
||||
#define MBOX_ABORT_TASK_SET 0x68
|
||||
#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
|
||||
|
||||
@ -131,6 +134,42 @@ typedef struct {
|
||||
u_int16_t param[8];
|
||||
} 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
|
||||
*/
|
||||
@ -161,14 +200,31 @@ typedef struct {
|
||||
#define RQSFLAG_BADPACKET 0x08
|
||||
|
||||
/* RQS entry_type definitions */
|
||||
#define RQSTYPE_REQUEST 1
|
||||
#define RQSTYPE_DATASEG 2
|
||||
#define RQSTYPE_RESPONSE 3
|
||||
#define RQSTYPE_MARKER 4
|
||||
#define RQSTYPE_CMDONLY 5
|
||||
#define RQSTYPE_T2RQS 17
|
||||
#define RQSTYPE_T3RQS 25
|
||||
#define RQSTYPE_T1DSEG 10
|
||||
#define RQSTYPE_REQUEST 0x01
|
||||
#define RQSTYPE_DATASEG 0x02
|
||||
#define RQSTYPE_RESPONSE 0x03
|
||||
#define RQSTYPE_MARKER 0x04
|
||||
#define RQSTYPE_CMDONLY 0x05
|
||||
#define RQSTYPE_ATIO 0x06 /* Target Mode */
|
||||
#define RQSTYPE_CTIO0 0x07 /* Target Mode */
|
||||
#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
|
||||
@ -226,6 +282,13 @@ typedef struct {
|
||||
#define REQFLAG_DATA_UNKNOWN 0x0060
|
||||
|
||||
#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 {
|
||||
isphdr_t req_header;
|
||||
@ -320,6 +383,17 @@ typedef struct {
|
||||
#define RQCS_ID_MSG_FAILED 0x0013
|
||||
#define RQCS_UNEXP_BUS_FREE 0x0014
|
||||
#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 */
|
||||
#define RQCS_PORT_UNAVAILABLE 0x0028
|
||||
#define RQCS_PORT_LOGGED_OUT 0x0029
|
||||
@ -349,12 +423,176 @@ typedef struct {
|
||||
#define RQSTF_TIMEOUT 0x0040
|
||||
#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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialization Control Block
|
||||
*
|
||||
* Version One format.
|
||||
*/
|
||||
typedef struct {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
@ -375,9 +613,16 @@ typedef struct {
|
||||
u_int8_t icb_retry_count;
|
||||
u_int8_t icb_retry_delay;
|
||||
#endif
|
||||
u_int16_t icb_nodename[4];
|
||||
u_int8_t icb_nodename[8];
|
||||
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_rspnsin;
|
||||
u_int16_t icb_rqstqlen;
|
||||
@ -385,10 +630,63 @@ typedef struct {
|
||||
u_int16_t icb_rqstaddr[4];
|
||||
u_int16_t icb_respaddr[4];
|
||||
} isp_icb_t;
|
||||
#define ICB_VERSION1 1
|
||||
|
||||
#define ICB_DFLT_FRMLEN 1024
|
||||
#define MAKE_NODE_NAME(isp, icbp) \
|
||||
(icbp)->icb_nodename[0] = 0, (icbp)->icb_nodename[1] = 0x5355,\
|
||||
(icbp)->icb_nodename[2] = 0x4E57, (icbp)->icb_nodename[3] = 0
|
||||
#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 RQRSP_ADDR0015 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 */
|
||||
|
@ -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
|
||||
* definitions for Qlogic ISP SCSI adapters.
|
||||
@ -196,6 +196,12 @@
|
||||
#define BIU_SEMA_STATUS 0x0002 /* Semaphore Status 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 */
|
||||
#define DMA_ENABLE_SXP_DMA 0x0008 /* Enable SXP to DMA Data */
|
||||
@ -303,31 +309,6 @@
|
||||
#define NMBOX(isp) \
|
||||
(((((isp)->isp_type & ISP_HA_SCSI) >= ISP_HA_SCSI_1040A) || \
|
||||
((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
|
||||
@ -550,6 +531,10 @@
|
||||
#define RISC_PSR_ALU_MSB 0x0400
|
||||
#define RISC_PSR_ALU_CARRY 0x0200
|
||||
#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_SXP_INT 0x0008
|
||||
#define RISC_PSR_HOST_INT 0x0004
|
||||
@ -586,4 +571,123 @@
|
||||
#define HCCR_PAUSE 0x0020 /* R : RISC paused */
|
||||
|
||||
#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 */
|
||||
|
@ -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.
|
||||
*
|
||||
@ -46,6 +46,9 @@
|
||||
#include <ispmbox.h>
|
||||
#endif
|
||||
|
||||
#define ISP_CORE_VERSION_MAJOR 1
|
||||
#define ISP_CORE_VERSION_MINOR 3
|
||||
|
||||
/*
|
||||
* Vector for MD code to provide specific services.
|
||||
*/
|
||||
@ -73,29 +76,30 @@ struct ispmdvec {
|
||||
};
|
||||
|
||||
#define MAX_TARGETS 16
|
||||
#define MAX_LUNS 8
|
||||
#define MAX_FC_TARG 126
|
||||
|
||||
#define RQUEST_QUEUE_LEN(isp) MAXISPREQUEST
|
||||
#define RESULT_QUEUE_LEN(isp) (MAXISPREQUEST/4)
|
||||
|
||||
#define QENTRY_LEN 64
|
||||
|
||||
#define ISP_QUEUE_ENTRY(q, idx) ((q) + ((idx) * QENTRY_LEN))
|
||||
#define ISP_QUEUE_SIZE(n) ((n) * QENTRY_LEN)
|
||||
|
||||
/* queue length must be a power of two */
|
||||
#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_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
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
u_int isp_adapter_enabled : 1,
|
||||
isp_req_ack_active_neg : 1,
|
||||
u_int isp_req_ack_active_neg : 1,
|
||||
isp_data_line_active_neg: 1,
|
||||
isp_cmd_dma_burst_enable: 1,
|
||||
isp_data_dma_burst_enabl: 1,
|
||||
isp_fifo_threshold : 2,
|
||||
isp_diffmode : 1,
|
||||
isp_fast_mttr : 1,
|
||||
isp_initiator_id : 4,
|
||||
isp_async_data_setup : 4;
|
||||
u_int16_t isp_selection_timeout;
|
||||
@ -106,26 +110,32 @@ typedef struct {
|
||||
u_int8_t isp_retry_count;
|
||||
u_int8_t isp_retry_delay;
|
||||
struct {
|
||||
u_int8_t dev_flags; /* Device Flags - see below */
|
||||
u_int8_t exc_throttle;
|
||||
u_int8_t sync_period;
|
||||
u_int sync_offset : 4,
|
||||
dev_enable : 1;
|
||||
u_int dev_update : 1,
|
||||
dev_enable : 1,
|
||||
exc_throttle : 7,
|
||||
sync_offset : 4,
|
||||
sync_period : 8;
|
||||
u_int16_t dev_flags; /* persistent device flags */
|
||||
u_int16_t cur_dflags; /* current device flags */
|
||||
} isp_devparam[MAX_TARGETS];
|
||||
} sdparam; /* scsi device parameters */
|
||||
|
||||
/*
|
||||
* Device Flags
|
||||
*/
|
||||
#define DPARM_DISC 0x80
|
||||
#define DPARM_PARITY 0x40
|
||||
#define DPARM_WIDE 0x20
|
||||
#define DPARM_SYNC 0x10
|
||||
#define DPARM_TQING 0x08
|
||||
#define DPARM_ARQ 0x04
|
||||
#define DPARM_QFRZ 0x02
|
||||
#define DPARM_RENEG 0x01
|
||||
#define DPARM_DEFAULT (0xff & ~DPARM_QFRZ)
|
||||
#define DPARM_DISC 0x8000
|
||||
#define DPARM_PARITY 0x4000
|
||||
#define DPARM_WIDE 0x2000
|
||||
#define DPARM_SYNC 0x1000
|
||||
#define DPARM_TQING 0x0800
|
||||
#define DPARM_ARQ 0x0400
|
||||
#define DPARM_QFRZ 0x0200
|
||||
#define DPARM_RENEG 0x0100
|
||||
#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_10M_SYNCPARMS 0x0c19
|
||||
@ -138,11 +148,15 @@ typedef struct {
|
||||
*/
|
||||
typedef struct {
|
||||
u_int64_t isp_wwn; /* WWN of adapter */
|
||||
u_int8_t isp_loopid; /* FCAL of this adapter inst */
|
||||
u_int8_t isp_retry_count;
|
||||
u_int8_t isp_loopid; /* hard loop id */
|
||||
u_int8_t isp_alpa; /* ALPA */
|
||||
u_int8_t isp_execthrottle;
|
||||
u_int8_t isp_retry_delay;
|
||||
u_int8_t isp_retry_count;
|
||||
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.
|
||||
*/
|
||||
@ -197,27 +211,37 @@ struct ispsoftc {
|
||||
* State, debugging, etc..
|
||||
*/
|
||||
|
||||
u_int32_t isp_state : 3,
|
||||
isp_dogactive : 1,
|
||||
isp_dblev : 4,
|
||||
u_int : 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 */
|
||||
|
||||
/*
|
||||
* Host Adapter Type and Parameters.
|
||||
* Some parameters nominally stored in NVRAM on card.
|
||||
*/
|
||||
u_int16_t isp_fwrev; /* Running F/W revision */
|
||||
u_int16_t isp_romfw_rev; /* 'ROM' F/W revision */
|
||||
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_residx; /* index of next result */
|
||||
volatile u_int8_t isp_sendmarker;
|
||||
volatile u_int8_t isp_seqno;
|
||||
volatile u_int8_t isp_seqno; /* rolling sequence # */
|
||||
|
||||
/*
|
||||
* 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...
|
||||
* 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_result;
|
||||
@ -252,14 +276,24 @@ struct ispsoftc {
|
||||
*/
|
||||
#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_UNKNOWN 0x0
|
||||
#define ISP_HA_SCSI_1020 0x1
|
||||
#define ISP_HA_SCSI_1040A 0x2
|
||||
#define ISP_HA_SCSI_1040B 0x3
|
||||
#define ISP_HA_SCSI_UNKNOWN 0x1
|
||||
#define ISP_HA_SCSI_1020 0x2
|
||||
#define ISP_HA_SCSI_1020A 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_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 *));
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
@ -323,6 +350,11 @@ void isp_init __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
|
||||
*/
|
||||
@ -336,6 +368,31 @@ void isp_watch __P((void *));
|
||||
/*
|
||||
* 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 */
|
||||
|
Loading…
Reference in New Issue
Block a user