@ -1636,9 +1636,9 @@ ahd_send_async(struct ahd_softc *ahd, char channel,
spi_period ( starget ) = tinfo - > curr . period ;
spi_width ( starget ) = tinfo - > curr . width ;
spi_offset ( starget ) = tinfo - > curr . offset ;
spi_dt ( starget ) = tinfo - > curr . ppr_options & MSG_EXT_PPR_DT_REQ ;
spi_qas ( starget ) = tinfo - > curr . ppr_options & MSG_EXT_PPR_QAS_REQ ;
spi_iu ( starget ) = tinfo - > curr . ppr_options & MSG_EXT_PPR_IU_REQ ;
spi_dt ( starget ) = tinfo - > curr . ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0 ;
spi_qas ( starget ) = tinfo - > curr . ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0 ;
spi_iu ( starget ) = tinfo - > curr . ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0 ;
spi_display_xfer_agreement ( starget ) ;
break ;
}
@ -2318,6 +2318,18 @@ done:
static void ahd_linux_exit ( void ) ;
static void ahd_linux_set_xferflags ( struct scsi_target * starget , unsigned int ppr_options , unsigned int period )
{
spi_qas ( starget ) = ( ppr_options & MSG_EXT_PPR_QAS_REQ ) ? 1 : 0 ;
spi_dt ( starget ) = ( ppr_options & MSG_EXT_PPR_DT_REQ ) ? 1 : 0 ;
spi_iu ( starget ) = ( ppr_options & MSG_EXT_PPR_IU_REQ ) ? 1 : 0 ;
spi_rd_strm ( starget ) = ( ppr_options & MSG_EXT_PPR_RD_STRM ) ? 1 : 0 ;
spi_wr_flow ( starget ) = ( ppr_options & MSG_EXT_PPR_WR_FLOW ) ? 1 : 0 ;
spi_pcomp_en ( starget ) = ( ppr_options & MSG_EXT_PPR_PCOMP_EN ) ? 1 : 0 ;
spi_rti ( starget ) = ( ppr_options & MSG_EXT_PPR_RTI ) ? 1 : 0 ;
spi_period ( starget ) = period ;
}
static void ahd_linux_set_width ( struct scsi_target * starget , int width )
{
struct Scsi_Host * shost = dev_to_shost ( starget - > dev . parent ) ;
@ -2343,9 +2355,14 @@ static void ahd_linux_set_period(struct scsi_target *starget, int period)
shost - > this_id , starget - > id , & tstate ) ;
struct ahd_devinfo devinfo ;
unsigned int ppr_options = tinfo - > goal . ppr_options ;
unsigned int dt ;
unsigned long flags ;
unsigned long offset = tinfo - > goal . offset ;
# ifdef AHD_DEBUG
if ( ( ahd_debug & AHD_SHOW_DV ) ! = 0 )
printf ( " %s: set period to %d \n " , ahd_name ( ahd ) , period ) ;
# endif
if ( offset = = 0 )
offset = MAX_OFFSET ;
@ -2357,6 +2374,8 @@ static void ahd_linux_set_period(struct scsi_target *starget, int period)
ppr_options | = MSG_EXT_PPR_IU_REQ ;
}
dt = ppr_options & MSG_EXT_PPR_DT_REQ ;
ahd_compile_devinfo ( & devinfo , shost - > this_id , starget - > id , 0 ,
starget - > channel + ' A ' , ROLE_INITIATOR ) ;
@ -2366,7 +2385,11 @@ static void ahd_linux_set_period(struct scsi_target *starget, int period)
ppr_options & = MSG_EXT_PPR_QAS_REQ ;
}
ahd_find_syncrate ( ahd , & period , & ppr_options , AHD_SYNCRATE_MAX ) ;
ahd_find_syncrate ( ahd , & period , & ppr_options ,
dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2 ) ;
ahd_linux_set_xferflags ( starget , ppr_options , period ) ;
ahd_lock ( ahd , & flags ) ;
ahd_set_syncrate ( ahd , & devinfo , period , offset ,
ppr_options , AHD_TRANS_GOAL , FALSE ) ;
@ -2385,15 +2408,24 @@ static void ahd_linux_set_offset(struct scsi_target *starget, int offset)
struct ahd_devinfo devinfo ;
unsigned int ppr_options = 0 ;
unsigned int period = 0 ;
unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ ;
unsigned long flags ;
# ifdef AHD_DEBUG
if ( ( ahd_debug & AHD_SHOW_DV ) ! = 0 )
printf ( " %s: set offset to %d \n " , ahd_name ( ahd ) , offset ) ;
# endif
ahd_compile_devinfo ( & devinfo , shost - > this_id , starget - > id , 0 ,
starget - > channel + ' A ' , ROLE_INITIATOR ) ;
if ( offset ! = 0 ) {
period = tinfo - > goal . period ;
ppr_options = tinfo - > goal . ppr_options ;
ahd_find_syncrate ( ahd , & period , & ppr_options , AHD_SYNCRATE_MAX ) ;
ahd_find_syncrate ( ahd , & period , & ppr_options ,
dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2 ) ;
}
ahd_linux_set_xferflags ( starget , ppr_options , period ) ;
ahd_lock ( ahd , & flags ) ;
ahd_set_syncrate ( ahd , & devinfo , period , offset , ppr_options ,
AHD_TRANS_GOAL , FALSE ) ;
@ -2415,17 +2447,28 @@ static void ahd_linux_set_dt(struct scsi_target *starget, int dt)
unsigned int period = tinfo - > goal . period ;
unsigned long flags ;
# ifdef AHD_DEBUG
if ( ( ahd_debug & AHD_SHOW_DV ) ! = 0 )
printf ( " %s: %s DT \n " , ahd_name ( ahd ) ,
dt ? " enabling " : " disabling " ) ;
# endif
if ( dt ) {
ppr_options | = MSG_EXT_PPR_DT_REQ ;
if ( period > 9 )
period = 9 ; /* at least 12.5ns for DT */
} else if ( period < = 9 )
period = 10 ; /* If resetting DT, period must be >= 25ns */
} else {
if ( period < = 9 )
period = 10 ; /* If resetting DT, period must be >= 25ns */
/* IU is invalid without DT set */
ppr_options & = ~ MSG_EXT_PPR_IU_REQ ;
}
ahd_compile_devinfo ( & devinfo , shost - > this_id , starget - > id , 0 ,
starget - > channel + ' A ' , ROLE_INITIATOR ) ;
ahd_find_syncrate ( ahd , & period , & ppr_options ,
dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2 ) ;
ahd_linux_set_xferflags ( starget , ppr_options , period ) ;
ahd_lock ( ahd , & flags ) ;
ahd_set_syncrate ( ahd , & devinfo , period , tinfo - > goal . offset ,
ppr_options , AHD_TRANS_GOAL , FALSE ) ;
@ -2445,16 +2488,28 @@ static void ahd_linux_set_qas(struct scsi_target *starget, int qas)
unsigned int ppr_options = tinfo - > goal . ppr_options
& ~ MSG_EXT_PPR_QAS_REQ ;
unsigned int period = tinfo - > goal . period ;
unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ ;
unsigned int dt ;
unsigned long flags ;
if ( qas )
ppr_options | = MSG_EXT_PPR_QAS_REQ ;
# ifdef AHD_DEBUG
if ( ( ahd_debug & AHD_SHOW_DV ) ! = 0 )
printf ( " %s: %s QAS \n " , ahd_name ( ahd ) ,
qas ? " enabling " : " disabling " ) ;
# endif
if ( qas ) {
ppr_options | = MSG_EXT_PPR_QAS_REQ ;
}
dt = ppr_options & MSG_EXT_PPR_DT_REQ ;
ahd_compile_devinfo ( & devinfo , shost - > this_id , starget - > id , 0 ,
starget - > channel + ' A ' , ROLE_INITIATOR ) ;
ahd_find_syncrate ( ahd , & period , & ppr_options ,
dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2 ) ;
spi_qas ( starget ) = ( ppr_options & MSG_EXT_PPR_QAS_REQ ) ? 1 : 0 ;
ahd_lock ( ahd , & flags ) ;
ahd_set_syncrate ( ahd , & devinfo , period , tinfo - > goal . offset ,
ppr_options , AHD_TRANS_GOAL , FALSE ) ;
@ -2474,16 +2529,29 @@ static void ahd_linux_set_iu(struct scsi_target *starget, int iu)
unsigned int ppr_options = tinfo - > goal . ppr_options
& ~ MSG_EXT_PPR_IU_REQ ;
unsigned int period = tinfo - > goal . period ;
unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ ;
unsigned int dt ;
unsigned long flags ;
if ( iu )
# ifdef AHD_DEBUG
if ( ( ahd_debug & AHD_SHOW_DV ) ! = 0 )
printf ( " %s: %s IU \n " , ahd_name ( ahd ) ,
iu ? " enabling " : " disabling " ) ;
# endif
if ( iu ) {
ppr_options | = MSG_EXT_PPR_IU_REQ ;
ppr_options | = MSG_EXT_PPR_DT_REQ ; /* IU requires DT */
}
dt = ppr_options & MSG_EXT_PPR_DT_REQ ;
ahd_compile_devinfo ( & devinfo , shost - > this_id , starget - > id , 0 ,
starget - > channel + ' A ' , ROLE_INITIATOR ) ;
ahd_find_syncrate ( ahd , & period , & ppr_options ,
dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2 ) ;
ahd_linux_set_xferflags ( starget , ppr_options , period ) ;
ahd_lock ( ahd , & flags ) ;
ahd_set_syncrate ( ahd , & devinfo , period , tinfo - > goal . offset ,
ppr_options , AHD_TRANS_GOAL , FALSE ) ;
@ -2506,6 +2574,12 @@ static void ahd_linux_set_rd_strm(struct scsi_target *starget, int rdstrm)
unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ ;
unsigned long flags ;
# ifdef AHD_DEBUG
if ( ( ahd_debug & AHD_SHOW_DV ) ! = 0 )
printf ( " %s: %s Read Streaming \n " , ahd_name ( ahd ) ,
rdstrm ? " enabling " : " disabling " ) ;
# endif
if ( rdstrm )
ppr_options | = MSG_EXT_PPR_RD_STRM ;
@ -2513,6 +2587,131 @@ static void ahd_linux_set_rd_strm(struct scsi_target *starget, int rdstrm)
starget - > channel + ' A ' , ROLE_INITIATOR ) ;
ahd_find_syncrate ( ahd , & period , & ppr_options ,
dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2 ) ;
spi_rd_strm ( starget ) = ( ppr_options & MSG_EXT_PPR_RD_STRM ) ? 1 : 0 ;
ahd_lock ( ahd , & flags ) ;
ahd_set_syncrate ( ahd , & devinfo , period , tinfo - > goal . offset ,
ppr_options , AHD_TRANS_GOAL , FALSE ) ;
ahd_unlock ( ahd , & flags ) ;
}
static void ahd_linux_set_wr_flow ( struct scsi_target * starget , int wrflow )
{
struct Scsi_Host * shost = dev_to_shost ( starget - > dev . parent ) ;
struct ahd_softc * ahd = * ( ( struct ahd_softc * * ) shost - > hostdata ) ;
struct ahd_tmode_tstate * tstate ;
struct ahd_initiator_tinfo * tinfo
= ahd_fetch_transinfo ( ahd ,
starget - > channel + ' A ' ,
shost - > this_id , starget - > id , & tstate ) ;
struct ahd_devinfo devinfo ;
unsigned int ppr_options = tinfo - > goal . ppr_options
& ~ MSG_EXT_PPR_WR_FLOW ;
unsigned int period = tinfo - > goal . period ;
unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ ;
unsigned long flags ;
# ifdef AHD_DEBUG
if ( ( ahd_debug & AHD_SHOW_DV ) ! = 0 )
printf ( " %s: %s Write Flow Control \n " , ahd_name ( ahd ) ,
wrflow ? " enabling " : " disabling " ) ;
# endif
if ( wrflow )
ppr_options | = MSG_EXT_PPR_WR_FLOW ;
ahd_compile_devinfo ( & devinfo , shost - > this_id , starget - > id , 0 ,
starget - > channel + ' A ' , ROLE_INITIATOR ) ;
ahd_find_syncrate ( ahd , & period , & ppr_options ,
dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2 ) ;
spi_wr_flow ( starget ) = ( ppr_options & MSG_EXT_PPR_WR_FLOW ) ? 1 : 0 ;
ahd_lock ( ahd , & flags ) ;
ahd_set_syncrate ( ahd , & devinfo , period , tinfo - > goal . offset ,
ppr_options , AHD_TRANS_GOAL , FALSE ) ;
ahd_unlock ( ahd , & flags ) ;
}
static void ahd_linux_set_rti ( struct scsi_target * starget , int rti )
{
struct Scsi_Host * shost = dev_to_shost ( starget - > dev . parent ) ;
struct ahd_softc * ahd = * ( ( struct ahd_softc * * ) shost - > hostdata ) ;
struct ahd_tmode_tstate * tstate ;
struct ahd_initiator_tinfo * tinfo
= ahd_fetch_transinfo ( ahd ,
starget - > channel + ' A ' ,
shost - > this_id , starget - > id , & tstate ) ;
struct ahd_devinfo devinfo ;
unsigned int ppr_options = tinfo - > goal . ppr_options
& ~ MSG_EXT_PPR_RTI ;
unsigned int period = tinfo - > goal . period ;
unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ ;
unsigned long flags ;
if ( ( ahd - > features & AHD_RTI ) = = 0 ) {
# ifdef AHD_DEBUG
if ( ( ahd_debug & AHD_SHOW_DV ) ! = 0 )
printf ( " %s: RTI not available \n " , ahd_name ( ahd ) ) ;
# endif
return ;
}
# ifdef AHD_DEBUG
if ( ( ahd_debug & AHD_SHOW_DV ) ! = 0 )
printf ( " %s: %s RTI \n " , ahd_name ( ahd ) ,
rti ? " enabling " : " disabling " ) ;
# endif
if ( rti )
ppr_options | = MSG_EXT_PPR_RTI ;
ahd_compile_devinfo ( & devinfo , shost - > this_id , starget - > id , 0 ,
starget - > channel + ' A ' , ROLE_INITIATOR ) ;
ahd_find_syncrate ( ahd , & period , & ppr_options ,
dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2 ) ;
spi_rti ( starget ) = ( ppr_options & MSG_EXT_PPR_RTI ) ? 1 : 0 ;
ahd_lock ( ahd , & flags ) ;
ahd_set_syncrate ( ahd , & devinfo , period , tinfo - > goal . offset ,
ppr_options , AHD_TRANS_GOAL , FALSE ) ;
ahd_unlock ( ahd , & flags ) ;
}
static void ahd_linux_set_pcomp_en ( struct scsi_target * starget , int pcomp )
{
struct Scsi_Host * shost = dev_to_shost ( starget - > dev . parent ) ;
struct ahd_softc * ahd = * ( ( struct ahd_softc * * ) shost - > hostdata ) ;
struct ahd_tmode_tstate * tstate ;
struct ahd_initiator_tinfo * tinfo
= ahd_fetch_transinfo ( ahd ,
starget - > channel + ' A ' ,
shost - > this_id , starget - > id , & tstate ) ;
struct ahd_devinfo devinfo ;
unsigned int ppr_options = tinfo - > goal . ppr_options
& ~ MSG_EXT_PPR_PCOMP_EN ;
unsigned int period = tinfo - > goal . period ;
unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ ;
unsigned long flags ;
# ifdef AHD_DEBUG
if ( ( ahd_debug & AHD_SHOW_DV ) ! = 0 )
printf ( " %s: %s Precompensation \n " , ahd_name ( ahd ) ,
pcomp ? " Enable " : " Disable " ) ;
# endif
if ( pcomp )
ppr_options | = MSG_EXT_PPR_PCOMP_EN ;
ahd_compile_devinfo ( & devinfo , shost - > this_id , starget - > id , 0 ,
starget - > channel + ' A ' , ROLE_INITIATOR ) ;
ahd_find_syncrate ( ahd , & period , & ppr_options ,
dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2 ) ;
spi_pcomp_en ( starget ) = ( ppr_options & MSG_EXT_PPR_PCOMP_EN ) ? 1 : 0 ;
ahd_lock ( ahd , & flags ) ;
ahd_set_syncrate ( ahd , & devinfo , period , tinfo - > goal . offset ,
ppr_options , AHD_TRANS_GOAL , FALSE ) ;
@ -2534,6 +2733,12 @@ static struct spi_function_template ahd_linux_transport_functions = {
. show_qas = 1 ,
. set_rd_strm = ahd_linux_set_rd_strm ,
. show_rd_strm = 1 ,
. set_wr_flow = ahd_linux_set_wr_flow ,
. show_wr_flow = 1 ,
. set_rti = ahd_linux_set_rti ,
. show_rti = 1 ,
. set_pcomp_en = ahd_linux_set_pcomp_en ,
. show_pcomp_en = 1 ,
} ;