|
Lines 1-4
Link Here
|
| 1 |
/* $NetBSD: ugen.c,v 1.59 2002/07/11 21:14:28 augustss Exp $ */ |
1 |
/* $NetBSD: ugen.c,v 1.79 2006/03/01 12:38:13 yamt Exp $ */ |
| 2 |
|
2 |
|
| 3 |
/* Also already merged from NetBSD: |
3 |
/* Also already merged from NetBSD: |
| 4 |
* $NetBSD: ugen.c,v 1.61 2002/09/23 05:51:20 simonb Exp $ |
4 |
* $NetBSD: ugen.c,v 1.61 2002/09/23 05:51:20 simonb Exp $ |
|
Lines 284-289
Link Here
|
| 284 |
ugen_make_devnodes(sc); |
284 |
ugen_make_devnodes(sc); |
| 285 |
#endif |
285 |
#endif |
| 286 |
|
286 |
|
|
|
287 |
usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, |
| 288 |
USBDEV(sc->sc_dev)); |
| 289 |
|
| 287 |
USB_ATTACH_SUCCESS_RETURN; |
290 |
USB_ATTACH_SUCCESS_RETURN; |
| 288 |
} |
291 |
} |
| 289 |
|
292 |
|
|
Lines 383-388
Link Here
|
| 383 |
M_WAITOK); |
386 |
M_WAITOK); |
| 384 |
niface_cache = niface; |
387 |
niface_cache = niface; |
| 385 |
|
388 |
|
|
|
389 |
memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints); |
| 386 |
for (ifaceno = 0; ifaceno < niface; ifaceno++) { |
390 |
for (ifaceno = 0; ifaceno < niface; ifaceno++) { |
| 387 |
DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); |
391 |
DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); |
| 388 |
err = usbd_device2interface_handle(dev, ifaceno, &iface); |
392 |
err = usbd_device2interface_handle(dev, ifaceno, &iface); |
|
Lines 511-517
Link Here
|
| 511 |
for (dir = OUT; dir <= IN; dir++) { |
515 |
for (dir = OUT; dir <= IN; dir++) { |
| 512 |
if (flag & (dir == OUT ? FWRITE : FREAD)) { |
516 |
if (flag & (dir == OUT ? FWRITE : FREAD)) { |
| 513 |
sce = &sc->sc_endpoints[endpt][dir]; |
517 |
sce = &sc->sc_endpoints[endpt][dir]; |
| 514 |
if (sce->edesc == 0) |
518 |
if (sce == 0 ||sce->edesc == 0) |
| 515 |
return (ENXIO); |
519 |
return (ENXIO); |
| 516 |
} |
520 |
} |
| 517 |
} |
521 |
} |
|
Lines 650-656
Link Here
|
| 650 |
if (!(flag & (dir == OUT ? FWRITE : FREAD))) |
654 |
if (!(flag & (dir == OUT ? FWRITE : FREAD))) |
| 651 |
continue; |
655 |
continue; |
| 652 |
sce = &sc->sc_endpoints[endpt][dir]; |
656 |
sce = &sc->sc_endpoints[endpt][dir]; |
| 653 |
if (sce->pipeh == NULL) |
657 |
if (sce == NULL || sce->pipeh == NULL) |
| 654 |
continue; |
658 |
continue; |
| 655 |
DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n", |
659 |
DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n", |
| 656 |
endpt, dir, sce)); |
660 |
endpt, dir, sce)); |
|
Lines 835-840
Link Here
|
| 835 |
|
839 |
|
| 836 |
USB_GET_SC(ugen, UGENUNIT(dev), sc); |
840 |
USB_GET_SC(ugen, UGENUNIT(dev), sc); |
| 837 |
|
841 |
|
|
|
842 |
if(sc->sc_dying) |
| 843 |
return (EIO); |
| 844 |
|
| 838 |
UGEN_DEV_REF(dev, sc); |
845 |
UGEN_DEV_REF(dev, sc); |
| 839 |
error = ugen_do_read(sc, endpt, uio, flag); |
846 |
error = ugen_do_read(sc, endpt, uio, flag); |
| 840 |
UGEN_DEV_RELE(dev, sc); |
847 |
UGEN_DEV_RELE(dev, sc); |
|
Lines 933-938
Link Here
|
| 933 |
|
940 |
|
| 934 |
USB_GET_SC(ugen, UGENUNIT(dev), sc); |
941 |
USB_GET_SC(ugen, UGENUNIT(dev), sc); |
| 935 |
|
942 |
|
|
|
943 |
if (sc->sc_dying) |
| 944 |
return (EIO); |
| 945 |
|
| 936 |
UGEN_DEV_REF(dev, sc); |
946 |
UGEN_DEV_REF(dev, sc); |
| 937 |
error = ugen_do_write(sc, endpt, uio, flag); |
947 |
error = ugen_do_write(sc, endpt, uio, flag); |
| 938 |
UGEN_DEV_RELE(dev, sc); |
948 |
UGEN_DEV_RELE(dev, sc); |
|
Lines 969-976
Link Here
|
| 969 |
return; |
979 |
return; |
| 970 |
USB_GET_SC(ugen, UGENUNIT(dev), sc); |
980 |
USB_GET_SC(ugen, UGENUNIT(dev), sc); |
| 971 |
sce = &sc->sc_endpoints[endpt][IN]; |
981 |
sce = &sc->sc_endpoints[endpt][IN]; |
| 972 |
if (sce->pipeh) |
982 |
if (sce) |
| 973 |
usbd_abort_pipe(sce->pipeh); |
983 |
{ |
|
|
984 |
if(sce->pipeh) |
| 985 |
usbd_abort_pipe(sce->pipeh); |
| 986 |
|
| 987 |
if (sce->state & UGEN_ASLP) { |
| 988 |
sce->state &= ~UGEN_ASLP; |
| 989 |
DPRINTFN(5, ("ugenpurge: waking %p\n", sce)); |
| 990 |
wakeup(sce); |
| 991 |
} |
| 992 |
selwakeuppri(&sce->rsel, PZERO); |
| 993 |
} |
| 994 |
sce = &sc->sc_endpoints[endpt][OUT]; |
| 995 |
if (sce) |
| 996 |
{ |
| 997 |
if(sce->pipeh) |
| 998 |
usbd_abort_pipe(sce->pipeh); |
| 999 |
|
| 1000 |
if (sce->state & UGEN_ASLP) { |
| 1001 |
sce->state &= ~UGEN_ASLP; |
| 1002 |
DPRINTFN(5, ("ugenpurge: waking %p\n", sce)); |
| 1003 |
wakeup(sce); |
| 1004 |
} |
| 1005 |
selwakeuppri(&sce->rsel, PZERO); |
| 1006 |
} |
| 974 |
} |
1007 |
} |
| 975 |
#endif |
1008 |
#endif |
| 976 |
|
1009 |
|
|
Lines 994-1004
Link Here
|
| 994 |
for (i = 0; i < USB_MAX_ENDPOINTS; i++) { |
1027 |
for (i = 0; i < USB_MAX_ENDPOINTS; i++) { |
| 995 |
for (dir = OUT; dir <= IN; dir++) { |
1028 |
for (dir = OUT; dir <= IN; dir++) { |
| 996 |
sce = &sc->sc_endpoints[i][dir]; |
1029 |
sce = &sc->sc_endpoints[i][dir]; |
| 997 |
if (sce->pipeh) |
1030 |
if (sce && sce->pipeh) |
| 998 |
usbd_abort_pipe(sce->pipeh); |
1031 |
usbd_abort_pipe(sce->pipeh); |
|
|
1032 |
selwakeuppri(&sce->rsel, PZERO); |
| 999 |
} |
1033 |
} |
| 1000 |
} |
1034 |
} |
| 1001 |
|
1035 |
|
|
|
1036 |
|
| 1002 |
#if defined(__NetBSD__) || defined(__OpenBSD__) |
1037 |
#if defined(__NetBSD__) || defined(__OpenBSD__) |
| 1003 |
s = splusb(); |
1038 |
s = splusb(); |
| 1004 |
if (sc->sc_refcnt > 0) { |
1039 |
if (sc->sc_refcnt > 0) { |
|
Lines 1035-1040
Link Here
|
| 1035 |
destroy_dev(sc->dev); |
1070 |
destroy_dev(sc->dev); |
| 1036 |
#endif |
1071 |
#endif |
| 1037 |
|
1072 |
|
|
|
1073 |
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, |
| 1074 |
USBDEV(sc->sc_dev)); |
| 1075 |
|
| 1038 |
return (0); |
1076 |
return (0); |
| 1039 |
} |
1077 |
} |
| 1040 |
|
1078 |
|
|
Lines 1292-1298
Link Here
|
| 1292 |
/* This flag only affects read */ |
1330 |
/* This flag only affects read */ |
| 1293 |
sce = &sc->sc_endpoints[endpt][IN]; |
1331 |
sce = &sc->sc_endpoints[endpt][IN]; |
| 1294 |
|
1332 |
|
| 1295 |
if (sce->pipeh == NULL) { |
1333 |
if (sce == NULL || sce->pipeh == NULL) { |
| 1296 |
printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n"); |
1334 |
printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n"); |
| 1297 |
return (EIO); |
1335 |
return (EIO); |
| 1298 |
} |
1336 |
} |
|
Lines 1304-1309
Link Here
|
| 1304 |
return (0); |
1342 |
return (0); |
| 1305 |
case USB_SET_TIMEOUT: |
1343 |
case USB_SET_TIMEOUT: |
| 1306 |
sce = &sc->sc_endpoints[endpt][IN]; |
1344 |
sce = &sc->sc_endpoints[endpt][IN]; |
|
|
1345 |
if (sce == NULL |
| 1346 |
/* XXX this shouldn't happen, but the distinction between |
| 1347 |
input and output pipes isn't clear enough. |
| 1348 |
|| sce->pipeh == NULL */ |
| 1349 |
) |
| 1350 |
return (EINVAL); |
| 1307 |
sce->timeout = *(int *)addr; |
1351 |
sce->timeout = *(int *)addr; |
| 1308 |
return (0); |
1352 |
return (0); |
| 1309 |
default: |
1353 |
default: |
|
Lines 1331-1339
Link Here
|
| 1331 |
err = ugen_set_config(sc, *(int *)addr); |
1375 |
err = ugen_set_config(sc, *(int *)addr); |
| 1332 |
switch (err) { |
1376 |
switch (err) { |
| 1333 |
case USBD_NORMAL_COMPLETION: |
1377 |
case USBD_NORMAL_COMPLETION: |
| 1334 |
#if defined(__FreeBSD__) |
|
|
| 1335 |
ugen_make_devnodes(sc); |
| 1336 |
#endif |
| 1337 |
break; |
1378 |
break; |
| 1338 |
case USBD_IN_USE: |
1379 |
case USBD_IN_USE: |
| 1339 |
return (EBUSY); |
1380 |
return (EBUSY); |
|
Lines 1541-1546
Link Here
|
| 1541 |
|
1582 |
|
| 1542 |
USB_GET_SC(ugen, UGENUNIT(dev), sc); |
1583 |
USB_GET_SC(ugen, UGENUNIT(dev), sc); |
| 1543 |
|
1584 |
|
|
|
1585 |
if (sc->sc_dying) |
| 1586 |
return (EIO); |
| 1587 |
|
| 1544 |
UGEN_DEV_REF(dev, sc); |
1588 |
UGEN_DEV_REF(dev, sc); |
| 1545 |
error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p); |
1589 |
error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p); |
| 1546 |
UGEN_DEV_RELE(dev, sc); |
1590 |
UGEN_DEV_RELE(dev, sc); |
|
Lines 1555-1568
Link Here
|
| 1555 |
int revents = 0; |
1599 |
int revents = 0; |
| 1556 |
int s; |
1600 |
int s; |
| 1557 |
|
1601 |
|
|
|
1602 |
/* Do not allow to poll a control endpoint */ |
| 1603 |
if ( UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT ) |
| 1604 |
return (EIO); |
| 1605 |
|
| 1558 |
USB_GET_SC(ugen, UGENUNIT(dev), sc); |
1606 |
USB_GET_SC(ugen, UGENUNIT(dev), sc); |
| 1559 |
|
1607 |
|
| 1560 |
if (sc->sc_dying) |
1608 |
if (sc->sc_dying) |
| 1561 |
return (EIO); |
1609 |
return (EIO); |
| 1562 |
|
1610 |
|
| 1563 |
/* XXX always IN */ |
1611 |
if((events & POLLIN) && (events & POLLOUT)) { |
| 1564 |
sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; |
1612 |
printf("ugenpoll: POLLIN and POLLOUT? We're not handling it, so bail.\n"); |
| 1565 |
#ifdef DIAGNOSTIC |
1613 |
return (EIO); |
|
|
1614 |
} |
| 1615 |
|
| 1616 |
if(events & (POLLIN | POLLRDNORM)) |
| 1617 |
sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; |
| 1618 |
else if(events & (POLLOUT | POLLWRNORM)) |
| 1619 |
sce = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT]; |
| 1620 |
else { |
| 1621 |
printf("ugenpoll: unhandled input event\n"); |
| 1622 |
return (EIO); |
| 1623 |
} |
| 1624 |
|
| 1625 |
if (sce == NULL) |
| 1626 |
return (EIO); |
| 1627 |
|
| 1566 |
if (!sce->edesc) { |
1628 |
if (!sce->edesc) { |
| 1567 |
printf("ugenpoll: no edesc\n"); |
1629 |
printf("ugenpoll: no edesc\n"); |
| 1568 |
return (EIO); |
1630 |
return (EIO); |
|
Lines 1571-1593
Link Here
|
| 1571 |
printf("ugenpoll: no pipe\n"); |
1633 |
printf("ugenpoll: no pipe\n"); |
| 1572 |
return (EIO); |
1634 |
return (EIO); |
| 1573 |
} |
1635 |
} |
| 1574 |
#endif |
|
|
| 1575 |
s = splusb(); |
1636 |
s = splusb(); |
| 1576 |
switch (sce->edesc->bmAttributes & UE_XFERTYPE) { |
1637 |
switch (sce->edesc->bmAttributes & UE_XFERTYPE) { |
| 1577 |
case UE_INTERRUPT: |
1638 |
case UE_INTERRUPT: |
| 1578 |
if (events & (POLLIN | POLLRDNORM)) { |
1639 |
if (sce->q.c_cc > 0) { |
| 1579 |
if (sce->q.c_cc > 0) |
1640 |
if (events & (POLLIN | POLLRDNORM)) |
| 1580 |
revents |= events & (POLLIN | POLLRDNORM); |
1641 |
revents |= events & (POLLIN | POLLRDNORM); |
| 1581 |
else |
1642 |
else if (events & (POLLOUT | POLLWRNORM)) |
| 1582 |
selrecord(p, &sce->rsel); |
1643 |
revents |= events & (POLLOUT | POLLWRNORM); |
|
|
1644 |
} else { |
| 1645 |
selrecord(p, &sce->rsel); |
| 1583 |
} |
1646 |
} |
| 1584 |
break; |
1647 |
break; |
| 1585 |
case UE_ISOCHRONOUS: |
1648 |
case UE_ISOCHRONOUS: |
| 1586 |
if (events & (POLLIN | POLLRDNORM)) { |
1649 |
if (sce->cur != sce->fill) { |
| 1587 |
if (sce->cur != sce->fill) |
1650 |
if (events & (POLLIN | POLLRDNORM)) |
| 1588 |
revents |= events & (POLLIN | POLLRDNORM); |
1651 |
revents |= events & (POLLIN | POLLRDNORM); |
| 1589 |
else |
1652 |
else if (events & (POLLOUT | POLLWRNORM)) |
| 1590 |
selrecord(p, &sce->rsel); |
1653 |
revents |= events & (POLLOUT | POLLWRNORM); |
|
|
1654 |
} else { |
| 1655 |
selrecord(p, &sce->rsel); |
| 1591 |
} |
1656 |
} |
| 1592 |
break; |
1657 |
break; |
| 1593 |
case UE_BULK: |
1658 |
case UE_BULK: |