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

📄 aha152x.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
extern unsigned long loops_per_sec;#define DELAY_DEFAULT 100/* some additional "phases" for getphase() */#define P_BUSFREE  1#define P_PARITY   2/* possible irq range */#define IRQ_MIN 9#define IRQ_MAX 12#define IRQS    IRQ_MAX-IRQ_MIN+1enum {  not_issued   = 0x0001,  in_selection = 0x0002,  disconnected = 0x0004,  aborted      = 0x0008,  sent_ident   = 0x0010,  in_other     = 0x0020,  in_sync      = 0x0040,  sync_ok      = 0x0080,};#if defined(MODULE)#if defined(DEBUG_AHA152X)int aha152x[]  = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT };int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT };#elseint aha152x[]  = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0 };int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0 };#endif#endif/* set by aha152x_setup according to the command line */static int  setup_count=0;static struct aha152x_setup {  int io_port;  int irq;  int scsiid;  int reconnect;  int parity;  int synchronous;  int delay;  int ext_trans;#ifdef DEBUG_AHA152X  int debug;#endif  char *conf;} setup[2];static struct Scsi_Host *aha152x_host[IRQS];#define HOSTDATA(shpnt)   ((struct aha152x_hostdata *) &shpnt->hostdata)#define CURRENT_SC        (HOSTDATA(shpnt)->current_SC)#define ISSUE_SC          (HOSTDATA(shpnt)->issue_SC)#define DISCONNECTED_SC   (HOSTDATA(shpnt)->disconnected_SC)#define DELAY             (HOSTDATA(shpnt)->delay)#define EXT_TRANS         (HOSTDATA(shpnt)->ext_trans)#define SYNCRATE          (HOSTDATA(shpnt)->syncrate[CURRENT_SC->target])#define MSG(i)            (HOSTDATA(shpnt)->message[i])#define MSGLEN            (HOSTDATA(shpnt)->message_len)#define ADDMSG(x)         (MSG(MSGLEN++)=x)struct aha152x_hostdata {  Scsi_Cmnd     *issue_SC;  Scsi_Cmnd     *current_SC;  Scsi_Cmnd     *disconnected_SC;  int           aborting;  int           abortion_complete;  int           abort_result;  int           commands;    int           reconnect;  int           parity;  int           synchronous;  int           delay;  int           ext_trans;  int           swint;   unsigned char syncrate[8];    unsigned char message[256];  int           message_len;#ifdef DEBUG_AHA152X  int           debug;#endif};void aha152x_intr(int irq, void *dev_id, struct pt_regs *);void aha152x_done(struct Scsi_Host *shpnt, int error);void aha152x_setup(char *str, int *ints);int aha152x_checksetup(struct aha152x_setup *setup);static void aha152x_reset_ports(struct Scsi_Host *shpnt);static void aha152x_panic(struct Scsi_Host *shpnt, char *msg);static void disp_ports(struct Scsi_Host *shpnt);static void show_command(Scsi_Cmnd *ptr);static void show_queues(struct Scsi_Host *shpnt);static void disp_enintr(struct Scsi_Host *shpnt);#if defined(DEBUG_RACE)static void enter_driver(const char *);static void leave_driver(const char *);#endif/* possible i/o addresses for the AIC-6260 */static unsigned short ports[] ={  0x340,      /* default first */  0x140};#define PORT_COUNT (sizeof(ports) / sizeof(unsigned short))#if !defined(SKIP_BIOSTEST)/* possible locations for the Adaptec BIOS */static void *addresses[] ={  (void *) 0xdc000,   /* default first */  (void *) 0xc8000,  (void *) 0xcc000,  (void *) 0xd0000,  (void *) 0xd4000,  (void *) 0xd8000,  (void *) 0xe0000,  (void *) 0xeb800,   /* VTech Platinum SMP */  (void *) 0xf0000,};#define ADDRESS_COUNT (sizeof(addresses) / sizeof(void *))/* signatures for various AIC-6[23]60 based controllers.   The point in detecting signatures is to avoid useless and maybe   harmful probes on ports. I'm not sure that all listed boards pass   auto-configuration. For those which fail the BIOS signature is   obsolete, because user intervention to supply the configuration is   needed anyway.  May be an information whether or not the BIOS supports   extended translation could be also useful here. */static struct signature {  char *signature;  int  sig_offset;  int  sig_length;} signatures[] ={  { "Adaptec AHA-1520 BIOS",      0x102e, 21 },  /* Adaptec 152x */  { "Adaptec AHA-1520B",            0x0b, 17 },  /* Adaptec 152x rev B */  { "Adaptec AHA-1520B/1522B",    0x3e20, 23 },  /* Adaptec 1520B/1522B */  { "Adaptec ASW-B626 BIOS",      0x1029, 21 },  /* on-board controller */  { "Adaptec BIOS: ASW-B626",       0x0f, 22 },  /* on-board controller */  { "Adaptec ASW-B626 S2",        0x2e6c, 19 },  /* on-board controller */  { "Adaptec BIOS:AIC-6360",         0xc, 21 },  /* on-board controller */  { "ScsiPro SP-360 BIOS",        0x2873, 19 },  /* ScsiPro-Controller  */  { "GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26 },  /* Gigabyte Local-Bus-SCSI */  { "Adaptec BIOS:AVA-282X",         0xc, 21 },  /* Adaptec 282x */  { "Adaptec IBM Dock II SCSI",   0x2edd, 24 },  /* IBM Thinkpad Dock II */  { "Adaptec BIOS:AHA-1532P",       0x1c, 22 },  /* IBM Thinkpad Dock II SCSI */};#define SIGNATURE_COUNT (sizeof(signatures) / sizeof(struct signature))#endifstatic void do_pause(unsigned amount) /* Pause for amount*10 milliseconds */{   unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */   while (jiffies < the_time)     barrier();}/* *  queue services: */static inline void append_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC){  Scsi_Cmnd *end;  new_SC->host_scribble = (unsigned char *) NULL;  if(!*SC)    *SC=new_SC;  else {    for(end=*SC; end->host_scribble; end = (Scsi_Cmnd *) end->host_scribble)      ;    end->host_scribble = (unsigned char *) new_SC;  }}static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd **SC){  Scsi_Cmnd *ptr;  ptr=*SC;  if(ptr)    *SC= (Scsi_Cmnd *) (*SC)->host_scribble;  return ptr;}static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, int target, int lun){  Scsi_Cmnd *ptr, *prev;  for(ptr=*SC, prev=NULL;       ptr && ((ptr->target!=target) || (ptr->lun!=lun));      prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble)    ;  if(ptr){    if(prev)      prev->host_scribble = ptr->host_scribble;    else      *SC= (Scsi_Cmnd *) ptr->host_scribble;  }  return ptr;}/* * read inbound byte and wait for ACK to get low */static void make_acklow(struct Scsi_Host *shpnt){  SETPORT(SXFRCTL0, CH1|SPIOEN);  GETPORT(SCSIDAT);  SETPORT(SXFRCTL0, CH1);  while(TESTHI(SCSISIG, ACKI))    barrier();}/* * detect current phase more reliable: * phase is valid, when the target asserts REQ after we've deasserted ACK. * * return value is a valid phase or an error code. * * errorcodes: *   P_BUSFREE   BUS FREE phase detected *   P_PARITY    parity error in DATA phase */static int getphase(struct Scsi_Host *shpnt){  int phase, sstat1;    while(1) {    do {      while(!((sstat1 = GETPORT(SSTAT1)) & (BUSFREE|SCSIRSTI|REQINIT)))        barrier();      if(sstat1 & BUSFREE)        return P_BUSFREE;      if(sstat1 & SCSIRSTI) {        printk("aha152x: RESET IN\n");        SETPORT(SSTAT1, SCSIRSTI);      }    } while(TESTHI(SCSISIG, ACKI) || TESTLO(SSTAT1, REQINIT));    SETPORT(SSTAT1, CLRSCSIPERR);      phase = GETPORT(SCSISIG) & P_MASK ;    if(TESTHI(SSTAT1, SCSIPERR)) {      if((phase & (CDO|MSGO))==0)                        /* DATA phase */        return P_PARITY;      make_acklow(shpnt);    } else      return phase;  }}/* called from init/main.c */void aha152x_setup(char *str, int *ints){  if(setup_count>2)    panic("aha152x: you can only configure up to two controllers\n");  setup[setup_count].conf        = str;  setup[setup_count].io_port     = ints[0] >= 1 ? ints[1] : 0x340;  setup[setup_count].irq         = ints[0] >= 2 ? ints[2] : 11;  setup[setup_count].scsiid      = ints[0] >= 3 ? ints[3] : 7;  setup[setup_count].reconnect   = ints[0] >= 4 ? ints[4] : 1;  setup[setup_count].parity      = ints[0] >= 5 ? ints[5] : 1;  setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 0 /* FIXME: 1 */;  setup[setup_count].delay       = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT;  setup[setup_count].ext_trans   = ints[0] >= 8 ? ints[8] : 0;#ifdef DEBUG_AHA152X  setup[setup_count].debug       = ints[0] >= 9 ? ints[9] : DEBUG_DEFAULT;  if(ints[0]>9) {     printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"           "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>[,<DEBUG>]]]]]]]]\n");#else  if(ints[0]>8) {    printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"           "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n");#endif  } else     setup_count++;}/* * Test, if port_base is valid. */static int aha152x_porttest(int io_port){  int i;  if(check_region(io_port, IO_RANGE))    return 0;  SETPORT(io_port+O_DMACNTRL1, 0);          /* reset stack pointer */  for(i=0; i<16; i++)    SETPORT(io_port+O_STACK, i);  SETPORT(io_port+O_DMACNTRL1, 0);          /* reset stack pointer */  for(i=0; i<16 && GETPORT(io_port+O_STACK)==i; i++)    ;  return(i==16);}int aha152x_checksetup(struct aha152x_setup *setup){  int i;  #ifndef PCMCIA  for(i=0; i<PORT_COUNT && (setup->io_port != ports[i]); i++)    ;    if(i==PORT_COUNT)    return 0;#endif    if(!aha152x_porttest(setup->io_port))    return 0;    if(setup->irq<IRQ_MIN && setup->irq>IRQ_MAX)    return 0;    if((setup->scsiid < 0) || (setup->scsiid > 7))    return 0;    if((setup->reconnect < 0) || (setup->reconnect > 1))    return 0;    if((setup->parity < 0) || (setup->parity > 1))    return 0;    if((setup->synchronous < 0) || (setup->synchronous > 1))    return 0;  if((setup->ext_trans < 0) || (setup->ext_trans > 1))    return 0;      return 1;}void aha152x_swintr(int irqno, void *dev_id, struct pt_regs * regs){  struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN];  if(!shpnt)    panic("aha152x: catched software interrupt for unknown controller.\n");  HOSTDATA(shpnt)->swint++;}int aha152x_detect(Scsi_Host_Template * tpnt){  int                 i, j, ok;#if defined(AUTOCONF)  aha152x_config      conf;#endif    tpnt->proc_dir = &proc_scsi_aha152x;  for(i=0; i<IRQS; i++)    aha152x_host[i] = (struct Scsi_Host *) NULL;    if(setup_count) {    printk("aha152x: processing commandline: ");       for(i=0; i<setup_count; i++)      if(!aha152x_checksetup(&setup[i])) {        printk("\naha152x: %s\n", setup[i].conf);        printk("aha152x: invalid line (controller=%d)\n", i+1);      }      printk("ok\n");  } #ifdef SETUP0  if(setup_count<2) {    struct aha152x_setup override = SETUP0;    if(setup_count==0 || (override.io_port != setup[0].io_port))      if(!aha152x_checksetup(&override)) {        printk("\naha152x: invalid override SETUP0={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",               override.io_port,               override.irq,               override.scsiid,               override.reconnect,               override.parity,               override.synchronous,               override.delay,               override.ext_trans);      } else        setup[setup_count++] = override;  }#endif#ifdef SETUP1  if(setup_count<2) {    struct aha152x_setup override = SETUP1;    if(setup_count==0 || (override.io_port != setup[0].io_port))      if(!aha152x_checksetup(&override)) {        printk("\naha152x: invalid override SETUP1={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",               override.io_port,               override.irq,               override.scsiid,               override.reconnect,               override.parity,               override.synchronous,               override.delay,               override.ext_trans);      } else        setup[setup_count++] = override;  }#endif#if defined(MODULE)  if(setup_count<2 && aha152x[0]!=0) {    setup[setup_count].conf        = "";    setup[setup_count].io_port     = aha152x[0];    setup[setup_count].irq         = aha152x[1];    setup[setup_count].scsiid      = aha152x[2];    setup[setup_count].reconnect   = aha152x[3];    setup[setup_count].parity      = aha152x[4];    setup[setup_count].synchronous = aha152x[5];    setup[setup_count].delay       = aha152x[6];    setup[setup_count].ext_trans   = aha152x[7];#ifdef DEBUG_AHA152X    setup[setup_count].debug       = aha152x[8];#endif    if(aha152x_checksetup(&setup[setup_count]))      setup_count++;

⌨️ 快捷键说明

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