diff options
author | Tomasz Moń <desowin@gmail.com> | 2021-06-07 19:42:29 +0200 |
---|---|---|
committer | Tomasz Moń <desowin@gmail.com> | 2021-06-09 10:21:06 +0000 |
commit | efa173a9237278c9b98c5e7660103e66be541597 (patch) | |
tree | e0915ad0993670b88ab04da8efe790e1cc654dd5 | |
parent | 7f3d0ce814ef2f4edf5128f3a2970f3673b9353b (diff) | |
download | rockbox-efa173a9237278c9b98c5e7660103e66be541597.tar.gz rockbox-efa173a9237278c9b98c5e7660103e66be541597.zip |
Sansa Connect: Fix bulk transfers greater than 64 bytes
Correctly set endpoint maximum packet size so host will not consider
end of transfer after receiving first packet when transfer is larger
than 64 bytes (at High Speed the endpoint max packet size was set to
64 but according to descriptor it is 512).
Split DMA transfers up to CPPI_MAX_FRAG so we get single interrupt
after each call to tnetv_cppi_send().
Change-Id: I385b66bc5d71975a4e3e9167efac0b1334bd3ffc
-rw-r--r-- | firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c b/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c index 4fdf73cb50..bf1305824d 100644 --- a/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c +++ b/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c | |||
@@ -591,7 +591,7 @@ static int tnetv_ep_start_xmit(int epn, void *buf, int size) | |||
591 | { | 591 | { |
592 | dma_addr_t buffer = (dma_addr_t)buf; | 592 | dma_addr_t buffer = (dma_addr_t)buf; |
593 | commit_discard_dcache_range(buf, size); | 593 | commit_discard_dcache_range(buf, size); |
594 | if ((buffer >= CONFIG_SDRAM_START) && (buffer <= CONFIG_SDRAM_START + SDRAM_SIZE)) | 594 | if ((buffer >= CONFIG_SDRAM_START) && (buffer + size < CONFIG_SDRAM_START + SDRAM_SIZE)) |
595 | { | 595 | { |
596 | if (tnetv_cppi_send(&cppi, (epn - 1), buffer, size, 0)) | 596 | if (tnetv_cppi_send(&cppi, (epn - 1), buffer, size, 0)) |
597 | { | 597 | { |
@@ -675,6 +675,7 @@ static int tnetv_gadget_ep_enable(int epn, bool in) | |||
675 | { | 675 | { |
676 | UsbEpCfgCtrlType epCfg; | 676 | UsbEpCfgCtrlType epCfg; |
677 | int flags; | 677 | int flags; |
678 | enum usb_device_speed speed; | ||
678 | 679 | ||
679 | if (epn == 0 || epn >= USB_NUM_ENDPOINTS) | 680 | if (epn == 0 || epn >= USB_NUM_ENDPOINTS) |
680 | { | 681 | { |
@@ -684,7 +685,8 @@ static int tnetv_gadget_ep_enable(int epn, bool in) | |||
684 | flags = disable_irq_save(); | 685 | flags = disable_irq_save(); |
685 | 686 | ||
686 | /* set the maxpacket for this endpoint based on the current speed */ | 687 | /* set the maxpacket for this endpoint based on the current speed */ |
687 | ep_runtime[epn].max_packet_size = MAX_PACKET(epn, usb_drv_port_speed()); | 688 | speed = usb_drv_port_speed() ? USB_SPEED_HIGH : USB_SPEED_FULL; |
689 | ep_runtime[epn].max_packet_size = MAX_PACKET(epn, speed); | ||
688 | 690 | ||
689 | /* Enable the endpoint */ | 691 | /* Enable the endpoint */ |
690 | epCfg.val = tnetv_usb_reg_read(TNETV_USB_EPx_CFG(epn)); | 692 | epCfg.val = tnetv_usb_reg_read(TNETV_USB_EPx_CFG(epn)); |
@@ -819,8 +821,21 @@ static void ep_write(int epn) | |||
819 | } | 821 | } |
820 | else | 822 | else |
821 | { | 823 | { |
822 | /* DMA takes care of splitting the buffer into packets */ | 824 | /* DMA takes care of splitting the buffer into packets, |
823 | tx_size = ep->tx_remaining; | 825 | * but only up to CPPI_MAX_FRAG. After the data is sent |
826 | * a single interrupt is generated. There appears to be | ||
827 | * splitting code in the tnetv_cppi_send() function but | ||
828 | * it is somewhat suspicious (it doesn't seem like it | ||
829 | * will work with requests larger than 2*CPPI_MAX_FRAG). | ||
830 | * Also, if tnetv_cppi_send() does the splitting, we will | ||
831 | * get an interrupt after CPPI_MAX_FRAG but before the | ||
832 | * full request is sent. | ||
833 | * | ||
834 | * CPPI_MAX_FRAG is multiple of both 64 and 512 so we | ||
835 | * don't have to worry about this split prematurely ending | ||
836 | * the transfer. | ||
837 | */ | ||
838 | tx_size = MIN(CPPI_MAX_FRAG, ep->tx_remaining); | ||
824 | } | 839 | } |
825 | tnetv_ep_start_xmit(epn, ep->tx_buf, tx_size); | 840 | tnetv_ep_start_xmit(epn, ep->tx_buf, tx_size); |
826 | ep->tx_remaining -= tx_size; | 841 | ep->tx_remaining -= tx_size; |