patch-2.1.127 linux/drivers/scsi/ncr53c8xx.c
Next file: linux/drivers/scsi/ncr53c8xx.h
Previous file: linux/drivers/scsi/dc390.h
Back to the patch index
Back to the overall index
- Lines: 433
- Date:
Sun Oct 25 14:46:44 1998
- Orig file:
v2.1.126/linux/drivers/scsi/ncr53c8xx.c
- Orig date:
Fri Oct 9 13:27:11 1998
diff -u --recursive --new-file v2.1.126/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
@@ -73,7 +73,7 @@
*/
/*
-** October 4 1998, version 3.0i
+** October 21 1998, version 3.1a
**
** Supported SCSI-II features:
** Synchronous negotiation
@@ -169,9 +169,11 @@
#endif
/*
-** Define the BSD style u_int32 type
+** Define the BSD style u_int32 and u_int64 type.
+** Are in fact u_int32_t and u_int64_t :-)
*/
typedef u32 u_int32;
+typedef u64 u_int64;
#include "ncr53c8xx.h"
@@ -366,25 +368,14 @@
#define NO_TAG (255)
/*
-** For more than 32 TAGS support, we do some address calculation
-** from the SCRIPTS using 2 additionnal SCR_COPY's and a fiew
-** bit handling on 64 bit integers. For these reasons, support for
-** 32 up to 64 TAGS is compiled conditionnaly.
+** Choose appropriate type for tag bitmap.
*/
-
-#if SCSI_NCR_MAX_TAGS <= 32
-struct nlink {
- ncrcmd l_cmd;
- ncrcmd l_paddr;
-};
+#if SCSI_NCR_MAX_TAGS > 32
+typedef u_int64 tagmap_t;
#else
-struct nlink {
- ncrcmd l_paddr;
-};
-typedef u64 u_int64;
+typedef u_int32 tagmap_t;
#endif
-
/*
** Number of targets supported by the driver.
** n permits target numbers 0..n-1.
@@ -583,16 +574,12 @@
#define iounmap vfree
#endif
-#ifdef __sparc__
+#if defined (__sparc__)
#include <asm/irq.h>
-#define remap_pci_mem(base, size) ((vm_offset_t) __va(base))
-#define unmap_pci_mem(vaddr, size)
-#define pcivtophys(p) ((p) & pci_dvma_mask)
-#else
-#if defined(__alpha__)
-#define pcivtophys(p) ((p) & 0xfffffffful)
+#elif defined (__alpha__)
+#define bus_dvma_to_mem(p) ((p) & 0xfffffffful)
#else
-#define pcivtophys(p) (p)
+#define bus_dvma_to_mem(p) (p)
#endif
#ifndef NCR_IOMAPPED
@@ -615,7 +602,6 @@
iounmap((void *) (vaddr & PAGE_MASK));
}
#endif /* !NCR_IOMAPPED */
-#endif /* __sparc__ */
/*
** Insert a delay in micro-seconds and milli-seconds.
@@ -1488,8 +1474,8 @@
** 64 possible tags.
**----------------------------------------------------------------
*/
- struct nlink jump_ccb_0; /* Default table if no tags */
- struct nlink *jump_ccb; /* Virtual address */
+ u_int32 jump_ccb_0; /* Default table if no tags */
+ u_int32 *jump_ccb; /* Virtual address */
/*----------------------------------------------------------------
** CCB queue management.
@@ -1514,11 +1500,7 @@
*/
u_char ia_tag; /* Allocation index */
u_char if_tag; /* Freeing index */
-#if SCSI_NCR_MAX_TAGS <= 32
- u_char cb_tags[32]; /* Circular tags buffer */
-#else
- u_char cb_tags[64]; /* Circular tags buffer */
-#endif
+ u_char cb_tags[SCSI_NCR_MAX_TAGS]; /* Circular tags buffer */
u_char usetags; /* Command queuing is active */
u_char maxtags; /* Max nr of tags asked by user */
u_char numtags; /* Current number of tags */
@@ -1528,14 +1510,13 @@
** QUEUE FULL control and ORDERED tag control.
**----------------------------------------------------------------
*/
+ /*----------------------------------------------------------------
+ ** QUEUE FULL and ORDERED tag control.
+ **----------------------------------------------------------------
+ */
u_short num_good; /* Nr of GOOD since QUEUE FULL */
-#if SCSI_NCR_MAX_TAGS <= 32
- u_int tags_umap; /* Used tags bitmap */
- u_int tags_smap; /* Tags in use at 'tag_stime' */
-#else
- u_int64 tags_umap; /* Used tags bitmap */
- u_int64 tags_smap; /* Tags in use at 'tag_stime' */
-#endif
+ tagmap_t tags_umap; /* Used tags bitmap */
+ tagmap_t tags_smap; /* Tags in use at 'tag_stime' */
u_long tags_stime; /* Last time we set smap=umap */
ccb_p held_ccb; /* CCB held for QUEUE FULL */
};
@@ -2065,18 +2046,10 @@
ncrcmd loadpos1 [ 4];
#endif
ncrcmd resel_lun [ 6];
-#if SCSI_NCR_MAX_TAGS <= 32
- ncrcmd resel_tag [ 8];
-#else
ncrcmd resel_tag [ 6];
ncrcmd jump_to_nexus [ 4];
ncrcmd nexus_indirect [ 4];
-#endif
-#if SCSI_NCR_MAX_TAGS <= 32
- ncrcmd resel_notag [ 4];
-#else
ncrcmd resel_notag [ 4];
-#endif
ncrcmd data_in [MAX_SCATTERL * 4];
ncrcmd data_in2 [ 4];
ncrcmd data_out [MAX_SCATTERL * 4];
@@ -2987,18 +2960,12 @@
/*
** Read the TAG from the SIDL.
** Still an aggressive optimization. ;-)
+ ** Compute the CCB indirect jump address which
+ ** is (#TAG*2 & 0xfc) due to tag numbering using
+ ** 1,3,5..MAXTAGS*2+1 actual values.
*/
- SCR_FROM_REG (sidl),
- 0,
- /*
- ** JUMP indirectly to the restart point of the CCB.
- */
-#if SCSI_NCR_MAX_TAGS <= 32
- SCR_SFBR_REG (temp, SCR_AND, 0xf8),
+ SCR_REG_SFBR (sidl, SCR_SHL, 0),
0,
- SCR_RETURN,
- 0,
-#else
SCR_SFBR_REG (temp, SCR_AND, 0xfc),
0,
}/*-------------------------< JUMP_TO_NEXUS >-------------------*/,{
@@ -3011,7 +2978,6 @@
RADDR (temp),
SCR_RETURN,
0,
-#endif
}/*-------------------------< RESEL_NOTAG >-------------------*/,{
/*
** No tag expected.
@@ -3019,13 +2985,8 @@
*/
SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
NADDR (msgin),
-#if SCSI_NCR_MAX_TAGS <= 32
- SCR_RETURN,
- 0,
-#else
SCR_JUMP,
PADDR (jump_to_nexus),
-#endif
}/*-------------------------< DATA_IN >--------------------*/,{
/*
** Because the size depends on the
@@ -3907,7 +3868,7 @@
switch (old & RELOC_MASK) {
case RELOC_REGISTER:
new = (old & ~RELOC_MASK)
- + pcivtophys(np->paddr);
+ + bus_dvma_to_mem(np->paddr);
break;
case RELOC_LABEL:
new = (old & ~RELOC_MASK) + np->p_script;
@@ -4654,7 +4615,7 @@
np->scripth = np->scripth0;
np->p_scripth = vtophys(np->scripth);
- np->p_script = (np->paddr2) ? pcivtophys(np->paddr2) : vtophys(np->script0);
+ np->p_script = (np->paddr2) ? bus_dvma_to_mem(np->paddr2) : vtophys(np->script0);
ncr_script_copy_and_bind (np, (ncrcmd *) &script0, (ncrcmd *) np->script0, sizeof(struct script));
ncr_script_copy_and_bind (np, (ncrcmd *) &scripth0, (ncrcmd *) np->scripth0, sizeof(struct scripth));
@@ -5063,12 +5024,12 @@
}
}
msgptr[msglen++] = order;
-#if SCSI_NCR_MAX_TAGS <= 32
- msgptr[msglen++] = (cp->tag << 3) + 1;
-#else
- msgptr[msglen++] = (cp->tag << 2) + 1;
-#endif
-
+ /*
+ ** Actual tags are numbered 1,3,5,..2*MAXTAGS+1,
+ ** since we may have to deal with devices that have
+ ** problems with #TAG 0 or too great #TAG numbers.
+ */
+ msgptr[msglen++] = (cp->tag << 1) + 1;
}
switch (nego) {
@@ -5316,7 +5277,7 @@
++lp->queuedccbs;
cp = xpt_que_entry(qp, struct ccb, link_ccbq);
xpt_insque_tail(qp, &lp->busy_ccbq);
- lp->jump_ccb[cp->tag == NO_TAG ? 0 : cp->tag].l_paddr =
+ lp->jump_ccb[cp->tag == NO_TAG ? 0 : cp->tag] =
cpu_to_scr(CCB_PHYS (cp, restart));
ncr_put_start_queue(np, cp);
}
@@ -5705,7 +5666,7 @@
#ifdef DEBUG_NCR53C8XX
printk("%s: freeing lp (%lx)\n", ncr_name(np), (u_long) lp);
#endif
- if (lp->maxnxs > 1)
+ if (lp->jump_ccb != &lp->jump_ccb_0)
m_free(lp->jump_ccb, 256);
m_free(lp, sizeof(*lp));
}
@@ -5861,9 +5822,10 @@
/*
** On standard INQUIRY response (EVPD and CmDt
** not set), setup logical unit according to
- ** announced capabilities.
+ ** announced capabilities (we need the 1rst 7 bytes).
*/
- if (cmd->cmnd[0] == 0x12 && !(cmd->cmnd[1] & 0x3)) {
+ if (cmd->cmnd[0] == 0x12 && !(cmd->cmnd[1] & 0x3) &&
+ cmd->cmnd[4] >= 7) {
ncr_setup_lcb (np, cmd->target, cmd->lun,
(char *) cmd->request_buffer);
}
@@ -6219,6 +6181,14 @@
}
/*
+ ** DEL 441 - 53C876 Rev 5 - Part Number 609-0392787/2788 - ITEM 2.
+ ** Disable overlapped arbitration.
+ */
+ if (np->device_id == PCI_DEVICE_ID_NCR_53C875 &&
+ np->revision_id >= 0x10 && np->revision_id <= 0x15)
+ OUTB (nc_ctest0, (1<<5));
+
+ /*
** Fill in target structure.
** Reinitialize usrsync.
** Reinitialize usrwide.
@@ -7778,7 +7748,7 @@
** We just assume lun=0, 1 CCB, no tag.
*/
if (tp->lp[0]) {
- OUTL (nc_dsp, scr_to_cpu(tp->lp[0]->jump_ccb[0].l_paddr));
+ OUTL (nc_dsp, scr_to_cpu(tp->lp[0]->jump_ccb[0]));
return;
}
case SIR_RESEL_BAD_TARGET: /* Will send a TARGET RESET message */
@@ -8307,17 +8277,9 @@
if (lp) {
if (tag != NO_TAG) {
++lp->ia_tag;
-#if SCSI_NCR_MAX_TAGS <= 32
- if (lp->ia_tag == 32)
-#else
- if (lp->ia_tag == 64)
-#endif
+ if (lp->ia_tag == SCSI_NCR_MAX_TAGS)
lp->ia_tag = 0;
-#if SCSI_NCR_MAX_TAGS <= 32
- lp->tags_umap |= (1u << tag);
-#else
- lp->tags_umap |= (((u_int64) 1) << tag);
-#endif
+ lp->tags_umap |= (((tagmap_t) 1) << tag);
}
}
@@ -8363,22 +8325,14 @@
if (lp) {
if (cp->tag != NO_TAG) {
lp->cb_tags[lp->if_tag++] = cp->tag;
-#if SCSI_NCR_MAX_TAGS <= 32
- if (lp->if_tag == 32)
-#else
- if (lp->if_tag == 64)
-#endif
+ if (lp->if_tag == SCSI_NCR_MAX_TAGS)
lp->if_tag = 0;
-#if SCSI_NCR_MAX_TAGS <= 32
- lp->tags_umap &= ~(1u << cp->tag);
-#else
- lp->tags_umap &= ~(((u_int64) 1) << cp->tag);
-#endif
+ lp->tags_umap &= ~(((tagmap_t) 1) << cp->tag);
lp->tags_smap &= lp->tags_umap;
- lp->jump_ccb[cp->tag].l_paddr =
+ lp->jump_ccb[cp->tag] =
cpu_to_scr(NCB_SCRIPTH_PHYS(np, bad_i_t_l_q));
} else {
- lp->jump_ccb[0].l_paddr =
+ lp->jump_ccb[0] =
cpu_to_scr(NCB_SCRIPTH_PHYS(np, bad_i_t_l));
}
}
@@ -8412,7 +8366,7 @@
#define ncr_reg_bus_addr(r) \
- (pcivtophys(np->paddr) + offsetof (struct ncr_reg, r))
+ (bus_dvma_to_mem(np->paddr) + offsetof (struct ncr_reg, r))
/*------------------------------------------------------------------------
** Initialize the fixed part of a CCB structure.
@@ -8579,28 +8533,6 @@
/*------------------------------------------------------------------------
-** Reselection JUMP table initialisation.
-**------------------------------------------------------------------------
-** The SCRIPTS processor jumps on reselection to the entry
-** corresponding to the CCB using the tag as offset.
-**------------------------------------------------------------------------
-*/
-static void ncr_setup_jump_ccb(ncb_p np, lcb_p lp)
-{
- int i;
-
- lp->p_jump_ccb = cpu_to_scr(vtophys(lp->jump_ccb));
- for (i = 0 ; i < lp->maxnxs ; i++) {
-#if SCSI_NCR_MAX_TAGS <= 32
- lp->jump_ccb[i].l_cmd = cpu_to_scr(SCR_JUMP);
-#endif
- lp->jump_ccb[i].l_paddr =
- cpu_to_scr(NCB_SCRIPTH_PHYS (np, bad_i_t_l_q));
- lp->cb_tags[i] = i;
- }
-}
-
-/*------------------------------------------------------------------------
** Lun control block allocation and initialization.
**------------------------------------------------------------------------
** This data structure is allocated and initialized after a SCSI
@@ -8649,12 +8581,12 @@
xpt_que_init(&lp->skip_ccbq);
/*
- ** Set max CCBs to 1 and use the default jump table
- ** by default.
+ ** Set max CCBs to 1 and use the default 1 entry
+ ** jump table by default.
*/
- lp->maxnxs = 1;
- lp->jump_ccb = &lp->jump_ccb_0;
- ncr_setup_jump_ccb(np, lp);
+ lp->maxnxs = 1;
+ lp->jump_ccb = &lp->jump_ccb_0;
+ lp->p_jump_ccb = cpu_to_scr(vtophys(lp->jump_ccb));
/*
** Initilialyze the reselect script:
@@ -8733,6 +8665,13 @@
inq_byte7 = inq_data[7];
/*
+ ** Throw away announced LUN capabilities if we are told
+ ** that there is no real device supported by the logical unit.
+ */
+ if ((inq_data[0] & 0xe0) > 0x20 || (inq_data[0] & 0x1f) == 0x1f)
+ inq_byte7 &= (INQ7_SYNC | INQ7_WIDE16);
+
+ /*
** If user is wanting SYNC, force this feature.
*/
if (driver_setup.force_sync_nego)
@@ -8751,19 +8690,21 @@
** If unit supports tagged commands, allocate the
** CCB JUMP table if not yet.
*/
- if ((inq_byte7 & INQ7_QUEUE) && lp->maxnxs < 2) {
- struct nlink *jumps;
- jumps = m_alloc(256, 8);
- if (!jumps)
+ if ((inq_byte7 & INQ7_QUEUE) && lp->jump_ccb == &lp->jump_ccb_0) {
+ int i;
+ lp->jump_ccb = m_alloc(256, 8);
+ if (!lp->jump_ccb) {
+ lp->jump_ccb = &lp->jump_ccb_0;
goto fail;
-#if SCSI_NCR_MAX_TAGS <= 32
- lp->maxnxs = 32;
-#else
- lp->maxnxs = 64;
-#endif
- lp->jump_ccb = jumps;
- ncr_setup_jump_ccb(np, lp);
- lp->tags_stime = jiffies;
+ }
+ lp->p_jump_ccb = cpu_to_scr(vtophys(lp->jump_ccb));
+ for (i = 0 ; i < 64 ; i++)
+ lp->jump_ccb[i] =
+ cpu_to_scr(NCB_SCRIPTH_PHYS (np, bad_i_t_l_q));
+ for (i = 0 ; i < SCSI_NCR_MAX_TAGS ; i++)
+ lp->cb_tags[i] = i;
+ lp->maxnxs = SCSI_NCR_MAX_TAGS;
+ lp->tags_stime = jiffies;
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov