summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Moń <desowin@gmail.com>2021-06-07 19:42:29 +0200
committerTomasz Moń <desowin@gmail.com>2021-06-09 10:21:06 +0000
commitefa173a9237278c9b98c5e7660103e66be541597 (patch)
treee0915ad0993670b88ab04da8efe790e1cc654dd5
parent7f3d0ce814ef2f4edf5128f3a2970f3673b9353b (diff)
downloadrockbox-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.c23
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;