Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/usb/usb_dev.c
Show First 20 Lines • Show All 872 Lines • ▼ Show 20 Lines | |||||
* usb_open - cdev callback | * usb_open - cdev callback | ||||
*------------------------------------------------------------------------*/ | *------------------------------------------------------------------------*/ | ||||
static int | static int | ||||
usb_open(struct cdev *dev, int fflags, int devtype, struct thread *td) | usb_open(struct cdev *dev, int fflags, int devtype, struct thread *td) | ||||
{ | { | ||||
struct usb_fs_privdata* pd = (struct usb_fs_privdata*)dev->si_drv1; | struct usb_fs_privdata* pd = (struct usb_fs_privdata*)dev->si_drv1; | ||||
struct usb_cdev_refdata refs; | struct usb_cdev_refdata refs; | ||||
struct usb_cdev_privdata *cpd; | struct usb_cdev_privdata *cpd; | ||||
int err, ep; | int err; | ||||
DPRINTFN(2, "%s fflags=0x%08x\n", devtoname(dev), fflags); | DPRINTFN(2, "%s fflags=0x%08x\n", devtoname(dev), fflags); | ||||
KASSERT(fflags & (FREAD|FWRITE), ("invalid open flags")); | KASSERT(fflags & (FREAD|FWRITE), ("invalid open flags")); | ||||
if (((fflags & FREAD) && !(pd->mode & FREAD)) || | if (((fflags & FREAD) && !(pd->mode & FREAD)) || | ||||
((fflags & FWRITE) && !(pd->mode & FWRITE))) { | ((fflags & FWRITE) && !(pd->mode & FWRITE))) { | ||||
DPRINTFN(2, "access mode not supported\n"); | DPRINTFN(2, "access mode not supported\n"); | ||||
return (EPERM); | return (EPERM); | ||||
} | } | ||||
cpd = malloc(sizeof(*cpd), M_USBDEV, M_WAITOK | M_ZERO); | cpd = malloc(sizeof(*cpd), M_USBDEV, M_WAITOK | M_ZERO); | ||||
ep = cpd->ep_addr = pd->ep_addr; | |||||
usb_loc_fill(pd, cpd); | usb_loc_fill(pd, cpd); | ||||
err = usb_ref_device(cpd, &refs, 1); | err = usb_ref_device(cpd, &refs, 1); | ||||
if (err) { | if (err) { | ||||
DPRINTFN(2, "cannot ref device\n"); | DPRINTFN(2, "cannot ref device\n"); | ||||
free(cpd, M_USBDEV); | free(cpd, M_USBDEV); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 505 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
usb_read(struct cdev *dev, struct uio *uio, int ioflag) | usb_read(struct cdev *dev, struct uio *uio, int ioflag) | ||||
{ | { | ||||
struct usb_cdev_refdata refs; | struct usb_cdev_refdata refs; | ||||
struct usb_cdev_privdata* cpd; | struct usb_cdev_privdata* cpd; | ||||
struct usb_fifo *f; | struct usb_fifo *f; | ||||
struct usb_mbuf *m; | struct usb_mbuf *m; | ||||
int fflags; | |||||
int resid; | |||||
int io_len; | int io_len; | ||||
int err; | int err; | ||||
uint8_t tr_data = 0; | uint8_t tr_data = 0; | ||||
err = devfs_get_cdevpriv((void **)&cpd); | err = devfs_get_cdevpriv((void **)&cpd); | ||||
if (err != 0) | if (err != 0) | ||||
return (err); | return (err); | ||||
err = usb_ref_device(cpd, &refs, 0 /* no uref */ ); | err = usb_ref_device(cpd, &refs, 0 /* no uref */ ); | ||||
if (err) | if (err) | ||||
return (ENXIO); | return (ENXIO); | ||||
fflags = cpd->fflags; | |||||
f = refs.rxfifo; | f = refs.rxfifo; | ||||
if (f == NULL) { | if (f == NULL) { | ||||
/* should not happen */ | /* should not happen */ | ||||
usb_unref_device(cpd, &refs); | usb_unref_device(cpd, &refs); | ||||
return (EPERM); | return (EPERM); | ||||
} | } | ||||
resid = uio->uio_resid; | |||||
mtx_lock(f->priv_mtx); | mtx_lock(f->priv_mtx); | ||||
/* check for permanent read error */ | /* check for permanent read error */ | ||||
if (f->flag_iserror) { | if (f->flag_iserror) { | ||||
err = EIO; | err = EIO; | ||||
goto done; | goto done; | ||||
} | } | ||||
/* check if USB-FS interface is active */ | /* check if USB-FS interface is active */ | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
usb_write(struct cdev *dev, struct uio *uio, int ioflag) | usb_write(struct cdev *dev, struct uio *uio, int ioflag) | ||||
{ | { | ||||
struct usb_cdev_refdata refs; | struct usb_cdev_refdata refs; | ||||
struct usb_cdev_privdata* cpd; | struct usb_cdev_privdata* cpd; | ||||
struct usb_fifo *f; | struct usb_fifo *f; | ||||
struct usb_mbuf *m; | struct usb_mbuf *m; | ||||
uint8_t *pdata; | uint8_t *pdata; | ||||
int fflags; | |||||
int resid; | |||||
int io_len; | int io_len; | ||||
int err; | int err; | ||||
uint8_t tr_data = 0; | uint8_t tr_data = 0; | ||||
DPRINTFN(2, "\n"); | DPRINTFN(2, "\n"); | ||||
err = devfs_get_cdevpriv((void **)&cpd); | err = devfs_get_cdevpriv((void **)&cpd); | ||||
if (err != 0) | if (err != 0) | ||||
return (err); | return (err); | ||||
err = usb_ref_device(cpd, &refs, 0 /* no uref */ ); | err = usb_ref_device(cpd, &refs, 0 /* no uref */ ); | ||||
if (err) | if (err) | ||||
return (ENXIO); | return (ENXIO); | ||||
fflags = cpd->fflags; | |||||
f = refs.txfifo; | f = refs.txfifo; | ||||
if (f == NULL) { | if (f == NULL) { | ||||
/* should not happen */ | /* should not happen */ | ||||
usb_unref_device(cpd, &refs); | usb_unref_device(cpd, &refs); | ||||
return (EPERM); | return (EPERM); | ||||
} | } | ||||
resid = uio->uio_resid; | |||||
mtx_lock(f->priv_mtx); | mtx_lock(f->priv_mtx); | ||||
/* check for permanent write error */ | /* check for permanent write error */ | ||||
if (f->flag_iserror) { | if (f->flag_iserror) { | ||||
err = EIO; | err = EIO; | ||||
goto done; | goto done; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 911 Lines • Show Last 20 Lines |