ncr.c
来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 2,919 行 · 第 1/5 页
C
2,919 行
/****************************************************************************** $Id: ncr.c,v 1.141.2.1 1999/05/07 00:43:45 ken Exp $**** Device driver for the NCR 53C8XX PCI-SCSI-Controller Family.****-------------------------------------------------------------------------**** Written for 386bsd and FreeBSD by** Wolfgang Stanglmeier <wolf@cologne.de>** Stefan Esser <se@mi.Uni-Koeln.de>****-------------------------------------------------------------------------**** 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 "pl30 98/1/1"#define NCR_VERSION (2)#define MAX_UNITS (16)#define NCR_GETCC_WITHMSG#if defined (__FreeBSD__) && defined(KERNEL)#include "opt_failsafe.h"#include "opt_ncr.h"#endif /* defined(KERNEL) *//*==========================================================**** 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 *//*==========================================================**** Configuration and Debugging****==========================================================*//*** Number of targets supported by the driver.** n permits target numbers 0..n-1.** Default is 7, meaning targets #0..#6.** #7 .. is myself.*/#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.*/#define MAX_START (256)/*** 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.*/#define MAX_SIZE ((MAX_SCATTER-1) * (long) PAGE_SIZE)/*** other*/#define NCR_SNOOP_TIMEOUT (1000000)/*==========================================================**** Include files****==========================================================*/#include <stddef.h>#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>#include <sys/sysctl.h>#include <machine/clock.h>#include <vm/vm.h>#include <vm/pmap.h>#include <vm/vm_extern.h>#endif /* KERNEL */#include <pci/pcivar.h>#include <pci/pcireg.h>#include <pci/ncrreg.h>#include <cam/cam.h>#include <cam/cam_ccb.h>#include <cam/cam_sim.h>#include <cam/cam_xpt_sim.h>#include <cam/cam_debug.h>#include <cam/scsi/scsi_all.h>#include <cam/scsi/scsi_message.h>/*==========================================================**** 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****----------------------------------------------------------*/#ifdef DIAGNOSTIC#define assert(expression) { \ if (!(expression)) { \ (void)printf("assertion \"%s\" failed: " \ "file \"%s\", line %d\n", \ #expression, __FILE__, __LINE__); \ Debugger(""); \ } \}#else#define assert(expression) { \ if (!(expression)) { \ (void)printf("assertion \"%s\" failed: " \ "file \"%s\", line %d\n", \ #expression, __FILE__, __LINE__); \ } \}#endif/*==========================================================**** Access to the controller chip.****==========================================================*/#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))#define INW(r) inw (np->port + offsetof(struct ncr_reg, r))#define INL(r) inl (np->port + offsetof(struct ncr_reg, r))#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)#define INW(r) (np->reg->r)#define INL(r) (np->reg->r)#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/*** 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_STALL (11) /* QUEUE FULL or BUSY */#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 nccb.****==========================================================*/#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 nccb.****==========================================================*/#define NS_SYNC (1)#define NS_WIDE (2)/*==========================================================**** XXX These are no longer used. Remove once the** script is updated.** "Special features" of targets.** quirks field of struct tcb.** actualquirks field of struct nccb.****==========================================================*/#define QUIRK_AUTOSAVE (0x01)#define QUIRK_NOMSG (0x02)#define QUIRK_NOSYNC (0x10)#define QUIRK_NOWIDE16 (0x20)#define QUIRK_NOTAGS (0x40)#define QUIRK_UPDATE (0x80)/*==========================================================**** Misc.****==========================================================*/#define CCB_MAGIC (0xf2691ad2)#define MAX_TAGS (32) /* hard limit *//*==========================================================**** OS dependencies.****==========================================================*/#define PRINT_ADDR(ccb) xpt_print_path((ccb)->ccb_h.path)/*==========================================================**** Declaration of structs.****==========================================================*/struct tcb;struct lcb;struct nccb;struct ncb;struct script;typedef struct ncb * ncb_p;typedef struct tcb * tcb_p;typedef struct lcb * lcb_p;typedef struct nccb * nccb_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****---------------------------------------*//* Type of the kernel variable `ticks'. XXX should be declared with the var. */typedef int ticks_t;struct tstamp { ticks_t start; ticks_t end; ticks_t select; ticks_t command; ticks_t data; ticks_t status; ticks_t disconnect;};/*** profiling data (per device)*/struct profile { u_long num_trans; u_long num_bytes; u_long num_disc; u_long num_break; u_long num_int; u_long num_fly; u_long ms_setup; u_long ms_data; u_long ms_disc; u_long ms_post;};/*==========================================================**** Declaration of structs: target control block****==========================================================*/#define NCR_TRANS_CUR 0x01 /* Modify current neogtiation status */#define NCR_TRANS_ACTIVE 0x03 /* Assume this is the active target */#define NCR_TRANS_GOAL 0x04 /* Modify negotiation goal */#define NCR_TRANS_USER 0x08 /* Modify user negotiation settings */struct ncr_transinfo { u_int8_t width; u_int8_t period; u_int8_t offset;};struct ncr_target_tinfo { /* Hardware version of our sync settings */ u_int8_t disc_tag;#define NCR_CUR_DISCENB 0x01#define NCR_CUR_TAGENB 0x02#define NCR_USR_DISCENB 0x04
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?