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

📄 aha152x.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#if defined(AHA152X_STAT)	} else {		HOSTDATA(shpnt)->busfree_without_done_command++;#endif	}	if(ISSUE_SC)		CURRENT_SC = remove_first_SC(&ISSUE_SC);	DO_UNLOCK(flags);	if(CURRENT_SC) {#if defined(AHA152X_STAT)		action++;#endif	    	CURRENT_SC->SCp.phase |= selecting;		DPRINTK(debug_selection, DEBUG_LEAD "selecting target\n", CMDINFO(CURRENT_SC));		/* clear selection timeout */		SETPORT(SSTAT1, SELTO);		SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);		SETPORT(SXFRCTL1, (PARITY ? ENSPCHK : 0 ) | ENSTIMER);		SETPORT(SCSISEQ, ENSELO | ENAUTOATNO | (DISCONNECTED_SC ? ENRESELI : 0));	} else {#if defined(AHA152X_STAT)		HOSTDATA(shpnt)->busfree_without_new_command++;#endif		SETPORT(SCSISEQ, DISCONNECTED_SC ? ENRESELI : 0);	}#if defined(AHA152X_STAT)	if(!action)		HOSTDATA(shpnt)->busfree_without_any_action++;#endif}/* * Selection done (OUT) * - queue IDENTIFY message and SDTR to selected target for message out *   (ATN asserted automagically via ENAUTOATNO in busfree()) */static void seldo_run(struct Scsi_Host *shpnt){	SETPORT(SCSISIG, 0);	SETPORT(SSTAT1, CLRBUSFREE);	SETPORT(SSTAT1, CLRPHASECHG);    	CURRENT_SC->SCp.phase &= ~(selecting|not_issued);	SETPORT(SCSISEQ, 0);	if (TESTLO(SSTAT0, SELDO)) {		printk(ERR_LEAD "aha152x: passing bus free condition\n", CMDINFO(CURRENT_SC));		done(shpnt, DID_NO_CONNECT << 16);		return;	}	SETPORT(SSTAT0, CLRSELDO);		ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->lun));	if (CURRENT_SC->SCp.phase & aborting) {		ADDMSGO(ABORT);	} else if (CURRENT_SC->SCp.phase & resetting) {		ADDMSGO(BUS_DEVICE_RESET);	} else if (SYNCNEG==0 && SYNCHRONOUS) {    		CURRENT_SC->SCp.phase |= syncneg;		ADDMSGO(EXTENDED_MESSAGE);		ADDMSGO(3);		ADDMSGO(EXTENDED_SDTR);		ADDMSGO(50);		/* 200ns */		ADDMSGO(8);		/* 8 byte req/ack offset */		SYNCNEG=1;		/* negotiation in progress */	}	SETRATE(SYNCRATE);}/* * Selection timeout * - return command to mid-level with failure cause * */static void selto_run(struct Scsi_Host *shpnt){	SETPORT(SCSISEQ, 0);			SETPORT(SSTAT1, CLRSELTIMO);	DPRINTK(debug_selection, DEBUG_LEAD "selection timeout\n", CMDINFO(CURRENT_SC));	if(!CURRENT_SC) {		DPRINTK(debug_selection, DEBUG_LEAD "!CURRENT_SC\n", CMDINFO(CURRENT_SC));		return;	}    	CURRENT_SC->SCp.phase &= ~selecting;	if (CURRENT_SC->SCp.phase & aborted) {		DPRINTK(debug_selection, DEBUG_LEAD "aborted\n", CMDINFO(CURRENT_SC));		done(shpnt, DID_ABORT << 16);	} else if (TESTLO(SSTAT0, SELINGO)) {		DPRINTK(debug_selection, DEBUG_LEAD "arbitration not won\n", CMDINFO(CURRENT_SC));		done(shpnt, DID_BUS_BUSY << 16);	} else {		/* ARBITRATION won, but SELECTION failed */		DPRINTK(debug_selection, DEBUG_LEAD "selection failed\n", CMDINFO(CURRENT_SC));		done(shpnt, DID_NO_CONNECT << 16);	}}/* * Selection in done * - put current command back to issue queue *   (reconnection of a disconnected nexus instead *    of successful selection out) * */static void seldi_run(struct Scsi_Host *shpnt){	int selid;	int target;	unsigned long flags;	SETPORT(SCSISIG, 0);	SETPORT(SSTAT0, CLRSELDI);	SETPORT(SSTAT1, CLRBUSFREE);	SETPORT(SSTAT1, CLRPHASECHG);	if(CURRENT_SC) {		if(!(CURRENT_SC->SCp.phase & not_issued))			printk(ERR_LEAD "command should not have been issued yet\n", CMDINFO(CURRENT_SC));		DPRINTK(debug_selection, ERR_LEAD "command requeued - reselection\n", CMDINFO(CURRENT_SC));		DO_LOCK(flags);		append_SC(&ISSUE_SC, CURRENT_SC);		DO_UNLOCK(flags);		CURRENT_SC = 0;	}	if(!DISCONNECTED_SC) {		DPRINTK(debug_selection, DEBUG_LEAD "unexpected SELDI ", CMDINFO(CURRENT_SC));		return;	}	RECONN_TARGET=-1;	selid = GETPORT(SELID) & ~(1 << shpnt->this_id);	if (selid==0) {		printk("aha152x%d: target id unknown (%02x)\n", HOSTNO, selid);		return;	}	for(target=7; !(selid & (1 << target)); target--)		;	if(selid & ~(1 << target)) {		printk("aha152x%d: multiple targets reconnected (%02x)\n",		       HOSTNO, selid);	}	SETPORT(SCSIID, (shpnt->this_id << OID_) | target);	SETPORT(SCSISEQ, 0);	SETRATE(HOSTDATA(shpnt)->syncrate[target]);	RECONN_TARGET=target;	DPRINTK(debug_selection, DEBUG_LEAD "target %d reselected (%02x).\n", CMDINFO(CURRENT_SC), target, selid);}/* * message in phase * - handle initial message after reconnection to identify *   reconnecting nexus * - queue command on DISCONNECTED_SC on DISCONNECT message * - set completed flag on COMMAND COMPLETE *   (other completition code moved to busfree_run) * - handle response to SDTR * - clear synchronous transfer agreements on BUS RESET * * FIXME: what about SAVE POINTERS, RESTORE POINTERS? * */static void msgi_run(struct Scsi_Host *shpnt){	for(;;) {		int sstat1 = GETPORT(SSTAT1);		if(sstat1 & (PHASECHG|PHASEMIS|BUSFREE) || !(sstat1 & REQINIT))			return;		if(TESTLO(SSTAT0,SPIORDY)) {			DPRINTK(debug_msgi, DEBUG_LEAD "!SPIORDY\n", CMDINFO(CURRENT_SC));			return;		}			ADDMSGI(GETPORT(SCSIDAT));#if defined(AHA152X_DEBUG)		if (HOSTDATA(shpnt)->debug & debug_msgi) {			printk(INFO_LEAD "inbound message %02x ", CMDINFO(CURRENT_SC), MSGI(0));			print_msg(&MSGI(0));			printk("\n");		}#endif		if(!CURRENT_SC) {			if(LASTSTATE!=seldi) {				printk(KERN_ERR "aha152x%d: message in w/o current command not after reselection\n", HOSTNO);			}			/*	 	 	 * Handle reselection	 		 */			if(!(MSGI(0) & IDENTIFY_BASE)) {				printk(KERN_ERR "aha152x%d: target didn't identify after reselection\n", HOSTNO);				continue;			}			CURRENT_SC = remove_lun_SC(&DISCONNECTED_SC, RECONN_TARGET, MSGI(0) & 0x3f);			if (!CURRENT_SC) {				show_queues(shpnt);				printk(KERN_ERR "aha152x%d: no disconnected command for target %d/%d\n", HOSTNO, RECONN_TARGET, MSGI(0) & 0x3f);				continue;			}			DPRINTK(debug_msgi, DEBUG_LEAD "target reconnected\n", CMDINFO(CURRENT_SC));			CURRENT_SC->SCp.Message = MSGI(0);			CURRENT_SC->SCp.phase &= ~disconnected;			MSGILEN=0;			/* next message if any */			continue;		} 		CURRENT_SC->SCp.Message = MSGI(0);		switch (MSGI(0)) {		case DISCONNECT:			if (!RECONNECT)				printk(WARN_LEAD "target was not allowed to disconnect\n", CMDINFO(CURRENT_SC));			CURRENT_SC->SCp.phase |= disconnected;			break;		case COMMAND_COMPLETE:			if(CURRENT_SC->SCp.phase & completed)				DPRINTK(debug_msgi, DEBUG_LEAD "again COMMAND COMPLETE\n", CMDINFO(CURRENT_SC));			CURRENT_SC->SCp.phase |= completed;			break;		case MESSAGE_REJECT:			if (SYNCNEG==1) {				printk(INFO_LEAD "Synchronous Data Transfer Request was rejected\n", CMDINFO(CURRENT_SC));				SYNCNEG=2;	/* negotiation completed */			} else				printk(INFO_LEAD "inbound message (MESSAGE REJECT)\n", CMDINFO(CURRENT_SC));			break;		case SAVE_POINTERS:			break;		case RESTORE_POINTERS:			break;		case EXTENDED_MESSAGE:			if(MSGILEN<2 || MSGILEN<MSGI(1)+2) {				/* not yet completed */				continue;			}			switch (MSGI(2)) {			case EXTENDED_SDTR:				{					long ticks;					if (MSGI(1) != 3) {						printk(ERR_LEAD "SDTR message length!=3\n", CMDINFO(CURRENT_SC));						break;					}					if (!HOSTDATA(shpnt)->synchronous)						break;					printk(INFO_LEAD, CMDINFO(CURRENT_SC));					print_msg(&MSGI(0));					printk("\n");					ticks = (MSGI(3) * 4 + 49) / 50;					if (syncneg) {						/* negotiation in progress */						if (ticks > 9 || MSGI(4) < 1 || MSGI(4) > 8) {							ADDMSGO(MESSAGE_REJECT);							printk(INFO_LEAD "received Synchronous Data Transfer Request invalid - rejected\n", CMDINFO(CURRENT_SC));							break;						}												SYNCRATE |= ((ticks - 2) << 4) + MSGI(4);					} else if (ticks <= 9 && MSGI(4) >= 1) {						ADDMSGO(EXTENDED_MESSAGE);						ADDMSGO(3);						ADDMSGO(EXTENDED_SDTR);						if (ticks < 4) {							ticks = 4;							ADDMSGO(50);						} else							ADDMSGO(MSGI(3));						if (MSGI(4) > 8)							MSGI(4) = 8;						ADDMSGO(MSGI(4));						SYNCRATE |= ((ticks - 2) << 4) + MSGI(4);					} else {						/* requested SDTR is too slow, do it asynchronously */						printk(INFO_LEAD "Synchronous Data Transfer Request too slow - Rejecting\n", CMDINFO(CURRENT_SC));						ADDMSGO(MESSAGE_REJECT);					}					SYNCNEG=2;		/* negotiation completed */					SETRATE(SYNCRATE);				}				break;			case BUS_DEVICE_RESET:				{					int i;					for(i=0; i<8; i++) {						HOSTDATA(shpnt)->syncrate[i]=0;						HOSTDATA(shpnt)->syncneg[i]=0;					}				}				break;			case EXTENDED_MODIFY_DATA_POINTER:			case EXTENDED_EXTENDED_IDENTIFY:			case EXTENDED_WDTR:			default:				ADDMSGO(MESSAGE_REJECT);				break;			}			break;		}		MSGILEN=0;	}}static void msgi_end(struct Scsi_Host *shpnt){	if(MSGILEN>0)		printk(WARN_LEAD "target left before message completed (%d)\n", CMDINFO(CURRENT_SC), MSGILEN);	if (MSGOLEN > 0 && !(GETPORT(SSTAT1) & BUSFREE)) {		DPRINTK(debug_msgi, DEBUG_LEAD "msgo pending\n", CMDINFO(CURRENT_SC));		SETPORT(SCSISIG, P_MSGI | SIG_ATNO);	} }/* * message out phase * */static void msgo_init(struct Scsi_Host *shpnt){	if(MSGOLEN==0) {		if((CURRENT_SC->SCp.phase & syncneg) && SYNCNEG==2 && SYNCRATE==0) {			ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->lun));		} else {			printk(INFO_LEAD "unexpected MESSAGE OUT phase; rejecting\n", CMDINFO(CURRENT_SC));			ADDMSGO(MESSAGE_REJECT);		}	}#if defined(AHA152X_DEBUG)	if(HOSTDATA(shpnt)->debug & debug_msgo) {		int i;		printk(DEBUG_LEAD "messages( ", CMDINFO(CURRENT_SC));		for (i=0; i<MSGOLEN; i+=print_msg(&MSGO(i)), printk(" "))			;		printk(")\n");	}#endif}/* * message out phase * */static void msgo_run(struct Scsi_Host *shpnt){	if(MSGO_I==MSGOLEN)		DPRINTK(debug_msgo, DEBUG_LEAD "messages all sent (%d/%d)\n", CMDINFO(CURRENT_SC), MSGO_I, MSGOLEN);	while(MSGO_I<MSGOLEN) {		DPRINTK(debug_msgo, DEBUG_LEAD "message byte %02x (%d/%d)\n", CMDINFO(CURRENT_SC), MSGO(MSGO_I), MSGO_I, MSGOLEN);		if(TESTLO(SSTAT0, SPIORDY)) {			DPRINTK(debug_msgo, DEBUG_LEAD "!SPIORDY\n", CMDINFO(CURRENT_SC));			return;		}		if (MSGO_I==MSGOLEN-1) {			/* Leave MESSAGE OUT after transfer */			SETPORT(SSTAT1, CLRATNO);		}		if (MSGO(MSGO_I) & IDENTIFY_BASE)			CURRENT_SC->SCp.phase |= identified;		if (MSGO(MSGO_I)==ABORT)			CURRENT_SC->SCp.phase |= aborted;		if (MSGO(MSGO_I)==BUS_DEVICE_RESET)			CURRENT_SC->SCp.phase |= resetted;		SETPORT(SCSIDAT, MSGO(MSGO_I++));	}}static void msgo_end(struct Scsi_Host *shpnt){	if(MSGO_I<MSGOLEN) {		printk(ERR_LEAD "message sent incompletely (%d/%d)\n", CMDINFO(CURRENT_SC), MSGO_I, MSGOLEN);		if(SYNCNEG==1) {			printk(INFO_LEAD "Synchronous Data Transfer Request was rejected\n", CMDINFO(CURRENT_SC));			SYNCNEG=2;		}	}			MSGO_I  = 0;	MSGOLEN = 0;}/*  * command phase * */static void cmd_init(struct Scsi_Host *shpnt){	if (CURRENT_SC->SCp.sent_command) {		printk(ERR_LEAD "command already sent\n", CMDINFO(CURRENT_SC));		done(shpnt, DID_ERROR << 16);		return;	}#if defined(AHA152X_DEBUG)	if (HOSTDATA(shpnt)->debug & debug_cmd) {		printk(DEBUG_LEAD "cmd_init: ", CMDINFO(CURRENT_SC));		print_command(CURRENT_SC->cmnd);	}#endif	CMD_I=0;}/* * command phase * */static void cmd_run(struct Scsi_Host *shpnt){	if(CMD_I==CURRENT_SC->cmd_len) {		DPRINTK(debug_cmd, DEBUG_LEAD "command already completely sent (%d/%d)", CMDINFO(CURRENT_SC), CMD_I, CURRENT_SC->cmd_len);		disp_ports(shpnt);	}	while(CMD_I<CURRENT_SC->cmd_len) {		DPRINTK(debug_cmd, DEBUG_LEAD "command byte %02x (%d/%d)\n", CMDINFO(CURRENT_SC), CURRENT_SC->cmnd[CMD_I], CMD_I, CURRENT_SC->cmd_len);		if(TESTLO(SSTAT0, SPIORDY)) {			DPRINTK(debug_cmd, DEBUG_LEAD "!SPIORDY\n", CMDINFO(CURRENT_SC));			return;		}		SETPORT(SCSIDAT, CURRENT_SC->cmnd[CMD_I++]);	}}static void cmd_end(struct Scsi_Host *shpnt){	if(CMD_I<CURRENT_SC->cmd_len)		printk(ERR_LEAD "command sent incompletely (%d/%d)\n", CMDINFO(CURRENT_SC), CMD_I, CURRENT_SC->cmd_len);	else		CURRENT_SC->

⌨️ 快捷键说明

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