📄 ncr53c8xx.c
字号:
/*---------------------------------------------------------------- ** Miscellaneous buffers accessed by the scripts-processor. ** They shall be DWORD aligned, because they may be read or ** written with a SCR_COPY script command. **---------------------------------------------------------------- */ u_char msgout[8]; /* Buffer for MESSAGE OUT */ u_char msgin [8]; /* Buffer for MESSAGE IN */ u_int32 lastmsg; /* Last SCSI message sent */ u_char scratch; /* Scratch for SCSI receive */ /*---------------------------------------------------------------- ** Miscellaneous configuration and status parameters. **---------------------------------------------------------------- */ u_char disc; /* Diconnection allowed */ u_char scsi_mode; /* Current SCSI BUS mode */ u_char order; /* Tag order to use */ u_char verbose; /* Verbosity for this controller*/ int ncr_cache; /* Used for cache test at init. */ /*---------------------------------------------------------------- ** Command completion handling. **---------------------------------------------------------------- */#ifdef SCSI_NCR_CCB_DONE_SUPPORT struct ccb *(ccb_done[MAX_DONE]); int ccb_done_ic;#endif /*---------------------------------------------------------------- ** Fields that should be removed or changed. **---------------------------------------------------------------- */ struct ccb *ccb; /* Global CCB */ struct usrcmd user; /* Command from user */ u_char release_stage; /* Synchronisation stage on release */};#define NCB_SCRIPT_PHYS(np,lbl) (np->p_script + offsetof (struct script, lbl))#define NCB_SCRIPTH_PHYS(np,lbl) (np->p_scripth + offsetof (struct scripth,lbl))/*==========================================================****** Script for NCR-Processor.**** Use ncr_script_fill() to create the variable parts.** Use ncr_script_copy_and_bind() to make a copy and** bind to physical addresses.******==========================================================**** We have to know the offsets of all labels before** we reach them (for forward jumps).** Therefore we declare a struct here.** If you make changes inside the script,** DONT FORGET TO CHANGE THE LENGTHS HERE!****----------------------------------------------------------*//*** Script fragments which are loaded into the on-chip RAM ** of 825A, 875 and 895 chips.*/struct script { ncrcmd start [ 5]; ncrcmd startpos [ 1]; ncrcmd select [ 6]; ncrcmd select2 [ 9]; ncrcmd loadpos [ 4]; ncrcmd send_ident [ 9]; ncrcmd prepare [ 6]; ncrcmd prepare2 [ 7];#ifdef SCSI_NCR_PROFILE_SUPPORT ncrcmd command [ 9];#else ncrcmd command [ 6];#endif ncrcmd dispatch [ 32]; ncrcmd clrack [ 4]; ncrcmd no_data [ 17];#ifdef SCSI_NCR_PROFILE_SUPPORT ncrcmd status [ 11];#else ncrcmd status [ 8];#endif ncrcmd msg_in [ 2]; ncrcmd msg_in2 [ 16]; ncrcmd msg_bad [ 4]; ncrcmd setmsg [ 7]; ncrcmd cleanup [ 6]; ncrcmd complete [ 9]; ncrcmd cleanup_ok [ 8]; ncrcmd cleanup0 [ 1];#ifndef SCSI_NCR_CCB_DONE_SUPPORT ncrcmd signal [ 12];#else ncrcmd signal [ 9]; ncrcmd done_pos [ 1]; ncrcmd done_plug [ 2]; ncrcmd done_end [ 7];#endif ncrcmd save_dp [ 7]; ncrcmd restore_dp [ 5];#ifdef SCSI_NCR_PROFILE_SUPPORT ncrcmd disconnect [ 28];#else ncrcmd disconnect [ 17];#endif ncrcmd msg_out [ 9]; ncrcmd msg_out_done [ 7]; ncrcmd idle [ 2]; ncrcmd reselect [ 8]; ncrcmd reselected [ 8]; ncrcmd resel_dsa [ 6];#ifdef SCSI_NCR_PROFILE_SUPPORT ncrcmd loadpos1 [ 7];#else ncrcmd loadpos1 [ 4];#endif ncrcmd resel_lun [ 6]; ncrcmd resel_tag [ 6]; ncrcmd jump_to_nexus [ 4]; ncrcmd nexus_indirect [ 4]; ncrcmd resel_notag [ 4]; ncrcmd data_in [MAX_SCATTERL * 4]; ncrcmd data_in2 [ 4]; ncrcmd data_out [MAX_SCATTERL * 4]; ncrcmd data_out2 [ 4];};/*** Script fragments which stay in main memory for all chips.*/struct scripth { ncrcmd tryloop [MAX_START*2]; ncrcmd tryloop2 [ 2];#ifdef SCSI_NCR_CCB_DONE_SUPPORT ncrcmd done_queue [MAX_DONE*5]; ncrcmd done_queue2 [ 2];#endif ncrcmd select_no_atn [ 8]; ncrcmd cancel [ 4]; ncrcmd skip [ 9]; ncrcmd skip2 [ 19]; ncrcmd par_err_data_in [ 6]; ncrcmd par_err_other [ 4]; ncrcmd msg_reject [ 8]; ncrcmd msg_ign_residue [ 24]; ncrcmd msg_extended [ 10]; ncrcmd msg_ext_2 [ 10]; ncrcmd msg_wdtr [ 14]; ncrcmd send_wdtr [ 7]; ncrcmd msg_ext_3 [ 10]; ncrcmd msg_sdtr [ 14]; ncrcmd send_sdtr [ 7]; ncrcmd nego_bad_phase [ 4]; ncrcmd msg_out_abort [ 10]; ncrcmd hdata_in [MAX_SCATTERH * 4]; ncrcmd hdata_in2 [ 2]; ncrcmd hdata_out [MAX_SCATTERH * 4]; ncrcmd hdata_out2 [ 2]; ncrcmd reset [ 4]; ncrcmd aborttag [ 4]; ncrcmd abort [ 2]; ncrcmd abort_resel [ 20]; ncrcmd resend_ident [ 4]; ncrcmd clratn_go_on [ 3]; ncrcmd nxtdsp_go_on [ 1]; ncrcmd sdata_in [ 8]; ncrcmd data_io [ 18]; ncrcmd bad_identify [ 12]; ncrcmd bad_i_t_l [ 4]; ncrcmd bad_i_t_l_q [ 4]; ncrcmd bad_target [ 8]; ncrcmd bad_status [ 8]; ncrcmd start_ram [ 4]; ncrcmd start_ram0 [ 4]; ncrcmd sto_restart [ 5]; ncrcmd snooptest [ 9]; ncrcmd snoopend [ 2];};/*==========================================================****** Function headers.******==========================================================*/static void ncr_alloc_ccb (ncb_p np, u_char tn, u_char ln);static void ncr_complete (ncb_p np, ccb_p cp);static void ncr_exception (ncb_p np);static void ncr_free_ccb (ncb_p np, ccb_p cp);static void ncr_init_ccb (ncb_p np, ccb_p cp);static void ncr_init_tcb (ncb_p np, u_char tn);static lcb_p ncr_alloc_lcb (ncb_p np, u_char tn, u_char ln);static lcb_p ncr_setup_lcb (ncb_p np, u_char tn, u_char ln, u_char *inq_data);static void ncr_getclock (ncb_p np, int mult);static void ncr_selectclock (ncb_p np, u_char scntl3);static ccb_p ncr_get_ccb (ncb_p np, u_char tn, u_char ln);static void ncr_init (ncb_p np, int reset, char * msg, u_long code);static int ncr_int_sbmc (ncb_p np);static int ncr_int_par (ncb_p np);static void ncr_int_ma (ncb_p np);static void ncr_int_sir (ncb_p np);static void ncr_int_sto (ncb_p np);static u_long ncr_lookup (char* id);static void ncr_negotiate (struct ncb* np, struct tcb* tp);#ifdef SCSI_NCR_PROFILE_SUPPORTstatic void ncb_profile (ncb_p np, ccb_p cp);#endifstatic void ncr_script_copy_and_bind (ncb_p np, ncrcmd *src, ncrcmd *dst, int len);static void ncr_script_fill (struct script * scr, struct scripth * scripth);static int ncr_scatter (ccb_p cp, Scsi_Cmnd *cmd);static void ncr_getsync (ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p);static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer);static void ncr_setup_tags (ncb_p np, u_char tn, u_char ln);static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide, u_char ack);static int ncr_show_msg (u_char * msg);static int ncr_snooptest (ncb_p np);static void ncr_timeout (ncb_p np);static void ncr_wakeup (ncb_p np, u_long code);static void ncr_wakeup_done (ncb_p np);static void ncr_start_next_ccb (ncb_p np, lcb_p lp, int maxn);static void ncr_put_start_queue(ncb_p np, ccb_p cp);static void ncr_start_reset (ncb_p np);static int ncr_reset_scsi_bus (ncb_p np, int enab_int, int settle_delay);#ifdef SCSI_NCR_USER_COMMAND_SUPPORTstatic void ncr_usercmd (ncb_p np);#endifstatic int ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device);static void insert_into_waiting_list(ncb_p np, Scsi_Cmnd *cmd);static Scsi_Cmnd *retrieve_from_waiting_list(int to_remove, ncb_p np, Scsi_Cmnd *cmd);static void process_waiting_list(ncb_p np, int sts);#define remove_from_waiting_list(np, cmd) \ retrieve_from_waiting_list(1, (np), (cmd))#define requeue_waiting_list(np) process_waiting_list((np), DID_OK)#define reset_waiting_list(np) process_waiting_list((np), DID_RESET)#ifdef SCSI_NCR_NVRAM_SUPPORTstatic int ncr_get_Symbios_nvram (ncr_slot *np, Symbios_nvram *nvram);static int ncr_get_Tekram_nvram (ncr_slot *np, Tekram_nvram *nvram);#endif/*==========================================================****** Global static data.******==========================================================*/#ifdef SCSI_NCR_DEBUG_INFO_SUPPORTstatic int ncr_debug = SCSI_NCR_DEBUG_FLAGS;#endifstatic inline char *ncr_name (ncb_p np){ return np->inst_name;}/*==========================================================****** Scripts for NCR-Processor.**** Use ncr_script_bind for binding to physical addresses.******==========================================================**** NADDR generates a reference to a field of the controller data.** PADDR generates a reference to another part of the script.** RADDR generates a reference to a script processor register.** FADDR generates a reference to a script processor register** with offset.****----------------------------------------------------------*/#define RELOC_SOFTC 0x40000000#define RELOC_LABEL 0x50000000#define RELOC_REGISTER 0x60000000#define RELOC_KVAR 0x70000000#define RELOC_LABELH 0x80000000#define RELOC_MASK 0xf0000000#define NADDR(label) (RELOC_SOFTC | offsetof(struct ncb, label))#define PADDR(label) (RELOC_LABEL | offsetof(struct script, label))#define PADDRH(label) (RELOC_LABELH | offsetof(struct scripth, label))#define RADDR(label) (RELOC_REGISTER | REG(label))#define FADDR(label,ofs)(RELOC_REGISTER | ((REG(label))+(ofs)))#define KVAR(which) (RELOC_KVAR | (which))#define SCRIPT_KVAR_JIFFIES (0)#define SCRIPT_KVAR_FIRST SCRIPT_KVAR_JIFFIES#define SCRIPT_KVAR_LAST SCRIPT_KVAR_JIFFIES/* * Kernel variables referenced in the scripts. * THESE MUST ALL BE ALIGNED TO A 4-BYTE BOUNDARY. */static void *script_kvars[] __initdata = { (void *)&jiffies };static struct script script0 __initdata = {/*--------------------------< START >-----------------------*/ { /* ** This NOP will be patched with LED ON ** SCR_REG_REG (gpreg, SCR_AND, 0xfe) */ SCR_NO_OP, 0, /* ** Clear SIGP. */ SCR_FROM_REG (ctest2), 0, /* ** Then jump to a certain point in tryloop. ** Due to the lack of indirect addressing the code ** is self modifying here. */ SCR_JUMP,}/*-------------------------< STARTPOS >--------------------*/,{ PADDRH(tryloop),}/*-------------------------< SELECT >----------------------*/,{ /* ** DSA contains the address of a scheduled ** data structure. ** ** SCRATCHA contains the address of the script, ** which starts the next entry. ** ** Set Initiator mode. ** ** (Target mode is left as an exercise for the reader) */ SCR_CLR (SCR_TRG), 0, SCR_LOAD_REG (HS_REG, HS_SELECTING), 0, /* ** And try to select this target. */ SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select), PADDR (reselect),}/*-------------------------< SELECT2 >----------------------*/,{ /* ** Now there are 4 possibilities: ** ** (1) The ncr looses arbitration. ** This is ok, because it will try again, ** when the bus becomes idle. ** (But beware of the timeout function!) ** ** (2) The ncr is reselected. ** Then the script processor takes the jump ** to the RESELECT label. ** ** (3) The ncr wins arbitration. ** Then it will execute SCRIPTS instruction until ** the next instruction that checks SCSI phase. ** Then will stop and wait for selection to be ** complete or selection time-out to occur. ** As a result the SCRIPTS instructions until ** LOADPOS + 2 should be executed in parallel with ** the SCSI core performing selection. */ /* ** The M_REJECT problem seems to be due to a selection ** timing problem. ** Wait immediately for the selection to complete. ** (2.5x behaves so) */ SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_OUT)), 0, /* ** Next time use the next slot. */ SCR_COPY (4), RADDR (temp), PADDR (startpos), /* ** The ncr doesn't have an indirect load ** or store command. So we have to ** copy part of the control block to a ** fixed place, where we can access it. ** ** We patch the address part of a ** COPY command with the DSA-register. */ SCR_COPY_F (4), RADDR (dsa), PADDR (loadpos), /* ** then we do the actual copy. */ SCR_COPY (sizeof (struct head)), /* ** continued after the next label ... */}/*-------------------------< LOADPOS >---------------------*/,{ 0, NADDR (header), /* ** Wait for the next phase or the selection ** to complete or time-out. */ SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), PADDR (prepare),}/*-------------------------< SEND_IDENT >----------------------*/,{ /* ** Selection complete. ** Send the IDENTIFY and SIMPLE_TAG messages ** (and the M_X_SYNC_REQ message) */ SCR_MOVE_TBL ^ SCR_MSG_OUT, offsetof (struct dsb, smsg), SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), PADDRH (resend_ident), SCR_LOAD_REG (scratcha, 0x80), 0, SCR_COPY (1), RADDR (scratcha
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -