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

📄 aha152x.c

📁 LINUX 1.0 内核c源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#if defined(DEBUG_DATAO)
            printk("data_count=%d, ", data_count);
#endif
  
            if(data_count == 1)
              {
                /* put a single byte in byte mode */
                SETBITS(DMACNTRL0, _8BIT );
                SETPORT(DATAPORT, *current_SC->SCp.ptr++);
                current_SC->SCp.this_residual--;
              }
            else
              {
                CLRBITS(DMACNTRL0, _8BIT );
                data_count >>= 1; /* Number of words */
                outsw( DATAPORT, current_SC->SCp.ptr, data_count );
                current_SC->SCp.ptr           += 2 * data_count;
                current_SC->SCp.this_residual -= 2 * data_count;
              }

            /* wait for FIFO to get empty */
            while( TESTLO ( DMASTAT, DFIFOEMP|INTSTAT ) )
              ;

#if defined(DEBUG_DATAO)
            printk("fifo (%d bytes), transfered (%d bytes), ",
                   GETPORT(FIFOSTAT), GETSTCNT() );
#endif

            /* if this buffer is empty and there are more buffers left */
            if ( TESTLO( SSTAT1, PHASEMIS ) &&
                 !current_SC->SCp.this_residual &&
                  current_SC->SCp.buffers_residual)
              {
                 /* advance to next buffer */
                 current_SC->SCp.buffers_residual--;
                 current_SC->SCp.buffer++;
                 current_SC->SCp.ptr =
                   current_SC->SCp.buffer->address;
                 current_SC->SCp.this_residual =
                 current_SC->SCp.buffer->length;
              }
          }

        if ( current_SC->SCp.this_residual ||
             current_SC->SCp.buffers_residual )
          {
            /* target leaves DATA OUT for an other phase
               (perhaps disconnect) */

            /* data in fifos has to be resend */
            data_count = GETPORT(SSTAT2) & (SFULL|SFCNT);

            data_count += GETPORT(FIFOSTAT) ;
            current_SC->SCp.ptr           -= data_count;
            current_SC->SCp.this_residual += data_count;
#if defined(DEBUG_DATAO)
            printk("left data (bytes=%d, buffers=%d), fifos (bytes=%d), transfer incomplete, resetting fifo, ",
                   current_SC->SCp.this_residual,
                   current_SC->SCp.buffers_residual,
                   data_count );
#endif
            SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO);
            CLRBITS(SXFRCTL0, SCSIEN|DMAEN );
            CLRBITS(DMACNTRL0, ENDMA);
          }
        else
          {
#if defined(DEBUG_DATAO)
            printk("waiting for SCSI fifo to get empty, ");
#endif
            /* wait for SCSI fifo to get empty */
            while( TESTLO( SSTAT2, SEMPTY ) )
              ;
#if defined(DEBUG_DATAO)
            printk("ok, ");
#endif

#if defined(DEBUG_DATAO)
            printk("left data (bytes=%d, buffers=%d) ",
                   current_SC->SCp.this_residual,
                   current_SC->SCp.buffers_residual);
#endif
            CLRBITS(SXFRCTL0, SCSIEN|DMAEN);

            /* transfer can be considered ended, when SCSIEN reads back zero */
            while( TESTHI( SXFRCTL0, SCSIEN ) )
              ;

            CLRBITS(DMACNTRL0, ENDMA);
          }

#if defined(DEBUG_DATAO) || defined(DEBUG_INTR)
        printk("sent %d data bytes, ", GETSTCNT() );
#endif
      }
      break;

    case P_BUSFREE:                                                /* BUSFREE */
#if defined(DEBUG_RACE)
      leave_driver("(BUSFREE) intr");
#endif
#if defined(DEBUG_PHASES)
      printk("unexpected BUS FREE, ");
#endif
      current_SC->SCp.phase = (current_SC->SCp.phase & ~(P_MASK<<16));

      aha152x_done( DID_ERROR << 16 );               /* Don't know any better */
      return;
      break;

    case P_PARITY:                              /* parity error in DATA phase */
#if defined(DEBUG_RACE)
      leave_driver("(DID_PARITY) intr");
#endif
      printk("PARITY error in DATA phase, ");

      current_SC->SCp.phase = (current_SC->SCp.phase & ~(P_MASK<<16));

      SETBITS( DMACNTRL0, INTEN );
      aha152x_done( DID_PARITY << 16 );
      return;
      break;

    default:
      printk("aha152x: unexpected phase\n");
      break;
    }

  if(done)
    {
#if defined(DEBUG_INTR)
      printk("command done.\n");
#endif
#if defined(DEBUG_RACE)
      leave_driver("(done) intr");
#endif

      SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );
      SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);
      SETPORT( SCSISEQ, disconnected_SC ? ENRESELI : 0 );

      SETBITS( DMACNTRL0, INTEN );

      aha152x_done(   (current_SC->SCp.Status  & 0xff)
                    | ( (current_SC->SCp.Message & 0xff) << 8)
                    | ( DID_OK << 16) );

#if defined(DEBUG_RACE)
      printk("done returned (DID_OK: Status=%x; Message=%x).\n",
             current_SC->SCp.Status, current_SC->SCp.Message);
#endif
      return;
    }

  if(current_SC)
    current_SC->SCp.phase |= 1<<16 ;

  SETPORT( SIMODE0, 0 );
  SETPORT( SIMODE1, ENPHASEMIS );
#if defined(DEBUG_INTR)
  disp_enintr();
#endif
#if defined(DEBUG_RACE)
  leave_driver("(PHASEEND) intr");
#endif

  SETBITS( DMACNTRL0, INTEN);
  return;
}

/* 
 * Dump the current driver status and panic...
 */
static void aha152x_panic(char *msg)
{
  printk("\naha152x_panic: %s\n", msg);
  show_queues();
  panic("aha152x panic");
}

/*
 * Display registers of AIC-6260
 */
static void disp_ports(void)
{
#if !defined(SKIP_PORTS)
  int s;

  printk("\n%s: ", current_SC ? "on bus" : "waiting");

  s=GETPORT(SCSISEQ);
  printk("SCSISEQ ( ");
  if( s & TEMODEO )     printk("TARGET MODE ");
  if( s & ENSELO )      printk("SELO ");
  if( s & ENSELI )      printk("SELI ");
  if( s & ENRESELI )    printk("RESELI ");
  if( s & ENAUTOATNO )  printk("AUTOATNO ");
  if( s & ENAUTOATNI )  printk("AUTOATNI ");
  if( s & ENAUTOATNP )  printk("AUTOATNP ");
  if( s & SCSIRSTO )    printk("SCSIRSTO ");
  printk(");");

  printk(" SCSISIG ( ");
  s=GETPORT(SCSISIG);
  switch(s & P_MASK)
    {
    case P_DATAO:
      printk("DATA OUT");
      break;
    case P_DATAI:
      printk("DATA IN");
      break;
    case P_CMD:
      printk("COMMAND"); 
      break;
    case P_STATUS:
      printk("STATUS"); 
      break;
    case P_MSGO:
      printk("MESSAGE OUT");
      break;
    case P_MSGI:
      printk("MESSAGE IN");
      break;
    default:
      printk("*illegal*");
      break;
    }
  
  printk(" ); ");

  printk("INTSTAT ( %s ); ", TESTHI(DMASTAT, INTSTAT) ? "hi" : "lo");

  printk("SSTAT ( ");
  s=GETPORT(SSTAT0);
  if( s & TARGET )   printk("TARGET ");
  if( s & SELDO )    printk("SELDO ");
  if( s & SELDI )    printk("SELDI ");
  if( s & SELINGO )  printk("SELINGO ");
  if( s & SWRAP )    printk("SWRAP ");
  if( s & SDONE )    printk("SDONE ");
  if( s & SPIORDY )  printk("SPIORDY ");
  if( s & DMADONE )  printk("DMADONE ");

  s=GETPORT(SSTAT1);
  if( s & SELTO )     printk("SELTO ");
  if( s & ATNTARG )   printk("ATNTARG ");
  if( s & SCSIRSTI )  printk("SCSIRSTI ");
  if( s & PHASEMIS )  printk("PHASEMIS ");
  if( s & BUSFREE )   printk("BUSFREE ");
  if( s & SCSIPERR )  printk("SCSIPERR ");
  if( s & PHASECHG )  printk("PHASECHG ");
  if( s & REQINIT )   printk("REQINIT ");
  printk("); ");


  printk("SSTAT ( ");

  s=GETPORT(SSTAT0) & GETPORT(SIMODE0);

  if( s & TARGET )    printk("TARGET ");
  if( s & SELDO )     printk("SELDO ");
  if( s & SELDI )     printk("SELDI ");
  if( s & SELINGO )   printk("SELINGO ");
  if( s & SWRAP )     printk("SWRAP ");
  if( s & SDONE )     printk("SDONE ");
  if( s & SPIORDY )   printk("SPIORDY ");
  if( s & DMADONE )   printk("DMADONE ");

  s=GETPORT(SSTAT1) & GETPORT(SIMODE1);

  if( s & SELTO )     printk("SELTO ");
  if( s & ATNTARG )   printk("ATNTARG ");
  if( s & SCSIRSTI )  printk("SCSIRSTI ");
  if( s & PHASEMIS )  printk("PHASEMIS ");
  if( s & BUSFREE )   printk("BUSFREE ");
  if( s & SCSIPERR )  printk("SCSIPERR ");
  if( s & PHASECHG )  printk("PHASECHG ");
  if( s & REQINIT )   printk("REQINIT ");
  printk("); ");

  printk("SXFRCTL0 ( ");

  s=GETPORT(SXFRCTL0);
  if( s & SCSIEN )    printk("SCSIEN ");
  if( s & DMAEN )     printk("DMAEN ");
  if( s & CH1 )       printk("CH1 ");
  if( s & CLRSTCNT )  printk("CLRSTCNT ");
  if( s & SPIOEN )    printk("SPIOEN ");
  if( s & CLRCH1 )    printk("CLRCH1 ");
  printk("); ");

  printk("SIGNAL ( ");

  s=GETPORT(SCSISIG);
  if( s & ATNI )  printk("ATNI ");
  if( s & SELI )  printk("SELI ");
  if( s & BSYI )  printk("BSYI ");
  if( s & REQI )  printk("REQI ");
  if( s & ACKI )  printk("ACKI ");
  printk("); ");

  printk("SELID ( %02x ), ", GETPORT(SELID) );

  printk("SSTAT2 ( ");

  s=GETPORT(SSTAT2);
  if( s & SOFFSET)  printk("SOFFSET ");
  if( s & SEMPTY)   printk("SEMPTY ");
  if( s & SFULL)    printk("SFULL ");
  printk("); SFCNT ( %d ); ", s & (SFULL|SFCNT) );

#if 0
  printk("SSTAT4 ( ");
  s=GETPORT(SSTAT4);
  if( s & SYNCERR)   printk("SYNCERR ");
  if( s & FWERR)     printk("FWERR ");
  if( s & FRERR)     printk("FRERR ");
  printk("); ");
#endif

  printk("FCNT ( %d ); ", GETPORT(FIFOSTAT) );

  printk("DMACNTRL0 ( ");
  s=GETPORT(DMACNTRL0);
  printk( "%s ", s & _8BIT      ? "8BIT"  : "16BIT" );
  printk( "%s ", s & DMA        ? "DMA"   : "PIO"   );
  printk( "%s ", s & WRITE_READ ? "WRITE" : "READ"  );
  if( s & ENDMA )    printk("ENDMA ");
  if( s & INTEN )    printk("INTEN ");
  if( s & RSTFIFO )  printk("RSTFIFO ");
  if( s & SWINT )    printk("SWINT ");
  printk("); ");


#if 0
  printk("DMACNTRL1 ( ");

  s=GETPORT(DMACNTRL1);
  if( s & PWRDWN )    printk("PWRDN ");
  printk("); ");


  printk("STK ( %d ); ", s & 0xf);

  printk("DMASTAT (");
  s=GETPORT(DMASTAT);
  if( s & ATDONE )     printk("ATDONE ");
  if( s & WORDRDY )    printk("WORDRDY ");
  if( s & DFIFOFULL )  printk("DFIFOFULL ");
  if( s & DFIFOEMP )   printk("DFIFOEMP ");
  printk(")");

#endif

  printk("\n");
#endif
}

/*
 * display enabled interrupts
 */
static void disp_enintr(void)
{
  int s;

  printk("enabled interrupts ( ");
  
  s=GETPORT(SIMODE0);
  if( s & ENSELDO )    printk("ENSELDO ");
  if( s & ENSELDI )    printk("ENSELDI ");
  if( s & ENSELINGO )  printk("ENSELINGO ");
  if( s & ENSWRAP )    printk("ENSWRAP ");
  if( s & ENSDONE )    printk("ENSDONE ");
  if( s & ENSPIORDY )  printk("ENSPIORDY ");
  if( s & ENDMADONE )  printk("ENDMADONE ");

  s=GETPORT(SIMODE1);
  if( s & ENSELTIMO )    printk("ENSELTIMO ");
  if( s & ENATNTARG )    printk("ENATNTARG ");
  if( s & ENPHASEMIS )   printk("ENPHASEMIS ");
  if( s & ENBUSFREE )    printk("ENBUSFREE ");
  if( s & ENSCSIPERR )   printk("ENSCSIPERR ");
  if( s & ENPHASECHG )   printk("ENPHASECHG ");
  if( s & ENREQINIT )    printk("ENREQINIT ");
  printk(")\n");
}

#if defined(DEBUG_RACE)

static const char *should_leave;
static int in_driver=0;

/*
 * Only one routine can be in the driver at once.
 */
static void enter_driver(const char *func)
{
  cli();
  printk("aha152x: entering %s() (%x)\n", func, jiffies);
  if(in_driver)
    {
      printk("%s should leave first.\n", should_leave);
      panic("aha152x: already in driver\n");
    }

  in_driver++;
  should_leave=func;
  sti();
}

static void leave_driver(const char *func)
{
  cli();
  printk("\naha152x: leaving %s() (%x)\n", func, jiffies);
  if(!in_driver)
    {
      printk("aha152x: %s already left.\n", should_leave);
      panic("aha152x: %s already left driver.\n");
    }

  in_driver--;
  should_leave=func;
  sti();
}
#endif

/*
 * Show the command data of a command
 */
static void show_command(Scsi_Cmnd *ptr)
{
  int i;

  printk("0x%08x: target=%d; lun=%d; cmnd=( ",
         (unsigned long) ptr, ptr->target, ptr->lun);
  
  for(i=0; i<COMMAND_SIZE(ptr->cmnd[0]); i++)
    printk("%02x ", ptr->cmnd[i]);

  printk("); residual=%d; buffers=%d; phase |",
         ptr->SCp.this_residual, ptr->SCp.buffers_residual);

  if( ptr->SCp.phase & not_issued   )  printk("not issued|");
  if( ptr->SCp.phase & in_selection )  printk("in selection|");
  if( ptr->SCp.phase & disconnected )  printk("disconnected|");
  if( ptr->SCp.phase & aborted      )  printk("aborted|");
  if( ptr->SCp.phase & sent_ident   )  printk("send_ident|");
  if( ptr->SCp.phase & in_other )
    { 
      printk("; in other(");
      switch( (ptr->SCp.phase >> 16) & P_MASK )
        {
        case P_DATAO:
          printk("DATA OUT");
          break;
        case P_DATAI:
          printk("DATA IN");
          break;
        case P_CMD:
          printk("COMMAND");
        

⌨️ 快捷键说明

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