@ -163,7 +163,7 @@ static int ehci_reset(void)
# ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
cmd = ehci_readl ( & hcor - > or_txfilltuning ) ;
cmd & = ~ TXFIFO_THRESH ( 0x3f ) ;
cmd & = ~ TXFIFO_THRESH_MASK ;
cmd | = TXFIFO_THRESH ( CONFIG_USB_EHCI_TXFIFO_THRESH ) ;
ehci_writel ( & hcor - > or_txfilltuning , cmd ) ;
# endif
@ -186,7 +186,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
while ( idx < QT_BUFFER_CNT ) {
td - > qt_buffer [ idx ] = cpu_to_hc32 ( addr ) ;
td - > qt_buffer_hi [ idx ] = 0 ;
next = ( addr + 4096 ) & ~ 4095 ;
next = ( addr + EHCI_PAGE_SIZE ) & ~ ( EHCI_PAGE_SIZE - 1 ) ;
delta = next - addr ;
if ( delta > = sz )
break ;
@ -208,7 +208,8 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
int length , struct devrequest * req )
{
ALLOC_ALIGN_BUFFER ( struct QH , qh , 1 , USB_DMA_MINALIGN ) ;
ALLOC_ALIGN_BUFFER ( struct qTD , qtd , 3 , USB_DMA_MINALIGN ) ;
# define QTD_COUNT 3
ALLOC_ALIGN_BUFFER ( struct qTD , qtd , QTD_COUNT , USB_DMA_MINALIGN ) ;
int qtd_counter = 0 ;
volatile struct qTD * vtd ;
@ -230,7 +231,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
le16_to_cpu ( req - > index ) ) ;
memset ( qh , 0 , sizeof ( struct QH ) ) ;
memset ( qtd , 0 , 3 * sizeof ( * qtd ) ) ;
memset ( qtd , 0 , QTD_COUNT * sizeof ( * qtd ) ) ;
toggle = usb_gettoggle ( dev , usb_pipeendpoint ( pipe ) , usb_pipeout ( pipe ) ) ;
@ -245,20 +246,17 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
* - qh_overlay . qt_altnext
*/
qh - > qh_link = cpu_to_hc32 ( ( uint32_t ) qh_list | QH_LINK_TYPE_QH ) ;
c = ( usb_pipespeed ( pipe ) ! = USB_SPEED_HIGH & &
usb_pipeendpoint ( pipe ) = = 0 ) ? 1 : 0 ;
endpt = ( 8 < < 28 ) |
( c < < 27 ) |
( usb_maxpacket ( dev , pipe ) < < 16 ) |
( 0 < < 15 ) |
( 1 < < 14 ) |
( usb_pipespeed ( pipe ) < < 12 ) |
( usb_pipeendpoint ( pipe ) < < 8 ) |
( 0 < < 7 ) | ( usb_pipedevice ( pipe ) < < 0 ) ;
c = usb_pipespeed ( pipe ) ! = USB_SPEED_HIGH & & ! usb_pipeendpoint ( pipe ) ;
endpt = QH_ENDPT1_RL ( 8 ) | QH_ENDPT1_C ( c ) |
QH_ENDPT1_MAXPKTLEN ( usb_maxpacket ( dev , pipe ) ) | QH_ENDPT1_H ( 0 ) |
QH_ENDPT1_DTC ( QH_ENDPT1_DTC_DT_FROM_QTD ) |
QH_ENDPT1_EPS ( usb_pipespeed ( pipe ) ) |
QH_ENDPT1_ENDPT ( usb_pipeendpoint ( pipe ) ) | QH_ENDPT1_I ( 0 ) |
QH_ENDPT1_DEVADDR ( usb_pipedevice ( pipe ) ) ;
qh - > qh_endpt1 = cpu_to_hc32 ( endpt ) ;
endpt = ( 1 < < 30 ) |
( dev - > portnr < < 23 ) |
( dev - > parent - > devnum < < 16 ) | ( 0 < < 8 ) | ( 0 < < 0 ) ;
endpt = QH_ENDPT2_MULT ( 1 ) | QH_ENDPT2_PORTNUM ( dev - > portnr ) |
QH_ENDPT2_HUBADDR ( dev - > parent - > devnum ) |
QH_ENDPT2_UFCMASK ( 0 ) | QH_ENDPT2_UFSMASK ( 0 ) ;
qh - > qh_endpt2 = cpu_to_hc32 ( endpt ) ;
qh - > qh_overlay . qt_next = cpu_to_hc32 ( QT_NEXT_TERMINATE ) ;
@ -276,12 +274,13 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
*/
qtd [ qtd_counter ] . qt_next = cpu_to_hc32 ( QT_NEXT_TERMINATE ) ;
qtd [ qtd_counter ] . qt_altnext = cpu_to_hc32 ( QT_NEXT_TERMINATE ) ;
token = ( 0 < < 31 ) |
( sizeof ( * req ) < < 16 ) |
( 0 < < 15 ) | ( 0 < < 12 ) | ( 3 < < 10 ) | ( 2 < < 8 ) | ( 0x80 < < 0 ) ;
token = QT_TOKEN_DT ( 0 ) | QT_TOKEN_TOTALBYTES ( sizeof ( * req ) ) |
QT_TOKEN_IOC ( 0 ) | QT_TOKEN_CPAGE ( 0 ) | QT_TOKEN_CERR ( 3 ) |
QT_TOKEN_PID ( QT_TOKEN_PID_SETUP ) |
QT_TOKEN_STATUS ( QT_TOKEN_STATUS_ACTIVE ) ;
qtd [ qtd_counter ] . qt_token = cpu_to_hc32 ( token ) ;
if ( ehci_td_buffer ( & qtd [ qtd_counter ] , req , sizeof ( * req ) ) ! = 0 ) {
printf ( " unable construct SETUP td \n " ) ;
if ( ehci_td_buffer ( & qtd [ qtd_counter ] , req , sizeof ( * req ) ) ) {
printf ( " unable to construct SETUP TD \n " ) ;
goto fail ;
}
/* Update previous qTD! */
@ -302,15 +301,14 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
*/
qtd [ qtd_counter ] . qt_next = cpu_to_hc32 ( QT_NEXT_TERMINATE ) ;
qtd [ qtd_counter ] . qt_altnext = cpu_to_hc32 ( QT_NEXT_TERMINATE ) ;
token = ( toggle < < 31 ) |
( length < < 16 ) |
( ( req = = NULL ? 1 : 0 ) < < 15 ) |
( 0 < < 12 ) |
( 3 < < 10 ) |
( ( usb_pipein ( pipe ) ? 1 : 0 ) < < 8 ) | ( 0x80 < < 0 ) ;
token = QT_TOKEN_DT ( toggle ) | QT_TOKEN_TOTALBYTES ( length ) |
QT_TOKEN_IOC ( req = = NULL ) | QT_TOKEN_CPAGE ( 0 ) |
QT_TOKEN_CERR ( 3 ) | QT_TOKEN_PID ( usb_pipein ( pipe ) ?
QT_TOKEN_PID_IN : QT_TOKEN_PID_OUT ) |
QT_TOKEN_STATUS ( QT_TOKEN_STATUS_ACTIVE ) ;
qtd [ qtd_counter ] . qt_token = cpu_to_hc32 ( token ) ;
if ( ehci_td_buffer ( & qtd [ qtd_counter ] , buffer , length ) ! = 0 ) {
printf ( " unable construct DATA td \n " ) ;
if ( ehci_td_buffer ( & qtd [ qtd_counter ] , buffer , length ) ) {
printf ( " unable to construct DATA TD \n " ) ;
goto fail ;
}
/* Update previous qTD! */
@ -328,12 +326,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
*/
qtd [ qtd_counter ] . qt_next = cpu_to_hc32 ( QT_NEXT_TERMINATE ) ;
qtd [ qtd_counter ] . qt_altnext = cpu_to_hc32 ( QT_NEXT_TERMINATE ) ;
token = ( toggle < < 31 ) |
( 0 < < 16 ) |
( 1 < < 15 ) |
( 0 < < 12 ) |
( 3 < < 10 ) |
( ( usb_pipein ( pipe ) ? 0 : 1 ) < < 8 ) | ( 0x80 < < 0 ) ;
token = QT_TOKEN_DT ( toggle ) | QT_TOKEN_TOTALBYTES ( 0 ) |
QT_TOKEN_IOC ( 1 ) | QT_TOKEN_CPAGE ( 0 ) | QT_TOKEN_CERR ( 3 ) |
QT_TOKEN_PID ( usb_pipein ( pipe ) ?
QT_TOKEN_PID_OUT : QT_TOKEN_PID_IN ) |
QT_TOKEN_STATUS ( QT_TOKEN_STATUS_ACTIVE ) ;
qtd [ qtd_counter ] . qt_token = cpu_to_hc32 ( token ) ;
/* Update previous qTD! */
* tdp = cpu_to_hc32 ( ( uint32_t ) & qtd [ qtd_counter ] ) ;
@ -346,7 +343,8 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
flush_dcache_range ( ( uint32_t ) qh_list ,
ALIGN_END_ADDR ( struct QH , qh_list , 1 ) ) ;
flush_dcache_range ( ( uint32_t ) qh , ALIGN_END_ADDR ( struct QH , qh , 1 ) ) ;
flush_dcache_range ( ( uint32_t ) qtd , ALIGN_END_ADDR ( struct qTD , qtd , 3 ) ) ;
flush_dcache_range ( ( uint32_t ) qtd ,
ALIGN_END_ADDR ( struct qTD , qtd , QTD_COUNT ) ) ;
/* Set async. queue head pointer. */
ehci_writel ( & hcor - > or_asynclistaddr , ( uint32_t ) qh_list ) ;
@ -359,10 +357,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
cmd | = CMD_ASE ;
ehci_writel ( & hcor - > or_usbcmd , cmd ) ;
ret = handshake ( ( uint32_t * ) & hcor - > or_usbsts , STD_ASS , STD _ASS ,
ret = handshake ( ( uint32_t * ) & hcor - > or_usbsts , STS_ASS , STS _ASS ,
100 * 1000 ) ;
if ( ret < 0 ) {
printf ( " EHCI fail timeout STD _ASS set \n " ) ;
printf ( " EHCI fail timeout STS _ASS set \n " ) ;
goto fail ;
}
@ -377,10 +375,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
invalidate_dcache_range ( ( uint32_t ) qh ,
ALIGN_END_ADDR ( struct QH , qh , 1 ) ) ;
invalidate_dcache_range ( ( uint32_t ) qtd ,
ALIGN_END_ADDR ( struct qTD , qtd , 3 ) ) ;
ALIGN_END_ADDR ( struct qTD , qtd , QTD_COUNT ) ) ;
token = hc32_to_cpu ( vtd - > qt_token ) ;
if ( ! ( token & 0x80 ) )
if ( ! ( QT_TOKEN_GET_STATUS ( token ) & QT_TOKEN_STATUS_ACTIVE ) )
break ;
WATCHDOG_RESET ( ) ;
} while ( get_timer ( ts ) < timeout ) ;
@ -398,50 +396,50 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
ALIGN ( ( uint32_t ) buffer + length , ARCH_DMA_MINALIGN ) ) ;
/* Check that the TD processing happened */
if ( token & 0x80 ) {
if ( QT_TOKEN_GET_STATUS ( token ) & QT_TOKEN_STATUS_ACTIVE )
printf ( " EHCI timed out on TD - token=%#x \n " , token ) ;
}
/* Disable async schedule. */
cmd = ehci_readl ( & hcor - > or_usbcmd ) ;
cmd & = ~ CMD_ASE ;
ehci_writel ( & hcor - > or_usbcmd , cmd ) ;
ret = handshake ( ( uint32_t * ) & hcor - > or_usbsts , STD _ASS , 0 ,
ret = handshake ( ( uint32_t * ) & hcor - > or_usbsts , STS _ASS , 0 ,
100 * 1000 ) ;
if ( ret < 0 ) {
printf ( " EHCI fail timeout STD _ASS reset \n " ) ;
printf ( " EHCI fail timeout STS _ASS reset \n " ) ;
goto fail ;
}
token = hc32_to_cpu ( qh - > qh_overlay . qt_token ) ;
if ( ! ( token & 0x80 ) ) {
if ( ! ( QT_TOKEN_GET_STATUS ( token ) & QT_TOKEN_STATUS_ACTIVE ) ) {
debug ( " TOKEN=%#x \n " , token ) ;
switch ( token & 0xfc ) {
switch ( QT_TOKEN_GET_STATUS ( token ) &
~ ( QT_TOKEN_STATUS_SPLITXSTATE | QT_TOKEN_STATUS_PERR ) ) {
case 0 :
toggle = token > > 31 ;
toggle = QT_TOKEN_GET_DT ( token ) ;
usb_settoggle ( dev , usb_pipeendpoint ( pipe ) ,
usb_pipeout ( pipe ) , toggle ) ;
dev - > status = 0 ;
break ;
case 0x40 :
case QT_TOKEN_STATUS_HALTED :
dev - > status = USB_ST_STALLED ;
break ;
case 0xa0 :
case 0x20 :
case QT_TOKEN_STATUS_ACTIVE | QT_TOKEN_STATUS_DATBUFERR :
case QT_TOKEN_STATUS_DATBUFERR :
dev - > status = USB_ST_BUF_ERR ;
break ;
case 0x50 :
case 0x10 :
case QT_TOKEN_STATUS_HALTED | QT_TOKEN_STATUS_BABBLEDET :
case QT_TOKEN_STATUS_BABBLEDET :
dev - > status = USB_ST_BABBLE_DET ;
break ;
default :
dev - > status = USB_ST_CRC_ERR ;
if ( ( token & 0x40 ) = = 0x40 )
if ( QT_TOKEN_GET_STATUS ( token ) & QT_TOKEN_STATUS_HALTED )
dev - > status | = USB_ST_STALLED ;
break ;
}
dev - > act_len = length - ( ( token > > 16 ) & 0x7fff ) ;
dev - > act_len = length - QT_TOKEN_GET_TOTALBYTES ( token ) ;
} else {
dev - > act_len = 0 ;
debug ( " dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x \n " ,
@ -499,12 +497,14 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
case USB_DT_DEVICE :
debug ( " USB_DT_DEVICE request \n " ) ;
srcptr = & descriptor . device ;
srclen = 0x12 ;
srclen = descriptor . device . bLength ;
break ;
case USB_DT_CONFIG :
debug ( " USB_DT_CONFIG config \n " ) ;
srcptr = & descriptor . config ;
srclen = 0x19 ;
srclen = descriptor . config . bLength +
descriptor . interface . bLength +
descriptor . endpoint . bLength ;
break ;
case USB_DT_STRING :
debug ( " USB_DT_STRING config \n " ) ;
@ -539,7 +539,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
case USB_DT_HUB :
debug ( " USB_DT_HUB config \n " ) ;
srcptr = & descriptor . hub ;
srclen = 0x8 ;
srclen = descriptor . hub . bLength ;
break ;
default :
debug ( " unknown value %x \n " , le16_to_cpu ( req - > value ) ) ;
@ -577,13 +577,13 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
tmpbuf [ 1 ] | = USB_PORT_STAT_POWER > > 8 ;
if ( ehci_is_TDI ( ) ) {
switch ( ( reg > > 26 ) & 3 ) {
case 0 :
switch ( PORTSC_PSPD ( reg ) ) {
case PORTSC_PSPD_FS :
break ;
case 1 :
case PORTSC_PSPD_LS :
tmpbuf [ 1 ] | = USB_PORT_STAT_LOW_SPEED > > 8 ;
break ;
case 2 :
case PORTSC_PSPD_HS :
default :
tmpbuf [ 1 ] | = USB_PORT_STAT_HIGH_SPEED > > 8 ;
break ;
@ -729,26 +729,28 @@ int usb_lowlevel_init(void)
uint32_t reg ;
uint32_t cmd ;
if ( ehci_hcd_init ( ) ! = 0 )
if ( ehci_hcd_init ( ) )
return - 1 ;
/* EHCI spec section 4.1 */
if ( ehci_reset ( ) ! = 0 )
if ( ehci_reset ( ) )
return - 1 ;
# if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET)
if ( ehci_hcd_init ( ) ! = 0 )
if ( ehci_hcd_init ( ) )
return - 1 ;
# endif
/* Set head of reclaim list */
memset ( qh_list , 0 , sizeof ( * qh_list ) ) ;
qh_list - > qh_link = cpu_to_hc32 ( ( uint32_t ) qh_list | QH_LINK_TYPE_QH ) ;
qh_list - > qh_endpt1 = cpu_to_hc32 ( ( 1 < < 15 ) | ( USB_SPEED_HIGH < < 12 ) ) ;
qh_list - > qh_endpt1 = cpu_to_hc32 ( QH_ENDPT1_H ( 1 ) |
QH_ENDPT1_EPS ( USB_SPEED_HIGH ) ) ;
qh_list - > qh_curtd = cpu_to_hc32 ( QT_NEXT_TERMINATE ) ;
qh_list - > qh_overlay . qt_next = cpu_to_hc32 ( QT_NEXT_TERMINATE ) ;
qh_list - > qh_overlay . qt_altnext = cpu_to_hc32 ( QT_NEXT_TERMINATE ) ;
qh_list - > qh_overlay . qt_token = cpu_to_hc32 ( 0x40 ) ;
qh_list - > qh_overlay . qt_token =
cpu_to_hc32 ( QT_TOKEN_STATUS ( QT_TOKEN_STATUS_HALTED ) ) ;
reg = ehci_readl ( & hccr - > cr_hcsparams ) ;
descriptor . hub . bNbrPorts = HCS_N_PORTS ( reg ) ;
@ -808,7 +810,7 @@ submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
}
if ( usb_pipedevice ( pipe ) = = rootdev ) {
if ( rootdev = = 0 )
if ( ! rootdev )
dev - > speed = USB_SPEED_HIGH ;
return ehci_submit_root ( dev , pipe , buffer , length , setup ) ;
}