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

📄 aic7xxx_inline.h

📁 linux-2.6.15.6
💻 H
📖 第 1 页 / 共 2 页
字号:
	ahc_outb(ahc, port+1, ((value) >> 8) & 0xFF);	ahc_outb(ahc, port+2, ((value) >> 16) & 0xFF);	ahc_outb(ahc, port+3, ((value) >> 24) & 0xFF);}static __inline uint64_tahc_inq(struct ahc_softc *ahc, u_int port){	return ((ahc_inb(ahc, port))	      | (ahc_inb(ahc, port+1) << 8)	      | (ahc_inb(ahc, port+2) << 16)	      | (ahc_inb(ahc, port+3) << 24)	      | (((uint64_t)ahc_inb(ahc, port+4)) << 32)	      | (((uint64_t)ahc_inb(ahc, port+5)) << 40)	      | (((uint64_t)ahc_inb(ahc, port+6)) << 48)	      | (((uint64_t)ahc_inb(ahc, port+7)) << 56));}static __inline voidahc_outq(struct ahc_softc *ahc, u_int port, uint64_t value){	ahc_outb(ahc, port, value & 0xFF);	ahc_outb(ahc, port+1, (value >> 8) & 0xFF);	ahc_outb(ahc, port+2, (value >> 16) & 0xFF);	ahc_outb(ahc, port+3, (value >> 24) & 0xFF);	ahc_outb(ahc, port+4, (value >> 32) & 0xFF);	ahc_outb(ahc, port+5, (value >> 40) & 0xFF);	ahc_outb(ahc, port+6, (value >> 48) & 0xFF);	ahc_outb(ahc, port+7, (value >> 56) & 0xFF);}/* * 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_htole32(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);	/*	 * Setup data "oddness".	 */	scb->hscb->lun &= LID;	if (ahc_get_transfer_length(scb) & 0x1)		scb->hscb->lun |= SCB_XFERLEN_ODD;	/*	 * Keep a history of SCBs we've downloaded in the qinfifo.	 */	ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;	/*	 * Make sure our data is consistent 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 int	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->flags & AHC_TQINFIFO_BLOCKED) == 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 intahc_intr(struct ahc_softc *ahc){	u_int	intstat;	if ((ahc->pause & INTEN) == 0) {		/*		 * Our interrupt is not enabled on the chip		 * and may be disabled for re-entrancy reasons,		 * so just return.  This is likely just a shared		 * interrupt.		 */		return (0);	}	/*	 * 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 & 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 (0);	}	ahc->unsolicited_ints = 0;	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);		ahc_run_qoutfifo(ahc);#ifdef AHC_TARGET_MODE		if ((ahc->flags & AHC_TARGETROLE) != 0)			ahc_run_tqinfifo(ahc, /*paused*/FALSE);#endif	}	/*	 * Handle statuses that may invalidate our cached	 * copy of INTSTAT separately.	 */	if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) {		/* Hot eject.  Do nothing */	} else if (intstat & BRKADRINT) {		ahc_handle_brkadrint(ahc);	} else 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);	}	return (1);}#endif  /* _AIC7XXX_INLINE_H_ */

⌨️ 快捷键说明

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