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

📄 aha152x.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
📖 第 1 页 / 共 5 页
字号:
          if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT))            printk("aha152x: P_CMD: %d(%d) bytes left in FIFO, resetting\n",                   GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT));          /* reset fifo and enable writes */          SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO);          SETPORT(DMACNTRL0, ENDMA|WRITE_READ);          /* clear transfer count and scsi fifo */          SETPORT(SXFRCTL0, CH1|CLRSTCNT|CLRCH1 );          SETPORT(SXFRCTL0, SCSIEN|DMAEN|CH1);            /* missing phase raises INTSTAT */          SETPORT( SIMODE0, 0 );          SETPORT( SIMODE1, ENPHASEMIS );  #if defined(DEBUG_CMD)          printk("waiting, ");#endif          /* wait for FIFO to get empty */          while( TESTLO ( DMASTAT, DFIFOEMP|INTSTAT ) )            ;            if( TESTHI( SSTAT1, PHASEMIS ) )            aha152x_panic("target left COMMAND phase");#if defined(DEBUG_CMD)          printk("DFIFOEMP, outsw (%d words), ",                 COMMAND_SIZE(current_SC->cmnd[0])>>1);          disp_ports();#endif            outsw( DATAPORT,                 &current_SC->cmnd,                 COMMAND_SIZE(current_SC->cmnd[0])>>1 );#if defined(DEBUG_CMD)          printk("FCNT=%d, STCNT=%d, ", GETPORT(FIFOSTAT), GETSTCNT() );          disp_ports();#endif          /* wait for SCSI FIFO to get empty.             very important to send complete commands. */          while( TESTLO ( SSTAT2, SEMPTY ) )            ;          CLRBITS(SXFRCTL0, SCSIEN|DMAEN);          /* transfer can be considered ended, when SCSIEN reads back zero */          while( TESTHI( SXFRCTL0, SCSIEN ) )            ;          CLRBITS(DMACNTRL0, ENDMA);#if defined(DEBUG_CMD) || defined(DEBUG_INTR)          printk("sent %d/%d command bytes, ", GETSTCNT(),                 COMMAND_SIZE(current_SC->cmnd[0]));#endif        }      else        aha152x_panic("Nothing to sent while in COMMAND OUT");      break;    case P_MSGI:                                          /* MESSAGE IN phase */#if defined(DEBUG_INTR) || defined(DEBUG_MSGI) || defined(DEBUG_PHASES)      printk("MESSAGE IN, ");#endif      SETPORT( SXFRCTL0, CH1);      SETPORT( SIMODE0, 0);      SETPORT( SIMODE1, ENBUSFREE);        while( phase == P_MSGI )         {          current_SC->SCp.Message = GETPORT( SCSIBUS );          switch(current_SC->SCp.Message)            {            case DISCONNECT:#if defined(DEBUG_MSGI) || defined(DEBUG_PHASES)              printk("target disconnected, ");#endif              current_SC->SCp.Message = 0;              current_SC->SCp.phase   |= disconnected;              if(!can_disconnect)                aha152x_panic("target was not allowed to disconnect");              break;                    case COMMAND_COMPLETE:#if defined(DEBUG_MSGI) || defined(DEBUG_PHASES)              printk("inbound message ( COMMAND COMPLETE ), ");#endif              done++;              break;            case MESSAGE_REJECT:#if defined(DEBUG_MSGI) || defined(DEBUG_TIMING)              printk("inbound message ( MESSAGE REJECT ), ");#endif              break;            case SAVE_POINTERS:#if defined(DEBUG_MSGI)              printk("inbound message ( SAVE DATA POINTERS ), ");#endif              break;            case EXTENDED_MESSAGE:              {                 int           i, code;#if defined(DEBUG_MSGI)                printk("inbound message ( EXTENDED MESSAGE ), ");#endif                make_acklow();                if(getphase()!=P_MSGI)                  break;                  i=GETPORT(SCSIBUS);#if defined(DEBUG_MSGI)                printk("length (%d), ", i);#endif#if defined(DEBUG_MSGI)                printk("code ( ");#endif                make_acklow();                if(getphase()!=P_MSGI)                  break;                code = GETPORT(SCSIBUS);                switch( code )                  {                  case 0x00:#if defined(DEBUG_MSGI)                    printk("MODIFY DATA POINTER ");#endif                    SETPORT(SCSISIG, P_MSGI|ATNO);                    break;                  case 0x01:#if defined(DEBUG_MSGI)                    printk("SYNCHRONOUS DATA TRANSFER REQUEST ");#endif                    SETPORT(SCSISIG, P_MSGI|ATNO);                    break;                  case 0x02:#if defined(DEBUG_MSGI)                    printk("EXTENDED IDENTIFY ");#endif                    break;                  case 0x03:#if defined(DEBUG_MSGI)                    printk("WIDE DATA TRANSFER REQUEST ");#endif                    SETPORT(SCSISIG, P_MSGI|ATNO);                    break;                  default:#if defined(DEBUG_MSGI)                    if( code & 0x80 )                      printk("reserved (%d) ", code );                    else                      printk("vendor specific (%d) ", code);#endif                    SETPORT(SCSISIG, P_MSGI|ATNO);                    break;                  }#if defined(DEBUG_MSGI)                printk(" ), data ( ");#endif                while( --i && (make_acklow(), getphase()==P_MSGI))                  {#if defined(DEBUG_MSGI)                    printk("%x ", GETPORT(SCSIBUS) );#else                    GETPORT(SCSIBUS);#endif                  }#if defined(DEBUG_MSGI)                printk(" ), ");#endif                /* We reject all extended messages. To do this                   we just enter MSGO by asserting ATN. Since                   we have already identified a REJECT message                   will be sent. */                SETPORT(SCSISIG, P_MSGI|ATNO);              }              break;                   default:              printk("unsupported inbound message %x, ", current_SC->SCp.Message);              break;            }          make_acklow();          phase=getphase();        }       /* clear SCSI fifo on BUSFREE */      if(phase==P_BUSFREE)        SETPORT(SXFRCTL0, CH1|CLRCH1);      if(current_SC->SCp.phase & disconnected)        {          cli();#if defined(DEBUG_QUEUES)          printk("d+, ");#endif          append_SC( &disconnected_SC, current_SC);          current_SC = NULL;          sti();          SETBITS( SCSISEQ, ENRESELI );          SETPORT(SIMODE0, disconnected_SC ? ENSELDI : 0 );          SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);          SETBITS( DMACNTRL0, INTEN );          return;        }      break;    case P_STATUS:                                         /* STATUS IN phase */#if defined(DEBUG_STATUS) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)      printk("STATUS, ");#endif      SETPORT( SXFRCTL0, CH1);      SETPORT( SIMODE0, 0 );      SETPORT( SIMODE1, ENREQINIT );      if( TESTHI( SSTAT1, PHASEMIS ) )	printk("aha152x: passing STATUS phase");	      current_SC->SCp.Status = GETPORT( SCSIBUS );      make_acklow();      getphase();#if defined(DEBUG_STATUS)      printk("inbound status ");      print_status( current_SC->SCp.Status );      printk(", ");#endif      break;    case P_DATAI:                                            /* DATA IN phase */      {        int fifodata, data_count, done;#if defined(DEBUG_DATAI) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)        printk("DATA IN, ");#endif        if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT))          printk("aha152x: P_DATAI: %d(%d) bytes left in FIFO, resetting\n",                 GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT));        /* reset host fifo */        SETPORT(DMACNTRL0, RSTFIFO);        SETPORT(DMACNTRL0, RSTFIFO|ENDMA);        SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN );        SETPORT( SIMODE0, 0 );        SETPORT( SIMODE1, ENPHASEMIS|ENBUSFREE );        /* done is set when the FIFO is empty after the target left DATA IN */        done=0;              /* while the target stays in DATA to transfer data */        while ( !done )           {#if defined(DEBUG_DATAI)            printk("expecting data, ");#endif            /* wait for PHASEMIS or full FIFO */            while( TESTLO ( DMASTAT, DFIFOFULL|INTSTAT ) )              ;            if( TESTHI( DMASTAT, DFIFOFULL ) )              fifodata=132;            else              {                /* wait for SCSI fifo to get empty */                while( TESTLO( SSTAT2, SEMPTY ) )                  ;                /* rest of data in FIFO */                fifodata=GETPORT(FIFOSTAT);#if defined(DEBUG_DATAI)                printk("last transfer, ");#endif                done=1;              }  #if defined(DEBUG_DATAI)            printk("fifodata=%d, ", fifodata);#endif            while( fifodata && current_SC->SCp.this_residual )              {                data_count=fifodata;                  /* limit data transfer to size of first sg buffer */                if (data_count > current_SC->SCp.this_residual)                  data_count = current_SC->SCp.this_residual;                  fifodata -= data_count;#if defined(DEBUG_DATAI)                printk("data_count=%d, ", data_count);#endif                  if(data_count == 1)                  {                    /* get a single byte in byte mode */                    SETBITS(DMACNTRL0, _8BIT );                    *current_SC->SCp.ptr++ = GETPORT( DATAPORT );                    current_SC->SCp.this_residual--;                  }                else                  {                    CLRBITS(DMACNTRL0, _8BIT );                    data_count >>= 1; /* Number of words */                    insw( DATAPORT, current_SC->SCp.ptr, data_count );#if defined(DEBUG_DATAI)/* show what comes with the last transfer */                    if(done)                      {                        int           i;                        unsigned char *data;                        printk("data on last transfer (%d bytes: ",                               2*data_count);                        data = (unsigned char *) current_SC->SCp.ptr;                        for( i=0; i<2*data_count; i++)                          printk("%2x ", *data++);                        printk("), ");                      }#endif                    current_SC->SCp.ptr           += 2 * data_count;                    current_SC->SCp.this_residual -= 2 * data_count;                  }                              /* if this buffer is full and there are more buffers left */                if (!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;                  }               }             /* rare (but possible) status bytes (probably also DISCONNECT                messages) get transfered in the data phase, so I assume 1               additional byte is ok */            if(fifodata>1)              {                printk("aha152x: more data than expected (%d bytes)\n",                       GETPORT(FIFOSTAT));              }#if defined(DEBUG_DATAI)            if(!fifodata)              printk("fifo empty, ");            else              printk("something left in fifo, ");#endif          }#if defined(DEBUG_DATAI)        if(current_SC->SCp.buffers_residual || current_SC->SCp.this_residual)          printk("left buffers (buffers=%d, bytes=%d), ",                 current_SC->SCp.buffers_residual,                  current_SC->SCp.this_residual);#endif        /* transfer can be considered ended, when SCSIEN reads back zero */        CLRBITS(SXFRCTL0, SCSIEN|DMAEN);        while( TESTHI( SXFRCTL0, SCSIEN ) )          ;        CLRBITS(DMACNTRL0, ENDMA );#if defined(DEBUG_DATAI) || defined(DEBUG_INTR)        printk("got %d bytes, ", GETSTCNT());#endif        current_SC->SCp.have_data_in++;      }      break;    case P_DATAO:                                           /* DATA OUT phase */      {        int data_count;#if defined(DEBUG_DATAO) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)        printk("DATA OUT, ");#endif#if defined(DEBUG_DATAO)        printk("got data to send (bytes=%d, buffers=%d), ",               current_SC->SCp.this_residual,               current_SC->SCp.buffers_residual );#endif        if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT) )          {            printk("%d(%d) left in FIFO, ", GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT) );            aha152x_panic("FIFO should be empty");          }        SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO);        SETPORT(DMACNTRL0, ENDMA|WRITE_READ);        SETPORT(SXFRCTL0, CH1|CLRSTCNT|CLRCH1 );        SETPORT(SXFRCTL0, SCSIEN|DMAEN|CH1);         SETPORT( SIMODE0, 0 );        SETPORT( SIMODE1, ENPHASEMIS );        /* while current buffer is not empty or           there are more buffers to transfer */        while( TESTLO( SSTAT1, PHASEMIS ) &&                 (current_SC->SCp.this_residual ||                  current_SC->SCp.buffers_residual) )          {#if defined(DEBUG_DATAO)            printk("sending data (left: bytes=%d, buffers=%d), waiting, ",                    current_SC->SCp.this_residual,                    current_SC->SCp.buffers_residual);#endif            /* transfer rest of buffer, but max. 128 byte */            data_count = current_SC->SCp.this_residual > 128 ?                         128 : current_SC->SCp.this_residual ;#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--;

⌨️ 快捷键说明

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