⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sym53c8xx.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
/********************************************************************************  High Performance device driver for the Symbios 53C896 controller.****  Copyright (C) 1998-2000  Gerard Roudier <groudier@club-internet.fr>****  This driver also supports all the Symbios 53C8XX controller family, **  except 53C810 revisions < 16, 53C825 revisions < 16 and all **  revisions of 53C815 controllers.****  This driver is based on the Linux port of the FreeBSD ncr driver.** **  Copyright (C) 1994  Wolfgang Stanglmeier**  **-----------------------------------------------------------------------------**  **  This program is free software; you can redistribute it and/or modify**  it under the terms of the GNU General Public License as published by**  the Free Software Foundation; either version 2 of the License, or**  (at your option) any later version.****  This program is distributed in the hope that it will be useful,**  but WITHOUT ANY WARRANTY; without even the implied warranty of**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the**  GNU General Public License for more details.****  You should have received a copy of the GNU General Public License**  along with this program; if not, write to the Free Software**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.****-----------------------------------------------------------------------------****  The Linux port of the FreeBSD ncr driver has been achieved in **  november 1995 by:****          Gerard Roudier              <groudier@club-internet.fr>****  Being given that this driver originates from the FreeBSD version, and**  in order to keep synergy on both, any suggested enhancements and corrections**  received on Linux are automatically a potential candidate for the FreeBSD **  version.****  The original driver has been written for 386bsd and FreeBSD by**          Wolfgang Stanglmeier        <wolf@cologne.de>**          Stefan Esser                <se@mi.Uni-Koeln.de>****-----------------------------------------------------------------------------****  Major contributions:**  --------------------****  NVRAM detection and reading.**    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>**********************************************************************************//***	May 11 2000, sym53c8xx 1.6b****	Supported SCSI features:**	    Synchronous data transfers**	    Wide16 SCSI BUS**	    Disconnection/Reselection**	    Tagged command queuing**	    SCSI Parity checking****	Supported NCR/SYMBIOS chips:**		53C810A	  (8 bits, Fast 10,	 no rom BIOS) **		53C825A	  (Wide,   Fast 10,	 on-board rom BIOS)**		53C860	  (8 bits, Fast 20,	 no rom BIOS)**		53C875	  (Wide,   Fast 20,	 on-board rom BIOS)**		53C876	  (Wide,   Fast 20 Dual, on-board rom BIOS)**		53C895	  (Wide,   Fast 40,	 on-board rom BIOS)**		53C895A	  (Wide,   Fast 40,	 on-board rom BIOS)**		53C896	  (Wide,   Fast 40 Dual, on-board rom BIOS)**		53C897	  (Wide,   Fast 40 Dual, on-board rom BIOS)**		53C1510D  (Wide,   Fast 40 Dual, on-board rom BIOS)**		53C1010	  (Wide,   Fast 80 Dual, on-board rom BIOS)**		53C1010_66(Wide,   Fast 80 Dual, on-board rom BIOS, 33/66MHz PCI)****	Other features:**		Memory mapped IO**		Module**		Shared IRQ*//***	Name and version of the driver*/#define SCSI_NCR_DRIVER_NAME	"sym53c8xx - version 1.6b"/* #define DEBUG_896R1 */#define SCSI_NCR_OPTIMIZE_896/* #define SCSI_NCR_OPTIMIZE_896_1 */#define SCSI_NCR_DEBUG_FLAGS	(0)#define NAME53C		"sym53c"#define NAME53C8XX	"sym53c8xx"/*==========================================================****      Include files****==========================================================*/#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))#include <linux/config.h>#ifdef MODULE#include <linux/module.h>#endif#include <asm/dma.h>#include <asm/io.h>#include <asm/system.h>#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)#include <linux/spinlock.h>#elif LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)#include <asm/spinlock.h>#endif#include <linux/delay.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/pci.h>#include <linux/string.h>#include <linux/malloc.h>#include <linux/mm.h>#include <linux/ioport.h>#include <linux/time.h>#include <linux/timer.h>#include <linux/stat.h>#include <linux/version.h>#include <linux/blk.h>#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,35)#include <linux/init.h>#endif#ifndef	__init#define	__init#endif#ifndef	__initdata#define	__initdata#endif#if LINUX_VERSION_CODE <= LinuxVersionCode(2,1,92)#include <linux/bios32.h>#endif#include "scsi.h"#include "hosts.h"#include "constants.h"#include "sd.h"#include <linux/types.h>/***	Define BITS_PER_LONG for earlier linux versions.*/#ifndef	BITS_PER_LONG#if (~0UL) == 0xffffffffUL#define	BITS_PER_LONG	32#else#define	BITS_PER_LONG	64#endif#endif/***	Define the BSD style u_int32 and u_int64 type.**	Are in fact u_int32_t and u_int64_t :-)*/typedef u32 u_int32;typedef u64 u_int64;#include "sym53c8xx.h"/***	Donnot compile integrity checking code for Linux-2.3.0 **	and above since SCSI data structures are not ready yet.*/#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,0)#define	SCSI_NCR_INTEGRITY_CHECKING#endif#define MIN(a,b)        (((a) < (b)) ? (a) : (b))#define MAX(a,b)        (((a) > (b)) ? (a) : (b))/***	Hmmm... What complex some PCI-HOST bridges actually are, **	despite the fact that the PCI specifications are looking **	so smart and simple! ;-)*/#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,47)#define SCSI_NCR_DYNAMIC_DMA_MAPPING#endif/*==========================================================****	A la VMS/CAM-3 queue management.**	Implemented from linux list management.****==========================================================*/typedef struct xpt_quehead {	struct xpt_quehead *flink;	/* Forward  pointer */	struct xpt_quehead *blink;	/* Backward pointer */} XPT_QUEHEAD;#define xpt_que_init(ptr) do { \	(ptr)->flink = (ptr); (ptr)->blink = (ptr); \} while (0)static inline void __xpt_que_add(struct xpt_quehead * new,	struct xpt_quehead * blink,	struct xpt_quehead * flink){	flink->blink	= new;	new->flink	= flink;	new->blink	= blink;	blink->flink	= new;}static inline void __xpt_que_del(struct xpt_quehead * blink,	struct xpt_quehead * flink){	flink->blink = blink;	blink->flink = flink;}static inline int xpt_que_empty(struct xpt_quehead *head){	return head->flink == head;}static inline void xpt_que_splice(struct xpt_quehead *list,	struct xpt_quehead *head){	struct xpt_quehead *first = list->flink;	if (first != list) {		struct xpt_quehead *last = list->blink;		struct xpt_quehead *at   = head->flink;		first->blink = head;		head->flink  = first;		last->flink = at;		at->blink   = last;	}}#define xpt_que_entry(ptr, type, member) \	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))#define xpt_insque(new, pos)		__xpt_que_add(new, pos, (pos)->flink)#define xpt_remque(el)			__xpt_que_del((el)->blink, (el)->flink)#define xpt_insque_head(new, head)	__xpt_que_add(new, head, (head)->flink)static inline struct xpt_quehead *xpt_remque_head(struct xpt_quehead *head){	struct xpt_quehead *elem = head->flink;	if (elem != head)		__xpt_que_del(head, elem->flink);	else		elem = 0;	return elem;}#define xpt_insque_tail(new, head)	__xpt_que_add(new, (head)->blink, head)static inline struct xpt_quehead *xpt_remque_tail(struct xpt_quehead *head){	struct xpt_quehead *elem = head->blink;	if (elem != head)		__xpt_que_del(elem->blink, head);	else		elem = 0;	return elem;}/*==========================================================****	On x86 architecture, write buffers management does **	not reorder writes to memory. So, using compiler **	optimization barriers is enough to guarantee some **	ordering when the CPU is writing data accessed by **	the NCR.**	On Alpha architecture, explicit memory barriers have **	to be used.**	Other architectures are defaulted to mb() macro if  **	defined, otherwise use compiler barrier.****==========================================================*/#if defined(__i386__)#define MEMORY_BARRIER()	barrier()#elif defined(__alpha__)#define MEMORY_BARRIER()	mb()#else#  ifdef mb#  define MEMORY_BARRIER()	mb()#  else#  define MEMORY_BARRIER()	barrier()#  endif#endif/*==========================================================****	Configuration and Debugging****==========================================================*//***    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/***    The maximum number of tags per logic unit.**    Used only for devices that support tags.*/#ifndef SCSI_NCR_MAX_TAGS#define SCSI_NCR_MAX_TAGS    (8)#endif/***    TAGS are actually unlimited (256 tags/lun).**    But Linux only supports 255. :)*/#if	SCSI_NCR_MAX_TAGS > 255#define	MAX_TAGS	255#else#define	MAX_TAGS SCSI_NCR_MAX_TAGS#endif/***    Since the ncr chips only have a 8 bit ALU, we try to be clever **    about offset calculation in the TASK TABLE per LUN that is an **    array of DWORDS = 4 bytes.*/#if	MAX_TAGS > (512/4)#define MAX_TASKS  (1024/4)#elif	MAX_TAGS > (256/4) #define MAX_TASKS  (512/4)#else#define MAX_TASKS  (256/4)#endif/***    This one means 'NO TAG for this job'*/#define NO_TAG	(256)/***    Number of targets supported by the driver.**    n permits target numbers 0..n-1.**    Default is 16, meaning targets #0..#15.**    #7 .. is myself.*/#ifdef SCSI_NCR_MAX_TARGET#define MAX_TARGET  (SCSI_NCR_MAX_TARGET)#else#define MAX_TARGET  (16)#endif/***    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.*/#ifdef SCSI_NCR_MAX_LUN#define MAX_LUN    64#else#define MAX_LUN    (1)#endif/***    Asynchronous pre-scaler (ns). Shall be 40 for **    the SCSI timings to be compliant.*/ #ifndef SCSI_NCR_MIN_ASYNC#define SCSI_NCR_MIN_ASYNC (40)#endif/***    The maximum number of jobs scheduled for starting.**    We allocate 4 entries more than the value we announce **    to the SCSI upper layer. Guess why ! :-)*/#ifdef SCSI_NCR_CAN_QUEUE#define MAX_START   (SCSI_NCR_CAN_QUEUE + 4)#else#define MAX_START   (MAX_TARGET + 7 * MAX_TAGS)#endif/***    We donnot want to allocate more than 1 PAGE for the **    the start queue and the done queue. We hard-code entry **    size to 8 in order to let cpp do the checking.**    Allows 512-4=508 pending IOs for i386 but Linux seems for **    now not able to provide the driver with this amount of IOs.*/#if	MAX_START > PAGE_SIZE/8#undef	MAX_START#define MAX_START (PAGE_SIZE/8)#endif/***    The maximum number of segments a transfer is split into.**    We support up to 127 segments for both read and write.*/#define MAX_SCATTER (SCSI_NCR_MAX_SCATTER)#define	SCR_SG_SIZE	(2)/***    Io mapped or memory mapped.*/#if defined(SCSI_NCR_IOMAPPED) || defined(SCSI_NCR_PCI_MEM_NOT_SUPPORTED)#define NCR_IOMAPPED#endif/***	other*/#define NCR_SNOOP_TIMEOUT (1000000)/*==========================================================****	Miscallaneous BSDish defines.****==========================================================*/#define u_char		unsigned char#define u_short		unsigned short#define u_int		unsigned int#define u_long		unsigned long#ifndef bcopy#define bcopy(s, d, n)	memcpy((d), (s), (n))#endif#ifndef bzero#define bzero(d, n)	memset((d), 0, (n))#endif #ifndef offsetof#define offsetof(t, m)	((size_t) (&((t *)0)->m))#endif/***	Simple Wrapper to kernel PCI bus interface.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -