📄 aha152x.c
字号:
#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 + -