📄 aha152x.c
字号:
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"); 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(")"); if(ptr->SCp.phase & (1<<16)) printk("; phaseend"); } printk("; next=0x%08x\n", (unsigned long) ptr->host_scribble);} /* * Dump the queued data */static void show_queues(void){ Scsi_Cmnd *ptr; cli(); printk("QUEUE STATUS:\nissue_SC:\n"); for(ptr=issue_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble ) show_command(ptr); printk("current_SC:\n"); if(current_SC) show_command(current_SC); else printk("none\n"); printk("disconnected_SC:\n"); for(ptr=disconnected_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble ) show_command(ptr); disp_ports(); disp_enintr(); sti();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -