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 + -
显示快捷键?