* of PCI-SCSI IO processors.
*
* Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr>
- * Copyright (c) 2003-2004 Matthew Wilcox <matthew@wil.cx>
*
* This driver is derived from the Linux sym53c8xx driver.
* Copyright (C) 1998-2000 Gerard Roudier
*
*-----------------------------------------------------------------------------
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Where this Software is combined with software released under the terms of
+ * the GNU Public License ("GPL") and the terms of the GPL would require the
+ * combined work to also be released under the terms of the GPL, the terms
+ * and conditions of this License will apply in addition to those of the
+ * GPL with the exception of any terms or conditions of this License that
+ * conflict with, or are expressly prohibited by, the GPL.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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.
*/
#include "sym_glue.h"
#include "sym_nvram.h"
}
out:
OUTB (nc_scntl1, 0);
+ /* MDELAY(100); */
return retv;
}
if (st->period > np->maxsync_dt)
st->period = np->maxsync_dt;
} else {
- st->options &= ~PPR_OPT_MASK;
if (st->offset > np->maxoffs)
st->offset = np->maxoffs;
if (st->period < np->minsync)
if (st->period > np->maxsync)
st->period = np->maxsync;
}
-}
+}
/*
* Prepare the next negotiation message if needed.
msgptr[msglen++] = 0;
msgptr[msglen++] = tp->tinfo.goal.offset;
msgptr[msglen++] = tp->tinfo.goal.width;
- msgptr[msglen++] = tp->tinfo.goal.options & PPR_OPT_MASK;
+ msgptr[msglen++] = tp->tinfo.goal.options & PPR_OPT_DT;
break;
};
if (np->features & (FE_ULTRA2|FE_ULTRA3)) {
OUTONW (nc_sien, SBMC);
if (reason == 0) {
- mdelay(100);
+ MDELAY(100);
INW (nc_sist);
}
np->scsi_mode = INB (nc_stest4) & SMODE;
/*
* Switch trans mode for current job and it's target.
*/
-static void sym_settrans(hcb_p np, int target, u_char opts, u_char ofs,
+static void sym_settrans(hcb_p np, int target, u_char dt, u_char ofs,
u_char per, u_char wide, u_char div, u_char fak)
{
SYM_QUEHEAD *qp;
*/
if (np->features & FE_C10) {
uval = uval & ~(U3EN|AIPCKEN);
- if (opts) {
+ if (dt) {
assert(np->features & FE_U3EN);
uval |= U3EN;
}
* Let everything be aware of the changes.
*/
static void
-sym_setpprot(hcb_p np, int target, u_char opts, u_char ofs,
+sym_setpprot(hcb_p np, int target, u_char dt, u_char ofs,
u_char per, u_char wide, u_char div, u_char fak)
{
tcb_p tp = &np->target[target];
- sym_settrans(np, target, opts, ofs, per, wide, div, fak);
+ sym_settrans(np, target, dt, ofs, per, wide, div, fak);
tp->tinfo.goal.width = tp->tinfo.curr.width = wide;
tp->tinfo.goal.period = tp->tinfo.curr.period = per;
tp->tinfo.goal.offset = tp->tinfo.curr.offset = ofs;
- tp->tinfo.goal.options = tp->tinfo.curr.options = opts;
+ tp->tinfo.goal.options = tp->tinfo.curr.options = dt;
sym_xpt_async_nego_ppr(np, target);
}
if (dsp == SCRIPTA_BA (np, send_ident)) {
if (cp->tag != NO_TAG && olen - rest <= 3) {
cp->host_status = HS_BUSY;
- np->msgout[0] = IDENTIFY(0, cp->lun);
+ np->msgout[0] = M_IDENTIFY | cp->lun;
nxtdsp = SCRIPTB_BA (np, ident_break_atn);
}
else
* requesting sense data.
*/
- cp->scsi_smsg2[0] = IDENTIFY(0, cp->lun);
+ /*
+ * identify message
+ */
+ cp->scsi_smsg2[0] = M_IDENTIFY | cp->lun;
msglen = 1;
/*
*/
if (lun != -1) {
lcb_p lp = sym_lp(np, tp, lun);
- lp->to_clear = 0; /* We don't expect to fail here */
- np->abrt_msg[0] = IDENTIFY(0, lun);
+ lp->to_clear = 0; /* We donnot expect to fail here */
+ np->abrt_msg[0] = M_IDENTIFY | lun;
np->abrt_msg[1] = M_ABORT;
np->abrt_tbl.size = 2;
break;
* We have some task to abort.
* Set the IDENTIFY(lun)
*/
- np->abrt_msg[0] = IDENTIFY(0, cp->lun);
+ np->abrt_msg[0] = M_IDENTIFY | cp->lun;
/*
* If we want to abort an untagged command, we
if (cp->tag == NO_TAG) {
np->abrt_msg[1] = M_ABORT;
np->abrt_tbl.size = 2;
- } else {
+ }
+ else {
np->abrt_msg[1] = cp->scsi_smsg[1];
np->abrt_msg[2] = cp->scsi_smsg[2];
np->abrt_msg[3] = M_ABORT_TAG;
sym_ppr_nego_check(hcb_p np, int req, int target)
{
tcb_p tp = &np->target[target];
- unsigned char fak, div;
- int dt, chg = 0;
-
- unsigned char per = np->msgin[3];
- unsigned char ofs = np->msgin[5];
- unsigned char wide = np->msgin[6];
- unsigned char opts = np->msgin[7] & PPR_OPT_MASK;
+ u_char chg, ofs, per, fak, dt, div, wide;
if (DEBUG_FLAGS & DEBUG_NEGO) {
sym_print_nego_msg(np, target, "ppr msgin", np->msgin);
- }
+ };
+
+ /*
+ * Get requested values.
+ */
+ chg = 0;
+ per = np->msgin[3];
+ ofs = np->msgin[5];
+ wide = np->msgin[6];
+ dt = np->msgin[7] & PPR_OPT_DT;
/*
* Check values against our limits.
wide = np->maxwide;
}
if (!wide || !(np->features & FE_ULTRA3))
- opts = 0;
+ dt &= ~PPR_OPT_DT;
if (!(np->features & FE_U3EN)) /* Broken U3EN bit not supported */
- opts = 0;
+ dt &= ~PPR_OPT_DT;
- if (opts != (np->msgin[7] & PPR_OPT_MASK))
- chg = 1;
-
- dt = opts & PPR_OPT_DT;
+ if (dt != (np->msgin[7] & PPR_OPT_MASK)) chg = 1;
if (ofs) {
- unsigned char maxoffs = dt ? np->maxoffs_dt : np->maxoffs;
- if (ofs > maxoffs) {
- chg = 1;
- ofs = maxoffs;
+ if (dt) {
+ if (ofs > np->maxoffs_dt)
+ {chg = 1; ofs = np->maxoffs_dt;}
}
+ else if (ofs > np->maxoffs)
+ {chg = 1; ofs = np->maxoffs;}
}
if (ofs) {
- unsigned char minsync = dt ? np->minsync_dt : np->minsync;
- if (per < np->minsync_dt) {
- chg = 1;
- per = minsync;
+ if (dt) {
+ if (per < np->minsync_dt)
+ {chg = 1; per = np->minsync_dt;}
}
+ else if (per < np->minsync)
+ {chg = 1; per = np->minsync;}
}
/*
/*
* Apply new values.
*/
- sym_setpprot(np, target, opts, ofs, per, wide, div, fak);
+ sym_setpprot (np, target, dt, ofs, per, wide, div, fak);
/*
* It was an answer. We are done.
np->msgout[4] = 0;
np->msgout[5] = ofs;
np->msgout[6] = wide;
- np->msgout[7] = opts;
+ np->msgout[7] = dt;
if (DEBUG_FLAGS & DEBUG_NEGO) {
sym_print_nego_msg(np, target, "ppr msgout", np->msgout);
* If it is a device response that should result in
* ST, we may want to try a legacy negotiation later.
*/
- if (!req && !opts) {
+ if (!req && !dt) {
tp->tinfo.goal.options = 0;
tp->tinfo.goal.width = wide;
tp->tinfo.goal.period = per;
{
tcb_p tp;
lcb_p lp;
- u_char *msgptr;
+ u_char idmsg, *msgptr;
u_int msglen;
- int can_disconnect;
/*
* Keep track of the IO in our CCB.
cp->cam_ccb = (cam_ccb_p) csio;
/*
- * Retrieve the target descriptor.
+ * Retreive the target descriptor.
*/
tp = &np->target[cp->target];
/*
- * Retrieve the lun descriptor.
+ * Retreive the lun descriptor.
*/
lp = sym_lp(np, tp, cp->lun);
- can_disconnect = (cp->tag != NO_TAG) ||
- (lp && (lp->curr_flags & SYM_DISC_ENABLED));
+ /*
+ * Build the IDENTIFY message.
+ */
+ idmsg = M_IDENTIFY | cp->lun;
+ if (cp->tag != NO_TAG || (lp && (lp->curr_flags & SYM_DISC_ENABLED)))
+ idmsg |= 0x40;
msgptr = cp->scsi_smsg;
msglen = 0;
- msgptr[msglen++] = IDENTIFY(can_disconnect, cp->lun);
+ msgptr[msglen++] = idmsg;
/*
* Build the tag message if present.
printf ("CCB=%lx STAT=%x/%x/%x DEV=%d/%d\n", (unsigned long)cp,
cp->host_status, cp->ssss_status, cp->host_flags,
cp->target, cp->lun);
+ MDELAY(100);
}
/*
/*
* Soft-attach the controller.
*/
+#ifdef SYM_OPT_NVRAM_PRE_READ
int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram)
+#else
+int sym_hcb_attach(hcb_p np, struct sym_fw *fw)
+#endif
{
+#ifndef SYM_OPT_NVRAM_PRE_READ
+ struct sym_nvram nvram_buf, *nvram = &nvram_buf;
+#endif
int i;
/*
*/
sym_chip_reset (np);
+ /*
+ * Try to read the user set-up.
+ */
+#ifndef SYM_OPT_NVRAM_PRE_READ
+ (void) sym_read_nvram(np, nvram);
+#endif
+
/*
* Prepare controller and devices settings, according
* to chip features, user set-up and driver set-up.