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

📄 aic79xx_core.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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;	u_int	ppr_busfree;	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;	ppr_busfree = (ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0;	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;			if (scb == NULL) {				ahd_print_devinfo(ahd, &devinfo);				printf("Abort for unidentified "				       "connection completed.\n");				/* restart the sequencer. */				return (1);			}			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_LUN_WILDCARD,					    CAM_BDR_SENT, "Bus Device Reset",					    /*verbose_level*/0);			printerror = 0;		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)			&& ppr_busfree == 0) {			struct ahd_initiator_tinfo *tinfo;			struct ahd_tmode_tstate *tstate;			/*			 * PPR Rejected.  Try non-ppr negotiation			 * and retry command.			 */#ifdef AHD_DEBUG			if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)				printf("PPR negotiation rejected busfree.\n");#endif			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)			&& ppr_busfree == 0) {			/*			 * Negotiation Rejected.  Go-narrow and			 * retry command.			 */#ifdef AHD_DEBUG			if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)				printf("WDTR negotiation rejected busfree.\n");#endif			ahd_set_width(ahd, &devinfo,				      MSG_EXT_WDTR_BUS_8_BIT,				      AHD_TRANS_CUR|AHD_TRANS_GOAL,				      /*paused*/TRUE);			ahd_qinfifo_requeue_tail(ahd, scb);			printerror = 0;		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)			&& ppr_busfree == 0) {			/*			 * Negotiation Rejected.  Go-async and			 * retry command.			 */#ifdef AHD_DEBUG			if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)				printf("SDTR negotiation rejected busfree.\n");#endif			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)) {#ifdef AHD_DEBUG			if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)				printf("Expected IDE Busfree\n");#endif			printerror = 0;		} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE)			&& ahd_sent_msg(ahd, AHDMSG_1B,					MSG_MESSAGE_REJECT, TRUE)) {#ifdef AHD_DEBUG			if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)				printf("Expected QAS Reject Busfree\n");#endif			printerror = 0;		}	}	/*	 * The busfree required flag is honored at the end of	 * the message phases.  We check it last in case we	 * had to send some other message that caused a busfree.	 */	if (printerror != 0	 && (lastphase == P_MESGIN || lastphase == P_MESGOUT)	 && ((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_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 {#ifdef 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);}static voidahd_handle_proto_violation(struct ahd_softc *ahd){	struct	ahd_devinfo devinfo;	struct	scb *scb;	u_int	scbid;	u_int	seq_flags;	u_int	curphase;	u_int	lastphase;	int	found;	ahd_fetch_devinfo(ahd, &devinfo);	scbid = ahd_get_scbptr(ahd);	scb = ahd_lookup_scb(ahd, scbid);	seq_flags = ahd_inb(ahd, SEQ_FLAGS);	curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;	lastphase = ahd_inb(ahd, LASTPHASE);	if ((seq_flags & NOT_IDENTIFIED) != 0) {		/*		 * The reconnecting target either did not send an		 * identify message, or did, but we didn't find an SCB		 * to match.		 */		ahd_print_devinfo(ahd, &devinfo);		printf("Target did not send an IDENTIFY message. "		       "LASTPHASE = 0x%x.\n", lastphase);		scb = NULL;	} else if (scb == NULL) {		/*		 * We don't seem to have an SCB active for this		 * transaction.  Print an error and reset the bus.		 */		ahd_print_devinfo(ahd, &devinfo);		printf("No SCB found during protocol violation\n");		goto proto_violation_reset;	} else {		ahd_set_transaction_status(scb, CAM_SEQUENCE_FAIL);		if ((seq_flags & NO_CDB_SENT) != 0) {			ahd_print_path(ahd, scb);			printf("No or incomplete CDB sent to device.\n");		} else if ((ahd_inb_scbram(ahd, SCB_CONTROL)			  & STATUS_RCVD) == 0) {			/*			 * The target never bothered to provide status to			 * us prior to completing the command.  Since we don't			 * know the disposition of this command, we must attempt			 * to abort it.  Assert ATN and prepare to send an abort			 * message.			 */			ahd_print_path(ahd, scb);			printf("Completed command without status.\n");		} else {			ahd_print_path(ahd, scb);			printf("Unknown protocol violation.\n");			ahd_dump_card_state(ahd);		}	}	if ((lastphase & ~P_DATAIN_DT) == 0	 || lastphase == P_COMMAND) {proto_violation_reset:		/*		 * Target either went directly to data		 * phase or didn't respond to our ATN.		 * The only safe thing to do is to blow		 * it away with a bus reset.		 */		found = ahd_reset_channel(ahd, 'A', TRUE);		printf("%s: Issued Channel %c Bus Reset. "		       "%d SCBs aborted\n", ahd_name(ahd), 'A', found);	} else {		/*		 * Leave the selection hardware off in case		 * this abort attempt will affect yet to		 * be sent commands.		 */		ahd_outb(ahd, SCSISEQ0,			 ahd_inb(ahd, SCSISEQ0) & ~ENSELO);		ahd_assert_atn(ahd);		ahd_outb(ahd, MSG_OUT, HOST_MSG);		if (scb == NULL) {			ahd_print_devinfo(ahd, &devinfo);			ahd->msgout_buf[0] = MSG_ABORT_TASK;			ahd->msgout_len = 1;			ahd->msgout_index = 0;			ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;		} else {			ahd_print_path(ahd, scb);			scb->flags |= SCB_ABORT;		}		printf("Protocol violation %s.  Attempting to abort.\n",		       ahd_lookup_phase_entry(curphase)->phasemsg);	}}/* * 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;#ifdef AHD_DEBUG	if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {		ahd_print_devinfo(ahd, devinfo);		printf("Forcing renegotiation\n");	}#endif	targ_info = ahd_fetch_transinfo(ahd,					devinfo->channel,					devinfo->our_scsiid,					devinfo->target,					&tstate);	ahd_update_neg_request(ahd, devinfo, tstate,			       targ_info, AHD_NEG_IF_NON_ASYNC);}#define AHD_MAX_STEPS 2000voidahd_clear_critical_section(struct ahd_softc *ahd){	ahd_mode_state	saved_modes;	int		stepping;	int		steps;	int		first_instr;	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;	first_instr = 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;		for (i = 0; i < ahd->num_critical_sections; i++, cs++) {						if (cs->begin < seqaddr && cs->end >= seqaddr)				break;		}		if (i == ahd->num_critical_sections)			break;		if (steps > AHD_MAX_STEPS) {			printf("%s: Infinite loop in critical section\n"			       "%s: First Instruction 0x%x now 0x%x\n",			       ahd_name(ahd), ahd_name(ahd), first_instr,			       seqaddr);			ahd_dump_card_state(ahd);			panic("critical section loop");		}		steps++;#ifdef AHD_DEBUG		if ((ahd_debug & AHD_SHOW_MISC) != 0)			printf("%s: Single stepping at 0x%x\n", ahd_name(ahd),			       seqaddr);#endif		if (stepping == FALSE) {			first_instr = seqaddr;  			ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);  			simode0 = ahd_inb(ahd, SIMODE0);			simode3 = ahd_inb(ahd, SIMODE3);			lqimode0 = ahd_inb(ahd, LQIMODE0);			lqimode1 = ahd_inb(ahd, LQIMODE1);			lqomode0 = ahd_inb(ahd, LQOMODE0);			lqomode1 = ahd_inb(ahd, LQOMODE1);			ahd_outb(ahd, SIMODE0, 0);			ahd_outb(ahd, SIMODE3, 0);			ahd_outb(ahd, LQIMODE0, 0);			ahd_outb(ahd, LQIMODE1, 0);			ahd_outb(ahd, LQOMODE0, 0);			ahd_outb(ahd, LQOMODE1, 0);			ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);  			simode1 

⌨️ 快捷键说明

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