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

📄 aic79xx_core.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
			       "Resetting bus\n", ahd_name(ahd));			ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);			return;		}		scb->flags |= SCB_TRANSMISSION_ERROR;	} else if ((lqistat1 & LQIBADLQI) != 0) {		printf("Need to handle BADLQI!\n");		ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);		return;	} else if ((perrdiag & (PARITYERR|LASTPHASE)) == PARITYERR) {		if ((curphase & ~P_DATAIN_DT) != 0) {			/* Ack the byte.  So we can continue. */			printf("Acking %s to clear perror\n",			       ahd_lookup_phase_entry(curphase)->phasemsg);			ahd_inb(ahd, SCSIDAT);		}			if (curphase == P_MESGIN)			msg_out = MSG_PARITY_ERROR;	}	/*	 * 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.	 */	ahd->send_msg_perror = msg_out;	ahd_outb(ahd, MSG_OUT, HOST_MSG);	ahd_outb(ahd, CLRINT, CLRSCSIINT);	ahd_unpause(ahd);}static voidahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1){	/*	 * Clear the sources of the interrupts.	 */	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);	ahd_outb(ahd, CLRLQIINT1, lqistat1);	/*	 * If the "illegal" phase changes were in response	 * to our ATN to flag a CRC error, AND we ended up	 * on packet boundaries, clear the error, restart the	 * LQI manager as appropriate, and go on our merry	 * way toward sending the message.  Otherwise, reset	 * the bus to clear the error.	 */	ahd_set_active_fifo(ahd);	if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0	 && (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) {		if ((lqistat1 & LQIPHASE_LQ) != 0) {			printf("LQIRETRY for LQIPHASE_LQ\n");			ahd_outb(ahd, LQCTL2, LQIRETRY);		} else if ((lqistat1 & LQIPHASE_NLQ) != 0) {			printf("LQICONTINUE for LQIPHASE_NLQ\n");			ahd_outb(ahd, LQCTL2, LQIRETRY);		} else			panic("ahd_handle_lqiphase_error: No phase errors\n");		ahd_dump_card_state(ahd);		ahd_outb(ahd, CLRINT, CLRSCSIINT);		ahd_unpause(ahd);	} else {		printf("Reseting Channel for LQI Phase error\n");		ahd_dump_card_state(ahd);		ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);	}}/* * Packetized unexpected or expected busfree. * Entered in MODE_SCSI. */static intahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime){	u_int lqostat1;	AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),			 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));	lqostat1 = ahd_inb(ahd, LQOSTAT1);	if ((lqostat1 & LQOBUSFREE) != 0) {		struct scb *scb;		u_int scbid;		u_int waiting_h;		u_int waiting_t;		u_int next;		if ((busfreetime & BUSFREE_LQO) == 0)			printf("%s: Warning, BUSFREE time is 0x%x.  "			       "Expected BUSFREE_LQO.\n",			       ahd_name(ahd), busfreetime);		scbid = ahd_get_scbptr(ahd);		scb = ahd_lookup_scb(ahd, scbid);		if (scb == NULL)		       panic("SCB not valid during LQOBUSFREE");		ahd_print_path(ahd, scb);		printf("Probable outgoing LQ CRC error.  Retrying command\n");		/*		 * Return the LQO manager to its idle loop.  It will		 * not do this automatically if the busfree occurs		 * after the first REQ of either the LQ or command		 * packet or between the LQ and command packet.		 */		ahd_outb(ahd, LQCTL2, ahd_inb(ahd, LQCTL2) | LQOTOIDLE);		/*		 * Clear the status.		 */		ahd_outb(ahd, CLRLQOINT1, CLRLQOBUSFREE);		if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {			ahd_outb(ahd, CLRLQOINT1, 0);		}		/*		 * The LQO manager detected an unexpected busfree		 * either:		 *		 * 1) During an outgoing LQ.		 * 2) After an outgoing LQ but before the first		 *    REQ of the command packet.		 * 3) During an outgoing command packet.		 *		 * In all cases, CURRSCB is pointing to the		 * SCB that encountered the failure.  Clean		 * up the queue, clear SELDO and LQOBUSFREE,		 * and allow the sequencer to restart the select		 * out at its lesure.		 */		ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);		ahd_outb(ahd, CLRSINT0, CLRSELDO);		waiting_h = ahd_inw(ahd, WAITING_TID_HEAD);		if (waiting_h != scbid) {			ahd_outw(ahd, WAITING_TID_HEAD, scbid);			waiting_t = ahd_inw(ahd, WAITING_TID_TAIL);			next = SCB_LIST_NULL;			if (waiting_t == waiting_h) {				ahd_outw(ahd, WAITING_TID_TAIL, scbid);			} else {				ahd_set_scbptr(ahd, waiting_h);				next = ahd_inw(ahd, SCB_NEXT2);			}			ahd_set_scbptr(ahd, scbid);			ahd_outw(ahd, SCB_NEXT2, next);		}		/* Return unpausing the sequencer. */		return (0);	}	if (ahd->src_mode != AHD_MODE_SCSI) {		u_int	scbid;		struct	scb *scb;		scbid = ahd_get_scbptr(ahd);		scb = ahd_lookup_scb(ahd, scbid);		ahd_print_path(ahd, scb);		printf("Unexpected PKT busfree condition\n");		ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A',			       SCB_GET_LUN(scb), SCB_GET_TAG(scb),			       ROLE_INITIATOR, CAM_UNEXP_BUSFREE);		/* Return restarting the sequencer. */		return (1);	}	printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd));	ahd_dump_card_state(ahd);	/* Restart the sequencer. */	return (1);}/* * Non-packetized unexpected or expected busfree. */static intahd_handle_nonpkt_busfree(struct ahd_softc *ahd){	struct	ahd_devinfo devinfo;	struct	scb *scb;	u_int	lastphase;	u_int	saved_scsiid;	u_int	saved_lun;	u_int	target;	u_int	initiator_role_id;	u_int	scbid;	int	printerror;	/*	 * 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 = ahd_inb(ahd, LASTPHASE);	saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);	saved_lun = ahd_inb(ahd, SAVED_LUN);	target = SCSIID_TARGET(ahd, saved_scsiid);	initiator_role_id = SCSIID_OUR_ID(saved_scsiid);	ahd_compile_devinfo(&devinfo, initiator_role_id,			    target, saved_lun, 'A', ROLE_INITIATOR);	printerror = 1;	scbid = ahd_get_scbptr(ahd);	scb = ahd_lookup_scb(ahd, scbid);	if (scb != NULL	 && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)		scb = NULL;	if (lastphase == P_MESGOUT) {		u_int tag;		tag = SCB_LIST_NULL;		if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE)		 || ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) {			int found;			int sent_msg;			sent_msg = ahd->msgout_buf[ahd->msgout_index - 1];			ahd_print_path(ahd, scb);			printf("SCB %d - Abort%s Completed.\n",			       SCB_GET_TAG(scb),			       sent_msg == MSG_ABORT_TAG ? "" : " Tag");			if (sent_msg == MSG_ABORT_TAG)				tag = SCB_GET_TAG(scb);			if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) {				/*				 * This abort is in response to an				 * unexpected switch to command phase				 * for a packetized connection.  Since				 * the identify message was never sent,				 * "saved lun" is 0.  We really want to				 * abort only the SCB that encountered				 * this error, which could have a different				 * lun.  The SCB will be retried so the OS				 * will see the UA after renegotiating to				 * packetized.				 */				tag = SCB_GET_TAG(scb);				saved_lun = scb->hscb->lun;			}			found = ahd_abort_scbs(ahd, target, 'A', saved_lun,					       tag, ROLE_INITIATOR,					       CAM_REQ_ABORTED);			printf("found == 0x%x\n", found);			printerror = 0;		} else if (ahd_sent_msg(ahd, AHDMSG_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			 && ahd_match_scb(ahd, scb, target, 'A',					  CAM_LUN_WILDCARD, SCB_LIST_NULL,					  ROLE_INITIATOR))				ahd_set_transaction_status(scb, CAM_REQ_CMP);#endif			ahd_handle_devreset(ahd, &devinfo, CAM_BDR_SENT,					    "Bus Device Reset",					    /*verbose_level*/0);			printerror = 0;		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)) {			struct ahd_initiator_tinfo *tinfo;			struct ahd_tmode_tstate *tstate;			/*			 * PPR Rejected.  Try non-ppr negotiation			 * and retry command.			 */			tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,						    devinfo.our_scsiid,						    devinfo.target, &tstate);			tinfo->curr.transport_version = 2;			tinfo->goal.transport_version = 2;			tinfo->goal.ppr_options = 0;			ahd_qinfifo_requeue_tail(ahd, scb);			printerror = 0;		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)			|| ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)) {			/*			 * Negotiation Rejected.  Go-async and			 * retry command.			 */			ahd_set_width(ahd, &devinfo,				      MSG_EXT_WDTR_BUS_8_BIT,				      AHD_TRANS_CUR|AHD_TRANS_GOAL,				      /*paused*/TRUE);			ahd_set_syncrate(ahd, &devinfo,					/*period*/0, /*offset*/0,					/*ppr_options*/0,					AHD_TRANS_CUR|AHD_TRANS_GOAL,					/*paused*/TRUE);			ahd_qinfifo_requeue_tail(ahd, scb);			printerror = 0;		} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0			&& ahd_sent_msg(ahd, AHDMSG_1B,					 MSG_INITIATOR_DET_ERR, TRUE)) {#if AHD_DEBUG			if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)				printf("Expected IDE Busfree\n");#endif			printerror = 0;		}	} else if (lastphase == P_MESGIN) {		if ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0) {			ahd_freeze_devq(ahd, scb);			ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);			ahd_freeze_scb(scb);			if ((ahd->msg_flags & MSG_FLAG_IU_REQ_CHANGED) != 0) {				ahd_print_path(ahd, scb);				printf("Now %spacketized.\n",				       (scb->flags & SCB_PACKETIZED) == 0				     ? "" : "non-");				ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),					       SCB_GET_CHANNEL(ahd, scb),					       SCB_GET_LUN(scb), SCB_LIST_NULL,					       ROLE_INITIATOR, CAM_REQ_ABORTED);			} else {#if AHD_DEBUG				if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)					printf("PPR Negotiation Busfree.\n");#endif				ahd_done(ahd, scb);			}			printerror = 0;		}	}	if (printerror != 0) {		int aborted;		aborted = 0;		if (scb != NULL) {			u_int tag;			if ((scb->hscb->control & TAG_ENB) != 0)				tag = SCB_GET_TAG(scb);			else				tag = SCB_LIST_NULL;			ahd_print_path(ahd, scb);			aborted = ahd_abort_scbs(ahd, target, 'A',				       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: ", ahd_name(ahd));		}		if (lastphase != P_BUSFREE)			ahd_force_renegotiation(ahd, &devinfo);		printf("Unexpected busfree %s, %d SCBs aborted, "		       "PRGMCNT == 0x%x\n",		       ahd_lookup_phase_entry(lastphase)->phasemsg,		       aborted,		       ahd_inb(ahd, PRGMCNT)			| (ahd_inb(ahd, PRGMCNT+1) << 8));		ahd_dump_card_state(ahd);	}	/* Always restart the sequencer. */	return (1);}/* * Force renegotiation to occur the next time we initiate * a command to the current device. */static voidahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo){	struct	ahd_initiator_tinfo *targ_info;	struct	ahd_tmode_tstate *tstate;	printf("Forcing renegotiation (%d:%c:%d)\n",	       devinfo->our_scsiid, devinfo->channel, 	       devinfo->target);	targ_info = ahd_fetch_transinfo(ahd,					devinfo->channel,					devinfo->our_scsiid,					devinfo->target,					&tstate);	ahd_update_neg_request(ahd, devinfo, tstate,			       targ_info, /*force*/TRUE);}#define AHD_MAX_STEPS 2000voidahd_clear_critical_section(struct ahd_softc *ahd){	ahd_mode_state	saved_modes;	int		stepping;	int		steps;	u_int		simode0;	u_int		simode1;	u_int		simode3;	u_int		lqimode0;	u_int		lqimode1;	u_int		lqomode0;	u_int		lqomode1;	if (ahd->num_critical_sections == 0)		return;	stepping = FALSE;	steps = 0;	simode0 = 0;	simode1 = 0;	simode3 = 0;	lqimode0 = 0;	lqimode1 = 0;	lqomode0 = 0;	lqomode1 = 0;	saved_modes = ahd_save_modes(ahd);	for (;;) {		struct	cs *cs;		u_int	seqaddr;		u_int	i;		ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);		seqaddr = ahd_inb(ahd, CURADDR)			| (ahd_inb(ahd, CURADDR+1) << 8);		cs = ahd->critical_sections;

⌨️ 快捷键说明

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