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

📄 aic7xxx_inline.h

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 H
📖 第 1 页 / 共 2 页
字号:
	return (&(*tstate)->transinfo[remote_id]);}/* * Get a free scb. If there are none, see if we can allocate a new SCB. */static __inline struct scb *ahc_get_scb(struct ahc_softc *ahc){	struct scb *scb;	if ((scb = SLIST_FIRST(&ahc->scb_data->free_scbs)) == NULL) {		ahc_alloc_scbs(ahc);		scb = SLIST_FIRST(&ahc->scb_data->free_scbs);		if (scb == NULL)			return (NULL);	}	SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links.sle);	return (scb);}/* * Return an SCB resource to the free list. */static __inline voidahc_free_scb(struct ahc_softc *ahc, struct scb *scb){       	struct hardware_scb *hscb;	hscb = scb->hscb;	/* Clean up for the next user */	ahc->scb_data->scbindex[hscb->tag] = NULL;	scb->flags = SCB_FREE;	hscb->control = 0;	SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links.sle);	/* Notify the OSM that a resource is now available. */	ahc_platform_scb_free(ahc, scb);}static __inline struct scb *ahc_lookup_scb(struct ahc_softc *ahc, u_int tag){	struct scb* scb;	scb = ahc->scb_data->scbindex[tag];	if (scb != NULL)		ahc_sync_scb(ahc, scb,			     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);	return (scb);}static __inline voidahc_swap_with_next_hscb(struct ahc_softc *ahc, struct scb *scb){	struct hardware_scb *q_hscb;	u_int  saved_tag;	/*	 * Our queuing method is a bit tricky.  The card	 * knows in advance which HSCB to download, and we	 * can't disappoint it.  To achieve this, the next	 * SCB to download is saved off in ahc->next_queued_scb.	 * When we are called to queue "an arbitrary scb",	 * we copy the contents of the incoming HSCB to the one	 * the sequencer knows about, swap HSCB pointers and	 * finally assign the SCB to the tag indexed location	 * in the scb_array.  This makes sure that we can still	 * locate the correct SCB by SCB_TAG.	 */	q_hscb = ahc->next_queued_scb->hscb;	saved_tag = q_hscb->tag;	memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));	if ((scb->flags & SCB_CDB32_PTR) != 0) {		q_hscb->shared_data.cdb_ptr =		    ahc_hscb_busaddr(ahc, q_hscb->tag)		  + offsetof(struct hardware_scb, cdb32);		}	q_hscb->tag = saved_tag;	q_hscb->next = scb->hscb->tag;	/* Now swap HSCB pointers. */	ahc->next_queued_scb->hscb = scb->hscb;	scb->hscb = q_hscb;	/* Now define the mapping from tag to SCB in the scbindex */	ahc->scb_data->scbindex[scb->hscb->tag] = scb;}/* * Tell the sequencer about a new transaction to execute. */static __inline voidahc_queue_scb(struct ahc_softc *ahc, struct scb *scb){	ahc_swap_with_next_hscb(ahc, scb);	if (scb->hscb->tag == SCB_LIST_NULL	 || scb->hscb->next == SCB_LIST_NULL)		panic("Attempt to queue invalid SCB tag %x:%x\n",		      scb->hscb->tag, scb->hscb->next);	/*	 * Keep a history of SCBs we've downloaded in the qinfifo.	 */	ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;	/*	 * Make sure our data is consistant from the	 * perspective of the adapter.	 */	ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);	/* Tell the adapter about the newly queued SCB */	if ((ahc->features & AHC_QUEUE_REGS) != 0) {		ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);	} else {		if ((ahc->features & AHC_AUTOPAUSE) == 0)			ahc_pause(ahc);		ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);		if ((ahc->features & AHC_AUTOPAUSE) == 0)			ahc_unpause(ahc);	}}static __inline struct scsi_sense_data *ahc_get_sense_buf(struct ahc_softc *ahc, struct scb *scb){	int offset;	offset = scb - ahc->scb_data->scbarray;	return (&ahc->scb_data->sense[offset]);}static __inline uint32_tahc_get_sense_bufaddr(struct ahc_softc *ahc, struct scb *scb){	int offset;	offset = scb - ahc->scb_data->scbarray;	return (ahc->scb_data->sense_busaddr	      + (offset * sizeof(struct scsi_sense_data)));}/************************** Interrupt Processing ******************************/static __inline void	ahc_sync_qoutfifo(struct ahc_softc *ahc, int op);static __inline void	ahc_sync_tqinfifo(struct ahc_softc *ahc, int op);static __inline u_int	ahc_check_cmdcmpltqueues(struct ahc_softc *ahc);static __inline void	ahc_intr(struct ahc_softc *ahc);static __inline voidahc_sync_qoutfifo(struct ahc_softc *ahc, int op){	ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,			/*offset*/0, /*len*/256, op);}static __inline voidahc_sync_tqinfifo(struct ahc_softc *ahc, int op){#ifdef AHC_TARGET_MODE	if ((ahc->flags & AHC_TARGETROLE) != 0) {		ahc_dmamap_sync(ahc, ahc->shared_data_dmat,				ahc->shared_data_dmamap,				ahc_targetcmd_offset(ahc, 0),				sizeof(struct target_cmd) * AHC_TMODE_CMDS,				op);	}#endif}/* * See if the firmware has posted any completed commands * into our in-core command complete fifos. */#define AHC_RUN_QOUTFIFO 0x1#define AHC_RUN_TQINFIFO 0x2static __inline u_intahc_check_cmdcmpltqueues(struct ahc_softc *ahc){	u_int retval;	retval = 0;	ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,			/*offset*/ahc->qoutfifonext, /*len*/1,			BUS_DMASYNC_POSTREAD);	if (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL)		retval |= AHC_RUN_QOUTFIFO;#ifdef AHC_TARGET_MODE	if ((ahc->flags & AHC_TARGETROLE) != 0) {		ahc_dmamap_sync(ahc, ahc->shared_data_dmat,				ahc->shared_data_dmamap,				ahc_targetcmd_offset(ahc, ahc->tqinfifofnext),				/*len*/sizeof(struct target_cmd),				BUS_DMASYNC_POSTREAD);		if (ahc->targetcmds[ahc->tqinfifonext].cmd_valid != 0)			retval |= AHC_RUN_TQINFIFO;	}#endif	return (retval);}/* * Catch an interrupt from the adapter */static __inline voidahc_intr(struct ahc_softc *ahc){	u_int	intstat;	/*	 * Instead of directly reading the interrupt status register,	 * infer the cause of the interrupt by checking our in-core	 * completion queues.  This avoids a costly PCI bus read in	 * most cases.	 */	if ((ahc->flags & (AHC_ALL_INTERRUPTS|AHC_EDGE_INTERRUPT)) == 0	 && (ahc_check_cmdcmpltqueues(ahc) != 0))		intstat = CMDCMPLT;	else {		intstat = ahc_inb(ahc, INTSTAT);	}	if (intstat & CMDCMPLT) {		ahc_outb(ahc, CLRINT, CLRCMDINT);		/*		 * Ensure that the chip sees that we've cleared		 * this interrupt before we walk the output fifo.		 * Otherwise, we may, due to posted bus writes,		 * clear the interrupt after we finish the scan,		 * and after the sequencer has added new entries		 * and asserted the interrupt again.		 */		ahc_flush_device_writes(ahc);#ifdef AHC_TARGET_MODE		if ((ahc->flags & AHC_INITIATORROLE) != 0)#endif			ahc_run_qoutfifo(ahc);#ifdef AHC_TARGET_MODE		if ((ahc->flags & AHC_TARGETROLE) != 0)			ahc_run_tqinfifo(ahc, /*paused*/FALSE);#endif	}	if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0)		/* Hot eject */		return;	if ((intstat & INT_PEND) == 0) {#if AHC_PCI_CONFIG > 0		if (ahc->unsolicited_ints > 500) {			ahc->unsolicited_ints = 0;			if ((ahc->chip & AHC_PCI) != 0			 && (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0)				ahc->bus_intr(ahc);		}#endif		ahc->unsolicited_ints++;		return;	}	ahc->unsolicited_ints = 0;	if (intstat & BRKADRINT) {		ahc_handle_brkadrint(ahc);		/* Fatal error, no more interrupts to handle. */		return;	}	if ((intstat & (SEQINT|SCSIINT)) != 0)		ahc_pause_bug_fix(ahc);	if ((intstat & SEQINT) != 0)		ahc_handle_seqint(ahc, intstat);	if ((intstat & SCSIINT) != 0)		ahc_handle_scsiint(ahc, intstat);}#endif  /* _AIC7XXX_INLINE_H_ */

⌨️ 快捷键说明

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