dwc_otg.c (266012) | dwc_otg.c (266394) |
---|---|
1/* $FreeBSD: head/sys/dev/usb/controller/dwc_otg.c 266012 2014-05-14 11:32:15Z hselasky $ */ | 1/* $FreeBSD: head/sys/dev/usb/controller/dwc_otg.c 266394 2014-05-18 09:13:29Z hselasky $ */ |
2/*- 3 * Copyright (c) 2012 Hans Petter Selasky. All rights reserved. 4 * Copyright (c) 2010-2011 Aleksandr Rybalko. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright --- 74 unchanged lines hidden (view full) --- 84 85#include <dev/usb/controller/dwc_otg.h> 86#include <dev/usb/controller/dwc_otgreg.h> 87 88#define DWC_OTG_BUS2SC(bus) \ 89 ((struct dwc_otg_softc *)(((uint8_t *)(bus)) - \ 90 ((uint8_t *)&(((struct dwc_otg_softc *)0)->sc_bus)))) 91 | 2/*- 3 * Copyright (c) 2012 Hans Petter Selasky. All rights reserved. 4 * Copyright (c) 2010-2011 Aleksandr Rybalko. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright --- 74 unchanged lines hidden (view full) --- 84 85#include <dev/usb/controller/dwc_otg.h> 86#include <dev/usb/controller/dwc_otgreg.h> 87 88#define DWC_OTG_BUS2SC(bus) \ 89 ((struct dwc_otg_softc *)(((uint8_t *)(bus)) - \ 90 ((uint8_t *)&(((struct dwc_otg_softc *)0)->sc_bus)))) 91 |
92#define DWC_OTG_PC2SC(pc) \ 93 DWC_OTG_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus) 94 | |
95#define DWC_OTG_PC2UDEV(pc) \ 96 (USB_DMATAG_TO_XROOT((pc)->tag_parent)->udev) 97 98#define DWC_OTG_MSK_GINT_ENABLED \ 99 (GINTMSK_ENUMDONEMSK | \ 100 GINTMSK_USBRSTMSK | \ 101 GINTMSK_USBSUSPMSK | \ 102 GINTMSK_IEPINTMSK | \ 103 GINTMSK_SESSREQINTMSK | \ 104 GINTMSK_OTGINTMSK | \ 105 GINTMSK_PRTINTMSK) 106 | 92#define DWC_OTG_PC2UDEV(pc) \ 93 (USB_DMATAG_TO_XROOT((pc)->tag_parent)->udev) 94 95#define DWC_OTG_MSK_GINT_ENABLED \ 96 (GINTMSK_ENUMDONEMSK | \ 97 GINTMSK_USBRSTMSK | \ 98 GINTMSK_USBSUSPMSK | \ 99 GINTMSK_IEPINTMSK | \ 100 GINTMSK_SESSREQINTMSK | \ 101 GINTMSK_OTGINTMSK | \ 102 GINTMSK_PRTINTMSK) 103 |
104#define DWC_OTG_MSK_GINT_THREAD_IRQ \ 105 (GINTSTS_USBRST | GINTSTS_ENUMDONE | GINTSTS_PRTINT | \ 106 GINTSTS_WKUPINT | GINTSTS_USBSUSP | GINTMSK_OTGINTMSK | \ 107 GINTSTS_SESSREQINT) 108 |
|
107static int dwc_otg_use_hsic; 108 109static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW, 0, "USB DWC OTG"); 110 111SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, use_hsic, CTLFLAG_RD | CTLFLAG_TUN, 112 &dwc_otg_use_hsic, 0, "DWC OTG uses HSIC interface"); 113TUNABLE_INT("hw.usb.dwc_otg.use_hsic", &dwc_otg_use_hsic); 114 --- 470 unchanged lines hidden (view full) --- 585 hcint = DWC_OTG_READ_4(sc, DOTG_HCINT(x)); 586 DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), hcint); 587 588 /* clear buffered interrupts */ 589 sc->sc_chan_state[x].hcint = 0; 590} 591 592static uint8_t | 109static int dwc_otg_use_hsic; 110 111static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW, 0, "USB DWC OTG"); 112 113SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, use_hsic, CTLFLAG_RD | CTLFLAG_TUN, 114 &dwc_otg_use_hsic, 0, "DWC OTG uses HSIC interface"); 115TUNABLE_INT("hw.usb.dwc_otg.use_hsic", &dwc_otg_use_hsic); 116 --- 470 unchanged lines hidden (view full) --- 587 hcint = DWC_OTG_READ_4(sc, DOTG_HCINT(x)); 588 DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), hcint); 589 590 /* clear buffered interrupts */ 591 sc->sc_chan_state[x].hcint = 0; 592} 593 594static uint8_t |
593dwc_otg_host_channel_alloc(struct dwc_otg_td *td, uint8_t which, uint8_t is_out) | 595dwc_otg_host_channel_alloc(struct dwc_otg_softc *sc, struct dwc_otg_td *td, uint8_t which, uint8_t is_out) |
594{ | 596{ |
595 struct dwc_otg_softc *sc; | |
596 uint32_t tx_p_size; 597 uint32_t tx_np_size; 598 uint8_t x; 599 600 if (td->channel[which] < DWC_OTG_MAX_CHANNELS) 601 return (0); /* already allocated */ 602 603 /* check if device is suspended */ 604 if (DWC_OTG_PC2UDEV(td->pc)->flags.self_suspended != 0) 605 return (1); /* busy - cannot transfer data */ 606 | 597 uint32_t tx_p_size; 598 uint32_t tx_np_size; 599 uint8_t x; 600 601 if (td->channel[which] < DWC_OTG_MAX_CHANNELS) 602 return (0); /* already allocated */ 603 604 /* check if device is suspended */ 605 if (DWC_OTG_PC2UDEV(td->pc)->flags.self_suspended != 0) 606 return (1); /* busy - cannot transfer data */ 607 |
607 /* get pointer to softc */ 608 sc = DWC_OTG_PC2SC(td->pc); 609 | |
610 /* compute needed TX FIFO size */ 611 if (is_out != 0) { 612 if (td->ep_type == UE_INTERRUPT || 613 td->ep_type == UE_ISOCHRONOUS) { 614 tx_p_size = td->max_packet_size; 615 tx_np_size = 0; 616 if (td->hcsplt != 0 && tx_p_size > HCSPLT_XACTLEN_BURST) 617 tx_p_size = HCSPLT_XACTLEN_BURST; --- 47 unchanged lines hidden (view full) --- 665 return (0); /* allocated */ 666 } 667 /* wait a bit */ 668 dwc_otg_enable_sof_irq(sc); 669 return (1); /* busy */ 670} 671 672static void | 608 /* compute needed TX FIFO size */ 609 if (is_out != 0) { 610 if (td->ep_type == UE_INTERRUPT || 611 td->ep_type == UE_ISOCHRONOUS) { 612 tx_p_size = td->max_packet_size; 613 tx_np_size = 0; 614 if (td->hcsplt != 0 && tx_p_size > HCSPLT_XACTLEN_BURST) 615 tx_p_size = HCSPLT_XACTLEN_BURST; --- 47 unchanged lines hidden (view full) --- 663 return (0); /* allocated */ 664 } 665 /* wait a bit */ 666 dwc_otg_enable_sof_irq(sc); 667 return (1); /* busy */ 668} 669 670static void |
673dwc_otg_host_channel_free(struct dwc_otg_td *td, uint8_t which) | 671dwc_otg_host_channel_free(struct dwc_otg_softc *sc, struct dwc_otg_td *td, uint8_t which) |
674{ | 672{ |
675 struct dwc_otg_softc *sc; | |
676 uint8_t x; 677 678 if (td->channel[which] >= DWC_OTG_MAX_CHANNELS) 679 return; /* already freed */ 680 681 /* free channel */ 682 x = td->channel[which]; 683 td->channel[which] = DWC_OTG_MAX_CHANNELS; 684 685 DPRINTF("CH=%d\n", x); 686 | 673 uint8_t x; 674 675 if (td->channel[which] >= DWC_OTG_MAX_CHANNELS) 676 return; /* already freed */ 677 678 /* free channel */ 679 x = td->channel[which]; 680 td->channel[which] = DWC_OTG_MAX_CHANNELS; 681 682 DPRINTF("CH=%d\n", x); 683 |
687 /* get pointer to softc */ 688 sc = DWC_OTG_PC2SC(td->pc); 689 | |
690 /* 691 * We need to let programmed host channels run till complete 692 * else the host channel will stop functioning. Assume that 693 * after a fixed given amount of time the host channel is no 694 * longer doing any USB traffic: 695 */ 696 if (td->ep_type == UE_ISOCHRONOUS || td->ep_type == UE_INTERRUPT) { 697 /* double buffered */ --- 11 unchanged lines hidden (view full) --- 709 dwc_otg_common_rx_ack(sc); 710 } 711 712 /* clear active channel */ 713 sc->sc_active_rx_ep &= ~(1 << x); 714} 715 716static uint8_t | 684 /* 685 * We need to let programmed host channels run till complete 686 * else the host channel will stop functioning. Assume that 687 * after a fixed given amount of time the host channel is no 688 * longer doing any USB traffic: 689 */ 690 if (td->ep_type == UE_ISOCHRONOUS || td->ep_type == UE_INTERRUPT) { 691 /* double buffered */ --- 11 unchanged lines hidden (view full) --- 703 dwc_otg_common_rx_ack(sc); 704 } 705 706 /* clear active channel */ 707 sc->sc_active_rx_ep &= ~(1 << x); 708} 709 710static uint8_t |
717dwc_otg_host_setup_tx(struct dwc_otg_td *td) | 711dwc_otg_host_setup_tx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) |
718{ 719 struct usb_device_request req __aligned(4); | 712{ 713 struct usb_device_request req __aligned(4); |
720 struct dwc_otg_softc *sc; | |
721 uint32_t hcint; 722 uint32_t hcchar; 723 uint8_t delta; 724 | 714 uint32_t hcint; 715 uint32_t hcchar; 716 uint8_t delta; 717 |
725 /* get pointer to softc */ 726 sc = DWC_OTG_PC2SC(td->pc); 727 | |
728 if (td->channel[0] < DWC_OTG_MAX_CHANNELS) { 729 hcint = sc->sc_chan_state[td->channel[0]].hcint; 730 731 DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", 732 td->channel[0], td->state, hcint, 733 DWC_OTG_READ_4(sc, DOTG_HCCHAR(td->channel[0])), 734 DWC_OTG_READ_4(sc, DOTG_HCTSIZ(td->channel[0]))); 735 } else { --- 73 unchanged lines hidden (view full) --- 809 810 default: 811 break; 812 } 813 goto busy; 814 815send_pkt: 816 /* free existing channel, if any */ | 718 if (td->channel[0] < DWC_OTG_MAX_CHANNELS) { 719 hcint = sc->sc_chan_state[td->channel[0]].hcint; 720 721 DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", 722 td->channel[0], td->state, hcint, 723 DWC_OTG_READ_4(sc, DOTG_HCCHAR(td->channel[0])), 724 DWC_OTG_READ_4(sc, DOTG_HCTSIZ(td->channel[0]))); 725 } else { --- 73 unchanged lines hidden (view full) --- 799 800 default: 801 break; 802 } 803 goto busy; 804 805send_pkt: 806 /* free existing channel, if any */ |
817 dwc_otg_host_channel_free(td, 0); | 807 dwc_otg_host_channel_free(sc, td, 0); |
818 819 if (sizeof(req) != td->remainder) { 820 td->error_any = 1; 821 goto complete; 822 } 823 824 if (td->hcsplt != 0) { 825 delta = td->tt_start_slot - sc->sc_last_frame_num - 1; --- 6 unchanged lines hidden (view full) --- 832 /* missed it */ 833 td->tt_scheduled = 0; 834 td->state = DWC_CHAN_ST_START; 835 goto busy; 836 } 837 } 838 839 /* allocate a new channel */ | 808 809 if (sizeof(req) != td->remainder) { 810 td->error_any = 1; 811 goto complete; 812 } 813 814 if (td->hcsplt != 0) { 815 delta = td->tt_start_slot - sc->sc_last_frame_num - 1; --- 6 unchanged lines hidden (view full) --- 822 /* missed it */ 823 td->tt_scheduled = 0; 824 td->state = DWC_CHAN_ST_START; 825 goto busy; 826 } 827 } 828 829 /* allocate a new channel */ |
840 if (dwc_otg_host_channel_alloc(td, 0, 1)) { | 830 if (dwc_otg_host_channel_alloc(sc, td, 0, 1)) { |
841 td->state = DWC_CHAN_ST_START; 842 goto busy; 843 } 844 845 if (td->hcsplt != 0) { 846 td->hcsplt &= ~HCSPLT_COMPSPLT; 847 td->state = DWC_CHAN_ST_WAIT_S_ANE; 848 } else { --- 21 unchanged lines hidden (view full) --- 870 DOTG_DFIFO(td->channel[0]), (uint32_t *)&req, sizeof(req) / 4); 871 872 /* store number of bytes transmitted */ 873 td->tx_bytes = sizeof(req); 874 goto busy; 875 876send_cpkt: 877 /* free existing channel, if any */ | 831 td->state = DWC_CHAN_ST_START; 832 goto busy; 833 } 834 835 if (td->hcsplt != 0) { 836 td->hcsplt &= ~HCSPLT_COMPSPLT; 837 td->state = DWC_CHAN_ST_WAIT_S_ANE; 838 } else { --- 21 unchanged lines hidden (view full) --- 860 DOTG_DFIFO(td->channel[0]), (uint32_t *)&req, sizeof(req) / 4); 861 862 /* store number of bytes transmitted */ 863 td->tx_bytes = sizeof(req); 864 goto busy; 865 866send_cpkt: 867 /* free existing channel, if any */ |
878 dwc_otg_host_channel_free(td, 0); | 868 dwc_otg_host_channel_free(sc, td, 0); |
879 880 delta = td->tt_complete_slot - sc->sc_last_frame_num - 1; 881 if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { 882 td->state = DWC_CHAN_ST_WAIT_C_PKT; 883 goto busy; 884 } 885 delta = sc->sc_last_frame_num - td->tt_start_slot; 886 if (delta > DWC_OTG_TT_SLOT_MAX) { 887 /* we missed the service interval */ 888 if (td->ep_type != UE_ISOCHRONOUS) 889 td->error_any = 1; 890 goto complete; 891 } 892 /* allocate a new channel */ | 869 870 delta = td->tt_complete_slot - sc->sc_last_frame_num - 1; 871 if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { 872 td->state = DWC_CHAN_ST_WAIT_C_PKT; 873 goto busy; 874 } 875 delta = sc->sc_last_frame_num - td->tt_start_slot; 876 if (delta > DWC_OTG_TT_SLOT_MAX) { 877 /* we missed the service interval */ 878 if (td->ep_type != UE_ISOCHRONOUS) 879 td->error_any = 1; 880 goto complete; 881 } 882 /* allocate a new channel */ |
893 if (dwc_otg_host_channel_alloc(td, 0, 0)) { | 883 if (dwc_otg_host_channel_alloc(sc, td, 0, 0)) { |
894 td->state = DWC_CHAN_ST_WAIT_C_PKT; 895 goto busy; 896 } 897 898 /* wait until next slot before trying again */ 899 td->tt_complete_slot++; 900 901 td->hcsplt |= HCSPLT_COMPSPLT; --- 10 unchanged lines hidden (view full) --- 912 913 /* must enable channel before writing data to FIFO */ 914 DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel[0]), hcchar); 915 916busy: 917 return (1); /* busy */ 918 919complete: | 884 td->state = DWC_CHAN_ST_WAIT_C_PKT; 885 goto busy; 886 } 887 888 /* wait until next slot before trying again */ 889 td->tt_complete_slot++; 890 891 td->hcsplt |= HCSPLT_COMPSPLT; --- 10 unchanged lines hidden (view full) --- 902 903 /* must enable channel before writing data to FIFO */ 904 DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel[0]), hcchar); 905 906busy: 907 return (1); /* busy */ 908 909complete: |
920 dwc_otg_host_channel_free(td, 0); | 910 dwc_otg_host_channel_free(sc, td, 0); |
921 return (0); /* complete */ 922} 923 924static uint8_t | 911 return (0); /* complete */ 912} 913 914static uint8_t |
925dwc_otg_setup_rx(struct dwc_otg_td *td) | 915dwc_otg_setup_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) |
926{ | 916{ |
927 struct dwc_otg_softc *sc; | |
928 struct usb_device_request req __aligned(4); 929 uint32_t temp; 930 uint16_t count; 931 | 917 struct usb_device_request req __aligned(4); 918 uint32_t temp; 919 uint16_t count; 920 |
932 /* get pointer to softc */ 933 sc = DWC_OTG_PC2SC(td->pc); 934 | |
935 /* check endpoint status */ 936 937 if (sc->sc_last_rx_status == 0) 938 goto not_complete; 939 940 if (GRXSTSRD_CHNUM_GET(sc->sc_last_rx_status) != 0) 941 goto not_complete; 942 --- 124 unchanged lines hidden (view full) --- 1067 if (td->set_toggle) { 1068 td->set_toggle = 0; 1069 td->toggle = 1; 1070 } 1071 return (0); 1072} 1073 1074static uint8_t | 921 /* check endpoint status */ 922 923 if (sc->sc_last_rx_status == 0) 924 goto not_complete; 925 926 if (GRXSTSRD_CHNUM_GET(sc->sc_last_rx_status) != 0) 927 goto not_complete; 928 --- 124 unchanged lines hidden (view full) --- 1053 if (td->set_toggle) { 1054 td->set_toggle = 0; 1055 td->toggle = 1; 1056 } 1057 return (0); 1058} 1059 1060static uint8_t |
1075dwc_otg_host_rate_check(struct dwc_otg_td *td) | 1061dwc_otg_host_rate_check(struct dwc_otg_softc *sc, struct dwc_otg_td *td) |
1076{ | 1062{ |
1077 struct dwc_otg_softc *sc; 1078 1079 /* get pointer to softc */ 1080 sc = DWC_OTG_PC2SC(td->pc); 1081 | |
1082 if (td->ep_type == UE_ISOCHRONOUS) { 1083 /* non TT isochronous traffic */ 1084 if ((td->tmr_val != 0) || 1085 (sc->sc_last_frame_num & (td->tmr_res - 1))) { 1086 goto busy; 1087 } 1088 td->tmr_val = 1; /* executed */ 1089 td->toggle = 0; --- 9 unchanged lines hidden (view full) --- 1099 td->toggle = 1; 1100 } 1101 return (0); 1102busy: 1103 return (1); 1104} 1105 1106static uint8_t | 1063 if (td->ep_type == UE_ISOCHRONOUS) { 1064 /* non TT isochronous traffic */ 1065 if ((td->tmr_val != 0) || 1066 (sc->sc_last_frame_num & (td->tmr_res - 1))) { 1067 goto busy; 1068 } 1069 td->tmr_val = 1; /* executed */ 1070 td->toggle = 0; --- 9 unchanged lines hidden (view full) --- 1080 td->toggle = 1; 1081 } 1082 return (0); 1083busy: 1084 return (1); 1085} 1086 1087static uint8_t |
1107dwc_otg_host_data_rx(struct dwc_otg_td *td) | 1088dwc_otg_host_data_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) |
1108{ | 1089{ |
1109 struct dwc_otg_softc *sc; | |
1110 uint32_t hcint; 1111 uint32_t hcchar; 1112 uint32_t count; 1113 uint8_t delta; 1114 uint8_t channel; 1115 | 1090 uint32_t hcint; 1091 uint32_t hcchar; 1092 uint32_t count; 1093 uint8_t delta; 1094 uint8_t channel; 1095 |
1116 /* get pointer to softc */ 1117 sc = DWC_OTG_PC2SC(td->pc); | |
1118 channel = td->channel[td->tt_channel_tog]; 1119 1120 if (channel < DWC_OTG_MAX_CHANNELS) { 1121 hcint = sc->sc_chan_state[channel].hcint; 1122 1123 DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", 1124 channel, td->state, hcint, 1125 DWC_OTG_READ_4(sc, DOTG_HCCHAR(channel)), --- 197 unchanged lines hidden (view full) --- 1323 1324 default: 1325 break; 1326 } 1327 goto busy; 1328 1329receive_pkt: 1330 /* free existing channel, if any */ | 1096 channel = td->channel[td->tt_channel_tog]; 1097 1098 if (channel < DWC_OTG_MAX_CHANNELS) { 1099 hcint = sc->sc_chan_state[channel].hcint; 1100 1101 DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", 1102 channel, td->state, hcint, 1103 DWC_OTG_READ_4(sc, DOTG_HCCHAR(channel)), --- 197 unchanged lines hidden (view full) --- 1301 1302 default: 1303 break; 1304 } 1305 goto busy; 1306 1307receive_pkt: 1308 /* free existing channel, if any */ |
1331 dwc_otg_host_channel_free(td, td->tt_channel_tog); | 1309 dwc_otg_host_channel_free(sc, td, td->tt_channel_tog); |
1332 1333 if (td->hcsplt != 0) { 1334 delta = td->tt_complete_slot - sc->sc_last_frame_num - 1; 1335 if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { 1336 td->state = DWC_CHAN_ST_WAIT_C_PKT; 1337 goto busy; 1338 } 1339 delta = sc->sc_last_frame_num - td->tt_start_slot; 1340 if (delta > DWC_OTG_TT_SLOT_MAX) { 1341 /* we missed the service interval */ 1342 if (td->ep_type != UE_ISOCHRONOUS) 1343 td->error_any = 1; 1344 goto complete; 1345 } 1346 /* complete split */ 1347 td->hcsplt |= HCSPLT_COMPSPLT; 1348 } else if (td->tt_xactpos == HCSPLT_XACTPOS_BEGIN && | 1310 1311 if (td->hcsplt != 0) { 1312 delta = td->tt_complete_slot - sc->sc_last_frame_num - 1; 1313 if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { 1314 td->state = DWC_CHAN_ST_WAIT_C_PKT; 1315 goto busy; 1316 } 1317 delta = sc->sc_last_frame_num - td->tt_start_slot; 1318 if (delta > DWC_OTG_TT_SLOT_MAX) { 1319 /* we missed the service interval */ 1320 if (td->ep_type != UE_ISOCHRONOUS) 1321 td->error_any = 1; 1322 goto complete; 1323 } 1324 /* complete split */ 1325 td->hcsplt |= HCSPLT_COMPSPLT; 1326 } else if (td->tt_xactpos == HCSPLT_XACTPOS_BEGIN && |
1349 dwc_otg_host_rate_check(td)) { | 1327 dwc_otg_host_rate_check(sc, td)) { |
1350 td->state = DWC_CHAN_ST_WAIT_C_PKT; 1351 goto busy; 1352 } 1353 1354 /* allocate a new channel */ | 1328 td->state = DWC_CHAN_ST_WAIT_C_PKT; 1329 goto busy; 1330 } 1331 1332 /* allocate a new channel */ |
1355 if (dwc_otg_host_channel_alloc(td, td->tt_channel_tog, 0)) { | 1333 if (dwc_otg_host_channel_alloc(sc, td, td->tt_channel_tog, 0)) { |
1356 td->state = DWC_CHAN_ST_WAIT_C_PKT; 1357 goto busy; 1358 } 1359 1360 channel = td->channel[td->tt_channel_tog]; 1361 1362 /* set toggle, if any */ 1363 if (td->set_toggle) { --- 48 unchanged lines hidden (view full) --- 1412 td->tt_complete_slot++; 1413 } 1414 } 1415 } 1416 goto busy; 1417 1418receive_spkt: 1419 /* free existing channel(s), if any */ | 1334 td->state = DWC_CHAN_ST_WAIT_C_PKT; 1335 goto busy; 1336 } 1337 1338 channel = td->channel[td->tt_channel_tog]; 1339 1340 /* set toggle, if any */ 1341 if (td->set_toggle) { --- 48 unchanged lines hidden (view full) --- 1390 td->tt_complete_slot++; 1391 } 1392 } 1393 } 1394 goto busy; 1395 1396receive_spkt: 1397 /* free existing channel(s), if any */ |
1420 dwc_otg_host_channel_free(td, 0); 1421 dwc_otg_host_channel_free(td, 1); | 1398 dwc_otg_host_channel_free(sc, td, 0); 1399 dwc_otg_host_channel_free(sc, td, 1); |
1422 1423 delta = td->tt_start_slot - sc->sc_last_frame_num - 1; 1424 if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { 1425 td->state = DWC_CHAN_ST_START; 1426 goto busy; 1427 } 1428 delta = sc->sc_last_frame_num - td->tt_start_slot; 1429 if (delta > 5) { 1430 /* missed it */ 1431 td->tt_scheduled = 0; 1432 td->state = DWC_CHAN_ST_START; 1433 goto busy; 1434 } 1435 1436 /* allocate a new channel */ | 1400 1401 delta = td->tt_start_slot - sc->sc_last_frame_num - 1; 1402 if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { 1403 td->state = DWC_CHAN_ST_START; 1404 goto busy; 1405 } 1406 delta = sc->sc_last_frame_num - td->tt_start_slot; 1407 if (delta > 5) { 1408 /* missed it */ 1409 td->tt_scheduled = 0; 1410 td->state = DWC_CHAN_ST_START; 1411 goto busy; 1412 } 1413 1414 /* allocate a new channel */ |
1437 if (dwc_otg_host_channel_alloc(td, 0, 0)) { | 1415 if (dwc_otg_host_channel_alloc(sc, td, 0, 0)) { |
1438 td->state = DWC_CHAN_ST_START; 1439 goto busy; 1440 } 1441 1442 channel = td->channel[0]; 1443 1444 td->hcsplt &= ~HCSPLT_COMPSPLT; 1445 td->state = DWC_CHAN_ST_WAIT_S_ANE; --- 17 unchanged lines hidden (view full) --- 1463 hcchar |= HCCHAR_EPDIR_IN; 1464 1465 /* must enable channel before data can be received */ 1466 DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(channel), hcchar); 1467busy: 1468 return (1); /* busy */ 1469 1470complete: | 1416 td->state = DWC_CHAN_ST_START; 1417 goto busy; 1418 } 1419 1420 channel = td->channel[0]; 1421 1422 td->hcsplt &= ~HCSPLT_COMPSPLT; 1423 td->state = DWC_CHAN_ST_WAIT_S_ANE; --- 17 unchanged lines hidden (view full) --- 1441 hcchar |= HCCHAR_EPDIR_IN; 1442 1443 /* must enable channel before data can be received */ 1444 DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(channel), hcchar); 1445busy: 1446 return (1); /* busy */ 1447 1448complete: |
1471 dwc_otg_host_channel_free(td, 0); 1472 dwc_otg_host_channel_free(td, 1); | 1449 dwc_otg_host_channel_free(sc, td, 0); 1450 dwc_otg_host_channel_free(sc, td, 1); |
1473 return (0); /* complete */ 1474} 1475 1476static uint8_t | 1451 return (0); /* complete */ 1452} 1453 1454static uint8_t |
1477dwc_otg_data_rx(struct dwc_otg_td *td) | 1455dwc_otg_data_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) |
1478{ | 1456{ |
1479 struct dwc_otg_softc *sc; | |
1480 uint32_t temp; 1481 uint16_t count; 1482 uint8_t got_short; 1483 1484 got_short = 0; 1485 | 1457 uint32_t temp; 1458 uint16_t count; 1459 uint8_t got_short; 1460 1461 got_short = 0; 1462 |
1486 /* get pointer to softc */ 1487 sc = DWC_OTG_PC2SC(td->pc); 1488 | |
1489 /* check endpoint status */ 1490 if (sc->sc_last_rx_status == 0) 1491 goto not_complete; 1492 1493 if (GRXSTSRD_CHNUM_GET(sc->sc_last_rx_status) != td->ep_no) 1494 goto not_complete; 1495 1496 /* check for SETUP packet */ --- 85 unchanged lines hidden (view full) --- 1582 DXEPTSIZ_SET_NPKT(4) | 1583 DXEPTSIZ_SET_NBYTES(4 * 1584 ((td->max_packet_size + 3) & ~3))); 1585 } 1586 return (1); /* not complete */ 1587} 1588 1589static uint8_t | 1463 /* check endpoint status */ 1464 if (sc->sc_last_rx_status == 0) 1465 goto not_complete; 1466 1467 if (GRXSTSRD_CHNUM_GET(sc->sc_last_rx_status) != td->ep_no) 1468 goto not_complete; 1469 1470 /* check for SETUP packet */ --- 85 unchanged lines hidden (view full) --- 1556 DXEPTSIZ_SET_NPKT(4) | 1557 DXEPTSIZ_SET_NBYTES(4 * 1558 ((td->max_packet_size + 3) & ~3))); 1559 } 1560 return (1); /* not complete */ 1561} 1562 1563static uint8_t |
1590dwc_otg_host_data_tx(struct dwc_otg_td *td) | 1564dwc_otg_host_data_tx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) |
1591{ | 1565{ |
1592 struct dwc_otg_softc *sc; | |
1593 uint32_t count; 1594 uint32_t hcint; 1595 uint32_t hcchar; 1596 uint8_t delta; 1597 uint8_t channel; 1598 | 1566 uint32_t count; 1567 uint32_t hcint; 1568 uint32_t hcchar; 1569 uint8_t delta; 1570 uint8_t channel; 1571 |
1599 /* get pointer to softc */ 1600 sc = DWC_OTG_PC2SC(td->pc); | |
1601 channel = td->channel[td->tt_channel_tog]; 1602 1603 if (channel < DWC_OTG_MAX_CHANNELS) { 1604 hcint = sc->sc_chan_state[channel].hcint; 1605 1606 DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", 1607 channel, td->state, hcint, 1608 DWC_OTG_READ_4(sc, DOTG_HCCHAR(channel)), --- 109 unchanged lines hidden (view full) --- 1718 if (td->hcsplt != 0 || td->remainder == 0) 1719 goto complete; 1720 1721 /* check for next packet */ 1722 if (td->max_packet_count > 1) 1723 td->tt_xactpos++; 1724 1725 /* free existing channel, if any */ | 1572 channel = td->channel[td->tt_channel_tog]; 1573 1574 if (channel < DWC_OTG_MAX_CHANNELS) { 1575 hcint = sc->sc_chan_state[channel].hcint; 1576 1577 DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", 1578 channel, td->state, hcint, 1579 DWC_OTG_READ_4(sc, DOTG_HCCHAR(channel)), --- 109 unchanged lines hidden (view full) --- 1689 if (td->hcsplt != 0 || td->remainder == 0) 1690 goto complete; 1691 1692 /* check for next packet */ 1693 if (td->max_packet_count > 1) 1694 td->tt_xactpos++; 1695 1696 /* free existing channel, if any */ |
1726 dwc_otg_host_channel_free(td, td->tt_channel_tog); | 1697 dwc_otg_host_channel_free(sc, td, td->tt_channel_tog); |
1727 1728 td->state = DWC_CHAN_ST_TX_PKT_ISOC; 1729 1730 /* FALLTHROUGH */ 1731 1732 case DWC_CHAN_ST_TX_PKT_ISOC: | 1698 1699 td->state = DWC_CHAN_ST_TX_PKT_ISOC; 1700 1701 /* FALLTHROUGH */ 1702 1703 case DWC_CHAN_ST_TX_PKT_ISOC: |
1733 if (dwc_otg_host_channel_alloc(td, 0, 1)) | 1704 if (dwc_otg_host_channel_alloc(sc, td, 0, 1)) |
1734 break; 1735 channel = td->channel[0]; 1736 goto send_isoc_pkt; 1737 default: 1738 break; 1739 } 1740 goto busy; 1741 1742send_pkt: 1743 /* free existing channel(s), if any */ | 1705 break; 1706 channel = td->channel[0]; 1707 goto send_isoc_pkt; 1708 default: 1709 break; 1710 } 1711 goto busy; 1712 1713send_pkt: 1714 /* free existing channel(s), if any */ |
1744 dwc_otg_host_channel_free(td, 0); 1745 dwc_otg_host_channel_free(td, 1); | 1715 dwc_otg_host_channel_free(sc, td, 0); 1716 dwc_otg_host_channel_free(sc, td, 1); |
1746 1747 if (td->hcsplt != 0) { 1748 delta = td->tt_start_slot - sc->sc_last_frame_num - 1; 1749 if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { 1750 td->state = DWC_CHAN_ST_START; 1751 goto busy; 1752 } 1753 delta = sc->sc_last_frame_num - td->tt_start_slot; 1754 if (delta > 5) { 1755 /* missed it */ 1756 td->tt_scheduled = 0; 1757 td->state = DWC_CHAN_ST_START; 1758 goto busy; 1759 } | 1717 1718 if (td->hcsplt != 0) { 1719 delta = td->tt_start_slot - sc->sc_last_frame_num - 1; 1720 if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { 1721 td->state = DWC_CHAN_ST_START; 1722 goto busy; 1723 } 1724 delta = sc->sc_last_frame_num - td->tt_start_slot; 1725 if (delta > 5) { 1726 /* missed it */ 1727 td->tt_scheduled = 0; 1728 td->state = DWC_CHAN_ST_START; 1729 goto busy; 1730 } |
1760 } else if (dwc_otg_host_rate_check(td)) { | 1731 } else if (dwc_otg_host_rate_check(sc, td)) { |
1761 td->state = DWC_CHAN_ST_START; 1762 goto busy; 1763 } 1764 1765 /* allocate a new channel */ | 1732 td->state = DWC_CHAN_ST_START; 1733 goto busy; 1734 } 1735 1736 /* allocate a new channel */ |
1766 if (dwc_otg_host_channel_alloc(td, 0, 1)) { | 1737 if (dwc_otg_host_channel_alloc(sc, td, 0, 1)) { |
1767 td->state = DWC_CHAN_ST_START; 1768 goto busy; 1769 } 1770 1771 channel = td->channel[0]; 1772 1773 /* set toggle, if any */ 1774 if (td->set_toggle) { --- 132 unchanged lines hidden (view full) --- 1907 } 1908 1909 /* store number of bytes transmitted */ 1910 td->tx_bytes = count; 1911 goto busy; 1912 1913send_cpkt: 1914 /* free existing channel, if any */ | 1738 td->state = DWC_CHAN_ST_START; 1739 goto busy; 1740 } 1741 1742 channel = td->channel[0]; 1743 1744 /* set toggle, if any */ 1745 if (td->set_toggle) { --- 132 unchanged lines hidden (view full) --- 1878 } 1879 1880 /* store number of bytes transmitted */ 1881 td->tx_bytes = count; 1882 goto busy; 1883 1884send_cpkt: 1885 /* free existing channel, if any */ |
1915 dwc_otg_host_channel_free(td, td->tt_channel_tog); | 1886 dwc_otg_host_channel_free(sc, td, td->tt_channel_tog); |
1916 1917 delta = td->tt_complete_slot - sc->sc_last_frame_num - 1; 1918 if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { 1919 td->state = DWC_CHAN_ST_WAIT_C_PKT; 1920 goto busy; 1921 } 1922 delta = sc->sc_last_frame_num - td->tt_start_slot; 1923 if (delta > DWC_OTG_TT_SLOT_MAX) { 1924 /* we missed the service interval */ 1925 if (td->ep_type != UE_ISOCHRONOUS) 1926 td->error_any = 1; 1927 goto complete; 1928 } 1929 1930 /* allocate a new channel */ | 1887 1888 delta = td->tt_complete_slot - sc->sc_last_frame_num - 1; 1889 if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { 1890 td->state = DWC_CHAN_ST_WAIT_C_PKT; 1891 goto busy; 1892 } 1893 delta = sc->sc_last_frame_num - td->tt_start_slot; 1894 if (delta > DWC_OTG_TT_SLOT_MAX) { 1895 /* we missed the service interval */ 1896 if (td->ep_type != UE_ISOCHRONOUS) 1897 td->error_any = 1; 1898 goto complete; 1899 } 1900 1901 /* allocate a new channel */ |
1931 if (dwc_otg_host_channel_alloc(td, td->tt_channel_tog, 0)) { | 1902 if (dwc_otg_host_channel_alloc(sc, td, td->tt_channel_tog, 0)) { |
1932 td->state = DWC_CHAN_ST_WAIT_C_PKT; 1933 goto busy; 1934 } 1935 1936 channel = td->channel[td->tt_channel_tog]; 1937 1938 td->hcsplt |= HCSPLT_COMPSPLT; 1939 td->state = DWC_CHAN_ST_WAIT_C_ANE; --- 41 unchanged lines hidden (view full) --- 1981 td->tt_complete_slot++; 1982 } 1983 } 1984 } 1985busy: 1986 return (1); /* busy */ 1987 1988complete: | 1903 td->state = DWC_CHAN_ST_WAIT_C_PKT; 1904 goto busy; 1905 } 1906 1907 channel = td->channel[td->tt_channel_tog]; 1908 1909 td->hcsplt |= HCSPLT_COMPSPLT; 1910 td->state = DWC_CHAN_ST_WAIT_C_ANE; --- 41 unchanged lines hidden (view full) --- 1952 td->tt_complete_slot++; 1953 } 1954 } 1955 } 1956busy: 1957 return (1); /* busy */ 1958 1959complete: |
1989 dwc_otg_host_channel_free(td, 0); 1990 dwc_otg_host_channel_free(td, 1); | 1960 dwc_otg_host_channel_free(sc, td, 0); 1961 dwc_otg_host_channel_free(sc, td, 1); |
1991 return (0); /* complete */ 1992} 1993 1994static uint8_t | 1962 return (0); /* complete */ 1963} 1964 1965static uint8_t |
1995dwc_otg_data_tx(struct dwc_otg_td *td) | 1966dwc_otg_data_tx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) |
1996{ | 1967{ |
1997 struct dwc_otg_softc *sc; | |
1998 uint32_t max_buffer; 1999 uint32_t count; 2000 uint32_t fifo_left; 2001 uint32_t mpkt; 2002 uint32_t temp; 2003 uint8_t to; 2004 2005 to = 3; /* don't loop forever! */ 2006 | 1968 uint32_t max_buffer; 1969 uint32_t count; 1970 uint32_t fifo_left; 1971 uint32_t mpkt; 1972 uint32_t temp; 1973 uint8_t to; 1974 1975 to = 3; /* don't loop forever! */ 1976 |
2007 /* get pointer to softc */ 2008 sc = DWC_OTG_PC2SC(td->pc); 2009 | |
2010 max_buffer = sc->sc_hw_ep_profile[td->ep_no].max_buffer; 2011 2012repeat: 2013 /* check for for endpoint 0 data */ 2014 2015 temp = sc->sc_last_rx_status; 2016 2017 if ((td->ep_no == 0) && (temp != 0) && --- 161 unchanged lines hidden (view full) --- 2179 } 2180 goto repeat; 2181 2182not_complete: 2183 return (1); /* not complete */ 2184} 2185 2186static uint8_t | 1977 max_buffer = sc->sc_hw_ep_profile[td->ep_no].max_buffer; 1978 1979repeat: 1980 /* check for for endpoint 0 data */ 1981 1982 temp = sc->sc_last_rx_status; 1983 1984 if ((td->ep_no == 0) && (temp != 0) && --- 161 unchanged lines hidden (view full) --- 2146 } 2147 goto repeat; 2148 2149not_complete: 2150 return (1); /* not complete */ 2151} 2152 2153static uint8_t |
2187dwc_otg_data_tx_sync(struct dwc_otg_td *td) | 2154dwc_otg_data_tx_sync(struct dwc_otg_softc *sc, struct dwc_otg_td *td) |
2188{ | 2155{ |
2189 struct dwc_otg_softc *sc; | |
2190 uint32_t temp; 2191 | 2156 uint32_t temp; 2157 |
2192 /* get pointer to softc */ 2193 sc = DWC_OTG_PC2SC(td->pc); 2194 | |
2195 /* 2196 * If all packets are transferred we are complete: 2197 */ 2198 temp = DWC_OTG_READ_4(sc, DOTG_DIEPTSIZ(td->ep_no)); 2199 2200 /* check that all packets have been transferred */ 2201 if (DXEPTSIZ_GET_NPKT(temp) != 0) { 2202 DPRINTFN(5, "busy ep=%d\n", td->ep_no); --- 20 unchanged lines hidden (view full) --- 2223 } else { 2224 /* dump data - wrong direction */ 2225 dwc_otg_common_rx_ack(sc); 2226 } 2227 } 2228 return (1); /* not complete */ 2229} 2230 | 2158 /* 2159 * If all packets are transferred we are complete: 2160 */ 2161 temp = DWC_OTG_READ_4(sc, DOTG_DIEPTSIZ(td->ep_no)); 2162 2163 /* check that all packets have been transferred */ 2164 if (DXEPTSIZ_GET_NPKT(temp) != 0) { 2165 DPRINTFN(5, "busy ep=%d\n", td->ep_no); --- 20 unchanged lines hidden (view full) --- 2186 } else { 2187 /* dump data - wrong direction */ 2188 dwc_otg_common_rx_ack(sc); 2189 } 2190 } 2191 return (1); /* not complete */ 2192} 2193 |
2231static uint8_t 2232dwc_otg_xfer_do_fifo(struct usb_xfer *xfer) | 2194static void 2195dwc_otg_xfer_do_fifo(struct dwc_otg_softc *sc, struct usb_xfer *xfer) |
2233{ 2234 struct dwc_otg_td *td; 2235 uint8_t toggle; 2236 uint8_t tmr_val; 2237 uint8_t tmr_res; 2238 2239 DPRINTFN(9, "\n"); 2240 2241 td = xfer->td_transfer_cache; | 2196{ 2197 struct dwc_otg_td *td; 2198 uint8_t toggle; 2199 uint8_t tmr_val; 2200 uint8_t tmr_res; 2201 2202 DPRINTFN(9, "\n"); 2203 2204 td = xfer->td_transfer_cache; |
2205 if (td == NULL) 2206 return; |
|
2242 2243 while (1) { | 2207 2208 while (1) { |
2244 if ((td->func) (td)) { | 2209 if ((td->func) (sc, td)) { |
2245 /* operation in progress */ 2246 break; 2247 } 2248 if (((void *)td) == xfer->td_transfer_last) { 2249 goto done; 2250 } 2251 if (td->error_any) { 2252 goto done; --- 14 unchanged lines hidden (view full) --- 2267 tmr_val = td->tmr_val; 2268 toggle = td->toggle; 2269 td = td->obj_next; 2270 xfer->td_transfer_cache = td; 2271 td->toggle = toggle; /* transfer toggle */ 2272 td->tmr_res = tmr_res; 2273 td->tmr_val = tmr_val; 2274 } | 2210 /* operation in progress */ 2211 break; 2212 } 2213 if (((void *)td) == xfer->td_transfer_last) { 2214 goto done; 2215 } 2216 if (td->error_any) { 2217 goto done; --- 14 unchanged lines hidden (view full) --- 2232 tmr_val = td->tmr_val; 2233 toggle = td->toggle; 2234 td = td->obj_next; 2235 xfer->td_transfer_cache = td; 2236 td->toggle = toggle; /* transfer toggle */ 2237 td->tmr_res = tmr_res; 2238 td->tmr_val = tmr_val; 2239 } |
2275 return (1); /* not complete */ | 2240 return; |
2276 2277done: | 2241 2242done: |
2278 /* compute all actual lengths */ | 2243 xfer->td_transfer_cache = NULL; 2244 sc->sc_xfer_complete = 1; 2245} |
2279 | 2246 |
2280 dwc_otg_standard_done(xfer); 2281 return (0); /* complete */ | 2247static uint8_t 2248dwc_otg_xfer_do_complete(struct dwc_otg_softc *sc, struct usb_xfer *xfer) 2249{ 2250 struct dwc_otg_td *td; 2251 2252 DPRINTFN(9, "\n"); 2253 2254 td = xfer->td_transfer_cache; 2255 if (td == NULL) { 2256 /* compute all actual lengths */ 2257 dwc_otg_standard_done(xfer); 2258 return (1); 2259 } 2260 return (0); |
2282} 2283 2284static void 2285dwc_otg_timer(void *_sc) 2286{ 2287 struct dwc_otg_softc *sc = _sc; 2288 struct usb_xfer *xfer; 2289 struct dwc_otg_td *td; 2290 2291 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); 2292 2293 DPRINTF("\n"); 2294 | 2261} 2262 2263static void 2264dwc_otg_timer(void *_sc) 2265{ 2266 struct dwc_otg_softc *sc = _sc; 2267 struct usb_xfer *xfer; 2268 struct dwc_otg_td *td; 2269 2270 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); 2271 2272 DPRINTF("\n"); 2273 |
2274 USB_BUS_SPIN_LOCK(&sc->sc_bus); 2275 |
|
2295 /* increment timer value */ 2296 sc->sc_tmr_val++; 2297 2298 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { 2299 td = xfer->td_transfer_cache; 2300 if (td != NULL) { 2301 /* reset NAK counter */ 2302 td->did_nak = 0; 2303 } 2304 } 2305 2306 /* enable SOF interrupt, which will poll jobs */ 2307 dwc_otg_enable_sof_irq(sc); 2308 | 2276 /* increment timer value */ 2277 sc->sc_tmr_val++; 2278 2279 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { 2280 td = xfer->td_transfer_cache; 2281 if (td != NULL) { 2282 /* reset NAK counter */ 2283 td->did_nak = 0; 2284 } 2285 } 2286 2287 /* enable SOF interrupt, which will poll jobs */ 2288 dwc_otg_enable_sof_irq(sc); 2289 |
2290 USB_BUS_SPIN_UNLOCK(&sc->sc_bus); 2291 |
|
2309 if (sc->sc_timer_active) { 2310 /* restart timer */ 2311 usb_callout_reset(&sc->sc_timer, 2312 hz / (1000 / DWC_OTG_HOST_TIMER_RATE), 2313 &dwc_otg_timer, sc); 2314 } 2315} 2316 --- 299 unchanged lines hidden (view full) --- 2616 if (!(sc->sc_active_rx_ep & (1U << ep_no))) { 2617 dwc_otg_common_rx_ack(sc); 2618 goto repeat; 2619 } 2620 2621 got_rx_status = 1; 2622 } 2623 | 2292 if (sc->sc_timer_active) { 2293 /* restart timer */ 2294 usb_callout_reset(&sc->sc_timer, 2295 hz / (1000 / DWC_OTG_HOST_TIMER_RATE), 2296 &dwc_otg_timer, sc); 2297 } 2298} 2299 --- 299 unchanged lines hidden (view full) --- 2599 if (!(sc->sc_active_rx_ep & (1U << ep_no))) { 2600 dwc_otg_common_rx_ack(sc); 2601 goto repeat; 2602 } 2603 2604 got_rx_status = 1; 2605 } 2606 |
2624 /* scan for completion events first */ 2625 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { 2626 if (!dwc_otg_xfer_do_fifo(xfer)) { 2627 /* queue has been modified */ 2628 goto repeat; 2629 } 2630 } | 2607 /* execute FIFOs */ 2608 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) 2609 dwc_otg_xfer_do_fifo(sc, xfer); |
2631 2632 if (got_rx_status) { 2633 /* check if data was consumed */ 2634 if (sc->sc_last_rx_status == 0) 2635 goto repeat; 2636 2637 /* disable RX FIFO level interrupt */ 2638 sc->sc_irq_mask &= ~GINTMSK_RXFLVLMSK; 2639 DWC_OTG_WRITE_4(sc, DOTG_GINTMSK, sc->sc_irq_mask); 2640 } 2641 | 2610 2611 if (got_rx_status) { 2612 /* check if data was consumed */ 2613 if (sc->sc_last_rx_status == 0) 2614 goto repeat; 2615 2616 /* disable RX FIFO level interrupt */ 2617 sc->sc_irq_mask &= ~GINTMSK_RXFLVLMSK; 2618 DWC_OTG_WRITE_4(sc, DOTG_GINTMSK, sc->sc_irq_mask); 2619 } 2620 |
2642 if (sc->sc_flags.status_device_mode == 0) { | 2621 if (sc->sc_flags.status_device_mode == 0 && sc->sc_xfer_complete == 0) { |
2643 /* update host transfer schedule, so that new transfers can be issued */ 2644 if (dwc_otg_update_host_transfer_schedule(sc)) 2645 goto repeat; 2646 } 2647} 2648 2649static void | 2622 /* update host transfer schedule, so that new transfers can be issued */ 2623 if (dwc_otg_update_host_transfer_schedule(sc)) 2624 goto repeat; 2625 } 2626} 2627 2628static void |
2629dwc_otg_interrupt_complete(struct dwc_otg_softc *sc) 2630{ 2631 struct usb_xfer *xfer; 2632repeat: 2633 /* scan for completion events */ 2634 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { 2635 if (dwc_otg_xfer_do_complete(sc, xfer)) 2636 goto repeat; 2637 } 2638} 2639 2640static void |
|
2650dwc_otg_vbus_interrupt(struct dwc_otg_softc *sc, uint8_t is_on) 2651{ 2652 DPRINTFN(5, "vbus = %u\n", is_on); 2653 2654 /* 2655 * If the USB host mode is forced, then assume VBUS is always 2656 * present else rely on the input to this function: 2657 */ --- 16 unchanged lines hidden (view full) --- 2674 2675 /* complete root HUB interrupt endpoint */ 2676 2677 dwc_otg_root_intr(sc); 2678 } 2679 } 2680} 2681 | 2641dwc_otg_vbus_interrupt(struct dwc_otg_softc *sc, uint8_t is_on) 2642{ 2643 DPRINTFN(5, "vbus = %u\n", is_on); 2644 2645 /* 2646 * If the USB host mode is forced, then assume VBUS is always 2647 * present else rely on the input to this function: 2648 */ --- 16 unchanged lines hidden (view full) --- 2665 2666 /* complete root HUB interrupt endpoint */ 2667 2668 dwc_otg_root_intr(sc); 2669 } 2670 } 2671} 2672 |
2673int 2674dwc_otg_filter_interrupt(void *arg) 2675{ 2676 struct dwc_otg_softc *sc = arg; 2677 int retval = FILTER_HANDLED; 2678 uint32_t status; 2679 2680 /* read and clear interrupt status */ 2681 status = DWC_OTG_READ_4(sc, DOTG_GINTSTS); 2682 2683 /* clear interrupts we are handling here */ 2684 DWC_OTG_WRITE_4(sc, DOTG_GINTSTS, status & ~DWC_OTG_MSK_GINT_THREAD_IRQ); 2685 2686 /* check for USB state change interrupts */ 2687 if ((status & DWC_OTG_MSK_GINT_THREAD_IRQ) != 0) 2688 retval = FILTER_SCHEDULE_THREAD; 2689 2690 /* clear all IN endpoint interrupts */ 2691 if (status & GINTSTS_IEPINT) { 2692 uint32_t temp; 2693 uint8_t x; 2694 2695 for (x = 0; x != sc->sc_dev_in_ep_max; x++) { 2696 temp = DWC_OTG_READ_4(sc, DOTG_DIEPINT(x)); 2697 if (temp & DIEPMSK_XFERCOMPLMSK) { 2698 DWC_OTG_WRITE_4(sc, DOTG_DIEPINT(x), 2699 DIEPMSK_XFERCOMPLMSK); 2700 } 2701 } 2702 } 2703 2704 USB_BUS_SPIN_LOCK(&sc->sc_bus); 2705 2706 /* poll FIFOs, if any */ 2707 dwc_otg_interrupt_poll(sc); 2708 2709 if (sc->sc_xfer_complete != 0) 2710 retval = FILTER_SCHEDULE_THREAD; 2711 2712 USB_BUS_SPIN_UNLOCK(&sc->sc_bus); 2713 2714 return (retval); 2715} 2716 |
|
2682void | 2717void |
2683dwc_otg_interrupt(struct dwc_otg_softc *sc) | 2718dwc_otg_interrupt(void *arg) |
2684{ | 2719{ |
2720 struct dwc_otg_softc *sc = arg; |
|
2685 uint32_t status; 2686 2687 USB_BUS_LOCK(&sc->sc_bus); | 2721 uint32_t status; 2722 2723 USB_BUS_LOCK(&sc->sc_bus); |
2724 USB_BUS_SPIN_LOCK(&sc->sc_bus); |
|
2688 2689 /* read and clear interrupt status */ 2690 status = DWC_OTG_READ_4(sc, DOTG_GINTSTS); | 2725 2726 /* read and clear interrupt status */ 2727 status = DWC_OTG_READ_4(sc, DOTG_GINTSTS); |
2691 DWC_OTG_WRITE_4(sc, DOTG_GINTSTS, status); | |
2692 | 2728 |
2729 /* clear interrupts we are handling here */ 2730 DWC_OTG_WRITE_4(sc, DOTG_GINTSTS, status & DWC_OTG_MSK_GINT_THREAD_IRQ); 2731 |
|
2693 DPRINTFN(14, "GINTSTS=0x%08x HAINT=0x%08x HFNUM=0x%08x\n", 2694 status, DWC_OTG_READ_4(sc, DOTG_HAINT), 2695 DWC_OTG_READ_4(sc, DOTG_HFNUM)); 2696 2697 if (status & GINTSTS_USBRST) { 2698 2699 /* set correct state */ 2700 sc->sc_flags.status_device_mode = 1; --- 152 unchanged lines hidden (view full) --- 2853 temp = DWC_OTG_READ_4(sc, DOTG_GOTGCTL); 2854 2855 DPRINTFN(5, "GOTGCTL=0x%08x\n", temp); 2856 2857 dwc_otg_vbus_interrupt(sc, 2858 (temp & (GOTGCTL_ASESVLD | GOTGCTL_BSESVLD)) ? 1 : 0); 2859 } 2860 | 2732 DPRINTFN(14, "GINTSTS=0x%08x HAINT=0x%08x HFNUM=0x%08x\n", 2733 status, DWC_OTG_READ_4(sc, DOTG_HAINT), 2734 DWC_OTG_READ_4(sc, DOTG_HFNUM)); 2735 2736 if (status & GINTSTS_USBRST) { 2737 2738 /* set correct state */ 2739 sc->sc_flags.status_device_mode = 1; --- 152 unchanged lines hidden (view full) --- 2892 temp = DWC_OTG_READ_4(sc, DOTG_GOTGCTL); 2893 2894 DPRINTFN(5, "GOTGCTL=0x%08x\n", temp); 2895 2896 dwc_otg_vbus_interrupt(sc, 2897 (temp & (GOTGCTL_ASESVLD | GOTGCTL_BSESVLD)) ? 1 : 0); 2898 } 2899 |
2861 /* clear all IN endpoint interrupts */ 2862 if (status & GINTSTS_IEPINT) { 2863 uint32_t temp; 2864 uint8_t x; | 2900 if (sc->sc_xfer_complete != 0) { 2901 sc->sc_xfer_complete = 0; |
2865 | 2902 |
2866 for (x = 0; x != sc->sc_dev_in_ep_max; x++) { 2867 temp = DWC_OTG_READ_4(sc, DOTG_DIEPINT(x)); 2868 if (temp & DIEPMSK_XFERCOMPLMSK) { 2869 DWC_OTG_WRITE_4(sc, DOTG_DIEPINT(x), 2870 DIEPMSK_XFERCOMPLMSK); 2871 } | 2903 /* complete FIFOs, if any */ 2904 dwc_otg_interrupt_complete(sc); 2905 2906 if (sc->sc_flags.status_device_mode == 0) { 2907 /* update host transfer schedule, so that new transfers can be issued */ 2908 if (dwc_otg_update_host_transfer_schedule(sc)) 2909 dwc_otg_interrupt_poll(sc); |
2872 } 2873 } 2874 | 2910 } 2911 } 2912 |
2875 /* poll FIFO(s) */ 2876 dwc_otg_interrupt_poll(sc); 2877 | 2913 USB_BUS_SPIN_UNLOCK(&sc->sc_bus); |
2878 USB_BUS_UNLOCK(&sc->sc_bus); 2879} 2880 2881static void 2882dwc_otg_setup_standard_chain_sub(struct dwc_otg_std_temp *temp) 2883{ 2884 struct dwc_otg_td *td; 2885 --- 347 unchanged lines hidden (view full) --- 3233 3234 DPRINTFN(9, "\n"); 3235 3236 /* 3237 * Poll one time in device mode, which will turn on the 3238 * endpoint interrupts. Else wait for SOF interrupt in host 3239 * mode. 3240 */ | 2914 USB_BUS_UNLOCK(&sc->sc_bus); 2915} 2916 2917static void 2918dwc_otg_setup_standard_chain_sub(struct dwc_otg_std_temp *temp) 2919{ 2920 struct dwc_otg_td *td; 2921 --- 347 unchanged lines hidden (view full) --- 3269 3270 DPRINTFN(9, "\n"); 3271 3272 /* 3273 * Poll one time in device mode, which will turn on the 3274 * endpoint interrupts. Else wait for SOF interrupt in host 3275 * mode. 3276 */ |
3241 if (sc->sc_flags.status_device_mode != 0 && 3242 dwc_otg_xfer_do_fifo(xfer) == 0) 3243 goto done; | 3277 if (sc->sc_flags.status_device_mode != 0) { 3278 dwc_otg_xfer_do_fifo(sc, xfer); 3279 if (dwc_otg_xfer_do_complete(sc, xfer)) 3280 return; 3281 } 3282 USB_BUS_SPIN_LOCK(&sc->sc_bus); |
3244 3245 /* put transfer on interrupt queue */ 3246 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer); 3247 3248 /* start timeout, if any */ 3249 if (xfer->timeout != 0) { 3250 usbd_transfer_timeout_ms(xfer, 3251 &dwc_otg_timeout, xfer->timeout); --- 17 unchanged lines hidden (view full) --- 3269 */ 3270 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { 3271 td = xfer->td_transfer_cache; 3272 if (td == NULL || td->ep_type != UE_BULK || xfer->xroot != xroot) 3273 continue; 3274 /* reset NAK counter */ 3275 td->did_nak = 0; 3276 } | 3283 3284 /* put transfer on interrupt queue */ 3285 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer); 3286 3287 /* start timeout, if any */ 3288 if (xfer->timeout != 0) { 3289 usbd_transfer_timeout_ms(xfer, 3290 &dwc_otg_timeout, xfer->timeout); --- 17 unchanged lines hidden (view full) --- 3308 */ 3309 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { 3310 td = xfer->td_transfer_cache; 3311 if (td == NULL || td->ep_type != UE_BULK || xfer->xroot != xroot) 3312 continue; 3313 /* reset NAK counter */ 3314 td->did_nak = 0; 3315 } |
3277done:; | 3316done: 3317 USB_BUS_SPIN_UNLOCK(&sc->sc_bus); |
3278} 3279 3280static void 3281dwc_otg_root_intr(struct dwc_otg_softc *sc) 3282{ 3283 DPRINTFN(9, "\n"); 3284 3285 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); --- 120 unchanged lines hidden (view full) --- 3406 * dwc_otg_device_done 3407 * 3408 * NOTE: this function can be called more than one time on the 3409 * same USB transfer! 3410 *------------------------------------------------------------------------*/ 3411static void 3412dwc_otg_device_done(struct usb_xfer *xfer, usb_error_t error) 3413{ | 3318} 3319 3320static void 3321dwc_otg_root_intr(struct dwc_otg_softc *sc) 3322{ 3323 DPRINTFN(9, "\n"); 3324 3325 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); --- 120 unchanged lines hidden (view full) --- 3446 * dwc_otg_device_done 3447 * 3448 * NOTE: this function can be called more than one time on the 3449 * same USB transfer! 3450 *------------------------------------------------------------------------*/ 3451static void 3452dwc_otg_device_done(struct usb_xfer *xfer, usb_error_t error) 3453{ |
3454 struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(xfer->xroot->bus); 3455 |
|
3414 DPRINTFN(9, "xfer=%p, endpoint=%p, error=%d\n", 3415 xfer, xfer->endpoint, error); 3416 3417 if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { | 3456 DPRINTFN(9, "xfer=%p, endpoint=%p, error=%d\n", 3457 xfer, xfer->endpoint, error); 3458 3459 if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { |
3418 DPRINTFN(15, "disabled interrupts!\n"); | 3460 /* Interrupts are cleared by the interrupt handler */ |
3419 } else { 3420 struct dwc_otg_td *td; 3421 3422 td = xfer->td_transfer_first; 3423 3424 if (td != NULL) { | 3461 } else { 3462 struct dwc_otg_td *td; 3463 3464 td = xfer->td_transfer_first; 3465 3466 if (td != NULL) { |
3425 dwc_otg_host_channel_free(td, 0); 3426 dwc_otg_host_channel_free(td, 1); | 3467 dwc_otg_host_channel_free(sc, td, 0); 3468 dwc_otg_host_channel_free(sc, td, 1); |
3427 } 3428 } 3429 /* dequeue transfer and start next transfer */ 3430 usbd_transfer_done(xfer, error); 3431} 3432 3433static void 3434dwc_otg_xfer_stall(struct usb_xfer *xfer) --- 44 unchanged lines hidden (view full) --- 3479 3480 if (sc->sc_last_rx_status != 0 && 3481 (ep_no & UE_ADDR) == GRXSTSRD_CHNUM_GET( 3482 sc->sc_last_rx_status)) { 3483 /* dump data */ 3484 dwc_otg_common_rx_ack(sc); 3485 /* poll interrupt */ 3486 dwc_otg_interrupt_poll(sc); | 3469 } 3470 } 3471 /* dequeue transfer and start next transfer */ 3472 usbd_transfer_done(xfer, error); 3473} 3474 3475static void 3476dwc_otg_xfer_stall(struct usb_xfer *xfer) --- 44 unchanged lines hidden (view full) --- 3521 3522 if (sc->sc_last_rx_status != 0 && 3523 (ep_no & UE_ADDR) == GRXSTSRD_CHNUM_GET( 3524 sc->sc_last_rx_status)) { 3525 /* dump data */ 3526 dwc_otg_common_rx_ack(sc); 3527 /* poll interrupt */ 3528 dwc_otg_interrupt_poll(sc); |
3529 dwc_otg_interrupt_complete(sc); |
|
3487 } 3488 } 3489} 3490 3491static void 3492dwc_otg_clear_stall_sub(struct dwc_otg_softc *sc, uint32_t mps, 3493 uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir) 3494{ --- 48 unchanged lines hidden (view full) --- 3543 GRSTCTL_TXFFLSH); 3544 3545 DWC_OTG_WRITE_4(sc, 3546 DOTG_DIEPTSIZ(ep_no), 0); 3547 } 3548 3549 /* poll interrupt */ 3550 dwc_otg_interrupt_poll(sc); | 3530 } 3531 } 3532} 3533 3534static void 3535dwc_otg_clear_stall_sub(struct dwc_otg_softc *sc, uint32_t mps, 3536 uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir) 3537{ --- 48 unchanged lines hidden (view full) --- 3586 GRSTCTL_TXFFLSH); 3587 3588 DWC_OTG_WRITE_4(sc, 3589 DOTG_DIEPTSIZ(ep_no), 0); 3590 } 3591 3592 /* poll interrupt */ 3593 dwc_otg_interrupt_poll(sc); |
3594 dwc_otg_interrupt_complete(sc); |
|
3551} 3552 3553static void 3554dwc_otg_clear_stall(struct usb_device *udev, struct usb_endpoint *ep) 3555{ 3556 struct dwc_otg_softc *sc; 3557 struct usb_endpoint_descriptor *ed; 3558 --- 282 unchanged lines hidden (view full) --- 3841} 3842 3843static void 3844dwc_otg_do_poll(struct usb_bus *bus) 3845{ 3846 struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(bus); 3847 3848 USB_BUS_LOCK(&sc->sc_bus); | 3595} 3596 3597static void 3598dwc_otg_clear_stall(struct usb_device *udev, struct usb_endpoint *ep) 3599{ 3600 struct dwc_otg_softc *sc; 3601 struct usb_endpoint_descriptor *ed; 3602 --- 282 unchanged lines hidden (view full) --- 3885} 3886 3887static void 3888dwc_otg_do_poll(struct usb_bus *bus) 3889{ 3890 struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(bus); 3891 3892 USB_BUS_LOCK(&sc->sc_bus); |
3893 USB_BUS_SPIN_LOCK(&sc->sc_bus); |
|
3849 dwc_otg_interrupt_poll(sc); | 3894 dwc_otg_interrupt_poll(sc); |
3895 dwc_otg_interrupt_complete(sc); 3896 if (sc->sc_flags.status_device_mode == 0) { 3897 /* update host transfer schedule, so that new transfers can be issued */ 3898 if (dwc_otg_update_host_transfer_schedule(sc)) 3899 dwc_otg_interrupt_poll(sc); 3900 } 3901 USB_BUS_SPIN_UNLOCK(&sc->sc_bus); |
|
3850 USB_BUS_UNLOCK(&sc->sc_bus); 3851} 3852 3853/*------------------------------------------------------------------------* 3854 * DWC OTG bulk support 3855 * DWC OTG control support 3856 * DWC OTG interrupt support 3857 *------------------------------------------------------------------------*/ --- 862 unchanged lines hidden --- | 3902 USB_BUS_UNLOCK(&sc->sc_bus); 3903} 3904 3905/*------------------------------------------------------------------------* 3906 * DWC OTG bulk support 3907 * DWC OTG control support 3908 * DWC OTG interrupt support 3909 *------------------------------------------------------------------------*/ --- 862 unchanged lines hidden --- |