summaryrefslogtreecommitdiffstats
path: root/sys/pci/ncr.c
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>1998-09-20 22:54:28 +0000
committerken <ken@FreeBSD.org>1998-09-20 22:54:28 +0000
commit2d9bbf7ec729f51622fdb7974ff3b946498a4786 (patch)
tree25dcc0d94e6620325aa534e0fc0069210b7a929d /sys/pci/ncr.c
parentdafd644ddde5252ee054b3eede832f6a805e0bf2 (diff)
downloadFreeBSD-src-2d9bbf7ec729f51622fdb7974ff3b946498a4786.zip
FreeBSD-src-2d9bbf7ec729f51622fdb7974ff3b946498a4786.tar.gz
Alpha patches for the NCR driver from Doug Rabson. I've tested these on an
NCR 810a, and they seem to work fine on the i386 as well. Reviewed by: gibbs Submitted by: dfr
Diffstat (limited to 'sys/pci/ncr.c')
-rw-r--r--sys/pci/ncr.c190
1 files changed, 136 insertions, 54 deletions
diff --git a/sys/pci/ncr.c b/sys/pci/ncr.c
index 52fa6d0..d08c378 100644
--- a/sys/pci/ncr.c
+++ b/sys/pci/ncr.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: ncr.c,v 1.129 1998/09/17 22:29:02 gibbs Exp $
+** $Id: ncr.c,v 1.130 1998/09/18 22:41:12 gibbs Exp $
**
** Device driver for the NCR 53C8XX PCI-SCSI-Controller Family.
**
@@ -272,6 +272,13 @@
**==========================================================
*/
+#ifdef __alpha__
+/* XXX */
+#undef vtophys
+#define vtophys(va) (pmap_kextract(((vm_offset_t) (va))) \
+ + 1*1024*1024*1024)
+#endif
+
#ifdef NCR_IOMAPPED
#define INB(r) inb (np->port + offsetof(struct ncr_reg, r))
@@ -281,11 +288,61 @@
#define OUTB(r, val) outb (np->port+offsetof(struct ncr_reg,r),(val))
#define OUTW(r, val) outw (np->port+offsetof(struct ncr_reg,r),(val))
#define OUTL(r, val) outl (np->port+offsetof(struct ncr_reg,r),(val))
+#define OUTL_OFF(o, val) outl(np->port + (o), (val))
#define INB_OFF(o) inb (np->port + (o))
#define INW_OFF(o) inw (np->port + (o))
#define INL_OFF(o) inl (np->port + (o))
+#define READSCRIPT_OFF(base, off) \
+ (*((u_int32_t *)((char *)base + (off))))
+
+#define WRITESCRIPT_OFF(base, off, val) \
+ do { \
+ *((u_int32_t *)((char *)base + (off))) = (val); \
+ } while (0)
+
+#define READSCRIPT(r) \
+ READSCRIPT_OFF(np->script, offsetof(struct script, r))
+
+#define WRITESCRIPT(r, val) \
+ WRITESCRIPT_OFF(np->script, offsetof(struct script, r), val)
+
+#else
+
+#ifdef __alpha__
+
+#define INB(r) readb (np->vaddr + offsetof(struct ncr_reg, r))
+#define INW(r) readw (np->vaddr + offsetof(struct ncr_reg, r))
+#define INL(r) readl (np->vaddr + offsetof(struct ncr_reg, r))
+
+#define OUTB(r, val) writeb (np->vaddr+offsetof(struct ncr_reg,r),(val))
+#define OUTW(r, val) writew (np->vaddr+offsetof(struct ncr_reg,r),(val))
+#define OUTL(r, val) writel (np->vaddr+offsetof(struct ncr_reg,r),(val))
+#define OUTL_OFF(o, val) writel (np->vaddr + (o), (val))
+
+#define INB_OFF(o) readb (np->vaddr + (o))
+#define INW_OFF(o) readw (np->vaddr + (o))
+#define INL_OFF(o) readl (np->vaddr + (o))
+
+#define READSCRIPT_OFF(base, off) \
+ (base ? *((u_int32_t *)((char *)base + (off))) : \
+ readl(np->vaddr2 + off))
+
+#define WRITESCRIPT_OFF(base, off, val) \
+ do { \
+ if (base) \
+ *((u_int32_t *)((char *)base + (off))) = (val); \
+ else \
+ writel(np->vaddr2 + off, val); \
+ } while (0)
+
+#define READSCRIPT(r) \
+ READSCRIPT_OFF(np->script, offsetof(struct script, r))
+
+#define WRITESCRIPT(r, val) \
+ WRITESCRIPT_OFF(np->script, offsetof(struct script, r), val)
+
#else
#define INB(r) (np->reg->r)
@@ -295,11 +352,19 @@
#define OUTB(r, val) np->reg->r = (val)
#define OUTW(r, val) np->reg->r = (val)
#define OUTL(r, val) np->reg->r = (val)
+#define OUTL_OFF(o, val) *(u_int32_t *) (((u_char *) np->reg) + (o)) = (val)
#define INB_OFF(o) *( ((u_char *) np->reg) + (o) )
#define INW_OFF(o) *((u_short *) ( ((u_char *) np->reg) + (o)) )
#define INL_OFF(o) *((u_int32_t *) ( ((u_char *) np->reg) + (o)) )
+#define READSCRIPT_OFF(base, off) (*((volatile u_int32_t *)((char *)base + (off))))
+#define WRITESCRIPT_OFF(base, off, val) (*((volatile u_int32_t *)((char *)base + (off))) = (val))
+#define READSCRIPT(r) (np->script->r)
+#define WRITESCRIPT(r, val) np->script->r = (val)
+
+#endif
+
#endif
/*
@@ -998,7 +1063,9 @@ struct ncb {
** pointer to the chip's registers.
*/
volatile
+#ifdef __i386__
struct ncr_reg* reg;
+#endif
/*
** Scripts instance virtual address.
@@ -1123,7 +1190,7 @@ struct ncb {
/*
** address of the ncr control registers in io space
*/
- u_short port;
+ pci_port_t port;
#endif
};
@@ -1288,7 +1355,7 @@ static void ncr_attach (pcici_t tag, int unit);
static char ident[] =
- "\n$Id: ncr.c,v 1.129 1998/09/17 22:29:02 gibbs Exp $\n";
+ "\n$Id: ncr.c,v 1.130 1998/09/18 22:41:12 gibbs Exp $\n";
static const u_long ncr_version = NCR_VERSION * 11
+ (u_long) sizeof (struct ncb) * 7
@@ -3022,14 +3089,17 @@ static void ncr_script_copy_and_bind (ncb_p np, ncrcmd *src, ncrcmd *dst, int le
{
ncrcmd opcode, new, old, tmp1, tmp2;
ncrcmd *start, *end;
- int relocs;
+ int relocs, offset;
start = src;
end = src + len/4;
+ offset = 0;
while (src < end) {
- *dst++ = opcode = *src++;
+ opcode = *src++;
+ WRITESCRIPT_OFF(dst, offset, opcode);
+ offset += 4;
/*
** If we forget to change the length
@@ -3074,7 +3144,8 @@ static void ncr_script_copy_and_bind (ncb_p np, ncrcmd *src, ncrcmd *dst, int le
** the NO FLUSH bit if present.
*/
if ((opcode & SCR_NO_FLUSH) && !(np->features&FE_PFEN))
- dst[-1] = (opcode & ~SCR_NO_FLUSH);
+ WRITESCRIPT_OFF(dst, offset - 4,
+ (opcode & ~SCR_NO_FLUSH));
break;
case 0x0:
@@ -3141,14 +3212,17 @@ static void ncr_script_copy_and_bind (ncb_p np, ncrcmd *src, ncrcmd *dst, int le
}
/* fall through */
default:
- panic("ncr_script_copy_and_bind: weird relocation %x @ %d\n", old, (src - start));
+ panic("ncr_script_copy_and_bind: weird relocation %x @ %d\n", old, (int)(src - start));
break;
}
- *dst++ = new;
+ WRITESCRIPT_OFF(dst, offset, new);
+ offset += 4;
}
- } else
- *dst++ = *src++;
+ } else {
+ WRITESCRIPT_OFF(dst, offset, *src++);
+ offset += 4;
+ }
};
}
@@ -3394,7 +3468,9 @@ ncr_attach (pcici_t config_id, int unit)
** can be used safely.
*/
+#ifdef __i386__
np->reg = (struct ncr_reg*) np->vaddr;
+#endif
#ifdef NCR_IOMAPPED
/*
@@ -3583,7 +3659,7 @@ ncr_attach (pcici_t config_id, int unit)
** Allocate structure for script relocation.
*/
if (np->vaddr2 != NULL) {
- np->script = (struct script *) np->vaddr2;
+ np->script = NULL;
np->p_script = np->paddr2;
} else if (sizeof (struct script) > PAGE_SIZE) {
np->script = (struct script*) vm_page_alloc_contig
@@ -3682,7 +3758,8 @@ ncr_attach (pcici_t config_id, int unit)
*/
ncr_script_fill (&script0, &scripth0);
- np->p_script = vtophys(np->script);
+ if (np->script)
+ np->p_script = vtophys(np->script);
np->p_scripth = vtophys(np->scripth);
ncr_script_copy_and_bind (np, (ncrcmd *) &script0,
@@ -3696,9 +3773,9 @@ ncr_attach (pcici_t config_id, int unit)
*/
if (np->features & FE_LED0) {
- np->script->reselect[0] = SCR_REG_REG(gpreg, SCR_OR, 0x01);
- np->script->reselect1[0] = SCR_REG_REG(gpreg, SCR_AND, 0xfe);
- np->script->reselect2[0] = SCR_REG_REG(gpreg, SCR_AND, 0xfe);
+ WRITESCRIPT(reselect[0], SCR_REG_REG(gpreg, SCR_OR, 0x01));
+ WRITESCRIPT(reselect1[0], SCR_REG_REG(gpreg, SCR_AND, 0xfe));
+ WRITESCRIPT(reselect2[0], SCR_REG_REG(gpreg, SCR_AND, 0xfe));
}
/*
@@ -4143,7 +4220,7 @@ ncr_action (struct cam_sim *sim, union ccb *ccb)
if(DEBUG_FLAGS & DEBUG_QUEUE)
printf("%s: queuepos=%d tryoffset=%d.\n",
ncr_name (np), np->squeueput,
- (unsigned)(np->script->startpos[0]-
+ (unsigned)(READSCRIPT(startpos[0]) -
(NCB_SCRIPTH_PHYS (np, tryloop))));
/*
@@ -4411,7 +4488,7 @@ ncr_complete (ncb_p np, nccb_p cp)
ncb_profile (np, cp);
if (DEBUG_FLAGS & DEBUG_TINY)
- printf ("CCB=%x STAT=%x/%x\n", (unsigned)cp & 0xfff,
+ printf ("CCB=%x STAT=%x/%x\n", (int)(intptr_t)cp & 0xfff,
cp->host_status,cp->s_status);
ccb = cp->ccb;
@@ -4521,8 +4598,8 @@ ncr_complete (ncb_p np, nccb_p cp)
** Other protocol messes
*/
PRINT_ADDR(ccb);
- printf ("COMMAND FAILED (%x %x) @%x.\n",
- cp->host_status, cp->s_status, (unsigned)cp);
+ printf ("COMMAND FAILED (%x %x) @%p.\n",
+ cp->host_status, cp->s_status, cp);
ccb->ccb_h.status = CAM_CMD_TIMEOUT;
}
@@ -4713,8 +4790,8 @@ void ncr_init
*/
np->squeueput = 0;
- np->script->startpos[0] = NCB_SCRIPTH_PHYS (np, tryloop);
- np->script->start0 [0] = SCR_INT ^ IFFALSE (0);
+ WRITESCRIPT(startpos[0], NCB_SCRIPTH_PHYS (np, tryloop));
+ WRITESCRIPT(start0 [0], SCR_INT ^ IFFALSE (0));
/*
** Wakeup all pending jobs.
@@ -5117,8 +5194,8 @@ ncr_timeout (void *arg)
cp->jump_nccb.l_cmd = (SCR_JUMP);
if (cp->phys.header.launch.l_paddr ==
NCB_SCRIPT_PHYS (np, select)) {
- printf ("%s: timeout nccb=%x (skip)\n",
- ncr_name (np), (unsigned)cp);
+ printf ("%s: timeout nccb=%p (skip)\n",
+ ncr_name (np), cp);
cp->phys.header.launch.l_paddr
= NCB_SCRIPT_PHYS (np, skip);
};
@@ -5228,7 +5305,7 @@ static void ncr_log_hard_error(ncb_p np, u_short sist, u_char dstat)
if (((script_ofs & 3) == 0) &&
(unsigned)script_ofs < script_size) {
printf ("%s: script cmd = %08x\n", ncr_name(np),
- (int) *(ncrcmd *)(script_base + script_ofs));
+ (int)READSCRIPT_OFF(script_base, script_ofs));
}
printf ("%s: regdump:", ncr_name(np));
@@ -5575,7 +5652,7 @@ void ncr_int_sto (ncb_p np)
/* assert ((diff <= MAX_START * 20) && !(diff % 20));*/
if ((diff <= MAX_START * 20) && !(diff % 20)) {
- np->script->startpos[0] = scratcha;
+ WRITESCRIPT(startpos[0], scratcha);
OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, start));
return;
};
@@ -5603,7 +5680,8 @@ static void ncr_int_ma (ncb_p np, u_char dstat)
u_int32_t dsa;
u_int32_t dsp;
u_int32_t nxtdsp;
- u_int32_t *vdsp;
+ volatile void *vdsp_base;
+ size_t vdsp_off;
u_int32_t oadr, olen;
u_int32_t *tblp, *newcmd;
u_char cmd, sbcl, ss0, ss2, ctest5;
@@ -5670,17 +5748,21 @@ static void ncr_int_ma (ncb_p np, u_char dstat)
*/
if (dsp == vtophys (&cp->patch[2])) {
- vdsp = &cp->patch[0];
- nxtdsp = vdsp[3];
+ vdsp_base = cp;
+ vdsp_off = offsetof(struct nccb, patch[0]);
+ nxtdsp = READSCRIPT_OFF(vdsp_base, vdsp_off + 3*4);
} else if (dsp == vtophys (&cp->patch[6])) {
- vdsp = &cp->patch[4];
- nxtdsp = vdsp[3];
+ vdsp_base = cp;
+ vdsp_off = offsetof(struct nccb, patch[4]);
+ nxtdsp = READSCRIPT_OFF(vdsp_base, vdsp_off + 3*4);
} else if (dsp > np->p_script &&
dsp <= np->p_script + sizeof(struct script)) {
- vdsp = (u_int32_t *) ((char*)np->script - np->p_script + dsp-8);
+ vdsp_base = np->script;
+ vdsp_off = dsp - np->p_script - 8;
nxtdsp = dsp;
} else {
- vdsp = (u_int32_t *) ((char*)np->scripth - np->p_scripth+dsp-8);
+ vdsp_base = np->scripth;
+ vdsp_off = dsp - np->p_scripth - 8;
nxtdsp = dsp;
};
@@ -5693,17 +5775,17 @@ static void ncr_int_ma (ncb_p np, u_char dstat)
(unsigned) rest, (unsigned) delta, ss0);
};
if (DEBUG_FLAGS & DEBUG_PHASE) {
- printf ("\nCP=%x CP2=%x DSP=%x NXT=%x VDSP=%x CMD=%x ",
- (unsigned)cp, (unsigned)np->header.cp,
- (unsigned)dsp,
- (unsigned)nxtdsp, (unsigned)vdsp, cmd);
+ printf ("\nCP=%p CP2=%p DSP=%x NXT=%x VDSP=%p CMD=%x ",
+ cp, np->header.cp,
+ dsp,
+ nxtdsp, (char*)vdsp_base+vdsp_off, cmd);
};
/*
** get old startaddress and old length.
*/
- oadr = vdsp[1];
+ oadr = READSCRIPT_OFF(vdsp_base, vdsp_off + 1*4);
if (cmd & 0x10) { /* Table indirect */
tblp = (u_int32_t *) ((char*) &cp->phys + oadr);
@@ -5711,13 +5793,13 @@ static void ncr_int_ma (ncb_p np, u_char dstat)
oadr = tblp[1];
} else {
tblp = (u_int32_t *) 0;
- olen = vdsp[0] & 0xffffff;
+ olen = READSCRIPT_OFF(vdsp_base, vdsp_off) & 0xffffff;
};
if (DEBUG_FLAGS & DEBUG_PHASE) {
- printf ("OCMD=%x\nTBLP=%x OLEN=%x OADR=%x\n",
- (unsigned) (vdsp[0] >> 24),
- (unsigned) tblp,
+ printf ("OCMD=%x\nTBLP=%lx OLEN=%x OADR=%x\n",
+ (unsigned) (READSCRIPT_OFF(vdsp_base, vdsp_off) >> 24),
+ (u_long) tblp,
(unsigned) olen,
(unsigned) oadr);
};
@@ -5726,10 +5808,11 @@ static void ncr_int_ma (ncb_p np, u_char dstat)
** if old phase not dataphase, leave here.
*/
- if (cmd != (vdsp[0] >> 24)) {
+ if (cmd != (READSCRIPT_OFF(vdsp_base, vdsp_off) >> 24)) {
PRINT_ADDR(cp->ccb);
printf ("internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n",
- (unsigned)cmd, (unsigned)vdsp[0] >> 24);
+ (unsigned)cmd,
+ (unsigned)READSCRIPT_OFF(vdsp_base, vdsp_off) >> 24);
return;
}
@@ -5763,7 +5846,7 @@ static void ncr_int_ma (ncb_p np, u_char dstat)
if (DEBUG_FLAGS & DEBUG_PHASE) {
PRINT_ADDR(cp->ccb);
printf ("newcmd[%d] %x %x %x %x.\n",
- newcmd - cp->patch,
+ (int)(newcmd - cp->patch),
(unsigned)newcmd[0],
(unsigned)newcmd[1],
(unsigned)newcmd[2],
@@ -5886,7 +5969,7 @@ void ncr_int_sir (ncb_p np)
** no job, resume normal processing
*/
if (DEBUG_FLAGS & DEBUG_RESTART) printf (" -- remove trap\n");
- np->script->start0[0] = SCR_INT ^ IFFALSE (0);
+ WRITESCRIPT(start0[0], SCR_INT ^ IFFALSE (0));
break;
case SIR_SENSE_FAILED:
@@ -5912,7 +5995,7 @@ void ncr_int_sir (ncb_p np)
/*
** And patch code to restart it.
*/
- np->script->start0[0] = SCR_INT;
+ WRITESCRIPT(start0[0], SCR_INT);
break;
/*-----------------------------------------------------------------------------
@@ -6344,7 +6427,7 @@ void ncr_int_sir (ncb_p np)
*/
printf ("%s: queue empty.\n", ncr_name (np));
- np->script->start1[0] = SCR_INT ^ IFFALSE (0);
+ WRITESCRIPT(start1[0], SCR_INT ^ IFFALSE (0));
break;
};
@@ -6526,7 +6609,7 @@ ncr_alloc_nccb (ncb_p np, u_long target, u_long lun)
return (NULL);
if (DEBUG_FLAGS & DEBUG_ALLOC) {
- printf ("new nccb @%x.\n", (unsigned) cp);
+ printf ("new nccb @%p.\n", cp);
}
/*
@@ -6616,8 +6699,8 @@ static int ncr_scatter
chunk /= 2;
if(DEBUG_FLAGS & DEBUG_SCATTER)
- printf("ncr?:\tscattering virtual=0x%x size=%d chunk=%d.\n",
- (unsigned) vaddr, (unsigned) datalen, (unsigned) chunk);
+ printf("ncr?:\tscattering virtual=%p size=%d chunk=%d.\n",
+ (void *) vaddr, (unsigned) datalen, (unsigned) chunk);
/*
** Build data descriptors.
@@ -6690,16 +6773,15 @@ static int ncr_scatter
#ifndef NCR_IOMAPPED
static int ncr_regtest (struct ncb* np)
{
- register volatile u_int32_t data, *addr;
+ register volatile u_int32_t data;
/*
** ncr registers may NOT be cached.
** write 0xffffffff to a read only register area,
** and try to read it back.
*/
- addr = (volatile u_int32_t *) &np->reg->nc_dstat;
data = 0xffffffff;
- *addr= data;
- data = *addr;
+ OUTL_OFF(offsetof(struct ncr_reg, nc_dstat), data);
+ data = INL_OFF(offsetof(struct ncr_reg, nc_dstat));
#if 1
if (data == 0xffffffff) {
#else
OpenPOWER on IntegriCloud