*/
{
union cvmx_usbcx_gusbcfg usbcx_gusbcfg;
+
usbcx_gusbcfg.u32 = __cvmx_usb_read_csr32(usb,
CVMX_USBCX_GUSBCFG(usb->index));
usbcx_gusbcfg.s.toutcal = 0;
*/
{
union cvmx_usbcx_hcfg usbcx_hcfg;
+
usbcx_hcfg.u32 = __cvmx_usb_read_csr32(usb,
CVMX_USBCX_HCFG(usb->index));
usbcx_hcfg.s.fslssupp = 0;
*/
{
union cvmx_usbcx_gnptxfsiz siz;
+
siz.u32 = __cvmx_usb_read_csr32(usb,
CVMX_USBCX_GNPTXFSIZ(usb->index));
siz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
*/
{
union cvmx_usbcx_hptxfsiz siz;
+
siz.u32 = __cvmx_usb_read_csr32(usb,
CVMX_USBCX_HPTXFSIZ(usb->index));
siz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
* Returns: A non-NULL value is a pipe. NULL means an error.
*/
static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct cvmx_usb_state *usb,
- int device_addr, int
- endpoint_num,
+ int device_addr,
+ int endpoint_num,
enum cvmx_usb_speed
device_speed,
int max_packet,
{
if (usb->periodic.head != usb->periodic.tail) {
union cvmx_usbcx_hptxsts tx_status;
+
tx_status.u32 = __cvmx_usb_read_csr32(usb,
CVMX_USBCX_HPTXSTS(usb->index));
if (__cvmx_usb_fill_tx_hw(usb, &usb->periodic,
if (usb->nonperiodic.head != usb->nonperiodic.tail) {
union cvmx_usbcx_gnptxsts tx_status;
+
tx_status.u32 = __cvmx_usb_read_csr32(usb,
CVMX_USBCX_GNPTXSTS(usb->index));
if (__cvmx_usb_fill_tx_hw(usb, &usb->nonperiodic,
/* Setup the locations the DMA engines use */
{
uint64_t dma_address = transaction->buffer + transaction->actual_bytes;
+
if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
dma_address = transaction->buffer + transaction->iso_packets[0].offset + transaction->actual_bytes;
__cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, dma_address);
*/
union cvmx_usbcx_hfnum hfnum = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index))};
union cvmx_usbcx_hfir hfir = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFIR(usb->index))};
+
if (hfnum.s.frrem < hfir.s.frint/4)
goto done;
}
/* Simply loop through and attempt to cancel each transaction */
list_for_each_entry_safe(transaction, next, &pipe->transactions, node) {
int result = cvmx_usb_cancel(usb, pipe, transaction);
+
if (unlikely(result != 0))
return result;
}
pipe->interval;
} else {
struct cvmx_usb_port_status port;
+
port = cvmx_usb_get_status(usb);
if (port.port_enabled) {
/* We'll retry the exact same transaction again */
* to clear this bit.
*/
union cvmx_usbcx_haint usbc_haint;
+
usbc_haint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINT(usb->index));
while (usbc_haint.u32) {
int channel;
enum cvmx_usb_speed speed;
int split_device = 0;
int split_port = 0;
+
switch (usb_pipetype(urb->pipe)) {
case PIPE_ISOCHRONOUS:
transfer_type = CVMX_USB_TRANSFER_ISOCHRONOUS;
* tree.
*/
struct usb_device *dev = urb->dev;
+
while (dev->parent) {
/*
* If our parent is high speed then he'll
struct octeon_hcd *priv = hcd_to_octeon(hcd);
struct cvmx_usb_pipe *pipe = ep->hcpriv;
unsigned long flags;
+
spin_lock_irqsave(&priv->lock, flags);
cvmx_usb_cancel_all(&priv->usb, pipe);
if (cvmx_usb_close_pipe(&priv->usb, pipe))
if (irq < 0) {
/* Defective device tree, but we know how to fix it. */
irq_hw_number_t hwirq = usb_num ? (1 << 6) + 17 : 56;
+
irq = irq_create_mapping(NULL, hwirq);
}