summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authorse <se@FreeBSD.org>1995-06-28 16:40:58 +0000
committerse <se@FreeBSD.org>1995-06-28 16:40:58 +0000
commitbe356b2ee66f4e894fcf0de23097e0ea031b8e35 (patch)
tree96d2e6bb14ff89b3387fdf2906e213e266441a34 /sys/pci
parentc772748789ba5f00d2de397c569a8dc6f1887a7d (diff)
downloadFreeBSD-src-be356b2ee66f4e894fcf0de23097e0ea031b8e35.zip
FreeBSD-src-be356b2ee66f4e894fcf0de23097e0ea031b8e35.tar.gz
Changes to support some CDROM drives and the Quantum Grand-Prix
series of hard disk drives, which don't accept any SCSI message within an REQUEST SENSE command (i.e. even not an IDENTIFY to set the LUN). This patch obviates the need for QUIRK_NOMSG and thus all of the device_tab[] entries in the NCR driver.
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/ncr.c111
1 files changed, 69 insertions, 42 deletions
diff --git a/sys/pci/ncr.c b/sys/pci/ncr.c
index 74fb3c5..6d5b43e 100644
--- a/sys/pci/ncr.c
+++ b/sys/pci/ncr.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: ncr.c,v 1.36 1995/03/31 00:05:08 se Exp $
+** $Id: ncr.c,v 1.37 1995/05/30 08:13:07 rgrimes Exp $
**
** Device driver for the NCR 53C810 PCI-SCSI-Controller.
**
@@ -356,6 +356,8 @@ extern PRINT_ADDR();
#define QUIRK_AUTOSAVE (0x01)
#define QUIRK_NOMSG (0x02)
+#define QUIRK_NOSYNC (0x10)
+#define QUIRK_NOWIDE16 (0x20)
#define QUIRK_UPDATE (0x80)
/*==========================================================
@@ -878,13 +880,13 @@ struct ccb {
u_long tlimit;
/*
- ** All ccbs of one hostadapter are linked.
+ ** All ccbs of one hostadapter are chained.
*/
ccb_p link_ccb;
/*
- ** All ccbs of one target/lun are linked.
+ ** All ccbs of one target/lun are chained.
*/
ccb_p next_ccb;
@@ -1041,8 +1043,8 @@ struct ncb {
** because they're written with a
** COPY script command.
*/
- u_char msgout[8];
- u_char msgin [8];
+ u_char msgout[8];
+ u_char msgin [8];
u_long lastmsg;
/*
@@ -1124,7 +1126,7 @@ struct script {
ncrcmd cleanup [ 12];
ncrcmd cleanup0 [ 11];
ncrcmd signal [ 10];
- ncrcmd save_dp [ 5];
+ ncrcmd save_dp [ 5];
ncrcmd restore_dp [ 5];
ncrcmd disconnect [ 12];
ncrcmd disconnect0 [ 5];
@@ -1134,7 +1136,11 @@ struct script {
ncrcmd msg_out_abort [ 10];
ncrcmd getcc [ 4];
ncrcmd getcc1 [ 5];
+#ifdef NCR_GETCC_WITHMSG
ncrcmd getcc2 [ 33];
+#else
+ ncrcmd getcc2 [ 14];
+#endif
ncrcmd getcc3 [ 10];
ncrcmd badgetcc [ 6];
ncrcmd reselect [ 12];
@@ -1216,7 +1222,7 @@ static void ncr_attach (pcici_t tag, int unit);
static char ident[] =
- "\n$Id: ncr.c,v 1.36 1995/03/31 00:05:08 se Exp $\n";
+ "\n$Id: ncr.c,v 1.37 1995/05/30 08:13:07 rgrimes Exp $\n";
u_long ncr_version = NCR_VERSION
+ (u_long) sizeof (struct ncb)
@@ -2489,6 +2495,7 @@ static struct script script0 = {
SCR_COPY (4),
PADDR (startpos),
RADDR (scratcha),
+#ifdef NCR_GETCC_WITHMSG
/*
** If QUIRK_NOMSG is set, select without ATN.
** and don't send a message.
@@ -2529,6 +2536,7 @@ static struct script script0 = {
SCR_JUMP,
PADDR (prepare2),
+#endif
}/*-------------------------< GETCC3 >----------------------*/,{
/*
** Try to connect to the target.
@@ -3070,7 +3078,7 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np)
void ncr_min_phys (struct buf *bp)
{
- if (bp->b_bcount > MAX_SIZE) bp->b_bcount = MAX_SIZE;
+ if ((unsigned long)bp->b_bcount > MAX_SIZE) bp->b_bcount = MAX_SIZE;
}
/*----------------------------------------------------------
@@ -3594,7 +3602,11 @@ static INT32 ncr_start (struct scsi_xfer * xp)
*/
if (!tp->period) {
- if (tp->inqdata[7] & INQ7_SYNC) {
+ if (SCSI_NCR_MAX_SYNC
+#if defined (CDROM_ASYNC) || defined (GENERIC)
+ && ((tp->inqdata[0] & 0x1f) != 5)
+#endif
+ && (tp->inqdata[7] & INQ7_SYNC)) {
nego = NS_SYNC;
} else {
tp->period =0xffff;
@@ -3641,7 +3653,7 @@ static INT32 ncr_start (struct scsi_xfer * xp)
};
} else {
cp->tag=0;
-#if 1
+#if 0
/*
** @GENSCSI@ Bug in "/sys/scsi/cd.c"
**
@@ -3785,7 +3797,7 @@ static INT32 ncr_start (struct scsi_xfer * xp)
/*----------------------------------------------------
**
- ** fill ccb
+ ** fill in ccb
**
**----------------------------------------------------
**
@@ -3826,6 +3838,7 @@ static INT32 ncr_start (struct scsi_xfer * xp)
** patch requested size into sense command
*/
cp->sensecmd[0] = 0x03;
+ cp->sensecmd[1] = xp->sc_link->lun << 5;
cp->sensecmd[4] = sizeof(struct scsi_sense_data);
if (xp->req_sense_length)
cp->sensecmd[4] = xp->req_sense_length;
@@ -3849,7 +3862,7 @@ static INT32 ncr_start (struct scsi_xfer * xp)
/*----------------------------------------------------
**
- ** Critical region: starting this job.
+ ** Critical region: start this job.
**
**----------------------------------------------------
*/
@@ -3860,10 +3873,10 @@ static INT32 ncr_start (struct scsi_xfer * xp)
cp->jump_ccb.l_cmd = (SCR_JUMP ^ IFFALSE (DATA (cp->tag)));
cp->tlimit = time.tv_sec + xp->timeout / 1000 + 2;
- cp->magic = CCB_MAGIC;
+ cp->magic = CCB_MAGIC;
/*
- ** insert into startqueue.
+ ** insert into start queue.
*/
ptr = np->squeueput + 1;
@@ -3879,7 +3892,7 @@ static INT32 ncr_start (struct scsi_xfer * xp)
(vtophys(&np->script->tryloop))));
/*
- ** Script processor may be waiting for reconnect.
+ ** Script processor may be waiting for reselect.
** Wake it up.
*/
OUTB (nc_istat, SIGP);
@@ -3995,10 +4008,10 @@ void ncr_complete (ncb_p np, ccb_p cp)
printf ("CCB=%x STAT=%x/%x\n", (unsigned)cp & 0xfff,
cp->host_status,cp->scsi_status);
- xp = cp->xfer;
+ xp = cp->xfer;
cp->xfer = NULL;
tp = &np->target[xp->sc_link->target];
- lp = tp->lp[xp->sc_link->lun];
+ lp = tp->lp[xp->sc_link->lun];
/*
** Check for parity errors.
@@ -5159,7 +5172,7 @@ void ncr_int_sto (ncb_p np)
scratcha = INL (nc_scratcha);
diff = scratcha - vtophys(&np->script->tryloop);
- assert ((diff <= MAX_START * 20) && !(diff % 20));
+/* assert ((diff <= MAX_START * 20) && !(diff % 20));*/
if ((diff <= MAX_START * 20) && !(diff % 20)) {
np->script->startpos[0] = scratcha;
@@ -5225,21 +5238,27 @@ static void ncr_int_ma (ncb_p np)
OUTB (nc_stest3, TE|CSF); /* clear scsi fifo */
/*
- ** verify cp
+ ** locate matching cp
*/
dsa = INL (nc_dsa);
cp = &np->ccb;
while (cp && (vtophys(&cp->phys) != dsa))
cp = cp->link_ccb;
- assert (cp == np->header.cp);
- assert (cp);
- if (!cp)
- return;
+ if (!cp) {
+ printf ("%s: SCSI phase error fixup: CCB already dequeued (0x%08x)\n",
+ ncr_name (np), np->header.cp);
+ return;
+ }
+ if (cp != np->header.cp) {
+ printf ("%s: SCSI phase error fixup: CCB address mismatch (0x%08x != 0x%08x)\n",
+ ncr_name (np), cp, np->header.cp);
+ return;
+ }
/*
** find the interrupted script command,
- ** and the address at where to continue.
+ ** and the address at which to continue.
*/
if (dsp == vtophys (&cp->patch[2])) {
@@ -5476,11 +5495,11 @@ void ncr_int_sir (ncb_p np)
** Was Sie schon immer ueber transfermode negotiation wissen wollten ...
**
** We try to negotiate sync and wide transfer only after
-** a successfull inquire command. We look to byte 7 of the
+** a successfull inquire command. We look at byte 7 of the
** inquire data to determine the capabilities if the target.
**
** When we try to negotiate, we append the negotiation message
-** to the identify and (maybe) simpletag message.
+** to the identify and (maybe) simple tag message.
** The host status field is set to HS_NEGOTIATE to mark this
** situation.
**
@@ -5494,20 +5513,20 @@ void ncr_int_sir (ncb_p np)
** for validity, and set the values.
**
** If we receive a Reject message immediately, we assume the
-** negotiation has failed, and set to the standard values.
+** negotiation has failed, and fall back to standard values.
**
** If we receive a negotiation message while not in HS_NEGOTIATE
** state, it's a target initiated negotiation. We prepare a
-** (hopefully) valid answer, set the values, and send this
-** answer back to the target.
+** (hopefully) valid answer, set our parameters, and send back
+** this answer to the target.
**
** If the target doesn't fetch the answer (no message out phase),
-** we assume the negotiation has failed, and set the values to
-** the default.
+** we assume the negotiation has failed, and fall back to default
+** settings.
**
-** When we set the values, we set in all ccbs belonging to this
-** target, in the controllers register, and in the "phys"
-** field of the controllers struct ncb.
+** When we set the values, we adjust them in all ccbs belonging
+** to this target, in the controller's register, and in the "phys"
+** field of the controller's struct ncb.
**
** Possible cases: hs sir msg_in value send goto
** We try try to negotiate:
@@ -5674,8 +5693,6 @@ void ncr_int_sir (ncb_p np)
np->msgout[3] = per;
np->msgout[4] = ofs;
- np->msgin [0] = M_NOOP;
-
cp->nego_status = NS_SYNC;
if (DEBUG_FLAGS & DEBUG_NEGO) {
@@ -5684,6 +5701,13 @@ void ncr_int_sir (ncb_p np)
(void) ncr_show_msg (np->msgin);
printf (".\n");
}
+
+ if (!ofs) {
+ OUTL (nc_dsp,vtophys (&np->script->msg_bad));
+ return;
+ }
+ np->msgin [0] = M_NOOP;
+
break;
case SIR_NEGO_WIDE:
@@ -6090,10 +6114,10 @@ static void ncr_alloc_ccb (ncb_p np, struct scsi_xfer * xp)
lp->jump_ccb.l_paddr = vtophys (&np->script->aborttag);
lp->actlink = 1;
+
/*
- ** Link into Lun-Chain
+ ** Chain into LUN list
*/
-
tp->jump_lcb.l_paddr = vtophys (&lp->jump_lcb);
tp->lp[lun] = lp;
@@ -6130,12 +6154,12 @@ static void ncr_alloc_ccb (ncb_p np, struct scsi_xfer * xp)
np->actccbs++;
/*
- ** Initialize it.
+ ** Initialize it
*/
bzero (cp, sizeof (*cp));
/*
- ** link in reselect chain.
+ ** Chain into reselect list
*/
cp->jump_ccb.l_cmd = SCR_JUMP;
cp->jump_ccb.l_paddr = lp->jump_ccb.l_paddr;
@@ -6144,13 +6168,13 @@ static void ncr_alloc_ccb (ncb_p np, struct scsi_xfer * xp)
cp->call_tmp.l_paddr = vtophys(&np->script->resel_tmp);
/*
- ** link in wakeup chain
+ ** Chain into wakeup list
*/
cp->link_ccb = np->ccb.link_ccb;
np->ccb.link_ccb = cp;
/*
- ** Link into CCB-Chain
+ ** Chain into CCB list
*/
cp->next_ccb = lp->next_ccb;
lp->next_ccb = cp;
@@ -6521,10 +6545,13 @@ struct table_entry {
static struct table_entry device_tab[] =
{
+#ifdef NCR_GETCC_WITHMSG
+ {"", "", "", QUIRK_NOMSG},
{"SONY", "SDT-5000", "3.17", QUIRK_NOMSG},
{"WangDAT", "Model 2600", "01.7", QUIRK_NOMSG},
{"WangDAT", "Model 3200", "02.2", QUIRK_NOMSG},
{"WangDAT", "Model 1300", "02.4", QUIRK_NOMSG},
+#endif
{"", "", "", 0} /* catch all: must be last entry. */
};
OpenPOWER on IntegriCloud