, Mitch Bradley <wmb@firmworks.com>
From: Matthew Jacob <mjacob@feral.com>
List: tech-kern
Date: 09/14/2001 11:44:11
On Fri, 14 Sep 2001, Matthew Fredette wrote:
>
> > > This controller is so simple, it doesn't look at the commands you ask
> > > it to put on the wire - meaning it's not really a SASI-only or SCSI-1
> > > only controller. I usually have more modern SCSI-2 disks and tapes
> > > hooked up and everything works fine.
> >
> > Well, disconnect/reconnect doesn't work last I checked. When I did
> > the SCSI rewrite at Sun (aeons ago) I also did unified ncr (for the
> > 5 different 5380 variants that Sun had) and the sc driver as well. I
> > found it indeed did mostly work with a base disk driver that assumed
> > CCS.
>
> Cool, finally I find someone that knows the sc board! Ya, no
> disconnect/reselect, and host can't initiate a message phase. Can you
> clear up a parity issue? I've heard rumblings that the sc might
> have flakey parity handling, so I run with it disabled on all devices.
You're asking me to remember stuff from 12 years ago :-)... I seem to recall
something about this, yes. Mitch? You still responding to email between golf
swings? Do you remember?
>
> > If you say it works with the current sd- and that the ACB4000 at the
> > other end should work, that's good.
>
> Yes, the sc does work with the current sd and modern drives. I'll use
> mhitch's patch to check for sure this weekend if the sc+ACB4000
> combination gets a usable drive (beyond not doing INQUIRY).
>
> > There are things beginning to creep in (like Synchronize Cache) that
> > might send such a board into the weeds- you have to see what they
> > do.
>
> Well if we can confidently determine somehow at INQUIRY time that
> we've got an old translator board (and which one!) and conjure up
> a fake INQUIRY response, we should be able to add quirk entries?
>
> > I don't think reading a sun disk label is right (for bootstrap reasons).
>
> Ya, this was just a bad idea.
>
> > But it sounds like this hack will work for the ACB4000. The MT-02 might be
> > another issue (and, no, I no longer have any :-()...
>
> My sun2 has a QIC-02 tape behind another kind of translator board. I'm
> 90% sure it's an MT-02, will check this weekend.
It might be a SYSGEN controller. Just. Say. No.
> My old SunOS 3 installation has a usr/src/sys/sundev/scsi.h that hints
> that the different translator boards return different numbers of sense
> bytes - maybe we can use this to differentiate them?
Oh, gross- yeah, that was the old SunOS hack. No. No. No. It really is a
'per-CPUtype' sort of thing- see below.
-matt
from my version of ncr.c- modifed last in 1994:
static int
ncr_probe(reg, ctlr)
u_short *reg;
int ctlr;
{
register struct ncrsbc *ncrp = (struct ncrsbc *) reg;
register struct ncr *ncr;
long val;
u_long dma_base, sbcaddr, ctladdr, dmaaddr;
#ifdef sun3
u_long udcp;
#endif
caddr_t dmabuf;
int host_type = -1;
u_short *shortp;
/*
* Check for ncr 5380 Scsi Bus Ctlr chip with "peekc()"; struct
* ncr-5380 is common to all onboard scsi and vme scsi board. if not
* exist, return 0.
*/
PRINTF3("ncr_probe: reg= %x virt, %x phys\n", reg,
getdevaddr((caddr_t) reg));
/*
* We can use the first byte address of reg, 'coz we'll guarantee
* (by the time we are through) that that will always be the first
* byte of the NCR 5380 SBC (which should be the cbsr register).
*/
if (peekc((caddr_t)reg) == -1) {
return (0);
}
sbcaddr = (u_long) reg;
dmaaddr = ((u_long) reg) + sizeof (struct ncrsbc);
/*
* probe for different host adaptor interfaces
*/
switch (cpu) {
#ifdef sun4
case CPU_SUN4_110:
/*
* probe for 4/110 dma interface
*/
ctladdr = ((u_long) reg) + COBRA_CSR_OFF;
if (peekl((long *) (dmaaddr), (long *) &val) == -1) {
return (0);
}
host_type = IS_COBRA;
dma_base = DMA_BASE_110;
break;
#endif sun4
#ifdef sun3
case CPU_SUN3_50:
case CPU_SUN3_60:
ctladdr = ((u_long) reg) + CSR_OFF;
if (peek((short *)&
((struct ncrdma *)dmaaddr)->udc_rdata) == -1)
return (0);
udcp = (u_long) IOPBALLOC(sizeof (struct udc_table));
if (udcp == 0 || udcp & 0x3) {
printf("%s%d: no udc table\n", CNAME, ctlr);
if (udcp)
IOPBFREE(udcp, sizeof (struct udc_table));
return (0);
}
host_type = IS_3_50;
dma_base = DMA_BASE_3_50;
break;
#endif sun3
default:
/*
* This is either a SCSI-3 or a 3/E VME board
*
* First see whether the dma address register is there
* The low 16 bits is common across all platforms.
*
*/
if (peek((short *) (dmaaddr + 2)) == -1) {
return (0);
}
/*
* Okay, now whether it is a 3/E board
*/
ctladdr = ((u_long) reg) + SUN3E_CSR_OFF;
if (peek((short *) (ctladdr + 2)) != -1) {
if (poke ((short *) (ctladdr + 2), 0) == 0) {
if (peek((short *) (ctladdr + 2)) == 0x402) {
dmabuf = ncr_mapdmabuf(reg);
if (dmabuf == (caddr_t) 0)
return (0);
host_type = IS_3E;
dma_base = 0;
break;
}
}
}
/*
* Okay- it wasn't a 3/E. Now see whether it's a scsi-3 board.
*
* Make sure that it isn't a SCSI-2 board (which occupies 4k
* of VME space instead of the 2k that the SCSI-3 occupies).
* (the above is a quote from si.c. The code below doesn't
* seem to bear this out exactly).
*
*/
if (peek((short *) (((u_long) reg) + 0x800)) != -1) {
return (0);
}
/*
* Make sure that we're cool (really a scsi-3 board).
*/
ctladdr = ((u_long) reg) + CSR_OFF;
if (peek((short *) (ctladdr + 2)) == -1)
return (0);
if ((((struct ncrctl *) ctladdr)->csr.lsw & NCR_CSR_ID) == 0) {
printf("%s%d: unmodified scsi-3 board- you lose..\n",
CNAME, ctlr);
return (0);
}
host_type = IS_SCSI3;
dma_base = 0;
break;
}
/*
* Establish initial softc values
*/
if (ncr_softc == 0) {
ncr_softc = (struct ncr *)
kmem_zalloc((unsigned) (NNCR * sizeof (struct ncr)));
if (ncr_softc == 0)
return (0);
Dmabase = dma_base;
timeout(ncr_watch, (caddr_t) 0, hz);
}
/*
* initialize software structure
*/
ncr = &ncr_softc[ctlr];
/*
* Allocate a page for being able to
* flush the last bit of a data transfer.
*/
ncr->n_kment = rmalloc(kernelmap, mmu_btopr(MMU_PAGESIZE));
if (ncr->n_kment == 0) {
return (0);
}
ncr->n_dev = &ncrdriver;
ncr->n_id = ncr_host_id;
ncr->n_sbc = (struct ncrsbc *) (sbcaddr);
ncr->n_dma = (struct ncrdma *) (dmaaddr);
ncr->n_ctl = (struct ncrctl *) (ctladdr);
ncr->n_type = host_type;
ncr->n_tran.tran_start = ncr_start;
ncr->n_tran.tran_abort = ncr_abort;
ncr->n_tran.tran_reset = ncr_reset;
ncr->n_tran.tran_getcap = ncr_getcap;
ncr->n_tran.tran_setcap = ncr_setcap;
ncr->n_tran.tran_pktalloc = scsi_std_pktalloc;
ncr->n_tran.tran_dmaget = scsi_std_dmaget;
ncr->n_tran.tran_pktfree = scsi_std_pktfree;
ncr->n_tran.tran_dmafree = scsi_std_dmafree;
ncr->n_last_slot = ncr->n_cur_slot = UNDEFINED;
switch (host_type) {
#ifdef sun4
case IS_COBRA:
ncr->n_dma_setup = ncr_dma_setup;
ncr->n_dma_cleanup = ncr_cobra_dma_cleanup;
break;
#endif sun4
#ifdef sun3
case IS_3_50:
ncr->n_dma_setup = ncr_ob_dma_setup;
ncr->n_dma_cleanup = ncr_ob_dma_cleanup;
ncr->n_udc = (struct udc_table *) udcp;
break;
#endif sun3
case IS_SCSI3:
ncr->n_dma_setup = ncr_dma_setup;
ncr->n_dma_cleanup = ncr_vme_dma_cleanup;
break;
case IS_3E:
ncr->n_dmabuf = dmabuf;
ncr->n_dma_setup = ncr_dma_setup;
ncr->n_dma_cleanup = ncr_3e_dma_cleanup;
break;
}
ncr_internal_reset(ncr, NCR_RESET_ALL, RESET_NOMSG);
return (NCR_HWSIZE);
}