📄 sym53c8xx.c
字号:
printf("script_data_out @ 0x%08lX\n",(unsigned long)&script_data_out[0]); printf("script_status @ 0x%08lX\n",(unsigned long)&script_status[0]); printf("script_complete @ 0x%08lX\n",(unsigned long)&script_complete[0]); printf("script_error @ 0x%08lX\n",(unsigned long)&script_error[0]);}void scsi_set_script(ccb *pccb){ int busdevfunc = pccb->priv; int i; i=0; script_select[i++]=swap_script(SCR_REG_REG(GPREG, SCR_AND, 0xfe)); script_select[i++]=0; /* LED ON */ script_select[i++]=swap_script(SCR_CLR(SCR_TRG)); /* select initiator mode */ script_select[i++]=0; /* script_select[i++]=swap_script(SCR_SEL_ABS_ATN | pccb->target << 16); */ script_select[i++]=swap_script(SCR_SEL_ABS | pccb->target << 16); script_select[i++]=swap_script(phys_to_bus(&script_cmd[4])); /* error handling */ script_select[i++]=swap_script(SCR_JUMP); /* next section */ /* script_select[i++]=swap_script((unsigned long)&script_msgout[0]); */ /* message out */ script_select[i++]=swap_script(phys_to_bus(&script_cmd[0])); /* command out */#ifdef SCSI_SINGLE_STEP start_script_select=(unsigned long)&script_select[0]; len_script_select=i*4;#endif i=0; script_msgout[i++]=swap_script(SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT))); script_msgout[i++]=SIR_SEL_ATN_NO_MSG_OUT; script_msgout[i++]=swap_script( SCR_MOVE_ABS(1) ^ SCR_MSG_OUT); script_msgout[i++]=swap_script(phys_to_bus(&pccb->msgout[0])); script_msgout[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_COMMAND))); /* if Command phase */ script_msgout[i++]=swap_script(phys_to_bus(&script_cmd[0])); /* switch to command */ script_msgout[i++]=swap_script(SCR_INT); /* interrupt if not */ script_msgout[i++]=SIR_MSG_OUT_NO_CMD;#ifdef SCSI_SINGLE_STEP start_script_msgout=(unsigned long)&script_msgout[0]; len_script_msgout=i*4;#endif i=0; script_cmd[i++]=swap_script(SCR_MOVE_ABS(pccb->cmdlen) ^ SCR_COMMAND); script_cmd[i++]=swap_script(phys_to_bus(&pccb->cmd[0])); script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN))); /* message in ? */ script_cmd[i++]=swap_script(phys_to_bus(&script_msgin[0])); script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT))); /* data out ? */ script_cmd[i++]=swap_script(phys_to_bus(&script_data_out[0])); script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN))); /* data in ? */ script_cmd[i++]=swap_script(phys_to_bus(&script_data_in[0])); script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_STATUS))); /* status ? */ script_cmd[i++]=swap_script(phys_to_bus(&script_status[0])); script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND))); /* command ? */ script_cmd[i++]=swap_script(phys_to_bus(&script_cmd[0])); script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT))); /* message out ? */ script_cmd[i++]=swap_script(phys_to_bus(&script_msgout[0])); script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_IN))); /* just for error handling message in ? */ script_cmd[i++]=swap_script(phys_to_bus(&script_msgin[0])); script_cmd[i++]=swap_script(SCR_INT); /* interrupt if not */ script_cmd[i++]=SIR_CMD_OUT_ILL_PH;#ifdef SCSI_SINGLE_STEP start_script_cmd=(unsigned long)&script_cmd[0]; len_script_cmd=i*4;#endif i=0; script_data_out[i++]=swap_script(SCR_MOVE_ABS(pccb->datalen)^ SCR_DATA_OUT); /* move */ script_data_out[i++]=swap_script(phys_to_bus(pccb->pdata)); /* pointer to buffer */ script_data_out[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS))); script_data_out[i++]=swap_script(phys_to_bus(&script_status[0])); script_data_out[i++]=swap_script(SCR_INT); script_data_out[i++]=SIR_DATA_OUT_ERR;#ifdef SCSI_SINGLE_STEP start_script_data_out=(unsigned long)&script_data_out[0]; len_script_data_out=i*4;#endif i=0; script_data_in[i++]=swap_script(SCR_MOVE_ABS(pccb->datalen)^ SCR_DATA_IN); /* move */ script_data_in[i++]=swap_script(phys_to_bus(pccb->pdata)); /* pointer to buffer */ script_data_in[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS))); script_data_in[i++]=swap_script(phys_to_bus(&script_status[0])); script_data_in[i++]=swap_script(SCR_INT); script_data_in[i++]=SIR_DATA_IN_ERR;#ifdef SCSI_SINGLE_STEP start_script_data_in=(unsigned long)&script_data_in[0]; len_script_data_in=i*4;#endif i=0; script_msgin[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); script_msgin[i++]=swap_script(phys_to_bus(&pccb->msgin[0])); script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE))); script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0])); script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT))); script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0])); script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP))); script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0])); script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP))); script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0])); script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED))); script_msgin[i++]=swap_script(phys_to_bus(&script_msg_ext[0])); script_msgin[i++]=swap_script(SCR_INT); script_msgin[i++]=SIR_MSG_RECEIVED;#ifdef SCSI_SINGLE_STEP start_script_msgin=(unsigned long)&script_msgin[0]; len_script_msgin=i*4;#endif i=0; script_msg_ext[i++]=swap_script(SCR_CLR (SCR_ACK)); /* clear ACK */ script_msg_ext[i++]=0; script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* assuming this is the msg length */ script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[1])); script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */ script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */ script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[2])); script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */ script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */ script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[3])); script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */ script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */ script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[4])); script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */ script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */ script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[5])); script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */ script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */ script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[6])); script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */ script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */ script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[7])); script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */ script_msg_ext[i++]=swap_script(SCR_INT); script_msg_ext[i++]=SIR_MSG_OVER7;#ifdef SCSI_SINGLE_STEP start_script_msg_ext=(unsigned long)&script_msg_ext[0]; len_script_msg_ext=i*4;#endif i=0; script_status[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_STATUS); script_status[i++]=swap_script(phys_to_bus(&pccb->status)); script_status[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN))); script_status[i++]=swap_script(phys_to_bus(&script_msgin[0])); script_status[i++]=swap_script(SCR_INT); script_status[i++]=SIR_STATUS_ILL_PH;#ifdef SCSI_SINGLE_STEP start_script_status=(unsigned long)&script_status[0]; len_script_status=i*4;#endif i=0; script_complete[i++]=swap_script(SCR_REG_REG (SCNTL2, SCR_AND, 0x7f)); script_complete[i++]=0; script_complete[i++]=swap_script(SCR_CLR (SCR_ACK|SCR_ATN)); script_complete[i++]=0; script_complete[i++]=swap_script(SCR_WAIT_DISC); script_complete[i++]=0; script_complete[i++]=swap_script(SCR_REG_REG(GPREG, SCR_OR, 0x01)); script_complete[i++]=0; /* LED OFF */ script_complete[i++]=swap_script(SCR_INT); script_complete[i++]=SIR_COMPLETE;#ifdef SCSI_SINGLE_STEP start_script_complete=(unsigned long)&script_complete[0]; len_script_complete=i*4;#endif i=0; script_error[i++]=swap_script(SCR_INT); /* interrupt if error */ script_error[i++]=SIR_SCRIPT_ERROR;#ifdef SCSI_SINGLE_STEP start_script_error=(unsigned long)&script_error[0]; len_script_error=i*4;#endif i=0; script_reselection[i++]=swap_script(SCR_CLR (SCR_TRG)); /* target status */ script_reselection[i++]=0; script_reselection[i++]=swap_script(SCR_WAIT_RESEL); script_reselection[i++]=swap_script(phys_to_bus(&script_select[0])); /* len = 4 */#ifdef SCSI_SINGLE_STEP start_script_reselection=(unsigned long)&script_reselection[0]; len_script_reselection=i*4;#endif}void scsi_issue(ccb *pccb){ int busdevfunc = pccb->priv; int i; unsigned short sstat; int retrycnt; /* retry counter */ for(i=0;i<3;i++) int_stat[i]=0; /* delete all int status */ /* struct pccb must be set-up correctly */ retrycnt=0; PRINTF("ID %d issue cmd %02X\n",pccb->target,pccb->cmd[0]); pccb->trans_bytes=0; /* no bytes transfered yet */ scsi_set_script(pccb); /* fill in SCRIPT */ scsi_int_mask=STO | UDC | MA; /* | CMP; / * Interrupts which are enabled */ script_int_mask=0xff; /* enable all Ints */ scsi_int_enable(); scsi_write_dsp(phys_to_bus(&script_select[0])); /* start script */ /* now we have to wait for IRQs */retry: /* * This version of the driver is _not_ interrupt driven, * but polls the chip's interrupt registers (ISTAT, DSTAT). */ while(int_stat[0]==0) handle_scsi_int(); if(int_stat[0]==SIR_COMPLETE) { if(pccb->msgin[0]==M_DISCONNECT) { PRINTF("Wait for reselection\n"); for(i=0;i<3;i++) int_stat[i]=0; /* delete all int status */ scsi_write_dsp(phys_to_bus(&script_reselection[0])); /* start reselection script */ goto retry; } pccb->contr_stat=SIR_COMPLETE; return; } if((int_stat[0] & SCSI_INT_STATE)==SCSI_INT_STATE) { /* scsi interrupt */ sstat=(unsigned short)int_stat[0]; if((sstat & STO)==STO) { /* selection timeout */ pccb->contr_stat=SCSI_SEL_TIME_OUT; scsi_write_byte(GPREG,0x01); PRINTF("ID: %X Selection Timeout\n",pccb->target); return; } if((sstat & UDC)==UDC) { /* unexpected disconnect */ pccb->contr_stat=SCSI_UNEXP_DIS; scsi_write_byte(GPREG,0x01); PRINTF("ID: %X Unexpected Disconnect\n",pccb->target); return; } if((sstat & RSL)==RSL) { /* reselection */ pccb->contr_stat=SCSI_UNEXP_DIS; scsi_write_byte(GPREG,0x01); PRINTF("ID: %X Unexpected Disconnect\n",pccb->target); return; } if(((sstat & MA)==MA)||((sstat & HTH)==HTH)) { /* phase missmatch */ if(retrycnt<SCSI_MAX_RETRY) { pccb->trans_bytes=pccb->datalen - ((unsigned long)scsi_read_byte(DBC) | ((unsigned long)scsi_read_byte(DBC+1)<<8) | ((unsigned long)scsi_read_byte(DBC+2)<<16)); for(i=0;i<3;i++) int_stat[i]=0; /* delete all int status */ retrycnt++; PRINTF("ID: %X Phase Missmatch Retry %d Phase %02X transfered %lx\n", pccb->target,retrycnt,scsi_read_byte(SBCL),pccb->trans_bytes); scsi_write_dsp(phys_to_bus(&script_cmd[4])); /* start retry script */ goto retry; } if((sstat & MA)==MA) pccb->contr_stat=SCSI_MA_TIME_OUT; else pccb->contr_stat=SCSI_HNS_TIME_OUT; PRINTF("Phase Missmatch stat %lx\n",pccb->contr_stat); return; } /* no phase int *//* if((sstat & CMP)==CMP) { pccb->contr_stat=SIR_COMPLETE; return; }*/ PRINTF("SCSI INT %lX\n",int_stat[0]); pccb->contr_stat=int_stat[0]; return; } /* end scsi int */ PRINTF("SCRIPT INT %lX phase %02X\n",int_stat[0],scsi_read_byte(SBCL)); pccb->contr_stat=int_stat[0]; return;}int scsi_exec(ccb *pccb){ unsigned char tmpcmd[16],tmpstat; int i,retrycnt,t; unsigned long transbytes,datalen; unsigned char *tmpptr; retrycnt=0;retry: scsi_issue(pccb); if(pccb->contr_stat!=SIR_COMPLETE) return FALSE; if(pccb->status==S_GOOD) return TRUE; if(pccb->status==S_CHECK_COND) { /* check condition */ for(i=0;i<16;i++) tmpcmd[i]=pccb->cmd[i]; pccb->cmd[0]=SCSI_REQ_SENSE; pccb->cmd[1]=pccb->lun<<5; pccb->cmd[2]=0; pccb->cmd[3]=0; pccb->cmd[4]=14; pccb->cmd[5]=0; pccb->cmdlen=6; pccb->msgout[0]=SCSI_IDENTIFY; transbytes=pccb->trans_bytes; tmpptr=pccb->pdata; pccb->pdata=&pccb->sense_buf[0]; datalen=pccb->datalen; pccb->datalen=14; tmpstat=pccb->status; scsi_issue(pccb); for(i=0;i<16;i++) pccb->cmd[i]=tmpcmd[i]; pccb->trans_bytes=transbytes; pccb->pdata=tmpptr; pccb->datalen=datalen; pccb->status=tmpstat; PRINTF("Request_sense sense key %x ASC %x ASCQ %x\n",pccb->sense_buf[2]&0x0f, pccb->sense_buf[12],pccb->sense_buf[13]); switch(pccb->sense_buf[2]&0xf) { case SENSE_NO_SENSE: case SENSE_RECOVERED_ERROR: /* seems to be ok */ return TRUE; break; case SENSE_NOT_READY: if((pccb->sense_buf[12]!=0x04)||(pccb->sense_buf[13]!=0x01)) { /* if device is not in process of becoming ready */ return FALSE; break; } /* else fall through */ case SENSE_UNIT_ATTENTION: if(retrycnt<SCSI_MAX_RETRY_NOT_READY) { PRINTF("Target %d not ready, retry %d\n",pccb->target,retrycnt); for(t=0;t<SCSI_NOT_READY_TIME_OUT;t++) udelay(1000); /* 1sec wait */ retrycnt++; goto retry; } PRINTF("Target %d not ready, %d retried\n",pccb->target,retrycnt); return FALSE; default: return FALSE; } } PRINTF("Status = %X\n",pccb->status); return FALSE;}void scsi_chip_init(void){ /* first we issue a soft reset */ scsi_write_byte(ISTAT,SRST); udelay(1000); scsi_write_byte(ISTAT,0); /* setup chip */ scsi_write_byte(SCNTL0,0xC0); /* full arbitration no start, no message, parity disabled, master */ scsi_write_byte(SCNTL1,0x00); scsi_write_byte(SCNTL2,0x00);#ifndef CFG_SCSI_SYM53C8XX_CCF /* config value for none 40 mhz clocks */ scsi_write_byte(SCNTL3,0x13); /* synchronous clock 40/4=10MHz, asynchronous 40MHz */#else scsi_write_byte(SCNTL3,CFG_SCSI_SYM53C8XX_CCF); /* config value for none 40 mhz clocks */#endif scsi_write_byte(SCID,0x47); /* ID=7, enable reselection */ scsi_write_byte(SXFER,0x00); /* synchronous transfer period 10MHz, asynchronous */ scsi_write_byte(SDID,0x00); /* targed SCSI ID = 0 */ scsi_int_mask=0x0000; /* no Interrupt is enabled */ script_int_mask=0x00; scsi_int_enable(); scsi_write_byte(GPREG,0x01); /* GPIO0 is LED (off) */ scsi_write_byte(GPCNTL,0x0E); /* GPIO0 is Output */ scsi_write_byte(STIME0,0x08); /* handshake timer disabled, selection timeout 512msec */ scsi_write_byte(RESPID,0x80); /* repond only to the own ID (reselection) */ scsi_write_byte(STEST1,0x00); /* not isolated, SCLK is used */ scsi_write_byte(STEST2,0x00); /* no Lowlevel Mode? */ scsi_write_byte(STEST3,0x80); /* enable tolerANT */ scsi_write_byte(CTEST3,0x04); /* clear FIFO */ scsi_write_byte(CTEST4,0x00); scsi_write_byte(CTEST5,0x00);#ifdef SCSI_SINGLE_STEP/* scsi_write_byte(DCNTL,IRQM | SSM); */ scsi_write_byte(DCNTL,IRQD | SSM); scsi_write_byte(DMODE,MAN);#else/* scsi_write_byte(DCNTL,IRQM); */ scsi_write_byte(DCNTL,IRQD); scsi_write_byte(DMODE,0x00);#endif}#endif /* (CONFIG_COMMANDS & CFG_CMD_SCSI) */#endif /* CONFIG_SCSI_SYM53C8XX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -