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

📄 seagate.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
					     == (REQ_DATAIN | STAT_REQ);					     --len) {						*data++ = DATA;						borken_wait ();					}#if (DEBUG & (PHASE_DATAIN))					transfered -= len;#endif				} else#endif					if (fast && transfersize					    && !(len % transfersize)					    && (len >= transfersize)#ifdef FAST32					    && !(transfersize % 4)#endif				    ) {					DPRINTK (DEBUG_FAST,						 "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"						 "         len = %d, data = %08x\n",						 hostno, SCint->underflow,						 SCint->transfersize, len,						 data);/* SJT: Start. Fast Read */#ifdef SEAGATE_USE_ASM					__asm__ ("cld\n\t"#ifdef FAST32						 "shr $2, %%ecx\n\t"						 "1:\t"						 "movl (%%esi), %%eax\n\t"						 "stosl\n\t"#else						 "1:\t"						 "movb (%%esi), %%al\n\t"						 "stosb\n\t"#endif						 "loop 1b\n\t"				      /* output */ :				      /* input */ :"S" (phys_to_virt (st0x_dr)),						 "D"						 (data),						 "c" (SCint->transfersize)/* clobbered */				      :	 "eax", "ecx",						 "edi");#else				/* SEAGATE_USE_ASM */					{#ifdef FAST32						const unsigned int *iop =						    phys_to_virt (st0x_dr);						unsigned int *dp =						    (unsigned int *) data;						int xferlen = len >> 2;#else						const unsigned char *iop =						    phys_to_virt (st0x_dr);						unsigned char *dp = data;						int xferlen = len;#endif						for (; xferlen; --xferlen)							*dp++ = *iop;					}#endif				/* SEAGATE_USE_ASM *//* SJT: End */					len -= transfersize;					data += transfersize;#if (DEBUG & PHASE_DATAIN)					printk ("scsi%d: transfered += %d\n",						hostno, transfersize);					transfered += transfersize;#endif					DPRINTK (DEBUG_FAST,						 "scsi%d : FAST transfer complete len = %d data = %08x\n",						 hostno, len, data);				} else {#if (DEBUG & PHASE_DATAIN)					printk ("scsi%d: transfered += %d\n",						hostno, len);					transfered += len;	/* Assume we'll transfer it all, then								   subtract what we *didn't* transfer */#endif/* *	We loop as long as we are in a data in phase, there is room to read, *      and BSY is still active *//* SJT: Start. */#ifdef SEAGATE_USE_ASM					int __dummy_3, __dummy_4;/* Dummy clobbering variables for the new gcc-2.95 *//* *      We loop as long as we are in a data in phase, there is room to read,  *      and BSY is still active */					/* Local variables : ecx = len, edi = data					   esi = st0x_cr_sr, ebx = st0x_dr */					__asm__ (							/* Test for room to read */							"orl %%ecx, %%ecx\n\t"							"jz 2f\n\t" "cld\n\t"/*                "movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%esi\n\t"  *//*                "movl " SYMBOL_NAME_STR(st0x_dr) ", %%ebx\n\t"  */							"1:\t"							"movb (%%esi), %%al\n\t"							/* Test for BSY */							"test $1, %%al\n\t"							"jz 2f\n\t"							/* Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, 							   = STAT_IO, which is 4. */							"movb $0xe, %%ah\n\t"							"andb %%al, %%ah\n\t"							"cmpb $0x04, %%ah\n\t"							"jne 2f\n\t"							/* Test for REQ */							"test $0x10, %%al\n\t"							"jz 1b\n\t"							"movb (%%ebx), %%al\n\t"							"stosb\n\t"							"loop 1b\n\t" "2:\n"				      /* output */ :"=D" (data), "=c" (len),							"=S"							(__dummy_3),							"=b" (__dummy_4)/* input */				      :		"0" (data), "1" (len),							"2" (phys_to_virt							     (st0x_cr_sr)),							"3" (phys_to_virt							     (st0x_dr))/* clobbered */				      :		"eax");#else				/* SEAGATE_USE_ASM */					while (len) {						unsigned char stat;						stat = STATUS;						if (!(stat & STAT_BSY)						    || ((stat & REQ_MASK) !=							REQ_DATAIN))							break;						if (stat & STAT_REQ) {							*data++ = DATA;							--len;						}					}#endif				/* SEAGATE_USE_ASM *//* SJT: End. */#if (DEBUG & PHASE_DATAIN)					printk ("scsi%d: transfered -= %d\n",						hostno, len);					transfered -= len;	/* Since we assumed all of Len got  *								   transfered, correct our mistake */#endif				}				if (!len && nobuffs) {					--nobuffs;					++buffer;					len = buffer->length;					data =					    (unsigned char *) buffer->address;					DPRINTK (DEBUG_SG,						 "scsi%d : next scatter-gather buffer len = %d address = %08x\n",						 hostno, len, data);				}				break;			case REQ_CMDOUT:				while (((status_read = STATUS) & STAT_BSY) &&				       ((status_read & REQ_MASK) == REQ_CMDOUT))					if (status_read & STAT_REQ) {						WRITE_DATA (*							    (const unsigned char							     *) cmnd);						cmnd =						    1 +						    (const unsigned char *)						    cmnd;#ifdef SLOW_RATE						if (borken)							borken_wait ();#endif					}				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. */				WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE);/* *	If we are reconnecting, then we must send an IDENTIFY message in *      response  to MSGOUT. */				switch (reselect) {				case CAN_RECONNECT:					WRITE_DATA (IDENTIFY (1, lun));					DPRINTK (PHASE_RESELECT | PHASE_MSGOUT,						 "scsi%d : sent IDENTIFY message.\n",						 hostno);					break;#ifdef LINKED				case LINKED_WRONG:					WRITE_DATA (ABORT);					linked_connected = 0;					reselect = CAN_RECONNECT;					goto connect_loop;					DPRINTK (PHASE_MSGOUT | DEBUG_LINKED,						 "scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n",						 hostno);#endif				/* LINKED */					DPRINTK (DEBUG_LINKED, "correct\n");				default:					WRITE_DATA (NOP);					printk					    ("scsi%d : target %d requested MSGOUT, sent NOP message.\n",					     hostno, target);				}				break;			case REQ_MSGIN:				switch (message = DATA) {				case DISCONNECT:					DANY ("seagate: deciding to disconnect\n");					should_reconnect = 1;					current_data = data;	/* WDE add */					current_buffer = buffer;					current_bufflen = len;	/* WDE add */					current_nobuffs = nobuffs;#ifdef LINKED					linked_connected = 0;#endif					done = 1;					DPRINTK ((PHASE_RESELECT | PHASE_MSGIN),						 "scsi%d : disconnected.\n",						 hostno);					break;#ifdef LINKED				case LINKED_CMD_COMPLETE:				case LINKED_FLG_CMD_COMPLETE:#endif				case COMMAND_COMPLETE:/* * Note : we should check for underflow here. */					DPRINTK (PHASE_MSGIN,						 "scsi%d : command complete.\n",						 hostno);					done = 1;					break;				case ABORT:					DPRINTK (PHASE_MSGIN,						 "scsi%d : abort message.\n",						 hostno);					done = 1;					break;				case SAVE_POINTERS:					current_buffer = buffer;					current_bufflen = len;	/* WDE add */					current_data = data;	/* WDE mod */					current_nobuffs = nobuffs;					DPRINTK (PHASE_MSGIN,						 "scsi%d : pointers saved.\n",						 hostno);					break;				case RESTORE_POINTERS:					buffer = current_buffer;					cmnd = current_cmnd;					data = current_data;	/* WDE mod */					len = current_bufflen;					nobuffs = current_nobuffs;					DPRINTK (PHASE_MSGIN,						 "scsi%d : pointers restored.\n",						 hostno);					break;				default:/* *	IDENTIFY distinguishes itself from the other messages by setting the *      high byte. [FIXME: should not this read "the high bit"? - pavel@ucw.cz] * *      Note : we need to handle at least one outstanding command per LUN, *      and need to hash the SCSI command for that I_T_L nexus based on the *      known ID (at this point) and LUN. */					if (message & 0x80) {						DPRINTK (PHASE_MSGIN,							 "scsi%d : IDENTIFY message received from id %d, lun %d.\n",							 hostno, target,							 message & 7);					} else {/* *      We should go into a MESSAGE OUT phase, and send  a MESSAGE_REJECT *      if we run into a message that we don't like.  The seagate driver *      needs some serious restructuring first though. */						DPRINTK (PHASE_MSGIN,							 "scsi%d : unknown message %d from target %d.\n",							 hostno, message,							 target);					}				}				break;			default:				printk ("scsi%d : unknown phase.\n", hostno);				st0x_aborted = DID_ERROR;			}	/* end of switch (status_read &				   REQ_MASK) */#ifdef SLOW_RATE/* * I really don't care to deal with borken devices in each single * byte transfer case (ie, message in, message out, status), so * I'll do the wait here if necessary. */			if (borken)				borken_wait ();#endif		}		/* if(status_read & STAT_REQ) ends */	}			/* while(((status_read = STATUS)...)				   ends */	DPRINTK (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT,		 "scsi%d : Transfered %d bytes\n", hostno, transfered);#if (DEBUG & PHASE_EXIT)#if 0				/* Doesn't work for scatter/gather */	printk ("Buffer : \n");	for (i = 0; i < 20; ++i)		printk ("%02x  ", ((unsigned char *) data)[i]);	/* WDE mod */	printk ("\n");#endif	printk ("scsi%d : status = ", hostno);	print_status (status);	printk ("message = %02x\n", message);#endif/* We shouldn't reach this until *after* BSY has been deasserted */#ifdef LINKED	else	{/* * Fix the message byte so that unsuspecting high level drivers don't * puke when they see a LINKED COMMAND message in place of the COMMAND * COMPLETE they may be expecting.  Shouldn't be necessary, but it's * better to be on the safe side. * * A non LINKED* message byte will indicate that the command completed, * and we are now disconnected. */		switch (message) {		case LINKED_CMD_COMPLETE:		case LINKED_FLG_CMD_COMPLETE:			message = COMMAND_COMPLETE;			linked_target = current_target;			linked_lun = current_lun;			linked_connected = 1;			DPRINTK (DEBUG_LINKED,				 "scsi%d : keeping I_T_L nexus established"				 "for linked command.\n", hostno);			/* We also will need to adjust status to accommodate intermediate			   conditions. */			if ((status == INTERMEDIATE_GOOD) ||			    (status == INTERMEDIATE_C_GOOD))				status = GOOD;			break;/* * We should also handle what are "normal" termination messages * here (ABORT, BUS_DEVICE_RESET?, and COMMAND_COMPLETE individually, * and flake if things aren't right. */		default:			DPRINTK (DEBUG_LINKED,				 "scsi%d : closing I_T_L nexus.\n", hostno);			linked_connected = 0;		}	}#endif				/* LINKED */	if (should_reconnect) {		DPRINTK (PHASE_RESELECT,			 "scsi%d : exiting seagate_st0x_queue_command()"			 "with reconnect enabled.\n", hostno);		WRITE_CONTROL (BASE_CMD | CMD_INTR);	} else		WRITE_CONTROL (BASE_CMD);	return retcode (st0x_aborted);}				/* end of internal_command */static int seagate_st0x_abort (Scsi_Cmnd * SCpnt){	st0x_aborted = DID_ABORT;	return SCSI_ABORT_PENDING;}#undef ULOOP#undef TIMEOUT/* * the seagate_st0x_reset function resets the SCSI bus  */static int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags){/* No timeouts - this command is going to fail because it was reset. */	DANY ("scsi%d: Reseting bus... ", hostno);/* assert  RESET signal on SCSI bus.  */	WRITE_CONTROL (BASE_CMD | CMD_RST);	udelay (20 * 1000);	WRITE_CONTROL (BASE_CMD);	st0x_aborted = DID_RESET;	DANY ("done.\n");	return SCSI_RESET_WAKEUP;}/* Eventually this will go into an include file, but this will be later */static Scsi_Host_Template driver_template = SEAGATE_ST0X;#include "scsi_module.c"

⌨️ 快捷键说明

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