Thu Dec 8 09:09:30 2011 UTC ()
partial sync with main branch


(mrg)
diff -r1.218.6.2.2.3 -r1.218.6.2.2.4 src/sys/dev/usb/ohci.c

cvs diff -r1.218.6.2.2.3 -r1.218.6.2.2.4 src/sys/dev/usb/ohci.c (expand / switch to unified diff)

--- src/sys/dev/usb/ohci.c 2011/12/08 08:52:25 1.218.6.2.2.3
+++ src/sys/dev/usb/ohci.c 2011/12/08 09:09:30 1.218.6.2.2.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ohci.c,v 1.218.6.2.2.3 2011/12/08 08:52:25 mrg Exp $ */ 1/* $NetBSD: ohci.c,v 1.218.6.2.2.4 2011/12/08 09:09:30 mrg Exp $ */
2/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ 2/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1998, 2004, 2005, 2011 The NetBSD Foundation, Inc. 5 * Copyright (c) 1998, 2004, 2005, 2011 The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at 9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca) 10 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca)
11 * and Matthew R. Green. 11 * and Matthew R. Green.
12 * This code is derived from software contributed to The NetBSD Foundation 12 * This code is derived from software contributed to The NetBSD Foundation
13 * by Charles M. Hannum. 13 * by Charles M. Hannum.
14 * 14 *
@@ -32,27 +32,27 @@ @@ -32,27 +32,27 @@
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37/* 37/*
38 * USB Open Host Controller driver. 38 * USB Open Host Controller driver.
39 * 39 *
40 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html 40 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
41 * USB spec: http://www.usb.org/developers/docs/ 41 * USB spec: http://www.usb.org/developers/docs/
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.2.2.3 2011/12/08 08:52:25 mrg Exp $"); 45__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.2.2.4 2011/12/08 09:09:30 mrg Exp $");
46 46
47#include "opt_usb.h" 47#include "opt_usb.h"
48 48
49#include <sys/param.h> 49#include <sys/param.h>
50#include <sys/systm.h> 50#include <sys/systm.h>
51#include <sys/kmem.h> 51#include <sys/kmem.h>
52#include <sys/kernel.h> 52#include <sys/kernel.h>
53#include <sys/device.h> 53#include <sys/device.h>
54#include <sys/select.h> 54#include <sys/select.h>
55#include <sys/proc.h> 55#include <sys/proc.h>
56#include <sys/queue.h> 56#include <sys/queue.h>
57 57
58#include <sys/bus.h> 58#include <sys/bus.h>
@@ -110,27 +110,28 @@ Static usbd_status ohci_alloc_std_chain( @@ -110,27 +110,28 @@ Static usbd_status ohci_alloc_std_chain(
110 ohci_soft_td_t *, ohci_soft_td_t **); 110 ohci_soft_td_t *, ohci_soft_td_t **);
111 111
112Static usbd_status ohci_open(usbd_pipe_handle); 112Static usbd_status ohci_open(usbd_pipe_handle);
113Static void ohci_poll(struct usbd_bus *); 113Static void ohci_poll(struct usbd_bus *);
114Static void ohci_softintr(void *); 114Static void ohci_softintr(void *);
115Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle); 115Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle);
116Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle); 116Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
117Static void ohci_rhsc_softint(void *arg); 117Static void ohci_rhsc_softint(void *arg);
118 118
119Static usbd_status ohci_device_request(usbd_xfer_handle xfer); 119Static usbd_status ohci_device_request(usbd_xfer_handle xfer);
120Static void ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *, 120Static void ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *,
121 ohci_soft_ed_t *); 121 ohci_soft_ed_t *);
122 122
123Static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *); 123Static void ohci_rem_ed(ohci_softc_t *, ohci_soft_ed_t *,
 124 ohci_soft_ed_t *);
124Static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *); 125Static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
125Static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *); 126Static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
126Static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t); 127Static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t);
127Static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *); 128Static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *);
128Static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *); 129Static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *);
129Static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t); 130Static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t);
130 131
131Static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe); 132Static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe);
132Static void ohci_device_isoc_enter(usbd_xfer_handle); 133Static void ohci_device_isoc_enter(usbd_xfer_handle);
133 134
134Static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t); 135Static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
135Static void ohci_freem(struct usbd_bus *, usb_dma_t *); 136Static void ohci_freem(struct usbd_bus *, usb_dma_t *);
136 137
@@ -261,88 +262,88 @@ struct ohci_pipe { @@ -261,88 +262,88 @@ struct ohci_pipe {
261 u_int length; 262 u_int length;
262 int isread; 263 int isread;
263 } bulk; 264 } bulk;
264 /* Iso pipe */ 265 /* Iso pipe */
265 struct iso { 266 struct iso {
266 int next, inuse; 267 int next, inuse;
267 } iso; 268 } iso;
268 } u; 269 } u;
269}; 270};
270 271
271#define OHCI_INTR_ENDPT 1 272#define OHCI_INTR_ENDPT 1
272 273
273Static const struct usbd_bus_methods ohci_bus_methods = { 274Static const struct usbd_bus_methods ohci_bus_methods = {
274 ohci_open, 275 .open_pipe = ohci_open,
275 ohci_softintr, 276 .soft_intr = ohci_softintr,
276 ohci_poll, 277 .do_poll = ohci_poll,
277 ohci_allocm, 278 .allocm = ohci_allocm,
278 ohci_freem, 279 .freem = ohci_freem,
279 ohci_allocx, 280 .allocx = ohci_allocx,
280 ohci_freex, 281 .freex = ohci_freex,
281 ohci_get_locks, 282 .get_locks = ohci_get_locks,
282}; 283};
283 284
284Static const struct usbd_pipe_methods ohci_root_ctrl_methods = { 285Static const struct usbd_pipe_methods ohci_root_ctrl_methods = {
285 ohci_root_ctrl_transfer, 286 .transfer = ohci_root_ctrl_transfer,
286 ohci_root_ctrl_start, 287 .start = ohci_root_ctrl_start,
287 ohci_root_ctrl_abort, 288 .abort = ohci_root_ctrl_abort,
288 ohci_root_ctrl_close, 289 .close = ohci_root_ctrl_close,
289 ohci_noop, 290 .cleartoggle = ohci_noop,
290 ohci_root_ctrl_done, 291 .done = ohci_root_ctrl_done,
291}; 292};
292 293
293Static const struct usbd_pipe_methods ohci_root_intr_methods = { 294Static const struct usbd_pipe_methods ohci_root_intr_methods = {
294 ohci_root_intr_transfer, 295 .transfer = ohci_root_intr_transfer,
295 ohci_root_intr_start, 296 .start = ohci_root_intr_start,
296 ohci_root_intr_abort, 297 .abort = ohci_root_intr_abort,
297 ohci_root_intr_close, 298 .close = ohci_root_intr_close,
298 ohci_noop, 299 .cleartoggle = ohci_noop,
299 ohci_root_intr_done, 300 .done = ohci_root_intr_done,
300}; 301};
301 302
302Static const struct usbd_pipe_methods ohci_device_ctrl_methods = { 303Static const struct usbd_pipe_methods ohci_device_ctrl_methods = {
303 ohci_device_ctrl_transfer, 304 .transfer = ohci_device_ctrl_transfer,
304 ohci_device_ctrl_start, 305 .start = ohci_device_ctrl_start,
305 ohci_device_ctrl_abort, 306 .abort = ohci_device_ctrl_abort,
306 ohci_device_ctrl_close, 307 .close = ohci_device_ctrl_close,
307 ohci_noop, 308 .cleartoggle = ohci_noop,
308 ohci_device_ctrl_done, 309 .done = ohci_device_ctrl_done,
309}; 310};
310 311
311Static const struct usbd_pipe_methods ohci_device_intr_methods = { 312Static const struct usbd_pipe_methods ohci_device_intr_methods = {
312 ohci_device_intr_transfer, 313 .transfer = ohci_device_intr_transfer,
313 ohci_device_intr_start, 314 .start = ohci_device_intr_start,
314 ohci_device_intr_abort, 315 .abort = ohci_device_intr_abort,
315 ohci_device_intr_close, 316 .close = ohci_device_intr_close,
316 ohci_device_clear_toggle, 317 .cleartoggle = ohci_device_clear_toggle,
317 ohci_device_intr_done, 318 .done = ohci_device_intr_done,
318}; 319};
319 320
320Static const struct usbd_pipe_methods ohci_device_bulk_methods = { 321Static const struct usbd_pipe_methods ohci_device_bulk_methods = {
321 ohci_device_bulk_transfer, 322 .transfer = ohci_device_bulk_transfer,
322 ohci_device_bulk_start, 323 .start = ohci_device_bulk_start,
323 ohci_device_bulk_abort, 324 .abort = ohci_device_bulk_abort,
324 ohci_device_bulk_close, 325 .close = ohci_device_bulk_close,
325 ohci_device_clear_toggle, 326 .cleartoggle = ohci_device_clear_toggle,
326 ohci_device_bulk_done, 327 .done = ohci_device_bulk_done,
327}; 328};
328 329
329Static const struct usbd_pipe_methods ohci_device_isoc_methods = { 330Static const struct usbd_pipe_methods ohci_device_isoc_methods = {
330 ohci_device_isoc_transfer, 331 .transfer = ohci_device_isoc_transfer,
331 ohci_device_isoc_start, 332 .start = ohci_device_isoc_start,
332 ohci_device_isoc_abort, 333 .abort = ohci_device_isoc_abort,
333 ohci_device_isoc_close, 334 .close = ohci_device_isoc_close,
334 ohci_noop, 335 .cleartoggle = ohci_noop,
335 ohci_device_isoc_done, 336 .done = ohci_device_isoc_done,
336}; 337};
337 338
338int 339int
339ohci_activate(device_t self, enum devact act) 340ohci_activate(device_t self, enum devact act)
340{ 341{
341 struct ohci_softc *sc = device_private(self); 342 struct ohci_softc *sc = device_private(self);
342 343
343 switch (act) { 344 switch (act) {
344 case DVACT_DEACTIVATE: 345 case DVACT_DEACTIVATE:
345 sc->sc_dying = 1; 346 sc->sc_dying = 1;
346 return 0; 347 return 0;
347 default: 348 default:
348 return EOPNOTSUPP; 349 return EOPNOTSUPP;
@@ -1487,27 +1488,29 @@ ohci_softintr(void *v) @@ -1487,27 +1488,29 @@ ohci_softintr(void *v)
1487 cv_broadcast(&sc->sc_softwake_cv); 1488 cv_broadcast(&sc->sc_softwake_cv);
1488 } 1489 }
1489 1490
1490 sc->sc_bus.intr_context--; 1491 sc->sc_bus.intr_context--;
1491 mutex_exit(&sc->sc_lock); 1492 mutex_exit(&sc->sc_lock);
1492 1493
1493 DPRINTFN(10,("ohci_softintr: done:\n")); 1494 DPRINTFN(10,("ohci_softintr: done:\n"));
1494} 1495}
1495 1496
1496void 1497void
1497ohci_device_ctrl_done(usbd_xfer_handle xfer) 1498ohci_device_ctrl_done(usbd_xfer_handle xfer)
1498{ 1499{
1499 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 1500 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
 1501#ifdef DIAGNOSTIC
1500 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; 1502 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
 1503#endif
1501 int len = UGETW(xfer->request.wLength); 1504 int len = UGETW(xfer->request.wLength);
1502 int isread = (xfer->request.bmRequestType & UT_READ); 1505 int isread = (xfer->request.bmRequestType & UT_READ);
1503 1506
1504 DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer)); 1507 DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer));
1505 1508
1506 KASSERT(mutex_owned(&sc->sc_lock)); 1509 KASSERT(mutex_owned(&sc->sc_lock));
1507 1510
1508#ifdef DIAGNOSTIC 1511#ifdef DIAGNOSTIC
1509 if (!(xfer->rqflags & URQ_REQUEST)) { 1512 if (!(xfer->rqflags & URQ_REQUEST)) {
1510 panic("ohci_device_ctrl_done: not a request"); 1513 panic("ohci_device_ctrl_done: not a request");
1511 } 1514 }
1512#endif 1515#endif
1513 if (len) 1516 if (len)
@@ -1563,27 +1566,29 @@ ohci_device_intr_done(usbd_xfer_handle x @@ -1563,27 +1566,29 @@ ohci_device_intr_done(usbd_xfer_handle x
1563 1566
1564 sed->ed.ed_tailp = HTOO32(tail->physaddr); 1567 sed->ed.ed_tailp = HTOO32(tail->physaddr);
1565 usb_syncmem(&sed->dma, 1568 usb_syncmem(&sed->dma,
1566 sed->offs + offsetof(ohci_ed_t, ed_tailp), 1569 sed->offs + offsetof(ohci_ed_t, ed_tailp),
1567 sizeof(sed->ed.ed_tailp), 1570 sizeof(sed->ed.ed_tailp),
1568 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1571 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1569 opipe->tail.td = tail; 1572 opipe->tail.td = tail;
1570 } 1573 }
1571} 1574}
1572 1575
1573void 1576void
1574ohci_device_bulk_done(usbd_xfer_handle xfer) 1577ohci_device_bulk_done(usbd_xfer_handle xfer)
1575{ 1578{
 1579#ifdef DIAGNOSTIC
1576 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; 1580 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
 1581#endif
1577 int isread = 1582 int isread =
1578 (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN); 1583 (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN);
1579 1584
1580 KASSERT(mutex_owned(&sc->sc_lock)); 1585 KASSERT(mutex_owned(&sc->sc_lock));
1581 1586
1582 DPRINTFN(10,("ohci_device_bulk_done: xfer=%p, actlen=%d\n", 1587 DPRINTFN(10,("ohci_device_bulk_done: xfer=%p, actlen=%d\n",
1583 xfer, xfer->actlen)); 1588 xfer, xfer->actlen));
1584 usb_syncmem(&xfer->dmabuf, 0, xfer->length, 1589 usb_syncmem(&xfer->dmabuf, 0, xfer->length,
1585 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1590 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1586} 1591}
1587 1592
1588Static void 1593Static void
1589ohci_rhsc_softint(void *arg) 1594ohci_rhsc_softint(void *arg)
@@ -1855,56 +1860,57 @@ ohci_device_request(usbd_xfer_handle xfe @@ -1855,56 +1860,57 @@ ohci_device_request(usbd_xfer_handle xfe
1855 return (USBD_NORMAL_COMPLETION); 1860 return (USBD_NORMAL_COMPLETION);
1856 1861
1857 bad3: 1862 bad3:
1858 ohci_free_std(sc, tail); 1863 ohci_free_std(sc, tail);
1859 bad2: 1864 bad2:
1860 ohci_free_std(sc, stat); 1865 ohci_free_std(sc, stat);
1861 bad1: 1866 bad1:
1862 return (err); 1867 return (err);
1863} 1868}
1864 1869
1865/* 1870/*
1866 * Add an ED to the schedule. Called at splusb(). 1871 * Add an ED to the schedule. Called at splusb().
1867 */ 1872 */
1868void 1873Static void
1869ohci_add_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head) 1874ohci_add_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
1870{ 1875{
1871 DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head)); 1876 DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head));
1872 1877
1873 SPLUSBCHECK; 1878 KASSERT(mutex_owned(&sc->sc_lock));
 1879
1874 usb_syncmem(&head->dma, head->offs + offsetof(ohci_ed_t, ed_nexted), 1880 usb_syncmem(&head->dma, head->offs + offsetof(ohci_ed_t, ed_nexted),
1875 sizeof(head->ed.ed_nexted), 1881 sizeof(head->ed.ed_nexted),
1876 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1882 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1877 sed->next = head->next; 1883 sed->next = head->next;
1878 sed->ed.ed_nexted = head->ed.ed_nexted; 1884 sed->ed.ed_nexted = head->ed.ed_nexted;
1879 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_nexted), 1885 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_nexted),
1880 sizeof(sed->ed.ed_nexted), 1886 sizeof(sed->ed.ed_nexted),
1881 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1887 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1882 head->next = sed; 1888 head->next = sed;
1883 head->ed.ed_nexted = HTOO32(sed->physaddr); 1889 head->ed.ed_nexted = HTOO32(sed->physaddr);
1884 usb_syncmem(&head->dma, head->offs + offsetof(ohci_ed_t, ed_nexted), 1890 usb_syncmem(&head->dma, head->offs + offsetof(ohci_ed_t, ed_nexted),
1885 sizeof(head->ed.ed_nexted), 1891 sizeof(head->ed.ed_nexted),
1886 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1892 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1887} 1893}
1888 1894
1889/* 1895/*
1890 * Remove an ED from the schedule. Called at splusb(). 1896 * Remove an ED from the schedule. Called at splusb().
1891 */ 1897 */
1892void 1898Static void
1893ohci_rem_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head) 1899ohci_rem_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
1894{ 1900{
1895 ohci_soft_ed_t *p; 1901 ohci_soft_ed_t *p;
1896 1902
1897 SPLUSBCHECK; 1903 //KASSERT(mutex_owned(&sc->sc_lock));
1898 1904
1899 /* XXX */ 1905 /* XXX */
1900 for (p = head; p != NULL && p->next != sed; p = p->next) 1906 for (p = head; p != NULL && p->next != sed; p = p->next)
1901 ; 1907 ;
1902 if (p == NULL) 1908 if (p == NULL)
1903 panic("ohci_rem_ed: ED not found"); 1909 panic("ohci_rem_ed: ED not found");
1904 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_nexted), 1910 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_nexted),
1905 sizeof(sed->ed.ed_nexted), 1911 sizeof(sed->ed.ed_nexted),
1906 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1912 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1907 p->next = sed->next; 1913 p->next = sed->next;
1908 p->ed.ed_nexted = sed->ed.ed_nexted; 1914 p->ed.ed_nexted = sed->ed.ed_nexted;
1909 usb_syncmem(&p->dma, p->offs + offsetof(ohci_ed_t, ed_nexted), 1915 usb_syncmem(&p->dma, p->offs + offsetof(ohci_ed_t, ed_nexted),
1910 sizeof(p->ed.ed_nexted), 1916 sizeof(p->ed.ed_nexted),
@@ -1918,73 +1924,74 @@ ohci_rem_ed(ohci_soft_ed_t *sed, ohci_so @@ -1918,73 +1924,74 @@ ohci_rem_ed(ohci_soft_ed_t *sed, ohci_so
1918 * and we have no simple way to translate this back to a kernel address. 1924 * and we have no simple way to translate this back to a kernel address.
1919 * To make the translation possible (and fast) we use a hash table of 1925 * To make the translation possible (and fast) we use a hash table of
1920 * TDs currently in the schedule. The physical address is used as the 1926 * TDs currently in the schedule. The physical address is used as the
1921 * hash value. 1927 * hash value.
1922 */ 1928 */
1923 1929
1924#define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE) 1930#define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE)
1925/* Called at splusb() */ 1931/* Called at splusb() */
1926void 1932void
1927ohci_hash_add_td(ohci_softc_t *sc, ohci_soft_td_t *std) 1933ohci_hash_add_td(ohci_softc_t *sc, ohci_soft_td_t *std)
1928{ 1934{
1929 int h = HASH(std->physaddr); 1935 int h = HASH(std->physaddr);
1930 1936
1931 SPLUSBCHECK; 1937 //KASSERT(mutex_owned(&sc->sc_lock));
1932 1938
1933 LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext); 1939 LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
1934} 1940}
1935 1941
1936/* Called at splusb() */ 1942/* Called at splusb() */
1937void 1943void
1938ohci_hash_rem_td(ohci_softc_t *sc, ohci_soft_td_t *std) 1944ohci_hash_rem_td(ohci_softc_t *sc, ohci_soft_td_t *std)
1939{ 1945{
1940 SPLUSBCHECK; 1946
 1947 //KASSERT(mutex_owned(&sc->sc_lock));
1941 1948
1942 LIST_REMOVE(std, hnext); 1949 LIST_REMOVE(std, hnext);
1943} 1950}
1944 1951
1945ohci_soft_td_t * 1952ohci_soft_td_t *
1946ohci_hash_find_td(ohci_softc_t *sc, ohci_physaddr_t a) 1953ohci_hash_find_td(ohci_softc_t *sc, ohci_physaddr_t a)
1947{ 1954{
1948 int h = HASH(a); 1955 int h = HASH(a);
1949 ohci_soft_td_t *std; 1956 ohci_soft_td_t *std;
1950 1957
1951 for (std = LIST_FIRST(&sc->sc_hash_tds[h]); 1958 for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
1952 std != NULL; 1959 std != NULL;
1953 std = LIST_NEXT(std, hnext)) 1960 std = LIST_NEXT(std, hnext))
1954 if (std->physaddr == a) 1961 if (std->physaddr == a)
1955 return (std); 1962 return (std);
1956 return (NULL); 1963 return (NULL);
1957} 1964}
1958 1965
1959/* Called at splusb() */ 1966/* Called at splusb() */
1960void 1967void
1961ohci_hash_add_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) 1968ohci_hash_add_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
1962{ 1969{
1963 int h = HASH(sitd->physaddr); 1970 int h = HASH(sitd->physaddr);
1964 1971
1965 SPLUSBCHECK; 1972 //KASSERT(mutex_owned(&sc->sc_lock));
1966 1973
1967 DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n", 1974 DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n",
1968 sitd, (u_long)sitd->physaddr)); 1975 sitd, (u_long)sitd->physaddr));
1969 1976
1970 LIST_INSERT_HEAD(&sc->sc_hash_itds[h], sitd, hnext); 1977 LIST_INSERT_HEAD(&sc->sc_hash_itds[h], sitd, hnext);
1971} 1978}
1972 1979
1973/* Called at splusb() */ 1980/* Called at splusb() */
1974void 1981void
1975ohci_hash_rem_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) 1982ohci_hash_rem_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
1976{ 1983{
1977 SPLUSBCHECK; 1984 //KASSERT(mutex_owned(&sc->sc_lock));
1978 1985
1979 DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n", 1986 DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n",
1980 sitd, (u_long)sitd->physaddr)); 1987 sitd, (u_long)sitd->physaddr));
1981 1988
1982 LIST_REMOVE(sitd, hnext); 1989 LIST_REMOVE(sitd, hnext);
1983} 1990}
1984 1991
1985ohci_soft_itd_t * 1992ohci_soft_itd_t *
1986ohci_hash_find_itd(ohci_softc_t *sc, ohci_physaddr_t a) 1993ohci_hash_find_itd(ohci_softc_t *sc, ohci_physaddr_t a)
1987{ 1994{
1988 int h = HASH(a); 1995 int h = HASH(a);
1989 ohci_soft_itd_t *sitd; 1996 ohci_soft_itd_t *sitd;
1990 1997
@@ -2215,70 +2222,69 @@ ohci_open(usbd_pipe_handle pipe) @@ -2215,70 +2222,69 @@ ohci_open(usbd_pipe_handle pipe)
2215 break; 2222 break;
2216 } 2223 }
2217 } 2224 }
2218 2225
2219 return USBD_NORMAL_COMPLETION; 2226 return USBD_NORMAL_COMPLETION;
2220 2227
2221 bad: 2228 bad:
2222 if (std != NULL) 2229 if (std != NULL)
2223 ohci_free_std(sc, std); 2230 ohci_free_std(sc, std);
2224 bad1: 2231 bad1:
2225 if (sed != NULL) 2232 if (sed != NULL)
2226 ohci_free_sed(sc, sed); 2233 ohci_free_sed(sc, sed);
2227 bad0: 2234 bad0:
2228 mutex_exit(&sc->sc_lock); 
2229 return err; 2235 return err;
2230 2236
2231} 2237}
2232 2238
2233/* 2239/*
2234 * Close a reqular pipe. 2240 * Close a reqular pipe.
2235 * Assumes that there are no pending transactions. 2241 * Assumes that there are no pending transactions.
2236 */ 2242 */
2237void 2243void
2238ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head) 2244ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head)
2239{ 2245{
2240 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 2246 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2241 ohci_softc_t *sc = pipe->device->bus->hci_private; 2247 ohci_softc_t *sc = pipe->device->bus->hci_private;
2242 ohci_soft_ed_t *sed = opipe->sed; 2248 ohci_soft_ed_t *sed = opipe->sed;
2243 2249
2244// KASSERT(mutex_owned(&sc->sc_lock)); 2250 KASSERT(mutex_owned(&sc->sc_lock));
2245 2251
2246#ifdef DIAGNOSTIC 2252#ifdef DIAGNOSTIC
2247 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); 2253 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
2248 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != 2254 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
2249 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) { 2255 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) {
2250 ohci_soft_td_t *std; 2256 ohci_soft_td_t *std;
2251 std = ohci_hash_find_td(sc, O32TOH(sed->ed.ed_headp)); 2257 std = ohci_hash_find_td(sc, O32TOH(sed->ed.ed_headp));
2252 printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x " 2258 printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x "
2253 "tl=0x%x pipe=%p, std=%p\n", sed, 2259 "tl=0x%x pipe=%p, std=%p\n", sed,
2254 (int)O32TOH(sed->ed.ed_headp), 2260 (int)O32TOH(sed->ed.ed_headp),
2255 (int)O32TOH(sed->ed.ed_tailp), 2261 (int)O32TOH(sed->ed.ed_tailp),
2256 pipe, std); 2262 pipe, std);
2257#ifdef USB_DEBUG 2263#ifdef USB_DEBUG
2258 usbd_dump_pipe(&opipe->pipe); 2264 usbd_dump_pipe(&opipe->pipe);
2259#endif 2265#endif
2260#ifdef OHCI_DEBUG 2266#ifdef OHCI_DEBUG
2261 ohci_dump_ed(sc, sed); 2267 ohci_dump_ed(sc, sed);
2262 if (std) 2268 if (std)
2263 ohci_dump_td(sc, std); 2269 ohci_dump_td(sc, std);
2264#endif 2270#endif
2265 usb_delay_ms(&sc->sc_bus, 2); 2271 usb_delay_ms(&sc->sc_bus, 2);
2266 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != 2272 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
2267 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) 2273 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK))
2268 printf("ohci_close_pipe: pipe still not empty\n"); 2274 printf("ohci_close_pipe: pipe still not empty\n");
2269 } 2275 }
2270#endif 2276#endif
2271 ohci_rem_ed(sed, head); 2277 ohci_rem_ed(sc, sed, head);
2272 /* Make sure the host controller is not touching this ED */ 2278 /* Make sure the host controller is not touching this ED */
2273 usb_delay_ms(&sc->sc_bus, 1); 2279 usb_delay_ms(&sc->sc_bus, 1);
2274 pipe->endpoint->datatoggle = 2280 pipe->endpoint->datatoggle =
2275 (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0; 2281 (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0;
2276 ohci_free_sed(sc, opipe->sed); 2282 ohci_free_sed(sc, opipe->sed);
2277} 2283}
2278 2284
2279/* 2285/*
2280 * Abort a device request. 2286 * Abort a device request.
2281 * If this routine is called at splusb() it guarantees that the request 2287 * If this routine is called at splusb() it guarantees that the request
2282 * will be removed from the hardware scheduling and that the callback 2288 * will be removed from the hardware scheduling and that the callback
2283 * for it will be called with USBD_CANCELLED status. 2289 * for it will be called with USBD_CANCELLED status.
2284 * It's impossible to guarantee that the requested transfer will not 2290 * It's impossible to guarantee that the requested transfer will not
@@ -3349,35 +3355,35 @@ ohci_device_setintr(ohci_softc_t *sc, st @@ -3349,35 +3355,35 @@ ohci_device_setintr(ohci_softc_t *sc, st
3349 ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS]; 3355 ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS];
3350 opipe->u.intr.nslots = nslots; 3356 opipe->u.intr.nslots = nslots;
3351 opipe->u.intr.pos = best; 3357 opipe->u.intr.pos = best;
3352 3358
3353 DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe)); 3359 DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
3354 return (USBD_NORMAL_COMPLETION); 3360 return (USBD_NORMAL_COMPLETION);
3355} 3361}
3356 3362
3357/***********************/ 3363/***********************/
3358 3364
3359usbd_status 3365usbd_status
3360ohci_device_isoc_transfer(usbd_xfer_handle xfer) 3366ohci_device_isoc_transfer(usbd_xfer_handle xfer)
3361{ 3367{
3362 //ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; 3368 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
3363 usbd_status err; 3369 usbd_status err;
3364 3370
3365 DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer)); 3371 DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer));
3366 3372
3367 /* Put it on our queue, */ 3373 /* Put it on our queue, */
3368 //mutex_enter(&sc->sc_lock); 3374 mutex_enter(&sc->sc_lock);
3369 err = usb_insert_transfer(xfer); 3375 err = usb_insert_transfer(xfer);
3370 //mutex_exit(&sc->sc_lock); 3376 mutex_exit(&sc->sc_lock);
3371 3377
3372 /* bail out on error, */ 3378 /* bail out on error, */
3373 if (err && err != USBD_IN_PROGRESS) 3379 if (err && err != USBD_IN_PROGRESS)
3374 return (err); 3380 return (err);
3375 3381
3376 /* XXX should check inuse here */ 3382 /* XXX should check inuse here */
3377 3383
3378 /* insert into schedule, */ 3384 /* insert into schedule, */
3379 ohci_device_isoc_enter(xfer); 3385 ohci_device_isoc_enter(xfer);
3380 3386
3381 /* and start if the pipe wasn't running */ 3387 /* and start if the pipe wasn't running */
3382 if (!err) 3388 if (!err)
3383 ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); 3389 ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
@@ -3482,36 +3488,36 @@ ohci_device_isoc_enter(usbd_xfer_handle  @@ -3482,36 +3488,36 @@ ohci_device_isoc_enter(usbd_xfer_handle
3482 xfer->actlen = offs; /* XXX pretend we did it all */ 3488 xfer->actlen = offs; /* XXX pretend we did it all */
3483 3489
3484 xfer->status = USBD_IN_PROGRESS; 3490 xfer->status = USBD_IN_PROGRESS;
3485 3491
3486#ifdef OHCI_DEBUG 3492#ifdef OHCI_DEBUG
3487 if (ohcidebug > 5) { 3493 if (ohcidebug > 5) {
3488 DPRINTF(("ohci_device_isoc_enter: frame=%d\n", 3494 DPRINTF(("ohci_device_isoc_enter: frame=%d\n",
3489 O32TOH(sc->sc_hcca->hcca_frame_number))); 3495 O32TOH(sc->sc_hcca->hcca_frame_number)));
3490 ohci_dump_itds(sc, xfer->hcpriv); 3496 ohci_dump_itds(sc, xfer->hcpriv);
3491 ohci_dump_ed(sc, sed); 3497 ohci_dump_ed(sc, sed);
3492 } 3498 }
3493#endif 3499#endif
3494 3500
3495 //mutex_enter(&sc->sc_lock); 3501 mutex_enter(&sc->sc_lock);
3496 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3502 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3497 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3503 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3498 sed->ed.ed_tailp = HTOO32(nsitd->physaddr); 3504 sed->ed.ed_tailp = HTOO32(nsitd->physaddr);
3499 opipe->tail.itd = nsitd; 3505 opipe->tail.itd = nsitd;
3500 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3506 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3501 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 3507 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
3502 sizeof(sed->ed.ed_flags), 3508 sizeof(sed->ed.ed_flags),
3503 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3509 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3504 //mutex_exit(&sc->sc_lock); 3510 mutex_exit(&sc->sc_lock);
3505 3511
3506#ifdef OHCI_DEBUG 3512#ifdef OHCI_DEBUG
3507 if (ohcidebug > 5) { 3513 if (ohcidebug > 5) {
3508 delay(150000); 3514 delay(150000);
3509 DPRINTF(("ohci_device_isoc_enter: after frame=%d\n", 3515 DPRINTF(("ohci_device_isoc_enter: after frame=%d\n",
3510 O32TOH(sc->sc_hcca->hcca_frame_number))); 3516 O32TOH(sc->sc_hcca->hcca_frame_number)));
3511 ohci_dump_itds(sc, xfer->hcpriv); 3517 ohci_dump_itds(sc, xfer->hcpriv);
3512 ohci_dump_ed(sc, sed); 3518 ohci_dump_ed(sc, sed);
3513 } 3519 }
3514#endif 3520#endif
3515} 3521}
3516 3522
3517usbd_status 3523usbd_status
@@ -3539,27 +3545,27 @@ ohci_device_isoc_start(usbd_xfer_handle  @@ -3539,27 +3545,27 @@ ohci_device_isoc_start(usbd_xfer_handle
3539 mutex_exit(&sc->sc_lock); 3545 mutex_exit(&sc->sc_lock);
3540 3546
3541 return (USBD_IN_PROGRESS); 3547 return (USBD_IN_PROGRESS);
3542} 3548}
3543 3549
3544void 3550void
3545ohci_device_isoc_abort(usbd_xfer_handle xfer) 3551ohci_device_isoc_abort(usbd_xfer_handle xfer)
3546{ 3552{
3547 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 3553 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3548 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; 3554 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private;
3549 ohci_soft_ed_t *sed; 3555 ohci_soft_ed_t *sed;
3550 ohci_soft_itd_t *sitd; 3556 ohci_soft_itd_t *sitd;
3551 3557
3552 DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer)); 3558 DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p lock=%p\n", xfer, &sc->sc_lock));
3553 3559
3554 mutex_enter(&sc->sc_lock); 3560 mutex_enter(&sc->sc_lock);
3555 3561
3556 /* Transfer is already done. */ 3562 /* Transfer is already done. */
3557 if (xfer->status != USBD_NOT_STARTED && 3563 if (xfer->status != USBD_NOT_STARTED &&
3558 xfer->status != USBD_IN_PROGRESS) { 3564 xfer->status != USBD_IN_PROGRESS) {
3559 printf("ohci_device_isoc_abort: early return\n"); 3565 printf("ohci_device_isoc_abort: early return\n");
3560 goto done; 3566 goto done;
3561 } 3567 }
3562 3568
3563 /* Give xfer the requested abort code. */ 3569 /* Give xfer the requested abort code. */
3564 xfer->status = USBD_CANCELLED; 3570 xfer->status = USBD_CANCELLED;
3565 3571
@@ -3589,27 +3595,27 @@ ohci_device_isoc_abort(usbd_xfer_handle  @@ -3589,27 +3595,27 @@ ohci_device_isoc_abort(usbd_xfer_handle
3589 3595
3590 usb_delay_ms(&sc->sc_bus, OHCI_ITD_NOFFSET); 3596 usb_delay_ms(&sc->sc_bus, OHCI_ITD_NOFFSET);
3591 3597
3592 mutex_enter(&sc->sc_lock); 3598 mutex_enter(&sc->sc_lock);
3593 3599
3594 /* Run callback. */ 3600 /* Run callback. */
3595 usb_transfer_complete(xfer); 3601 usb_transfer_complete(xfer);
3596 3602
3597 sed->ed.ed_headp = HTOO32(sitd->physaddr); /* unlink TDs */ 3603 sed->ed.ed_headp = HTOO32(sitd->physaddr); /* unlink TDs */
3598 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */ 3604 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */
3599 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3605 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3600 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3606 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3601 3607
3602 done: ; 3608 done:
3603 mutex_exit(&sc->sc_lock); 3609 mutex_exit(&sc->sc_lock);
3604} 3610}
3605 3611
3606void 3612void
3607ohci_device_isoc_done(usbd_xfer_handle xfer) 3613ohci_device_isoc_done(usbd_xfer_handle xfer)
3608{ 3614{
3609 DPRINTFN(1,("ohci_device_isoc_done: xfer=%p\n", xfer)); 3615 DPRINTFN(1,("ohci_device_isoc_done: xfer=%p\n", xfer));
3610} 3616}
3611 3617
3612usbd_status 3618usbd_status
3613ohci_setup_isoc(usbd_pipe_handle pipe) 3619ohci_setup_isoc(usbd_pipe_handle pipe)
3614{ 3620{
3615 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 3621 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;