⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aic7xxx.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
  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_AIC7895_FE       = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA,  AHC_AIC7896_FE       = AHC_AIC7890_FE,  AHC_AIC7892_FE       = AHC_AIC7890_FE|AHC_ULTRA160,  AHC_AIC7899_FE       = AHC_AIC7890_FE|AHC_ULTRA160,} ahc_feature;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[6];  /*                                               * Allocate 6 characters for                                               * sense command.                                               */        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;};/* * 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 */  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 user_width;  unsigned char user_period;  unsigned char user_offset;} 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 ahc_flag_type   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  needsdtr;  volatile unsigned short  sdtr_pending;  volatile unsigned short  needwdtr;  volatile unsigned short  wdtr_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;#define  DEVICE_PRESENT                 0x01#define  BUS_DEVICE_RESET_PENDING       0x02#define  DEVICE_RESET_DELAY             0x04#define  DEVICE_PRINT_SDTR              0x08#define  DEVICE_PRINT_WDTR              0x10#define  DEVICE_WAS_BUSY                0x20#define  DEVICE_SCANNED                 0x80  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];#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)  spinlock_t               spin_lock;  volatile unsigned char   cpu_lock_count[NR_CPUS];#endif#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS  Scsi_Cmnd               *dev_wdtr_cmnd[MAX_TARGETS];  Scsi_Cmnd               *dev_sdtr_cmnd[MAX_TARGETS];#endif  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];  volatile scb_queue_type  delayed_scbs[MAX_TARGETS];  unsigned char            msg_buf[9];       /* The message for the target */  unsigned char            msg_type;#define MSG_TYPE_NONE              0x00#define MSG_TYPE_INITIATOR_MSGOUT  0x01#define MSG_TYPE_INITIATOR_MSGIN   0x02  unsigned char            msg_len;          /* Length of message */  unsigned char            msg_index;        /* Index into msg_buf array */  transinfo_type           transinfo[MAX_TARGETS];  /*   * We put the less frequently used host structure items after the more   * frequently used items to try and ease the burden on the cache subsystem.   * These entries are not *commonly* accessed, whereas the preceding entries   * are accessed very often.  The only exceptions are the qinfifo, qoutfifo,   * and untagged_scbs array.  But, they are often accessed only once and each   * access into these arrays is likely to blow a cache line, so they are put   * down here so we can minimize the number of cache lines required to hold   * the preceeding entries.   */  volatile unsigned char   untagged_scbs[256];  volatile unsigned char   qoutfifo[256];  volatile unsigned char   qinfifo[256];  unsigned int             irq;              /* IRQ for this adapter */  int                      instance;         /* aic7xxx instance number */  int                      scsi_id;          /* host adapter SCSI ID */  int                      scsi_id_b;        /* channel B for twin adapters */  unsigned int             bios_address;  int                      board_name_index;  unsigned short           needsdtr_copy;    /* default config */  unsigned short           needwdtr_copy;    /* default config */  unsigned short           ultraenb;         /* Ultra mode target list */  unsigned short           bios_control;     /* bios control - SEEPROM */  unsigned short           adapter_control;  /* adapter control - SEEPROM */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)  struct pci_dev          *pdev;#endif  unsigned char            pci_bus;  unsigned char            pci_device_fn;  struct seeprom_config    sc;  unsigned short           sc_type;  unsigned short           sc_size;  struct aic7xxx_host     *next;             /* allow for multiple IRQs */  struct Scsi_Host        *host;             /* pointer to scsi host */  int                      host_no;          /* SCSI host number */  unsigned long            mbase;            /* I/O memory address */  ahc_chip                 chip;             /* chip type */  /*   * Statistics Kept:   *   * Total Xfers (count for each command that has a data xfer),   * broken down further by reads && writes.   *   * Binned sizes, writes && reads:   *    < 512, 512, 1-2K, 2-4K, 4-8K, 8-16K, 16-32K, 32-64K, 64K-128K, > 128K   *   * Total amounts read/written above 512 bytes (amts under ignored)   *   * NOTE: Enabling this feature is likely to cause a noticeable performance   * decrease as the accesses into the stats structures blows apart multiple   * cache lines and is CPU time consuming.   *   * NOTE: Since it doesn't really buy us much, but consumes *tons* of RAM   * and blows apart all sorts of cache lines, I modified this so that we   * no longer look at the LUN.  All LUNs now go into the same bin on each   * device for stats purposes.   */  struct aic7xxx_xferstats {    long w_total;                          /* total writes */    long r_total;                          /* total reads */#ifdef AIC7XXX_PROC_STATS    long w_bins[8];                       /* binned write */    long r_bins[8];                       /* binned reads */#endif /* AIC7XXX_PROC_STATS */  } stats[MAX_TARGETS];                    /* [(channel << 3)|target] */#if 0  struct target_cmd       *targetcmds;  unsigned int             num_targetcmds;#endif};/* * Valid SCSIRATE values. (p. 3-17) * Provides a mapping of transfer periods in ns/4 to the proper value to * stick in the SCSIRATE reg to use that transfer rate. */#define AHC_SYNCRATE_ULTRA2 0#define AHC_SYNCRATE_ULTRA  2#define AHC_SYNCRATE_FAST   5static struct aic7xxx_syncrate {  /* Rates in Ultra mode have bit 8 of sxfr set */#define                ULTRA_SXFR 0x100  int sxfr_ultra2;  int sxfr;  unsigned char period;  const char *rate[2];} aic7xxx_syncrates[] = {  { 0x13,  0x000,  10,  {"40.0", "80.0"} },  { 0x14,  0x000,  11,  {"33.0", "66.6"} },  { 0x15,  0x100,  12,  {"20.0", "40.0"} },  { 0x16,  0x110,  15,  {"16.0", "32.0"} },  { 0x17,  0x120,  18,  {"13.4", "26.8"} },  { 0x18,  0x000,  25,  {"10.0", "20.0"} },  { 0x19,  0x010,  31,  {"8.0",  "16.0"} },  { 0x1a,  0x020,  37,  {"6.67", "13.3"} },  { 0x1b,  0x030,  43,  {"5.7",  "11.4"} },  { 0x10,  0x040,  50,  {"5.0",  "10.0"} },  { 0x00,  0x050,  56,  {"4.4",  "8.8" } },  { 0x00,  0x060,  62,  {"4.0",  "8.0" } },  { 0x00,  0x070,  68,  {"3.6",  "7.2" } },  { 0x00,  0x000,  0,   {NULL, NULL}   },};#define CTL_OF_SCB(scb) (((scb->hscb)->target_channel_lun >> 3) & 0x1),  \                        (((scb->hscb)->target_channel_lun >> 4) & 0xf), \                        ((scb->hscb)->target_channel_lun & 0x07)#define CTL_OF_CMD(cmd) ((cmd->channel) & 0x01),  \                        ((cmd->target) & 0x0f), \                        ((cmd->lun) & 0x07)#define TARGET_INDEX(cmd)  ((cmd)->target | ((cmd)->channel << 3))/* * A nice little define to make doing our printks a little easier */#define WARN_LEAD KERN_WARNING "(scsi%d:%d:%d:%d) "#define INFO_LEAD KERN_INFO "(scsi%d:%d:%d:%d) "/* * XXX - these options apply unilaterally to _all_ 274x/284x/294x *       cards in the system.  This should be fixed.  Exceptions to this *       rule are noted in the comments. *//* * Skip the scsi bus reset.  Non 0 make us skip the reset at startup.  This * has no effect on any later resets that might occur due to things like * SCSI bus timeouts. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -