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

📄 sm.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
              if (s & DVMA_REQPEND) {	/* DMA request pending */ 	 	EPRINTF1("sm_intr: DVMA-scsi req_pend, stat= %x\n", s);                /* DMA request pending, should not ocurred */                toutcnt = LOOP_4SEC;    /* must be over 2sec */                /* wait for a short while to see it will clear itself */                while ((--toutcnt) && (dvma->ctl_stat & DVMA_REQPEND));                if (toutcnt == ZERO) {                        smsnap->cur_err = SE_REQPEND;                        goto INTR_CHK_ERR;                }	      }	      if (s & DVMA_ERRPEND) {	/* memory exception error */		smsnap->cur_err = SE_MEMERR; 	 	DPRINTF1("sm_intr: DVMA mem_err, stat= %x\n", s);               	goto INTR_CHK_ERR;	      }	 	   } 	   /* status errors are mainly for internal firmware debug */           if (espstat & STAT_ERR_MASK) {		smsnap->cur_retry++;	                /* ESP's status reg ERROR */                if (espstat & ESP_STAT_PERR) { /* parity error */                        EPRINTF("sm_intr: SCSI bus parity error\n");                        smsnap->cur_err = SE_PARITY;                }                /* if mismatch, the 'DMA" direction is wrong */                if ((((dvma->ctl_stat & DVMA_WRITE) == ZERO) &&                      (smsnap->sync_chk == SM_RECV_DATA)) ||                      ((dvma->ctl_stat & DVMA_WRITE) &&                      (smsnap->sync_chk == SM_SEND_DATA))) {                        EPRINTF2("sm_intr: wrong dma dir= %x, stat= %x\n",				smsnap->sync_chk, dvma->ctl_stat);                        smsnap->cur_err = SE_DIRERR;                }                if ((ESP_RD.fifo_flag & KEEP_5BITS) == MAX_FIFO_FLAG) {                        /* fifo overwritten */                        EPRINTF1("sm_intr: fifo_flag ERROR= %x\n",                                ESP_RD.fifo_flag);                        /* the 'TOP of FIFO' had been overwritten */                        smsnap->cur_err = SE_FIFOVER;                }#ifdef notdef                /* If none of the above, GROSS error is from cmd overflown */		/* top_of_cmd had been overwritten */                /* ignore this for P4-ESP for timing reason */                if (smsnap->cur_err == ZERO) {                        EPRINTF1("sm_intr: cur_cmd= %x\n", ESP_RD.cmd);                        smsnap->cur_err = SE_CMDOVER;                }#endif notdef                if (smsnap->cur_err) {			EPRINTF1("sm_intr: esp stat_err= %x\n", espstat);                        goto INTR_CHK_ERR;		}           }        } INTR_CHK_STAT:	/* CORRECTON for an ESP ERRATA: ensure phase change detection reset */	ESP_WR.cmd = CMD_NOP;	smsnap->esp_stat &= ESP_PHASE_MASK;	s = ESP_RD.stat;	i = s & ESP_PHASE_MASK;	if (i != smsnap->esp_stat) {		DPRINTF2("sm_intr: phase changed, old= %x, new= %x\n", 			smsnap->esp_stat, i);		smsnap->esp_stat = i;		espstat = s;		i = ESP_RD.intr;                if (i) {                    DPRINTF2("sm_intr: INTR changed, old= %x, new= %x\n",                        smsnap->esp_intr, i);                    smsnap->esp_intr = i;                }	}	DPRINTF2("sm_intr: ESP_int= %x, state= %x\n", 		smsnap->esp_intr, smsnap->cur_state);	switch (smsnap->esp_intr) {	   case ESP_INT_DISCON:  	/* disconnect INT */		switch (smsnap->cur_state) {		    /* case STATE_MSG_DISCON not needed */		    case STATE_COMP_REQ: /* cmd completed seuqence sent out */		    case STATE_MSG_CMPT: /* command completed msg accepted */			/* All ZERO= good, All other, bit 1= check cond, */			/* bit 3= busy, bit 4=resev conflict are errors */			if (smsnap->scsi_status & SCSI_BUSY_MASK) {				DPRINTF1("sm_intr: BUS_ERR status= %x\n", 					smsnap->scsi_status);				smsnap->cur_err = SE_BUSTATERR;			}			smsnap->cur_state = STATE_FREE;			break;		    case STATE_SEL_REQ:	/* selection command timeout */			smsnap->cur_err = SE_SELTOUT;		    case STATE_FREE:				break;		    default:	/* could be from target dropping BSY */			EPRINTF("sm_intr: target drop busy\n");			smsnap->cur_err = SE_PHASERR;	        }		break;		   case ESP_INT_FCMP:/* function complete INT */		   case ESP_INT_BUS:  /* from"select_seq","comp_seq","msg_accept" cmd */	   case INT_OK_MASK:  /* from"select_seq","comp_seq","msg_accept" cmd */		if (smsnap->cur_state == STATE_SEL_REQ) {		    /* for initator, only SEL_SEQ has */                    /* intermittent step indications: */                    /* both sel w/wo ATN need 4 steps to complete OK */                    /* only sel w/ATN/stop is 3 steps to complete OK */		    /* both sel w/wo ATN need 4 steps to complete OK */		    if ((smsnap->esp_step & KEEP_3BITS) != STEP_SEL_OK) {			EPRINTF2("sm_intr: BAD_SEL, step= %x, stat= %x\n", 				smsnap->esp_step, smsnap->esp_stat);			if (smsnap->esp_stat != ESP_PHASE_STATUS) {					smsnap->cur_err = SE_SELTOUT;				goto INTR_CHK_ERR;			}			ESP_WR.cmd = CMD_FLUSH;			ESP_WR.cmd = CMD_NOP;			/* ready for next phase */		    }		    smsnap->cur_state = STATE_SEL_DONE;		}		switch (smsnap->esp_stat) {   /* current phase */		  case ESP_PHASE_DATA_IN:	/* either data in or out */		  case ESP_PHASE_DATA_OUT:	/* either data in or out */			DPRINTF1("sm_intr: data phase, pre_state= %x\n", 				smsnap->cur_state);			DEBUG_DELAY(1000000);			/* if this phase came after a non-command phase */			/* try to service this unexpected data phase */			if (smsnap->cur_state != STATE_SEL_DONE) {				DPRINTF("sm_intr: wrong data phase\n");				if (++smsnap->cur_retry > MAX_RETRY) {					EPRINTF("sm_intr: wrong data phase\n");					smsnap->cur_err = SE_PHASERR;					goto INTR_CHK_ERR;				}				ESP_WR.cmd = CMD_NOP;				smsnap->esp_stat = ESP_RD.stat & ESP_PHASE_MASK;                                i = ESP_RD.intr;                                DPRINTF2("sm_intr: stat= %x, intr = %x\n",                                        smsnap->esp_stat, i);                                if (i) {                                        smsnap->esp_intr = i;                                        goto INTR_CHK_STAT;                                }                                else    /* just service and ignore */                                        goto INTR_RTN;			}			/* assume ALL cmd that has NO data, do not need DMA */			if (smsnap->sync_chk == SM_NO_DATA) {				DPRINTF1("sm_intr: spurious data phase, state= %x\n", 					smsnap->cur_state);				if (++smsnap->cur_retry > MAX_RETRY) {					EPRINTF1("sm_intr: spurious data phase, state= %x\n", 					smsnap->cur_state);					smsnap->cur_err = SE_PHASERR;					goto INTR_CHK_ERR;				}				/* try to fake one out a data xfr */				ESP_WR.cmd = CMD_TRAN_PAD | CMD_DMA;			}			else { 	/* data transfer required */				smsnap->cur_state = STATE_DATA_REQ;				/* force async transfer */				ESP_WR.sync_offset = ZERO; 				/* enable dvma and R/W*/				sm_dma_setup(h_sip);					/* add in per ESP errata note */                        	ESP_WR.cmd = CMD_NOP;				ESP_WR.cmd = CMD_TRAN_INFO | CMD_DMA;			}				break;		  case ESP_PHASE_STATUS:			DPRINTF1("sm_intr: status phase, pre_state= %x\n", 				smsnap->cur_state);			if (sm_dma_cleanup(h_sip, espstat)) 				goto INTR_CHK_ERR;	  	 	smsnap->cur_state = STATE_COMP_REQ;			DPRINTF("sm_intr: send complete_seq\n");			ESP_WR.cmd = CMD_COMP_SEQ;			break;		  case ESP_PHASE_MSG_IN:			DPRINTF2("sm_intr: msg_in phase, state= %x, flag= %x\n", 				smsnap->cur_state, ESP_RD.fifo_flag);			switch (smsnap->cur_state) {			  case STATE_COMP_REQ:	/* two bytes */				smsnap->scsi_status = ESP_RD.fifo_data; 			  case STATE_MSGIN_REQ:				smsnap->scsi_message = ESP_RD.fifo_data;				break;			  case STATE_DATA_REQ:                                 DPRINTF2("sm_intr: msg_in dma_stat= %x, cnt= %x\n",                                         dvma->ctl_stat, h_sip->cc);                                 if (sm_dma_cleanup(h_sip, espstat))                                         goto INTR_CHK_ERR;                                 /* fall through */                            default:                                 /* get message byte */                                 if (ESP_RD.fifo_flag) {                                   if (ESP_RD.fifo_flag > 1) {			        EPRINTF2("sm_intr: msg_in flag= %x, state= %x\n",                                         ESP_RD.fifo_flag, smsnap->cur_state);                                      EPRINTF2("sm_intr: stat= %x, intr= %x\n",                                        smsnap->esp_stat, smsnap->esp_intr);                                         while (ESP_RD.fifo_flag) {                                                 i = ESP_RD.fifo_data;                                                 EPRINTF1(" %x", i);                                         }                                         ESP_WR.cmd = CMD_NOP;                                        goto INTR_CHK_STAT;                                     }                                     smsnap->scsi_message = ESP_RD.fifo_data;                                 }                                 else {                                         ESP_WR.cmd = CMD_TRAN_INFO;					 smsnap->cur_state = STATE_MSGIN_REQ;                                         goto INTR_RTN;				}			}			DPRINTF2("sm_intr: status= %x, message= %x\n",				smsnap->scsi_status, smsnap->scsi_message);			DPRINTF1("sm_intr: flag= %x\n", ESP_RD.fifo_flag);			switch (smsnap->scsi_message) {			   case SC_COMMAND_COMPLETE:			   case SC_NO_OP:				smsnap->cur_state = STATE_MSG_CMPT;				/* save the scsi_status for now */				/* a disconnect INT shuold show up */				/* after sending out "msg_accpt" cmd */				/* at that time, we are TOTALLY done */				break;			   case SC_PARITY:				DPRINTF("sm_intr: PARITY_err msg\n");				smsnap->cur_err  = SE_PARITY;				smsnap->cur_state = STATE_MSG_PARITY;				break;			   case SC_DEVICE_RESET:				DPRINTF("sm_intr: RESET_err msg\n");				smsnap->cur_state = STATE_RESET;				smsnap->cur_err  = SE_RESET;				break;				   case SC_ABORT:				DPRINTF("sm_intr: ABORT_err msg\n");				smsnap->cur_state = STATE_MSG_ABORT;				smsnap->cur_err = SE_MSGERR;				break;	/* no need to send abort msg */			   case SC_MSG_REJECT:				DPRINTF("sm_intr: REJECT_err msg\n");				smsnap->cur_state = STATE_MSG_REJECT;				break;				/* All other is ocnsidered ERROR for now */			   case SC_DISCONNECT:			   case SC_SAVE_DATA_PTR:			   case SC_RESTORE_PTRS:			   case SC_EXTENDED_MESSAGE:				   case SC_LINK_CMD_CPLT:			   case SC_FLAG_LINK_CMD_CPLT: 			   case SC_IDENTIFY:			   case SC_DR_IDENTIFY:			   default:				EPRINTF1("sm_intr: unsupported message: %x\n", 					smsnap->scsi_message);				smsnap->cur_err = SE_MSGERR;			}			/* send a message accpt cmd */			ESP_WR.cmd = CMD_MSG_ACPT;			ESP_WR.cmd = CMD_NOP;		/* for ESP bug */			break;		          case ESP_PHASE_MSG_OUT:			  case ESP_PHASE_COMMAND:		  default: 	/* all others are bad, just set PHASE error */			EPRINTF1("sm_intr: bad phase, pre_state: %x\n", 				smsnap->cur_state);			smsnap->cur_err = SE_PHASERR;		}		break;	    case ESP_INT_RESET:	/* external scsi RESET interrupt received */		DPRINTF1("sm_intr: SCSI bus_reset int, state= %x\n", 			smsnap->cur_state);		/* just set flag, and sm_reset() will be called later */		smsnap->cur_err = SE_RESET;		break;	   case ESP_INT_ILLCMD:	/* illegal cmd */ 	   case INT_ILL_BUS:		/* illegal bus status */ 		DPRINTF1("sm_intr: illegal cmd= %x\n", ESP_RD.cmd);		smsnap->cur_err = SE_ILLCMD;		break;	    case ESP_INT_RESEL:            case ESP_INT_SELATN:	/* selected with ATN -- target cmd */    	    case ESP_INT_SEL:		/* selected without ATN -- target cmd */	    default:		/* all others are not supported NOW */		EPRINTF1("sm_intr: bad interrupt= %x\n", smsnap->esp_intr);		smsnap->cur_err = SE_PHASERR;	}INTR_CHK_ERR:	if (smsnap->cur_retry > MAX_RETRY) {                 EPRINTF1("sm_intr: retry exhausted, phase= %x\n",                         smsnap->cur_state);                 DEBUG_DELAY(10000000);                smsnap->cur_err = SE_TOUTERR;        }	/* Just simply pass the status to upper level callers */	if (smsnap->cur_err) {#ifdef SMDEBUG            if (smsnap->cur_err != SE_BUSTATERR) {                EPRINTF2("sm_intr: ESP_ERR= %x, phase= %x\n",                        smsnap->cur_err, smsnap->cur_state);            }#endif SMDEBUG	    DEBUG_DELAY(1000000);		 	    switch (smsnap->cur_err) {		case SE_SELTOUT:   /* select/resel timeout */		   ESP_WR.cmd = CMD_FLUSH;                   ESP_WR.cmd = CMD_NOP;		   break;	   /* return error, but NO reset */		case SE_BUSTATERR: /* bus ERR, i.e, chk_cond, busy */	  	   smsnap->cur_err = ZERO;	  	   smsnap->cur_state = STATE_FREE;		   break;	   /* return error, but NO reset */	        case SE_MEMERR:	   /* memory exception error during DMA */		case SE_DIRERR:    /* WRONG DMA direction, could trash MEM */                case SE_DVMAERR:   /* DVMA Drain stuck */                case SE_ILLCMD:	   /* illegal command detected */		case SE_PARITY:	   /* either ESP or target parity ERR */		case SE_FIFOVER:   /* ESP status err, fifo overflown */		case SE_CMDOVER:   /* ESP status err, command overflown */ 		case SE_RESET:	   /* reset detected */		   /* software reset (NO external SCSI reset) */		   sm_reset(h_sip, RESET_INT_ONLY);		   break;		case SE_TOUTERR:   /* DMA timed out */		case SE_MSGERR:	   /* ESP has un-expected message */		case SE_PHASERR:   /* ESP has un-expected phase */		   /* possible HW error, do a HARD-SCSI reset */		   sm_reset(h_sip, RESET_ALL_SCSI);		   break;		case SE_REQPEND:	/* DMA's request pending stuck */                   toutcnt = (int)dvma->ctl_stat;                   EPRINTF1("sm_intr: DVMA-scsi req_pend stuck, stat= %x\n", 			toutcnt);		   break;		case SE_SPURINT:			   EPRINTF1("sm_intr: spurious esp_intr= %x\n",                        smsnap->esp_intr);                   smsnap->cur_err = ZERO;		   goto INTR_RTN;		default:		   DPRINTF1("sm_intr: spurious esp_err= %x\n", smsnap->cur_err);	    }	    smsnap->cur_state = STATE_FREE;	}INTR_RTN:	DPRINTF1("sm_intr: INTR_END, state= %x\n", smsnap->cur_state);	DEBUG_DELAY(100000);}#endif (defined sun4) || (defined sun3x)/* end of SCSI-ESP standalone boot driver (smboot.c) */

⌨️ 快捷键说明

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