usb core fixes + ohci fixes + ohci dm support
Subsystems (4)
cover usb core fixes + ohci fixes + ohci dm support
Hi Marek and Simon,
Here is a series with a few usb core fixes, a lot of ohci fixes and ohci dm support (tested on sunxi). This series sits on top of the series adding companion controller support to the dm usb code and 2 ehci fixes which I send earlier today.
Regards,
Hans
PATCH 1/16 usb: Fix maxpacketsize for first descriptor read for low-speed usb devs
This fixes descriptor reading of lowspeed devices through ohci not working.
--- common/usb.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
common/usb.c +11 -6
@@ -948,13 +948,18 @@ static int usb_setup_descriptor(struct usb_device *dev, bool do_read)* send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is * only 18 bytes long, this will terminate with a short packet. But if * the maxpacket size is 8 or 16 the device may be waiting to transmit -* some more, or keeps on retransmitting the 8 byte header. */ +* some more, or keeps on retransmitting the 8 byte header. +*/ - dev->descriptor.bMaxPacketSize0 =64 ;/* Start off at 64 bytes */ -/* Default to 64 byte max packet size */ - dev->maxpacketsize =PACKET_SIZE_64 ; - dev->epmaxpacketin[0 ] =64 ; - dev->epmaxpacketout[0 ] =64 ; +if (dev->speed ==USB_SPEED_LOW ) { + dev->descriptor.bMaxPacketSize0 =8 ; + dev->maxpacketsize =PACKET_SIZE_8 ; + }else { + dev->descriptor.bMaxPacketSize0 =64 ; + dev->maxpacketsize =PACKET_SIZE_64 ; + } + dev->epmaxpacketin[0 ] = dev->descriptor.bMaxPacketSize0; + dev->epmaxpacketout[0 ] = dev->descriptor.bMaxPacketSize0;if (do_read) {int err;
Signature · 1 line
2.3.6
PATCH 1/16 usb: Fix maxpacketsize for first descriptor read for low-speed usb devs
Quoted 3 lines · Hans de Goede
This fixes descriptor reading of lowspeed devices through ohci not working.
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 1/16 usb: Fix maxpacketsize for first descriptor read for low-speed usb devs
Quoted 6 lines · Marek Vasut
Quoted 3 lines · Hans de Goede
This fixes descriptor reading of lowspeed devices through ohci not working.
Signed-off-by Hans de Goede <[email protected]>Acked-by Marek Vasut <[email protected]>
Applied to u-boot-dm, thanks!
PATCH 2/16 usb: Stop reset procedure when a dev is handed over to a companion hcd
In reply to Hans de GoedeDo not try to reset a device 5 times when it is handed over to a companion controller, also do not print an error when it has been handed over.
--- common/usb_hub.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
common/usb_hub.c +10 -2
@@ -168,8 +168,15 @@ int legacy_hub_port_reset(struct usb_device *dev, int port,debug ("%s: resetting port %d...\n" , __func__, port +1 );#endif for (tries =0 ; tries <MAX_TRIES ; tries++) { - +int prev_companion_device_count = usb_companion_device_count;usb_set_port_feature (dev, port +1 ,USB_PORT_FEAT_RESET ); +/* +* If companion device count changed, the device was handed +* over and we are done. +*/ +if (usb_companion_device_count != prev_companion_device_count) +return -ENXIO ; +mdelay (200 );if (usb_get_port_status (dev, port +1 , portsts) <0 ) {
@@ -269,7 +276,8 @@ int usb_hub_port_connect_change(struct usb_device *dev, int port)/* Reset the port */ ret =legacy_hub_port_reset (dev, port, &portstatus);if (ret <0 ) { -printf ("cannot reset port %i!?\n" , port +1 ); +if (ret != -ENXIO ) +printf ("cannot reset port %i!?\n" , port +1 );return ret; }
Signature · 1 line
2.3.6
PATCH 2/16 usb: Stop reset procedure when a dev is handed over to a companion hcd
Quoted 4 lines · Hans de Goede
Do not try to reset a device 5 times when it is handed over to a companion controller, also do not print an error when it has been handed over.
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 3/16 usb: ohci: Remove unused devgone global variable
In reply to Hans de Goededevgone is never assigned a value, so the one comparisson reading it will never be true, and devgone can be completely removed.
--- drivers/usb/host/ohci-hcd.c | 8 -------- 1 file changed, 8 deletions(-)
drivers/usb/host/ohci-hcd.c +0 -8
@@ -111,8 +111,6 @@ struct ohci_hcca ghcca[1];struct ohci_hcca *phcca;/* this allocates EDs for all possible endpoints */ struct ohci_device ohci_dev; -/* device which was disconnected */ -struct usb_device *devgone;static inline u32 roothub_a (struct ohci *hc) {return ohci_readl (&hc->regs->roothub.a); }
@@ -1380,12 +1378,6 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, urb->transfer_buffer_length = transfer_len; urb->interval = interval; -/* device pulled? Shortcut the action. */ -if (devgone == dev) { - dev->status =USB_ST_CRC_ERR ; -return 0 ; - } -#ifdef DEBUG urb->actual_length =0 ; pkt_print(urb, dev, pipe, buffer, transfer_len,
Signature · 1 line
2.3.6
PATCH 3/16 usb: ohci: Remove unused devgone global variable
Quoted 4 lines · Hans de Goede
devgone is never assigned a value, so the one comparisson reading it will never be true, and devgone can be completely removed.
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 3/16 usb: ohci: Remove unused devgone global variable
Quoted 7 lines · Marek Vasut
Quoted 4 lines · Hans de Goede
devgone is never assigned a value, so the one comparisson reading it will never be true, and devgone can be completely removed.
Signed-off-by Hans de Goede <[email protected]>Acked-by Marek Vasut <[email protected]>
Applied to u-boot-dm, thanks!
PATCH 4/16 usb: ohci: Pass around a pointer to ohci_t rather then accessing global vars
In reply to Hans de GoedeThis is a preparation patch for adding driver-model support.
--- drivers/usb/host/ohci-hcd.c | 124 +++++++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 60 deletions(-)
drivers/usb/host/ohci-hcd.c +64 -60
@@ -122,9 +122,9 @@ static inline u32 roothub_portstatus(struct ohci *hc, int i) {return ohci_readl (&hc->regs->roothub.portstatus[i]); }/* forward declaration */ -static int hc_interrupt (void ); -static void td_submit_job (struct usb_device *dev,unsigned long pipe, -void *buffer,int transfer_len, +static int hc_interrupt (ohci_t *ohci); +static void td_submit_job (ohci_t *ohci,struct usb_device *dev, +unsigned long pipe,void *buffer,int transfer_len,struct devrequest *setup,urb_priv_t *urb,int interval);
@@ -156,18 +156,18 @@ static void urb_free_priv(urb_priv_t *urb)/*-------------------------------------------------------------------------*/ #ifdef DEBUG -static int sohci_get_current_frame_number (struct usb_device *dev); +static int sohci_get_current_frame_number (ohci_t *ohci);/* debug| print the main components of an URB * small: 0) header + data packets 1) just header */ -static void pkt_print (urb_priv_t *purb,struct usb_device *dev, +static void pkt_print (ohci_t *ohci,urb_priv_t *purb,struct usb_device *dev,unsigned long pipe,void *buffer,int transfer_len,struct devrequest *setup,char *str,int small) { dbg("%s URB:[%4x] dev:%2lu,ep:%2lu-%c,type:%s,len:%d/%d stat:%#lx", str, - sohci_get_current_frame_number(dev), + sohci_get_current_frame_number(ohci), usb_pipedevice(pipe), usb_pipeendpoint(pipe), usb_pipeout(pipe)? 'O': 'I',
@@ -389,9 +389,8 @@ static void ohci_dump(ohci_t *controller, int verbose)/* get a transfer request */ -int sohci_submit_job (urb_priv_t *urb,struct devrequest *setup) +int sohci_submit_job (ohci_t *ohci,urb_priv_t *urb,struct devrequest *setup) { -ohci_t *ohci;ed_t *ed;urb_priv_t *purb_priv = urb;int i, size =0 ;
@@ -401,8 +400,6 @@ int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup)int transfer_len = urb->transfer_buffer_length;int interval = urb->interval; - ohci = &gohci; -/* when controller's hung, permit only roothub cleanup attempts * such as powering down ports */ if (ohci->disabled) {
@@ -471,7 +468,7 @@ int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup)ep_link (ohci, ed);/* fill the TDs and link it to the ed */ -td_submit_job (dev, pipe, buffer, transfer_len, +td_submit_job (ohci, dev, pipe, buffer, transfer_len, setup, purb_priv, interval);return 0 ;
@@ -493,7 +490,7 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)ohci_readl (®s->intrdisable);/* PCI posting flush */ } urb->actual_length =0 ; - td_submit_job( + td_submit_job( hc, urb->dev, urb->pipe, urb->transfer_buffer,
@@ -515,11 +512,8 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)#ifdef DEBUG /* tell us the current USB frame number */ - -static int sohci_get_current_frame_number (struct usb_device *usb_dev) +static int sohci_get_current_frame_number (ohci_t *ohci) { -ohci_t *ohci = &gohci; -return m16_swap (ohci->hcca->frame_no); }#endif
@@ -849,12 +843,11 @@ static void td_fill(ohci_t *ohci, unsigned int info,/* prepare all TDs of a transfer */ -static void td_submit_job (struct usb_device *dev,unsigned long pipe, -void *buffer,int transfer_len, +static void td_submit_job (ohci_t *ohci,struct usb_device *dev, +unsigned long pipe,void *buffer,int transfer_len,struct devrequest *setup,urb_priv_t *urb,int interval) { -ohci_t *ohci = &gohci;int data_len = transfer_len;void *data;int cnt =0 ;
@@ -1098,16 +1091,16 @@ static int dl_done_list(ohci_t *ohci)#define OK (x) len = (x); break#ifdef DEBUG #define WR_RH_STAT (x) {info("WR:status %#8x", (x)); ohci_writel((x), \ - &gohci.regs->roothub.status); } + &ohci->regs->roothub.status); }#define WR_RH_PORTSTAT (x) {info("WR:portstatus[%d] %#8x", wIndex-1, \ - (x)); ohci_writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); } + (x)); ohci_writel((x), &ohci->regs->roothub.portstatus[wIndex-1]); }#else -#define WR_RH_STAT (x) ohci_writel((x), &gohci.regs->roothub.status) +#define WR_RH_STAT (x) ohci_writel((x), &ohci->regs->roothub.status)#define WR_RH_PORTSTAT (x) ohci_writel((x), \ - &gohci.regs->roothub.portstatus[wIndex-1]) + &ohci->regs->roothub.portstatus[wIndex-1])#endif -#define RD_RH_STAT roothub_status(&gohci) -#define RD_RH_PORTSTAT roothub_portstatus(&gohci, wIndex-1) +#define RD_RH_STAT roothub_status(ohci) +#define RD_RH_PORTSTAT roothub_portstatus(ohci, wIndex-1)/* request to virtual root hub */
@@ -1135,8 +1128,9 @@ int rh_check_port_status(ohci_t *controller)return res; } -static int ohci_submit_rh_msg (struct usb_device *dev,unsigned long pipe, -void *buffer,int transfer_len,struct devrequest *cmd) +static int ohci_submit_rh_msg (ohci_t *ohci,struct usb_device *dev, +unsigned long pipe,void *buffer,int transfer_len, +struct devrequest *cmd) {void *data = buffer;int leni = transfer_len;
@@ -1149,7 +1143,7 @@ static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,ALLOC_ALIGN_BUFFER (__u8, databuf,16 ,sizeof (u32));#ifdef DEBUG -pkt_print (NULL , dev, pipe, buffer, transfer_len, +pkt_print (ohci,NULL , dev, pipe, buffer, transfer_len, cmd,"SUB(rh)" ,usb_pipein (pipe));#else mdelay (1 );
@@ -1243,7 +1237,7 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len,break ;case RH_SET_ADDRESS : - gohci.rh.devnum = wValue; + ohci->rh.devnum = wValue;OK (0 );case RH_GET_DESCRIPTOR :
@@ -1288,7 +1282,7 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len,case RH_GET_DESCRIPTOR |RH_CLASS : { -__u32 temp =roothub_a (&gohci); +__u32 temp =roothub_a (ohci); databuf[0 ] =9 ;/* min length; */ databuf[1 ] =0x29 ;
@@ -1307,7 +1301,7 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, databuf[4 ] =0 ; databuf[5 ] = (temp &RH_A_POTPGT ) >>24 ; databuf[6 ] =0 ; - temp =roothub_b (&gohci); + temp =roothub_b (ohci); databuf[7 ] = temp &RH_B_DR ;if (databuf[2 ] <7 ) { databuf[8 ] =0xff ;
@@ -1336,7 +1330,7 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, }#ifdef DEBUG -ohci_dump_roothub (&gohci,1 ); +ohci_dump_roothub (ohci,1 );#else mdelay (1 );#endif
@@ -1348,7 +1342,7 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, dev->status = stat;#ifdef DEBUG -pkt_print (NULL , dev, pipe, buffer, +pkt_print (ohci,NULL , dev, pipe, buffer, transfer_len, cmd,"RET(rh)" ,0 /*usb_pipein(pipe)*/ );#else mdelay (1 );
@@ -1361,8 +1355,9 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len,/* common code for handling submit messages - used for all but root hub */ /* accesses. */ -int submit_common_msg (struct usb_device *dev,unsigned long pipe,void *buffer, -int transfer_len,struct devrequest *setup,int interval) +static int submit_common_msg (ohci_t *ohci,struct usb_device *dev, +unsigned long pipe,void *buffer,int transfer_len, +struct devrequest *setup,int interval) {int stat =0 ;int maxsize =usb_maxpacket (dev, pipe);
@@ -1380,7 +1375,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,#ifdef DEBUG urb->actual_length =0 ; -pkt_print (urb, dev, pipe, buffer, transfer_len, +pkt_print (ohci, urb, dev, pipe, buffer, transfer_len, setup,"SUB" ,usb_pipein (pipe));#else mdelay (1 );
@@ -1391,14 +1386,14 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,return -1 ; } -if (sohci_submit_job (urb, setup) <0 ) { +if (sohci_submit_job (ohci, urb, setup) <0 ) {err ("sohci_submit_job failed" );return -1 ; }#if 0 mdelay (10 ); -/* ohci_dump_status(&gohci); */ +/* ohci_dump_status(ohci); */ #endif timeout =USB_TIMEOUT_MS (pipe);
@@ -1406,7 +1401,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,/* wait for it to complete */ for (;;) {/* check whether the controller is done */ - stat =hc_interrupt (); + stat =hc_interrupt (ohci);if (stat <0 ) { stat =USB_ST_CRC_ERR ;break ;
@@ -1444,7 +1439,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, dev->act_len = urb->actual_length;#ifdef DEBUG -pkt_print (urb, dev, pipe, buffer, transfer_len, +pkt_print (ohci, urb, dev, pipe, buffer, transfer_len, setup,"RET(ctlr)" ,usb_pipein (pipe));#else mdelay (1 );
@@ -1461,17 +1456,27 @@ int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len) {info ("submit_bulk_msg" ); -return submit_common_msg (dev, pipe, buffer, transfer_len,NULL ,0 ); +return submit_common_msg (&gohci, dev, pipe, buffer, transfer_len, +NULL ,0 ); +} + +int submit_int_msg (struct usb_device *dev,unsigned long pipe,void *buffer, +int transfer_len,int interval) +{ +info ("submit_int_msg" ); +return submit_common_msg (&gohci, dev, pipe, buffer, transfer_len,NULL , + interval); } -int submit_control_msg (struct usb_device *dev,unsigned long pipe,void *buffer, -int transfer_len,struct devrequest *setup) +static int _ohci_submit_control_msg (ohci_t *ohci,struct usb_device *dev, +unsigned long pipe,void *buffer,int transfer_len, +struct devrequest *setup) {int maxsize =usb_maxpacket (dev, pipe);info ("submit_control_msg" );#ifdef DEBUG -pkt_print (NULL , dev, pipe, buffer, transfer_len, +pkt_print (ohci,NULL , dev, pipe, buffer, transfer_len, setup,"SUB" ,usb_pipein (pipe));#else mdelay (1 );
@@ -1481,22 +1486,15 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, pipe);return -1 ; } -if (((pipe >>8 ) &0x7f ) == gohci.rh.devnum) { - gohci.rh.dev = dev; +if (((pipe >>8 ) &0x7f ) == ohci->rh.devnum) { + ohci->rh.dev = dev;/* root hub - redirect */ -return ohci_submit_rh_msg (dev, pipe, buffer, transfer_len, - setup); +return ohci_submit_rh_msg (ohci, dev, pipe, buffer, + transfer_len, setup); } -return submit_common_msg (dev, pipe, buffer, transfer_len, setup,0 ); -} - -int submit_int_msg (struct usb_device *dev,unsigned long pipe,void *buffer, -int transfer_len,int interval) -{ -info ("submit_int_msg" ); -return submit_common_msg (dev, pipe, buffer, transfer_len,NULL , - interval); +return submit_common_msg (ohci, dev, pipe, buffer, transfer_len, + setup,0 ); }/*-------------------------------------------------------------------------*
@@ -1640,9 +1638,8 @@ static int hc_start(ohci_t *ohci)/* an interrupt happens */ -static int hc_interrupt (void ) +static int hc_interrupt (ohci_t *ohci) { -ohci_t *ohci = &gohci;struct ohci_regs *regs = ohci->regs;int ints;int stat =-1 ;
@@ -1694,7 +1691,7 @@ static int hc_interrupt(void)mdelay (1 );ohci_writel (OHCI_INTR_WDH , ®s->intrdisable); (void )ohci_readl (®s->intrdisable);/* flush */ - stat =dl_done_list (&gohci); + stat =dl_done_list (ohci);ohci_writel (OHCI_INTR_WDH , ®s->intrenable); (void )ohci_readl (®s->intrdisable);/* flush */ }
@@ -1872,3 +1869,10 @@ int usb_lowlevel_stop(int index) ohci_inited =0 ;return 0 ; } + +int submit_control_msg (struct usb_device *dev,unsigned long pipe, +void *buffer,int transfer_len,struct devrequest *setup) +{ +return _ohci_submit_control_msg (&gohci, dev, pipe, buffer, + transfer_len, setup); +}
Signature · 1 line
2.3.6
PATCH 4/16 usb: ohci: Pass around a pointer to ohci_t rather then accessing global vars
Quoted 3 lines · Hans de Goede
This is a preparation patch for adding driver-model support.
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 4/16 usb: ohci: Pass around a pointer to ohci_t rather then accessing global vars
Quoted 6 lines · Marek Vasut
Quoted 3 lines · Hans de Goede
This is a preparation patch for adding driver-model support.
Signed-off-by Hans de Goede <[email protected]>Acked-by Marek Vasut <[email protected]>
Applied to u-boot-dm, thanks!
PATCH 5/16 usb: ohci: Move the ohci_dev struct to inside the main ohci struct
In reply to Hans de GoedeThis is a preparation patch for adding driver-model support.
Note we do keep ohci_dev as a separate struct so that we can later add support for interrupt-queues which requires allocating a separate ohci_dev per interrupt-queue.
--- drivers/usb/host/ohci-hcd.c | 22 ++++++++-------------- drivers/usb/host/ohci.h | 20 +++++++++++--------- 2 files changed, 19 insertions(+), 23 deletions(-)
drivers/usb/host/ohci-hcd.c +8 -14
@@ -109,8 +109,6 @@ static ohci_t gohci;struct ohci_hcca ghcca[1 ];/* a pointer to the aligned storage */ struct ohci_hcca *phcca; -/* this allocates EDs for all possible endpoints */ -struct ohci_device ohci_dev;static inline u32 roothub_a (struct ohci *hc) {return ohci_readl (&hc->regs->roothub.a); }
@@ -389,7 +387,8 @@ static void ohci_dump(ohci_t *controller, int verbose)/* get a transfer request */ -int sohci_submit_job (ohci_t *ohci,urb_priv_t *urb,struct devrequest *setup) +int sohci_submit_job (ohci_t *ohci,ohci_dev_t *ohci_dev,urb_priv_t *urb, +struct devrequest *setup) {ed_t *ed;urb_priv_t *purb_priv = urb;
@@ -412,7 +411,7 @@ int sohci_submit_job(ohci_t *ohci, urb_priv_t *urb, struct devrequest *setup) urb->finished =0 ;/* every endpoint has a ed, locate and fill it */ - ed =ep_add_ed (dev, pipe, interval,1 ); + ed =ep_add_ed (ohci_dev, dev, pipe, interval,1 );if (!ed) {err ("sohci_submit_job: ENOMEM" );return -1 ;
@@ -743,14 +742,14 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi)* info fields are setted anyway even though most of them should not * change */ -static ed_t *ep_add_ed (struct usb_device *usb_dev,unsigned long pipe, -int interval,int load) +static ed_t *ep_add_ed (ohci_dev_t *ohci_dev,struct usb_device *usb_dev, +unsigned long pipe,int interval,int load) {td_t *td;ed_t *ed_ret;volatile ed_t *ed; - ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) <<1 ) | + ed = ed_ret = &ohci_dev->ed[(usb_pipeendpoint (pipe) <<1 ) | (usb_pipecontrol (pipe)?0 :usb_pipeout (pipe))];if ((ed->state &ED_DEL ) || (ed->state &ED_URB_DEL )) {
@@ -766,7 +765,7 @@ static ed_t *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe, ed->hwHeadP = ed->hwTailP; ed->state =ED_UNLINK ; ed->type =usb_pipetype (pipe); - ohci_dev.ed_cnt++; + ohci_dev->ed_cnt++; } ed->hwINFO = m32_swap(usb_pipedevice(pipe)
@@ -1386,7 +1385,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,return -1 ; } -if (sohci_submit_job (ohci, urb, setup) <0 ) { +if (sohci_submit_job (ohci, &ohci->ohci_dev, urb, setup) <0 ) {err ("sohci_submit_job failed" );return -1 ; }
@@ -1763,11 +1762,6 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) } phcca = &ghcca[0 ];info ("aligned ghcca %p" , phcca); -memset (&ohci_dev,0 ,sizeof (struct ohci_device )); -if ((__u32)&ohci_dev.ed[0 ] &0x7 ) { -err ("EDs not aligned!!" ); -return -1 ; - }memset (gtd,0 ,sizeof (td_t) * (NUM_TD +1 ));if ((__u32 )gtd &0x7 ) {err ("TDs not aligned!!" );
drivers/usb/host/ohci.h +11 -9
@@ -408,6 +408,13 @@ typedef struct } urb_priv_t;#define URB_DEL 1 +#define NUM_EDS 8/* num of preallocated endpoint descriptors */ + +typedef struct ohci_device { +ed_t ed[NUM_EDS ]__aligned(16) ; +int ed_cnt; +}ohci_dev_t ; +/* * This is the full ohci controller description *
@@ -417,6 +424,8 @@ typedef struct typedef struct ohci { + /* this allocates EDs for all possible endpoints */ + struct ohci_device ohci_dev __aligned(16); struct ohci_hcca *hcca; /* hcca */ /*dma_addr_t hcca_dma;*/
@@ -439,19 +448,12 @@ typedef struct ohci {const char *slot_name; } ohci_t; -#define NUM_EDS 8/* num of preallocated endpoint descriptors */ - -struct ohci_device { -ed_t ed[NUM_EDS ]; -int ed_cnt; -}; -/* hcd */ /* endpoint */ static int ep_link (ohci_t * ohci,ed_t * ed);static int ep_unlink (ohci_t * ohci,ed_t * ed); -static ed_t *ep_add_ed (struct usb_device * usb_dev,unsigned long pipe, -int interval,int load); +static ed_t *ep_add_ed (ohci_dev_t *ohci_dev,struct usb_device *usb_dev, +unsigned long pipe,int interval,int load);/*-------------------------------------------------------------------------*/
Signature · 1 line
2.3.6
PATCH 5/16 usb: ohci: Move the ohci_dev struct to inside the main ohci struct
Quoted 7 lines · Hans de Goede
This is a preparation patch for adding driver-model support.
Note we do keep
ohci_devas a separate struct so that we can later add support for interrupt-queues which requires allocating a separateohci_devper interrupt-queue.Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 5/16 usb: ohci: Move the ohci_dev struct to inside the main ohci struct
Quoted 10 lines · Marek Vasut
Quoted 7 lines · Hans de Goede
This is a preparation patch for adding driver-model support.
Note we do keep
ohci_devas a separate struct so that we can later add support for interrupt-queues which requires allocating a separateohci_devper interrupt-queue.Signed-off-by Hans de Goede <[email protected]>Acked-by Marek Vasut <[email protected]>
Applied to u-boot-dm, thanks!
PATCH 6/16 usb: ohci: Move the td array struct to inside the ohci_dev struct
In reply to Hans de GoedeThis is a preparation patch for adding driver-model support.
--- drivers/usb/host/ohci-hcd.c | 10 ++-------- drivers/usb/host/ohci.h | 19 +++++++------------ 2 files changed, 9 insertions(+), 20 deletions(-)
drivers/usb/host/ohci-hcd.c +2 -8
@@ -447,7 +447,7 @@ int sohci_submit_job(ohci_t *ohci, ohci_dev_t *ohci_dev, urb_priv_t *urb,/* allocate the TDs */ /* note that td[0] was allocated in ep_add_ed */ for (i =0 ; i < size; i++) { - purb_priv->td[i] =td_alloc (dev); + purb_priv->td[i] =td_alloc (ohci_dev, dev);if (!purb_priv->td[i]) { purb_priv->length = i;urb_free_priv (purb_priv);
@@ -760,7 +760,7 @@ static ed_t *ep_add_ed(ohci_dev_t *ohci_dev, struct usb_device *usb_dev,if (ed->state ==ED_NEW ) {/* dummy td; end of td list for ed */ - td =td_alloc (usb_dev); + td =td_alloc (ohci_dev, usb_dev); ed->hwTailP =m32_swap ((unsigned long )td); ed->hwHeadP = ed->hwTailP; ed->state =ED_UNLINK ;
@@ -1762,12 +1762,6 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) } phcca = &ghcca[0 ];info ("aligned ghcca %p" , phcca); -memset (gtd,0 ,sizeof (td_t) * (NUM_TD +1 )); -if ((__u32 )gtd &0x7 ) { -err ("TDs not aligned!!" ); -return -1 ; - } - ptd = gtd; gohci.hcca = phcca;memset (phcca,0 ,sizeof (struct ohci_hcca ));
drivers/usb/host/ohci.h +7 -12
@@ -410,8 +410,11 @@ typedef struct#define NUM_EDS 8/* num of preallocated endpoint descriptors */ +#define NUM_TD 64/* we need more TDs than EDs */ +typedef struct ohci_device {ed_t ed[NUM_EDS ]__aligned(16) ; +td_t tds[NUM_TD ]__aligned(32) ;int ed_cnt; }ohci_dev_t ;
@@ -425,7 +428,7 @@ typedef struct ohci_device { typedef struct ohci { /* this allocates EDs for all possible endpoints */ - struct ohci_device ohci_dev __aligned(16); + struct ohci_device ohci_dev __aligned(32); struct ohci_hcca *hcca; /* hcca */ /*dma_addr_t hcca_dma;*/
@@ -457,17 +460,9 @@ static ed_t *ep_add_ed(ohci_dev_t *ohci_dev, struct usb_device *usb_dev,/*-------------------------------------------------------------------------*/ -/* we need more TDs than EDs */ -#define NUM_TD 64 - -/* +1 so we can align the storage */ -td_t gtd[NUM_TD +1 ]; -/* pointers to aligned storage */ -td_t *ptd; -/* TDs ... */ static inline struct td * -td_alloc (struct usb_device *usb_dev) +td_alloc (ohci_dev_t *ohci_dev,struct usb_device *usb_dev) {int i;struct td *td;
@@ -475,9 +470,9 @@ td_alloc (struct usb_device *usb_dev) td =NULL ;for (i =0 ; i <NUM_TD ; i++) { -if (ptd[i].usb_dev ==NULL ) +if (ohci_dev->tds[i].usb_dev ==NULL ) { - td = &ptd[i]; + td = &ohci_dev->tds[i]; td->usb_dev = usb_dev;break ; }
Signature · 1 line
2.3.6
PATCH 6/16 usb: ohci: Move the td array struct to inside the ohci_dev struct
Quoted 3 lines · Hans de Goede
This is a preparation patch for adding driver-model support.
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 6/16 usb: ohci: Move the td array struct to inside the ohci_dev struct
Quoted 6 lines · Marek Vasut
Quoted 3 lines · Hans de Goede
This is a preparation patch for adding driver-model support.
Signed-off-by Hans de Goede <[email protected]>Acked-by Marek Vasut <[email protected]>
Applied to u-boot-dm, thanks!
PATCH 7/16 usb: ohci: Remove unnecessary phcca variable
In reply to Hans de GoedeThis is a preparation patch for adding driver-model support.
--- drivers/usb/host/ohci-hcd.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/usb/host/ohci-hcd.c +3 -6
@@ -107,8 +107,6 @@ static struct pci_device_id ehci_pci_ids[] = {static ohci_t gohci;/* this must be aligned to a 256 byte boundary */ struct ohci_hcca ghcca[1 ]; -/* a pointer to the aligned storage */ -struct ohci_hcca *phcca;static inline u32 roothub_a (struct ohci *hc) {return ohci_readl (&hc->regs->roothub.a); }
@@ -1760,10 +1758,9 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)err ("HCCA not aligned!!" );return -1 ; } - phcca = &ghcca[0 ]; -info ("aligned ghcca %p" , phcca); - gohci.hcca = phcca; -memset (phcca,0 ,sizeof (struct ohci_hcca )); + gohci.hcca = &ghcca[0 ]; +info ("aligned ghcca %p" , gohci.hcca); +memset (gohci.hcca,0 ,sizeof (struct ohci_hcca )); gohci.disabled =1 ; gohci.sleeping =0 ;
Signature · 1 line
2.3.6
PATCH 7/16 usb: ohci: Remove unnecessary phcca variable
Quoted 3 lines · Hans de Goede
This is a preparation patch for adding driver-model support.
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 7/16 usb: ohci: Remove unnecessary phcca variable
Quoted 6 lines · Marek Vasut
Quoted 3 lines · Hans de Goede
This is a preparation patch for adding driver-model support.
Signed-off-by Hans de Goede <[email protected]>Acked-by Marek Vasut <[email protected]>
Applied to u-boot-dm, thanks!
PATCH 8/16 usb: ohci: Move static func and var declarations from ohci.h to ohci-hcd.c
In reply to Hans de GoedeNon static function and variable declarations do not belong in a .h file.
--- drivers/usb/host/ohci-hcd.c | 86 +++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/ohci.h | 93 --------------------------------------------- 2 files changed, 86 insertions(+), 93 deletions(-)
drivers/usb/host/ohci-hcd.c +86 -0
@@ -108,6 +108,61 @@ static ohci_t gohci;/* this must be aligned to a 256 byte boundary */ struct ohci_hcca ghcca[1 ]; +/* mapping of the OHCI CC status to error codes */ +static int cc_to_error[16 ] = { +/* No Error */ 0 , +/* CRC Error */ USB_ST_CRC_ERR , +/* Bit Stuff */ USB_ST_BIT_ERR , +/* Data Togg */ USB_ST_CRC_ERR , +/* Stall */ USB_ST_STALLED , +/* DevNotResp */ -1 , +/* PIDCheck */ USB_ST_BIT_ERR , +/* UnExpPID */ USB_ST_BIT_ERR , +/* DataOver */ USB_ST_BUF_ERR , +/* DataUnder */ USB_ST_BUF_ERR , +/* reservd */ -1 , +/* reservd */ -1 , +/* BufferOver */ USB_ST_BUF_ERR , +/* BuffUnder */ USB_ST_BUF_ERR , +/* Not Access */ -1 , +/* Not Access */ -1 +}; + +static const char *cc_to_string[16 ] = { +"No Error" , +"CRC: Last data packet from endpoint contained a CRC error." , +"BITSTUFFING: Last data packet from endpoint contained a bit " \ +"stuffing violation" , +"DATATOGGLEMISMATCH: Last packet from endpoint had data toggle PID\n" \ +"that did not match the expected value." , +"STALL: TD was moved to the Done Queue because the endpoint returned" \ +" a STALL PID" , +"DEVICENOTRESPONDING: Device did not respond to token (IN) or did\n" \ +"not provide a handshake (OUT)" , +"PIDCHECKFAILURE: Check bits on PID from endpoint failed on data PID\n" \ +"(IN) or handshake (OUT)" , +"UNEXPECTEDPID: Receive PID was not valid when encountered or PID\n" \ +"value is not defined." , +"DATAOVERRUN: The amount of data returned by the endpoint exceeded\n" \ +"either the size of the maximum data packet allowed\n" \ +"from the endpoint (found in MaximumPacketSize field\n" \ +"of ED) or the remaining buffer size." , +"DATAUNDERRUN: The endpoint returned less than MaximumPacketSize\n" \ +"and that amount was not sufficient to fill the\n" \ +"specified buffer" , +"reserved1" , +"reserved2" , +"BUFFEROVERRUN: During an IN, HC received data from endpoint faster\n" \ +"than it could be written to system memory" , +"BUFFERUNDERRUN: During an OUT, HC could not retrieve data from\n" \ +"system memory fast enough to keep up with data USB " \ +"data rate." , +"NOT ACCESSED: This code is set by software before the TD is placed" \ +"on a list to be processed by the HC.(1)" , +"NOT ACCESSED: This code is set by software before the TD is placed" \ +"on a list to be processed by the HC.(2)" , +}; +static inline u32 roothub_a (struct ohci *hc) {return ohci_readl (&hc->regs->roothub.a); }static inline u32 roothub_b (struct ohci *hc)
@@ -123,6 +178,37 @@ static void td_submit_job(ohci_t *ohci, struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval); +static int ep_link (ohci_t * ohci,ed_t * ed); +static int ep_unlink (ohci_t * ohci,ed_t * ed); +static ed_t *ep_add_ed (ohci_dev_t *ohci_dev,struct usb_device *usb_dev, +unsigned long pipe,int interval,int load); + +/*-------------------------------------------------------------------------*/ + +/* TDs ... */ +static struct td *td_alloc (ohci_dev_t *ohci_dev,struct usb_device *usb_dev) +{ +int i; +struct td *td; + + td =NULL ; +for (i =0 ; i <NUM_TD ; i++) + { +if (ohci_dev->tds[i].usb_dev ==NULL ) + { + td = &ohci_dev->tds[i]; + td->usb_dev = usb_dev; +break ; + } + } + +return td; +} + +static inline void ed_free (struct ed *ed) +{ + ed->usb_dev =NULL ; +}/*-------------------------------------------------------------------------* * URB support functions
drivers/usb/host/ohci.h +0 -93
103 lines not on this page · raw message
Signature · 1 line
2.3.6
PATCH 8/16 usb: ohci: Move static func and var declarations from ohci.h to ohci-hcd.c
Quoted 3 lines · Hans de Goede
Non static function and variable declarations do not belong in a .h file.
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 8/16 usb: ohci: Move static func and var declarations from ohci.h to ohci-hcd.c
Quoted 6 lines · Marek Vasut
Quoted 3 lines · Hans de Goede
Non static function and variable declarations do not belong in a .h file.
Signed-off-by Hans de Goede <[email protected]>Acked-by Marek Vasut <[email protected]>
Applied to u-boot-dm, thanks!
PATCH 9/16 usb: ohci: Fix ctrl in messages with a data-len of 0
In reply to Hans de GoedeFix taken from the Linux kernel ohci driver.
--- drivers/usb/host/ohci-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/ohci-hcd.c +1 -1
@@ -988,7 +988,7 @@ static void td_submit_job(ohci_t *ohci, struct usb_device *dev, }/* Status phase */ - info =usb_pipeout (pipe)? + info = (usb_pipeout (pipe) || data_len ==0 ) ?TD_CC |TD_DP_IN |TD_T_DATA1 :TD_CC |TD_DP_OUT |TD_T_DATA1 ;td_fill (ohci, info, data,0 , dev, cnt++, urb);
Signature · 1 line
2.3.6
PATCH 9/16 usb: ohci: Fix ctrl in messages with a data-len of 0
Quoted 1 line · Hans de Goede
Fix taken from the Linux kernel ohci driver.
Commit ID from Linux where this came from would be nice to have in the commit message, but that's a minor thing.
Quoted 1 line
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 9/16 usb: ohci: Fix ctrl in messages with a data-len of 0
Hi,
Quoted 5 lines · Marek Vasut
Quoted 1 line · Hans de Goede
Fix taken from the Linux kernel ohci driver.
Commit ID from Linux where this came from would be nice to have in the commit message, but that's a minor thing.
I did not take this from a specific commit, I noticed this when comparing bits of the u-boot and linux code.
Regards,
Hans
Quoted 8 lines
Quoted 2 lines
Signed-off-by Hans de Goede <[email protected]>Acked-by Marek Vasut <[email protected]>Best regards,
Marek Vasut
PATCH 9/16 usb: ohci: Fix ctrl in messages with a data-len of 0
Quoted 11 lines · Hans de Goede
Hi,
Quoted 5 lines · Marek Vasut
Quoted 1 line · Hans de Goede
Fix taken from the Linux kernel ohci driver.
Commit ID from Linux where this came from would be nice to have in the commit message, but that's a minor thing.
I did not take this from a specific commit, I noticed this when comparing bits of the u-boot and linux code.
Then that's also ok. Thanks !
Best regards,
Marek Vasut
PATCH 9/16 usb: ohci: Fix ctrl in messages with a data-len of 0
Quoted 7 lines · Marek Vasut
Quoted 6 lines · Hans de Goede
Hi,
Quoted 3 lines · Marek Vasut
Quoted 1 line · Hans de Goede
Fix taken from the Linux kernel ohci driver.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Commit ID from Linux where this came from would be nice to have in the commit message, but that's a minor thing.
I did not take this from a specific commit, I noticed this when comparing bits of the u-boot and linux code.
Then that's also ok. Thanks !
Applied to u-boot-dm, thanks!
PATCH 10/16 usb: ohci: Add proper cache flushing / invalidating for non cache coherent cpus
In reply to Hans de GoedeAdd proper cache flushing / invalidating for non cache coherent cpus, for now only enable this for new (driver-model) usb code to avoid regressions.
--- drivers/usb/host/ohci-hcd.c | 67 +++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/ohci.h | 22 +++++++++++---- 2 files changed, 84 insertions(+), 5 deletions(-)
drivers/usb/host/ohci-hcd.c +67 -0
@@ -103,6 +103,32 @@ static struct pci_device_id ehci_pci_ids[] = {# define m32_swap (x) cpu_to_le32(x)#endif /* CONFIG_SYS_OHCI_BE_CONTROLLER */ +#ifdef CONFIG_DM_USB +/* +* We really should do proper cache flushing everywhere, but for now we only +* do it for new (driver-model) usb code to avoid regressions. +*/ +#define flush_dcache_buffer (addr, size) \ + flush_dcache_range((unsigned long)(addr), \ + ALIGN((unsigned long)(addr) + size, ARCH_DMA_MINALIGN)) +#define invalidate_dcache_buffer (addr, size) \ + invalidate_dcache_range((unsigned long)(addr), \ + ALIGN((unsigned long)(addr) + size, ARCH_DMA_MINALIGN)) +#else +#define flush_dcache_buffer (addr, size) +#define invalidate_dcache_buffer (addr, size) +#endif + +/* Do not use sizeof(ed / td) as our ed / td structs contain extra members */ +#define flush_dcache_ed (addr) flush_dcache_buffer(addr, 16) +#define flush_dcache_td (addr) flush_dcache_buffer(addr, 16) +#define flush_dcache_iso_td (addr) flush_dcache_buffer(addr, 32) +#define flush_dcache_hcca (addr) flush_dcache_buffer(addr, 256) +#define invalidate_dcache_ed (addr) invalidate_dcache_buffer(addr, 16) +#define invalidate_dcache_td (addr) invalidate_dcache_buffer(addr, 16) +#define invalidate_dcache_iso_td (addr) invalidate_dcache_buffer(addr, 32) +#define invalidate_dcache_hcca (addr) invalidate_dcache_buffer(addr, 256) +/* global ohci_t */ static ohci_t gohci;/* this must be aligned to a 256 byte boundary */
@@ -293,9 +319,11 @@ void ep_print_int_eds(ohci_t *ohci, char *str) ed_p = &(ohci->hcca->int_table [i]);if (*ed_p ==0 )continue ; +invalidate_dcache_ed (ed_p);printf (__FILE__": %s branch int %2d(%2x):" , str, i, i);while (*ed_p !=0 && j--) {ed_t *ed = (ed_t *)m32_swap (ed_p); +invalidate_dcache_ed (ed);printf (" ed: %4x;" , ed->hwINFO); ed_p = &ed->hwNextED; }
@@ -326,6 +354,7 @@ static void maybe_print_eds(char *label, __u32 value)if (value) {dbg ("%s %08x" , label, value); +invalidate_dcache_ed (edp);dbg ("%08x" , edp->hwINFO);dbg ("%08x" , edp->hwTailP);dbg ("%08x" , edp->hwHeadP);
@@ -460,6 +489,7 @@ static void ohci_dump(ohci_t *controller, int verbose)ohci_dump_status (controller);if (verbose)ep_print_int_eds (controller,"hcca" ); +invalidate_dcache_hcca (controller->hcca);dbg ("hcca frame #%04x" , controller->hcca->frame_no);ohci_dump_roothub (controller,1 ); }
@@ -597,6 +627,7 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)/* tell us the current USB frame number */ static int sohci_get_current_frame_number (ohci_t *ohci) { +invalidate_dcache_hcca (ohci->hcca);return m16_swap (ohci->hcca->frame_no); }#endif
@@ -675,6 +706,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi)switch (ed->type) {case PIPE_CONTROL : ed->hwNextED =0 ; +flush_dcache_ed (ed);if (ohci->ed_controltail ==NULL )ohci_writel (ed, &ohci->regs->ed_controlhead);else
@@ -692,6 +724,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi)case PIPE_BULK : ed->hwNextED =0 ; +flush_dcache_ed (ed);if (ohci->ed_bulktail ==NULL )ohci_writel (ed, &ohci->regs->ed_bulkhead);else
@@ -724,7 +757,9 @@ static int ep_link(ohci_t *ohci, ed_t *edi) inter =ep_rev (6 , ((ed_t *)ed_p)->int_interval); ed->hwNextED = *ed_p; +flush_dcache_ed (ed); *ed_p =m32_swap ((unsigned long )ed); +flush_dcache_hcca (ohci->hcca); }break ; }
@@ -737,6 +772,8 @@ static int ep_link(ohci_t *ohci, ed_t *edi)static void periodic_unlink (struct ohci *ohci,volatile struct ed *ed,unsigned index,unsigned period) { +__maybe_unused unsigned long aligned_ed_p; +for (; index <NUM_INTS ; index += period) {__u32 *ed_p = &ohci->hcca->int_table [index];
@@ -745,6 +782,12 @@ static void periodic_unlink(struct ohci *ohci, volatile struct ed *ed,if (((struct ed *)m32_swap ((unsigned long )ed_p)) == ed) { *ed_p = ed->hwNextED; +#ifdef CONFIG_DM_USB + aligned_ed_p = (unsigned long )ed_p; + aligned_ed_p &= ~(ARCH_DMA_MINALIGN -1 ); +flush_dcache_range (aligned_ed_p, + aligned_ed_p +ARCH_DMA_MINALIGN ); +#endif break ; } ed_p = &(((struct ed *)
@@ -764,6 +807,7 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi)int i; ed->hwINFO |=m32_swap (OHCI_ED_SKIP ); +flush_dcache_ed (ed);switch (ed->type) {case PIPE_CONTROL :
@@ -777,6 +821,7 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi) &ohci->regs->ed_controlhead); }else { ed->ed_prev->hwNextED = ed->hwNextED; +flush_dcache_ed (ed->ed_prev); }if (ohci->ed_controltail == ed) { ohci->ed_controltail = ed->ed_prev;
@@ -797,6 +842,7 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi) &ohci->regs->ed_bulkhead); }else { ed->ed_prev->hwNextED = ed->hwNextED; +flush_dcache_ed (ed->ed_prev); }if (ohci->ed_bulktail == ed) { ohci->ed_bulktail = ed->ed_prev;
@@ -865,6 +911,8 @@ static ed_t *ep_add_ed(ohci_dev_t *ohci_dev, struct usb_device *usb_dev, ed->int_load = load; } +flush_dcache_ed (ed); +return ed_ret; }
@@ -890,6 +938,7 @@ static void td_fill(ohci_t *ohci, unsigned int info,/* use this td as the next dummy */ td_pt = urb_priv->td [index]; td_pt->hwNextTD =0 ; +flush_dcache_td (td_pt);/* fill the old dummy TD */ td = urb_priv->td [index] =
@@ -917,9 +966,11 @@ static void td_fill(ohci_t *ohci, unsigned int info, td->hwBE =0 ; td->hwNextTD =m32_swap ((unsigned long )td_pt); +flush_dcache_td (td);/* append to queue */ td->ed->hwTailP = td->hwNextTD; +flush_dcache_ed (td->ed); }/*-------------------------------------------------------------------------*/
@@ -937,6 +988,8 @@ static void td_submit_job(ohci_t *ohci, struct usb_device *dev,__u32 info =0 ;unsigned int toggle =0 ; +flush_dcache_buffer (buffer, data_len); +/* OHCI handles the DATA-toggles itself, we just use the USB-toggle * bits for reseting */ if (usb_gettoggle (dev,usb_pipeendpoint (pipe),usb_pipeout (pipe))) {
@@ -976,6 +1029,7 @@ static void td_submit_job(ohci_t *ohci, struct usb_device *dev,case PIPE_CONTROL :/* Setup phase */ info =TD_CC |TD_DP_SETUP |TD_T_DATA0 ; +flush_dcache_buffer (setup,8 );td_fill (ohci, info, setup,8 , dev, cnt++, urb);/* Optional Data phase */
@@ -1047,6 +1101,7 @@ static void check_status(td_t *td_list)if (cc) {err (" USB-error: %s (%x)" , cc_to_string[cc], cc); +invalidate_dcache_ed (td_list->ed);if (*phwHeadP &m32_swap (0x1 )) {if (lurb_priv && ((td_list->index +1 ) < urb_len)) {
@@ -1059,9 +1114,11 @@ static void check_status(td_t *td_list) td_list->index -1 ; }else *phwHeadP &=m32_swap (0xfffffff2 ); +flush_dcache_ed (td_list->ed); }#ifdef CONFIG_MPC5200 td_list->hwNextTD =0 ; +flush_dcache_td (td_list);#endif } }
@@ -1074,11 +1131,14 @@ static td_t *dl_reverse_done_list(ohci_t *ohci)td_t *td_rev =NULL ;td_t *td_list =NULL ; +invalidate_dcache_hcca (ohci->hcca); td_list_hc =m32_swap (ohci->hcca->done_head) &0xfffffff0 ; ohci->hcca->done_head =0 ; +flush_dcache_hcca (ohci->hcca);while (td_list_hc) { td_list = (td_t *)td_list_hc; +invalidate_dcache_td (td_list);check_status (td_list); td_list->next_dl_td = td_rev; td_rev = td_list;
@@ -1113,6 +1173,7 @@ static int takeback_td(ohci_t *ohci, td_t *td_list)urb_priv_t *lurb_priv;__u32 tdINFO, edHeadP, edTailP; +invalidate_dcache_td (td_list); tdINFO =m32_swap (td_list->hwINFO); ed = td_list->ed;
@@ -1138,6 +1199,7 @@ static int takeback_td(ohci_t *ohci, td_t *td_list) lurb_priv->td_cnt, lurb_priv->length);if (ed->state !=ED_NEW && (!usb_pipeint (lurb_priv->pipe))) { +invalidate_dcache_ed (ed); edHeadP =m32_swap (ed->hwHeadP) &0xfffffff0 ; edTailP =m32_swap (ed->hwTailP);
@@ -1521,6 +1583,9 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, dev->status = stat; dev->act_len = urb->actual_length; +if (usb_pipein (pipe) && dev->status ==0 && dev->act_len) +invalidate_dcache_buffer (buffer, dev->act_len); +#ifdef DEBUG pkt_print (ohci, urb, dev, pipe, buffer, transfer_len, setup,"RET(ctlr)" ,usb_pipein (pipe));
@@ -1727,6 +1792,8 @@ static int hc_interrupt(ohci_t *ohci)int ints;int stat =-1 ; +invalidate_dcache_hcca (ohci->hcca); +if ((ohci->hcca->done_head !=0 ) && !(m32_swap (ohci->hcca->done_head) &0x01 )) { ints =OHCI_INTR_WDH ;
drivers/usb/host/ohci.h +17 -5
@@ -18,6 +18,18 @@# define ohci_writel (a, b) (*((volatile u32 *)(b)) = ((volatile u32)a))#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */ +#if definedCONFIG_DM_USB &&ARCH_DMA_MINALIGN >16 +#define ED_ALIGNMENT ARCH_DMA_MINALIGN +#else +#define ED_ALIGNMENT 16 +#endif + +#if definedCONFIG_DM_USB &&ARCH_DMA_MINALIGN >32 +#define TD_ALIGNMENT ARCH_DMA_MINALIGN +#else +#define TD_ALIGNMENT 32 +#endif +/* functions for doing board or CPU specific setup/cleanup */ int usb_board_stop (void );
@@ -52,7 +64,7 @@ struct ed {struct usb_device *usb_dev;void *purb;__u32 unused[2 ]; -} __attribute__((aligned(16))); +} __attribute__((aligned(ED_ALIGNMENT)));typedef struct ed ed_t ;
@@ -112,7 +124,7 @@ struct td {__u32 data;__u32 unused2[2 ]; -} __attribute__((aligned(32))); +} __attribute__((aligned(TD_ALIGNMENT)));typedef struct td td_t ;#define OHCI_ED_SKIP (1 << 14)
@@ -356,8 +368,8 @@ typedef struct#define NUM_TD 64/* we need more TDs than EDs */ typedef struct ohci_device { -ed_t ed[NUM_EDS ]__aligned(16) ; -td_t tds[NUM_TD ]__aligned(32) ; +ed_t ed[NUM_EDS ]__aligned(ED_ALIGNMENT) ; +td_t tds[NUM_TD ]__aligned(TD_ALIGNMENT) ;int ed_cnt; }ohci_dev_t ;
@@ -371,7 +383,7 @@ typedef struct ohci_device { typedef struct ohci { /* this allocates EDs for all possible endpoints */ - struct ohci_device ohci_dev __aligned(32); + struct ohci_device ohci_dev __aligned(TD_ALIGNMENT); struct ohci_hcca *hcca; /* hcca */ /*dma_addr_t hcca_dma;*/
Signature · 1 line
2.3.6
PATCH 10/16 usb: ohci: Add proper cache flushing / invalidating for non cache coherent cpus
Quoted 4 lines · Hans de Goede
Add proper cache flushing / invalidating for non cache coherent cpus, for now only enable this for new (driver-model) usb code to avoid regressions.
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 10/16 usb: ohci: Add proper cache flushing / invalidating for non cache coherent cpus
Quoted 7 lines · Marek Vasut
Quoted 4 lines · Hans de Goede
Add proper cache flushing / invalidating for non cache coherent cpus, for now only enable this for new (driver-model) usb code to avoid regressions.
Signed-off-by Hans de Goede <[email protected]>Reviewed-by Marek Vasut <[email protected]>
Applied to u-boot-dm, thanks!
PATCH 11/16 usb: ohci: Don't log an error on interrupt packet timeout
In reply to Hans de GoedeInterrupts transfers timing out is normal, so do not log an error for this.
--- drivers/usb/host/ohci-hcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/host/ohci-hcd.c +2 -1
@@ -1572,7 +1572,8 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,dbg ("*" ); }else { -err ("CTL:TIMEOUT " ); +if (!usb_pipeint (pipe)) +err ("CTL:TIMEOUT " );dbg ("submit_common_msg: TO status %x\n" , stat); urb->finished =1 ; stat =USB_ST_CRC_ERR ;
Signature · 1 line
2.3.6
PATCH 11/16 usb: ohci: Don't log an error on interrupt packet timeout
Quoted 3 lines · Hans de Goede
Interrupts transfers timing out is normal, so do not log an error for this.
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 11/16 usb: ohci: Don't log an error on interrupt packet timeout
Quoted 6 lines · Marek Vasut
Quoted 3 lines · Hans de Goede
Interrupts transfers timing out is normal, so do not log an error for this.
Signed-off-by Hans de Goede <[email protected]>Acked-by Marek Vasut <[email protected]>
Applied to u-boot-dm, thanks!
PATCH 12/16 usb: ohci: Do not resubmit and leak urbs for interrupt packets
In reply to Hans de GoedeAuto-resubmission of interrupt packets does not match the u-boot usb model.
--- drivers/usb/host/ohci-hcd.c | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-)
drivers/usb/host/ohci-hcd.c +2 -39
@@ -587,40 +587,6 @@ int sohci_submit_job(ohci_t *ohci, ohci_dev_t *ohci_dev, urb_priv_t *urb,return 0 ; } -static inline int sohci_return_job (struct ohci *hc,urb_priv_t *urb) -{ -struct ohci_regs *regs = hc->regs; - -switch (usb_pipetype (urb->pipe)) { -case PIPE_INTERRUPT : -/* implicitly requeued */ -if (urb->dev->irq_handle && - (urb->dev->irq_act_len = urb->actual_length)) { -ohci_writel (OHCI_INTR_WDH , ®s->intrenable); -ohci_readl (®s->intrenable);/* PCI posting flush */ - urb->dev->irq_handle (urb->dev); -ohci_writel (OHCI_INTR_WDH , ®s->intrdisable); -ohci_readl (®s->intrdisable);/* PCI posting flush */ - } - urb->actual_length =0 ; -td_submit_job ( hc, - urb->dev, - urb->pipe, - urb->transfer_buffer, - urb->transfer_buffer_length, -NULL , - urb, - urb->interval); -break ; -case PIPE_CONTROL : -case PIPE_BULK : -break ; -default : -return 0 ; - } -return 1 ; -} -/*-------------------------------------------------------------------------*/ #ifdef DEBUG
@@ -1153,7 +1119,7 @@ static td_t *dl_reverse_done_list(ohci_t *ohci)static void finish_urb (ohci_t *ohci,urb_priv_t *urb,int status) {if ((status & (ED_OPER |ED_UNLINK )) && (urb->state !=URB_DEL )) - urb->finished =sohci_return_job (ohci, urb); + urb->finished =1 ;else dbg ("finish_urb: strange.., ED state %x, \n" , status); }
@@ -1593,10 +1559,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,#else mdelay (1 );#endif - -/* free TDs in urb_priv */ -if (!usb_pipeint (pipe)) -urb_free_priv (urb); +urb_free_priv (urb);return 0 ; }
Signature · 1 line
2.3.6
PATCH 12/16 usb: ohci: Do not resubmit and leak urbs for interrupt packets
Quoted 1 line · Hans de Goede
Auto-resubmission of interrupt packets does not match the u-boot usb model.
Just a bit more verbose commit message would be helpful, really ;-)
Quoted 1 line
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 13/16 usb: ohci: Remove unnecessary delays from hc_start and power power-on paths
In reply to Hans de GoedeThe common usb_hub code already waits a full second after powering up ports, so there is no need for additional delays inside the hcd code.
--- drivers/usb/host/ohci-hcd.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/usb/host/ohci-hcd.c +0 -4
@@ -1338,7 +1338,6 @@ pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len,OK (0 );case (RH_PORT_POWER ):WR_RH_PORTSTAT (RH_PS_PPS ); -mdelay (100 );OK (0 );case (RH_PORT_ENABLE ):/* BUG IN HUP CODE *********/ if (RD_RH_PORTSTAT &RH_PS_CCS )
@@ -1737,9 +1736,6 @@ static int hc_start(ohci_t *ohci)ohci_writel (RH_HS_LPSC , &ohci->regs->roothub.status);#endif /* OHCI_USE_NPS */ -/* POTPGT delay is bits 24-31, in 2 ms units. */ -mdelay ((roothub_a (ohci) >>23 ) &0x1fe ); -/* connect the virtual root hub */ ohci->rh.devnum =0 ;
Signature · 1 line
2.3.6
PATCH 13/16 usb: ohci: Remove unnecessary delays from hc_start and power power-on paths
Quoted 4 lines · Hans de Goede
The common
usb_hubcode already waits a full second after powering up ports, so there is no need for additional delays inside the hcd code.Signed-off-by Hans de Goede <[email protected]>
This makes a driver depend on the behavior of the subsystem, which might change though, right ? Won't this bite us in the future ?
Best regards,
Marek Vasut
PATCH 13/16 usb: ohci: Remove unnecessary delays from hc_start and power power-on paths
Hi,
Quoted 8 lines · Marek Vasut
Quoted 4 lines · Hans de Goede
The common
usb_hubcode already waits a full second after powering up ports, so there is no need for additional delays inside the hcd code.Signed-off-by Hans de Goede <[email protected]>This makes a driver depend on the behavior of the subsystem, which might change though, right ? Won't this bite us in the future ?
Well since the usb spec says that we must wait a minimum amount of time after port power on (exact time is in the hub descriptor) the subsys code better not change otherwise we would be violating the spec in the future, also note that we must not only do the wait for root ports but also for external hub ports, so we can really never drop the wait from the subsys code, and having a separate wait for just the root hub in the hcd code will only lead to doing the waiting twice.
I'll change the commit message to make this clear.
Regards,
Hans
PATCH 13/16 usb: ohci: Remove unnecessary delays from hc_start and power power-on paths
Quoted 1 line · Hans de Goede
Hi,
Hi!
Quoted 18 lines · Marek Vasut
Quoted 8 lines · Hans de Goede
Quoted 4 lines
The common
usb_hubcode already waits a full second after powering up ports, so there is no need for additional delays inside the hcd code.Signed-off-by Hans de Goede <[email protected]>This makes a driver depend on the behavior of the subsystem, which might change though, right ? Won't this bite us in the future ?
Well since the usb spec says that we must wait a minimum amount of time after port power on (exact time is in the hub descriptor) the subsys code better not change otherwise we would be violating the spec in the future, also note that we must not only do the wait for root ports but also for external hub ports, so we can really never drop the wait from the subsys code, and having a separate wait for just the root hub in the hcd code will only lead to doing the waiting twice.
Quoted 1 line
I'll change the commit message to make this clear.
Thanks!
Best regards,
Marek Vasut
PATCH 14/16 usb: ohci: Skip unnecessary mdelay(1) calls in various places
In reply to Hans de GoedeFor some reason the ohci code is full with:
pkt_print(...) mdelay(1);
AFAICT there is no reason for the mdelay(1) calls. This commit disables them when building the ohci code for new driver-model using boards. It leaves the mdelay(1) calls in place when building for older boards, so as to avoid causing any regressions there.
--- drivers/usb/host/ohci-hcd.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/usb/host/ohci-hcd.c +9 -7
@@ -1256,7 +1256,7 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev,#ifdef DEBUG pkt_print (ohci,NULL , dev, pipe, buffer, transfer_len, cmd,"SUB(rh)" ,usb_pipein (pipe)); -#else +#elif !definedCONFIG_DM_USB mdelay (1 );#endif if (usb_pipeint (pipe)) {
@@ -1441,7 +1441,7 @@ pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len,#ifdef DEBUG ohci_dump_roothub (ohci,1 ); -#else +#elif !definedCONFIG_DM_USB mdelay (1 );#endif
@@ -1454,7 +1454,7 @@ pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len,#ifdef DEBUG pkt_print (ohci,NULL , dev, pipe, buffer, transfer_len, cmd,"RET(rh)" ,0 /*usb_pipein(pipe)*/ ); -#else +#elif !definedCONFIG_DM_USB mdelay (1 );#endif
@@ -1487,7 +1487,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, urb->actual_length =0 ;pkt_print (ohci, urb, dev, pipe, buffer, transfer_len, setup,"SUB" ,usb_pipein (pipe)); -#else +#elif !definedCONFIG_DM_USB mdelay (1 );#endif if (!maxsize) {
@@ -1555,7 +1555,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,#ifdef DEBUG pkt_print (ohci, urb, dev, pipe, buffer, transfer_len, setup,"RET(ctlr)" ,usb_pipein (pipe)); -#else +#elif !definedCONFIG_DM_USB mdelay (1 );#endif urb_free_priv (urb);
@@ -1589,7 +1589,7 @@ static int _ohci_submit_control_msg(ohci_t *ohci, struct usb_device *dev,#ifdef DEBUG pkt_print (ohci,NULL , dev, pipe, buffer, transfer_len, setup,"SUB" ,usb_pipein (pipe)); -#else +#elif !definedCONFIG_DM_USB mdelay (1 );#endif if (!maxsize) {
@@ -1786,7 +1786,7 @@ static int hc_interrupt(ohci_t *ohci)#ifdef DEBUG ohci_dump (ohci,1 ); -#else +#elif !definedCONFIG_DM_USB mdelay (1 );#endif /* FIXME: be optimistic, hope that bug won't repeat often. */
@@ -1798,7 +1798,9 @@ static int hc_interrupt(ohci_t *ohci) }if (ints &OHCI_INTR_WDH ) { +#if !definedCONFIG_DM_USB mdelay (1 ); +#endif ohci_writel (OHCI_INTR_WDH , ®s->intrdisable); (void )ohci_readl (®s->intrdisable);/* flush */ stat =dl_done_list (ohci);
Signature · 1 line
2.3.6
PATCH 14/16 usb: ohci: Skip unnecessary mdelay(1) calls in various places
Quoted 11 lines · Hans de Goede
For some reason the ohci code is full with:
pkt_print(...) mdelay(1);AFAICT there is no reason for the mdelay(1) calls. This commit disables them when building the ohci code for new driver-model using boards. It leaves the mdelay(1) calls in place when building for older boards, so as to avoid causing any regressions there.
Signed-off-by Hans de Goede <[email protected]>
You might as well define a ohcidelay(1) function to avoid poluting the code with ifdefs .
Best regards,
Marek Vasut
PATCH 15/16 usb: ohci: Add dm support
In reply to Hans de GoedeAdd driver-model support to the ohci code.
--- drivers/usb/host/ohci-hcd.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/ohci.h | 7 ++++ 2 files changed, 91 insertions(+)
drivers/usb/host/ohci-hcd.c +84 -0
@@ -30,6 +30,8 @@#include <common.h> #include <asm/byteorder.h> +#include <dm.h> +#include <errno.h> #if defined(CONFIG_PCI_OHCI )# include <pci.h>
@@ -129,10 +131,12 @@ static struct pci_device_id ehci_pci_ids[] = {#define invalidate_dcache_iso_td (addr) invalidate_dcache_buffer(addr, 32)#define invalidate_dcache_hcca (addr) invalidate_dcache_buffer(addr, 256) +#ifndef CONFIG_DM_USB /* global ohci_t */ static ohci_t gohci;/* this must be aligned to a 256 byte boundary */ struct ohci_hcca ghcca[1 ]; +#endif /* mapping of the OHCI CC status to error codes */ static int cc_to_error[16 ] = {
@@ -1562,6 +1566,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,return 0 ; } +#ifndef CONFIG_DM_USB /* submit routines called from usb.c */ int submit_bulk_msg (struct usb_device *dev,unsigned long pipe,void *buffer,int transfer_len)
@@ -1578,6 +1583,7 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,return submit_common_msg (&gohci, dev, pipe, buffer, transfer_len,NULL , interval); } +#endif static int _ohci_submit_control_msg(ohci_t *ohci, struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len,
@@ -1830,6 +1836,8 @@ static int hc_interrupt(ohci_t *ohci)/*-------------------------------------------------------------------------*/ +#ifndef CONFIG_DM_USB +/*-------------------------------------------------------------------------*/ /* De-allocate all resources.. */
@@ -1976,3 +1984,79 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe,return _ohci_submit_control_msg (&gohci, dev, pipe, buffer, transfer_len, setup); } +#endif + +#ifdef CONFIG_DM_USB +static int ohci_submit_control_msg (struct udevice *dev,struct usb_device *udev, +unsigned long pipe,void *buffer,int length, +struct devrequest *setup) +{ +ohci_t *ohci =dev_get_priv (usb_get_bus (dev)); + +return _ohci_submit_control_msg (ohci, udev, pipe, buffer, + length, setup); +} + +static int ohci_submit_bulk_msg (struct udevice *dev,struct usb_device *udev, +unsigned long pipe,void *buffer,int length) +{ +ohci_t *ohci =dev_get_priv (usb_get_bus (dev)); + +return submit_common_msg (ohci, udev, pipe, buffer, length,NULL ,0 ); +} + +static int ohci_submit_int_msg (struct udevice *dev,struct usb_device *udev, +unsigned long pipe,void *buffer,int length, +int interval) +{ +ohci_t *ohci =dev_get_priv (usb_get_bus (dev)); + +return submit_common_msg (ohci, udev, pipe, buffer, length, +NULL , interval); +} + +int ohci_register (struct udevice *dev,struct ohci_regs *regs) +{ +struct usb_bus_priv *priv =dev_get_uclass_priv (dev); +ohci_t *ohci =dev_get_priv (dev); +u32 reg; + + priv->desc_before_addr = true; + + ohci->regs = regs; + ohci->hcca =memalign (256 ,sizeof (struct ohci_hcca )); +if (!ohci->hcca) +return -ENOMEM ; +memset (ohci->hcca,0 ,sizeof (struct ohci_hcca )); + +if (hc_reset (ohci) <0 ) +return -EIO ; + +if (hc_start (ohci) <0 ) +return -EIO ; + + reg =ohci_readl (®s->revision); +printf ("USB OHCI %x.%x\n" , (reg >>4 ) &0xf , reg &0xf ); + +return 0 ; +} + +int ohci_deregister (struct udevice *dev) +{ +ohci_t *ohci =dev_get_priv (dev); + +if (hc_reset (ohci) <0 ) +return -EIO ; + +/* TODO free hcca, and ohci ? */ + +return 0 ; +} + +struct dm_usb_ops ohci_usb_ops = { + .control = ohci_submit_control_msg, + .bulk = ohci_submit_bulk_msg, + .interrupt = ohci_submit_int_msg, +}; + +#endif
drivers/usb/host/ohci.h +7 -0
@@ -405,3 +405,10 @@ typedef struct ohci {const char *slot_name; } ohci_t; + +#ifdef CONFIG_DM_USB +extern struct dm_usb_ops ohci_usb_ops; + +int ohci_register (struct udevice *dev,struct ohci_regs *regs); +int ohci_deregister (struct udevice *dev); +#endif
Signature · 1 line
2.3.6
PATCH 15/16 usb: ohci: Add dm support
Quoted 3 lines · Hans de Goede
Add driver-model support to the ohci code.
Signed-off-by Hans de Goede <[email protected]>
I'll leave thorough review of this to Simon, but a brief skim tells me to add
The "todo" in ohci_deregister() is a bit concerning btw.
Best regards,
Marek Vasut
PATCH 16/16 sunxi: ohci: Add ohci usb host controller support
In reply to Hans de GoedeThis commit adds support for the OHCI companionen controller, which makes usb-1 devices directly plugged into to usb root port work.
Note for now this switches usb-keyboard support for sunxi back from int-queue support to the old interrupt polling method. Adding int-queue support to the ohci code and switching back to int-queue support is in the works.
--- arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 2 + drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-sunxi.c | 100 ++++++++++++++++++++++++++ include/configs/sunxi-common.h | 5 +- 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/host/ohci-sunxi.c
arch/arm/include/asm/arch-sunxi/clock_sun4i.h +2 -0
@@ -320,6 +320,8 @@ struct sunxi_ccm_reg {#define CCM_USB_CTRL_PHY0_RST (0x1 << 0)#define CCM_USB_CTRL_PHY1_RST (0x1 << 1)#define CCM_USB_CTRL_PHY2_RST (0x1 << 2) +#define CCM_USB_CTRL_OHCI0_CLK (0x1 << 6) +#define CCM_USB_CTRL_OHCI1_CLK (0x1 << 7)#define CCM_USB_CTRL_PHYGATE (0x1 << 8)/* These 3 are sun6i only, define them as 0 on sun4i */ #define CCM_USB_CTRL_PHY0_CLK 0
drivers/usb/host/Makefile +1 -0
@@ -19,6 +19,7 @@ obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o obj-$(CONFIG_USB_SL811HS) += sl811-hcd.o obj-$(CONFIG_USB_OHCI_S3C24XX) += ohci-s3c24xx.o obj-$(CONFIG_USB_OHCI_EP93XX) += ohci-ep93xx.o +obj-$(CONFIG_USB_OHCI_SUNXI) += ohci-sunxi.o # echi obj-$(CONFIG_USB_EHCI) += ehci-hcd.o
drivers/usb/host/ohci-sunxi.c new file +100 -0
100 lines not on this page · raw message
include/configs/sunxi-common.h +4 -1
@@ -363,6 +363,9 @@ extern int soft_i2c_gpio_scl;#endif #ifdef CONFIG_USB_EHCI +#define CONFIG_USB_OHCI_NEW +#define CONFIG_USB_OHCI_SUNXI +#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1#endif
@@ -380,7 +383,7 @@ extern int soft_i2c_gpio_scl;#define CONFIG_CONSOLE_MUX #define CONFIG_PREBOOT #define CONFIG_SYS_STDIO_DEREGISTER -#define CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE +#define CONFIG_SYS_USB_EVENT_POLL #endif #if !defined CONFIG_ENV_IS_IN_MMC && \
Signature · 1 line
2.3.6
PATCH 16/16 sunxi: ohci: Add ohci usb host controller support
Quoted 9 lines · Hans de Goede
This commit adds support for the OHCI companionen controller, which makes usb-1 devices directly plugged into to usb root port work.
Note for now this switches usb-keyboard support for sunxi back from int-queue support to the old interrupt polling method. Adding int-queue support to the ohci code and switching back to int-queue support is in the works.
Signed-off-by Hans de Goede <[email protected]>
Best regards,
Marek Vasut
PATCH 16/16 sunxi: ohci: Add ohci usb host controller support
Quoted 2 lines · Marek Vasut
Quoted 1 line · Hans de Goede
This commit adds support for the OHCI companionen controller, which makes
"companion"
Quoted 10 lines
Quoted 8 lines
usb-1 devices directly plugged into to usb root port work.
Note for now this switches usb-keyboard support for sunxi back from int-queue support to the old interrupt polling method. Adding int-queue support to the ohci code and switching back to int-queue support is in the works.
Signed-off-by Hans de Goede <[email protected]>Acked-by Marek Vasut <[email protected]>
Likewise,
cover usb core fixes + ohci fixes + ohci dm support
In reply to Hans de GoedeQuoted 1 line · Hans de Goede
Hi Marek and Simon,
Hi!
Quoted 4 lines
Here is a series with a few usb core fixes, a lot of ohci fixes and ohci dm support (tested on sunxi). This series sits on top of the series adding companion controller support to the dm usb code and 2 ehci fixes which I send earlier today.
Who do you what to pick this (and the EHCI DM one) please ?
Best regards,
Marek Vasut
cover usb core fixes + ohci fixes + ohci dm support
Hi Marek,
Quoted 11 lines · Marek Vasut
Quoted 1 line · Hans de Goede
Hi Marek and Simon,
Hi!
Quoted 4 lines
Here is a series with a few usb core fixes, a lot of ohci fixes and ohci dm support (tested on sunxi). This series sits on top of the series adding companion controller support to the dm usb code and 2 ehci fixes which I send earlier today.
Who do you what to pick this (and the EHCI DM one) please ?
I'm happy to pick it up with your ack. My perspective is mostly on driver model.
Regards,
Simon
cover usb core fixes + ohci fixes + ohci dm support
In reply to Marek VasutHi,
Quoted 11 lines · Marek Vasut
Quoted 1 line · Hans de Goede
Hi Marek and Simon,
Hi!
Quoted 4 lines
Here is a series with a few usb core fixes, a lot of ohci fixes and ohci dm support (tested on sunxi). This series sits on top of the series adding companion controller support to the dm usb code and 2 ehci fixes which I send earlier today.
Who do you what to pick this (and the EHCI DM one) please ?
Since this entire series only touches non dm code, except for the last one I was sortof expecting you to pick it up, but going through the dm tree, or through the sunxi tree for that matter is fine with me to.
Regards,
Hans
cover usb core fixes + ohci fixes + ohci dm support
Quoted 1 line · Hans de Goede
Hi,
Hi!
Quoted 11 lines · Marek Vasut
Quoted 10 lines · Hans de Goede
Quoted 1 line
Hi Marek and Simon,
Hi!
Quoted 4 lines
Here is a series with a few usb core fixes, a lot of ohci fixes and ohci dm support (tested on sunxi). This series sits on top of the series adding companion controller support to the dm usb code and 2 ehci fixes which I send earlier today.
Quoted 5 lines
Quoted 1 line
Who do you what to pick this (and the EHCI DM one) please ?
Since this entire series only touches non dm code, except for the last one I was sortof expecting you to pick it up, but going through the dm tree, or through the sunxi tree for that matter is fine with me to.
I don't have much which can interfere in the usb tree, so going through -dm is fine with me. Please take it through -dm .
Best regards,
Marek Vasut
cover usb core fixes + ohci fixes + ohci dm support
Quoted 16 lines · Marek Vasut
Quoted 1 line · Hans de Goede
Hi,
Hi!
Quoted 11 lines · Marek Vasut
Quoted 10 lines · Hans de Goede
Quoted 1 line
Hi Marek and Simon,
Hi!
Quoted 4 lines
Here is a series with a few usb core fixes, a lot of ohci fixes and ohci dm support (tested on sunxi). This series sits on top of the series adding companion controller support to the dm usb code and 2 ehci fixes which I send earlier today.
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Who do you what to pick this (and the EHCI DM one) please ?
Since this entire series only touches non dm code, except for the last one I was sortof expecting you to pick it up, but going through the dm tree, or through the sunxi tree for that matter is fine with me to.
I don't have much which can interfere in the usb tree, so going through -dm is fine with me. Please take it through -dm .
Ah, OK. Will await your review/ack.
Regards,
Simon
cover usb core fixes + ohci fixes + ohci dm support
Quoted 19 lines · Simon Glass
Quoted 18 lines · Marek Vasut
Quoted 1 line · Hans de Goede
Hi,
Hi!
Quoted 13 lines · Marek Vasut
Quoted 11 lines · Hans de Goede
Quoted 1 line
Hi Marek and Simon,
Hi!
Quoted 4 lines
Here is a series with a few usb core fixes, a lot of ohci fixes and ohci dm support (tested on sunxi). This series sits on top of the series adding companion controller support to the dm usb code and 2 ehci fixes which I send earlier today.
Who do you what to pick this (and the EHCI DM one) please ?
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
Since this entire series only touches non dm code, except for the last one I was sortof expecting you to pick it up, but going through the dm tree, or through the sunxi tree for that matter is fine with me to.
I don't have much which can interfere in the usb tree, so going through -dm is fine with me. Please take it through -dm .
Ah, OK. Will await your review/ack.
I'm just nagging a little here and there, otherwise the series looks good.
Best regards,
Marek Vasut
cover usb core fixes + ohci fixes + ohci dm support
In reply to Hans de GoedeHi Hans,
Quoted 19 lines · Hans de Goede
Hi,
Quoted 15 lines · Marek Vasut
Quoted 2 lines · Hans de Goede
Hi Marek and Simon,
Hi!
Quoted 5 lines
Here is a series with a few usb core fixes, a lot of ohci fixes and ohci dm support (tested on sunxi). This series sits on top of the series adding
companion controller support to the dm usb code and 2 ehci fixes which I send earlier today.
Quoted 6 lines
Quoted 1 line
Who do you what to pick this (and the EHCI DM one) please ?
Since this entire series only touches non dm code, except for the last one I was sortof expecting you to pick it up, but going through the dm tree, or through the sunxi tree for that matter is fine with me to.
Sounds good if that's OK with you Marek. Would like to see if this can go in soonish (maybe next week?).
Regards,
Simon