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

📄 53c7,8xx.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Purpose : Initialize internal structures, as required on startup, or  *	after a SCSI bus reset. *  * Inputs : host - pointer to this host adapter's structure */static void NCR53c7x0_driver_init (struct Scsi_Host *host) {    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)	host->hostdata;    int i, j;    u32 *curr;    for (i = 0; i < 16; ++i) {	hostdata->request_sense[i] = 0;    	for (j = 0; j < 8; ++j) 	    hostdata->busy[i][j] = 0;	set_synchronous (host, i, /* sxfer */ 0, hostdata->saved_scntl3, 0);    }    hostdata->issue_queue = NULL;    hostdata->running_list = hostdata->finished_queue = 	hostdata->curr = NULL;    for (i = 0, curr = (u32 *) hostdata->schedule; 	i < host->can_queue; ++i, curr += 2) {	curr[0] = hostdata->NOP_insn;	curr[1] = le32_to_cpu(0xdeadbeef);    }    curr[0] = le32_to_cpu(((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE);    curr[1] = (u32) le32_to_cpu(virt_to_bus (hostdata->script) +	hostdata->E_wait_reselect);    hostdata->reconnect_dsa_head = 0;    hostdata->addr_reconnect_dsa_head = (u32) 	le32_to_cpu(virt_to_bus((void *) &(hostdata->reconnect_dsa_head)));    hostdata->expecting_iid = 0;    hostdata->expecting_sto = 0;    if (hostdata->options & OPTION_ALWAYS_SYNCHRONOUS) 	hostdata->initiate_sdtr = le32_to_cpu(0xffff);     else    	hostdata->initiate_sdtr = 0;    hostdata->talked_to = 0;    hostdata->idle = 1;}/*  * Function : static int ccf_to_clock (int ccf) * * Purpose :  Return the largest SCSI clock allowable for a given *	clock conversion factor, allowing us to do synchronous periods *	when we don't know what the SCSI clock is by taking at least  *	as long as the device says we can. * * Inputs : ccf * * Returns : clock on success, -1 on failure. */static int ccf_to_clock (int ccf) {    switch (ccf) {    case 1: return 25000000; 	/* Divide by 1.0 */    case 2: return 37500000;	/* Divide by 1.5 */    case 3: return 50000000;  	/* Divide by 2.0 */    case 0: 			/* Divide by 3.0 */    case 4: return 66000000;     default: return -1;    }}/*  * Function : static int clock_to_ccf (int clock) * * Purpose :  Return the clock conversion factor for a given SCSI clock. * * Inputs : clock - SCSI clock expressed in Hz. * * Returns : ccf on success, -1 on failure. */static int clock_to_ccf (int clock) {    if (clock < 16666666)	return -1;    if (clock < 25000000)	return 1; 	/* Divide by 1.0 */    else if (clock < 37500000)	return 2; 	/* Divide by 1.5 */    else if (clock < 50000000)	return 3;	/* Divide by 2.0 */    else if (clock < 66000000)	return 4;	/* Divide by 3.0 */    else 	return -1;}    /*  * Function : static int NCR53c7x0_init (struct Scsi_Host *host) * * Purpose :  initialize the internal structures for a given SCSI host * * Inputs : host - pointer to this host adapter's structure * * Preconditions : when this function is called, the chip_type  * 	field of the hostdata structure MUST have been set. * * Returns : 0 on success, -1 on failure. */static int NCR53c7x0_init (struct Scsi_Host *host) {    NCR53c7x0_local_declare();    int i, ccf, expected_ccf;    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)	host->hostdata;    struct Scsi_Host *search;    /*      * There are some things which we need to know about in order to provide     * a semblance of support.  Print 'em if they aren't what we expect,      * otherwise don't add to the noise.     *      * -1 means we don't know what to expect.     */    int expected_id = -1;    int expected_clock = -1;    int uninitialized = 0;    /*      * FIXME : this is only on Intel boxes.  On other platforms, this     * will differ.     */    int expected_mapping = OPTION_IO_MAPPED;    NCR53c7x0_local_setup(host);    switch (hostdata->chip) {    case 820:    case 825:#ifdef notyet	host->max_id = 15;#endif	/* Fall through */    case 810:    case 815:    	hostdata->dstat_sir_intr = NCR53c8x0_dstat_sir_intr;    	hostdata->init_save_regs = NULL;    	hostdata->dsa_fixup = NCR53c8xx_dsa_fixup;    	hostdata->init_fixup = NCR53c8x0_init_fixup;    	hostdata->soft_reset = NCR53c8x0_soft_reset;	hostdata->run_tests = NCR53c8xx_run_tests;/* Is the SCSI clock ever anything else on these chips? */	expected_clock = hostdata->scsi_clock = 40000000;	expected_id = 7;    	break;    default:	printk ("scsi%d : chip type of %d is not supported yet, detaching.\n",	    host->host_no, hostdata->chip);	scsi_unregister (host);	return -1;    }    /* Assign constants accessed by NCR */    hostdata->NCR53c7xx_zero = 0;			    hostdata->NCR53c7xx_msg_reject = le32_to_cpu(MESSAGE_REJECT);    hostdata->NCR53c7xx_msg_abort = le32_to_cpu(ABORT);    hostdata->NCR53c7xx_msg_nop = le32_to_cpu(NOP);    hostdata->NOP_insn = le32_to_cpu((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24);    if (expected_mapping == -1 || 	(hostdata->options & (OPTION_MEMORY_MAPPED)) != 	(expected_mapping & OPTION_MEMORY_MAPPED))	printk ("scsi%d : using %s mapped access\n", host->host_no, 	    (hostdata->options & OPTION_MEMORY_MAPPED) ? "memory" : 	    "io");    hostdata->dmode = (hostdata->chip == 700 || hostdata->chip == 70066) ? 	DMODE_REG_00 : DMODE_REG_10;    hostdata->istat = ((hostdata->chip / 100) == 8) ?     	ISTAT_REG_800 : ISTAT_REG_700;/* Only the ISTAT register is readable when the NCR is running, so make    sure it's halted. */    ncr_halt(host);/*  * XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc, *	as does the 710 with one bit per SCSI ID.  Conversely, the NCR * 	uses a normal, 3 bit binary representation of these values. * * Get the rest of the NCR documentation, and FIND OUT where the change * was. */#if 0    tmp = hostdata->this_id_mask = NCR53c7x0_read8(SCID_REG);    for (host->this_id = 0; tmp != 1; tmp >>=1, ++host->this_id);#else    host->this_id = NCR53c7x0_read8(SCID_REG) & 15;    if (host->this_id == 0)	host->this_id = 7;	/* sanitize hostid---0 doesn't make sense */    hostdata->this_id_mask = 1 << host->this_id;#endif/* * Note : we should never encounter a board setup for ID0.  So, * 	if we see ID0, assume that it was uninitialized and set it * 	to the industry standard 7. */    if (!host->this_id) {	printk("scsi%d : initiator ID was %d, changing to 7\n",	    host->host_no, host->this_id);	host->this_id = 7;	hostdata->this_id_mask = 1 << 7;	uninitialized = 1;    };    if (expected_id == -1 || host->this_id != expected_id)    	printk("scsi%d : using initiator ID %d\n", host->host_no,    	    host->this_id);    /*     * Save important registers to allow a soft reset.     */    if ((hostdata->chip / 100) == 8) {    /*      * CTEST4 controls burst mode disable.     */	hostdata->saved_ctest4 = NCR53c7x0_read8(CTEST4_REG_800) &     	    CTEST4_800_SAVE;    } else {    /*     * CTEST7 controls cache snooping, burst mode, and support for      * external differential drivers.     */	hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE;    }    /*     * On NCR53c700 series chips, DCNTL controls the SCSI clock divisor,     * on 800 series chips, it allows for a totem-pole IRQ driver.     */    hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);    /*      * DCNTL_800_IRQM controls weather we are using an open drain     * driver (reset) or totem pole driver (set).  In all cases,      * it's level active.  I suppose this is an issue when we're trying to      * wire-or the same PCI INTx line?     */    if ((hostdata->chip / 100) == 8)	hostdata->saved_dcntl &= ~DCNTL_800_IRQM;    /*     * DMODE controls DMA burst length, and on 700 series chips,     * 286 mode and bus width       */    hostdata->saved_dmode = NCR53c7x0_read8(hostdata->dmode);    /*      * Now that burst length and enabled/disabled status is known,      * clue the user in on it.       */       if ((hostdata->chip / 100) == 8) {	if (hostdata->saved_ctest4 & CTEST4_800_BDIS) {	    printk ("scsi%d : burst mode disabled\n", host->host_no);	} else {	    switch (hostdata->saved_dmode & DMODE_BL_MASK) {	    case DMODE_BL_2: i = 2; break;	    case DMODE_BL_4: i = 4; break;	    case DMODE_BL_8: i = 8; break;	    case DMODE_BL_16: i = 16; break;            default: i = 0;	    }	    printk ("scsi%d : burst length %d\n", host->host_no, i);	}    }    /*     * On NCR53c810 and NCR53c820 chips, SCNTL3 contails the synchronous     * and normal clock conversion factors.     */    if (hostdata->chip / 100 == 8)  {	expected_ccf = clock_to_ccf (expected_clock);	hostdata->saved_scntl3 = NCR53c7x0_read8(SCNTL3_REG_800);	ccf = hostdata->saved_scntl3 & SCNTL3_800_CCF_MASK;	if (expected_ccf != -1 && ccf != expected_ccf && !ccf) {	    hostdata->saved_scntl3 = (hostdata->saved_scntl3 &		~SCNTL3_800_CCF_MASK) | expected_ccf;	    if (!uninitialized) {		printk ("scsi%d : reset ccf to %d from %d\n", 		    host->host_no, expected_ccf, ccf);		uninitialized = 1;	    }	}    } else    	ccf = 0;    /*     * If we don't have a SCSI clock programmed, pick one on the upper     * bound of that allowed by NCR so that our transfers err on the      * slow side, since transfer period must be >= the agreed      * upon period.     */    if ((!hostdata->scsi_clock) && (hostdata->scsi_clock = ccf_to_clock (ccf)) 	== -1) {	printk ("scsi%d : clock conversion factor %d unknown.\n"		"         synchronous transfers disabled\n",		host->host_no, ccf);	hostdata->options &= ~OPTION_SYNCHRONOUS;	hostdata->scsi_clock = 0;     }    if (expected_clock == -1 || hostdata->scsi_clock != expected_clock)    	printk ("scsi%d : using %dMHz SCSI clock\n", host->host_no, 	    hostdata->scsi_clock / 1000000);    for (i = 0; i < 16; ++i) 	hostdata->cmd_allocated[i] = 0;    if (hostdata->init_save_regs)    	hostdata->init_save_regs (host);    if (hostdata->init_fixup)    	hostdata->init_fixup (host);    if (!the_template) {	the_template = host->hostt;	first_host = host;    }    /*      * Linux SCSI drivers have always been plagued with initialization      * problems - some didn't work with the BIOS disabled since they expected     * initialization from it, some didn't work when the networking code     * was enabled and registers got scrambled, etc.     *     * To avoid problems like this, in the future, we will do a soft      * reset on the SCSI chip, taking it back to a sane state.     */    hostdata->soft_reset (host);#if 1    hostdata->debug_count_limit = -1;#else    hostdata->debug_count_limit = 1;#endif    hostdata->intrs = -1;    hostdata->resets = -1;    memcpy ((void *) hostdata->synchronous_want, (void *) sdtr_message, 	sizeof (hostdata->synchronous_want));    NCR53c7x0_driver_init (host);    /*     * Set up an interrupt handler if we aren't already sharing an IRQ     * with another board.     */    for (search = first_host; search && !(search->hostt == the_template &&	search->irq == host->irq && search != host); search=search->next);    if (!search) {#ifdef __powerpc__	if (request_irq(host->irq, do_NCR53c7x0_intr, SA_SHIRQ, "53c7,8xx", NULL)) #else	if (request_irq(host->irq, do_NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx", NULL))#endif	  {	  	  	    printk("scsi%d : IRQ%d not free, detaching\n"	           "         You have either a configuration problem, or a\n"                   "         broken BIOS.  You may wish to manually assign\n"	           "         an interrupt to the NCR board rather than using\n"                   "         an automatic setting.\n", 		host->host_no, host->irq);	    scsi_unregister (host);	    return -1;	}     } else {	printk("scsi%d : using interrupt handler previously installed for scsi%d\n",	    host->host_no, search->host_no);    }    if ((hostdata->run_tests && hostdata->run_tests(host) == -1) ||        (hostdata->options & OPTION_DEBUG_TESTS_ONLY)) {    	/* XXX Should disable interrupts, etc. here */	scsi_unregister (host);

⌨️ 快捷键说明

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