diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1997-03-03 00:25:05 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1997-03-03 00:25:05 +0000 |
commit | 9fa1bac5dc7ddac9616341845d4ff5a3147885df (patch) | |
tree | e7c37d9c02f2c111b5e987700d1abb8174fbd807 /sys/dev/pci/ncr.c | |
parent | e516a54a925181933c9f41012fd91250b1b683b7 (diff) |
Sync with NetBSD which is syncing with FreeBSD, whee!
OpenBSD-specific changes are surrounded by #ifdef __OpenBSD__
or #ifndef __OpenBSD__
Diffstat (limited to 'sys/dev/pci/ncr.c')
-rw-r--r-- | sys/dev/pci/ncr.c | 635 |
1 files changed, 398 insertions, 237 deletions
diff --git a/sys/dev/pci/ncr.c b/sys/dev/pci/ncr.c index 7f38bbfe277..b6a56862a89 100644 --- a/sys/dev/pci/ncr.c +++ b/sys/dev/pci/ncr.c @@ -1,11 +1,11 @@ -/* $OpenBSD: ncr.c,v 1.25 1997/01/22 21:46:51 deraadt Exp $ */ -/* $NetBSD: ncr.c,v 1.48 1996/10/25 21:33:33 cgd Exp $ */ +/* $OpenBSD: ncr.c,v 1.26 1997/03/03 00:25:03 millert Exp $ */ +/* $NetBSD: ncr.c,v 1.55 1997/01/10 05:57:10 perry Exp $ */ /************************************************************************** ** ** Device driver for the NCR 53C810 PCI-SCSI-Controller. ** -** FreeBSD / NetBSD +** FreeBSD / NetBSD / OpenBSD ** **------------------------------------------------------------------------- ** @@ -15,7 +15,6 @@ ** ** Ported to NetBSD by ** Charles M. Hannum <mycroft@gnu.ai.mit.edu> -** Dave Huang <khym@bga.com> ** **------------------------------------------------------------------------- ** @@ -46,18 +45,27 @@ *************************************************************************** */ -#define NCR_DATE "pl23 95/09/07" +#define NCR_DATE "pl24 96/12/14" #define NCR_VERSION (2) #define MAX_UNITS (16) #define NCR_GETCC_WITHMSG -#ifdef FAILSAFE +#ifdef __OpenBSD__ +#define __BROKEN_INDIRECT_CONFIG +#endif + +#if defined (__FreeBSD__) && defined(KERNEL) +#include "opt_ncr.h" +#endif /* defined (__FreeBSD__) && defined(KERNEL) */ + +#ifdef FAILSAFE +#ifndef SCSI_NCR_DFLT_TAGS #define SCSI_NCR_DFLT_TAGS (0) -#define MAX_LUN (1) -#define CDROM_ASYNC -#endif /* FAILSAFE */ +#endif /* SCSI_NCR_DFLT_TAGS */ +#define NCR_CDROM_ASYNC +#endif /* FAILSAFE */ /*========================================================== ** @@ -124,9 +132,13 @@ /* ** Number of logic units supported by the driver. ** n enables logic unit numbers 0..n-1. +** The common SCSI devices require only +** one lun, so take 1 as the default. */ +#ifndef MAX_LUN #define MAX_LUN (8) +#endif /* MAX_LUN */ /* ** The maximum number of jobs scheduled for starting. @@ -209,7 +221,7 @@ #ifndef __alpha__ #define DELAY(x) delay(x) #endif -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ #include <scsi/scsi_all.h> #include <scsi/scsiconf.h> @@ -246,12 +258,12 @@ ** Can be changed at runtime too. */ -#ifdef SCSI_DEBUG_FLAGS +#ifdef SCSI_NCR_DEBUG #define DEBUG_FLAGS ncr_debug -#else /* SCSI_DEBUG_FLAGS */ - #define SCSI_DEBUG_FLAGS 0 +#else /* SCSI_NCR_DEBUG */ + #define SCSI_NCR_DEBUG 0 #define DEBUG_FLAGS 0 -#endif /* SCSI_DEBUG_FLAGS */ +#endif /* SCSI_NCR_DEBUG */ @@ -331,7 +343,7 @@ #endif -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ #ifdef NCR_IOMAPPED @@ -354,14 +366,14 @@ #define INL(r) (np->reg->r) #define INL_OFF(o) (*((volatile INT32 *)((char *)np->reg + (o)))) -#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 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) *((volatile INT32 *)((char *)np->reg + (o))) = val #endif -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ /*========================================================== ** @@ -1006,9 +1018,9 @@ struct ncb { bus_space_tag_t sc_memt; pci_chipset_tag_t sc_pc; bus_space_handle_t sc_bah; -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ int unit; -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ /*----------------------------------------------- ** Scripts .. @@ -1064,9 +1076,17 @@ struct ncb { /* ** timing parameters */ - u_char ns_async; u_char ns_sync; + u_char maxoffs; + + /* + ** BIOS supplied PCI bus options + */ u_char rv_scntl3; + u_char rv_dcntl; + u_char rv_dmode; + u_char rv_ctest3; + u_char rv_ctest5; /*----------------------------------------------- ** Link to the generic SCSI driver @@ -1279,7 +1299,7 @@ static int ncr_intr (void *vnp); #else static void ncr_intr (void *vnp); static U_INT32 ncr_info (int unit); -#endif /* !__NetBSD__ */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ static void ncr_int_ma (ncb_p np); static void ncr_int_sir (ncb_p np); static void ncr_int_sto (ncb_p np); @@ -1297,7 +1317,7 @@ static void ncb_profile (ncb_p np, ccb_p cp); static void ncr_script_copy_and_bind (struct script * script, ncb_p np); static void ncr_script_fill (struct script * scr); -static int ncr_scatter (ncb_p np, struct dsb* phys, vm_offset_t vaddr, +static int ncr_scatter (struct dsb* phys, vm_offset_t vaddr, vm_size_t datalen); static void ncr_setmaxtags (tcb_p tp, u_long usrtags); static void ncr_setsync (ncb_p np, ccb_p cp, u_char sxfer); @@ -1311,12 +1331,16 @@ static void ncr_usercmd (ncb_p np); static void ncr_wakeup (ncb_p np, u_long code); #if defined(__NetBSD__) || defined(__OpenBSD__) +#ifdef __BROKEN_INDIRECT_CONFIG static int ncr_probe (struct device *, void *, void *); +#else +static int ncr_probe (struct device *, struct cfdata *, void *); +#endif static void ncr_attach (struct device *, struct device *, void *); -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ static char* ncr_probe (pcici_t tag, pcidi_t type); static void ncr_attach (pcici_t tag, int unit); -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ #endif /* KERNEL */ @@ -1332,7 +1356,7 @@ static void ncr_attach (pcici_t tag, int unit); #if 0 static char ident[] = - "\n$NetBSD: ncr.c,v 1.48 1996/10/25 21:33:33 cgd Exp $\n"; + "\n$OpenBSD: ncr.c,v 1.26 1997/03/03 00:25:03 millert Exp $\n"; #endif static const u_long ncr_version = NCR_VERSION * 11 @@ -1345,13 +1369,13 @@ static const u_long ncr_version = NCR_VERSION * 11 #if !(defined(__NetBSD__) || defined(__OpenBSD__)) static const int nncr=MAX_UNITS; /* XXX to be replaced by SYSCTL */ -ncb_p ncrp [MAX_UNITS]; /* XXX to be replaced by SYSCTL */ -#endif /* !__NetBSD__ */ +ncb_p ncrp [MAX_UNITS]; /* XXX to be replaced by SYSCTL */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ -static int ncr_debug = SCSI_DEBUG_FLAGS; -#if !defined(__NetBSD__) && !defined(__OpenBSD__) +static int ncr_debug = SCSI_NCR_DEBUG; +#if !(defined(__NetBSD__) || defined(__OpenBSD__)) SYSCTL_INT(_debug, OID_AUTO, ncr_debug, CTLFLAG_RW, &ncr_debug, 0, ""); -#endif /* !__NetBSD__ */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ static int ncr_cache; /* to be aligned _NOT_ static */ @@ -1365,7 +1389,6 @@ static int ncr_cache; /* to be aligned _NOT_ static */ */ #define NCR_810_ID (0x00011000ul) -#define NCR_810AP_ID (0x00051000ul) #define NCR_815_ID (0x00041000ul) #define NCR_825_ID (0x00031000ul) #define NCR_860_ID (0x00061000ul) @@ -1381,7 +1404,7 @@ struct cfdriver ncr_cd = { NULL, "ncr", DV_DULL }; -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ static u_long ncr_count; @@ -1395,7 +1418,7 @@ static struct pci_device ncr_device = { DATA_SET (pcidevice_set, ncr_device); -#endif /* !__NetBSD__ */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ static struct scsi_adapter ncr_switch = { @@ -1410,7 +1433,7 @@ static struct scsi_adapter ncr_switch = #if !(defined(__NetBSD__) || defined(__OpenBSD__)) ncr_info, "ncr", -#endif /* !__NetBSD__ */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ }; static struct scsi_device ncr_dev = @@ -1421,14 +1444,14 @@ static struct scsi_device ncr_dev = NULL, /* Use default 'done' routine */ #if !(defined(__NetBSD__) || defined(__OpenBSD__)) "ncr", -#endif /* !__NetBSD__ */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ }; #if defined(__NetBSD__) || defined(__OpenBSD__) #define ncr_name(np) (np->sc_dev.dv_xname) -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ static char *ncr_name (ncb_p np) { @@ -3092,12 +3115,12 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np) int relocs; #if !(defined(__NetBSD__) || defined(__OpenBSD__)) - np->script = (struct script*) vm_page_alloc_contig + np->script = (struct script*) vm_page_alloc_contig (round_page(sizeof (struct script)), 0x100000, 0xffffffff, PAGE_SIZE); -#else /* !__NetBSD___ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ np->script = (struct script *) malloc (sizeof (struct script), M_DEVBUF, M_WAITOK); -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ np->p_script = vtophys(np->script); @@ -3119,8 +3142,8 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np) */ if (opcode == 0) { - printf ("%s: ERROR0 IN SCRIPT at %d.\n", - ncr_name(np), src-start-1); + printf ("%s: ERROR0 IN SCRIPT at %ld.\n", + ncr_name(np), (long)(src-start-1)); DELAY (1000000); }; @@ -3144,8 +3167,8 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np) if ((tmp2 & RELOC_MASK) == RELOC_KVAR) tmp2 = 0; if ((tmp1 ^ tmp2) & 3) { - printf ("%s: ERROR1 IN SCRIPT at %d.\n", - ncr_name(np), src-start-1); + printf ("%s: ERROR1 IN SCRIPT at %ld.\n", + ncr_name(np), (long)(src-start-1)); DELAY (1000000); }; break; @@ -3287,7 +3310,12 @@ U_INT32 ncr_info (int unit) int ncr_probe(parent, match, aux) struct device *parent; - void *match, *aux; +#ifdef __BROKEN_INDIRECT_CONFIG + void *match; +#else + struct cfdata *match; +#endif + void *aux; { struct pci_attach_args *pa = aux; #if 0 @@ -3297,7 +3325,6 @@ ncr_probe(parent, match, aux) return 0; #endif if (pa->pa_id != NCR_810_ID && - pa->pa_id != NCR_810AP_ID && pa->pa_id != NCR_815_ID && pa->pa_id != NCR_825_ID && pa->pa_id != NCR_860_ID && @@ -3307,24 +3334,26 @@ ncr_probe(parent, match, aux) return 1; } -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ static char* ncr_probe (pcici_t tag, pcidi_t type) { + u_char rev = pci_conf_read (tag, PCI_CLASS_REG) & 0xff; switch (type) { case NCR_810_ID: - return ("ncr 53c810 scsi"); - - case NCR_810AP_ID: - return ("ncr 53c810ap scsi"); + return (rev & 0xf0) == 0x00 + ? ("ncr 53c810 scsi") + : ("ncr 53c810a scsi"); case NCR_815_ID: return ("ncr 53c815 scsi"); case NCR_825_ID: - return ("ncr 53c825 wide scsi"); + return (rev & 0xf0) == 0x00 + ? ("ncr 53c825 wide scsi") + : ("ncr 53c825a wide scsi"); case NCR_860_ID: return ("ncr 53c860 scsi"); @@ -3335,7 +3364,7 @@ static char* ncr_probe (pcici_t tag, pcidi_t type) return (NULL); } -#endif /* !__NetBSD__ */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ /*========================================================== @@ -3351,7 +3380,6 @@ static char* ncr_probe (pcici_t tag, pcidi_t type) #define MIN_SYNC_PD 20 #if defined(__NetBSD__) || defined(__OpenBSD__) - void ncr_attach(parent, self, aux) struct device *parent, *self; @@ -3366,20 +3394,18 @@ ncr_attach(parent, self, aux) const char *intrstr; ncb_p np = (void *)self; int wide = 0; + u_char rev = pci_conf_read(pc, pa->pa_tag, PCI_CLASS_REG) & 0xff; printf(": NCR "); switch (pa->pa_id) { case NCR_810_ID: - printf("53c810"); - break; - case NCR_810AP_ID: - printf("53c810ap"); + printf((rev & 0xf0) == 0x00 ? "53c810" : "53c810a"); break; case NCR_815_ID: printf("53c815"); break; case NCR_825_ID: - printf("53c825 Wide"); + printf((rev & 0xf0) == 0x00 ? "53c825 Wide" : "53c825a Wide"); wide = 1; break; case NCR_860_ID: @@ -3425,8 +3451,13 @@ ncr_attach(parent, self, aux) return; } intrstr = pci_intr_string(pc, intrhandle); +#ifndef __OpenBSD__ + np->sc_ih = pci_intr_establish(pc, intrhandle, IPL_BIO, + ncr_intr, np); +#else /* !__OpenBSD__ */ np->sc_ih = pci_intr_establish(pc, intrhandle, IPL_BIO, ncr_intr, np, self->dv_xname); +#endif /* __OpenBSD__ */ if (np->sc_ih == NULL) { printf("%s: couldn't establish interrupt", self->dv_xname); if (intrstr != NULL) @@ -3437,7 +3468,7 @@ ncr_attach(parent, self, aux) if (intrstr != NULL) printf("%s: interrupting at %s\n", self->dv_xname, intrstr); -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ static void ncr_attach (pcici_t config_id, int unit) { @@ -3492,16 +3523,25 @@ static void ncr_attach (pcici_t config_id, int unit) return; #endif -#endif /* !__NetBSD__ */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ /* - ** Do chip dependent initialization. + ** Save some controller register default values */ - np->maxwide = 0; + np->rv_dmode = INB (nc_dmode); + np->rv_dcntl = INB (nc_dcntl) | CLSE | PFEN | NOCOM; + np->rv_ctest3 = INB (nc_ctest3); + np->rv_ctest5 = 0; np->rv_scntl3 = 0x13; /* default: 40MHz clock */ - np->ns_sync = 25; /* XXX no support for Fast-20, yet */ - np->ns_async = 50; + + /* + ** Do chip dependent initialization. + */ + + np->maxwide = 0; + np->ns_sync = 25; /* in units of 4ns */ + np->maxoffs = 8; /* ** Get the frequency of the chip's clock. @@ -3510,17 +3550,36 @@ static void ncr_attach (pcici_t config_id, int unit) #if defined(__NetBSD__) || defined(__OpenBSD__) switch (pa->pa_id) { -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ switch (pci_conf_read (config_id, PCI_ID_REG)) { -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ case NCR_825_ID: + { +#if !(defined(__NetBSD__) || defined(__OpenBSD__)) + u_char rev = pci_conf_read (config_id, PCI_CLASS_REG) & 0xff; +#endif /* !(__NetBSD__ || __OpenBSD__) */ + if ((rev & 0xf0) == 0x10) + np->maxoffs = 16; np->maxwide = 1; break; + } case NCR_860_ID: np->rv_scntl3 = 0x35; /* always assume 80MHz clock for 860 */ + /*np->ns_sync = 12;*/ /* in units of 4ns */ break; case NCR_875_ID: np->maxwide = 1; + /*np->ns_sync = 12;*/ /* in units of 4ns */ + np->maxoffs = 16; +#ifdef NCR_TEKRAM_EEPROM + if (bootverbose) + { + printf ("%s: Tekram EEPROM read %s\n", + ncr_name(np), + read_tekram_eeprom (np, NULL) ? + "succeeded" : "failed"); + } +#endif /* NCR_TEKRAM_EEPROM */ ncr_getclock(np); break; } @@ -3547,14 +3606,6 @@ static void ncr_attach (pcici_t config_id, int unit) np->myaddr = INB(nc_scid) & 0x07; if (!np->myaddr) np->myaddr = SCSI_NCR_MYADDR; - /* - ** Reset chip. - */ - - OUTB (nc_istat, SRST); - DELAY (1000); - OUTB (nc_istat, 0 ); - #ifdef NCR_DUMP_REG /* ** Log the initial register contents @@ -3563,23 +3614,23 @@ static void ncr_attach (pcici_t config_id, int unit) int reg; #if defined(__NetBSD__) || defined(__OpenBSD__) u_long config_id = pa->pa_tag; -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ for (reg=0; reg<256; reg+=4) { if (reg%16==0) printf ("reg[%2x]", reg); printf (" %08x", (int)pci_conf_read (config_id, reg)); if (reg%16==12) printf ("\n"); } } +#endif /* NCR_DUMP_REG */ /* - ** Reset chip, once again. + ** Reset chip. */ OUTB (nc_istat, SRST); DELAY (1000); OUTB (nc_istat, 0 ); -#endif /* NCR_DUMP_REG */ /* ** Now check the cache handling of the pci chipset. @@ -3597,7 +3648,7 @@ static void ncr_attach (pcici_t config_id, int unit) if (!pci_map_int (config_id, ncr_intr, np, &bio_imask)) printf ("\tinterruptless mode: reduced performance.\n"); -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ /* ** After SCSI devices have been opened, we cannot @@ -3627,23 +3678,24 @@ static void ncr_attach (pcici_t config_id, int unit) np->sc_link.openings = 1; #ifndef __OpenBSD__ np->sc_link.channel = SCSI_CHANNEL_ONLY_ONE; + np->sc_link.max_target = wide ? 15 : 7; #else if (np->maxwide) np->sc_link.adapter_buswidth = MAX_TARGET; -#endif -#else /* !__NetBSD__ */ +#endif /* __OpenBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ np->sc_link.adapter_unit = unit; np->sc_link.adapter_softc = np; np->sc_link.adapter_targ = np->myaddr; np->sc_link.fordriver = 0; -#endif /* !__NetBSD__ */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ np->sc_link.adapter = &ncr_switch; np->sc_link.device = &ncr_dev; np->sc_link.flags = 0; #if defined(__NetBSD__) || defined(__OpenBSD__) config_found(self, &np->sc_link, scsiprint); -#else +#else /* !(__NetBSD__ || __OpenBSD__) */ #if (__FreeBSD__ >= 2) scbus = scsi_alloc_bus(); if(!scbus) @@ -3674,7 +3726,7 @@ static void ncr_attach (pcici_t config_id, int unit) #else scsi_attachdevs (&np->sc_link); #endif /* !__FreeBSD__ >= 2 */ -#endif /* !__NetBSD__ */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ /* ** start the timeout daemon @@ -3705,9 +3757,9 @@ static void ncr_attach (pcici_t config_id, int unit) #if defined(__NetBSD__) || defined(__OpenBSD__) static int -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ static void -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ ncr_intr(vnp) void *vnp; { @@ -3830,8 +3882,9 @@ static INT32 ncr_start (struct scsi_xfer * xp) if (DEBUG_FLAGS & DEBUG_TINY) { PRINT_ADDR(xp); - printf ("CMD=%x F=%p A=%p L=%p ", - cmd->opcode, xp->flags, xp->data, xp->datalen); + printf ("CMD=%x F=%x A=%p L=%x ", + cmd->opcode, (unsigned)xp->flags, xp->data, + (unsigned)xp->datalen); } /*-------------------------------------------- @@ -3935,9 +3988,9 @@ static INT32 ncr_start (struct scsi_xfer * xp) if (!nego && !tp->period) { if (SCSI_NCR_MAX_SYNC -#if defined (CDROM_ASYNC) || defined (GENERIC) +#ifdef NCR_CDROM_ASYNC && ((tp->inqdata[0] & 0x1f) != 5) -#endif +#endif /* NCR_CDROM_ASYNC */ && (tp->inqdata[7] & INQ7_SYNC)) { nego = NS_SYNC; } else { @@ -4058,7 +4111,7 @@ static INT32 ncr_start (struct scsi_xfer * xp) **---------------------------------------------------- */ - segments = ncr_scatter (np, &cp->phys, (vm_offset_t) xp->data, + segments = ncr_scatter (&cp->phys, (vm_offset_t) xp->data, (vm_size_t) xp->datalen); if (segments < 0) { @@ -4203,9 +4256,9 @@ static INT32 ncr_start (struct scsi_xfer * xp) #if defined(__NetBSD__) || defined(__OpenBSD__) if (!(flags & SCSI_POLL)) { -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ if (!(flags & SCSI_NOMASK)) { -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ if (np->lasttime) { if(DEBUG_FLAGS & DEBUG_TINY) printf ("Q"); return(SUCCESSFULLY_QUEUED); @@ -4256,9 +4309,9 @@ static INT32 ncr_start (struct scsi_xfer * xp) }; #if defined(__NetBSD__) || defined(__OpenBSD__) if (!(flags & SCSI_POLL)) -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ if (!(flags & SCSI_NOMASK)) -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ return (SUCCESSFULLY_QUEUED); switch (xp->error) { case 0 : return (COMPLETE); @@ -4307,8 +4360,7 @@ void ncr_complete (ncb_p np, ccb_p cp) ncb_profile (np, cp); if (DEBUG_FLAGS & DEBUG_TINY) - printf ("CCB=%p STAT=%x/%x\n", - (caddr_t)((vm_offset_t)cp & 0xfff), + printf ("CCB=%lx STAT=%x/%x\n", (unsigned long)cp & 0xfff, cp->host_status,cp->scsi_status); xp = cp->xfer; @@ -4326,7 +4378,7 @@ void ncr_complete (ncb_p np, ccb_p cp) /* ** fallback to asynch transfer. */ - tp->usrsync=255; + tp->usrsync = 255; tp->period = 0; }; @@ -4347,7 +4399,7 @@ void ncr_complete (ncb_p np, ccb_p cp) printf ("extended error %d.\n", cp->xerr_status); break; }; - if (cp->host_status==HS_COMPLETE) + if (cp->host_status == HS_COMPLETE) cp->host_status = HS_FAIL; }; @@ -4361,7 +4413,7 @@ void ncr_complete (ncb_p np, ccb_p cp) ** Don't override the error value. */ } else -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ if ( (cp->host_status == HS_COMPLETE) && (cp->scsi_status == S_GOOD)) { @@ -4389,7 +4441,7 @@ void ncr_complete (ncb_p np, ccb_p cp) /* ** On inquire cmd (0x12) save some data. */ - if (xp->cmd->opcode == 0x12) { + if (xp->cmd->opcode == 0x12 && xp->sc_link->lun == 0) { bcopy ( xp->data, &tp->inqdata, sizeof (tp->inqdata)); @@ -4428,7 +4480,7 @@ void ncr_complete (ncb_p np, ccb_p cp) ** Not correct, but errors expected. */ xp->resid = 0; -#endif /* !__NetBSD__ */ +#endif /* !(__NetBSD__ || __OpenBSD__) */ } else if ((cp->host_status == HS_COMPLETE) && (cp->scsi_status == (S_SENSE|S_GOOD))) { @@ -4622,29 +4674,36 @@ void ncr_init (ncb_p np, char * msg, u_long code) ** Init chip. */ -#if !(defined(__NetBSD__) || defined(__OpenBSD__)) - if (pci_max_burst_len < 4) { - static u_char tbl[4]={0,0,0x40,0x80}; - burstlen = tbl[pci_max_burst_len]; - } else burstlen = 0xc0; -#else /* !__NetBSD__ */ - burstlen = 0xc0; -#endif /* __NetBSD__ */ - - OUTB (nc_istat, 0 ); /* Remove Reset, abort ... */ + burstlen = 0xc0; /* XXX 53c875 needs code change to */ + /* be able to use larger bursts */ + + OUTB (nc_istat, 0x00 ); /* Remove Reset, abort ... */ OUTB (nc_scntl0, 0xca ); /* full arb., ena parity, par->ATN */ OUTB (nc_scntl1, 0x00 ); /* odd parity, and remove CRST!! */ OUTB (nc_scntl3, np->rv_scntl3);/* timing prescaler */ OUTB (nc_scid , RRE|np->myaddr);/* host adapter SCSI address */ OUTW (nc_respid, 1ul<<np->myaddr);/* id to respond to */ OUTB (nc_istat , SIGP ); /* Signal Process */ - OUTB (nc_dmode , burstlen); /* Burst length = 2 .. 16 transfers */ - OUTB (nc_dcntl , NOCOM ); /* no single step mode, protect SFBR*/ - OUTB (nc_ctest4, 0x08 ); /* enable master parity checking */ + OUTB (nc_dmode , np->rv_dmode); /* XXX modify burstlen ??? */ + OUTB (nc_dcntl , np->rv_dcntl); + OUTB (nc_ctest3, np->rv_ctest3); + OUTB (nc_ctest5, np->rv_ctest5); + OUTB (nc_ctest4, MPEE ); /* enable master parity checking */ OUTB (nc_stest2, EXT ); /* Extended Sreq/Sack filtering */ OUTB (nc_stest3, TE ); /* TolerANT enable */ OUTB (nc_stime0, 0x0b ); /* HTH = disabled, STO = 0.1 sec. */ +#ifdef __FreeBSD__ + if (bootverbose) { + printf ("\tBIOS values: dmode: %02x, dcntl: %02x, ctest3: %02x\n", + np->rv_dmode, np->rv_dcntl, np->rv_ctest3); + printf ("\tdmode: %02x/%02x, dcntl: %02x/%02x, ctest3: %02x/%02x\n", + burstlen | ERL | ERMP | BOF, INB (nc_dmode), + CLSE | PFEN | NOCOM, INB (nc_dcntl), + WRIE, INB (nc_ctest3)); + } +#endif /* __FreeBSD__ */ + /* ** Reinitialize usrsync. ** Have to renegotiate synch mode. @@ -4722,8 +4781,6 @@ static void ncr_negotiate (struct ncb* np, struct tcb* tp) u_long minsync = tp->usrsync; - if (minsync < 25) minsync=25; - /* ** if not scsi 2 ** don't believe FAST! @@ -4747,7 +4804,7 @@ static void ncr_negotiate (struct ncb* np, struct tcb* tp) minsync = 255; tp->minsync = minsync; - tp->maxoffs = (minsync<255 ? 8 : 0); + tp->maxoffs = (minsync<255 ? np->maxoffs : 0); /* ** period=0: has to negotiate sync transfer @@ -4783,7 +4840,7 @@ static void ncr_setsync (ncb_p np, ccb_p cp, u_char sxfer) assert (target == (xp->sc_link->target & 0x0f)); tp = &np->target[target]; - tp->period= sxfer&0xf ? ((sxfer>>5)+4) * np->ns_sync : 0xffff; + tp->period= sxfer&0x1f ? ((sxfer>>5)+4) * np->ns_sync : 0xffff; if (tp->sval == sxfer) return; tp->sval = sxfer; @@ -4792,15 +4849,15 @@ static void ncr_setsync (ncb_p np, ccb_p cp, u_char sxfer) ** Bells and whistles ;-) */ PRINT_ADDR(xp); - if (sxfer & 0x0f) { + if (sxfer & 0x1f) { + unsigned f10 = 10000 << (tp->widedone ? tp->widedone -1 : 0); + unsigned mb10 = (f10 + tp->period/2) / tp->period; /* ** Disable extended Sreq/Sack filtering */ if (tp->period <= 200) OUTB (nc_stest2, 0); - printf ("%s%dns (%d Mb/sec) offset %d.\n", - tp->period<200 ? "FAST SCSI-2 ":"", - tp->period, (1000+tp->period/2)/tp->period, - sxfer & 0x0f); + printf ("%d.%d MB/s (%d ns, offset %d)\n", + mb10 / 10, mb10 % 10, tp->period, sxfer & 0x1f); } else printf ("asynchronous.\n"); /* @@ -5049,30 +5106,11 @@ static void ncr_timeout (ncb_p np) ** If there are no requests, the script ** processor will sleep on SEL_WAIT_RESEL. ** But we have to check whether it died. - ** Let's wake it up. + ** Let's try to wake it up. */ OUTB (nc_istat, SIGP); }; -#ifdef undef - if (np->latetime>4) { - /* - ** Although we tried to wake it up, - ** the script processor didn't respond. - ** - ** May be a target is hanging, - ** or another initator lets a tape device - ** rewind with disconnect disabled :-( - ** - ** We won't accept that. - */ - if (INB (nc_sbcl) & CBSY) - OUTB (nc_scntl1, CRST); - DELAY (1000); - ncr_init (np, "ncr dead ?", HS_TIMEOUT); - np->heartbeat = thistime; - }; -#endif /*---------------------------------------------------- ** ** handle ccb timeouts @@ -5176,8 +5214,8 @@ void ncr_exception (ncb_p np) ** Never test for an error condition you don't know how to handle. */ + sist = (istat & SIP) ? INW (nc_sist) : 0; dstat = (istat & DIP) ? INB (nc_dstat) : 0; - sist = (istat & SIP) ? INW (nc_sist) : 0; np->profile.num_int++; if (DEBUG_FLAGS & DEBUG_TINY) @@ -5338,7 +5376,8 @@ void ncr_exception (ncb_p np) !(dstat & DFE)) { printf ("%s: have to clear fifos.\n", ncr_name (np)); OUTB (nc_stest3, TE|CSF); /* clear scsi fifo */ - OUTB (nc_ctest3, CLF); /* clear dma fifo */ + OUTB (nc_ctest3, np->rv_ctest3 | CLF); + /* clear dma fifo */ } /*---------------------------------------- @@ -5386,7 +5425,7 @@ void ncr_exception (ncb_p np) ** It's an early reconnect. ** Let's continue ... */ - OUTB (nc_dcntl, (STD|NOCOM)); + OUTB (nc_dcntl, np->rv_dcntl | STD); /* ** info message */ @@ -5411,7 +5450,7 @@ void ncr_exception (ncb_p np) if ((dstat & SSI) && !(sist & (STO|GEN|HTH|MA|SGE|UDC|RST|PAR)) && !(dstat & (MDPE|BF|ABRT|SIR|IID))) { - OUTB (nc_dcntl, (STD|NOCOM)); + OUTB (nc_dcntl, np->rv_dcntl | STD); return; }; @@ -5424,7 +5463,8 @@ void ncr_exception (ncb_p np) */ if (sist & SGE) { - OUTB (nc_ctest3, CLF); /* clear scsi offsets */ + /* clear scsi offsets */ + OUTB (nc_ctest3, np->rv_ctest3 | CLF); } /* @@ -5584,8 +5624,8 @@ static void ncr_int_ma (ncb_p np) if (ss2 & OLF1) rest++; if (ss2 & ORF1) rest++; }; - OUTB (nc_ctest3, CLF ); /* clear dma fifo */ - OUTB (nc_stest3, TE|CSF); /* clear scsi fifo */ + OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ + OUTB (nc_stest3, TE|CSF); /* clear scsi fifo */ /* ** locate matching cp @@ -5676,7 +5716,7 @@ static void ncr_int_ma (ncb_p np) cmd&7, sbcl&7, (unsigned)olen, (unsigned)oadr, (unsigned)rest); - OUTB (nc_dcntl, (STD|NOCOM)); + OUTB (nc_dcntl, np->rv_dcntl | STD); return; }; @@ -5699,8 +5739,8 @@ static void ncr_int_ma (ncb_p np) if (DEBUG_FLAGS & DEBUG_PHASE) { PRINT_ADDR(cp->xfer); - printf ("newcmd[%d] %x %x %x %x.\n", - newcmd - cp->patch, + printf ("newcmd[%ld] %x %x %x %x.\n", + (long)(newcmd - cp->patch), (unsigned)newcmd[0], (unsigned)newcmd[1], (unsigned)newcmd[2], @@ -6319,7 +6359,7 @@ void ncr_int_sir (ncb_p np) }; out: - OUTB (nc_dcntl, (STD|NOCOM)); + OUTB (nc_dcntl, np->rv_dcntl | STD); } /*========================================================== @@ -6336,7 +6376,9 @@ static ccb_p ncr_get_ccb { lcb_p lp; ccb_p cp = (ccb_p) 0; + int oldspl; + oldspl = splhigh(); /* ** Lun structure available ? */ @@ -6349,7 +6391,9 @@ static ccb_p ncr_get_ccb ** Look for free CCB */ - while (cp && cp->magic) cp = cp->next_ccb; + while (cp && cp->magic) { + cp = cp->next_ccb; + } } /* @@ -6368,10 +6412,13 @@ static ccb_p ncr_get_ccb break; }; - if (cp->magic) + if (cp->magic) { + splx(oldspl); return ((ccb_p) 0); + } cp->magic = 1; + splx(oldspl); return (cp); } @@ -6575,12 +6622,12 @@ static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp) diff = xp->sc_link->openings; xp->sc_link->openings -= diff; -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ if (diff > xp->sc_link->opennings) diff = xp->sc_link->opennings; xp->sc_link->opennings -= diff; -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ lp->actlink -= diff; if (DEBUG_FLAGS & DEBUG_TAGS) printf ("%s: actlink: diff=%d, new=%d, req=%d\n", @@ -6596,9 +6643,9 @@ static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp) #if defined(__NetBSD__) || defined(__OpenBSD__) xp->sc_link->openings += diff; -#else /* !__NetBSD__ */ +#else /* !(__NetBSD__ || __OpenBSD__) */ xp->sc_link->opennings += diff; -#endif /* __NetBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ lp->actlink += diff; wakeup ((caddr_t) xp->sc_link); if (DEBUG_FLAGS & DEBUG_TAGS) @@ -6624,7 +6671,7 @@ static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp) */ static int ncr_scatter - (ncb_p np, struct dsb* phys, vm_offset_t vaddr, vm_size_t datalen) + (struct dsb* phys, vm_offset_t vaddr, vm_size_t datalen) { u_long paddr, pnext; @@ -6812,6 +6859,9 @@ static int ncr_snooptest (struct ncb* np) */ if (pc != NCB_SCRIPT_PHYS (np, snoopend)+8) { printf ("CACHE TEST FAILED: script execution failed.\n"); + printf ("\tstart=%08lx, pc=%08lx, end=%08lx\n", + NCB_SCRIPT_PHYS (np, snooptest), pc, + NCB_SCRIPT_PHYS (np, snoopend) +8); return (0x40); }; /* @@ -6994,81 +7044,192 @@ ncrgetfreq (ncb_p np, int gen) * Measure GEN timer delay in order * to calculate SCSI clock frequency * - * This code will never execute too - * many loop iterations (if DELAY is - * reasonably correct). It could get - * too low a delay (too high a freq.) - * if the CPU is slow executing the - * loop for some reason (an NMI, for - * example). For this reason we will - * if multiple measurements are to be - * performed trust the higher delay - * (lower frequency returned). - */ - OUTB (nc_stest1, 0); /* make sure clock doubler is OFF */ - OUTW (nc_sien , 0); /* mask all scsi interrupts */ - (void) INW (nc_sist); /* clear pending scsi interrupt */ - OUTB (nc_dien , 0); /* mask all dma interrupts */ - (void) INW (nc_sist); /* another one, just to be sure :) */ - OUTB (nc_scntl3, 4); /* set pre-scaler to divide by 3 */ - OUTB (nc_stime1, 0); /* disable general purpose timer */ - OUTB (nc_stime1, gen); /* set to nominal delay of (1<<gen) * 125us */ - while (!(INW(nc_sist) & GEN) && ms++ < 1000) - DELAY(1000); /* count ms */ - OUTB (nc_stime1, 0); /* disable general purpose timer */ - OUTB (nc_scntl3, 0); - /* - * Set prescaler to divide by whatever "0" means. - * "0" ought to choose divide by 2, but appears - * to set divide by 3.5 mode in my 53c810 ... - */ - OUTB (nc_scntl3, 0); - - if (bootverbose) - printf ("\tDelay (GEN=%d): %u msec\n", gen, ms); - /* - * adjust for prescaler, and convert into KHz - */ - return ms ? ((1 << gen) * 4440) / ms : 0; - } - - static void ncr_getclock (ncb_p np) - { - unsigned char scntl3; - unsigned char stest1; - scntl3 = INB(nc_scntl3); - stest1 = INB(nc_stest1); - - /* always false, except for 875 with clock doubler selected */ - if ((stest1 & (DBLEN+DBLSEL)) == DBLEN+DBLSEL) { - OUTB(nc_stest1, 0); - scntl3 = 3; - } else { - if ((scntl3 & 7) == 0) { - unsigned f1, f2; - /* throw away first result */ - (void) ncrgetfreq (np, 11); - f1 = ncrgetfreq (np, 11); - f2 = ncrgetfreq (np, 11); - - if (bootverbose) - printf ("\tNCR clock is %uKHz, %uKHz\n", f1, f2); - if (f1 > f2) f1 = f2; /* trust lower result */ - if (f1 > 45000) { - scntl3 = 5; /* >45Mhz: assume 80MHz */ - } else { - scntl3 = 3; /* <45Mhz: assume 40MHz */ - } - } - } - - np->rv_scntl3 = ((scntl3 & 0x7) << 4) -0x20 + (scntl3 & 0x7); - - if (bootverbose) { - printf ("\tinitial value of SCNTL3 = %02x, final = %02x\n", - scntl3, np->rv_scntl3); - } + * This code will never execute too + * many loop iterations (if DELAY is + * reasonably correct). It could get + * too low a delay (too high a freq.) + * if the CPU is slow executing the + * loop for some reason (an NMI, for + * example). For this reason we will + * if multiple measurements are to be + * performed trust the higher delay + * (lower frequency returned). + */ + OUTB (nc_stest1, 0); /* make sure clock doubler is OFF */ + OUTW (nc_sien , 0); /* mask all scsi interrupts */ + (void) INW (nc_sist); /* clear pending scsi interrupt */ + OUTB (nc_dien , 0); /* mask all dma interrupts */ + (void) INW (nc_sist); /* another one, just to be sure :) */ + OUTB (nc_scntl3, 4); /* set pre-scaler to divide by 3 */ + OUTB (nc_stime1, 0); /* disable general purpose timer */ + OUTB (nc_stime1, gen); /* set to nominal delay of (1<<gen) * 125us */ + while (!(INW(nc_sist) & GEN) && ms++ < 1000) + DELAY(1000); /* count ms */ + OUTB (nc_stime1, 0); /* disable general purpose timer */ + OUTB (nc_scntl3, 0); + /* + * Set prescaler to divide by whatever "0" means. + * "0" ought to choose divide by 2, but appears + * to set divide by 3.5 mode in my 53c810 ... + */ + OUTB (nc_scntl3, 0); + + if (bootverbose) + printf ("\tDelay (GEN=%d): %u msec\n", gen, ms); + /* + * adjust for prescaler, and convert into KHz + */ + return ms ? ((1 << gen) * 4440) / ms : 0; +} + +static void ncr_getclock (ncb_p np) +{ + unsigned char scntl3; + unsigned char stest1; + scntl3 = INB(nc_scntl3); + stest1 = INB(nc_stest1); + + /* always false, except for 875 with clock doubler selected */ + if ((stest1 & (DBLEN+DBLSEL)) == DBLEN+DBLSEL) { + OUTB(nc_stest1, 0); + scntl3 = 3; + } else { + if ((scntl3 & 7) == 0) { + unsigned f1, f2; + /* throw away first result */ + (void) ncrgetfreq (np, 11); + f1 = ncrgetfreq (np, 11); + f2 = ncrgetfreq (np, 11); + + if (bootverbose) + printf ("\tNCR clock is %uKHz, %uKHz\n", f1, f2); + if (f1 > f2) f1 = f2; /* trust lower result */ + if (f1 > 45000) { + scntl3 = 5; /* >45Mhz: assume 80MHz */ + } else { + scntl3 = 3; /* <45Mhz: assume 40MHz */ + } + } + } + + np->rv_scntl3 = ((scntl3 & 0x7) << 4) -0x20 + (scntl3 & 0x7); + + if (bootverbose) { + printf ("\tinitial value of SCNTL3 = %02x, final = %02x\n", + scntl3, np->rv_scntl3); + } +} + +/*=========================================================================*/ + +#ifdef NCR_TEKRAM_EEPROM + +struct tekram_eeprom_dev { + u_char devmode; +#define TKR_PARCHK 0x01 +#define TKR_TRYSYNC 0x02 +#define TKR_ENDISC 0x04 +#define TKR_STARTUNIT 0x08 +#define TKR_USETAGS 0x10 +#define TKR_TRYWIDE 0x20 + u_char syncparam; /* max. sync transfer rate (table ?) */ + u_char filler1; + u_char filler2; +}; + + +struct tekram_eeprom { + struct tekram_eeprom_dev + dev[16]; + u_char adaptid; + u_char adaptmode; +#define TKR_ADPT_GT2DRV 0x01 +#define TKR_ADPT_GT1GB 0x02 +#define TKR_ADPT_RSTBUS 0x04 +#define TKR_ADPT_ACTNEG 0x08 +#define TKR_ADPT_NOSEEK 0x10 +#define TKR_ADPT_MORLUN 0x20 + u_char delay; /* unit ? (table ???) */ + u_char tags; /* use 4 times as many ... */ + u_char filler[60]; +}; + +static void +tekram_write_bit (ncb_p np, int bit) +{ + u_char val = 0x10 + ((bit & 1) << 1); + + DELAY(10); + OUTB (nc_gpreg, val); + DELAY(10); + OUTB (nc_gpreg, val | 0x04); + DELAY(10); + OUTB (nc_gpreg, val); + DELAY(10); +} + +static int +tekram_read_bit (ncb_p np) +{ + OUTB (nc_gpreg, 0x10); + DELAY(10); + OUTB (nc_gpreg, 0x14); + DELAY(10); + return INB (nc_gpreg) & 1; +} + +static u_short +read_tekram_eeprom_reg (ncb_p np, int reg) +{ + int bit; + u_short result = 0; + int cmd = 0x80 | reg; + + OUTB (nc_gpreg, 0x10); + + tekram_write_bit (np, 1); + for (bit = 7; bit >= 0; bit--) + { + tekram_write_bit (np, cmd >> bit); + } + + for (bit = 0; bit < 16; bit++) + { + result <<= 1; + result |= tekram_read_bit (np); + } + + OUTB (nc_gpreg, 0x00); + return result; +} + +static int +read_tekram_eeprom(ncb_p np, struct tekram_eeprom *buffer) +{ + u_short *p = (u_short *) buffer; + u_short sum = 0; + int i; + + if (INB (nc_gpcntl) != 0x09) + { + return 0; + } + for (i = 0; i < 64; i++) + { + u_short val; +if((i&0x0f) == 0) printf ("%02x:", i*2); + val = read_tekram_eeprom_reg (np, i); + if (p) + *p++ = val; + sum += val; +if((i&0x01) == 0x00) printf (" "); + printf ("%02x%02x", val & 0xff, (val >> 8) & 0xff); +if((i&0x0f) == 0x0f) printf ("\n"); + } +printf ("Sum = %04x\n", sum); + return sum == 0x1234; } +#endif /* NCR_TEKRAM_EEPROM */ /*=========================================================================*/ #endif /* KERNEL */ |