?? ncr.c
字號:
/* $OpenBSD: ncr.c,v 1.46 1999/06/06 23:17:24 deraadt Exp $ *//* $NetBSD: ncr.c,v 1.63 1997/09/23 02:39:15 perry Exp $ *//****************************************************************************** Id: ncr.c,v 1.112 1997/11/07 09:20:56 phk Exp**** Device driver for the NCR 53C8xx PCI-SCSI-Controller.**** FreeBSD / NetBSD / OpenBSD****-------------------------------------------------------------------------**** Written for 386bsd and FreeBSD by** Wolfgang Stanglmeier <wolf@cologne.de>** Stefan Esser <se@mi.Uni-Koeln.de>**** Ported to NetBSD by** Charles M. Hannum <mycroft@gnu.ai.mit.edu>**** Modified for big endian systems by** Per Fogelstrom for RTMX Inc, North Carolina. <pefo@opsycon.se>****-------------------------------------------------------------------------**** Copyright (c) 1994 Wolfgang Stanglmeier. All rights reserved.**** Redistribution and use in source and binary forms, with or without** modification, are permitted provided that the following conditions** are met:** 1. Redistributions of source code must retain the above copyright** notice, this list of conditions and the following disclaimer.** 2. Redistributions in binary form must reproduce the above copyright** notice, this list of conditions and the following disclaimer in the** documentation and/or other materials provided with the distribution.** 3. The name of the author may not be used to endorse or promote products** derived from this software without specific prior written permission.**** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.******************************************************************************/#define NCR_DATE "pl24 96/12/14"#define NCR_VERSION (2)#define MAX_UNITS (16)#define NCR_GETCC_WITHMSG#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)#endif /* SCSI_NCR_DFLT_TAGS */#define NCR_CDROM_ASYNC#endif /* FAILSAFE *//*==========================================================**** Configuration and Debugging**** May be overwritten in <arch/conf/xxxx>****==========================================================*//*** SCSI address of this device.** The boot routines should have set it.** If not, use this.*/#ifndef SCSI_NCR_MYADDR#define SCSI_NCR_MYADDR (7)#endif /* SCSI_NCR_MYADDR *//*** The default synchronous period factor** (0=asynchronous)** If maximum synchronous frequency is defined, use it instead.*/#ifndef SCSI_NCR_MAX_SYNC#ifndef SCSI_NCR_DFLT_SYNC#define SCSI_NCR_DFLT_SYNC (12)#endif /* SCSI_NCR_DFLT_SYNC */#else#if SCSI_NCR_MAX_SYNC == 0#define SCSI_NCR_DFLT_SYNC 0#else#define SCSI_NCR_DFLT_SYNC (250000 / SCSI_NCR_MAX_SYNC)#endif#endif/*** The minimal asynchronous pre-scaler period (ns)** Shall be 40.*/#ifndef SCSI_NCR_MIN_ASYNC#define SCSI_NCR_MIN_ASYNC (40)#endif /* SCSI_NCR_MIN_ASYNC *//*** The maximal bus with (in log2 byte)** (0=8 bit, 1=16 bit)*/#ifndef SCSI_NCR_MAX_WIDE#define SCSI_NCR_MAX_WIDE (1)#endif /* SCSI_NCR_MAX_WIDE *//*** The maximum number of tags per logic unit.** Used only for disk devices that support tags.*/#ifndef SCSI_NCR_DFLT_TAGS#define SCSI_NCR_DFLT_TAGS (4)#endif /* SCSI_NCR_DFLT_TAGS *//*==========================================================**** Configuration and Debugging****==========================================================*//*** Number of targets supported by the driver.** n permits target numbers 0..n-1.** Default is 16, meaning targets #0..#15.** #7 is the host adapter.*/#define MAX_TARGET (16)/*** 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.** There should be one slot per target, and one slot** for each tag of each target in use.** The calculation below is actually quite silly ...*/#define MAX_START (MAX_TARGET + (MAX_TARGET - 1) * SCSI_NCR_DFLT_TAGS)/*** The maximum number of segments a transfer is split into.*/#define MAX_SCATTER (33)/*** The maximum transfer length (should be >= 64k).** MUST NOT be greater than (MAX_SCATTER-1) * PAGE_SIZE.*/#ifdef __OpenBSD__#define MAX_SIZE ((MAX_SCATTER-1) * (long) NBPG)#else#define MAX_SIZE ((MAX_SCATTER-1) * (long) PAGE_SIZE)#endif/*** other*/#define NCR_SNOOP_TIMEOUT (1000000)/*==========================================================**** Include files****==========================================================*/#ifdef __OpenBSD__#ifdef _KERNEL#define KERNEL#endif#else#include <stddef.h>#endif#define offsetof(type, member) ((size_t)(&((type *)0)->member))#include <sys/param.h>#include <sys/time.h>#ifdef KERNEL#include <sys/systm.h>#include <sys/malloc.h>#include <sys/buf.h>#include <sys/kernel.h>#ifndef __OpenBSD__#include <sys/sysctl.h>#include <machine/clock.h>#endif#include <vm/vm.h>#if 0#include <vm/pmap.h>#include <vm/vm_extern.h>#endif#endif /* KERNEL */#ifndef __OpenBSD__#include <pci/pcivar.h>#include <pci/pcireg.h>#include <pci/ncrreg.h>#else#include <sys/device.h>#include <machine/bus.h>#include <machine/intr.h>#include <dev/pci/ncrreg.h>#include <dev/pci/pcireg.h>#include <dev/pci/pcivar.h>#if !defined(__alpha__) && !defined(__mips__) && !defined(__powerpc__)#define DELAY(x) delay(x)#endif#include <scsi/scsi_all.h>#endif /* __OpenBSD__ */#include <scsi/scsiconf.h>#ifdef __OpenBSD__#define __BROKEN_INDIRECT_CONFIG#ifdef NCR_VERBOSE#define bootverbose NCR_VERBOSE#else#define bootverbose 0#endif#endif#if !defined(NCR_KVATOPHYS)#define NCR_KVATOPHYS(sc, va) vtophys(va)#endif#if defined(__OpenBSD__) && defined(__alpha__)/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */#undef vtophys#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))#endif/*==========================================================**** Debugging tags****==========================================================*/#define DEBUG_ALLOC (0x0001)#define DEBUG_PHASE (0x0002)#define DEBUG_POLL (0x0004)#define DEBUG_QUEUE (0x0008)#define DEBUG_RESULT (0x0010)#define DEBUG_SCATTER (0x0020)#define DEBUG_SCRIPT (0x0040)#define DEBUG_TINY (0x0080)#define DEBUG_TIMING (0x0100)#define DEBUG_NEGO (0x0200)#define DEBUG_TAGS (0x0400)#define DEBUG_FREEZE (0x0800)#define DEBUG_RESTART (0x1000)/*** Enable/Disable debug messages.** Can be changed at runtime too.*/#ifdef SCSI_NCR_DEBUG #define DEBUG_FLAGS ncr_debug#else /* SCSI_NCR_DEBUG */ #define SCSI_NCR_DEBUG 0 #define DEBUG_FLAGS 0#endif /* SCSI_NCR_DEBUG *//*==========================================================**** assert ()****==========================================================**** modified copy from 386bsd:/usr/include/sys/assert.h****----------------------------------------------------------*/#undef assert#define assert(expression) { \ if (!(expression)) { \ (void)printf(\ "assertion \"%s\" failed: file \"%s\", line %d\n", \ #expression, \ __FILE__, __LINE__); \ } \}/*==========================================================**** Access to the controller chip.****==========================================================*/#ifdef __OpenBSD__#define INB(r) \ INB_OFF(offsetof(struct ncr_reg, r))#define INB_OFF(o) \ bus_space_read_1 (np->sc_st, np->sc_sh, (o))#define INW(r) \ bus_space_read_2 (np->sc_st, np->sc_sh, offsetof(struct ncr_reg, r))#define INL(r) \ INL_OFF(offsetof(struct ncr_reg, r))#define INL_OFF(o) \ bus_space_read_4 (np->sc_st, np->sc_sh, (o))#define OUTB(r, val) \ bus_space_write_1 (np->sc_st, np->sc_sh, offsetof(struct ncr_reg, r), (val))#define OUTW(r, val) \ bus_space_write_2 (np->sc_st, np->sc_sh, offsetof(struct ncr_reg, r), (val))#define OUTL(r, val) \ OUTL_OFF(offsetof(struct ncr_reg, r), (val))#define OUTL_OFF(o, val) \ bus_space_write_4 (np->sc_st, np->sc_sh, (o), (val))#define READSCRIPT_OFF(base, off) \ SCR_BO(base ? *((int32_t *)((char *)base + (off))) : \ bus_space_read_4 (np->ram_tag, np->ram_handle, off))#define WRITESCRIPT_OFF(base, off, val) \ do { \ if (base) \ *((int32_t *)((char *)base + (off))) = (SCR_BO(val)); \ else \ bus_space_write_4 (np->ram_tag, np->ram_handle, off, SCR_BO(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 /* !__OpenBSD__ */#ifdef NCR_IOMAPPED#define INB(r) inb (np->port + offsetof(struct ncr_reg, r))#define INB_OFF(o) inb (np->port + (o))#define INW(r) inw (np->port + offsetof(struct ncr_reg, r))#define INL(r) inl (np->port + offsetof(struct ncr_reg, r))#define INL_OFF(o) inl (np->port + (o))#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))#else#define INB(r) (np->reg->r)#define INB_OFF(o) (*((volatile int8_t *)((char *)np->reg + (o))))#define INW(r) (np->reg->r)#define INL(r) (np->reg->r)#define INL_OFF(o) (*((volatile int32_t *)((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 OUTL_OFF(o, val) *((volatile int32_t *)((char *)np->reg + (o))) = val#endif#define READSCRIPT_OFF(base, off) (*((int32_t *)((char *)base + (off))))#define READSCRIPT(r) (np->script->r)#define WRITESCRIPT(r, val) np->script->r = (val)#endif /* __OpenBSD__ *//*** Set bit field ON, OFF*/#define OUTONB(r, m) OUTB(r, INB(r) | (m))#define OUTOFFB(r, m) OUTB(r, INB(r) & ~(m))#define OUTONW(r, m) OUTW(r, INW(r) | (m))#define OUTOFFW(r, m) OUTW(r, INW(r) & ~(m))#define OUTONL(r, m) OUTL(r, INL(r) | (m))#define OUTOFFL(r, m) OUTL(r, INL(r) & ~(m))/*==========================================================**** Command control block states.****==========================================================*/#define HS_IDLE (0)#define HS_BUSY (1)#define HS_NEGOTIATE (2) /* sync/wide data transfer*/#define HS_DISCONNECT (3) /* Disconnected by target */#define HS_COMPLETE (4)#define HS_SEL_TIMEOUT (5) /* Selection timeout */#define HS_RESET (6) /* SCSI reset */#define HS_ABORTED (7) /* Transfer aborted */#define HS_TIMEOUT (8) /* Software timeout */#define HS_FAIL (9) /* SCSI or PCI bus errors */#define HS_UNEXPECTED (10) /* Unexpected disconnect */#define HS_DONEMASK (0xfc)/*==========================================================**** Software Interrupt Codes****==========================================================*/#define SIR_SENSE_RESTART (1)#define SIR_SENSE_FAILED (2)#define SIR_STALL_RESTART (3)#define SIR_STALL_QUEUE (4)#define SIR_NEGO_SYNC (5)#define SIR_NEGO_WIDE (6)#define SIR_NEGO_FAILED (7)#define SIR_NEGO_PROTO (8)#define SIR_REJECT_RECEIVED (9)#define SIR_REJECT_SENT (10)#define SIR_IGN_RESIDUE (11)#define SIR_MISSING_SAVE (12)#define SIR_MAX (12)/*==========================================================**** Extended error codes.** xerr_status field of struct ccb.****==========================================================*/#define XE_OK (0)#define XE_EXTRA_DATA (1) /* unexpected data phase */#define XE_BAD_PHASE (2) /* illegal phase (4/5) *//*==========================================================**** Negotiation status.** nego_status field of struct ccb.****==========================================================*/#define NS_SYNC (1)#define NS_WIDE (2)/*==========================================================**** "Special features" of targets.** quirks field of struct tcb.** actualquirks field of struct ccb.****==========================================================*/#define QUIRK_AUTOSAVE (0x01)#define QUIRK_NOMSG (0x02)#define QUIRK_NOSYNC (0x10)#define QUIRK_NOWIDE16 (0x20)#define QUIRK_NOTAGS (0x40)#define QUIRK_UPDATE (0x80)/*==========================================================**** Capability bits in Inquire response byte 7.****==========================================================*/#define INQ7_QUEUE (0x02)#define INQ7_SYNC (0x10)#define INQ7_WIDE16 (0x20)/*==========================================================**** Misc.****==========================================================*/#define CCB_MAGIC (0xf2691ad2)#define MAX_TAGS (16) /* hard limit *//*==========================================================**** OS dependencies.**** Note that various types are defined in ncrreg.h.****==========================================================*/#define PRINT_ADDR(xp) sc_print_addr(xp->sc_link)/*==========================================================**** Declaration of structs.****==========================================================*/struct tcb;struct lcb;struct ccb;struct ncb;struct script;typedef struct ncb * ncb_p;typedef struct tcb * tcb_p;typedef struct lcb * lcb_p;typedef struct ccb * ccb_p;struct link { ncrcmd l_cmd; ncrcmd l_paddr;};struct usrcmd { u_long target; u_long lun; u_long data; u_long cmd;};#define UC_SETSYNC 10#define UC_SETTAGS 11#define UC_SETDEBUG 12#define UC_SETORDER 13#define UC_SETWIDE 14#define UC_SETFLAG 15#define UF_TRACE (0x01)/*---------------------------------------**** Timestamps for profiling****---------------------------------------*/struct tstamp { struct timeval start; struct timeval end; struct timeval select; struct timeval command; struct timeval data; struct timeval status; struct timeval disconnect;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -