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

📄 seagate.c

📁 linux0.99源代码用于研究linux操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
 *	degraded performance by a factor > 10 - so it is no more. *//* *	SELECTION PHASE * *	Now, we select the disk, giving it the SCSI ID at data *	and a command of PARITY if necessary, and we raise SEL. */#if (DEBUG & PHASE_SELECTION)		printk("scsi%d : phase = SELECTION\n", hostno);#endif		clock = jiffies + ST0X_SELECTION_DELAY;/* *	If we wish to disconnect, we should request a MESSAGE OUT *	at this point.  Technically, ATTN should be raised before  *	SEL = true and BSY = false (from arbitration), but I think this  *	should do. */		if (reselect)			CONTROL = BASE_CMD | CMD_DRVR_ENABLE |				CMD_ATTN;		/* *	We must assert both our ID and our target's ID on the bus. */		DATA = (unsigned char) ((1 << target) | 0x80);/* *	If we are allowing ourselves to reconnect, then I will keep  *	ATTN raised so we get MSG OUT.  */ 		CONTROL =  BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | 			(reselect ? CMD_ATTN : 0);/* *	When the SCSI device decides that we're gawking at it, it will  *	respond by asserting BUSY on the bus. */		while (!((status_read = STATUS) & STAT_BSY) && 			(jiffies < clock) && !st0x_aborted)#if (DEBUG & PHASE_SELECTION)		{		temp = clock - jiffies;		if (!(jiffies % 5))			printk("seagate_st0x_timeout : %d            \r",temp);			}		printk("Done.                                             \n\r");		printk("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", 			hostno, status_read, temp, st0x_aborted);#else		;#endif			if ((jiffies > clock)  || (!st0x_aborted && 			!(status_read & STAT_BSY)))			{#if (DEBUG & PHASE_SELECT)			printk ("scsi%d : NO CONNECT with target %d, status = %x \n", 				hostno, target, STATUS);#endif			return retcode(DID_NO_CONNECT);			}/* *	If we have been aborted, and we have a command in progress, IE the  *	target still has BSY asserted, then we will reset the bus, and  * 	notify the midlevel driver to expect sense. */		if (st0x_aborted)			{			CONTROL = BASE_CMD;			if (STATUS & STAT_BSY)				{				seagate_st0x_reset();				return retcode(DID_RESET);				}			return retcode(st0x_aborted);			}			}	CONTROL = BASE_CMD | CMD_DRVR_ENABLE | 		((reselect == CAN_RECONNECT) ? CMD_ATTN : 0) ;	/* * 	INFORMATION TRANSFER PHASE * *	The nasty looking read / write inline assembler loops we use for  *	DATAIN and DATAOUT phases are approximately 4-5 times as fast as  *	the 'C' versions - since we're moving 1024 bytes of data, this *	really adds up. */#if (DEBUG & PHASE_ETC)	printk("scsi%d : phase = INFORMATION TRANSFER\n", hostno);#endif  	incommand = 1;/* * 	Now, we poll the device for status information, *	and handle any requests it makes.  Note that since we are unsure of  *	how much data will be flowing across the system, etc and cannot  *	make reasonable timeouts, that we will instead have the midlevel * 	driver handle any timeouts that occur in this phase. */	while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) 		{#ifdef PARITY		if (status_read & STAT_PARITY)			{			done = 1;			st0x_aborted = DID_PARITY;			}	#endif		if (status_read & STAT_REQ)			{#if (DEBUG & PHASE_ETC)			if ((newphase = (status_read & REQ_MASK)) != phase)				{				phase = newphase;				switch (phase)				{				case REQ_DATAOUT: 					printk("scsi%d : phase = DATA OUT\n",						hostno); 					break;				case REQ_DATAIN : 					printk("scsi%d : phase = DATA IN\n",						hostno); 					break;				case REQ_CMDOUT : 					printk("scsi%d : phase = COMMAND OUT\n",						hostno); 					break;				case REQ_STATIN :					 printk("scsi%d : phase = STATUS IN\n",						hostno); 					break;				case REQ_MSGOUT :					printk("scsi%d : phase = MESSAGE OUT\n",						hostno); 					break;				case REQ_MSGIN :					printk("scsi%d : phase = MESSAGE IN\n",						hostno);					break;				default : 					printk("scsi%d : phase = UNKNOWN\n",						hostno); 					st0x_aborted = 1; 					done = 1;				}					}#endif		switch (status_read & REQ_MASK)		{					case REQ_DATAOUT : /* * 	We loop as long as we are in a data out phase, there is data to send,  *	and BSY is still active. */		__asm__ (/*	Local variables : 	len = ecx	data = esi	st0x_cr_sr = ebx	st0x_dr =  edi	Test for any data here at all.*/	"movl %0, %%esi\n"		/* local value of data */	"\tmovl %1, %%ecx\n"		/* local value of len */		"\torl %%ecx, %%ecx	jz 2f	cld	movl _st0x_cr_sr, %%ebx	movl _st0x_dr, %%edi	1:	movb (%%ebx), %%al\n"/*	Test for BSY*/	"\ttest $1, %%al	jz 2f\n"/*	Test for data out phase - STATUS & REQ_MASK should be REQ_DATAOUT, which is 0.*/	"\ttest $0xe, %%al	jnz 2f	\n"/*	Test for REQ*/		"\ttest $0x10, %%al	jz 1b	lodsb	movb %%al, (%%edi) 	loop 1b2: 	movl %%esi, %2	movl %%ecx, %3									":/* output */"=r" (data), "=r" (len) :/* input */"0" (data), "1" (len) :/* clobbered */"ebx", "ecx", "edi", "esi"); 			break;		case REQ_DATAIN : /* * 	We loop as long as we are in a data in phase, there is room to read,  * 	and BSY is still active */ 			__asm__ (/*	Local variables : 	ecx = len	edi = data	esi = st0x_cr_sr	ebx = st0x_dr	Test for room to read*/	"movl %0, %%edi\n"		/* data */	"\tmovl %1, %%ecx\n"		/* len */	"\torl %%ecx, %%ecx	jz 2f	cld	movl _st0x_cr_sr, %%esi	movl _st0x_dr, %%ebx1:	movb (%%esi), %%al\n"/*	Test for BSY*/	"\ttest $1, %%al 	jz 2f\n"/*	Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, = STAT_IO, which is 4.*/	"\tmovb $0xe, %%ah		andb %%al, %%ah	cmpb $0x04, %%ah	jne 2f\n"		/*	Test for REQ*/		"\ttest $0x10, %%al	jz 1b	movb (%%ebx), %%al		stosb		loop 1b2: 	movl %%edi, %2\n"	 	/* data */	"\tmovl %%ecx, %3\n" 		/* len */									:/* output */"=r" (data), "=r" (len) :/* input */"0" (data), "1" (len) :/* clobbered */"ebx", "ecx", "edi", "esi"); 			break;		case REQ_CMDOUT : 			while (((status_read = STATUS) & STAT_BSY) && 			       ((status_read & REQ_MASK) == REQ_CMDOUT))				if (status_read & STAT_REQ)					DATA = *(unsigned char *) cmnd ++;			break;			case REQ_STATIN : 			status = DATA;			break;						case REQ_MSGOUT : /* *	We can only have sent a MSG OUT if we requested to do this  *	by raising ATTN.  So, we must drop ATTN. */			CONTROL = BASE_CMD | CMD_DRVR_ENABLE;/* * 	If we are reconecting, then we must send an IDENTIFY message in  *	 response  to MSGOUT. */			if (reselect)				{				DATA = IDENTIFY(1, lun);#if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT)) 				printk("scsi%d : sent IDENTIFY message.\n", hostno);#endif				}			else  				{				DATA = MESSAGE_REJECT;				#if (DEBUG & PHASE_MSGOUT)				printk("scsi%d : sent MESSAGE REJECT message.\n", hostno);#endif				}			break;							case REQ_MSGIN : 			switch (message = DATA)			{			case DISCONNECT :				should_reconnect = 1;                                current_data = data;    /* WDE add */                                current_bufflen = len;  /* WDE add */#if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))				printk("scsi%d : disconnected.\n", hostno);				done=1;				break;#endif			case COMMAND_COMPLETE :#if (DEBUG & PHASE_MSGIN)					printk("scsi%d : command complete.\n", hostno);				done=1;				break;#endif			case ABORT :#if (DEBUG & PHASE_MSGIN)				printk("scsi%d : abort message.\n", hostno);#endif				done=1;				break;			case SAVE_POINTERS :				current_data = data;	/* WDE mod */                                current_bufflen = len;  /* WDE add */#if (DEBUG & PHASE_MSGIN)				printk("scsi%d : pointers saved.\n", hostno);#endif 				break;			case RESTORE_POINTERS:				data=current_data;	/* WDE mod */				cmnd=current_cmnd;#if (DEBUG & PHASE_MSGIN)				printk("scsi%d : pointers restored.\n", hostno);#endif				break;			default:/* * 	IDENTIFY distinguishes itself from the other messages by setting the *	high byte. */				if (message & 0x80)					{#if (DEBUG & PHASE_MSGIN)					printk("scsi%d : IDENTIFY message received from id %d, lun %d.\n",						hostno, target, message & 7);#endif					}					else					{			#if (DEBUG & PHASE_MSGIN)					printk("scsi%d : unknown message %d from target %d.\n",						hostno,  message,   target);#endif						}			}			break;		default : 			printk("scsi%d : unknown phase.\n", hostno); 			st0x_aborted = DID_ERROR; 		}			} /* while ends */		} /* if ends */#if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))	printk("Transfered %d bytes, allowed %d additional bytes\n", (bufflen - len), len);#endif#if (DEBUG & PHASE_EXIT)	printk("Buffer : \n");	for (i = 0; i < 20; ++i) 		printk ("%02x  ", ((unsigned char *) data)[i]);	/* WDE mod */	printk("\n");	printk("Status = %02x, message = %02x\n", status, message);#endif		if (st0x_aborted)		{		if (STATUS & STAT_BSY)			{			seagate_st0x_reset();			st0x_aborted = DID_RESET;			}		abort_confirm = 1;		}			if (should_reconnect)		{#if (DEBUG & PHASE_RESELECT)		printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",			hostno);#endif		CONTROL = BASE_CMD | CMD_INTR ;		}	else		CONTROL = BASE_CMD;	return retcode (st0x_aborted);	}int seagate_st0x_abort (Scsi_Cmnd * SCpnt, int code)	{	if (code)		st0x_aborted = code;	else		st0x_aborted = DID_ABORT;		return 0;	}/*	the seagate_st0x_reset function resets the SCSI bus*/	int seagate_st0x_reset (void)	{	unsigned clock;	/*		No timeouts - this command is going to fail because 		it was reset.	*/#ifdef DEBUG	printk("In seagate_st0x_reset()\n");#endif	/* assert  RESET signal on SCSI bus.  */			CONTROL = BASE_CMD  | CMD_RST;	clock=jiffies+2;		/* Wait.  */		while (jiffies < clock);	CONTROL = BASE_CMD;		st0x_aborted = DID_RESET;#ifdef DEBUG	printk("SCSI bus reset.\n");#endif	return 0;	}#endif	

⌨️ 快捷键说明

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