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

📄 53c7xx.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * 53c710 driver.  Modified from Drew Eckhardts driver * for 53c810 by Richard Hirst [richard@sleepie.demon.co.uk] * Check out PERM_OPTIONS and EXPECTED_CLOCK, which may be defined in the * relevant machine specific file (eg. mvme16x.[ch], amiga7xx.[ch]). * There are also currently some defines at the top of 53c7xx.scr. * The chip type is #defined in script_asm.pl, as well as the Makefile. * Host scsi ID expected to be 7 - see NCR53c7x0_init(). * * I have removed the PCI code and some of the 53c8xx specific code -  * simply to make this file smaller and easier to manage. * * MVME16x issues: *   Problems trying to read any chip registers in NCR53c7x0_init(), as they *   may never have been set by 16xBug (eg. If kernel has come in over tftp). *//* * Adapted for Linux/m68k Amiga platforms for the A4000T/A4091 and * WarpEngine SCSI controllers. * By Alan Hourihane <alanh@fairlite.demon.co.uk> * Thanks to Richard Hirst for making it possible with the MVME additions *//* * 53c710 rev 0 doesn't support add with carry.  Rev 1 and 2 does.  To * overcome this problem you can define FORCE_DSA_ALIGNMENT, which ensures * that the DSA address is always xxxxxx00.  If disconnection is not allowed, * then the script only ever tries to add small (< 256) positive offsets to * DSA, so lack of carry isn't a problem.  FORCE_DSA_ALIGNMENT can, of course, * be defined for all chip revisions at a small cost in memory usage. */#define FORCE_DSA_ALIGNMENT/* * Selection timer does not always work on the 53c710, depending on the * timing at the last disconnect, if this is a problem for you, try * using validids as detailed below. * * Options for the NCR7xx driver * * noasync:0		-	disables sync and asynchronous negotiation * nosync:0		-	disables synchronous negotiation (does async) * nodisconnect:0	-	disables disconnection * validids:0x??	-	Bitmask field that disallows certain ID's. *			-	e.g.	0x03	allows ID 0,1 *			-		0x1F	allows ID 0,1,2,3,4 * opthi:n		-	replace top word of options with 'n' * optlo:n		-	replace bottom word of options with 'n' *			-	ALWAYS SPECIFY opthi THEN optlo <<<<<<<<<< *//* * PERM_OPTIONS are driver options which will be enabled for all NCR boards * in the system at driver initialization time. * * Don't THINK about touching these in PERM_OPTIONS :  *   OPTION_MEMORY_MAPPED  * 	680x0 doesn't have an IO map! * *   OPTION_DEBUG_TEST1 *	Test 1 does bus mastering and interrupt tests, which will help weed  *	out brain damaged main boards. * * Other PERM_OPTIONS settings are listed below.  Note the actual options * required are set in the relevant file (mvme16x.c, amiga7xx.c, etc): * *   OPTION_NO_ASYNC *	Don't negotiate for asynchronous transfers on the first command  *	when OPTION_ALWAYS_SYNCHRONOUS is set.  Useful for dain bramaged *	devices which do something bad rather than sending a MESSAGE  *	REJECT back to us like they should if they can't cope. * *   OPTION_SYNCHRONOUS *	Enable support for synchronous transfers.  Target negotiated  *	synchronous transfers will be responded to.  To initiate  *	a synchronous transfer request,  call  * *	    request_synchronous (hostno, target)  * *	from within KGDB. * *   OPTION_ALWAYS_SYNCHRONOUS *	Negotiate for synchronous transfers with every target after *	driver initialization or a SCSI bus reset.  This is a bit dangerous,  *	since there are some dain bramaged SCSI devices which will accept *	SDTR messages but keep talking asynchronously. * *   OPTION_DISCONNECT *	Enable support for disconnect/reconnect.  To change the  *	default setting on a given host adapter, call * *	    request_disconnect (hostno, allow) * *	where allow is non-zero to allow, 0 to disallow. *  *  If you really want to run 10MHz FAST SCSI-II transfers, you should  *  know that the NCR driver currently ignores parity information.  Most *  systems do 5MHz SCSI fine.  I've seen a lot that have problems faster *  than 8MHz.  To play it safe, we only request 5MHz transfers. * *  If you'd rather get 10MHz transfers, edit sdtr_message and change  *  the fourth byte from 50 to 25. *//* * Sponsored by  *	iX Multiuser Multitasking Magazine *	Hannover, Germany *	hm@ix.de * * Copyright 1993, 1994, 1995 Drew Eckhardt *      Visionary Computing  *      (Unix and Linux consulting and custom programming) *      drew@PoohSticks.ORG *	+1 (303) 786-7975 * * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation. *  * For more information, please consult  * * NCR53C810  * SCSI I/O Processor * Programmer's Guide * * NCR 53C810 * PCI-SCSI I/O Processor * Data Manual * * NCR 53C810/53C820 * PCI-SCSI I/O Processor Design In Guide * * For literature on Symbios Logic Inc. formerly NCR, SCSI,  * and Communication products please call (800) 334-5454 or * (719) 536-3300.  *  * PCI BIOS Specification Revision * PCI Local Bus Specification * PCI System Design Guide * * PCI Special Interest Group * M/S HF3-15A * 5200 N.E. Elam Young Parkway * Hillsboro, Oregon 97124-6497 * +1 (503) 696-2000  * +1 (800) 433-5177 *//* * Design issues :  * The cumulative latency needed to propagate a read/write request  * through the file system, buffer cache, driver stacks, SCSI host, and  * SCSI device is ultimately the limiting factor in throughput once we  * have a sufficiently fast host adapter. *   * So, to maximize performance we want to keep the ratio of latency to data  * transfer time to a minimum by * 1.  Minimizing the total number of commands sent (typical command latency *	including drive and bus mastering host overhead is as high as 4.5ms) *	to transfer a given amount of data.   * *      This is accomplished by placing no arbitrary limit on the number *	of scatter/gather buffers supported, since we can transfer 1K *	per scatter/gather buffer without Eric's cluster patches,  *	4K with.   * * 2.  Minimizing the number of fatal interrupts serviced, since * 	fatal interrupts halt the SCSI I/O processor.  Basically, *	this means offloading the practical maximum amount of processing  *	to the SCSI chip. *  *	On the NCR53c810/820/720,  this is accomplished by using  *		interrupt-on-the-fly signals when commands complete,  *		and only handling fatal errors and SDTR / WDTR 	messages  *		in the host code. * *	On the NCR53c710, interrupts are generated as on the NCR53c8x0, *		only the lack of a interrupt-on-the-fly facility complicates *		things.   Also, SCSI ID registers and commands are  *		bit fielded rather than binary encoded. *		 * 	On the NCR53c700 and NCR53c700-66, operations that are done via  *		indirect, table mode on the more advanced chips must be *	        replaced by calls through a jump table which  *		acts as a surrogate for the DSA.  Unfortunately, this  * 		will mean that we must service an interrupt for each  *		disconnect/reconnect. *  * 3.  Eliminating latency by pipelining operations at the different levels. * 	 *	This driver allows a configurable number of commands to be enqueued *	for each target/lun combination (experimentally, I have discovered *	that two seems to work best) and will ultimately allow for  *	SCSI-II tagged queuing. * 	 * * Architecture :  * This driver is built around a Linux queue of commands waiting to  * be executed, and a shared Linux/NCR array of commands to start.  Commands * are transfered to the array  by the run_process_issue_queue() function  * which is called whenever a command completes. * * As commands are completed, the interrupt routine is triggered, * looks for commands in the linked list of completed commands with * valid status, removes these commands from a list of running commands,  * calls the done routine, and flags their target/luns as not busy. * * Due to limitations in the intelligence of the NCR chips, certain * concessions are made.  In many cases, it is easier to dynamically  * generate/fix-up code rather than calculate on the NCR at run time.   * So, code is generated or fixed up for * * - Handling data transfers, using a variable number of MOVE instructions *	interspersed with CALL MSG_IN, WHEN MSGIN instructions. * * 	The DATAIN and DATAOUT routines	are separate, so that an incorrect *	direction can be trapped, and space isn't wasted.  * *	It may turn out that we're better off using some sort  *	of table indirect instruction in a loop with a variable *	sized table on the NCR53c710 and newer chips. * * - Checking for reselection (NCR53c710 and better) * * - Handling the details of SCSI context switches (NCR53c710 and better), *	such as reprogramming appropriate synchronous parameters,  *	removing the dsa structure from the NCR's queue of outstanding *	commands, etc. * */#ifdef MODULE#include <linux/module.h>#endif#include <linux/config.h>#include <linux/types.h>#include <asm/setup.h>#include <asm/dma.h>#include <asm/io.h>#include <asm/system.h>#include <linux/delay.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/malloc.h>#include <linux/vmalloc.h>#include <linux/mm.h>#include <linux/ioport.h>#include <linux/time.h>#include <linux/blk.h>#include <linux/spinlock.h>#include <asm/pgtable.h>#ifdef CONFIG_AMIGA#include <asm/amigahw.h>#include <asm/amigaints.h>#include <asm/irq.h>#define BIG_ENDIAN#define NO_IO_SPACE#endif#ifdef CONFIG_MVME16x#include <asm/mvme16xhw.h>#define BIG_ENDIAN#define NO_IO_SPACE#define VALID_IDS#endif#ifdef CONFIG_BVME6000#include <asm/bvme6000hw.h>#define BIG_ENDIAN#define NO_IO_SPACE#define VALID_IDS#endif#include "scsi.h"#include "hosts.h"#include "53c7xx.h"#include "constants.h"#include "sd.h"#include <linux/stat.h>#include <linux/stddef.h>#ifdef NO_IO_SPACE/* * The following make the definitions in 53c7xx.h (write8, etc) smaller, * we don't have separate i/o space anyway. */#undef inb#undef outb#undef inw#undef outw#undef inl#undef outl#define inb(x)          1#define inw(x)          1#define inl(x)          1#define outb(x,y)       1#define outw(x,y)       1#define outl(x,y)       1#endifstatic int check_address (unsigned long addr, int size);static void dump_events (struct Scsi_Host *host, int count);static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host,     int free, int issue);static void hard_reset (struct Scsi_Host *host);static void ncr_scsi_reset (struct Scsi_Host *host);static void print_lots (struct Scsi_Host *host);static void set_synchronous (struct Scsi_Host *host, int target, int sxfer,     int scntl3, int now_connected);static int datapath_residual (struct Scsi_Host *host);static const char * sbcl_to_phase (int sbcl);static void print_progress (Scsi_Cmnd *cmd);static void print_queues (struct Scsi_Host *host);static void process_issue_queue (unsigned long flags);static int shutdown (struct Scsi_Host *host);static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);static int disable (struct Scsi_Host *host);static int NCR53c7xx_run_tests (struct Scsi_Host *host);static void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);static void NCR53c7x0_intfly (struct Scsi_Host *host);static int ncr_halt (struct Scsi_Host *host);static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd     *cmd);static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);static void print_dsa (struct Scsi_Host *host, u32 *dsa,    const char *prefix);static int print_insn (struct Scsi_Host *host, const u32 *insn,    const char *prefix, int kernel);static void NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd);static void NCR53c7x0_init_fixup (struct Scsi_Host *host);static int NCR53c7x0_dstat_sir_intr (struct Scsi_Host *host, struct     NCR53c7x0_cmd *cmd);static void NCR53c7x0_soft_reset (struct Scsi_Host *host);/* Size of event list (per host adapter) */static int track_events = 0;static struct Scsi_Host *first_host = NULL;	/* Head of list of NCR boards */static Scsi_Host_Template *the_template = NULL;	/* NCR53c710 script handling code */#include "53c7xx_d.h"#ifdef A_int_debug_sync#define DEBUG_SYNC_INTR A_int_debug_sync#endifint NCR53c7xx_script_len = sizeof (SCRIPT);int NCR53c7xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;#ifdef FORCE_DSA_ALIGNMENTint CmdPageStart = (0 - Ent_dsa_zero - sizeof(struct NCR53c7x0_cmd)) & 0xff;#endifstatic char *setup_strings[] =	{"","","","","","","",""};#define MAX_SETUP_STRINGS (sizeof(setup_strings) / sizeof(char *))#define SETUP_BUFFER_SIZE 200static char setup_buffer[SETUP_BUFFER_SIZE];static char setup_used[MAX_SETUP_STRINGS];void ncr53c7xx_setup (char *str, int *ints){   int i;   char *p1, *p2;   p1 = setup_buffer;   *p1 = '\0';   if (str)      strncpy(p1, str, SETUP_BUFFER_SIZE - strlen(setup_buffer));   setup_buffer[SETUP_BUFFER_SIZE - 1] = '\0';   p1 = setup_buffer;   i = 0;   while (*p1 && (i < MAX_SETUP_STRINGS)) {      p2 = strchr(p1, ',');      if (p2) {         *p2 = '\0';         if (p1 != p2)            setup_strings[i] = p1;         p1 = p2 + 1;         i++;         }      else {         setup_strings[i] = p1;         break;

⌨️ 快捷键说明

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