From 4394c92f5265ea659629dfe337018f174c57b0e7 Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Thu, 25 Mar 1999 22:52:45 +0000 Subject: [PATCH] Add in 1080 LVD support and some basis also for the 1240. The port database printout is now enabled. --- sys/dev/isp/isp.c | 466 ++++++++++++++++++++-------------- sys/dev/isp/isp_freebsd.c | 176 +++++++------ sys/dev/isp/isp_freebsd.h | 11 +- sys/dev/isp/isp_freebsd_cam.h | 4 +- sys/dev/isp/ispreg.h | 31 ++- sys/dev/isp/ispvar.h | 27 +- 6 files changed, 413 insertions(+), 302 deletions(-) diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 769d296e872..efc5217b740 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -1,14 +1,12 @@ -/* $Id: isp.c,v 1.13 1999/02/09 01:07:06 mjacob Exp $ */ -/* release_03_16_99 */ +/* $Id: isp.c,v 1.14 1999/03/17 05:04:38 mjacob Exp $ */ +/* release_03_25_99 */ /* * Machine and OS Independent (well, as best as possible) * code for the Qlogic ISP SCSI adapters. * - *--------------------------------------- * Copyright (c) 1997, 1998 by Matthew Jacob * NASA/Ames Research Center * All rights reserved. - *--------------------------------------- * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -113,7 +111,7 @@ static void isp_fastpost_complete __P((struct ispsoftc *, int)); static void isp_fibre_init __P((struct ispsoftc *)); static void isp_mark_getpdb_all __P((struct ispsoftc *)); static int isp_getpdb __P((struct ispsoftc *, int, isp_pdb_t *)); -static int isp_fclink_test __P((struct ispsoftc *)); +static int isp_fclink_test __P((struct ispsoftc *, int)); static void isp_fw_state __P((struct ispsoftc *)); static void isp_dumpregs __P((struct ispsoftc *, const char *)); static void isp_dumpxflist __P((struct ispsoftc *)); @@ -189,11 +187,33 @@ isp_reset(isp) if (IS_FC(isp)) { revname = "2100"; } else if (IS_1080(isp)) { + u_int16_t l; sdparam *sdp = isp->isp_param; revname = "1080"; - sdp->isp_clock = 0; /* don't set clock */ - sdp->isp_diffmode = 1; - sdp->isp_ultramode = 1; + sdp->isp_clock = 100; + l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK; + switch (l) { + case ISP1080_LVD_MODE: + sdp->isp_lvdmode = 1; + PRINTF("%s: LVD Mode\n", isp->isp_name); + break; + case ISP1080_HVD_MODE: + sdp->isp_diffmode = 1; + PRINTF("%s: Differential Mode\n", isp->isp_name); + break; + case ISP1080_SE_MODE: + sdp->isp_ultramode = 1; + PRINTF("%s: Single-Ended Mode\n", isp->isp_name); + break; + default: + /* + * Hmm. Up in a wierd mode. This means all SCSI I/O + * buffer lines are tristated, so we're in a lot of + * trouble if we don't set things up right. + */ + PRINTF("%s: Illegal Mode 0x%x\n", isp->isp_name, l); + break; + } } else { sdparam *sdp = isp->isp_param; i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK; @@ -203,7 +223,7 @@ isp_reset(isp) isp->isp_name, i); /* FALLTHROUGH */ case 1: - revname = "1020"; + revname = "1020"; isp->isp_type = ISP_HA_SCSI_1020; sdp->isp_clock = 40; break; @@ -213,7 +233,7 @@ isp_reset(isp) * run the clock rate up for that unless told to * do so by the Ultra Capable bits being set. */ - revname = "1020A"; + revname = "1020A"; isp->isp_type = ISP_HA_SCSI_1020A; sdp->isp_clock = 40; break; @@ -257,7 +277,7 @@ isp_reset(isp) * even for the SBus version. */ sdp->isp_clock = 60; - } else { + } else { sdp->isp_ultramode = 0; /* * Clock is known. Gronk. @@ -307,9 +327,9 @@ again: * Clear data && control DMA engines. */ ISP_WRITE(isp, CDMA_CONTROL, - DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); + DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); ISP_WRITE(isp, DDMA_CONTROL, - DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); + DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); } else { @@ -386,11 +406,11 @@ again: } #ifdef PTI_CARDS if (((sdparam *) isp->isp_param)->isp_ultramode) { - while(ISP_READ(isp, RISC_MTR) != 0x1313) { + while (ISP_READ(isp, RISC_MTR) != 0x1313) { ISP_WRITE(isp, RISC_MTR, 0x1313); ISP_WRITE(isp, HCCR, HCCR_CMD_STEP); } - } else { + } else { ISP_WRITE(isp, RISC_MTR, 0x1212); } /* @@ -550,7 +570,7 @@ again: PRINTF("%s: Board Revision %s, %s F/W Revision %d.%d\n", isp->isp_name, revname, dodnld? "loaded" : "resident", mbs.param[1], mbs.param[2]); - if (isp->isp_type & ISP_HA_FC) { + if (IS_FC(isp)) { if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) { PRINTF("%s: in 64-Bit PCI slot\n", isp->isp_name); } @@ -590,7 +610,7 @@ isp_init(isp) PRINTF("%s: can't setup dma mailboxes\n", isp->isp_name); return; } - + /* * If we're fibre, we have a completely different * initialization method. @@ -693,27 +713,25 @@ isp_init(isp) /* * It is not quite clear when this changed over so that * we could force narrow and async, so assume >= 7.55. - * - * Otherwise, a SCSI bus reset issued below will force - * the back to the narrow, async state (but see note - * below also). Technically we should also do without - * Parity. */ if (isp->isp_fwrev >= ISP_FW_REV(7, 55)) { sdf |= DPARM_NARROW | DPARM_ASYNC; } - mbs.param[0] = MBOX_SET_TARGET_PARAMS; mbs.param[1] = tgt << 8; mbs.param[2] = sdf; - mbs.param[3] = 0; + mbs.param[3] = + (sdp->isp_devparam[tgt].sync_offset << 8) | + (sdp->isp_devparam[tgt].sync_period); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { sdf = DPARM_SAFE_DFLT; mbs.param[0] = MBOX_SET_TARGET_PARAMS; mbs.param[1] = tgt << 8; mbs.param[2] = sdf; - mbs.param[3] = 0; + mbs.param[3] = + (sdp->isp_devparam[tgt].sync_offset << 8) | + (sdp->isp_devparam[tgt].sync_period); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: failed even to set defaults for " @@ -721,8 +739,26 @@ isp_init(isp) continue; } } - sdp->isp_devparam[tgt].cur_dflags = sdf; - + /* + * We don't update dev_flags with what we've set + * because that's not the ultimate goal setting. + * If we succeed with the command, we *do* update + * cur_dflags. + */ + mbs.param[0] = MBOX_GET_TARGET_PARAMS; + mbs.param[1] = (tgt << 8); + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + /* + * Urrr.... We'll set cur_dflags to DPARM_SAFE_DFLT so + * we don't try and do tags if tags aren't enabled. + */ + sdp->isp_devparam[tgt].cur_dflags = DPARM_SAFE_DFLT; + } else { + sdp->isp_devparam[tgt].cur_dflags = mbs.param[2]; + sdp->isp_devparam[tgt].cur_offset = mbs.param[3] >> 8; + sdp->isp_devparam[tgt].cur_period = mbs.param[3] & 0xff; + } maxlun = (isp->isp_fwrev >= ISP_FW_REV(7, 55))? 32 : 8; for (lun = 0; lun < maxlun; lun++) { mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS; @@ -770,25 +806,32 @@ isp_init(isp) isp->isp_reqidx = isp->isp_reqodx = 0; /* - * Turn on Fast Posting + * Turn on Fast Posting, LVD transitions */ -#ifndef ISP_NO_FASTPOST_SCSI - if (isp->isp_fwrev >= ISP_FW_REV(7, 55)) { + + if (IS_1080(isp) || isp->isp_fwrev >= ISP_FW_REV(7, 55)) { mbs.param[0] = MBOX_SET_FW_FEATURES; - mbs.param[1] = FW_FEATURE_FAST_POST; - isp_mboxcmd(isp, &mbs); - if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { - PRINTF("%s: unable to enable FAST Posting\n", - isp->isp_name); +#ifndef ISP_NO_FASTPOST_SCSI + mbs.param[1] |= FW_FEATURE_FAST_POST; +#else + mbs.param[1] = 0; +#endif + if (IS_1080(isp)) + mbs.param[1] |= FW_FEATURE_LVD_NOTIFY; + if (mbs.param[1] != 0) { + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + PRINTF("%s: unable enable FW features\n", + isp->isp_name); + } } } -#endif /* * Let the outer layers decide whether to issue a SCSI bus reset. */ #if 0 - /* + /* * XXX: See whether or not for 7.55 F/W or later we * XXX: can do without this, and see whether we should * XXX: honor the NVRAM SCSI_RESET_DISABLE token. @@ -944,6 +987,8 @@ isp_fibre_init(isp) isp->isp_state = ISP_INITSTATE; fcp->isp_fwstate = FW_CONFIG_WAIT; + isp_mark_getpdb_all(isp); + #ifdef ISP_TARGET_MODE if (isp_modify_lun(isp, 0, 1, 1)) { PRINTF("%s: failed to enable target mode\n", isp->isp_name); @@ -975,31 +1020,19 @@ isp_getpdb(isp, id, pdbp) int id; isp_pdb_t *pdbp; { -#ifdef GETPDB_WORKING_YET fcparam *fcp = (fcparam *) isp->isp_param; mbreg_t mbs; - - /* - * Get Port Queue Parameters first- this is - * a Q&D way to see whether we're logged into - * this port. - */ - mbs.param[0] = MBOX_GET_DEV_QUEUE_PARAMS; - mbs.param[1] = id << 8; - mbs.param[2] = 0; -#ifdef ISP2100_SCCLUN - mbs.param[3] = 0; -#endif - isp_mboxcmd(isp, &mbs); - if (mbs.param[0] != MBOX_COMMAND_COMPLETE) - return (-1); - mbs.param[0] = MBOX_GET_PORT_DB; mbs.param[1] = id << 8; mbs.param[2] = (u_int16_t) (fcp->isp_scdma >> 16); mbs.param[3] = (u_int16_t) (fcp->isp_scdma & 0xffff); - mbs.param[4] = 0; - mbs.param[5] = 0; + /* + * Unneeded. For the 2100, except for initializing f/w, registers + * 4/5 have to not be written to. + * mbs.param[4] = 0; + * mbs.param[5] = 0; + * + */ mbs.param[6] = 0; mbs.param[7] = 0; isp_mboxcmd(isp, &mbs); @@ -1014,16 +1047,13 @@ isp_getpdb(isp, id, pdbp) case MBOX_COMMAND_PARAM_ERROR: /* Not Logged In */ IDPRINTF(3, ("%s: Comand Param Error on Get Port Database\n", - isp->isp_name)); + isp->isp_name)); return (-1); default: PRINTF("%s: error 0x%x getting port database for ID %d\n", isp->isp_name, mbs.param[0], id); return (-1); } -#else - pdbp->pdb_options = 1; -#endif return (0); } @@ -1032,8 +1062,9 @@ isp_getpdb(isp, id, pdbp) */ static int -isp_fclink_test(isp) +isp_fclink_test(isp, waitdelay) struct ispsoftc *isp; + int waitdelay; { mbreg_t mbs; int count; @@ -1044,10 +1075,9 @@ isp_fclink_test(isp) /* * Wait up to N microseconds for F/W to go to a ready state. - * This is a platform specific */ lwfs = FW_CONFIG_WAIT; - for (count = 0; count < FC_FW_READY_DELAY; count += 100) { + for (count = 0; count < waitdelay; count += 100) { isp_fw_state(isp); if (lwfs != fcp->isp_fwstate) { PRINTF("%s: Firmware State %s -> %s\n", @@ -1067,13 +1097,14 @@ isp_fclink_test(isp) if (fcp->isp_fwstate != FW_READY) { return (-1); } + /* * Get our Loop ID (if possible). We really need to have it. */ mbs.param[0] = MBOX_GET_LOOP_ID; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { - PRINTF("%s: GET LOOP ID failed\n", isp->isp_name); + PRINTF("%s: GET LOOP ID failed\n", isp->isp_name); return (-1); } fcp->isp_loopid = mbs.param[1]; @@ -1114,7 +1145,7 @@ ispscsicmd(xs) /* * We *could* do the different sequence type that has close - * to the whole Queue Entry for the command,... + * to the whole Queue Entry for the command... */ if (XS_CDBLEN(xs) > ((isp->isp_type & ISP_HA_FC)? 16 : 12)) { @@ -1137,30 +1168,18 @@ ispscsicmd(xs) * our cached copy of it... */ if (fcp->isp_fwstate != FW_READY) { - if (isp_fclink_test(isp)) { + if (isp_fclink_test(isp, FC_FW_READY_DELAY)) { XS_SETERR(xs, HBA_SELTIMEOUT); return (CMD_COMPLETE); } } /* - * Here's the spot we would need to find out whether - * the port names have changed, whether it's still - * a target role, etc.. + * Refresh our port database if needed. */ if (pdbp->pdb_options == INVALID_PDB_OPTIONS) { - /* - * If we don't know what it is- don't talk to it. - * This also handles cases where it's not logged - * into this port/target. - */ - if (isp_getpdb(isp, XS_TGT(xs), pdbp)) { - XS_SETERR(xs, HBA_SELTIMEOUT); - return (CMD_COMPLETE); -#ifdef GETPDB_WORKING_YET - } else { + if (isp_getpdb(isp, XS_TGT(xs), pdbp) == 0) { isp_async(isp, ISPASYNC_PDB_CHANGE_COMPLETE, (void *) (long) XS_TGT(xs)); -#endif } } } @@ -1242,6 +1261,7 @@ ispscsicmd(xs) * See comment in isp_intr */ XS_RESID(xs) = 0; + /* * Fibre Channel always requires some kind of tag. * If we're marked as "Can't Tag", just do simple @@ -1252,7 +1272,7 @@ ispscsicmd(xs) if (XS_CANTAG(xs)) { t2reqp->req_flags = XS_KINDOF_TAG(xs); } else { - t2reqp->req_flags = REQFLAG_STAG; + t2reqp->req_flags = REQFLAG_STAG; } } else { sdparam *sdp = (sdparam *)isp->isp_param; @@ -1365,7 +1385,7 @@ isp_control(isp, ctl, arg) PRINTF("%s: driver initiated bus reset\n", isp->isp_name); return (0); - case ISPCTL_RESET_DEV: + case ISPCTL_RESET_DEV: mbs.param[0] = MBOX_ABORT_TARGET; mbs.param[1] = ((long)arg) << 8; mbs.param[2] = 3; /* 'delay', in seconds */ @@ -1379,7 +1399,7 @@ isp_control(isp, ctl, arg) isp->isp_sendmarker = 1; return (0); - case ISPCTL_ABORT_CMD: + case ISPCTL_ABORT_CMD: xs = (ISP_SCSI_XFER_T *) arg; for (i = 0; i < RQUEST_QUEUE_LEN; i++) { if (xs == isp->isp_xflist[i]) { @@ -1418,10 +1438,10 @@ isp_control(isp, ctl, arg) case ISPCTL_UPDATE_PARAMS: isp_update(isp); - return(0); + return (0); case ISPCTL_FCLINK_TEST: - return (isp_fclink_test(isp)); + return (isp_fclink_test(isp, FC_FW_READY_DELAY)); } return (-1); } @@ -1448,7 +1468,7 @@ isp_intr(arg) if (isr == 0 || (isr & BIU2100_ISR_RISC_INT) == 0) { if (isr) { IDPRINTF(4, ("%s: isp_intr isr=%x\n", - isp->isp_name, isr)); + isp->isp_name, isr)); } return (0); } @@ -1456,7 +1476,7 @@ isp_intr(arg) if (isr == 0 || (isr & BIU_ISR_RISC_INT) == 0) { if (isr) { IDPRINTF(4, ("%s: isp_intr isr=%x\n", - isp->isp_name, isr)); + isp->isp_name, isr)); } return (0); } @@ -1465,10 +1485,8 @@ isp_intr(arg) if (ISP_READ(isp, BIU_SEMA) & 1) { u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0); if (mbox & 0x4000) { - if (mbox != MBOX_COMMAND_COMPLETE) { - PRINTF("%s: isp_intr sees 0x%x\n", - isp->isp_name,mbox); - } + IDPRINTF(3, ("%s: isp_intr sees 0x%x\n", + isp->isp_name, mbox)); ISP_WRITE(isp, BIU_SEMA, 0); } else { u_int32_t fhandle = isp_parse_async(isp, (int) mbox); @@ -1476,8 +1494,7 @@ isp_intr(arg) if (fhandle < 0) { return (1); } else if (fhandle > 0) { - xs = (ISP_SCSI_XFER_T *) - isp->isp_xflist[fhandle - 1]; + xs = (void *)isp->isp_xflist[fhandle - 1]; isp->isp_xflist[fhandle - 1] = NULL; /* * Since we don't have a result queue entry @@ -1491,7 +1508,7 @@ isp_intr(arg) } if (isp->isp_nactive > 0) isp->isp_nactive--; - complist[ndone++] = xs; + complist[ndone++] = xs; } } } @@ -1565,7 +1582,7 @@ isp_intr(arg) ISP_WRITE(isp, INMAILBOX5, optr); continue; } - xs = (ISP_SCSI_XFER_T *) isp->isp_xflist[sp->req_handle - 1]; + xs = (void *) isp->isp_xflist[sp->req_handle - 1]; if (xs == NULL) { PRINTF("%s: NULL xs in xflist (handle %x)\n", isp->isp_name, sp->req_handle); @@ -1674,7 +1691,7 @@ isp_intr(arg) */ if (nlooked) { ISP_WRITE(isp, INMAILBOX5, optr); - isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4); + isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4); } isp->isp_residx = optr; for (i = 0; i < ndone; i++) { @@ -1765,8 +1782,37 @@ isp_parse_async(isp, mbox) break; case ASYNC_BUS_TRANSIT: - PRINTF("%s: LBD->HVD Transition 0x%x\n", - isp->isp_name, ISP_READ(isp, OUTMAILBOX1)); + mbox = ISP_READ(isp, OUTMAILBOX2); + switch (mbox & 0x1c00) { + case SXP_PINS_LVD_MODE: + PRINTF("%s: Transition to LVD mode\n", isp->isp_name); + ((sdparam *)isp->isp_param)->isp_diffmode = 0; + ((sdparam *)isp->isp_param)->isp_ultramode = 0; + ((sdparam *)isp->isp_param)->isp_lvdmode = 1; + break; + case SXP_PINS_HVD_MODE: + PRINTF("%s: Transition to Differential mode\n", + isp->isp_name); + ((sdparam *)isp->isp_param)->isp_diffmode = 1; + ((sdparam *)isp->isp_param)->isp_ultramode = 0; + ((sdparam *)isp->isp_param)->isp_lvdmode = 0; + break; + case SXP_PINS_SE_MODE: + PRINTF("%s: Transition to Single Ended mode\n", + isp->isp_name); + ((sdparam *)isp->isp_param)->isp_diffmode = 0; + ((sdparam *)isp->isp_param)->isp_ultramode = 1; + ((sdparam *)isp->isp_param)->isp_lvdmode = 0; + break; + default: + PRINTF("%s: Transition to unknown mode 0x%x\n", + isp->isp_name, mbox); + break; + } + /* + * XXX: Set up to renegotiate again! + */ + isp->isp_sendmarker = 1; break; case ASYNC_CMD_CMPLT: @@ -1839,7 +1885,7 @@ isp_handle_other_response(isp, sp, optrp) in_fcentry_t *inot_fc; na_entry_t *nack; na_fcentry_t *nack_fc; - void *voidp; + void *voidp; #define atio un.atio #define at2io un.at2io #define ctio un.ctio @@ -1900,20 +1946,20 @@ isp_handle_other_response(isp, sp, optrp) ptisp_got_msg(ptp, &inot); break; case IN_RSRC_UNAVAIL: - PRINTF("%s: Firmware out of ATIOs\n", isp->isp_name); - break; - case IN_ABORT_TASK: + PRINTF("%s: Firmware out of ATIOs\n", isp->isp_name); + break; + case IN_ABORT_TASK: PRINTF("%s: Abort Task iid %d rx_id 0x%x\n", inot_fc->in_iid, seqid); - break; - case IN_PORT_LOGOUT: + break; + case IN_PORT_LOGOUT: PRINTF("%s: Port Logout for Initiator %d\n", isp->isp_name, inot_fc->in_iid); - break; - default: + break; + default: PRINTF("%s: bad status (0x%x) in Immediate Notify\n", - isp->isp_name, status); - break; + isp->isp_name, status); + break; } isp_notify_ack(isp, un.voidp); @@ -2001,7 +2047,7 @@ isp_handle_other_response(isp, sp, optrp) ct2->req_m.mode0.req_scsi_status = CTIO2_STATUS_VALID; ct2->req_seg_count = 1; if (at2->req_cdb[0] == 0x12) { - s = sizeof(tgtiqd); + s = sizeof (tgtiqd); MEMCPY(fcp->isp_scratch, tgtiqd, s); } else { s = at2->req_datalen; @@ -2073,7 +2119,7 @@ isp_handle_other_response(isp, sp, optrp) PRINTF("%s: CTIO2 returned status 0x%x\n", isp->isp_name, ct2->req_status); /* - * Return the ATIO to the board. + * Return the ATIO to the board. */ at2 = (ispatiot2_t *) sp; at2->req_header.rqs_entry_type = RQSTYPE_ATIO2; @@ -2274,7 +2320,7 @@ isp_handle_atio (isp, aep) * did not set DiscPriv in the identify message. We don't care * about this so it's ignored. */ - switch(status & ~TGTSVALID) { + switch (status & ~TGTSVALID) { case AT_PATH_INVALID: /* * ATIO rejected by the firmware due to disabled lun. @@ -2373,7 +2419,7 @@ isp_handle_atio2(isp, aep) * why this ATIO was sent to us. * If SenseValid is set, the firware has recommended Sense Data. */ - switch(status & ~TGTSVALID) { + switch (status & ~TGTSVALID) { case AT_PATH_INVALID: /* * ATIO rejected by the firmware due to disabled lun. @@ -2691,7 +2737,7 @@ isp_parse_status(isp, sp, xs) default: PRINTF("%s: comp status %x\n", isp->isp_name, - sp->req_completion_status); + sp->req_completion_status); break; } XS_SETERR(xs, HBA_BOTCH); @@ -2728,7 +2774,7 @@ isp_fastpost_complete(isp, fph) #define HINIB(x) ((x) >> 0x4) #define LONIB(x) ((x) & 0xf) -#define MAKNIB(a, b) (((a) << 4) | (b)) +#define MAKNIB(a, b) (((a) << 4) | (b)) static u_int8_t mbpcnt[] = { MAKNIB(1, 1), /* 0x00: MBOX_NO_OP */ MAKNIB(5, 5), /* 0x01: MBOX_LOAD_RAM */ @@ -2754,7 +2800,7 @@ static u_int8_t mbpcnt[] = { MAKNIB(4, 4), /* 0x15: MBOX_ABORT */ MAKNIB(2, 2), /* 0x16: MBOX_ABORT_DEVICE */ MAKNIB(3, 3), /* 0x17: MBOX_ABORT_TARGET */ - MAKNIB(2, 2), /* 0x18: MBOX_BUS_RESET */ + MAKNIB(3, 1), /* 0x18: MBOX_BUS_RESET */ MAKNIB(2, 3), /* 0x19: MBOX_STOP_QUEUE */ MAKNIB(2, 3), /* 0x1a: MBOX_START_QUEUE */ MAKNIB(2, 3), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */ @@ -2903,14 +2949,10 @@ isp_mboxcmd(isp, mbp) command_known: -#define NEW_MB_WAY 1 -#ifdef NEW_MB_WAY /* * Set semaphore on mailbox registers to win any races to acquire them. */ ISP_WRITE(isp, BIU_SEMA, 1); -#endif - /* * Make sure we can send some words. Check to see id there's @@ -2963,14 +3005,39 @@ command_known: } } + /* + * If we're a 1080 or a 1240, make sure that for a couple of commands + * the port parameter is set. This is sort of a temporary solution + * to do it here rather than every place a mailbox command is formed. + */ + if (IS_1080(isp) || IS_12X0(isp)) { + switch (mbp->param[0]) { + case MBOX_BUS_RESET: + mbp->param[2] = isp->isp_port; + break; + default: + break; + } + } + /* * Write input parameters. */ switch (inparam) { case 8: ISP_WRITE(isp, INMAILBOX7, mbp->param[7]); mbp->param[7] = 0; case 7: ISP_WRITE(isp, INMAILBOX6, mbp->param[6]); mbp->param[6] = 0; - case 6: ISP_WRITE(isp, INMAILBOX5, mbp->param[5]); mbp->param[5] = 0; - case 5: ISP_WRITE(isp, INMAILBOX4, mbp->param[4]); mbp->param[4] = 0; + case 6: + /* + * The Qlogic 2100 cannot have registers 4 and 5 written to + * after initialization or BAD THINGS HAPPEN (tm). + */ + if (IS_SCSI(isp) || mbp->param[0] == MBOX_INIT_FIRMWARE) + ISP_WRITE(isp, INMAILBOX5, mbp->param[5]); + mbp->param[5] = 0; + case 5: + if (IS_SCSI(isp) || mbp->param[0] == MBOX_INIT_FIRMWARE) + ISP_WRITE(isp, INMAILBOX4, mbp->param[4]); + mbp->param[4] = 0; case 4: ISP_WRITE(isp, INMAILBOX3, mbp->param[3]); mbp->param[3] = 0; case 3: ISP_WRITE(isp, INMAILBOX2, mbp->param[2]); mbp->param[2] = 0; case 2: ISP_WRITE(isp, INMAILBOX1, mbp->param[1]); mbp->param[1] = 0; @@ -2994,40 +3061,6 @@ command_known: */ ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT); -#ifndef NEW_MB_WAY - /* - * Wait until RISC int is set, except 2100 - */ - if ((isp->isp_type & ISP_HA_FC) == 0) { - loops = MBOX_DELAY_COUNT; - while ((ISP_READ(isp, BIU_ISR) & BIU_ISR_RISC_INT) == 0) { - SYS_DELAY(100); - if (--loops < 0) { - PRINTF("%s: isp_mboxcmd timeout #2\n", - isp->isp_name); - return; - } - } - } - - /* - * Check to make sure that the semaphore has been set. - */ - loops = MBOX_DELAY_COUNT; - while ((ISP_READ(isp, BIU_SEMA) & 1) == 0) { - SYS_DELAY(100); - /* - * Wierd- I've seen the case where the semaphore register - * isn't getting set- sort of a violation of the protocol.. - */ - if (ISP_READ(isp, OUTMAILBOX0) & 0x4000) - break; - if (--loops < 0) { - PRINTF("%s: isp_mboxcmd timeout #3\n", isp->isp_name); - return; - } - } -#else /* * Wait until HOST INT has gone away (meaning that the Qlogic * has picked up the mailbox command. Wait a long time. @@ -3059,7 +3092,6 @@ command_known: return; } } -#endif /* * Make sure that the MBOX_BUSY has gone away @@ -3121,7 +3153,7 @@ command_known: /* * Just to be chatty here... */ - switch(mbp->param[0]) { + switch (mbp->param[0]) { case MBOX_COMMAND_COMPLETE: break; case MBOX_INVALID_COMMAND: @@ -3194,7 +3226,7 @@ isp_lostcmd(isp, xs) } if (mbs.param[1]) { PRINTF("%s: %d commands on completion queue\n", - isp->isp_name, mbs.param[1]); + isp->isp_name, mbs.param[1]); } if (XS_NULL(xs)) return; @@ -3227,7 +3259,7 @@ isp_dumpregs(isp, msg) else PRINTF(" biu_csr=%x", ISP_READ(isp, BIU2100_CSR)); PRINTF(" biu_icr=%x biu_isr=%x biu_sema=%x ", ISP_READ(isp, BIU_ICR), - ISP_READ(isp, BIU_ISR), ISP_READ(isp, BIU_SEMA)); + ISP_READ(isp, BIU_ISR), ISP_READ(isp, BIU_SEMA)); PRINTF("risc_hccr=%x\n", ISP_READ(isp, HCCR)); @@ -3329,6 +3361,12 @@ isp_update(isp) continue; } + /* + * If the goal is to update the status of the device, + * take what's in dev_flags and try and set the device + * toward that. Otherwise, if we're just refreshing the + * current device state, get the current parameters. + */ if (sdp->isp_devparam[tgt].dev_update) { mbs.param[0] = MBOX_SET_TARGET_PARAMS; mbs.param[2] = sdp->isp_devparam[tgt].dev_flags; @@ -3336,8 +3374,20 @@ isp_update(isp) (sdp->isp_devparam[tgt].sync_offset << 8) | (sdp->isp_devparam[tgt].sync_period); sdp->isp_devparam[tgt].dev_update = 0; - sdp->isp_devparam[tgt].dev_refresh = 1; - isp->isp_update = 1; + /* + * A command completion later that has + * RQSTF_NEGOTIATION set will cause + * the dev_refresh/announce cycle. + * + * Note: It is really important to update our current + * flags with at least the state of TAG capabilities- + * otherwise we might try and send a tagged command + * when we have it all turned off. So change it here + * to say that current already matches goal. + */ + sdp->isp_devparam[tgt].cur_dflags &= ~DPARM_TQING; + sdp->isp_devparam[tgt].cur_dflags |= + (sdp->isp_devparam[tgt].dev_flags & DPARM_TQING); get = 0; } else if (sdp->isp_devparam[tgt].dev_refresh) { mbs.param[0] = MBOX_GET_TARGET_PARAMS; @@ -3360,16 +3410,14 @@ isp_update(isp) * XXX: Need a SYNC_TARGET for efficiency... */ isp->isp_sendmarker = 1; - sdp->isp_devparam[tgt].cur_dflags = - sdp->isp_devparam[tgt].dev_flags; continue; } flags = mbs.param[2]; period = mbs.param[3] & 0xff; offset = mbs.param[3] >> 8; if (sdp->isp_devparam[tgt].cur_dflags != flags || - sdp->isp_devparam[tgt].sync_period != period || - sdp->isp_devparam[tgt].sync_offset != offset) { + sdp->isp_devparam[tgt].cur_period != period || + sdp->isp_devparam[tgt].cur_offset != offset) { IDPRINTF(3, ("%s: tgt %d flags 0x%x period %d " "off %d\n", isp->isp_name, tgt, flags, period, offset)); @@ -3377,11 +3425,9 @@ isp_update(isp) } else { changed = 0; } - sdp->isp_devparam[tgt].cur_dflags = flags; - sdp->isp_devparam[tgt].dev_flags = flags; - sdp->isp_devparam[tgt].sync_period = period; - sdp->isp_devparam[tgt].sync_offset = offset; + sdp->isp_devparam[tgt].cur_period = period; + sdp->isp_devparam[tgt].cur_offset = offset; if (sdp->isp_devparam[tgt].dev_announced == 0 || changed) { if (isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &tgt)) sdp->isp_devparam[tgt].dev_announced = 0; @@ -3395,7 +3441,7 @@ static void isp_setdfltparm(isp) struct ispsoftc *isp; { - int i; + int tgt; mbreg_t mbs; sdparam *sdp; @@ -3408,9 +3454,17 @@ isp_setdfltparm(isp) } isp->isp_gotdparms = 1; - if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0 && - (isp_read_nvram(isp) == 0)) { - return; + /* + * If we've not been told to avoid reading NVRAM, try and read it. + * If we're successful reading it, we can return since NVRAM will + * tell us the right thing to do. Otherwise, establish some reasonable + * defaults. + */ + + if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) { + if (isp_read_nvram(isp) == 0) { + return; + } } if (IS_FC(isp)) { fcparam *fcp = (fcparam *) isp->isp_param; @@ -3441,19 +3495,32 @@ isp_setdfltparm(isp) sdp->isp_data_line_active_neg = (mbs.param[1] >> 5) & 0x1; } - for (i = 0; i < MAX_TARGETS; i++) { - sdp->isp_devparam[i].dev_flags = DPARM_DEFAULT; - sdp->isp_devparam[i].cur_dflags = DPARM_SAFE_DFLT; + /* + * The trick here is to establish a default for the default (honk!) + * state (dev_flags). Then try and get the current status from + * the card to fill in the current state. We don't, in fact, set + * the default to the SAFE default state- that's not the goal state. + */ + for (tgt = 0; tgt < MAX_TARGETS; tgt++) { + sdp->isp_devparam[tgt].cur_offset = 0; + sdp->isp_devparam[tgt].cur_period = 0; + sdp->isp_devparam[tgt].dev_flags = DPARM_DEFAULT; + sdp->isp_devparam[tgt].cur_dflags = 0; if (isp->isp_type < ISP_HA_SCSI_1040 || (sdp->isp_clock && sdp->isp_clock < 60)) { - sdp->isp_devparam[i].sync_offset = + sdp->isp_devparam[tgt].sync_offset = ISP_10M_SYNCPARMS >> 8; - sdp->isp_devparam[i].sync_period = + sdp->isp_devparam[tgt].sync_period = ISP_10M_SYNCPARMS & 0xff; + } else if (IS_1080(isp)) { + sdp->isp_devparam[tgt].sync_offset = + ISP_40M_SYNCPARMS >> 8; + sdp->isp_devparam[tgt].sync_period = + ISP_40M_SYNCPARMS & 0xff; } else { - sdp->isp_devparam[i].sync_offset = + sdp->isp_devparam[tgt].sync_offset = ISP_20M_SYNCPARMS >> 8; - sdp->isp_devparam[i].sync_period = + sdp->isp_devparam[tgt].sync_period = ISP_20M_SYNCPARMS & 0xff; } @@ -3461,29 +3528,33 @@ isp_setdfltparm(isp) * Don't get current target parameters if we've been * told not to use NVRAM- it's really the same thing. */ - if (isp->isp_confopts & ISP_CFG_NONVRAM) + if (isp->isp_confopts & ISP_CFG_NONVRAM) { continue; + } mbs.param[0] = MBOX_GET_TARGET_PARAMS; - mbs.param[1] = i << 8; + mbs.param[1] = tgt << 8; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { continue; } - sdp->isp_devparam[i].dev_flags = mbs.param[2]; + sdp->isp_devparam[tgt].cur_dflags = mbs.param[2]; + sdp->isp_devparam[tgt].dev_flags = mbs.param[2]; + sdp->isp_devparam[tgt].cur_period = mbs.param[3] & 0xff; + sdp->isp_devparam[tgt].cur_offset = mbs.param[3] >> 8; + /* * The maximum period we can really see * here is 100 (decimal), or 400 ns. * For some unknown reason we sometimes * get back wildass numbers from the - * boot device's parameters. - * - * XXX: Hmm- this may be based on a different - * XXX: clock rate. + * boot device's parameters (alpha only). */ if ((mbs.param[3] & 0xff) <= 0x64) { - sdp->isp_devparam[i].sync_period = mbs.param[3] & 0xff; - sdp->isp_devparam[i].sync_offset = mbs.param[3] >> 8; + sdp->isp_devparam[tgt].sync_period = + mbs.param[3] & 0xff; + sdp->isp_devparam[tgt].sync_offset = + mbs.param[3] >> 8; } /* @@ -3491,11 +3562,11 @@ isp_setdfltparm(isp) */ if (((sdp->isp_clock && sdp->isp_clock < 60) || (isp->isp_type < ISP_HA_SCSI_1020A)) && - (sdp->isp_devparam[i].sync_period == + (sdp->isp_devparam[tgt].sync_period <= (ISP_20M_SYNCPARMS & 0xff))) { - sdp->isp_devparam[i].sync_offset = + sdp->isp_devparam[tgt].sync_offset = ISP_10M_SYNCPARMS >> 8; - sdp->isp_devparam[i].sync_period = + sdp->isp_devparam[tgt].sync_period = ISP_10M_SYNCPARMS & 0xff; } } @@ -3519,13 +3590,13 @@ isp_setdfltparm(isp) sdp->isp_retry_count = 0; sdp->isp_retry_delay = 1; - for (i = 0; i < MAX_TARGETS; i++) { - sdp->isp_devparam[i].exc_throttle = 16; - sdp->isp_devparam[i].dev_enable = 1; + for (tgt = 0; tgt < MAX_TARGETS; tgt++) { + sdp->isp_devparam[tgt].exc_throttle = 16; + sdp->isp_devparam[tgt].dev_enable = 1; } } -/* +/* * Re-initialize the ISP and complete all orphaned commands * with a 'botched' notice. * @@ -3653,7 +3724,7 @@ isp_read_nvram(isp) sdp->isp_async_data_setup = 6; } } - + sdp->isp_req_ack_active_neg = ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data); @@ -3757,6 +3828,7 @@ isp_read_nvram(isp) sdp->isp_devparam[i].dev_flags |= DPARM_PARITY; if (ISP_NVRAM_TGT_DISC(nvram_data, i)) sdp->isp_devparam[i].dev_flags |= DPARM_DISC; + sdp->isp_devparam[i].cur_dflags = 0; /* we don't know */ if (isp->isp_dblev > 2) { PRINTF(" Target %d: Enabled %d Throttle %d " "Offset %d Period %d Flags 0x%x\n", i, diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index dcbf7528fd7..39abdff1e26 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -1,5 +1,5 @@ -/* $Id: isp_freebsd.c,v 1.12 1999/02/09 01:08:38 mjacob Exp $ */ -/* release_03_16_99 */ +/* $Id: isp_freebsd.c,v 1.13 1999/03/17 05:04:38 mjacob Exp $ */ +/* release_03_25_99 */ /* * Platform (FreeBSD) dependent common attachment code for Qlogic adapters. * @@ -329,7 +329,7 @@ isp_action(struct cam_sim *sim, union ccb *ccb) /* * Note that these operations affect the - * the permanent flags (dev_flags)- not + * the goal 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. @@ -371,8 +371,10 @@ isp_action(struct cam_sim *sim, union ccb *ccb) } else { *dptr &= ~DPARM_SYNC; } - IDPRINTF(3, ("%s: set target %d period %d offset %d " - "dev_flags 0x%x\n", isp->isp_name, tgt, + IDPRINTF(3, ("%s: %d set %s period 0x%x offset 0x%x" + " flags 0x%x\n", isp->isp_name, tgt, + (cts->flags & CCB_TRANS_CURRENT_SETTINGS)? + "current" : "user", sdp->isp_devparam[tgt].sync_period, sdp->isp_devparam[tgt].sync_offset, sdp->isp_devparam[tgt].dev_flags)); @@ -407,12 +409,17 @@ isp_action(struct cam_sim *sim, union ccb *ccb) cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; } else { sdparam *sdp = isp->isp_param; - u_int16_t dval; + u_int16_t dval, pval, oval; - if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) + if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) { dval = sdp->isp_devparam[tgt].cur_dflags; - else + oval = sdp->isp_devparam[tgt].cur_offset; + pval = sdp->isp_devparam[tgt].cur_period; + } else { dval = sdp->isp_devparam[tgt].dev_flags; + oval = sdp->isp_devparam[tgt].sync_offset; + pval = sdp->isp_devparam[tgt].sync_period; + } s = splcam(); cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB); @@ -431,17 +438,18 @@ isp_action(struct cam_sim *sim, union ccb *ccb) 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; + if ((dval & DPARM_SYNC) && oval != 0) { + cts->sync_period = pval; + cts->sync_offset = oval; cts->valid |= CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID; } splx(s); + IDPRINTF(3, ("%s: %d get %s period 0x%x offset 0x%x" + " flags 0x%x\n", isp->isp_name, tgt, + (cts->flags & CCB_TRANS_CURRENT_SETTINGS)? + "current" : "user", pval, oval, dval)); } ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); @@ -503,9 +511,9 @@ isp_action(struct cam_sim *sim, union ccb *ccb) 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) { + if (IS_FC(isp)) { + cpi->hba_misc = PIM_NOBUSRESET; cpi->max_target = MAX_FC_TARG-1; cpi->initiator_id = ((fcparam *)isp->isp_param)->isp_loopid; @@ -515,6 +523,7 @@ isp_action(struct cam_sim *sim, union ccb *ccb) cpi->max_lun = (1 << 4) - 1; #endif } else { + cpi->hba_misc = 0; cpi->initiator_id = ((sdparam *)isp->isp_param)->isp_initiator_id; cpi->max_target = MAX_TARGETS-1; @@ -612,7 +621,7 @@ isp_async(isp, cmd, arg) break; } - flags = sdp->isp_devparam[tgt].dev_flags; + flags = sdp->isp_devparam[tgt].cur_dflags; neg.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; if (flags & DPARM_DISC) { neg.flags |= CCB_TRANS_DISC_ENB; @@ -623,14 +632,15 @@ isp_async(isp, cmd, arg) neg.valid |= CCB_TRANS_BUS_WIDTH_VALID; neg.bus_width = (flags & DPARM_WIDE)? MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT; - neg.sync_period = sdp->isp_devparam[tgt].sync_period; - neg.sync_offset = sdp->isp_devparam[tgt].sync_offset; + neg.sync_period = sdp->isp_devparam[tgt].cur_period; + neg.sync_offset = sdp->isp_devparam[tgt].cur_offset; if (flags & DPARM_SYNC) { - neg.valid |= CCB_TRANS_SYNC_RATE_VALID | - CCB_TRANS_SYNC_OFFSET_VALID; + neg.valid |= + CCB_TRANS_SYNC_RATE_VALID | + CCB_TRANS_SYNC_OFFSET_VALID; } - IDPRINTF(3, ("%s: new params target %d period %d " - "offset %d flags 0x%x\n", isp->isp_name, tgt, + IDPRINTF(3, ("%s: New params tgt %d period 0x%x " + "offset 0x%x flags 0x%x\n", isp->isp_name, tgt, neg.sync_period, neg.sync_offset, flags)); xpt_setup_ccb(&neg.ccb_h, tmppath, 1); xpt_async(AC_TRANSFER_NEG, tmppath, &neg); @@ -676,55 +686,48 @@ isp_async(isp, cmd, arg) } break; case ISPASYNC_PDB_CHANGE_COMPLETE: - if (isp->isp_type & ISP_HA_FC) { - int i; + if (IS_FC(isp)) { + long i = (long) arg; static char *roles[4] = { "No", "Target", "Initiator", "Target/Initiator" }; - for (i = 0; i < MAX_FC_TARG; i++) { - isp_pdb_t *pdbp = - &((fcparam *)isp->isp_param)->isp_pdb[i]; - if (pdbp->pdb_options == INVALID_PDB_OPTIONS) - continue; - printf("%s: Loop ID %d, %s role\n", - isp->isp_name, pdbp->pdb_loopid, - roles[(pdbp->pdb_prli_svc3 >> 4) & 0x3]); - printf(" Node Address 0x%x WWN 0x" + isp_pdb_t *pdbp = &((fcparam *)isp->isp_param)->isp_pdb[i]; + if (pdbp->pdb_options == INVALID_PDB_OPTIONS) { + break; + } + printf("%s: Loop ID %d, %s role\n", isp->isp_name, + pdbp->pdb_loopid, roles[(pdbp->pdb_prli_svc3 >> 4) & 0x3]); + printf(" Node Address 0x%x WWN 0x" + "%02x%02x%02x%02x%02x%02x%02x%02x\n", + BITS2WORD(pdbp->pdb_portid_bits), + pdbp->pdb_portname[0], pdbp->pdb_portname[1], + pdbp->pdb_portname[2], pdbp->pdb_portname[3], + pdbp->pdb_portname[4], pdbp->pdb_portname[5], + pdbp->pdb_portname[6], pdbp->pdb_portname[7]); + if (pdbp->pdb_options & PDB_OPTIONS_ADISC) + printf(" Hard Address 0x%x WWN 0x" "%02x%02x%02x%02x%02x%02x%02x%02x\n", - BITS2WORD(pdbp->pdb_portid_bits), - pdbp->pdb_portname[0], pdbp->pdb_portname[1], - pdbp->pdb_portname[2], pdbp->pdb_portname[3], - pdbp->pdb_portname[4], pdbp->pdb_portname[5], - pdbp->pdb_portname[6], pdbp->pdb_portname[7]); - if (pdbp->pdb_options & PDB_OPTIONS_ADISC) - printf(" Hard Address 0x%x WWN 0x" - "%02x%02x%02x%02x%02x%02x%02x%02x\n", - BITS2WORD(pdbp->pdb_hardaddr_bits), - pdbp->pdb_nodename[0], - pdbp->pdb_nodename[1], - pdbp->pdb_nodename[2], - pdbp->pdb_nodename[3], - pdbp->pdb_nodename[4], - pdbp->pdb_nodename[5], - pdbp->pdb_nodename[6], - pdbp->pdb_nodename[7]); - switch (pdbp->pdb_prli_svc3 & SVC3_ROLE_MASK) { - case SVC3_TGT_ROLE|SVC3_INI_ROLE: - printf(" Master State=%s, Slave State=%s\n", - isp2100_pdb_statename(pdbp->pdb_mstate), - isp2100_pdb_statename(pdbp->pdb_sstate)); - break; - case SVC3_TGT_ROLE: - printf(" Master State=%s\n", - isp2100_pdb_statename(pdbp->pdb_mstate)); - break; - case SVC3_INI_ROLE: - printf(" Slave State=%s\n", - isp2100_pdb_statename(pdbp->pdb_sstate)); - break; - default: - break; - } + BITS2WORD(pdbp->pdb_hardaddr_bits), + pdbp->pdb_nodename[0], pdbp->pdb_nodename[1], + pdbp->pdb_nodename[2], pdbp->pdb_nodename[3], + pdbp->pdb_nodename[4], pdbp->pdb_nodename[5], + pdbp->pdb_nodename[6], pdbp->pdb_nodename[7]); + switch (pdbp->pdb_prli_svc3 & SVC3_ROLE_MASK) { + case SVC3_TGT_ROLE|SVC3_INI_ROLE: + printf(" Master State=%s, Slave State=%s\n", + isp2100_pdb_statename(pdbp->pdb_mstate), + isp2100_pdb_statename(pdbp->pdb_sstate)); + break; + case SVC3_TGT_ROLE: + printf(" Master State=%s\n", + isp2100_pdb_statename(pdbp->pdb_mstate)); + break; + case SVC3_INI_ROLE: + printf(" Slave State=%s\n", + isp2100_pdb_statename(pdbp->pdb_sstate)); + break; + default: + break; } break; } @@ -945,15 +948,34 @@ isp_async(isp, cmd, arg) if (isp->isp_type & ISP_HA_SCSI) { sdparam *sdp = isp->isp_param; char *wt; - int ns, flags, tgt; + int mhz, flags, tgt, period; tgt = *((int *) arg); - - flags = sdp->isp_devparam[tgt].dev_flags; - if (flags & DPARM_SYNC) { - ns = sdp->isp_devparam[tgt].sync_period * 4; + + flags = sdp->isp_devparam[tgt].cur_dflags; + period = sdp->isp_devparam[tgt].cur_period; + if ((flags & DPARM_SYNC) && period && + (sdp->isp_devparam[tgt].cur_offset) != 0) { + if (sdp->isp_lvdmode) { + switch (period) { + case 0xa: + mhz = 40; + break; + case 0xb: + mhz = 33; + break; + case 0xc: + mhz = 25; + break; + default: + mhz = 1000 / (period * 4); + break; + } + } else { + mhz = 1000 / (period * 4); + } } else { - ns = 0; + mhz = 0; } switch (flags & (DPARM_WIDE|DPARM_TQING)) { case DPARM_WIDE: @@ -969,10 +991,10 @@ isp_async(isp, cmd, arg) wt = "\n"; break; } - if (ns) { + if (mhz) { printf("%s: Target %d at %dMHz Max Offset %d%s", - isp->isp_name, tgt, 1000 / ns, - sdp->isp_devparam[tgt].sync_offset, wt); + isp->isp_name, tgt, mhz, + sdp->isp_devparam[tgt].cur_offset, wt); } else { printf("%s: Target %d Async Mode%s", isp->isp_name, tgt, wt); diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h index e9e50230ffa..bd58a28de58 100644 --- a/sys/dev/isp/isp_freebsd.h +++ b/sys/dev/isp/isp_freebsd.h @@ -1,5 +1,5 @@ -/* $Id: isp_freebsd.h,v 1.11 1999/02/09 01:05:42 mjacob Exp $ */ -/* release_03_16_99 */ +/* $Id: isp_freebsd.h,v 1.12 1999/03/17 05:04:39 mjacob Exp $ */ +/* release_03_25_99 */ /* * Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions (non CAM version) *--------------------------------------- @@ -36,7 +36,7 @@ #define _ISP_FREEBSD_H #define ISP_PLATFORM_VERSION_MAJOR 0 -#define ISP_PLATFORM_VERSION_MINOR 98 +#define ISP_PLATFORM_VERSION_MINOR 99 #include @@ -90,8 +90,8 @@ struct isposinfo { #define XS_NULL(xs) xs == NULL || xs->sc_link == NULL #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_LUN(xs) ((int) (xs)->sc_link->lun) +#define XS_TGT(xs) ((int) (xs)->sc_link->target) #define XS_RESID(xs) (xs)->resid #define XS_XFRLEN(xs) (xs)->datalen #define XS_CDBLEN(xs) (xs)->cmdlen @@ -267,6 +267,5 @@ static __inline const char *isp2100_pdb_statename(int pdb_state) #define ISP_NO_FASTPOST_SCSI 1 #define ISP_NO_FASTPOST_FC 1 -#define ISP_DISABLE_1080_SUPPORT 1 #endif /* _ISP_FREEBSD_H */ diff --git a/sys/dev/isp/isp_freebsd_cam.h b/sys/dev/isp/isp_freebsd_cam.h index 7a7665761ae..85b2ccfa9ea 100644 --- a/sys/dev/isp/isp_freebsd_cam.h +++ b/sys/dev/isp/isp_freebsd_cam.h @@ -1,5 +1,5 @@ -/* $Id: isp_freebsd_cam.h,v 1.14 1999/02/09 01:09:03 mjacob Exp $ */ -/* release_03_16_99 */ +/* $Id: isp_freebsd_cam.h,v 1.15 1999/03/17 05:04:39 mjacob Exp $ */ +/* release_03_25_99 */ /* * Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions (CAM version) *--------------------------------------- diff --git a/sys/dev/isp/ispreg.h b/sys/dev/isp/ispreg.h index 940aa50a136..4e5429cf586 100644 --- a/sys/dev/isp/ispreg.h +++ b/sys/dev/isp/ispreg.h @@ -1,14 +1,13 @@ -/* $Id: ispreg.h,v 1.6 1999/02/09 01:09:35 mjacob Exp $ */ -/* release_03_16_99 */ +/* $Id: ispreg.h,v 1.7 1999/03/17 05:04:39 mjacob Exp $ */ +/* release_03_25_99 */ /* * Machine Independent (well, as best as possible) register * definitions for Qlogic ISP SCSI adapters. * - *--------------------------------------- - * Copyright (c) 1997 by Matthew Jacob + * Copyright (c) 1997, 1998, 1999 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: @@ -159,7 +158,7 @@ #define BIU_PCI1080_CONF1_SXP 0x0100 /* SXP bank select */ #define BIU_PCI1080_CONF1_DMA 0x0300 /* DMA bank select */ - /* ISP2100 Bus Control/Status Register */ +/* ISP2100 Bus Control/Status Register */ #define BIU2100_ICSR_REGBSEL 0x30 /* RW: register bank select */ #define BIU2100_RISC_REGS (0 << 4) /* RISC Regs */ @@ -503,6 +502,18 @@ #define SXP_PINS_DIFF_TARGET 0x0002 /* Enable SXP target mode */ #define SXP_PINS_DIFF_INITIATOR 0x0001 /* Enable SXP initiator mode */ +/* 1080 only */ +#define SXP_PINS_LVD_MODE 0x1000 +#define SXP_PINS_HVD_MODE 0x0800 +#define SXP_PINS_SE_MODE 0x0400 + +/* The above have to be put together with the DIFFM pin to make sense */ +#define ISP1080_LVD_MODE (SXP_PINS_LVD_MODE) +#define ISP1080_HVD_MODE (SXP_PINS_HVD_MODE|SXP_PINS_DIFF_MODE) +#define ISP1080_SE_MODE (SXP_PINS_SE_MODE) +#define ISP1080_MODE_MASK \ + (SXP_PINS_LVD_MODE|SXP_PINS_HVD_MODE|SXP_PINS_SE_MODE|SXP_PINS_DIFF_MODE) + /* * RISC and Host Command and Control Block Register Offsets */ @@ -604,8 +615,8 @@ */ #define ISP_NVRAM_SIZE 128 - -#define ISPBSMX(c, byte, shift, mask) \ + +#define ISPBSMX(c, byte, shift, mask) \ (((c)[(byte)] >> (shift)) & (mask)) #define ISP_NVRAM_VERSION(c) (c)[4] @@ -677,7 +688,7 @@ #define ISP2100_NVRAM_RETRY_COUNT(c) (c)[16] #define ISP2100_NVRAM_RETRY_DELAY(c) (c)[17] -#define ISP2100_NVRAM_NODE_NAME(c) ( \ +#define ISP2100_NVRAM_NODE_NAME(c) (\ (((u_int64_t)(c)[18]) << 56) | \ (((u_int64_t)(c)[19]) << 48) | \ (((u_int64_t)(c)[20]) << 40) | \ @@ -696,7 +707,7 @@ #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) ( \ +#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) | \ diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index 139a0d72e8d..82a1641d677 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -1,5 +1,5 @@ -/* $Id: ispvar.h,v 1.10 1999/02/09 01:11:35 mjacob Exp $ */ -/* release_03_16_99 */ +/* $Id: ispvar.h,v 1.11 1999/03/17 05:04:39 mjacob Exp $ */ +/* release_03_25_99 */ /* * Soft Definitions for for Qlogic ISP SCSI adapters. * @@ -48,7 +48,7 @@ #endif #define ISP_CORE_VERSION_MAJOR 1 -#define ISP_CORE_VERSION_MINOR 6 +#define ISP_CORE_VERSION_MINOR 7 /* * Vector for bus specific code to provide specific services. @@ -106,6 +106,7 @@ typedef struct { isp_fifo_threshold : 3, isp_ultramode : 1, isp_diffmode : 1, + isp_lvdmode : 1, isp_fast_mttr : 1, isp_initiator_id : 4, isp_async_data_setup : 4; @@ -122,11 +123,13 @@ typedef struct { dev_announced : 1, dev_update : 1, dev_refresh : 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 */ + exc_throttle : 8, + cur_offset : 4, + sync_offset : 4; + u_int8_t cur_period; /* current sync period */ + u_int8_t sync_period; /* goal sync period */ + u_int16_t dev_flags; /* goal device flags */ + u_int16_t cur_dflags; /* current device flags */ } isp_devparam[MAX_TARGETS]; } sdparam; /* scsi device parameters */ @@ -147,6 +150,8 @@ typedef struct { #define DPARM_SAFE_DFLT (DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING)) +/* technically, not really correct, as they need to be rated based upon clock */ +#define ISP_40M_SYNCPARMS 0x080a #define ISP_20M_SYNCPARMS 0x080c #define ISP_10M_SYNCPARMS 0x0c19 #define ISP_08M_SYNCPARMS 0x0c25 @@ -246,7 +251,7 @@ struct ispsoftc { u_int : 8, isp_confopts : 8, - : 1, + isp_port : 1, /* for dual ported impls */ isp_used : 1, isp_dblev : 3, isp_gotdparms : 1, @@ -351,12 +356,14 @@ struct ispsoftc { #define ISP_HA_SCSI_1040 0x4 #define ISP_HA_SCSI_1040A 0x5 #define ISP_HA_SCSI_1040B 0x6 -#define ISP_HA_SCSI_1080 0xe +#define ISP_HA_SCSI_1080 0xd +#define ISP_HA_SCSI_12X0 0xe #define ISP_HA_FC 0xf0 #define ISP_HA_FC_2100 0x10 #define IS_SCSI(isp) (isp->isp_type & ISP_HA_SCSI) #define IS_1080(isp) (isp->isp_type == ISP_HA_SCSI_1080) +#define IS_12X0(isp) (isp->isp_type == ISP_HA_SCSI_12X0) #define IS_FC(isp) (isp->isp_type & ISP_HA_FC) /*