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

📄 53c700.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * setting of the SXFER register */	min_period = 1000*(4+min_xferp)/(4*hostdata->sync_clock);	if(min_period > NCR_700_MIN_PERIOD) {		NCR_700_SDTR_msg[3] = min_period;	}	if(hostdata->chip710)		NCR_700_SDTR_msg[4] = NCR_710_MAX_OFFSET;}STATIC voidNCR_700_chip_reset(struct Scsi_Host *host){	struct NCR_700_Host_Parameters *hostdata = 		(struct NCR_700_Host_Parameters *)host->hostdata[0];	if(hostdata->chip710) {		NCR_700_writeb(SOFTWARE_RESET_710, host, ISTAT_REG);		udelay(100);		NCR_700_writeb(0, host, ISTAT_REG);	} else {		NCR_700_writeb(SOFTWARE_RESET, host, DCNTL_REG);		udelay(100);				NCR_700_writeb(0, host, DCNTL_REG);	}	mdelay(1000);	NCR_700_chip_setup(host);}/* The heart of the message processing engine is that the instruction * immediately after the INT is the normal case (and so must be CLEAR * ACK).  If we want to do something else, we call that routine in * scripts and set temp to be the normal case + 8 (skipping the CLEAR * ACK) so that the routine returns correctly to resume its activity * */STATIC __u32process_extended_message(struct Scsi_Host *host, 			 struct NCR_700_Host_Parameters *hostdata,			 Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps){	__u32 resume_offset = dsp, temp = dsp + 8;	__u8 pun = 0xff, lun = 0xff;	if(SCp != NULL) {		pun = SCp->target;		lun = SCp->lun;	}	switch(hostdata->msgin[2]) {	case A_SDTR_MSG:		if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {			__u8 period = hostdata->msgin[3];			__u8 offset = hostdata->msgin[4];			__u8 sxfer;			if(offset != 0 && period != 0)				sxfer = NCR_700_offset_period_to_sxfer(hostdata, offset, period);			else 				sxfer = 0;						if(sxfer != NCR_700_get_SXFER(SCp->device)) {				printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n",				       host->host_no, pun, lun,				       offset, period*4);								NCR_700_set_SXFER(SCp->device, sxfer);			}						NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);						NCR_700_writeb(NCR_700_get_SXFER(SCp->device),				       host, SXFER_REG);		} else {			/* SDTR message out of the blue, reject it */			printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n",			       host->host_no);			hostdata->msgout[0] = A_REJECT_MSG;			NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);			script_patch_16(hostdata->script, MessageCount, 1);			/* SendMsgOut returns, so set up the return			 * address */			resume_offset = hostdata->pScript + Ent_SendMessageWithATN;		}		break;		case A_WDTR_MSG:		printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",		       host->host_no, pun, lun);		hostdata->msgout[0] = A_REJECT_MSG;		NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);		script_patch_16(hostdata->script, MessageCount, 1);		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;		break;	default:		printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",		       host->host_no, pun, lun,		       NCR_700_phase[(dsps & 0xf00) >> 8]);		print_msg(hostdata->msgin);		printk("\n");		/* just reject it */		hostdata->msgout[0] = A_REJECT_MSG;		NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);		script_patch_16(hostdata->script, MessageCount, 1);		/* SendMsgOut returns, so set up the return		 * address */		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;	}	NCR_700_writel(temp, host, TEMP_REG);	return resume_offset;}STATIC __u32process_message(struct Scsi_Host *host,	struct NCR_700_Host_Parameters *hostdata,		Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps){	/* work out where to return to */	__u32 temp = dsp + 8, resume_offset = dsp;	__u8 pun = 0xff, lun = 0xff;	if(SCp != NULL) {		pun = SCp->target;		lun = SCp->lun;	}#ifdef NCR_700_DEBUG	printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,	       NCR_700_phase[(dsps & 0xf00) >> 8]);	print_msg(hostdata->msgin);	printk("\n");#endif	switch(hostdata->msgin[0]) {	case A_EXTENDED_MSG:		resume_offset =  process_extended_message(host, hostdata, SCp,							  dsp, dsps);		break;	case A_REJECT_MSG:		if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {			/* Rejected our sync negotiation attempt */			NCR_700_set_SXFER(SCp->device, 0);			NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);		} else if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {			/* rejected our first simple tag message */			printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun);			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);			hostdata->tag_negotiated &= ~(1<<SCp->target);			SCp->device->tagged_queue = 0;			SCp->device->tagged_supported = 0;		} else {			printk(KERN_WARNING "scsi%d (%d:%d) Unexpected REJECT Message %s\n",			       host->host_no, pun, lun,			       NCR_700_phase[(dsps & 0xf00) >> 8]);			/* however, just ignore it */		}		break;	case A_PARITY_ERROR_MSG:		printk(KERN_ERR "scsi%d (%d:%d) Parity Error!\n", host->host_no,		       pun, lun);		NCR_700_internal_bus_reset(host);		break;	case A_SIMPLE_TAG_MSG:		printk(KERN_INFO "scsi%d (%d:%d) SIMPLE TAG %d %s\n", host->host_no,		       pun, lun, hostdata->msgin[1],		       NCR_700_phase[(dsps & 0xf00) >> 8]);		/* just ignore it */		break;	default:		printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",		       host->host_no, pun, lun,		       NCR_700_phase[(dsps & 0xf00) >> 8]);		print_msg(hostdata->msgin);		printk("\n");		/* just reject it */		hostdata->msgout[0] = A_REJECT_MSG;		NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);		script_patch_16(hostdata->script, MessageCount, 1);		/* SendMsgOut returns, so set up the return		 * address */		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;		break;	}	NCR_700_writel(temp, host, TEMP_REG);	/* set us up to receive another message */	NCR_700_dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);	return resume_offset;}STATIC __u32process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,			 struct Scsi_Host *host,			 struct NCR_700_Host_Parameters *hostdata){	__u32 resume_offset = 0;	__u8 pun = 0xff, lun=0xff;	if(SCp != NULL) {		pun = SCp->target;		lun = SCp->lun;	}	if(dsps == A_GOOD_STATUS_AFTER_STATUS) {		DEBUG(("  COMMAND COMPLETE, status=%02x\n",		       hostdata->status[0]));		/* OK, if TCQ still on, we know it works */		NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);		/* check for contingent allegiance contitions */		if(status_byte(hostdata->status[0]) == CHECK_CONDITION ||		   status_byte(hostdata->status[0]) == COMMAND_TERMINATED) {			struct NCR_700_command_slot *slot =				(struct NCR_700_command_slot *)SCp->host_scribble;			if(SCp->cmnd[0] == REQUEST_SENSE) {				/* OOPS: bad device, returning another				 * contingent allegiance condition */				printk(KERN_ERR "scsi%d (%d:%d) broken device is looping in contingent allegiance: ignoring\n", host->host_no, pun, lun);				NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);			} else {#ifdef NCR_DEBUG				print_command(SCp->cmnd);				printk("  cmd %p has status %d, requesting sense\n",				       SCp, hostdata->status[0]);#endif				/* we can destroy the command here				 * because the contingent allegiance				 * condition will cause a retry which				 * will re-copy the command from the				 * saved data_cmnd.  We also unmap any				 * data associated with the command				 * here */				NCR_700_unmap(hostdata, SCp, slot);				SCp->cmnd[0] = REQUEST_SENSE;				SCp->cmnd[1] = (SCp->lun & 0x7) << 5;				SCp->cmnd[2] = 0;				SCp->cmnd[3] = 0;				SCp->cmnd[4] = sizeof(SCp->sense_buffer);				SCp->cmnd[5] = 0;				SCp->cmd_len = 6;				/* Here's a quiet hack: the				 * REQUEST_SENSE command is six bytes,				 * so store a flag indicating that				 * this was an internal sense request				 * and the original status at the end				 * of the command */				SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;				SCp->cmnd[7] = hostdata->status[0];				SCp->cmnd[8] = SCp->use_sg;				SCp->use_sg = 0;				SCp->sc_data_direction = SCSI_DATA_READ;				pci_dma_sync_single(hostdata->pci_dev,						    slot->pCmd,						    SCp->cmd_len,						    PCI_DMA_TODEVICE);				SCp->request_bufflen = sizeof(SCp->sense_buffer);				slot->dma_handle = pci_map_single(hostdata->pci_dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), PCI_DMA_FROMDEVICE);				slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));				slot->SG[0].pAddr = bS_to_host(slot->dma_handle);				slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);				slot->SG[1].pAddr = 0;				slot->resume_offset = hostdata->pScript;				NCR_700_dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG[0])*2);				NCR_700_dma_cache_inv((unsigned long)SCp->sense_buffer, sizeof(SCp->sense_buffer));								/* queue the command for reissue */				slot->state = NCR_700_SLOT_QUEUED;				hostdata->state = NCR_700_HOST_FREE;				hostdata->cmd = NULL;			}		} else {			// Currently rely on the mid layer evaluation			// of the tag queuing capability			//			//if(status_byte(hostdata->status[0]) == GOOD &&			//   SCp->cmnd[0] == INQUIRY && SCp->use_sg == 0) {			//	/* Piggy back the tag queueing support			//	 * on this command */			//	pci_dma_sync_single(hostdata->pci_dev,			//			    slot->dma_handle,			//			    SCp->request_bufflen,			//			    PCI_DMA_FROMDEVICE);			//	if(((char *)SCp->request_buffer)[7] & 0x02) {			//		printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun);			//		hostdata->tag_negotiated |= (1<<SCp->target);			//		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);			//	} else {			//		NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);			//		hostdata->tag_negotiated &= ~(1<<SCp->target);			//	}			//}			NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);		}	} else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) {		__u8 i = (dsps & 0xf00) >> 8;		printk(KERN_ERR "scsi%d: (%d:%d), UNEXPECTED PHASE %s (%s)\n",		       host->host_no, pun, lun,		       NCR_700_phase[i],		       sbcl_to_string(NCR_700_readb(host, SBCL_REG)));		printk(KERN_ERR "         len = %d, cmd =", SCp->cmd_len);		print_command(SCp->cmnd);		NCR_700_internal_bus_reset(host);	} else if((dsps & 0xfffff000) == A_FATAL) {		int i = (dsps & 0xfff);		printk(KERN_ERR "scsi%d: (%d:%d) FATAL ERROR: %s\n",		       host->host_no, pun, lun, NCR_700_fatal_messages[i]);		if(dsps == A_FATAL_ILLEGAL_MSG_LENGTH) {			printk(KERN_ERR "     msg begins %02x %02x\n",			       hostdata->msgin[0], hostdata->msgin[1]);		}		NCR_700_internal_bus_reset(host);	} else if((dsps & 0xfffff0f0) == A_DISCONNECT) {#ifdef NCR_700_DEBUG		__u8 i = (dsps & 0xf00) >> 8;		printk("scsi%d: (%d:%d), DISCONNECTED (%d) %s\n",		       host->host_no, pun, lun,		       i, NCR_700_phase[i]);#endif		save_for_reselection(hostdata, SCp, dsp);	} else if(dsps == A_RESELECTION_IDENTIFIED) {		__u8 lun;		struct NCR_700_command_slot *slot;		__u8 reselection_id = hostdata->reselection_id;		lun = hostdata->msgin[0] & 0x1f;		hostdata->reselection_id = 0xff;		DEBUG(("scsi%d: (%d:%d) RESELECTED!\n",		       host->host_no, reselection_id, lun));		/* clear the reselection indicator */		if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) {			slot = find_ITLQ_Nexus(hostdata, reselection_id,					       lun, hostdata->msgin[2]);		} else {			slot = find_ITL_Nexus(hostdata, reselection_id, lun);		}	retry:		if(slot == NULL) {			struct NCR_700_command_slot *s = find_ITL_Nexus(hostdata, reselection_id, lun);			printk(KERN_ERR "scsi%d: (%d:%d) RESELECTED but no saved command (MSG = %02x %02x %02x)!!\n",			       host->host_no, reselection_id, lun,			       hostdata->msgin[0], hostdata->msgin[1],			       hostdata->msgin[2]);			printk(KERN_ERR " OUTSTANDING TAGS:");			while(s != NULL) {				if(s->cmnd->target == reselection_id &&				   s->cmnd->lun == lun) {					printk("%d ", s->tag);					if(s->tag == hostdata->msgin[2]) {						printk(" ***FOUND*** \n");						slot = s;						goto retry;					}										}				s = s->ITL_back;			}			printk("\n");		} else {			if(hostdata->state != NCR_700_HOST_BUSY)				printk(KERN_ERR "scsi%d: FATAL, host not busy during valid reselection!\n",				       host->host_no);			resume_offset = slot->resume_offset;			hostdata->cmd = slot->cmnd;			/* re-patch for this command */			script_patch_32_abs(hostdata->script, CommandAddress, 					    slot->pCmd);			script_patch_16(hostdata->script,					CommandCount, slot->cmnd->cmd_len);			script_patch_32_abs(hostdata->script, SGScriptStartAddress,					    to32bit(&slot->pSG[0].ins));			/* Note: setting SXFER only works if we're			 * still in the MESSAGE phase, so it is vital			 * that ACK is still asserted when we process			 * the reselection message.  The resume offset			 * should therefore always clear ACK */			NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),				       host, SXFER_REG);			NCR_700_dma_cache_inv((unsigned long)hostdata->msgin,				      MSG_ARRAY_SIZE);

⌨️ 快捷键说明

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