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

📄 aha152x.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
📖 第 1 页 / 共 5 页
字号:
    return 0;  SETPORT( DMACNTRL1, 0 );          /* reset stack pointer */  for(i=0; i<16; i++)    SETPORT( STACK, i );  SETPORT( DMACNTRL1, 0 );          /* reset stack pointer */  for(i=0; i<16 && GETPORT(STACK)==i; i++)    ;  return(i==16);}int aha152x_detect(int hostno){  int                 i, j,  ok;  aha152x_config      conf;  struct sigaction    sa;  int                 interrupt_level;  #if defined(DEBUG_RACE)  enter_driver("detect");#endif    printk("aha152x: Probing: ");  if(setup_called)    {      printk("processing commandline: ");         if(setup_called!=4)        {          printk("\naha152x: %s\n", setup_str );          printk("aha152x: usage: aha152x=<PORTBASE>,<IRQ>,<SCSI ID>,<RECONNECT>\n");          panic("aha152x panics in line %d", __LINE__);        }      port_base       = setup_portbase;      interrupt_level = setup_irq;      this_host       = setup_scsiid;      can_disconnect  = setup_reconnect;      for( i=0; i<PORT_COUNT && (port_base != ports[i]); i++)        ;      if(i==PORT_COUNT)        {          printk("unknown portbase 0x%03x\n", port_base);          panic("aha152x panics in line %d", __LINE__);        }      if(!aha152x_porttest(port_base))        {          printk("portbase 0x%03x fails probe\n", port_base);          panic("aha152x panics in line %d", __LINE__);        }      i=0;      while(ints[i] && (interrupt_level!=ints[i]))        i++;      if(!ints[i])        {          printk("illegal IRQ %d\n", interrupt_level);          panic("aha152x panics in line %d", __LINE__);        }      if( (this_host < 0) || (this_host > 7) )        {          printk("illegal SCSI ID %d\n", this_host);          panic("aha152x panics in line %d", __LINE__);        }      if( (can_disconnect < 0) || (can_disconnect > 1) )        {          printk("reconnect %d should be 0 or 1\n", can_disconnect);          panic("aha152x panics in line %d", __LINE__);        }      printk("ok, ");    }  else    {#if !defined(SKIP_BIOSTEST)      printk("BIOS test: ");      ok=0;      for( i=0; i < ADDRESS_COUNT && !ok; i++)        for( j=0; (j < SIGNATURE_COUNT) && !ok; j++)          ok=!memcmp((void *) addresses[i]+signatures[j].sig_offset,                     (void *) signatures[j].signature,                     (int) signatures[j].sig_length);      if(!ok)        {#if defined(DEBUG_RACE)          leave_driver("(1) detect");#endif          printk("failed\n");          return 0;        }      printk("ok, ");#endif /* !SKIP_BIOSTEST */ #if !defined(PORTBASE)      printk("porttest: ");      for( i=0; i<PORT_COUNT && !aha152x_porttest(ports[i]); i++)        ;      if(i==PORT_COUNT)        {          printk("failed\n");#if defined(DEBUG_RACE)          leave_driver("(2) detect");#endif          return 0;        }      else        port_base=ports[i];      printk("ok, ");#else      port_base=PORTBASE;#endif /* !PORTBASE */#if defined(AUTOCONF)      conf.cf_port = (GETPORT(PORTA)<<8) + GETPORT(PORTB);      interrupt_level = ints[conf.cf_irq];      this_host       = conf.cf_id;      can_disconnect  = conf.cf_tardisc;      printk("auto configuration: ok, ");#endif /* AUTOCONF */#if defined(IRQ)      interrupt_level = IRQ; #endif#if defined(SCSI_ID)      this_host = SCSI_ID;#endif#if defined(RECONNECT)      can_disconnect=RECONNECT;#endif    }  printk("detection complete\n");   sa.sa_handler  = aha152x_intr;  sa.sa_flags    = SA_INTERRUPT;  sa.sa_mask     = 0;  sa.sa_restorer = NULL;    ok = irqaction( interrupt_level, &sa);    if(ok<0)    {      if(ok == -EINVAL)        {           printk("aha152x: bad IRQ %d.\n", interrupt_level);           printk("         Contact author.\n");        }      else        if( ok == -EBUSY)          printk( "aha152x: IRQ %d already in use. Configure another.\n",                  interrupt_level);        else          {            printk( "\naha152x: Unexpected error code on requesting IRQ %d.\n",                    interrupt_level);            printk("         Contact author.\n");          }      panic("aha152x: driver needs an IRQ.\n");    }  SETPORT( SCSIID, this_host << 4 );  scsi_hosts[hostno].this_id=this_host;    if(can_disconnect)    scsi_hosts[hostno].can_queue=AHA152X_MAXQUEUE;  /* RESET OUT */  SETBITS(SCSISEQ, SCSIRSTO );  do_pause(5);  CLRBITS(SCSISEQ, SCSIRSTO );  do_pause(10);  aha152x_reset(NULL);  printk("aha152x: vital data: PORTBASE=0x%03x, IRQ=%d, SCSI ID=%d, reconnect=%s, parity=enabled\n",         port_base, interrupt_level, this_host, can_disconnect ? "enabled" : "disabled" );  snarf_region(port_base, TEST-SCSISEQ);        /* Register */    /* not expecting any interrupts */  SETPORT(SIMODE0, 0);  SETPORT(SIMODE1, 0);#if defined(DEBUG_RACE)  leave_driver("(3) detect");#endif  SETBITS( DMACNTRL0, INTEN);  return 1;}/* *  return the name of the thing */const char *aha152x_info(void){#if defined(DEBUG_RACE)  enter_driver("info");  leave_driver("info");#else#if defined(DEBUG_INFO)  printk("\naha152x: info()\n");#endif#endif  return(aha152x_id);}/*  *  Queue a command and setup interrupts for a free bus. */int aha152x_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)){#if defined(DEBUG_RACE)  enter_driver("queue");#else#if defined(DEBUG_QUEUE)  printk("aha152x: queue(), ");#endif#endif#if defined(DEBUG_QUEUE)  printk( "SCpnt (target = %d lun = %d cmnd = 0x%02x pieces = %d size = %u), ",          SCpnt->target,          SCpnt->lun,          *(unsigned char *)SCpnt->cmnd,          SCpnt->use_sg,          SCpnt->request_bufflen );  disp_ports();#endif  SCpnt->scsi_done =       done;  /* setup scratch area     SCp.ptr              : buffer pointer     SCp.this_residual    : buffer length     SCp.buffer           : next buffer     SCp.buffers_residual : left buffers in list     SCp.phase            : current state of the command */  SCpnt->SCp.phase = not_issued;  if (SCpnt->use_sg)    {      SCpnt->SCp.buffer           = (struct scatterlist *)SCpnt->request_buffer;      SCpnt->SCp.ptr              = SCpnt->SCp.buffer->address;      SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;      SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;    }  else    {      SCpnt->SCp.ptr              = (char *)SCpnt->request_buffer;      SCpnt->SCp.this_residual    = SCpnt->request_bufflen;      SCpnt->SCp.buffer           = NULL;      SCpnt->SCp.buffers_residual = 0;    }            SCpnt->SCp.Status              = CHECK_CONDITION;  SCpnt->SCp.Message             = 0;  SCpnt->SCp.have_data_in        = 0;  SCpnt->SCp.sent_command        = 0;  /* Turn led on, when this is the first command. */  cli();  commands++;  if(commands==1)    SETPORT( PORTA, 1 );#if defined(DEBUG_QUEUES)  printk("i+ (%d), ", commands );#endif  append_SC( &issue_SC, SCpnt);    /* Enable bus free interrupt, when we aren't currently on the bus */  if(!current_SC)    {      SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );      SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);    }  sti();  return 0;}/* *  We only support command in interrupt-driven fashion */int aha152x_command( Scsi_Cmnd *SCpnt ){  printk( "aha152x: interrupt driven driver; use aha152x_queue()\n" );  return -1;}/* *  Abort a queued command *  (commands that are on the bus can't be aborted easily) */int aha152x_abort( Scsi_Cmnd *SCpnt, int code ){  Scsi_Cmnd *ptr, *prev;  cli();#if defined(DEBUG_ABORT)  printk("aha152x: abort(), SCpnt=0x%08x, ", (unsigned long) SCpnt );#endif  show_queues();  /* look for command in issue queue */  for( ptr=issue_SC, prev=NULL;       ptr && ptr!=SCpnt;       prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble)    ;  if(ptr)    {      /* dequeue */      if(prev)        prev->host_scribble = ptr->host_scribble;      else        issue_SC = (Scsi_Cmnd *) ptr->host_scribble;      sti();      ptr->host_scribble = NULL;      ptr->result = (code ? code : DID_ABORT ) << 16;      ptr->done(ptr);      return 0;    }  /* Fail abortion, if we're on the bus */  if (current_SC)    {       sti();       return -1;    }  /* look for command in disconnected queue */  for( ptr=disconnected_SC, prev=NULL;       ptr && ptr!=SCpnt;       prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble)    ;  if(ptr && TESTLO(SSTAT1, BUSFREE) )    printk("bus busy but no current command, ");  if(ptr && TESTHI(SSTAT1, BUSFREE) )    {      /* dequeue */      if(prev)        prev->host_scribble = ptr->host_scribble;      else        issue_SC = (Scsi_Cmnd *) ptr->host_scribble;      /* set command current and initiate selection,         let the interrupt routine take care of the abortion */      current_SC     = ptr;      ptr->SCp.phase = in_selection|aborted;      SETPORT( SCSIID, (this_host << OID_) | current_SC->target );      /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */      SETPORT( SIMODE0, ENSELDO | (disconnected_SC ? ENSELDI : 0) );      SETPORT( SIMODE1, ENSELTIMO );      /* Enable SELECTION OUT sequence */      SETBITS(SCSISEQ, ENSELO | ENAUTOATNO );      SETBITS( DMACNTRL0, INTEN );      abort_result=0;      sti();      /* sleep until the abortion is complete */      sleep_on( &abortion_complete );      return abort_result;    }  else    printk("aha152x: bus busy but no current command\n");  /* command wasn't found */  sti();  return 0;}/* *  Restore default values to the AIC-6260 registers and reset the fifos */static void aha152x_reset_ports(void){  /* disable interrupts */  SETPORT(DMACNTRL0, RSTFIFO);  SETPORT(SCSISEQ, 0);  SETPORT(SXFRCTL1, 0);  SETPORT( SCSISIG, 0);  SETPORT(SCSIRATE, 0);  /* clear all interrupt conditions */  SETPORT(SSTAT0, 0x7f);  SETPORT(SSTAT1, 0xef);  SETPORT(SSTAT4, SYNCERR|FWERR|FRERR);  SETPORT(DMACNTRL0, 0);  SETPORT(DMACNTRL1, 0);  SETPORT(BRSTCNTRL, 0xf1);  /* clear SCSI fifo and transfer count */  SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);  SETPORT(SXFRCTL0, CH1);  /* enable interrupts */  SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );  SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);}/* *  Reset registers, reset a hanging bus and *  kill active and disconnected commands */int aha152x_reset(Scsi_Cmnd * __unused){  Scsi_Cmnd *ptr;  aha152x_reset_ports();  /* Reset, if bus hangs */  if( TESTLO( SSTAT1, BUSFREE ) )    {       CLRBITS( DMACNTRL0, INTEN );#if defined( DEBUG_RESET )       printk("aha152x: reset(), bus not free: SCSI RESET OUT\n");#endif       show_queues();       if(current_SC)         {           current_SC->host_scribble = NULL;           current_SC->result = DID_RESET << 16;           current_SC->done(current_SC);           current_SC=NULL;         }       while(disconnected_SC)         {           ptr = disconnected_SC;           disconnected_SC = (Scsi_Cmnd *) ptr->host_scribble;           ptr->host_scribble = NULL;           ptr->result = DID_RESET << 16;           ptr->done(ptr);         }       /* RESET OUT */       SETPORT(SCSISEQ, SCSIRSTO);       do_pause(5);       SETPORT(SCSISEQ, 0);       do_pause(10);       SETPORT(SIMODE0, 0 );       SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);

⌨️ 快捷键说明

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