📄 ncr53c8xx.c
字号:
u_char sv_stest2; u_char sv_stest4; u_char rv_scntl0; u_char rv_scntl3; u_char rv_dmode; u_char rv_dcntl; u_char rv_ctest3; u_char rv_ctest4; u_char rv_ctest5; u_char rv_stest2; u_char scsi_mode; /*----------------------------------------------- ** Scripts .. **----------------------------------------------- ** ** During reselection the ncr jumps to this point. ** The SFBR register is loaded with the encoded target id. ** ** Jump to the first target. ** ** JUMP ** @(next tcb) */ struct link jump_tcb; /*----------------------------------------------- ** Configuration .. **----------------------------------------------- ** ** virtual and physical addresses ** of the 53c810 chip. */ vm_offset_t vaddr; vm_offset_t paddr; vm_offset_t vaddr2; vm_offset_t paddr2; /* ** pointer to the chip's registers. */ volatile struct ncr_reg* reg; /* ** A copy of the scripts, relocated for this ncb. */ struct script *script0; struct scripth *scripth0; /* ** Scripts instance virtual address. */ struct script *script; struct scripth *scripth; /* ** Scripts instance physical address. */ u_long p_script; u_long p_scripth; /* ** The SCSI address of the host adapter. */ u_char myaddr; /* ** Max dwords burst supported by the adapter. */ u_char maxburst; /* log base 2 of dwords burst */ /* ** timing parameters */ u_char minsync; /* Minimum sync period factor */ u_char maxsync; /* Maximum sync period factor */ u_char maxoffs; /* Max scsi offset */ u_char multiplier; /* Clock multiplier (1,2,4) */ u_char clock_divn; /* Number of clock divisors */ u_long clock_khz; /* SCSI clock frequency in KHz */ u_int features; /* Chip features map */ /*----------------------------------------------- ** Link to the generic SCSI driver **----------------------------------------------- */ /* struct scsi_link sc_link; */ /*----------------------------------------------- ** Job control **----------------------------------------------- ** ** Commands from user */ struct usrcmd user; u_char order; /* ** Target data */ struct tcb target[MAX_TARGET]; /* ** Start queue. */ u_int32 squeue [MAX_START]; u_short squeueput; u_short actccbs; /* ** Timeout handler */#if 0 u_long heartbeat; u_short ticks; u_short latetime;#endif u_long lasttime; /*----------------------------------------------- ** Debug and profiling **----------------------------------------------- ** ** register dump */ struct ncr_reg regdump; u_long regtime; /* ** Profiling data */ struct profile profile; u_long disc_phys; u_long disc_ref; /* ** The global control block. ** It's used only during the configuration phase. ** A target control block will be created ** after the first successful transfer. */ struct ccb *ccb; /* ** message buffers. ** Should be longword aligned, ** because they're written with a ** COPY script command. */ u_char msgout[8]; u_char msgin [8]; u_int32 lastmsg; /* ** Buffer for STATUS_IN phase. */ u_char scratch; /* ** controller chip dependent maximal transfer width. */ u_char maxwide; /* ** option for M_IDENTIFY message: enables disconnecting */ u_char disc; /* ** address of the ncr control registers in io space */ u_int port; /* ** irq level */ u_short irq;};#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,** DON'T FORGET TO CHANGE THE LENGTHS HERE!****----------------------------------------------------------*//*** Script fragments which are loaded into the on-board RAM ** of 825A, 875 and 895 chips.*/struct script { ncrcmd start [ 4]; ncrcmd start0 [ 2]; ncrcmd start1 [ 3]; ncrcmd startpos [ 1]; ncrcmd trysel [ 8]; ncrcmd skip [ 8]; ncrcmd skip2 [ 3]; ncrcmd idle [ 2]; ncrcmd select [ 22]; ncrcmd prepare [ 4]; ncrcmd loadpos [ 14]; ncrcmd prepare2 [ 24]; ncrcmd setmsg [ 5]; ncrcmd clrack [ 2]; ncrcmd dispatch [ 38]; ncrcmd no_data [ 17]; ncrcmd checkatn [ 10]; ncrcmd command [ 15]; ncrcmd status [ 27]; ncrcmd msg_in [ 26]; ncrcmd msg_bad [ 6]; ncrcmd complete [ 13]; ncrcmd cleanup [ 12]; ncrcmd cleanup0 [ 11]; ncrcmd signal [ 10]; ncrcmd save_dp [ 5]; ncrcmd restore_dp [ 5]; ncrcmd disconnect [ 12]; ncrcmd disconnect0 [ 5]; ncrcmd disconnect1 [ 23]; ncrcmd msg_out [ 9]; ncrcmd msg_out_done [ 7]; ncrcmd badgetcc [ 6]; ncrcmd reselect [ 8]; ncrcmd reselect1 [ 8]; ncrcmd reselect2 [ 8]; ncrcmd resel_tmp [ 5]; ncrcmd resel_lun [ 18]; ncrcmd resel_tag [ 24]; ncrcmd data_io [ 6]; ncrcmd data_in [MAX_SCATTER * 4 + 4];};/*** Script fragments which stay in main memory for all chips.*/struct scripth { ncrcmd tryloop [MAX_START*5+2]; ncrcmd msg_parity [ 6]; ncrcmd msg_reject [ 8]; ncrcmd msg_ign_residue [ 32]; ncrcmd msg_extended [ 18]; ncrcmd msg_ext_2 [ 18]; ncrcmd msg_wdtr [ 27]; ncrcmd msg_ext_3 [ 18]; ncrcmd msg_sdtr [ 27]; ncrcmd msg_out_abort [ 10]; ncrcmd getcc [ 4]; ncrcmd getcc1 [ 5];#ifdef NCR_GETCC_WITHMSG ncrcmd getcc2 [ 33];#else ncrcmd getcc2 [ 14];#endif ncrcmd getcc3 [ 10]; ncrcmd data_out [MAX_SCATTER * 4 + 4]; ncrcmd aborttag [ 4]; ncrcmd abort [ 22]; ncrcmd snooptest [ 9]; ncrcmd snoopend [ 2];};/*==========================================================****** Function headers.******==========================================================*/static void ncr_alloc_ccb (ncb_p np, u_long t, u_long l);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, u_long t, u_long l);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_long t,u_long l);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);static void ncr_opennings (ncb_p np, lcb_p lp, Scsi_Cmnd * xp);#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_setmaxtags (ncb_p np, tcb_p tp, u_long numtags);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_settags (tcb_p tp, lcb_p lp);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_start_reset (ncb_p np, int settle_delay);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 >-----------------------*/ {#if 0 /* ** Claim to be still alive ... */ SCR_COPY (sizeof (((struct ncb *)0)->heartbeat)), KVAR(SCRIPT_KVAR_JIFFIES), NADDR (heartbeat),#endif /* ** Make data structure address invalid. ** clear SIGP. */ SCR_LOAD_REG (dsa, 0xff), 0, SCR_FROM_REG (ctest2), 0,}/*-------------------------< START0 >----------------------*/,{ /* ** Hook for interrupted GetConditionCode. ** Will be patched to ... IFTRUE by ** the interrupt handler. */ SCR_INT ^ IFFALSE (0), SIR_SENSE_RESTART,}/*-------------------------< START1 >----------------------*/,{ /* ** Hook for stalled start queue. ** Will be patched to IFTRUE by the interrupt handler. */ SCR_INT ^ IFFALSE (0), SIR_STALL_RESTART, /* ** 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),}/*-------------------------< TRYSEL >----------------------*/,{ /* ** Now: ** DSA: Address of a Data Structure ** or Address of the IDLE-Label. ** ** TEMP: Address of a script, which tries to ** start the NEXT entry. ** ** Save the TEMP register into the SCRATCHA register. ** Then copy the DSA to TEMP and RETURN. ** This is kind of an indirect jump. ** (The script processor has NO stack, so the ** CALL is actually a jump and link, and the ** RETURN is an indirect jump.) ** ** If the slot was empty, DSA contains the address ** of the IDLE part of this script. The processor ** jumps to IDLE and waits for a reselect. ** It will wake up and try the same slot again ** after the SIGP bit becomes set by the host. ** ** If the slot was not empty, DSA contains ** the address of the phys-part of a ccb. ** The processor jumps to this address. ** phys starts with head, ** head starts with launch, ** so actually the processor jumps to ** the lauch part. ** If the entry is scheduled for execution, ** then launch contains a jump to SELECT. ** If it's not scheduled, it contains a jump to IDLE. */ SCR_COPY (4), RADDR (temp), RADDR (scratcha), SCR_COPY (4), RADDR (dsa), RADDR (temp), SCR_RETURN, 0}/*-------------------------< SKIP >------------------------*/,{ /* ** This entry has been canceled. ** Next time use the next slot. */ SCR_COPY (4), RADDR (scratcha), PADDR (startpos), /* ** patch the launch field. ** should look like an idle process. */ SCR_COPY_F (4), RADDR (dsa), PADDR (skip2), SCR_COPY (8), PADDR (idle),}/*-------------------------< SKIP2 >-----------------------*/,{ 0, SCR_JUMP, PADDR(start),}/*-------------------------< IDLE >------------------------*/,{ /* ** Nothing to do? ** Wait for reselect. */ SCR_JUMP, PADDR(reselect),}/*-------------------------< 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, 0xff), 0, /* ** And try to select this target. */ SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select), PADDR (reselect),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -