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

📄 53c78xx.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
 * 	we do this, we need to handle the case where we disconnect *	between segments. *  * 2.  Currently, when Icky things happen we do a FATAL().  Instead, *     we want to do an integrity check on the parts of the NCR hostdata *     structure which were initialized at boot time; FATAL() if that  *     fails, and otherwise try to recover.  Keep track of how many *     times this has happened within a single SCSI command; if it  *     gets excessive, then FATAL(). * * 3.  Parity checking is currently disabled, and a few things should  *     happen here now that we support synchronous SCSI transfers : *     1.  On soft-reset, we should set the EPC (Enable Parity Checking) *	   and AAP (Assert SATN/ on parity error) bits in SCNTL0. *	 *     2.  We should enable the parity interrupt in the SIEN0 register. *  *     3.  intr_phase_mismatch() needs to believe that message out is  *	   always an "acceptable" phase to have a mismatch in.  If  *	   the old phase was MSG_IN, we should send a MESSAGE PARITY  *	   error.  If the old phase was something else, we should send *	   a INITIATOR_DETECTED_ERROR message.  Note that this could *	   cause a RESTORE POINTERS message; so we should handle that  *	   correctly first.  Instead, we should probably do an  *	   initiator_abort. * * 4.  MPEE bit of CTEST4 should be set so we get interrupted if  *     we detect an error. * *   * 5.  The initial code has been tested on the NCR53c810.  I don't  *     have access to NCR53c700, 700-66 (Forex boards), NCR53c710 *     (NCR Pentium systems), NCR53c720, NCR53c820, or NCR53c825 boards to  *     finish development on those platforms. * *     NCR53c820/825/720 - need to add wide transfer support, including WDTR  *     		negotiation, programming of wide transfer capabilities *		on reselection and table indirect selection. * *     NCR53c710 - need to add fatal interrupt or GEN code for  *		command completion signaling.   Need to modify all  *		SDID, SCID, etc. registers, and table indirect select code  *		since these use bit fielded (ie 1<<target) instead of  *		binary encoded target ids.  Need to accommodate *		different register mappings, probably scan through *		the SCRIPT code and change the non SFBR register operand *		of all MOVE instructions. *  *     NCR53c700/700-66 - need to add code to refix addresses on  *		every nexus change, eliminate all table indirect code, *		very messy. * * 6.  The NCR53c7x0 series is very popular on other platforms that  *     could be running Linux - ie, some high performance AMIGA SCSI  *     boards use it.   *	 *     So, I should include #ifdef'd code so that it is  *     compatible with these systems. *	 *     Specifically, the little Endian assumptions I made in my  *     bit fields need to change, and if the NCR doesn't see memory *     the right way, we need to provide options to reverse words *     when the scripts are relocated. * * 7.  Use vremap() to access memory mapped boards.   *//*  * Allow for simultaneous existence of multiple SCSI scripts so we  * can have a single driver binary for all of the family. * * - one for NCR53c700 and NCR53c700-66 chips	(not yet supported) * - one for rest (only the NCR53c810, 815, 820, and 825 are currently  *	supported) *  * So that we only need two SCSI scripts, we need to modify things so * that we fixup register accesses in READ/WRITE instructions, and  * we'll also have to accommodate the bit vs. binary encoding of IDs * with the 7xx chips. *//* * Use pci_chips_ids to translate in both directions between PCI device ID  * and chip numbers.   */static struct {    unsigned short pci_device_id;    int chip;/*  * The revision field of the PCI_CLASS_REVISION register is compared  * against each of these fields if the field is not -1.  If it * is less than min_revision or larger than max_revision, a warning * message is printed. */    int max_revision;    int min_revision;} pci_chip_ids[] = {     {PCI_DEVICE_ID_NCR_53C810, 810, 2, 1},     {PCI_DEVICE_ID_NCR_53C815, 815, 3, 2},    {PCI_DEVICE_ID_NCR_53C820, 820, -1, -1},    {PCI_DEVICE_ID_NCR_53C825, 825, -1, -1}};#define NPCI_CHIP_IDS (sizeof (pci_chip_ids) / sizeof(pci_chip_ids[0]))#define ROUNDUP(adr,type)	\  ((void *) (((long) (adr) + sizeof(type) - 1) & ~(sizeof(type) - 1)))/*  * Forced detection and autoprobe code for various hardware.  Currently,  * entry points for these are not included in init/main.c because if the  * PCI BIOS code isn't working right, you're not going to be able to use  * the hardware anyways; this way we force users to solve their  * problems rather than forcing detection and blaming us when it  * does not work. */static struct override {    int chip;	/* 700, 70066, 710, 720, 810, 820 */    int board;	/* Any special board level gunk */    unsigned pci:1;    union {	struct {	    int base;	/* Memory address - indicates memory mapped regs */	    int io_port;/* I/O port address - indicates I/O mapped regs */    	    int irq;	/* IRQ line */		    	    int dma;	/* DMA channel 		- often none */	} normal;	struct {	    int bus;	    int device;	    int function;	} pci;    } data;    long long options;} overrides [4] = {{0,},};static int commandline_current = 0;static int no_overrides = 0;#if 0#define OVERRIDE_LIMIT (sizeof(overrides) / sizeof(struct override))#else#define OVERRIDE_LIMIT commandline_current#endif/* * Function: issue_to_cmd * * Purpose: convert jump instruction in issue array to NCR53c7x0_cmd *	structure pointer.   * * Inputs; issue - pointer to start of NOP or JUMP instruction *	in issue array. * * Returns: pointer to command on success; 0 if opcode is NOP. */static inline struct NCR53c7x0_cmd *issue_to_cmd (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,    u32 *issue){    return (issue[0] != hostdata->NOP_insn) ?     /*      * If the IF TRUE bit is set, it's a JUMP instruction.  The     * operand is a bus pointer to the dsa_begin routine for this DSA.  The     * dsa field of the NCR53c7x0_cmd structure starts with the      * DSA code template.  By converting to a virtual address,     * subtracting the code template size, and offset of the      * dsa field, we end up with a pointer to the start of the      * structure (alternatively, we could use the      * dsa_cmnd field, an anachronism from when we weren't     * sure what the relationship between the NCR structures     * and host structures were going to be.     */	(struct NCR53c7x0_cmd *) ((char *) bus_to_virt (issue[1]) - 	    (hostdata->E_dsa_code_begin - hostdata->E_dsa_code_template) -	    offsetof(struct NCR53c7x0_cmd, dsa))     /* If the IF TRUE bit is not set, it's a NOP */	: NULL;}/* * Function : static internal_setup(int board, int chip, char *str, int *ints) * * Purpose : LILO command line initialization of the overrides array, *  * Inputs : board - currently, unsupported.  chip - 700, 70066, 710, 720 * 	810, 815, 820, 825, although currently only the NCR53c810 is  *	supported. *  */static void internal_setup(int board, int chip, char *str, int *ints) {    unsigned char pci;		/* Specifies a PCI override, with bus, device,				   function */    pci = (str && !strcmp (str, "pci")) ? 1 : 0;    /* * Override syntaxes are as follows :  * ncr53c700,ncr53c700-66,ncr53c710,ncr53c720=mem,io,irq,dma * ncr53c810,ncr53c820,ncr53c825=mem,io,irq or pci,bus,device,function */    if (commandline_current < OVERRIDE_LIMIT) {	overrides[commandline_current].pci = pci ? 1 : 0;	if (!pci) {	    overrides[commandline_current].data.normal.base = ints[1];	    overrides[commandline_current].data.normal.io_port = ints[2];	    overrides[commandline_current].data.normal.irq = ints[3];    	    overrides[commandline_current].data.normal.dma = (ints[0] >= 4) ?    	    	ints[4] : DMA_NONE;	    /* FIXME: options is now a long long */    	    overrides[commandline_current].options = (ints[0] >= 5) ?    	    	ints[5] : 0;	} else {	    overrides[commandline_current].data.pci.bus = ints[1];	    overrides[commandline_current].data.pci.device = ints[2];	    overrides[commandline_current].data.pci.function = ints[3];	    /* FIXME: options is now a long long */    	    overrides[commandline_current].options = (ints[0] >= 4) ?    	    	ints[4] : 0;	}	overrides[commandline_current].board = board;	overrides[commandline_current].chip = chip;	++commandline_current;    	++no_overrides;    } else {	printk ("53c7,7x0.c:internal_setup() : too many overrides\n");    }}/* * XXX - we might want to implement a single override function *       with a chip type field, revamp the command line configuration, * 	 etc. */#define setup_wrapper(x) 				\void ncr53c##x##_setup (char *str, int *ints) {		\    internal_setup (BOARD_GENERIC, x, str, ints);	\}setup_wrapper(700)setup_wrapper(70066)setup_wrapper(710)setup_wrapper(720)setup_wrapper(810)setup_wrapper(815)setup_wrapper(820)setup_wrapper(825)/*  * FIXME: we should junk these, in favor of synchronous_want and  * wide_want in the NCR53c7x0_hostdata structure. *//* Template for "preferred" synchronous transfer parameters. */static const unsigned char sdtr_message[] = {#ifdef CONFIG_SCSI_NCR53C7xx_FAST    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 25 /* *4ns */, 8 /* off */ #else    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 50 /* *4ns */, 8 /* off */ #endif};/* Template to request asynchronous transfers */static const unsigned char async_message[] = {    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */};/* Template for "preferred" WIDE transfer parameters */static const unsigned char wdtr_message[] = {    EXTENDED_MESSAGE, 2 /* length */, EXTENDED_WDTR, 1 /* 2^1 bytes */};/* * Function : struct Scsi_Host *find_host (int host) *  * Purpose : KGDB support function which translates a host number  * 	to a host structure.  * * Inputs : host - number of SCSI host * * Returns : NULL on failure, pointer to host structure on success. */static struct Scsi_Host *find_host (int host) {    struct Scsi_Host *h;    for (h = first_host; h && h->host_no != host; h = h->next);    if (!h) {	printk (KERN_ALERT "scsi%d not found\n", host);	return NULL;    } else if (h->hostt != the_template) {	printk (KERN_ALERT "scsi%d is not a NCR board\n", host);	return NULL;    }    return h;}/* * Function : request_synchronous (int host, int target) *  * Purpose : KGDB interface which will allow us to negotiate for  * 	synchronous transfers.  This ill be replaced with a more  * 	integrated function; perhaps a new entry in the scsi_host  *	structure, accessible via an ioctl() or perhaps /proc/scsi. * * Inputs : host - number of SCSI host; target - number of target. * * Returns : 0 when negotiation has been setup for next SCSI command, *	-1 on failure. */static intrequest_synchronous (int host, int target) {    struct Scsi_Host *h;    struct NCR53c7x0_hostdata *hostdata;    unsigned long flags;    if (target < 0) {	printk (KERN_ALERT "target %d is bogus\n", target);	return -1;    }    if (!(h = find_host (host)))	return -1;    else if (h->this_id == target) {	printk (KERN_ALERT "target %d is host ID\n", target);	return -1;    } #ifndef LINUX_1_2    else if (target > h->max_id) {	printk (KERN_ALERT "target %d exceeds maximum of %d\n", target,	    h->max_id);	return -1;    }#endif    hostdata = (struct NCR53c7x0_hostdata *)h->hostdata;    save_flags(flags);    cli();    if (hostdata->initiate_sdtr & (1 << target)) {	restore_flags(flags);	printk (KERN_ALERT "target %d already doing SDTR\n", target);	return -1;    }     hostdata->initiate_sdtr |= (1 << target);    restore_flags(flags);    return 0;}/* * Function : request_disconnect (int host, int on_or_off) *  * Purpose : KGDB support function, tells us to allow or disallow  *	disconnections. * * Inputs : host - number of SCSI host; on_or_off - non-zero to allow, *	zero to disallow. * * Returns : 0 on success, *	-1 on failure. */static int request_disconnect (int host, int on_or_off) {    struct Scsi_Host *h;    struct NCR53c7x0_hostdata *hostdata;    if (!(h = find_host (host)))	return -1;    hostdata = (struct NCR53c7x0_hostdata *) h->hostdata;    if (on_or_off) 	hostdata->options |= OPTION_DISCONNECT;    else	hostdata->options &= ~OPTION_DISCONNECT;    return 0;}/* * Function : static void NCR53c7x0_driver_init (struct Scsi_Host *host) * * Purpose : Initialize internal structures, as required on startup, or  *	after a SCSI bus reset. *  * Inputs : host - pointer to this host adapter's structure

⌨️ 快捷键说明

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