32#ifdef USB_GLOBAL_INCLUDE_FILE
33#include USB_GLOBAL_INCLUDE_FILE
35#ifdef COMPAT_FREEBSD32
36#include <sys/abi_compat.h>
38#include <sys/stdint.h>
39#include <sys/stddef.h>
44#include <sys/kernel.h>
46#include <sys/module.h>
49#include <sys/condvar.h>
50#include <sys/sysctl.h>
52#include <sys/unistd.h>
53#include <sys/callout.h>
54#include <sys/malloc.h>
65#define USB_DEBUG_VAR usb_fifo_debug
82#include <sys/ttycom.h>
83#include <sys/syscallsubr.h>
85#include <machine/stdarg.h>
91static int usb_fifo_debug = 0;
93static SYSCTL_NODE(_hw_usb, OID_AUTO, dev, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
96 &usb_fifo_debug, 0,
"Debug Level");
99#if ((__FreeBSD_version >= 700001) || (__FreeBSD_version == 0) || \
100 ((__FreeBSD_version >= 600034) && (__FreeBSD_version < 700000)))
101#define USB_UCRED struct ucred *ucred,
110static void usb_fifo_close(
struct usb_fifo *,
int);
111static void usb_dev_init(
void *);
112static void usb_dev_init_post(
void *);
113static void usb_dev_uninit(
void *);
114static int usb_fifo_uiomove(
struct usb_fifo *,
void *,
int,
117static struct usb_fifo *usb_fifo_alloc(
struct mtx *);
122static void usb_close(
void *);
127static d_open_t usb_open;
128static d_ioctl_t usb_ioctl;
129static d_read_t usb_read;
130static d_write_t usb_write;
131static d_poll_t usb_poll;
132static d_kqfilter_t usb_kqfilter;
134static d_ioctl_t usb_static_ioctl;
143 .d_version = D_VERSION,
145 .d_ioctl = usb_ioctl,
147 .d_flags = D_TRACKCLOSE,
149 .d_write = usb_write,
151 .d_kqfilter = usb_kqfilter,
154static struct cdev* usb_dev = NULL;
157static struct cdevsw usb_static_devsw = {
158 .d_version = D_VERSION,
159 .d_ioctl = usb_static_ioctl,
164static struct sx usb_sym_lock;
201 DPRINTFN(2,
"cpd=%p need uref=%d\n", cpd, need_uref);
204 memset(crd, 0,
sizeof(*crd));
208 if (cpd->
bus == NULL) {
209 DPRINTFN(2,
"no bus at %u\n", cpd->
bus_index);
213 if (cpd->
udev == NULL) {
214 DPRINTFN(2,
"no device at %u\n", cpd->
dev_index);
219 DPRINTFN(2,
"device is detached\n");
223 DPRINTFN(2,
"ref udev - needed\n");
226 DPRINTFN(2,
"no dev ref\n");
258 if (cpd->
fflags & FWRITE) {
259 ppf = cpd->
udev->fifo;
274 if (cpd->
fflags & FREAD) {
275 ppf = cpd->
udev->fifo;
292 DPRINTFN(2,
"ref write\n");
296 DPRINTFN(2,
"ref read\n");
312 DPRINTFN(2,
"fail\n");
315 memset(crd, 0,
sizeof(*crd));
344 usb_unref_device(cpd, crd);
346 return (usb_ref_device(cpd, crd, 1 ));
360 DPRINTFN(2,
"cpd=%p is_uref=%d\n", cpd, crd->
is_uref);
387usb_fifo_alloc(
struct mtx *mtx)
391 f = malloc(
sizeof(*f), M_USBDEV, M_WAITOK | M_ZERO);
392 cv_init(&f->
cv_io,
"FIFO-IO");
393 cv_init(&f->
cv_drain,
"FIFO-DRAIN");
396 knlist_init_mtx(&f->
selinfo.si_note, mtx);
417 is_tx = (cpd->
fflags & FWRITE) ? 1 : 0;
418 is_rx = (cpd->
fflags & FREAD) ? 1 : 0;
424 DPRINTFN(5,
"Preallocated FIFO\n");
440 KASSERT(e >= 0 && e <= 15, (
"endpoint %d out of range", e));
443 DPRINTFN(5,
"Endpoint device, searching for 0x%02x\n", e);
444 for (
n = 0;;
n += 2) {
451 DPRINTFN(5,
"out of FIFOs\n");
468 }
else if (no_null) {
485 }
else if (no_null) {
495 DPRINTFN(5,
"ep out of range\n");
496 return (is_busy ? EBUSY : EINVAL);
500 if ((e != 0) && is_busy) {
505 DPRINTFN(5,
"busy\n");
513 DPRINTFN(5,
"dev_get_endpoint(%d, 0x%x)\n", e,
USB_FIFO_TX);
515 DPRINTFN(5,
"dev_get_endpoint returned NULL\n");
520 DPRINTFN(5,
"could not alloc tx fifo\n");
538 DPRINTFN(5,
"dev_get_endpoint(%d, 0x%x)\n", e,
USB_FIFO_RX);
540 DPRINTFN(5,
"dev_get_endpoint returned NULL\n");
545 DPRINTFN(5,
"could not alloc rx fifo\n");
566 DPRINTFN(5,
"fifo index = %d\n",
n);
584 for (
n = 0;
n != 2;
n++) {
598 DPRINTFN(0,
"USB FIFO %p has not been linked\n", f);
612 cv_broadcast(&f->
cv_io);
630 usb_fifo_close(f, 0);
632 cv_destroy(&f->
cv_io);
635 knlist_clear(&f->
selinfo.si_note, 0);
637 knlist_destroy(&f->
selinfo.si_note);
643usb_dev_get_ep(
struct usb_device *udev, uint8_t ep_index, uint8_t dir)
671 if (ep->
edesc == NULL) {
693 DPRINTFN(2,
"no FIFO\n");
697 fflags &= ~(FWRITE | FREAD);
781usb_fifo_close(
struct usb_fifo *f,
int fflags)
798 KNOTE_LOCKED(&f->
selinfo.si_note, 0);
808 kern_psignal(f->
async_p, SIGIO);
813 fflags &= ~(FWRITE | FREAD);
860 DPRINTFN(2,
"Sleeping at close!\n");
874usb_open(
struct cdev *dev,
int fflags,
int devtype,
struct thread *td)
881 DPRINTFN(2,
"%s fflags=0x%08x\n", devtoname(dev), fflags);
883 KASSERT(fflags & (FREAD|FWRITE), (
"invalid open flags"));
884 if (((fflags & FREAD) && !(pd->
mode & FREAD)) ||
885 ((fflags & FWRITE) && !(pd->
mode & FWRITE))) {
886 DPRINTFN(2,
"access mode not supported\n");
890 cpd = malloc(
sizeof(*cpd), M_USBDEV, M_WAITOK | M_ZERO);
892 usb_loc_fill(pd, cpd);
893 err = usb_ref_device(cpd, &refs, 1);
895 DPRINTFN(2,
"cannot ref device\n");
902 err = usb_fifo_create(cpd, &refs);
905 DPRINTFN(2,
"cannot create fifo\n");
906 usb_unref_device(cpd, &refs);
910 if (fflags & FREAD) {
911 err = usb_fifo_open(cpd, refs.rxfifo, fflags);
913 DPRINTFN(2,
"read open failed\n");
914 usb_unref_device(cpd, &refs);
919 if (fflags & FWRITE) {
920 err = usb_fifo_open(cpd, refs.txfifo, fflags);
922 DPRINTFN(2,
"write open failed\n");
923 if (fflags & FREAD) {
924 usb_fifo_close(refs.rxfifo, fflags);
926 usb_unref_device(cpd, &refs);
931 usb_unref_device(cpd, &refs);
932 devfs_set_cdevpriv(cpd, usb_close);
947 DPRINTFN(2,
"cpd=%p\n", cpd);
949 err = usb_ref_device(cpd, &refs,
952 DPRINTFN(2,
"Cannot grab USB reference when "
953 "closing USB file handle\n");
956 if (cpd->
fflags & FREAD) {
957 usb_fifo_close(refs.rxfifo, cpd->
fflags);
959 if (cpd->
fflags & FWRITE) {
960 usb_fifo_close(refs.txfifo, cpd->
fflags);
962 usb_unref_device(cpd, &refs);
968usb_dev_init(
void *arg)
970 mtx_init(&
usb_ref_lock,
"USB ref mutex", NULL, MTX_DEF);
971 sx_init(&usb_sym_lock,
"USB sym mutex");
972 TAILQ_INIT(&usb_sym_head);
978SYSINIT(usb_dev_init, SI_SUB_KLD, SI_ORDER_FIRST, usb_dev_init, NULL);
981usb_dev_init_post(
void *arg)
987 usb_dev = make_dev(&usb_static_devsw, 0, UID_ROOT, GID_OPERATOR,
989 if (usb_dev == NULL) {
990 DPRINTFN(0,
"Could not create usb bus device\n");
994SYSINIT(usb_dev_init_post, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, usb_dev_init_post, NULL);
997usb_dev_uninit(
void *arg)
999 if (usb_dev != NULL) {
1000 destroy_dev(usb_dev);
1004 sx_destroy(&usb_sym_lock);
1007SYSUNINIT(usb_dev_uninit, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb_dev_uninit, NULL);
1010usb_ioctl_f_sub(
struct usb_fifo *f, u_long cmd,
void *addr,
1050 DPRINTFN(3,
"cmd 0x%lx = %d\n", cmd,
error);
1058usb_ioctl(
struct cdev *dev, u_long cmd, caddr_t addr,
int fflag,
struct thread* td)
1066 DPRINTFN(2,
"cmd=0x%lx\n", cmd);
1068 err = devfs_get_cdevpriv((
void **)&cpd);
1077 err = usb_ref_device(cpd, &refs, 0 );
1086 if (fflags & FWRITE) {
1088 err = usb_ioctl_f_sub(f, cmd, addr, td);
1090 if (fflags & FREAD) {
1092 err = usb_ioctl_f_sub(f, cmd, addr, td);
1094 KASSERT(f != NULL, (
"fifo not found"));
1095 if (err != ENOIOCTL)
1100 DPRINTFN(2,
"f_ioctl cmd 0x%lx = %d\n", cmd, err);
1102 if (err != ENOIOCTL)
1105 if (usb_usb_ref_device(cpd, &refs)) {
1112 DPRINTFN(2,
"f_ioctl_post cmd 0x%lx = %d\n", cmd, err);
1114 if (err == ENOIOCTL)
1123 usb_unref_device(cpd, &refs);
1127 while (usb_ref_device(cpd, &refs, 1 )) {
1128 if (usb_ref_device(cpd, &refs, 0)) {
1132 usb_unref_device(cpd, &refs);
1138 usb_unref_device(cpd, &refs);
1143usb_filter_detach(
struct knote *kn)
1146 knlist_remove(&f->
selinfo.si_note, kn, 0);
1150usb_filter_write(
struct knote *kn,
long hint)
1191usb_filter_read(
struct knote *kn,
long hint)
1235static struct filterops usb_filtops_write = {
1237 .f_detach = usb_filter_detach,
1238 .f_event = usb_filter_write,
1241static struct filterops usb_filtops_read = {
1243 .f_detach = usb_filter_detach,
1244 .f_event = usb_filter_read,
1249usb_kqfilter(
struct cdev* dev,
struct knote *kn)
1259 if (devfs_get_cdevpriv((
void **)&cpd) != 0 ||
1260 usb_ref_device(cpd, &refs, 0) != 0)
1263 fflags = cpd->fflags;
1266 switch (kn->kn_filter) {
1268 if (fflags & FWRITE) {
1270 kn->kn_fop = &usb_filtops_write;
1275 if (fflags & FREAD) {
1277 kn->kn_fop = &usb_filtops_read;
1289 knlist_add(&f->
selinfo.si_note, kn, 1);
1293 usb_unref_device(cpd, &refs);
1299usb_poll(
struct cdev* dev,
int events,
struct thread* td)
1305 int fflags, revents;
1307 if (devfs_get_cdevpriv((
void **)&cpd) != 0 ||
1308 usb_ref_device(cpd, &refs, 0) != 0)
1310 (POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM));
1312 fflags = cpd->fflags;
1316 if ((events & (POLLOUT | POLLWRNORM)) &&
1317 (fflags & FWRITE)) {
1322 if (!refs.is_usbfs) {
1346 revents |= events & (POLLOUT | POLLWRNORM);
1354 if ((events & (POLLIN | POLLRDNORM)) &&
1360 if (!refs.is_usbfs) {
1384 revents |= events & (POLLIN | POLLRDNORM);
1389 if (!refs.is_usbfs) {
1397 usb_unref_device(cpd, &refs);
1402usb_read(
struct cdev *dev,
struct uio *uio,
int ioflag)
1410 uint8_t tr_data = 0;
1412 err = devfs_get_cdevpriv((
void **)&cpd);
1416 err = usb_ref_device(cpd, &refs, 0 );
1423 usb_unref_device(cpd, &refs);
1435 if (refs.is_usbfs) {
1443 while (uio->uio_resid > 0) {
1451 if (ioflag & IO_NDELAY) {
1479 DPRINTFN(2,
"transfer %d bytes from %p\n",
1482 err = usb_fifo_uiomove(f,
1510 usb_unref_device(cpd, &refs);
1516usb_write(
struct cdev *dev,
struct uio *uio,
int ioflag)
1525 uint8_t tr_data = 0;
1529 err = devfs_get_cdevpriv((
void **)&cpd);
1533 err = usb_ref_device(cpd, &refs, 0 );
1540 usb_unref_device(cpd, &refs);
1552 if (refs.is_usbfs) {
1569 if (ioflag & IO_NDELAY) {
1591 if (io_len > uio->uio_resid)
1592 io_len = uio->uio_resid;
1597 if (io_len > uio->uio_resid)
1598 io_len = uio->uio_resid;
1602 DPRINTFN(2,
"transfer %d bytes to %p\n",
1605 err = usb_fifo_uiomove(f, pdata, io_len, uio);
1641 }
while (uio->uio_resid > 0);
1645 usb_unref_device(cpd, &refs);
1651usb_static_ioctl(
struct cdev *dev, u_long cmd, caddr_t data,
int fflag,
1656#ifdef COMPAT_FREEBSD32
1657 struct usb_read_dir32 *urd32;
1667 u.urd->urd_startentry, u.urd->urd_maxlen);
1669#ifdef COMPAT_FREEBSD32
1670 case USB_READ_DIR32:
1672 u.urd32->urd_startentry, u.urd32->urd_maxlen);
1686 err = priv_check(curthread, PRIV_DRIVER);
1699usb_fifo_uiomove(
struct usb_fifo *f,
void *cp,
1700 int n,
struct uio *uio)
1710 error = uiomove(cp,
n, uio);
1744 cv_broadcast(&f->
cv_io);
1753 KNOTE_LOCKED(&f->
selinfo.si_note, 0);
1761 kern_psignal(f->
async_p, SIGIO);
1767usb_fifo_dummy_open(
struct usb_fifo *fifo,
int fflags)
1773usb_fifo_dummy_close(
struct usb_fifo *fifo,
int fflags)
1779usb_fifo_dummy_ioctl(
struct usb_fifo *fifo, u_long cmd,
void *addr,
int fflags)
1785usb_fifo_dummy_cmd(
struct usb_fifo *fifo)
1796 pm->
f_open = &usb_fifo_dummy_open;
1799 pm->
f_close = &usb_fifo_dummy_close;
1802 pm->
f_ioctl = &usb_fifo_dummy_ioctl;
1832 struct usb_fifo_sc *f_sc, uint16_t unit, int16_t subunit,
1833 uint8_t iface_index, uid_t uid, gid_t gid,
int mode)
1847 usb_fifo_check_methods(pm);
1853 for (
n = 0;;
n += 2) {
1872 if ((f_tx == NULL) || (f_rx == NULL)) {
1901 for (
n = 0;
n != 4;
n++) {
1906 if (snprintf(devname,
sizeof(devname),
1913 if (snprintf(devname,
sizeof(devname),
1933 f_sc->
dev = usb_make_dev(
udev, devname, -1,
1935 FREAD|FWRITE, uid, gid, mode);
1938 DPRINTFN(2,
"attached %p/%p\n", f_tx, f_rx);
1961 M_USBDEV, &temp_q, bufsize, nbuf);
1963 if (queue_data == NULL && bufsize != 0 && nbuf != 0)
2006 free(queue_data, M_USBDEV);
2021 usb_destroy_dev(f_sc->
dev);
2025 DPRINTFN(2,
"detached %p\n", f_sc);
2058 while (
len || (what == 1)) {
2072 if ((
len == 0) && (what == 1)) {
2079 if ((
len == 0) || (what == 1)) {
2095 while (
len || (what == 1)) {
2109 if ((
len == 0) && (what == 1)) {
2116 if ((
len == 0) || (what == 1)) {
2167 uint8_t tr_data = 0;
2183 actlen[0] += io_len;
2229 uint8_t tr_data = 0;
2245 actlen[0] += io_len;
2320 ps = malloc(
sizeof(*ps), M_USBDEV, M_WAITOK);
2327 sx_xlock(&usb_sym_lock);
2328 TAILQ_INSERT_TAIL(&usb_sym_head, ps, sym_entry);
2329 sx_unlock(&usb_sym_lock);
2342 sx_xlock(&usb_sym_lock);
2343 TAILQ_REMOVE(&usb_sym_head, ps, sym_entry);
2344 sx_unlock(&usb_sym_lock);
2365 sx_xlock(&usb_sym_lock);
2367 TAILQ_FOREACH(ps, &usb_sym_head, sym_entry) {
2381 if (startentry != 0) {
2386 if (temp > user_len) {
2438 if ((user_len != 0) && (
error == 0)) {
2444 sx_unlock(&usb_sym_lock);
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB DWC OTG")
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN, &dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2/3 - ULPI/HSIC/INTERNAL/UTMI+")
struct usb_device ** devices
enum usb_hc_mode usb_mode
struct usb_endpoint ctrl_ep
uint8_t re_enumerate_wait
struct usb_device_flags flags
struct usb_endpoint_descriptor * edesc
usb_fifo_ioctl_t * f_ioctl_post
usb_fifo_close_t * f_close
usb_fifo_cmd_t * f_start_read
usb_fifo_filter_t * f_filter_read
usb_fifo_ioctl_t * f_ioctl
usb_fifo_cmd_t * f_start_write
usb_fifo_cmd_t * f_stop_read
usb_fifo_cmd_t * f_stop_write
usb_fifo_filter_t * f_filter_write
struct usb_fs_privdata * dev
struct usb_ifqueue free_q
uint8_t flag_write_defrag
struct usb_ifqueue used_q
uint8_t flag_have_fragment
struct usb_cdev_privdata * curr_cpd
struct usb_symlink * symlink[2]
struct usb_fifo_methods * methods
void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
SYSUNINIT(usb_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb_bus_unload, NULL)
#define USB_ADD_BYTES(ptr, size)
int usb_read_symlink(uint8_t *user_ptr, uint32_t startentry, uint32_t user_len)
struct usb_symlink * usb_alloc_symlink(const char *target)
void usb_free_symlink(struct usb_symlink *ps)
void usb_fifo_signal(struct usb_fifo *fifo)
int usb_fifo_wait(struct usb_fifo *fifo)
void usbd_enum_unlock(struct usb_device *udev)
struct usb_endpoint * usbd_get_ep_by_addr(struct usb_device *udev, uint8_t ea_val)
TAILQ_HEAD(, urb) bsd_urb_list
usb_quirk_ioctl_t * usb_quirk_ioctl_p
devclass_t usb_devclass_ptr
#define USB_PROC_GET_GID(td)
#define USB_TD_GET_PROC(td)
struct usb_fifo_methods usb_ugen_methods
#define USB_QUIRK_NAME_GET
#define USB_DEV_QUIRK_ADD
#define USB_DEV_QUIRK_REMOVE
#define USB_DEV_QUIRK_GET
void * usb_alloc_mbufs(struct malloc_type *type, struct usb_ifqueue *ifq, usb_size_t block_size, uint16_t nblocks)
#define USB_IF_DEQUEUE(ifq, m)
#define USB_IF_ENQUEUE(ifq, m)
#define USB_MBUF_RESET(m)
#define USB_IF_POLL(ifq, m)
#define USB_IF_PREPEND(ifq, m)
SYSINIT(usb_quirk_init, SI_SUB_LOCK, SI_ORDER_FIRST, usb_quirk_init, NULL)
void usb_pause_mtx(struct mtx *mtx, int timo)
int usb_fifo_alloc_buffer(struct usb_fifo *f, uint32_t bufsize, uint16_t nbuf)
#define USB_DEFAULT_TIMEOUT
uint8_t usb_fifo_get_data_buffer(struct usb_fifo *f, void **pptr, usb_size_t *plen)
#define USB_MTX_ASSERT(_m, _t)
int() usb_fifo_ioctl_t(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags)
void * usb_fifo_softc(struct usb_fifo *fifo)
void() usb_fifo_close_t(struct usb_fifo *fifo, int fflags)
void usb_fifo_detach(struct usb_fifo_sc *f_sc)
void usb_fifo_wakeup(struct usb_fifo *f)
void usb_fifo_put_data(struct usb_fifo *fifo, struct usb_page_cache *pc, usb_frlength_t offset, usb_frlength_t len, uint8_t what)
void usb_fifo_free(struct usb_fifo *f)
void usb_fifo_put_data_linear(struct usb_fifo *fifo, void *ptr, usb_size_t len, uint8_t what)
void usb_fifo_get_data_error(struct usb_fifo *fifo)
int usb_fifo_attach(struct usb_device *udev, void *priv_sc, struct mtx *priv_mtx, struct usb_fifo_methods *pm, struct usb_fifo_sc *f_sc, uint16_t unit, int16_t subunit, uint8_t iface_index, uid_t uid, gid_t gid, int mode)
void() usb_fifo_cmd_t(struct usb_fifo *fifo)
void usb_fifo_set_write_defrag(struct usb_fifo *, uint8_t)
void usb_fifo_free_buffer(struct usb_fifo *f)
void usb_fifo_put_data_error(struct usb_fifo *fifo)
uint8_t usb_fifo_get_data(struct usb_fifo *fifo, struct usb_page_cache *pc, usb_frlength_t offset, usb_frlength_t len, usb_frlength_t *actlen, uint8_t what)
void usb_fifo_reset(struct usb_fifo *f)
uint8_t usb_fifo_put_data_buffer(struct usb_fifo *f, void *ptr, usb_size_t len)
#define USB_MS_TO_TICKS(ms)
uint8_t usb_fifo_get_data_linear(struct usb_fifo *fifo, void *ptr, usb_size_t len, usb_size_t *actlen, uint8_t what)
int() usb_fifo_open_t(struct usb_fifo *fifo, int fflags)
void usb_fifo_set_close_zlp(struct usb_fifo *, uint8_t)
uint32_t usb_fifo_put_bytes_max(struct usb_fifo *fifo)