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

📄 53c7,8xx.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Purpose : detects and initializes NCR53c7,8x0 SCSI chips *	that were autoprobed, overridden on the LILO command line,  *	or specified at compile time. * * Inputs : tpnt - template for this SCSI adapter *  * Returns : number of host adapters detected * */__initfunc(int NCR53c7xx_detect(Scsi_Host_Template *tpnt)) {    int i;    int current_override;    int count;			/* Number of boards detected */    unsigned char pci_bus, pci_device_fn;    static short pci_index=0;	/* Device index to PCI BIOS calls */#ifndef LINUX_1_2    tpnt->proc_dir = &proc_scsi_ncr53c7xx;#endif    for (current_override = count = 0; current_override < OVERRIDE_LIMIT; 	 ++current_override) {	 if (overrides[current_override].pci ? 	    !ncr_pci_init (tpnt, overrides[current_override].board,		overrides[current_override].chip,		(unsigned char) overrides[current_override].data.pci.bus,		(((overrides[current_override].data.pci.device		<< 3) & 0xf8)|(overrides[current_override].data.pci.function & 		7)), overrides[current_override].options):	    !normal_init (tpnt, overrides[current_override].board, 		overrides[current_override].chip, 		overrides[current_override].data.normal.base, 		overrides[current_override].data.normal.io_port,		overrides[current_override].data.normal.irq,		overrides[current_override].data.normal.dma,		0 /* PCI data invalid */, 0 /* PCI bus place holder */,  		0 /* PCI device_function place holder */,    	    	overrides[current_override].options)) {    	    ++count;	}     }    if (pci_present()) {	for (i = 0; i < NPCI_CHIP_IDS; ++i) 	    for (pci_index = 0;		!pcibios_find_device (PCI_VENDOR_ID_NCR, 		    pci_chip_ids[i].pci_device_id, pci_index, &pci_bus, 		    &pci_device_fn);     		++pci_index)		if (!ncr_pci_init (tpnt, BOARD_GENERIC, pci_chip_ids[i].chip, 		    pci_bus, pci_device_fn, /* no options */ 0))		    ++count;    }    return count;}/* NCR53c810 and NCR53c820 script handling code */#include "53c8xx_d.h"#ifdef A_int_debug_sync#define DEBUG_SYNC_INTR A_int_debug_sync#endifstatic int NCR53c8xx_script_len = sizeof (SCRIPT);static int NCR53c8xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;/*  * Function : static void NCR53c8x0_init_fixup (struct Scsi_Host *host) * * Purpose :  copy and fixup the SCSI SCRIPTS(tm) code for this device. * * Inputs : host - pointer to this host adapter's structure * */static void NCR53c8x0_init_fixup (struct Scsi_Host *host) {    NCR53c7x0_local_declare();    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)	host->hostdata;    unsigned char tmp;    int i, ncr_to_memory, memory_to_ncr;    u32 base;#ifdef __powerpc__    unsigned long *script_ptr;#endif        NCR53c7x0_local_setup(host);    /* XXX - NOTE : this code MUST be made endian aware */    /*  Copy code into buffer that was allocated at detection time.  */    memcpy ((void *) hostdata->script, (void *) SCRIPT, 	sizeof(SCRIPT));    /* Fixup labels */    for (i = 0; i < PATCHES; ++i) 	hostdata->script[LABELPATCHES[i]] +=     	    virt_to_bus(hostdata->script);    /* Fixup addresses of constants that used to be EXTERNAL */    patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort,     	virt_to_bus(&(hostdata->NCR53c7xx_msg_abort)));    patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject,     	virt_to_bus(&(hostdata->NCR53c7xx_msg_reject)));    patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero,     	virt_to_bus(&(hostdata->NCR53c7xx_zero)));    patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink,     	virt_to_bus(&(hostdata->NCR53c7xx_sink)));    patch_abs_32 (hostdata->script, 0, NOP_insn,	virt_to_bus(&(hostdata->NOP_insn)));    patch_abs_32 (hostdata->script, 0, schedule,	virt_to_bus((void *) hostdata->schedule));    /* Fixup references to external variables: */    for (i = 0; i < EXTERNAL_PATCHES_LEN; ++i)       hostdata->script[EXTERNAL_PATCHES[i].offset] +=         virt_to_bus(EXTERNAL_PATCHES[i].address);    /*      * Fixup absolutes set at boot-time.     *      * All non-code absolute variables suffixed with "dsa_" and "int_"     * are constants, and need no fixup provided the assembler has done      * it for us (I don't know what the "real" NCR assembler does in      * this case, my assembler does the right magic).     */    patch_abs_rwri_data (hostdata->script, 0, dsa_save_data_pointer,     	Ent_dsa_code_save_data_pointer - Ent_dsa_zero);    patch_abs_rwri_data (hostdata->script, 0, dsa_restore_pointers,    	Ent_dsa_code_restore_pointers - Ent_dsa_zero);    patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect,    	Ent_dsa_code_check_reselect - Ent_dsa_zero);    /*     * Just for the hell of it, preserve the settings of      * Burst Length and Enable Read Line bits from the DMODE      * register.  Make sure SCRIPTS start automagically.     */    tmp = NCR53c7x0_read8(DMODE_REG_10);    tmp &= (DMODE_800_ERL | DMODE_BL_MASK);    if (!(hostdata->options & OPTION_MEMORY_MAPPED)) {    	base = (u32) host->io_port;    	memory_to_ncr = tmp|DMODE_800_DIOM;    	ncr_to_memory = tmp|DMODE_800_SIOM;    } else {    	base = virt_to_bus(host->base);	memory_to_ncr = ncr_to_memory = tmp;    }    patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);    patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);    /*     * I needed some variables in the script to be accessible to      * both the NCR chip and the host processor. For these variables,     * I made the arbitrary decision to store them directly in the      * hostdata structure rather than in the RELATIVE area of the      * SCRIPTS.     */        patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp);    patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr);    patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);    patch_abs_32 (hostdata->script, 0, msg_buf, 	virt_to_bus((void *)&(hostdata->msg_buf)));    patch_abs_32 (hostdata->script, 0, reconnect_dsa_head,     	virt_to_bus((void *)&(hostdata->reconnect_dsa_head)));    patch_abs_32 (hostdata->script, 0, addr_reconnect_dsa_head, 	virt_to_bus((void *)&(hostdata->addr_reconnect_dsa_head)));    patch_abs_32 (hostdata->script, 0, reselected_identify,     	virt_to_bus((void *)&(hostdata->reselected_identify)));/* reselected_tag is currently unused */#if 0    patch_abs_32 (hostdata->script, 0, reselected_tag,     	virt_to_bus((void *)&(hostdata->reselected_tag)));#endif    patch_abs_32 (hostdata->script, 0, test_dest, 	virt_to_bus((void*)&hostdata->test_dest));    patch_abs_32 (hostdata->script, 0, test_src, 	virt_to_bus(&hostdata->test_source));    patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect, 	(unsigned char)(Ent_dsa_code_check_reselect - Ent_dsa_zero));/* These are for event logging; the ncr_event enum contains the    actual interrupt numbers. */#ifdef A_int_EVENT_SELECT   patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT, (u32) EVENT_SELECT);#endif#ifdef A_int_EVENT_DISCONNECT   patch_abs_32 (hostdata->script, 0, int_EVENT_DISCONNECT, (u32) EVENT_DISCONNECT);#endif#ifdef A_int_EVENT_RESELECT   patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT, (u32) EVENT_RESELECT);#endif#ifdef A_int_EVENT_COMPLETE   patch_abs_32 (hostdata->script, 0, int_EVENT_COMPLETE, (u32) EVENT_COMPLETE);#endif#ifdef A_int_EVENT_IDLE   patch_abs_32 (hostdata->script, 0, int_EVENT_IDLE, (u32) EVENT_IDLE);#endif#ifdef A_int_EVENT_SELECT_FAILED   patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT_FAILED, 	(u32) EVENT_SELECT_FAILED);#endif#ifdef A_int_EVENT_BEFORE_SELECT   patch_abs_32 (hostdata->script, 0, int_EVENT_BEFORE_SELECT,	(u32) EVENT_BEFORE_SELECT);#endif#ifdef A_int_EVENT_RESELECT_FAILED   patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT_FAILED, 	(u32) EVENT_RESELECT_FAILED);#endif    /*     * Make sure the NCR and Linux code agree on the location of      * certain fields.     */    hostdata->E_accept_message = Ent_accept_message;    hostdata->E_command_complete = Ent_command_complete;		    hostdata->E_cmdout_cmdout = Ent_cmdout_cmdout;    hostdata->E_data_transfer = Ent_data_transfer;    hostdata->E_debug_break = Ent_debug_break;	    hostdata->E_dsa_code_template = Ent_dsa_code_template;    hostdata->E_dsa_code_template_end = Ent_dsa_code_template_end;    hostdata->E_end_data_transfer = Ent_end_data_transfer;    hostdata->E_initiator_abort = Ent_initiator_abort;    hostdata->E_msg_in = Ent_msg_in;    hostdata->E_other_transfer = Ent_other_transfer;    hostdata->E_other_in = Ent_other_in;    hostdata->E_other_out = Ent_other_out;    hostdata->E_reject_message = Ent_reject_message;    hostdata->E_respond_message = Ent_respond_message;    hostdata->E_select = Ent_select;    hostdata->E_select_msgout = Ent_select_msgout;    hostdata->E_target_abort = Ent_target_abort;#ifdef Ent_test_0    hostdata->E_test_0 = Ent_test_0;#endif    hostdata->E_test_1 = Ent_test_1;    hostdata->E_test_2 = Ent_test_2;#ifdef Ent_test_3    hostdata->E_test_3 = Ent_test_3;#endif    hostdata->E_wait_reselect = Ent_wait_reselect;    hostdata->E_dsa_code_begin = Ent_dsa_code_begin;    hostdata->dsa_cmdout = A_dsa_cmdout;    hostdata->dsa_cmnd = A_dsa_cmnd;    hostdata->dsa_datain = A_dsa_datain;    hostdata->dsa_dataout = A_dsa_dataout;    hostdata->dsa_end = A_dsa_end;			    hostdata->dsa_msgin = A_dsa_msgin;    hostdata->dsa_msgout = A_dsa_msgout;    hostdata->dsa_msgout_other = A_dsa_msgout_other;    hostdata->dsa_next = A_dsa_next;    hostdata->dsa_select = A_dsa_select;    hostdata->dsa_start = Ent_dsa_code_template - Ent_dsa_zero;    hostdata->dsa_status = A_dsa_status;    hostdata->dsa_jump_dest = Ent_dsa_code_fix_jump - Ent_dsa_zero + 	8 /* destination operand */;    /* sanity check */    if (A_dsa_fields_start != Ent_dsa_code_template_end -     	Ent_dsa_zero)     	printk("scsi%d : NCR dsa_fields start is %d not %d\n",    	    host->host_no, A_dsa_fields_start, Ent_dsa_code_template_end -     	    Ent_dsa_zero);#ifdef __powerpc__/* The PowerPC is Big Endian - adjust script appropriately */    script_ptr = hostdata->script;    for (i = 0;  i < sizeof(SCRIPT);  i += sizeof(long))    {        *script_ptr++ = le32_to_cpu(*script_ptr);    }#endif    	        printk("scsi%d : NCR code relocated to 0x%lx (virt 0x%p)\n", host->host_no,	virt_to_bus(hostdata->script), hostdata->script);}/* * Function : static int NCR53c8xx_run_tests (struct Scsi_Host *host) * * Purpose : run various verification tests on the NCR chip,  *	including interrupt generation, and proper bus mastering * 	operation. *  * Inputs : host - a properly initialized Scsi_Host structure * * Preconditions : the NCR chip must be in a halted state. * * Returns : 0 if all tests were successful, -1 on error. *  */static int NCR53c8xx_run_tests (struct Scsi_Host *host) {    NCR53c7x0_local_declare();    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)	host->hostdata;    unsigned long timeout;    u32 start;    int failed, i;    unsigned long flags;    NCR53c7x0_local_setup(host);    /* The NCR chip _must_ be idle to run the test scripts */    save_flags(flags);    cli();    if (!hostdata->idle) {	printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);	restore_flags(flags);	return -1;    }    /*      * Check for functional interrupts, this could work as an     * autoprobe routine.     */    if ((hostdata->options & OPTION_DEBUG_TEST1) && 	    hostdata->state != STATE_DISABLED) {	hostdata->idle = 0;	hostdata->test_running = 1;	hostdata->test_completed = -1;	hostdata->test_dest = 0;	hostdata->test_source = 0xdeadbeef;	start = virt_to_bus (hostdata->script) + hostdata->E_test_1;    	hostdata->state = STATE_RUNNING;	printk ("scsi%d : test 1", host->host_no);	NCR53c7x0_write32 (DSP_REG, start);	printk (" started\n");	restore_flags(flags);	/* 	 * This is currently a .5 second timeout, since (in theory) no slow 	 * board will take that long.  In practice, we've seen one 	 * pentium which occasionally fails with this, but works with 	 * 10 times as much?	 */	timeout = jiffies + 5 * HZ / 10;	while ((hostdata->test_completed == -1) && jiffies < timeout)		barrier();	failed = 1;	if (hostdata->test_completed == -1)	    printk ("scsi%d : driver test 1 timed out%s\n",host->host_no ,		(hostdata->test_dest == 0xdeadbeef) ? 		    " due to lost interrupt.\n"		    "         Please verify that the correct IRQ is being used for your board,\n"		    "	      and that the motherboard IRQ jumpering matches the PCI setup on\n"		    "         PCI systems.\n"		    "         If you are using a NCR53c810 board in a PCI system, you should\n" 		    "         also verify that the board is jumpered to use PCI INTA, since\n"		    "         most PCI motherboards lack support for INTB, INTC, and INTD.\n"		    : "");      else if (hostdata->test_completed != 1) 	    printk ("scsi%d : test 1 bad interrupt value (%d)\n", 		host->host_no, hostdata->test_completed);	else 	    failed = (hostdata->test_dest != 0xdeadbeef);	if (hostdata->test_dest != 0xdeadbeef) {	    printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n"                    "         probable cache invalidation problem.  Please configure caching\n"		    "         as write-through or disabled\n",		host->host_no, hostdata->test_dest);	}	if (failed) {	    printk ("scsi%d : DSP = 0x%p (script at 0x%p, start at 0x%x)\n",		host->host_no, bus_to_virt(NCR53c7x0_read32(DSP_REG)),		hostdata->script, start);	    printk ("scsi%d : DSPS = 

⌨️ 快捷键说明

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