| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ehci.c,v 1.181.6.14 2012/02/26 05:05:44 mrg Exp $ */ | | 1 | /* $NetBSD: ehci.c,v 1.181.6.15 2012/03/03 02:28:52 mrg Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2004-2012 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2004-2012 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Lennart Augustsson (lennart@augustsson.net), Charles M. Hannum, | | 8 | * by Lennart Augustsson (lennart@augustsson.net), Charles M. Hannum, |
9 | * Jeremy Morse (jeremy.morse@gmail.com), Jared D. McNeill | | 9 | * Jeremy Morse (jeremy.morse@gmail.com), Jared D. McNeill |
10 | * (jmcneill@invisible.ca) and Matthew R. Green (mrg@eterna.com.au). | | 10 | * (jmcneill@invisible.ca) and Matthew R. Green (mrg@eterna.com.au). |
11 | * | | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | | 12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions | | 13 | * modification, are permitted provided that the following conditions |
14 | * are met: | | 14 | * are met: |
| @@ -43,27 +43,27 @@ | | | @@ -43,27 +43,27 @@ |
43 | | | 43 | |
44 | /* | | 44 | /* |
45 | * TODO: | | 45 | * TODO: |
46 | * 1) hold off explorations by companion controllers until ehci has started. | | 46 | * 1) hold off explorations by companion controllers until ehci has started. |
47 | * | | 47 | * |
48 | * 2) The hub driver needs to handle and schedule the transaction translator, | | 48 | * 2) The hub driver needs to handle and schedule the transaction translator, |
49 | * to assign place in frame where different devices get to go. See chapter | | 49 | * to assign place in frame where different devices get to go. See chapter |
50 | * on hubs in USB 2.0 for details. | | 50 | * on hubs in USB 2.0 for details. |
51 | * | | 51 | * |
52 | * 3) Command failures are not recovered correctly. | | 52 | * 3) Command failures are not recovered correctly. |
53 | */ | | 53 | */ |
54 | | | 54 | |
55 | #include <sys/cdefs.h> | | 55 | #include <sys/cdefs.h> |
56 | __KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.14 2012/02/26 05:05:44 mrg Exp $"); | | 56 | __KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.15 2012/03/03 02:28:52 mrg Exp $"); |
57 | | | 57 | |
58 | #include "ohci.h" | | 58 | #include "ohci.h" |
59 | #include "uhci.h" | | 59 | #include "uhci.h" |
60 | #include "opt_usb.h" | | 60 | #include "opt_usb.h" |
61 | | | 61 | |
62 | #include <sys/param.h> | | 62 | #include <sys/param.h> |
63 | #include <sys/systm.h> | | 63 | #include <sys/systm.h> |
64 | #include <sys/kernel.h> | | 64 | #include <sys/kernel.h> |
65 | #include <sys/kmem.h> | | 65 | #include <sys/kmem.h> |
66 | #include <sys/device.h> | | 66 | #include <sys/device.h> |
67 | #include <sys/select.h> | | 67 | #include <sys/select.h> |
68 | #include <sys/proc.h> | | 68 | #include <sys/proc.h> |
69 | #include <sys/queue.h> | | 69 | #include <sys/queue.h> |
| @@ -2869,27 +2869,27 @@ ehci_free_sqtd_chain(ehci_softc_t *sc, e | | | @@ -2869,27 +2869,27 @@ ehci_free_sqtd_chain(ehci_softc_t *sc, e |
2869 | sqtd, sqtdend)); | | 2869 | sqtd, sqtdend)); |
2870 | | | 2870 | |
2871 | for (i = 0; sqtd != sqtdend; sqtd = p, i++) { | | 2871 | for (i = 0; sqtd != sqtdend; sqtd = p, i++) { |
2872 | p = sqtd->nextqtd; | | 2872 | p = sqtd->nextqtd; |
2873 | ehci_free_sqtd(sc, sqtd); | | 2873 | ehci_free_sqtd(sc, sqtd); |
2874 | } | | 2874 | } |
2875 | } | | 2875 | } |
2876 | | | 2876 | |
2877 | Static ehci_soft_itd_t * | | 2877 | Static ehci_soft_itd_t * |
2878 | ehci_alloc_itd(ehci_softc_t *sc) | | 2878 | ehci_alloc_itd(ehci_softc_t *sc) |
2879 | { | | 2879 | { |
2880 | struct ehci_soft_itd *itd, *freeitd; | | 2880 | struct ehci_soft_itd *itd, *freeitd; |
2881 | usbd_status err; | | 2881 | usbd_status err; |
2882 | int i, s, offs, frindex, previndex; | | 2882 | int i, offs, frindex, previndex; |
2883 | usb_dma_t dma; | | 2883 | usb_dma_t dma; |
2884 | | | 2884 | |
2885 | KASSERT(mutex_owned(&sc->sc_lock)); | | 2885 | KASSERT(mutex_owned(&sc->sc_lock)); |
2886 | | | 2886 | |
2887 | /* Find an itd that wasn't freed this frame or last frame. This can | | 2887 | /* Find an itd that wasn't freed this frame or last frame. This can |
2888 | * discard itds that were freed before frindex wrapped around | | 2888 | * discard itds that were freed before frindex wrapped around |
2889 | * XXX - can this lead to thrashing? Could fix by enabling wrap-around | | 2889 | * XXX - can this lead to thrashing? Could fix by enabling wrap-around |
2890 | * interrupt and fiddling with list when that happens */ | | 2890 | * interrupt and fiddling with list when that happens */ |
2891 | frindex = (EOREAD4(sc, EHCI_FRINDEX) + 1) >> 3; | | 2891 | frindex = (EOREAD4(sc, EHCI_FRINDEX) + 1) >> 3; |
2892 | previndex = (frindex != 0) ? frindex - 1 : sc->sc_flsize; | | 2892 | previndex = (frindex != 0) ? frindex - 1 : sc->sc_flsize; |
2893 | | | 2893 | |
2894 | freeitd = NULL; | | 2894 | freeitd = NULL; |
2895 | LIST_FOREACH(itd, &sc->sc_freeitds, u.free_list) { | | 2895 | LIST_FOREACH(itd, &sc->sc_freeitds, u.free_list) { |
| @@ -2923,27 +2923,26 @@ ehci_alloc_itd(ehci_softc_t *sc) | | | @@ -2923,27 +2923,26 @@ ehci_alloc_itd(ehci_softc_t *sc) |
2923 | } | | 2923 | } |
2924 | | | 2924 | |
2925 | itd = freeitd; | | 2925 | itd = freeitd; |
2926 | LIST_REMOVE(itd, u.free_list); | | 2926 | LIST_REMOVE(itd, u.free_list); |
2927 | memset(&itd->itd, 0, sizeof(ehci_itd_t)); | | 2927 | memset(&itd->itd, 0, sizeof(ehci_itd_t)); |
2928 | usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_next), | | 2928 | usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_next), |
2929 | sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE | | | 2929 | sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE | |
2930 | BUS_DMASYNC_PREREAD); | | 2930 | BUS_DMASYNC_PREREAD); |
2931 | | | 2931 | |
2932 | itd->u.frame_list.next = NULL; | | 2932 | itd->u.frame_list.next = NULL; |
2933 | itd->u.frame_list.prev = NULL; | | 2933 | itd->u.frame_list.prev = NULL; |
2934 | itd->xfer_next = NULL; | | 2934 | itd->xfer_next = NULL; |
2935 | itd->slot = 0; | | 2935 | itd->slot = 0; |
2936 | splx(s); | | | |
2937 | | | 2936 | |
2938 | return itd; | | 2937 | return itd; |
2939 | } | | 2938 | } |
2940 | | | 2939 | |
2941 | Static void | | 2940 | Static void |
2942 | ehci_free_itd(ehci_softc_t *sc, ehci_soft_itd_t *itd) | | 2941 | ehci_free_itd(ehci_softc_t *sc, ehci_soft_itd_t *itd) |
2943 | { | | 2942 | { |
2944 | | | 2943 | |
2945 | KASSERT(mutex_owned(&sc->sc_lock)); | | 2944 | KASSERT(mutex_owned(&sc->sc_lock)); |
2946 | | | 2945 | |
2947 | LIST_INSERT_HEAD(&sc->sc_freeitds, itd, u.free_list); | | 2946 | LIST_INSERT_HEAD(&sc->sc_freeitds, itd, u.free_list); |
2948 | } | | 2947 | } |
2949 | | | 2948 | |