📄 aic7xxx_old.c
字号:
#define AIC7XXX_MAX_SG 128/* * The maximum number of SCBs we could have for ANY type * of card. DON'T FORGET TO CHANGE THE SCB MASK IN THE * SEQUENCER CODE IF THIS IS MODIFIED! */#define AIC7XXX_MAXSCB 255struct aic7xxx_hwscb {/* ------------ Begin hardware supported fields ---------------- *//* 0*/ unsigned char control;/* 1*/ unsigned char target_channel_lun; /* 4/1/3 bits *//* 2*/ unsigned char target_status;/* 3*/ unsigned char SG_segment_count;/* 4*/ unsigned int SG_list_pointer;/* 8*/ unsigned char residual_SG_segment_count;/* 9*/ unsigned char residual_data_count[3];/*12*/ unsigned int data_pointer;/*16*/ unsigned int data_count;/*20*/ unsigned int SCSI_cmd_pointer;/*24*/ unsigned char SCSI_cmd_length;/*25*/ unsigned char tag; /* Index into our kernel SCB array. * Also used as the tag for tagged I/O */#define SCB_PIO_TRANSFER_SIZE 26 /* amount we need to upload/download * via PIO to initialize a transaction. *//*26*/ unsigned char next; /* Used to thread SCBs awaiting selection * or disconnected down in the sequencer. *//*27*/ unsigned char prev;/*28*/ unsigned int pad; /* * Unused by the kernel, but we require * the padding so that the array of * hardware SCBs is aligned on 32 byte * boundaries so the sequencer can index */};typedef enum { SCB_FREE = 0x0000, SCB_DTR_SCB = 0x0001, SCB_WAITINGQ = 0x0002, SCB_ACTIVE = 0x0004, SCB_SENSE = 0x0008, SCB_ABORT = 0x0010, SCB_DEVICE_RESET = 0x0020, SCB_RESET = 0x0040, SCB_RECOVERY_SCB = 0x0080, SCB_MSGOUT_PPR = 0x0100, SCB_MSGOUT_SENT = 0x0200, SCB_MSGOUT_SDTR = 0x0400, SCB_MSGOUT_WDTR = 0x0800, SCB_MSGOUT_BITS = SCB_MSGOUT_PPR | SCB_MSGOUT_SENT | SCB_MSGOUT_SDTR | SCB_MSGOUT_WDTR, SCB_QUEUED_ABORT = 0x1000, SCB_QUEUED_FOR_DONE = 0x2000, SCB_WAS_BUSY = 0x4000} scb_flag_type;typedef enum { AHC_FNONE = 0x00000000, AHC_PAGESCBS = 0x00000001, AHC_CHANNEL_B_PRIMARY = 0x00000002, AHC_USEDEFAULTS = 0x00000004, AHC_INDIRECT_PAGING = 0x00000008, AHC_CHNLB = 0x00000020, AHC_CHNLC = 0x00000040, AHC_EXTEND_TRANS_A = 0x00000100, AHC_EXTEND_TRANS_B = 0x00000200, AHC_TERM_ENB_A = 0x00000400, AHC_TERM_ENB_SE_LOW = 0x00000400, AHC_TERM_ENB_B = 0x00000800, AHC_TERM_ENB_SE_HIGH = 0x00000800, AHC_HANDLING_REQINITS = 0x00001000, AHC_TARGETMODE = 0x00002000, AHC_NEWEEPROM_FMT = 0x00004000, /* * Here ends the FreeBSD defined flags and here begins the linux defined * flags. NOTE: I did not preserve the old flag name during this change * specifically to force me to evaluate what flags were being used properly * and what flags weren't. This way, I could clean up the flag usage on * a use by use basis. Doug Ledford */ AHC_MOTHERBOARD = 0x00020000, AHC_NO_STPWEN = 0x00040000, AHC_RESET_DELAY = 0x00080000, AHC_A_SCANNED = 0x00100000, AHC_B_SCANNED = 0x00200000, AHC_MULTI_CHANNEL = 0x00400000, AHC_BIOS_ENABLED = 0x00800000, AHC_SEEPROM_FOUND = 0x01000000, AHC_TERM_ENB_LVD = 0x02000000, AHC_ABORT_PENDING = 0x04000000, AHC_RESET_PENDING = 0x08000000,#define AHC_IN_ISR_BIT 28 AHC_IN_ISR = 0x10000000, AHC_IN_ABORT = 0x20000000, AHC_IN_RESET = 0x40000000, AHC_EXTERNAL_SRAM = 0x80000000} ahc_flag_type;typedef enum { AHC_NONE = 0x0000, AHC_CHIPID_MASK = 0x00ff, AHC_AIC7770 = 0x0001, AHC_AIC7850 = 0x0002, AHC_AIC7860 = 0x0003, AHC_AIC7870 = 0x0004, AHC_AIC7880 = 0x0005, AHC_AIC7890 = 0x0006, AHC_AIC7895 = 0x0007, AHC_AIC7896 = 0x0008, AHC_AIC7892 = 0x0009, AHC_AIC7899 = 0x000a, AHC_VL = 0x0100, AHC_EISA = 0x0200, AHC_PCI = 0x0400,} ahc_chip;typedef enum { AHC_FENONE = 0x0000, AHC_ULTRA = 0x0001, AHC_ULTRA2 = 0x0002, AHC_WIDE = 0x0004, AHC_TWIN = 0x0008, AHC_MORE_SRAM = 0x0010, AHC_CMD_CHAN = 0x0020, AHC_QUEUE_REGS = 0x0040, AHC_SG_PRELOAD = 0x0080, AHC_SPIOCAP = 0x0100, AHC_ULTRA3 = 0x0200, AHC_NEW_AUTOTERM = 0x0400, AHC_AIC7770_FE = AHC_FENONE, AHC_AIC7850_FE = AHC_SPIOCAP, AHC_AIC7860_FE = AHC_ULTRA|AHC_SPIOCAP, AHC_AIC7870_FE = AHC_FENONE, AHC_AIC7880_FE = AHC_ULTRA, AHC_AIC7890_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA2| AHC_QUEUE_REGS|AHC_SG_PRELOAD|AHC_NEW_AUTOTERM, AHC_AIC7895_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA, AHC_AIC7896_FE = AHC_AIC7890_FE, AHC_AIC7892_FE = AHC_AIC7890_FE|AHC_ULTRA3, AHC_AIC7899_FE = AHC_AIC7890_FE|AHC_ULTRA3,} ahc_feature;#define SCB_DMA_ADDR(scb, addr) ((unsigned long)(addr) + (scb)->scb_dma->dma_offset)struct aic7xxx_scb_dma { unsigned long dma_offset; /* Correction you have to add * to virtual address to get * dma handle in this region */ dma_addr_t dma_address; /* DMA handle of the start, * for unmap */ unsigned int dma_len; /* DMA length */};typedef enum { AHC_BUG_NONE = 0x0000, AHC_BUG_TMODE_WIDEODD = 0x0001, AHC_BUG_AUTOFLUSH = 0x0002, AHC_BUG_CACHETHEN = 0x0004, AHC_BUG_CACHETHEN_DIS = 0x0008, AHC_BUG_PCI_2_1_RETRY = 0x0010, AHC_BUG_PCI_MWI = 0x0020, AHC_BUG_SCBCHAN_UPLOAD = 0x0040,} ahc_bugs;struct aic7xxx_scb { struct aic7xxx_hwscb *hscb; /* corresponding hardware scb */ Scsi_Cmnd *cmd; /* Scsi_Cmnd for this scb */ struct aic7xxx_scb *q_next; /* next scb in queue */ volatile scb_flag_type flags; /* current state of scb */ struct hw_scatterlist *sg_list; /* SG list in adapter format */ unsigned char tag_action; unsigned char sg_count; unsigned char *sense_cmd; /* * Allocate 6 characters for * sense command. */ unsigned char *cmnd; unsigned int sg_length; /* We init this during buildscb so we * don't have to calculate anything * during underflow/overflow/stat code */ void *kmalloc_ptr; struct aic7xxx_scb_dma *scb_dma;};/* * Define a linked list of SCBs. */typedef struct { struct aic7xxx_scb *head; struct aic7xxx_scb *tail;} scb_queue_type;static struct { unsigned char errno; const char *errmesg;} hard_error[] = { { ILLHADDR, "Illegal Host Access" }, { ILLSADDR, "Illegal Sequencer Address referenced" }, { ILLOPCODE, "Illegal Opcode in sequencer program" }, { SQPARERR, "Sequencer Ram Parity Error" }, { DPARERR, "Data-Path Ram Parity Error" }, { MPARERR, "Scratch Ram/SCB Array Ram Parity Error" }, { PCIERRSTAT,"PCI Error detected" }, { CIOPARERR, "CIOBUS Parity Error" }};static unsigned chargeneric_sense[] = { REQUEST_SENSE, 0, 0, 0, 255, 0 };typedef struct { scb_queue_type free_scbs; /* * SCBs assigned to free slot on * card (no paging required) */ struct aic7xxx_scb *scb_array[AIC7XXX_MAXSCB]; struct aic7xxx_hwscb *hscbs; unsigned char numscbs; /* current number of scbs */ unsigned char maxhscbs; /* hardware scbs */ unsigned char maxscbs; /* max scbs including pageable scbs */ dma_addr_t hscbs_dma; /* DMA handle to hscbs */ unsigned int hscbs_dma_len; /* length of the above DMA area */ void *hscb_kmalloc_ptr;} scb_data_type;struct target_cmd { unsigned char mesg_bytes[4]; unsigned char command[28];};#define AHC_TRANS_CUR 0x0001#define AHC_TRANS_ACTIVE 0x0002#define AHC_TRANS_GOAL 0x0004#define AHC_TRANS_USER 0x0008#define AHC_TRANS_QUITE 0x0010typedef struct { unsigned char cur_width; unsigned char goal_width; unsigned char cur_period; unsigned char goal_period; unsigned char cur_offset; unsigned char goal_offset; unsigned char cur_options; unsigned char goal_options; unsigned char user_width; unsigned char user_period; unsigned char user_offset; unsigned char user_options;} transinfo_type;/* * Define a structure used for each host adapter. Note, in order to avoid * problems with architectures I can't test on (because I don't have one, * such as the Alpha based systems) which happen to give faults for * non-aligned memory accesses, care was taken to align this structure * in a way that gauranteed all accesses larger than 8 bits were aligned * on the appropriate boundary. It's also organized to try and be more * cache line efficient. Be careful when changing this lest you might hurt * overall performance and bring down the wrath of the masses. */struct aic7xxx_host { /* * This is the first 64 bytes in the host struct */ /* * We are grouping things here....first, items that get either read or * written with nearly every interrupt */ volatile long flags; ahc_feature features; /* chip features */ unsigned long base; /* card base address */ volatile unsigned char *maddr; /* memory mapped address */ unsigned long isr_count; /* Interrupt count */ unsigned long spurious_int; scb_data_type *scb_data; volatile unsigned short needppr; volatile unsigned short needsdtr; volatile unsigned short needwdtr; volatile unsigned short dtr_pending; struct aic7xxx_cmd_queue { Scsi_Cmnd *head; Scsi_Cmnd *tail; } completeq; /* * Things read/written on nearly every entry into aic7xxx_queue() */ volatile scb_queue_type waiting_scbs; unsigned short discenable; /* Targets allowed to disconnect */ unsigned short tagenable; /* Targets using tagged I/O */ unsigned short orderedtag; /* Ordered Q tags allowed */ unsigned char unpause; /* unpause value for HCNTRL */ unsigned char pause; /* pause value for HCNTRL */ volatile unsigned char qoutfifonext; volatile unsigned char activescbs; /* active scbs */ volatile unsigned char max_activescbs; volatile unsigned char qinfifonext; volatile unsigned char *untagged_scbs; volatile unsigned char *qoutfifo; volatile unsigned char *qinfifo;#define DEVICE_PRESENT 0x01#define BUS_DEVICE_RESET_PENDING 0x02#define DEVICE_RESET_DELAY 0x04#define DEVICE_PRINT_DTR 0x08#define DEVICE_WAS_BUSY 0x10#define DEVICE_SCSI_3 0x20#define DEVICE_DTR_SCANNED 0x40 volatile unsigned char dev_flags[MAX_TARGETS]; volatile unsigned char dev_active_cmds[MAX_TARGETS]; volatile unsigned char dev_temp_queue_depth[MAX_TARGETS]; unsigned char dev_commands_sent[MAX_TARGETS]; unsigned int dev_timer_active; /* Which devs have a timer set */ struct timer_list dev_timer; unsigned long dev_expires[MAX_TARGETS]; spinlock_t spin_lock; volatile unsigned char cpu_lock_count[NR_CPUS]; unsigned char dev_last_queue_full[MAX_TARGETS]; unsigned char dev_last_queue_full_count[MAX_TARGETS]; unsigned char dev_max_queue_depth[MAX_TARGETS];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -