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

📄 aic7xxx.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
static unsigned int aic7xxx_no_reset = 0;/* * Certain PCI motherboards will scan PCI devices from highest to lowest, * others scan from lowest to highest, and they tend to do all kinds of * strange things when they come into contact with PCI bridge chips.  The * net result of all this is that the PCI card that is actually used to boot * the machine is very hard to detect.  Most motherboards go from lowest * PCI slot number to highest, and the first SCSI controller found is the * one you boot from.  The only exceptions to this are when a controller * has its BIOS disabled.  So, we by default sort all of our SCSI controllers * from lowest PCI slot number to highest PCI slot number.  We also force * all controllers with their BIOS disabled to the end of the list.  This * works on *almost* all computers.  Where it doesn't work, we have this * option.  Setting this option to non-0 will reverse the order of the sort * to highest first, then lowest, but will still leave cards with their BIOS * disabled at the very end.  That should fix everyone up unless there are * really strange cirumstances. */static int aic7xxx_reverse_scan = 0;/* * Should we force EXTENDED translation on a controller. *     0 == Use whatever is in the SEEPROM or default to off *     1 == Use whatever is in the SEEPROM or default to on */static unsigned int aic7xxx_extended = 0;/* * The IRQ trigger method used on EISA controllers. Does not effect PCI cards. *   -1 = Use detected settings. *    0 = Force Edge triggered mode. *    1 = Force Level triggered mode. */static int aic7xxx_irq_trigger = -1;/* * This variable is used to override the termination settings on a controller. * This should not be used under normal conditions.  However, in the case * that a controller does not have a readable SEEPROM (so that we can't * read the SEEPROM settings directly) and that a controller has a buggered * version of the cable detection logic, this can be used to force the * correct termination.  It is preferable to use the manual termination * settings in the BIOS if possible, but some motherboard controllers store * those settings in a format we can't read.  In other cases, auto term * should also work, but the chipset was put together with no auto term * logic (common on motherboard controllers).  In those cases, we have * 32 bits here to work with.  That's good for 8 controllers/channels.  The * bits are organized as 4 bits per channel, with scsi0 getting the lowest * 4 bits in the int.  A 1 in a bit position indicates the termination setting * that corresponds to that bit should be enabled, a 0 is disabled. * It looks something like this: * *    0x0f =  1111-Single Ended Low Byte Termination on/off *            ||\-Single Ended High Byte Termination on/off *            |\-LVD Low Byte Termination on/off *            \-LVD High Byte Termination on/off * * For non-Ultra2 controllers, the upper 2 bits are not important.  So, to * enable both high byte and low byte termination on scsi0, I would need to * make sure that the override_term variable was set to 0x03 (bits 0011). * To make sure that all termination is enabled on an Ultra2 controller at * scsi2 and only high byte termination on scsi1 and high and low byte * termination on scsi0, I would set override_term=0xf23 (bits 1111 0010 0011) * * For the most part, users should never have to use this, that's why I * left it fairly cryptic instead of easy to understand.  If you need it, * most likely someone will be telling you what your's needs to be set to. */static int aic7xxx_override_term = -1;/* * Certain motherboard chipset controllers tend to screw * up the polarity of the term enable output pin.  Use this variable * to force the correct polarity for your system.  This is a bitfield variable * similar to the previous one, but this one has one bit per channel instead * of four. *    0 = Force the setting to active low. *    1 = Force setting to active high. * Most Adaptec cards are active high, several motherboards are active low. * To force a 2940 card at SCSI 0 to active high and a motherboard 7895 * controller at scsi1 and scsi2 to active low, and a 2910 card at scsi3 * to active high, you would need to set stpwlev=0x9 (bits 1001). * * People shouldn't need to use this, but if you are experiencing lots of * SCSI timeout problems, this may help.  There is one sure way to test what * this option needs to be.  Using a boot floppy to boot the system, configure * your system to enable all SCSI termination (in the Adaptec SCSI BIOS) and * if needed then also pass a value to override_term to make sure that the * driver is enabling SCSI termination, then set this variable to either 0 * or 1.  When the driver boots, make sure there are *NO* SCSI cables * connected to your controller.  If it finds and inits the controller * without problem, then the setting you passed to stpwlev was correct.  If * the driver goes into a reset loop and hangs the system, then you need the * other setting for this variable.  If neither setting lets the machine * boot then you have definite termination problems that may not be fixable. */static int aic7xxx_stpwlev = -1;/* * Set this to non-0 in order to force the driver to panic the kernel * and print out debugging info on a SCSI abort or reset cycle. */static int aic7xxx_panic_on_abort = 0;/* * PCI bus parity checking of the Adaptec controllers.  This is somewhat * dubious at best.  To my knowledge, this option has never actually * solved a PCI parity problem, but on certain machines with broken PCI * chipset configurations, it can generate tons of false error messages. * It's included in the driver for completeness. *   0 = Shut off PCI parity check *  -1 = Normal polarity pci parity checking *   1 = reverse polarity pci parity checking * * NOTE: you can't actually pass -1 on the lilo prompt.  So, to set this * variable to -1 you would actually want to simply pass the variable * name without a number.  That will invert the 0 which will result in * -1. */static int aic7xxx_pci_parity = 0;/* * Set this to any non-0 value to cause us to dump the contents of all * the card's registers in a hex dump format tailored to each model of * controller. * * NOTE: THE CONTROLLER IS LEFT IN AN UNUSEABLE STATE BY THIS OPTION. *       YOU CANNOT BOOT UP WITH THIS OPTION, IT IS FOR DEBUGGING PURPOSES *       ONLY */static int aic7xxx_dump_card = 0;/* * Set this to a non-0 value to make us dump out the 32 bit instruction * registers on the card after completing the sequencer download.  This * allows the actual sequencer download to be verified.  It is possible * to use this option and still boot up and run your system.  This is * only intended for debugging purposes. */static int aic7xxx_dump_sequencer = 0;/* * Certain newer motherboards have put new PCI based devices into the * IO spaces that used to typically be occupied by VLB or EISA cards. * This overlap can cause these newer motherboards to lock up when scanned * for older EISA and VLB devices.  Setting this option to non-0 will * cause the driver to skip scanning for any VLB or EISA controllers and * only support the PCI controllers.  NOTE: this means that if the kernel * os compiled with PCI support disabled, then setting this to non-0 * would result in never finding any devices :) */static int aic7xxx_no_probe = 0;/* * So that insmod can find the variable and make it point to something */#ifdef MODULEstatic char * aic7xxx = NULL;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,18)MODULE_PARM(aic7xxx, "s");#endif/* * Just in case someone uses commas to separate items on the insmod * command line, we define a dummy buffer here to avoid having insmod * write wild stuff into our code segment */static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n";#endif#define VERBOSE_NORMAL         0x0000#define VERBOSE_NEGOTIATION    0x0001#define VERBOSE_SEQINT         0x0002#define VERBOSE_SCSIINT        0x0004#define VERBOSE_PROBE          0x0008#define VERBOSE_PROBE2         0x0010#define VERBOSE_NEGOTIATION2   0x0020#define VERBOSE_MINOR_ERROR    0x0040#define VERBOSE_TRACING        0x0080#define VERBOSE_ABORT          0x0f00#define VERBOSE_ABORT_MID      0x0100#define VERBOSE_ABORT_FIND     0x0200#define VERBOSE_ABORT_PROCESS  0x0400#define VERBOSE_ABORT_RETURN   0x0800#define VERBOSE_RESET          0xf000#define VERBOSE_RESET_MID      0x1000#define VERBOSE_RESET_FIND     0x2000#define VERBOSE_RESET_PROCESS  0x4000#define VERBOSE_RESET_RETURN   0x8000static int aic7xxx_verbose = VERBOSE_NORMAL | VERBOSE_NEGOTIATION |           VERBOSE_PROBE;                     /* verbose messages *//**************************************************************************** * * We're going to start putting in function declarations so that order of * functions is no longer important.  As needed, they are added here. * ***************************************************************************/static void aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd);static void aic7xxx_print_card(struct aic7xxx_host *p);static void aic7xxx_print_scratch_ram(struct aic7xxx_host *p);static void aic7xxx_print_sequencer(struct aic7xxx_host *p, int downloaded);#ifdef AIC7XXX_VERBOSE_DEBUGGINGstatic void aic7xxx_check_scbs(struct aic7xxx_host *p, char *buffer);#endif/**************************************************************************** * * These functions are now used.  They happen to be wrapped in useless * inb/outb port read/writes around the real reads and writes because it * seems that certain very fast CPUs have a problem dealing with us when * going at full speed. * ***************************************************************************/#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)static inline voidmdelay(int milliseconds){  int i;  for(i=0; i<milliseconds; i++)    udelay(1000);}static inline inttime_after_eq(unsigned long a, unsigned long b){  return((long)((a) - (b)) >= 0L);}static inline inttimer_pending(struct timer_list *timer){  return( timer->prev != NULL );}#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075#endifstatic inline unsigned charaic_inb(struct aic7xxx_host *p, long port){#ifdef MMAPIO  unsigned char x;  if(p->maddr)  {    x = p->maddr[port];  }  else  {    x = inb(p->base + port);  }  mb();  return(x);#else  return(inb(p->base + port));#endif}static inline voidaic_outb(struct aic7xxx_host *p, unsigned char val, long port){#ifdef MMAPIO  if(p->maddr)  {    p->maddr[port] = val;  }  else  {    outb(val, p->base + port);  }  mb();#else  outb(val, p->base + port);#endif}/*+F************************************************************************* * Function: *   aic7xxx_setup * * Description: *   Handle Linux boot parameters. This routine allows for assigning a value *   to a parameter with a ':' between the parameter and the value. *   ie. aic7xxx=unpause:0x0A,extended *-F*************************************************************************/voidaic7xxx_setup(char *s, int *dummy){  int   i, n;  char *p;  char *end;  static struct {    const char *name;    unsigned int *flag;  } options[] = {    { "extended",    &aic7xxx_extended },    { "no_reset",    &aic7xxx_no_reset },    { "irq_trigger", &aic7xxx_irq_trigger },    { "verbose",     &aic7xxx_verbose },    { "reverse_scan",&aic7xxx_reverse_scan },    { "override_term", &aic7xxx_override_term },    { "stpwlev", &aic7xxx_stpwlev },    { "no_probe", &aic7xxx_no_probe },    { "panic_on_abort", &aic7xxx_panic_on_abort },    { "pci_parity", &aic7xxx_pci_parity },    { "dump_card", &aic7xxx_dump_card },    { "dump_sequencer", &aic7xxx_dump_sequencer },    { "tag_info",    NULL }  };  end = strchr(s, '\0');  for (p = strtok(s, ",."); p; p = strtok(NULL, ",."))  {    for (i = 0; i < NUMBER(options); i++)    {      n = strlen(options[i].name);      if (!strncmp(options[i].name, p, n))      {        if (!strncmp(p, "tag_info", n)) 

⌨️ 快捷键说明

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