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

📄 eata.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
#include <asm/dma.h>#include <asm/irq.h>#include "eata.h"#include <linux/stat.h>#include <linux/config.h>#include <linux/pci.h>#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,93)#include <linux/bios32.h>#endif#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,36)#include <linux/init.h>#else#define __initfunc(A) A#define __initdata#define __init#endif#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101)#include <asm/spinlock.h>#define IRQ_FLAGS#define IRQ_LOCK#define IRQ_LOCK_SAVE#define IRQ_UNLOCK#define IRQ_UNLOCK_RESTORE#define SPIN_FLAGS unsigned long spin_flags;#define SPIN_LOCK spin_lock_irq(&io_request_lock);#define SPIN_LOCK_SAVE spin_lock_irqsave(&io_request_lock, spin_flags);#define SPIN_UNLOCK spin_unlock_irq(&io_request_lock);#define SPIN_UNLOCK_RESTORE \                  spin_unlock_irqrestore(&io_request_lock, spin_flags);static int use_new_eh_code = TRUE;#else#define IRQ_FLAGS unsigned long irq_flags;#define IRQ_LOCK cli();#define IRQ_LOCK_SAVE do {save_flags(irq_flags); cli();} while (0);#define IRQ_UNLOCK sti();#define IRQ_UNLOCK_RESTORE do {restore_flags(irq_flags);} while (0);#define SPIN_FLAGS#define SPIN_LOCK#define SPIN_LOCK_SAVE#define SPIN_UNLOCK#define SPIN_UNLOCK_RESTOREstatic int use_new_eh_code = FALSE;#endifstruct proc_dir_entry proc_scsi_eata2x = {    PROC_SCSI_EATA2X, 6, "eata2x",    S_IFDIR | S_IRUGO | S_IXUGO, 2};/* Subversion values */#define ISA  0#define ESA 1#undef FORCE_CONFIG#undef  DEBUG_LINKED_COMMANDS#undef  DEBUG_DETECT#undef  DEBUG_PCI_DETECT#undef  DEBUG_INTERRUPT#undef  DEBUG_RESET#undef  DEBUG_GENERATE_ERRORS#undef  DEBUG_GENERATE_ABORTS#undef  DEBUG_GEOMETRY#define MAX_ISA 4#define MAX_VESA 0#define MAX_EISA 15#define MAX_PCI 16#define MAX_BOARDS (MAX_ISA + MAX_VESA + MAX_EISA + MAX_PCI)#define MAX_CHANNEL 4#define MAX_LUN 32#define MAX_TARGET 32#define MAX_MAILBOXES 64#define MAX_SGLIST 64#define MAX_LARGE_SGLIST 122#define MAX_INTERNAL_RETRIES 64#define MAX_CMD_PER_LUN 2#define MAX_TAGGED_CMD_PER_LUN (MAX_MAILBOXES - MAX_CMD_PER_LUN)#define SKIP ULONG_MAX#define FALSE 0#define TRUE 1#define FREE 0#define IN_USE   1#define LOCKED   2#define IN_RESET 3#define IGNORE   4#define READY    5#define ABORTING 6#define NO_DMA  0xff#define MAXLOOP  10000#define TAG_MIXED    0#define TAG_SIMPLE   1#define TAG_HEAD     2#define TAG_ORDERED  3#define REG_CMD         7#define REG_STATUS      7#define REG_AUX_STATUS  8#define REG_DATA        0#define REG_DATA2       1#define REG_SEE         6#define REG_LOW         2#define REG_LM          3#define REG_MID         4#define REG_MSB         5#define REGION_SIZE     9#define MAX_ISA_ADDR    0x03ff#define MIN_EISA_ADDR   0x1c88#define MAX_EISA_ADDR   0xfc88#define BSY_ASSERTED      0x80#define DRQ_ASSERTED      0x08#define ABSY_ASSERTED     0x01#define IRQ_ASSERTED      0x02#define READ_CONFIG_PIO   0xf0#define SET_CONFIG_PIO    0xf1#define SEND_CP_PIO       0xf2#define RECEIVE_SP_PIO    0xf3#define TRUNCATE_XFR_PIO  0xf4#define RESET_PIO         0xf9#define READ_CONFIG_DMA   0xfd#define SET_CONFIG_DMA    0xfe#define SEND_CP_DMA       0xff#define ASOK              0x00#define ASST              0x01#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0])#define YESNO(a) ((a) ? 'y' : 'n')#define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM)/* "EATA", in Big Endian format */#define EATA_SIGNATURE 0x41544145/* Number of valid bytes in the board config structure for EATA 2.0x */#define EATA_2_0A_SIZE 28#define EATA_2_0B_SIZE 30#define EATA_2_0C_SIZE 34/* Board info structure */struct eata_info {   ulong  data_len;     /* Number of valid bytes after this field */   ulong  sign;         /* ASCII "EATA" signature */   unchar        :4,    /* unused low nibble */          version:4;    /* EATA version, should be 0x1 */   unchar  ocsena:1,    /* Overlap Command Support Enabled */           tarsup:1,    /* Target Mode Supported */           trnxfr:1,    /* Truncate Transfer Cmd NOT Necessary */           morsup:1,    /* More Supported */           dmasup:1,    /* DMA Supported */           drqvld:1,    /* DRQ Index (DRQX) is valid */              ata:1,    /* This is an ATA device */           haaval:1;    /* Host Adapter Address Valid */   ushort cp_pad_len;   /* Number of pad bytes after cp_len */   unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */   ulong  cp_len;       /* Number of valid bytes in cp */   ulong  sp_len;       /* Number of valid bytes in sp */   ushort queue_size;   /* Max number of cp that can be queued */   ushort unused;   ushort scatt_size;   /* Max number of entries in scatter/gather table */   unchar     irq:4,    /* Interrupt Request assigned to this controller */           irq_tr:1,    /* 0 for edge triggered, 1 for level triggered */           second:1,    /* 1 if this is a secondary (not primary) controller */             drqx:2;    /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */   unchar  sync;        /* 1 if scsi target id 7...0 is running sync scsi */   /* Structure extension defined in EATA 2.0B */   unchar  isaena:1,    /* ISA i/o addressing is disabled/enabled */         forcaddr:1,    /* Port address has been forced */         large_sg:1,    /* 1 if large SG lists are supported */             res1:1,                 :4;   unchar  max_id:5,    /* Max SCSI target ID number */         max_chan:3;    /* Max SCSI channel number on this board */   /* Structure extension defined in EATA 2.0C */   unchar   max_lun;    /* Max SCSI LUN number */   unchar        :4,               m1:1,    /* This is a PCI with an M1 chip installed */          idquest:1,    /* RAIDNUM returned is questionable */              pci:1,    /* This board is PCI */             eisa:1;    /* This board is EISA */   unchar   raidnum;    /* Uniquely identifies this HBA in a system */   unchar   notused;   ushort ipad[247];   };/* Board config structure */struct eata_config {   ushort len;          /* Number of bytes following this field */   unchar edis:1,       /* Disable EATA interface after config command */         ocena:1,       /* Overlapped Commands Enabled */        mdpena:1,       /* Transfer all Modified Data Pointer Messages */        tarena:1,       /* Target Mode Enabled for this controller */              :4;   unchar cpad[511];   };/* Returned status packet structure */struct mssp {   unchar adapter_status:7,    /* State related to current command */                     eoc:1;    /* End Of Command (1 = command completed) */   unchar target_status;       /* SCSI status received after data transfer */   unchar unused[2];   ulong inv_res_len;          /* Number of bytes not transferred */   struct mscp *cpp;           /* Address set in cp */   char mess[12];   };struct sg_list {   unsigned int address;                /* Segment Address */   unsigned int num_bytes;              /* Segment Length */   };/* MailBox SCSI Command Packet */struct mscp {   unchar  sreset:1,     /* SCSI Bus Reset Signal should be asserted */             init:1,     /* Re-initialize controller and self test */           reqsen:1,     /* Transfer Request Sense Data to addr using DMA */               sg:1,     /* Use Scatter/Gather */                 :1,           interp:1,     /* The controller interprets cp, not the target */             dout:1,     /* Direction of Transfer is Out (Host to Target) */              din:1;     /* Direction of Transfer is In (Target to Host) */   unchar sense_len;     /* Request Sense Length */   unchar unused[3];   unchar  fwnest:1,     /* Send command to a component of an Array Group */                 :7;   unchar phsunit:1,     /* Send to Target Physical Unit (bypass RAID) */              iat:1,     /* Inhibit Address Translation */            hbaci:1,     /* Inhibit HBA Caching for this command */                 :5;   unchar  target:5,     /* SCSI target ID */          channel:3;     /* SCSI channel number */   unchar     lun:5,     /* SCSI logical unit number */           luntar:1,     /* This cp is for Target (not LUN) */           dispri:1,     /* Disconnect Privilege granted */              one:1;     /* 1 */   unchar mess[3];       /* Massage to/from Target */   unchar cdb[12];       /* Command Descriptor Block */   ulong  data_len;      /* If sg=0 Data Length, if sg=1 sglist length */   struct mscp *cpp;     /* Address to be returned in sp */   ulong  data_address;  /* If sg=0 Data Address, if sg=1 sglist address */   ulong  sp_addr;       /* Address where sp is DMA'ed when cp completes */   ulong  sense_addr;    /* Address where Sense Data is DMA'ed on error */   Scsi_Cmnd *SCpnt;   unsigned int index;   /* cp index */   struct sg_list *sglist;   };struct hostdata {   struct mscp cp[MAX_MAILBOXES];       /* Mailboxes for this board */   unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */   unsigned int last_cp_used;           /* Index of last mailbox used */   unsigned int iocount;                /* Total i/o done for this board */   int board_number;                    /* Number of this board */   char board_name[16];                 /* Name of this board */   char board_id[256];                  /* data from INQUIRY on this board */   int in_reset;                        /* True if board is doing a reset */   int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */   int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If TRUE redo i/o on target */   unsigned int retries;                /* Number of internal retries */   unsigned long last_retried_pid;      /* Pid of last retried command */   unsigned char subversion;            /* Bus type, either ISA or EISA/PCI */   unsigned char protocol_rev;          /* EATA 2.0 rev., 'A' or 'B' or 'C' */   struct mssp sp[2];                   /* Returned status for this board */   };static struct Scsi_Host *sh[MAX_BOARDS + 1];static const char *driver_name = "EATA";static char sha[MAX_BOARDS];/* Initialize num_boards so that ihdlr can work while detect is in progress */static unsigned int num_boards = MAX_BOARDS;static unsigned long io_port[] __initdata = {   /* Space for MAX_INT_PARAM ports usable while loading as a module */   SKIP,    SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,    SKIP,   /* First ISA */   0x1f0,   /* Space for MAX_PCI ports possibly reported by PCI_BIOS */   SKIP,    SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,    SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   /* MAX_EISA ports */   0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,   0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88,   /* Other (MAX_ISA - 1) ports */   0x170,  0x230,  0x330,   /* End of list */   0x0   };#define HD(board) ((struct hostdata *) &sh[board]->hostdata)#define BN(board) (HD(board)->board_name)#define H2DEV(x) htonl(x)#define DEV2H(x) H2DEV(x)#define V2DEV(addr) ((addr) ? H2DEV(virt_to_bus((void *)addr)) : 0)#define DEV2V(addr) ((addr) ? DEV2H(bus_to_virt((unsigned long)addr)) : 0)static void do_interrupt_handler(int, void *, struct pt_regs *);static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int);static int do_trace = FALSE;static int setup_done = FALSE;static int link_statistics = 0;static int tag_mode = TAG_MIXED;static int ext_tran = FALSE;static int rev_scan = TRUE;#if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE)static int tagged_comm = TRUE;#elsestatic int tagged_comm = FALSE;#endif#if defined(CONFIG_SCSI_EATA_LINKED_COMMANDS)static int linked_comm = TRUE;#elsestatic int linked_comm = FALSE;#endif#if defined(CONFIG_SCSI_EATA_MAX_TAGS)static int max_queue_depth = CONFIG_SCSI_EATA_MAX_TAGS;#elsestatic int max_queue_depth = MAX_CMD_PER_LUN;#endifstatic void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) {   Scsi_Device *dev;   int j, ntag = 0, nuntag = 0, tqd, utqd;   IRQ_FLAGS   IRQ_LOCK_SAVE   j = ((struct hostdata *) host->hostdata)->board_number;   for(dev = devlist; dev; dev = dev->next) {      if (dev->host != host) continue;      if (TLDEV(dev->type) && (dev->tagged_supported || linked_comm))         ntag++;      else         nuntag++;      }   utqd = MAX_CMD_PER_LUN;   tqd = (host->can_queue - utqd * nuntag) / (ntag ? ntag : 1);   if (tqd > max_queue_depth) tqd = max_queue_depth;   if (tqd < MAX_CMD_PER_LUN) tqd = MAX_CMD_PER_LUN;   for(dev = devlist; dev; dev = dev->next) {      char *tag_suffix = "", *link_suffix = "";      if (dev->host != host) continue;      if (TLDEV(dev->type) && (dev->tagged_supported || linked_comm))         dev->queue_depth = tqd;      else         dev->queue_depth = utqd;      if (TLDEV(dev->type)) {         if (linked_comm && dev->queue_depth > 2)            link_suffix = ", sorted";         else            link_suffix = ", unsorted";         }      if (tagged_comm && dev->tagged_supported && TLDEV(dev->type)) {         dev->tagged_queue = 1;         dev->current_tag = 1;         }      if (dev->tagged_supported && TLDEV(dev->type) && dev->tagged_queue)         tag_suffix = ", tagged";      else if (dev->tagged_supported && TLDEV(dev->type))         tag_suffix = ", untagged";

⌨️ 快捷键说明

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