From ddc693c29945ee709b16b5344594eba790677c25 Mon Sep 17 00:00:00 2001 From: mjacob Date: Sat, 5 Apr 1997 02:53:22 +0000 Subject: [PATCH] A) Attempt to get clock rate from ISP chip prior to bashing it over the head in reset. If none there, try and get from the bus/platform specific code. If a nonzero value for either, set the clock rate. This is why the PCI card versions weren't working- they need to be set at 60MHZ, rather than the default 40MHZ (which worked fine for the internal ISP chips on the Alpha 8X00). B) If a isp_poll returns failure (command never completed) to the caller and no error is set in the xs struct, set XS_SELTIMEOUT. And then call... C) Added isp_lostcmd function to try and ask the ISP chip about it's current state as well as the state of commands for a particular target/lun. This is going along to try and figure out why the very first command to the ISP always seems to get swallowed up. --- sys/dev/ic/isp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c index 4965f7e52162..4a1a00a53de5 100644 --- a/sys/dev/ic/isp.c +++ b/sys/dev/ic/isp.c @@ -1,4 +1,4 @@ -/* $NetBSD: isp.c,v 1.3 1997/03/23 00:50:07 cgd Exp $ */ +/* $NetBSD: isp.c,v 1.4 1997/04/05 02:53:22 mjacob Exp $ */ /* * Machine Independent (well, as best as possible) @@ -86,6 +86,7 @@ static struct scsi_device isp_dev = { NULL, NULL, NULL, NULL }; static int isp_poll __P((struct ispsoftc *, struct scsi_xfer *, int)); static int isp_parse_status __P((struct ispsoftc *, ispstatusreq_t *)); +static void isp_lostcmd __P((struct ispsoftc *, struct scsi_xfer *)); /* * Reset Hardware. @@ -98,13 +99,26 @@ isp_reset(isp) { mbreg_t mbs; int loops, i; + u_int8_t oldclock; isp->isp_state = ISP_NILSTATE; /* * Do MD specific pre initialization */ ISP_RESET0(isp); - + + /* + * Try and get old clock rate out before we hit the + * chip over the head. + */ + mbs.param[0] = MBOX_GET_CLOCK_RATE; + (void) isp_mboxcmd(isp, &mbs); + if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { + oldclock = mbs.param[1]; + } else { + oldclock = 0; + } + /* * Hit the chip over the head with hammer. */ @@ -252,6 +266,21 @@ isp_reset(isp) mbs.param[0] = MBOX_EXEC_FIRMWARE; mbs.param[1] = isp->isp_mdvec->dv_codeorg; (void) isp_mboxcmd(isp, &mbs); + + /* + * Set CLOCK RATE + */ + if (isp->isp_mdvec->dv_clock || oldclock) { + u_int8_t save; + mbs.param[0] = MBOX_SET_CLOCK_RATE; + save = mbs.param[1] = + (oldclock)? oldclock : isp->isp_mdvec->dv_clock; + (void) isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + printf("%s: failed to set CLOCKRATE\n", isp->isp_name); + return; + } + } mbs.param[0] = MBOX_ABOUT_FIRMWARE; (void) isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { @@ -474,7 +503,7 @@ isp_attach(isp) isp->isp_link.adapter_target = isp->isp_initiator_id; isp->isp_link.adapter = &isp_switch; isp->isp_link.device = &isp_dev; - isp->isp_link.openings = RESULT_QUEUE_LEN / (MAX_TARGETS - 1); + isp->isp_link.openings = RQUEST_QUEUE_LEN / (MAX_TARGETS - 1); isp->isp_link.max_target = MAX_TARGETS-1; config_found((void *)isp, &isp->isp_link, scsiprint); } @@ -610,6 +639,14 @@ ispscsicmd(xs) /* XXX really nuke it */ } #endif + /* + * If no other error occurred but we didn't finish, + * assume a *selection* timeout. + */ + if ((xs->flags & ITSDONE) == 0 && xs->error == XS_NOERROR) { + isp_lostcmd(isp, xs); + xs->error = XS_SELTIMEOUT; + } } return (COMPLETE); } @@ -1006,3 +1043,31 @@ isp_mboxcmd(isp, mbp) ISP_WRITE(isp, BIU_SEMA, 0); return (0); } + +static void +isp_lostcmd(struct ispsoftc *isp, struct scsi_xfer *xs) +{ + mbreg_t mbs; + mbs.param[0] = MBOX_GET_FIRMWARE_STATUS; + (void) isp_mboxcmd(isp, &mbs); + + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + printf("%s: couldn't GET FIRMWARE STATUS\n", isp->isp_name); + return; + } + printf("%s: lost command, %d commands active of total %d\n", + isp->isp_name, mbs.param[1], mbs.param[2]); + if (xs == NULL || xs->sc_link == NULL) + return; + + mbs.param[0] = MBOX_GET_DEV_QUEUE_STATUS; + mbs.param[1] = xs->sc_link->target << 8 | xs->sc_link->lun; + (void) isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + printf("%s: couldn't GET DEVICE STATUS\n", isp->isp_name); + return; + } + printf("%s: lost command, target %d lun %d, State: %x\n", + isp->isp_name, mbs.param[1] >> 8, mbs.param[1] & 0x7, + mbs.param[2] & 0xff); +}