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

📄 aic94xx_seq.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			udelay(PAUSE_DELAY);		}	}	reg = asd_read_reg_dword(asd_ha, COMSTAT);	if (!(reg & OVLYDMADONE) || (reg & OVLYERR)	    || (asd_read_reg_dword(asd_ha, CHIMINT) & DEVEXCEPT_MASK)){		asd_printk("%s: error DMA-ing sequencer code\n",			   pci_name(asd_ha->pcidev));		err = -ENODEV;	}	asd_free_coherent(asd_ha, token); out:	asd_write_reg_dword(asd_ha, COMSTATEN, comstaten);	return err ? : asd_verify_seq(asd_ha, prog, size, lseq_mask);}#else /* ASD_DMA_MODE_DOWNLOAD */static int asd_download_seq(struct asd_ha_struct *asd_ha, const u8 *_prog,			    u32 size, u8 lseq_mask){	int i;	u32 reg = 0;	const u32 *prog = (u32 *) _prog;	if (size % 4) {		asd_printk("sequencer program not multiple of 4\n");		return -1;	}	asd_pause_cseq(asd_ha);	asd_pause_lseq(asd_ha, 0xFF);	reg |= (lseq_mask ? (((u32)lseq_mask) << 8) : OVLYCSEQ);	reg |= PIOCMODE;	asd_write_reg_dword(asd_ha, OVLYDMACNT, size);	asd_write_reg_dword(asd_ha, OVLYDMACTL, reg);	ASD_DPRINTK("downloading %s sequencer%s in PIO mode...\n",		    lseq_mask ? "LSEQ" : "CSEQ", lseq_mask ? "s" : "");	for (i = 0; i < size; i += 4, prog++)		asd_write_reg_dword(asd_ha, SPIODATA, *prog);	reg = (reg & ~PIOCMODE) | OVLYHALTERR;	asd_write_reg_dword(asd_ha, OVLYDMACTL, reg);	return asd_verify_seq(asd_ha, _prog, size, lseq_mask);}#endif /* ASD_DMA_MODE_DOWNLOAD *//** * asd_seq_download_seqs - download the sequencer microcode * @asd_ha: pointer to host adapter structure * * Download the central and link sequencer microcode. */static int asd_seq_download_seqs(struct asd_ha_struct *asd_ha){	int 	err;	if (!asd_ha->hw_prof.enabled_phys) {		asd_printk("%s: no enabled phys!\n", pci_name(asd_ha->pcidev));		return -ENODEV;	}	/* Download the CSEQ */	ASD_DPRINTK("downloading CSEQ...\n");	err = asd_download_seq(asd_ha, cseq_code, cseq_code_size, 0);	if (err) {		asd_printk("CSEQ download failed:%d\n", err);		return err;	}	/* Download the Link Sequencers code. All of the Link Sequencers	 * microcode can be downloaded at the same time.	 */	ASD_DPRINTK("downloading LSEQs...\n");	err = asd_download_seq(asd_ha, lseq_code, lseq_code_size,			       asd_ha->hw_prof.enabled_phys);	if (err) {		/* Try it one at a time */		u8 lseq;		u8 lseq_mask = asd_ha->hw_prof.enabled_phys;		for_each_sequencer(lseq_mask, lseq_mask, lseq) {			err = asd_download_seq(asd_ha, lseq_code,					       lseq_code_size, 1<<lseq);			if (err)				break;		}	}	if (err)		asd_printk("LSEQs download failed:%d\n", err);	return err;}/* ---------- Initializing the chip, chip memory, etc. ---------- *//** * asd_init_cseq_mip - initialize CSEQ mode independent pages 4-7 * @asd_ha: pointer to host adapter structure */static void asd_init_cseq_mip(struct asd_ha_struct *asd_ha){	/* CSEQ Mode Independent, page 4 setup. */	asd_write_reg_word(asd_ha, CSEQ_Q_EXE_HEAD, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_EXE_TAIL, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_DONE_HEAD, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_DONE_TAIL, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_SEND_HEAD, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_SEND_TAIL, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_DMA2CHIM_HEAD, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_DMA2CHIM_TAIL, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_COPY_HEAD, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_COPY_TAIL, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_REG0, 0);	asd_write_reg_word(asd_ha, CSEQ_REG1, 0);	asd_write_reg_dword(asd_ha, CSEQ_REG2, 0);	asd_write_reg_byte(asd_ha, CSEQ_LINK_CTL_Q_MAP, 0);	{		u8 con = asd_read_reg_byte(asd_ha, CCONEXIST);		u8 val = hweight8(con);		asd_write_reg_byte(asd_ha, CSEQ_MAX_CSEQ_MODE, (val<<4)|val);	}	asd_write_reg_word(asd_ha, CSEQ_FREE_LIST_HACK_COUNT, 0);	/* CSEQ Mode independent, page 5 setup. */	asd_write_reg_dword(asd_ha, CSEQ_EST_NEXUS_REQ_QUEUE, 0);	asd_write_reg_dword(asd_ha, CSEQ_EST_NEXUS_REQ_QUEUE+4, 0);	asd_write_reg_dword(asd_ha, CSEQ_EST_NEXUS_REQ_COUNT, 0);	asd_write_reg_dword(asd_ha, CSEQ_EST_NEXUS_REQ_COUNT+4, 0);	asd_write_reg_word(asd_ha, CSEQ_Q_EST_NEXUS_HEAD, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_EST_NEXUS_TAIL, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_NEED_EST_NEXUS_SCB, 0);	asd_write_reg_byte(asd_ha, CSEQ_EST_NEXUS_REQ_HEAD, 0);	asd_write_reg_byte(asd_ha, CSEQ_EST_NEXUS_REQ_TAIL, 0);	asd_write_reg_byte(asd_ha, CSEQ_EST_NEXUS_SCB_OFFSET, 0);	/* CSEQ Mode independent, page 6 setup. */	asd_write_reg_word(asd_ha, CSEQ_INT_ROUT_RET_ADDR0, 0);	asd_write_reg_word(asd_ha, CSEQ_INT_ROUT_RET_ADDR1, 0);	asd_write_reg_word(asd_ha, CSEQ_INT_ROUT_SCBPTR, 0);	asd_write_reg_byte(asd_ha, CSEQ_INT_ROUT_MODE, 0);	asd_write_reg_byte(asd_ha, CSEQ_ISR_SCRATCH_FLAGS, 0);	asd_write_reg_word(asd_ha, CSEQ_ISR_SAVE_SINDEX, 0);	asd_write_reg_word(asd_ha, CSEQ_ISR_SAVE_DINDEX, 0);	asd_write_reg_word(asd_ha, CSEQ_Q_MONIRTT_HEAD, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_MONIRTT_TAIL, 0xFFFF);	/* Calculate the free scb mask. */	{		u16 cmdctx = asd_get_cmdctx_size(asd_ha);		cmdctx = (~((cmdctx/128)-1)) >> 8;		asd_write_reg_byte(asd_ha, CSEQ_FREE_SCB_MASK, (u8)cmdctx);	}	asd_write_reg_word(asd_ha, CSEQ_BUILTIN_FREE_SCB_HEAD,			   first_scb_site_no);	asd_write_reg_word(asd_ha, CSEQ_BUILTIN_FREE_SCB_TAIL,			   last_scb_site_no);	asd_write_reg_word(asd_ha, CSEQ_EXTENDED_FREE_SCB_HEAD, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_EXTENDED_FREE_SCB_TAIL, 0xFFFF);	/* CSEQ Mode independent, page 7 setup. */	asd_write_reg_dword(asd_ha, CSEQ_EMPTY_REQ_QUEUE, 0);	asd_write_reg_dword(asd_ha, CSEQ_EMPTY_REQ_QUEUE+4, 0);	asd_write_reg_dword(asd_ha, CSEQ_EMPTY_REQ_COUNT, 0);	asd_write_reg_dword(asd_ha, CSEQ_EMPTY_REQ_COUNT+4, 0);	asd_write_reg_word(asd_ha, CSEQ_Q_EMPTY_HEAD, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_Q_EMPTY_TAIL, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_NEED_EMPTY_SCB, 0);	asd_write_reg_byte(asd_ha, CSEQ_EMPTY_REQ_HEAD, 0);	asd_write_reg_byte(asd_ha, CSEQ_EMPTY_REQ_TAIL, 0);	asd_write_reg_byte(asd_ha, CSEQ_EMPTY_SCB_OFFSET, 0);	asd_write_reg_word(asd_ha, CSEQ_PRIMITIVE_DATA, 0);	asd_write_reg_dword(asd_ha, CSEQ_TIMEOUT_CONST, 0);}/** * asd_init_cseq_mdp - initialize CSEQ Mode dependent pages * @asd_ha: pointer to host adapter structure */static void asd_init_cseq_mdp(struct asd_ha_struct *asd_ha){	int	i;	int	moffs;	moffs = CSEQ_PAGE_SIZE * 2;	/* CSEQ Mode dependent, modes 0-7, page 0 setup. */	for (i = 0; i < 8; i++) {		asd_write_reg_word(asd_ha, i*moffs+CSEQ_LRM_SAVE_SINDEX, 0);		asd_write_reg_word(asd_ha, i*moffs+CSEQ_LRM_SAVE_SCBPTR, 0);		asd_write_reg_word(asd_ha, i*moffs+CSEQ_Q_LINK_HEAD, 0xFFFF);		asd_write_reg_word(asd_ha, i*moffs+CSEQ_Q_LINK_TAIL, 0xFFFF);		asd_write_reg_byte(asd_ha, i*moffs+CSEQ_LRM_SAVE_SCRPAGE, 0);	}	/* CSEQ Mode dependent, mode 0-7, page 1 and 2 shall be ignored. */	/* CSEQ Mode dependent, mode 8, page 0 setup. */	asd_write_reg_word(asd_ha, CSEQ_RET_ADDR, 0xFFFF);	asd_write_reg_word(asd_ha, CSEQ_RET_SCBPTR, 0);	asd_write_reg_word(asd_ha, CSEQ_SAVE_SCBPTR, 0);	asd_write_reg_word(asd_ha, CSEQ_EMPTY_TRANS_CTX, 0);	asd_write_reg_word(asd_ha, CSEQ_RESP_LEN, 0);	asd_write_reg_word(asd_ha, CSEQ_TMF_SCBPTR, 0);	asd_write_reg_word(asd_ha, CSEQ_GLOBAL_PREV_SCB, 0);	asd_write_reg_word(asd_ha, CSEQ_GLOBAL_HEAD, 0);	asd_write_reg_word(asd_ha, CSEQ_CLEAR_LU_HEAD, 0);	asd_write_reg_byte(asd_ha, CSEQ_TMF_OPCODE, 0);	asd_write_reg_byte(asd_ha, CSEQ_SCRATCH_FLAGS, 0);	asd_write_reg_word(asd_ha, CSEQ_HSB_SITE, 0);	asd_write_reg_word(asd_ha, CSEQ_FIRST_INV_SCB_SITE,			   (u16)last_scb_site_no+1);	asd_write_reg_word(asd_ha, CSEQ_FIRST_INV_DDB_SITE,			   (u16)asd_ha->hw_prof.max_ddbs);	/* CSEQ Mode dependent, mode 8, page 1 setup. */	asd_write_reg_dword(asd_ha, CSEQ_LUN_TO_CLEAR, 0);	asd_write_reg_dword(asd_ha, CSEQ_LUN_TO_CLEAR + 4, 0);	asd_write_reg_dword(asd_ha, CSEQ_LUN_TO_CHECK, 0);	asd_write_reg_dword(asd_ha, CSEQ_LUN_TO_CHECK + 4, 0);	/* CSEQ Mode dependent, mode 8, page 2 setup. */	/* Tell the sequencer the bus address of the first SCB. */	asd_write_reg_addr(asd_ha, CSEQ_HQ_NEW_POINTER,			   asd_ha->seq.next_scb.dma_handle);	ASD_DPRINTK("First SCB dma_handle: 0x%llx\n",		    (unsigned long long)asd_ha->seq.next_scb.dma_handle);	/* Tell the sequencer the first Done List entry address. */	asd_write_reg_addr(asd_ha, CSEQ_HQ_DONE_BASE,			   asd_ha->seq.actual_dl->dma_handle);	/* Initialize the Q_DONE_POINTER with the least significant	 * 4 bytes of the first Done List address. */	asd_write_reg_dword(asd_ha, CSEQ_HQ_DONE_POINTER,			    ASD_BUSADDR_LO(asd_ha->seq.actual_dl->dma_handle));	asd_write_reg_byte(asd_ha, CSEQ_HQ_DONE_PASS, ASD_DEF_DL_TOGGLE);	/* CSEQ Mode dependent, mode 8, page 3 shall be ignored. */}/** * asd_init_cseq_scratch -- setup and init CSEQ * @asd_ha: pointer to host adapter structure * * Setup and initialize Central sequencers. Initialiaze the mode * independent and dependent scratch page to the default settings. */static void asd_init_cseq_scratch(struct asd_ha_struct *asd_ha){	asd_init_cseq_mip(asd_ha);	asd_init_cseq_mdp(asd_ha);}/** * asd_init_lseq_mip -- initialize LSEQ Mode independent pages 0-3 * @asd_ha: pointer to host adapter structure */static void asd_init_lseq_mip(struct asd_ha_struct *asd_ha, u8 lseq){	int i;	/* LSEQ Mode independent page 0 setup. */	asd_write_reg_word(asd_ha, LmSEQ_Q_TGTXFR_HEAD(lseq), 0xFFFF);	asd_write_reg_word(asd_ha, LmSEQ_Q_TGTXFR_TAIL(lseq), 0xFFFF);	asd_write_reg_byte(asd_ha, LmSEQ_LINK_NUMBER(lseq), lseq);	asd_write_reg_byte(asd_ha, LmSEQ_SCRATCH_FLAGS(lseq),			   ASD_NOTIFY_ENABLE_SPINUP);	asd_write_reg_dword(asd_ha, LmSEQ_CONNECTION_STATE(lseq),0x08000000);	asd_write_reg_word(asd_ha, LmSEQ_CONCTL(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_CONSTAT(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_CONNECTION_MODES(lseq), 0);	asd_write_reg_word(asd_ha, LmSEQ_REG1_ISR(lseq), 0);	asd_write_reg_word(asd_ha, LmSEQ_REG2_ISR(lseq), 0);	asd_write_reg_word(asd_ha, LmSEQ_REG3_ISR(lseq), 0);	asd_write_reg_dword(asd_ha, LmSEQ_REG0_ISR(lseq), 0);	asd_write_reg_dword(asd_ha, LmSEQ_REG0_ISR(lseq)+4, 0);	/* LSEQ Mode independent page 1 setup. */	asd_write_reg_word(asd_ha, LmSEQ_EST_NEXUS_SCBPTR0(lseq), 0xFFFF);	asd_write_reg_word(asd_ha, LmSEQ_EST_NEXUS_SCBPTR1(lseq), 0xFFFF);	asd_write_reg_word(asd_ha, LmSEQ_EST_NEXUS_SCBPTR2(lseq), 0xFFFF);	asd_write_reg_word(asd_ha, LmSEQ_EST_NEXUS_SCBPTR3(lseq), 0xFFFF);	asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_OPCODE0(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_OPCODE1(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_OPCODE2(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_OPCODE3(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_HEAD(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_TAIL(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_BUF_AVAIL(lseq), 0);	asd_write_reg_dword(asd_ha, LmSEQ_TIMEOUT_CONST(lseq), 0);	asd_write_reg_word(asd_ha, LmSEQ_ISR_SAVE_SINDEX(lseq), 0);	asd_write_reg_word(asd_ha, LmSEQ_ISR_SAVE_DINDEX(lseq), 0);	/* LSEQ Mode Independent page 2 setup. */	asd_write_reg_word(asd_ha, LmSEQ_EMPTY_SCB_PTR0(lseq), 0xFFFF);	asd_write_reg_word(asd_ha, LmSEQ_EMPTY_SCB_PTR1(lseq), 0xFFFF);	asd_write_reg_word(asd_ha, LmSEQ_EMPTY_SCB_PTR2(lseq), 0xFFFF);	asd_write_reg_word(asd_ha, LmSEQ_EMPTY_SCB_PTR3(lseq), 0xFFFF);	asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_OPCD0(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_OPCD1(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_OPCD2(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_OPCD3(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_HEAD(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_TAIL(lseq), 0);	asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_BUFS_AVAIL(lseq), 0);	for (i = 0; i < 12; i += 4)		asd_write_reg_dword(asd_ha, LmSEQ_ATA_SCR_REGS(lseq) + i, 0);	/* LSEQ Mode Independent page 3 setup. */	/* Device present timer timeout */	asd_write_reg_dword(asd_ha, LmSEQ_DEV_PRES_TMR_TOUT_CONST(lseq),			    ASD_DEV_PRESENT_TIMEOUT);	/* SATA interlock timer disabled */	asd_write_reg_dword(asd_ha, LmSEQ_SATA_INTERLOCK_TIMEOUT(lseq),			    ASD_SATA_INTERLOCK_TIMEOUT);	/* STP shutdown timer timeout constant, IGNORED by the sequencer,	 * always 0. */	asd_write_reg_dword(asd_ha, LmSEQ_STP_SHUTDOWN_TIMEOUT(lseq),			    ASD_STP_SHUTDOWN_TIMEOUT);	asd_write_reg_dword(asd_ha, LmSEQ_SRST_ASSERT_TIMEOUT(lseq),			    ASD_SRST_ASSERT_TIMEOUT);	asd_write_reg_dword(asd_ha, LmSEQ_RCV_FIS_TIMEOUT(lseq),			    ASD_RCV_FIS_TIMEOUT);	asd_write_reg_dword(asd_ha, LmSEQ_ONE_MILLISEC_TIMEOUT(lseq),			    ASD_ONE_MILLISEC_TIMEOUT);	/* COM_INIT timer */	asd_write_reg_dword(asd_ha, LmSEQ_TEN_MS_COMINIT_TIMEOUT(lseq),			    ASD_TEN_MILLISEC_TIMEOUT);	asd_write_reg_dword(asd_ha, LmSEQ_SMP_RCV_TIMEOUT(lseq),			    ASD_SMP_RCV_TIMEOUT);}/** * asd_init_lseq_mdp -- initialize LSEQ mode dependent pages. * @asd_ha: pointer to host adapter structure */static void asd_init_lseq_mdp(struct asd_ha_struct *asd_ha,  int lseq){	int    i;	u32    moffs;	u16 ret_addr[] = {		0xFFFF,		  /* mode 0 */		0xFFFF,		  /* mode 1 */		mode2_task,	  /* mode 2 */

⌨️ 快捷键说明

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