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

📄 aic7xxx.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
		       ahc_inb(ahc, SCB_CONTROL));		printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",		       ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));		ahc_dump_card_state(ahc);		panic("for safety");		break;	}	default:		printf("ahc_intr: seqint, "		       "intstat == 0x%x, scsisigi = 0x%x\n",		       intstat, ahc_inb(ahc, SCSISIGI));		break;	}unpause:	/*	 *  The sequencer is paused immediately on	 *  a SEQINT, so we should restart it when	 *  we're done.	 */	ahc_unpause(ahc);}voidahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat){	u_int	scb_index;	u_int	status0;	u_int	status;	struct	scb *scb;	char	cur_channel;	char	intr_channel;	/* Make sure the sequencer is in a safe location. */	ahc_clear_critical_section(ahc);	if ((ahc->features & AHC_TWIN) != 0	 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))		cur_channel = 'B';	else		cur_channel = 'A';	intr_channel = cur_channel;	if ((ahc->features & AHC_ULTRA2) != 0)		status0 = ahc_inb(ahc, SSTAT0) & IOERR;	else		status0 = 0;	status = ahc_inb(ahc, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);	if (status == 0 && status0 == 0) {		if ((ahc->features & AHC_TWIN) != 0) {			/* Try the other channel */		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);			status = ahc_inb(ahc, SSTAT1)			       & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);			intr_channel = (cur_channel == 'A') ? 'B' : 'A';		}		if (status == 0) {			printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));			ahc_outb(ahc, CLRINT, CLRSCSIINT);			ahc_unpause(ahc);			return;		}	}	scb_index = ahc_inb(ahc, SCB_TAG);	scb = ahc_lookup_scb(ahc, scb_index);	if (scb != NULL	 && (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) == 0)		scb = NULL;	if ((ahc->features & AHC_ULTRA2) != 0	 && (status0 & IOERR) != 0) {		int now_lvd;		now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;		printf("%s: Transceiver State Has Changed to %s mode\n",		       ahc_name(ahc), now_lvd ? "LVD" : "SE");		ahc_outb(ahc, CLRSINT0, CLRIOERR);		/*		 * When transitioning to SE mode, the reset line		 * glitches, triggering an arbitration bug in some		 * Ultra2 controllers.  This bug is cleared when we		 * assert the reset line.  Since a reset glitch has		 * already occurred with this transition and a		 * transceiver state change is handled just like		 * a bus reset anyway, asserting the reset line		 * ourselves is safe.		 */		ahc_reset_channel(ahc, intr_channel,				 /*Initiate Reset*/now_lvd == 0);	} else if ((status & SCSIRSTI) != 0) {		printf("%s: Someone reset channel %c\n",			ahc_name(ahc), intr_channel);		if (intr_channel != cur_channel)		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);		ahc_reset_channel(ahc, intr_channel, /*Initiate Reset*/FALSE);	} else if ((status & SCSIPERR) != 0) {		/*		 * Determine the bus phase and queue an appropriate message.		 * SCSIPERR is latched true as soon as a parity error		 * occurs.  If the sequencer acked the transfer that		 * caused the parity error and the currently presented		 * transfer on the bus has correct parity, SCSIPERR will		 * be cleared by CLRSCSIPERR.  Use this to determine if		 * we should look at the last phase the sequencer recorded,		 * or the current phase presented on the bus.		 */		u_int mesg_out;		u_int curphase;		u_int errorphase;		u_int lastphase;		u_int scsirate;		u_int i;		u_int sstat2;		lastphase = ahc_inb(ahc, LASTPHASE);		curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;		sstat2 = ahc_inb(ahc, SSTAT2);		ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);		/*		 * For all phases save DATA, the sequencer won't		 * automatically ack a byte that has a parity error		 * in it.  So the only way that the current phase		 * could be 'data-in' is if the parity error is for		 * an already acked byte in the data phase.  During		 * synchronous data-in transfers, we may actually		 * ack bytes before latching the current phase in		 * LASTPHASE, leading to the discrepancy between		 * curphase and lastphase.		 */		if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0		 || curphase == P_DATAIN || curphase == P_DATAIN_DT)			errorphase = curphase;		else			errorphase = lastphase;		for (i = 0; i < num_phases; i++) {			if (errorphase == ahc_phase_table[i].phase)				break;		}		mesg_out = ahc_phase_table[i].mesg_out;		if (scb != NULL)			ahc_print_path(ahc, scb);		else			printf("%s:%c:%d: ", ahc_name(ahc), intr_channel,			       SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)));		scsirate = ahc_inb(ahc, SCSIRATE);		printf("parity error detected %s. "		       "SEQADDR(0x%x) SCSIRATE(0x%x)\n",		       ahc_phase_table[i].phasemsg,		       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8),		       scsirate);		if ((ahc->features & AHC_DT) != 0) {			if ((sstat2 & CRCVALERR) != 0)				printf("\tCRC Value Mismatch\n");			if ((sstat2 & CRCENDERR) != 0)				printf("\tNo terminal CRC packet recevied\n");			if ((sstat2 & CRCREQERR) != 0)				printf("\tIllegal CRC packet request\n");			if ((sstat2 & DUAL_EDGE_ERR) != 0)				printf("\tUnexpected %sDT Data Phase\n",				       (scsirate & SINGLE_EDGE) ? "" : "non-");		}		/*		 * We've set the hardware to assert ATN if we   		 * get a parity error on "in" phases, so all we  		 * need to do is stuff the message buffer with		 * the appropriate message.  "In" phases have set		 * mesg_out to something other than MSG_NOP.		 */		if (mesg_out != MSG_NOOP) {			if (ahc->msg_type != MSG_TYPE_NONE)				ahc->send_msg_perror = TRUE;			else				ahc_outb(ahc, MSG_OUT, mesg_out);		}		/*		 * Force a renegotiation with this target just in		 * case we are out of sync for some external reason		 * unknown (or unreported) by the target.		 */		ahc_force_renegotiation(ahc);		ahc_outb(ahc, CLRINT, CLRSCSIINT);		ahc_unpause(ahc);	} else if ((status & SELTO) != 0) {		u_int	scbptr;		/* Stop the selection */		ahc_outb(ahc, SCSISEQ, 0);		/* No more pending messages */		ahc_clear_msg_state(ahc);		/* Clear interrupt state */		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);		ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);		/*		 * Although the driver does not care about the		 * 'Selection in Progress' status bit, the busy		 * LED does.  SELINGO is only cleared by a sucessfull		 * selection, so we must manually clear it to insure		 * the LED turns off just incase no future successful		 * selections occur (e.g. no devices on the bus).		 */		ahc_outb(ahc, CLRSINT0, CLRSELINGO);		scbptr = ahc_inb(ahc, WAITING_SCBH);		ahc_outb(ahc, SCBPTR, scbptr);		scb_index = ahc_inb(ahc, SCB_TAG);		scb = ahc_lookup_scb(ahc, scb_index);		if (scb == NULL) {			printf("%s: ahc_intr - referenced scb not "			       "valid during SELTO scb(%d, %d)\n",			       ahc_name(ahc), scbptr, scb_index);		} else {			ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);			ahc_freeze_devq(ahc, scb);		}		ahc_outb(ahc, CLRINT, CLRSCSIINT);		/*		 * Force a renegotiation with this target just in		 * case the cable was pulled and will later be		 * re-attached.  The target may forget its negotiation		 * settings with us should it attempt to reselect		 * during the interruption.  The target will not issue		 * a unit attention in this case, so we must always		 * renegotiate.		 */		ahc_force_renegotiation(ahc);		ahc_restart(ahc);	} else if ((status & BUSFREE) != 0		&& (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {		u_int lastphase;		u_int saved_scsiid;		u_int saved_lun;		u_int target;		u_int initiator_role_id;		char channel;		int printerror;		/*		 * Clear our selection hardware as soon as possible.		 * We may have an entry in the waiting Q for this target,		 * that is affected by this busfree and we don't want to		 * go about selecting the target while we handle the event.		 */		ahc_outb(ahc, SCSISEQ,			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));		/*		 * Disable busfree interrupts and clear the busfree		 * interrupt status.  We do this here so that several		 * bus transactions occur prior to clearing the SCSIINT		 * latch.  It can take a bit for the clearing to take effect.		 */		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);		ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);		/*		 * Look at what phase we were last in.		 * If its message out, chances are pretty good		 * that the busfree was in response to one of		 * our abort requests.		 */		lastphase = ahc_inb(ahc, LASTPHASE);		saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);		saved_lun = ahc_inb(ahc, SAVED_LUN);		target = SCSIID_TARGET(ahc, saved_scsiid);		initiator_role_id = SCSIID_OUR_ID(saved_scsiid);		channel = SCSIID_CHANNEL(ahc, saved_scsiid);		printerror = 1;		if (lastphase == P_MESGOUT) {			struct ahc_devinfo devinfo;			u_int tag;			ahc_fetch_devinfo(ahc, &devinfo);			tag = SCB_LIST_NULL;			if (ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT_TAG, TRUE)			 || ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT, TRUE)) {				if (ahc->msgout_buf[ahc->msgout_index - 1]				 == MSG_ABORT_TAG)					tag = scb->hscb->tag;				ahc_print_path(ahc, scb);				printf("SCB %d - Abort%s Completed.\n",				       scb->hscb->tag, tag == SCB_LIST_NULL ?				       "" : " Tag");				ahc_abort_scbs(ahc, target, channel,					       saved_lun, tag,					       ROLE_INITIATOR,					       CAM_REQ_ABORTED);				printerror = 0;			} else if (ahc_sent_msg(ahc, AHCMSG_1B,						MSG_BUS_DEV_RESET, TRUE)) {#ifdef __FreeBSD__				/*				 * Don't mark the user's request for this BDR				 * as completing with CAM_BDR_SENT.  CAM3				 * specifies CAM_REQ_CMP.				 */				if (scb != NULL				 && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV				 && ahc_match_scb(ahc, scb, target, channel,						  CAM_LUN_WILDCARD,						  SCB_LIST_NULL,						  ROLE_INITIATOR)) {					ahc_set_transaction_status(scb, CAM_REQ_CMP);				}#endif				ahc_compile_devinfo(&devinfo,						    initiator_role_id,						    target,						    CAM_LUN_WILDCARD,						    channel,						    ROLE_INITIATOR);				ahc_handle_devreset(ahc, &devinfo,						    CAM_BDR_SENT,						    "Bus Device Reset",						    /*verbose_level*/0);				printerror = 0;			} else if (ahc_sent_msg(ahc, AHCMSG_EXT,						MSG_EXT_PPR, FALSE)) {				struct ahc_initiator_tinfo *tinfo;				struct ahc_tmode_tstate *tstate;				/*				 * PPR Rejected.  Try non-ppr negotiation				 * and retry command.				 */				tinfo = ahc_fetch_transinfo(ahc,							    devinfo.channel,							    devinfo.our_scsiid,							    devinfo.target,							    &tstate);				tinfo->curr.transport_version = 2;				tinfo->goal.transport_version = 2;				tinfo->goal.ppr_options = 0;				ahc_qinfifo_requeue_tail(ahc, scb);				printerror = 0;			} else if (ahc_sent_msg(ahc, AHCMSG_EXT,						MSG_EXT_WDTR, FALSE)				|| ahc_sent_msg(ahc, AHCMSG_EXT,						MSG_EXT_SDTR, FALSE)) {				/*				 * Negotiation Rejected.  Go-async and				 * retry command.				 */				ahc_set_width(ahc, &devinfo,					      MSG_EXT_WDTR_BUS_8_BIT,					      AHC_TRANS_CUR|AHC_TRANS_GOAL,					      /*paused*/TRUE);				ahc_set_syncrate(ahc, &devinfo,						/*syncrate*/NULL,						/*period*/0, /*offset*/0,						/*ppr_options*/0,						AHC_TRANS_CUR|AHC_TRANS_GOAL,						/*paused*/TRUE);				ahc_qinfifo_requeue_tail(ahc, scb);				printerror = 0;			}		}		if (printerror != 0) {			u_int i;			if (scb != NULL) {				u_int tag;				if ((scb->hscb->control & TAG_ENB) != 0)					tag = scb->hscb->tag;				else					tag = SCB_LIST_NULL;				ahc_print_path(ahc, scb);				ahc_abort_scbs(ahc, target, channel,					       SCB_GET_LUN(scb), tag,					       ROLE_INITIATOR,					       CAM_UNEXP_BUSFREE);			} else {				/*				 * We had not fully identified this connection,				 * so we cannot abort anything.				 */				printf("%s: ", ahc_name(ahc));			}			for (i = 0; i < num_phases; i++) {				if (lastphase == ahc_phase_table[i].phase)					break;			}			printf("Unexpected busfree %s\n"			       "SEQADDR == 0x%x\n",			       ahc_phase_table[i].phasemsg,			       ahc_inb(ahc, SEQADDR0)				| (ahc_inb(ahc, SEQADDR1) << 8));		}		ahc_clear_msg_state(ahc);		ahc_outb(ahc, CLRINT, CLRSCSIINT);		ahc_restart(ahc);	} else {		printf("%s: Missing case in ahc_handle_scsiint. status = %x\n",		       ahc_name(ahc), status);		ahc_outb(ahc, CLRINT, CLRSCSIINT);	}}/* * Force renegotiation to occur the next time we initiate * a command to the current device. */static voidahc_force_renegotiation(struct ahc_softc *ahc){	struct	ahc_devinfo devinfo;	struct	ahc_initiator_tinfo *targ_info;	struct	ahc_tmode_tstate *tstate;	ahc_fetch_devinfo(ahc, &devinfo);	targ_info = ahc_fetch_transinfo(ahc,					devinfo.channel,					devinfo.our_scsiid,					devinfo.target,					&tstate);	ahc_update_neg_request(ahc, &devinfo, tstate,			       targ_info, /*force*/TRUE);}#define AHC_MAX_STEPS 2000voidahc_clear_critical_section(struct ahc_softc *ahc){	int	stepping;	int	steps;	u_int	simode0;	u_int	simode1;	if (ahc->num_critical_sections == 0)		return;	stepping = FALSE;	steps = 0;	simode0 = 0;	simode1 = 0;	for (;;) {		struct	cs *cs;		u_int	seqaddr;		u_int	i;

⌨️ 快捷键说明

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