📄 53c7xx.h
字号:
* pointers and offsets that are unique for the different * scripts rather than having a slew of switch(hostdata->chip) * statements. * * It also means that the #defines from the SCSI SCRIPTS(tm) * don't have to be visible outside of the script-specific * instructions, preventing name space pollution. */ void (* init_fixup)(struct Scsi_Host *host); void (* init_save_regs)(struct Scsi_Host *host); void (* dsa_fixup)(struct NCR53c7x0_cmd *cmd); void (* soft_reset)(struct Scsi_Host *host); int (* run_tests)(struct Scsi_Host *host); /* * Called when DSTAT_SIR is set, indicating an interrupt generated * by the INT instruction, where values are unique for each SCSI * script. Should return one of the SPEC_* values. */ int (* dstat_sir_intr)(struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd); int dsa_len; /* Size of DSA structure */ /* * Location of DSA fields for the SCSI SCRIPT corresponding to this * chip. */ s32 dsa_start; s32 dsa_end; s32 dsa_next; s32 dsa_prev; s32 dsa_cmnd; s32 dsa_select; s32 dsa_msgout; s32 dsa_cmdout; s32 dsa_dataout; s32 dsa_datain; s32 dsa_msgin; s32 dsa_msgout_other; s32 dsa_write_sync; s32 dsa_write_resume; s32 dsa_check_reselect; s32 dsa_status; s32 dsa_saved_pointer; s32 dsa_jump_dest; /* * Important entry points that generic fixup code needs * to know about, fixed up. */ s32 E_accept_message; s32 E_command_complete; s32 E_data_transfer; s32 E_dsa_code_template; s32 E_dsa_code_template_end; s32 E_end_data_transfer; s32 E_msg_in; s32 E_initiator_abort; s32 E_other_transfer; s32 E_other_in; s32 E_other_out; s32 E_target_abort; s32 E_debug_break; s32 E_reject_message; s32 E_respond_message; s32 E_select; s32 E_select_msgout; s32 E_test_0; s32 E_test_1; s32 E_test_2; s32 E_test_3; s32 E_dsa_zero; s32 E_cmdout_cmdout; s32 E_wait_reselect; s32 E_dsa_code_begin; long long options; /* Bitfielded set of options enabled */ volatile u32 test_completed; /* Test completed */ int test_running; /* Test currently running */ s32 test_source __attribute__ ((aligned (4))); volatile s32 test_dest; volatile int state; /* state of driver, only used for OPTION_700 */ unsigned char dmode; /* * set to the address of the DMODE * register for this chip. */ unsigned char istat; /* * set to the address of the ISTAT * register for this chip. */ int scsi_clock; /* * SCSI clock in HZ. 0 may be used * for unknown, although this will * disable synchronous negotiation. */ volatile int intrs; /* Number of interrupts */ volatile int resets; /* Number of SCSI resets */ unsigned char saved_dmode; unsigned char saved_ctest4; unsigned char saved_ctest7; unsigned char saved_dcntl; unsigned char saved_scntl3; unsigned char this_id_mask; /* Debugger information */ struct NCR53c7x0_break *breakpoints, /* Linked list of all break points */ *breakpoint_current; /* Current breakpoint being stepped through, NULL if we are running normally. */#ifdef NCR_DEBUG int debug_size; /* Size of debug buffer */ volatile int debug_count; /* Current data count */ volatile char *debug_buf; /* Output ring buffer */ volatile char *debug_write; /* Current write pointer */ volatile char *debug_read; /* Current read pointer */#endif /* def NCR_DEBUG */ /* XXX - primitive debugging junk, remove when working ? */ int debug_print_limit; /* Number of commands to print out exhaustive debugging information for if OPTION_DEBUG_DUMP is set */ unsigned char debug_lun_limit[16]; /* If OPTION_DEBUG_TARGET_LIMIT set, puke if commands are sent to other target/lun combinations */ int debug_count_limit; /* Number of commands to execute before puking to limit debugging output */ volatile unsigned idle:1; /* set to 1 if idle */ /* * Table of synchronous+wide transfer parameters set on a per-target * basis. */ volatile struct NCR53c7x0_synchronous sync[16] __attribute__ ((aligned (4))); volatile Scsi_Cmnd *issue_queue __attribute__ ((aligned (4))); /* waiting to be issued by Linux driver */ volatile struct NCR53c7x0_cmd *running_list; /* commands running, maintained by Linux driver */ volatile struct NCR53c7x0_cmd *ncrcurrent; /* currently connected nexus, ONLY valid for NCR53c700/NCR53c700-66 */ volatile struct NCR53c7x0_cmd *spare; /* pointer to spare, allocated at probe time, which we can use for initialization */ volatile struct NCR53c7x0_cmd *free; int max_cmd_size; /* Maximum size of NCR53c7x0_cmd based on number of scatter/gather segments, etc. */ volatile int num_cmds; /* Number of commands allocated */ volatile int extra_allocate; volatile unsigned char cmd_allocated[16]; /* Have we allocated commands for this target yet? If not, do so ASAP */ volatile unsigned char busy[16][8]; /* number of commands executing on each target */ /* * Eventually, I'll switch to a coroutine for calling * cmd->done(cmd), etc. so that we can overlap interrupt * processing with this code for maximum performance. */ volatile struct NCR53c7x0_cmd *finished_queue; /* Shared variables between SCRIPT and host driver */ volatile u32 *schedule __attribute__ ((aligned (4))); /* Array of JUMPs to dsa_begin routines of various DSAs. When not in use, replace with jump to next slot */ volatile unsigned char msg_buf[16]; /* buffer for messages other than the command complete message */ /* Per-target default synchronous and WIDE messages */ volatile unsigned char synchronous_want[16][5]; volatile unsigned char wide_want[16][4]; /* Bit fielded set of targets we want to speak synchronously with */ volatile u16 initiate_sdtr; /* Bit fielded set of targets we want to speak wide with */ volatile u16 initiate_wdtr; /* Bit fielded list of targets we've talked to. */ volatile u16 talked_to; /* Array of bit-fielded lun lists that we need to request_sense */ volatile unsigned char request_sense[16]; u32 addr_reconnect_dsa_head __attribute__ ((aligned (4))); /* RISCy style constant, address of following */ volatile u32 reconnect_dsa_head; /* Data identifying nexus we are trying to match during reselection */ volatile unsigned char reselected_identify; /* IDENTIFY message */ volatile unsigned char reselected_tag; /* second byte of queue tag message or 0 */ /* These were static variables before we moved them */ s32 NCR53c7xx_zero __attribute__ ((aligned (4))); s32 NCR53c7xx_sink; u32 NOP_insn; char NCR53c7xx_msg_reject; char NCR53c7xx_msg_abort; char NCR53c7xx_msg_nop; /* * Following item introduced by RGH to support NCRc710, which is * VERY brain-dead when it come to memory moves */ /* DSA save area used only by the NCR chip */ volatile unsigned long saved2_dsa __attribute__ ((aligned (4))); volatile unsigned long emulated_intfly __attribute__ ((aligned (4))); volatile int event_size, event_index; volatile struct NCR53c7x0_event *events; /* If we need to generate code to kill off the currently connected command, this is where we do it. Should have a BMI instruction to source or sink the current data, followed by a JUMP to abort_connected */ u32 *abort_script; int script_count; /* Size of script in words */ u32 script[0]; /* Relocated SCSI script */};#define IRQ_NONE 255#define DMA_NONE 255#define IRQ_AUTO 254#define DMA_AUTO 254#define BOARD_GENERIC 0#define NCR53c7x0_insn_size(insn) \ (((insn) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI ? 3 : 2) #define NCR53c7x0_local_declare() \ volatile unsigned char *NCR53c7x0_address_memory; \ unsigned int NCR53c7x0_address_io; \ int NCR53c7x0_memory_mapped#define NCR53c7x0_local_setup(host) \ NCR53c7x0_address_memory = (void *) (host)->base; \ NCR53c7x0_address_io = (unsigned int) (host)->io_port; \ NCR53c7x0_memory_mapped = ((struct NCR53c7x0_hostdata *) \ host->hostdata[0])-> options & OPTION_MEMORY_MAPPED #ifdef BIG_ENDIAN/* These could be more efficient, given that we are always memory mapped, * but they don't give the same problems as the write macros, so leave * them. */#define NCR53c7x0_read8(address) \ (NCR53c7x0_memory_mapped ? \ (unsigned int)readb((u32)NCR53c7x0_address_memory + ((u32)(address)^3)) : \ inb(NCR53c7x0_address_io + (address)))#define NCR53c7x0_read16(address) \ (NCR53c7x0_memory_mapped ? \ (unsigned int)readw((u32)NCR53c7x0_address_memory + ((u32)(address)^2)) : \ inw(NCR53c7x0_address_io + (address)))#else#define NCR53c7x0_read8(address) \ (NCR53c7x0_memory_mapped ? \ (unsigned int)readb((u32)NCR53c7x0_address_memory + (u32)(address)) : \ inb(NCR53c7x0_address_io + (address)))#define NCR53c7x0_read16(address) \ (NCR53c7x0_memory_mapped ? \ (unsigned int)readw((u32)NCR53c7x0_address_memory + (u32)(address)) : \ inw(NCR53c7x0_address_io + (address)))#endif#define NCR53c7x0_read32(address) \ (NCR53c7x0_memory_mapped ? \ (unsigned int) readl((u32)NCR53c7x0_address_memory + (u32)(address)) : \ inl(NCR53c7x0_address_io + (address)))#ifdef BIG_ENDIAN/* If we are big-endian, then we are not Intel, so probably don't have * an i/o map as well as a memory map. So, let's assume memory mapped. * Also, I am having terrible problems trying to persuade the compiler * not to lay down code which does a read after write for these macros. * If you remove 'volatile' from writeb() and friends it is ok.... */#define NCR53c7x0_write8(address,value) \ *(volatile unsigned char *) \ ((u32)NCR53c7x0_address_memory + ((u32)(address)^3)) = (value)#define NCR53c7x0_write16(address,value) \ *(volatile unsigned short *) \ ((u32)NCR53c7x0_address_memory + ((u32)(address)^2)) = (value)#define NCR53c7x0_write32(address,value) \ *(volatile unsigned long *) \ ((u32)NCR53c7x0_address_memory + ((u32)(address))) = (value)#else#define NCR53c7x0_write8(address,value) \ (NCR53c7x0_memory_mapped ? \ ({writeb((value), (u32)NCR53c7x0_address_memory + (u32)(address)); mb();}) : \ outb((value), NCR53c7x0_address_io + (address)))#define NCR53c7x0_write16(address,value) \ (NCR53c7x0_memory_mapped ? \ ({writew((value), (u32)NCR53c7x0_address_memory + (u32)(address)); mb();}) : \ outw((value), NCR53c7x0_address_io + (address)))#define NCR53c7x0_write32(address,value) \ (NCR53c7x0_memory_mapped ? \ ({writel((value), (u32)NCR53c7x0_address_memory + (u32)(address)); mb();}) : \ outl((value), NCR53c7x0_address_io + (address)))#endif/* Patch arbitrary 32 bit words in the script */#define patch_abs_32(script, offset, symbol, value) \ for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof \ (u32)); ++i) { \ (script)[A_##symbol##_used[i] - (offset)] += (value); \ if (hostdata->options & OPTION_DEBUG_FIXUP) \ printk("scsi%d : %s reference %d at 0x%x in %s is now 0x%x\n",\ host->host_no, #symbol, i, A_##symbol##_used[i] - \ (int)(offset), #script, (script)[A_##symbol##_used[i] - \ (offset)]); \ }/* Patch read/write instruction immediate field */#define patch_abs_rwri_data(script, offset, symbol, value) \ for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof \ (u32)); ++i) \ (script)[A_##symbol##_used[i] - (offset)] = \ ((script)[A_##symbol##_used[i] - (offset)] & \ ~DBC_RWRI_IMMEDIATE_MASK) | \ (((value) << DBC_RWRI_IMMEDIATE_SHIFT) & \ DBC_RWRI_IMMEDIATE_MASK)/* Patch transfer control instruction data field */#define patch_abs_tci_data(script, offset, symbol, value) \ for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof \ (u32)); ++i) \ (script)[A_##symbol##_used[i] - (offset)] = \ ((script)[A_##symbol##_used[i] - (offset)] & \ ~DBC_TCI_DATA_MASK) | \ (((value) << DBC_TCI_DATA_SHIFT) & \ DBC_TCI_DATA_MASK)/* Patch field in dsa structure (assignment should be +=?) */#define patch_dsa_32(dsa, symbol, word, value) \ { \ (dsa)[(hostdata->##symbol - hostdata->dsa_start) / sizeof(u32) \ + (word)] = (value); \ if (hostdata->options & OPTION_DEBUG_DSA) \ printk("scsi : dsa %s symbol %s(%d) word %d now 0x%x\n", \ #dsa, #symbol, hostdata->##symbol, \ (word), (u32) (value)); \ }/* Paranoid people could use panic() here. */#define FATAL(host) shutdown((host));#endif /* NCR53c710_C */#endif /* NCR53c710_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -