102ac6454SAndrew Thompson /* $FreeBSD$ */ 202ac6454SAndrew Thompson /*- 302ac6454SAndrew Thompson * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 402ac6454SAndrew Thompson * 502ac6454SAndrew Thompson * Redistribution and use in source and binary forms, with or without 602ac6454SAndrew Thompson * modification, are permitted provided that the following conditions 702ac6454SAndrew Thompson * are met: 802ac6454SAndrew Thompson * 1. Redistributions of source code must retain the above copyright 902ac6454SAndrew Thompson * notice, this list of conditions and the following disclaimer. 1002ac6454SAndrew Thompson * 2. Redistributions in binary form must reproduce the above copyright 1102ac6454SAndrew Thompson * notice, this list of conditions and the following disclaimer in the 1202ac6454SAndrew Thompson * documentation and/or other materials provided with the distribution. 1302ac6454SAndrew Thompson * 1402ac6454SAndrew Thompson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1502ac6454SAndrew Thompson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1602ac6454SAndrew Thompson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1702ac6454SAndrew Thompson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1802ac6454SAndrew Thompson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1902ac6454SAndrew Thompson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2002ac6454SAndrew Thompson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2102ac6454SAndrew Thompson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2202ac6454SAndrew Thompson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2302ac6454SAndrew Thompson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2402ac6454SAndrew Thompson * SUCH DAMAGE. 2502ac6454SAndrew Thompson */ 2602ac6454SAndrew Thompson 2702ac6454SAndrew Thompson #ifndef _USB2_DEV_H_ 2802ac6454SAndrew Thompson #define _USB2_DEV_H_ 2902ac6454SAndrew Thompson 3002ac6454SAndrew Thompson #include <sys/file.h> 3102ac6454SAndrew Thompson #include <sys/vnode.h> 3202ac6454SAndrew Thompson #include <sys/poll.h> 3302ac6454SAndrew Thompson #include <sys/signalvar.h> 3402ac6454SAndrew Thompson #include <sys/conf.h> 3502ac6454SAndrew Thompson #include <sys/fcntl.h> 3602ac6454SAndrew Thompson #include <sys/proc.h> 3702ac6454SAndrew Thompson 3802ac6454SAndrew Thompson #define USB_FIFO_TX 0 3902ac6454SAndrew Thompson #define USB_FIFO_RX 1 4002ac6454SAndrew Thompson 4102ac6454SAndrew Thompson struct usb2_fifo; 4202ac6454SAndrew Thompson struct usb2_mbuf; 4302ac6454SAndrew Thompson 44ee3e3ff5SAndrew Thompson typedef int (usb2_fifo_open_t)(struct usb2_fifo *fifo, int fflags); 45ee3e3ff5SAndrew Thompson typedef void (usb2_fifo_close_t)(struct usb2_fifo *fifo, int fflags); 46ee3e3ff5SAndrew Thompson typedef int (usb2_fifo_ioctl_t)(struct usb2_fifo *fifo, u_long cmd, void *addr, int fflags); 4702ac6454SAndrew Thompson typedef void (usb2_fifo_cmd_t)(struct usb2_fifo *fifo); 4802ac6454SAndrew Thompson typedef void (usb2_fifo_filter_t)(struct usb2_fifo *fifo, struct usb2_mbuf *m); 4902ac6454SAndrew Thompson 5002ac6454SAndrew Thompson struct usb2_symlink { 5102ac6454SAndrew Thompson TAILQ_ENTRY(usb2_symlink) sym_entry; 5202ac6454SAndrew Thompson char src_path[32]; /* Source path - including terminating 5302ac6454SAndrew Thompson * zero */ 5402ac6454SAndrew Thompson char dst_path[32]; /* Destination path - including 5502ac6454SAndrew Thompson * terminating zero */ 5602ac6454SAndrew Thompson uint8_t src_len; /* String length */ 5702ac6454SAndrew Thompson uint8_t dst_len; /* String length */ 5802ac6454SAndrew Thompson }; 5902ac6454SAndrew Thompson 6002ac6454SAndrew Thompson /* 6102ac6454SAndrew Thompson * Locking note for the following functions. All the 6202ac6454SAndrew Thompson * "usb2_fifo_cmd_t" and "usb2_fifo_filter_t" functions are called 6302ac6454SAndrew Thompson * locked. The others are called unlocked. 6402ac6454SAndrew Thompson */ 6502ac6454SAndrew Thompson struct usb2_fifo_methods { 6602ac6454SAndrew Thompson usb2_fifo_open_t *f_open; 6702ac6454SAndrew Thompson usb2_fifo_close_t *f_close; 6802ac6454SAndrew Thompson usb2_fifo_ioctl_t *f_ioctl; 6902ac6454SAndrew Thompson /* 7002ac6454SAndrew Thompson * NOTE: The post-ioctl callback is called after the USB reference 7102ac6454SAndrew Thompson * gets locked in the IOCTL handler: 7202ac6454SAndrew Thompson */ 7302ac6454SAndrew Thompson usb2_fifo_ioctl_t *f_ioctl_post; 7402ac6454SAndrew Thompson usb2_fifo_cmd_t *f_start_read; 7502ac6454SAndrew Thompson usb2_fifo_cmd_t *f_stop_read; 7602ac6454SAndrew Thompson usb2_fifo_cmd_t *f_start_write; 7702ac6454SAndrew Thompson usb2_fifo_cmd_t *f_stop_write; 7802ac6454SAndrew Thompson usb2_fifo_filter_t *f_filter_read; 7902ac6454SAndrew Thompson usb2_fifo_filter_t *f_filter_write; 8002ac6454SAndrew Thompson const char *basename[4]; 8102ac6454SAndrew Thompson const char *postfix[4]; 8202ac6454SAndrew Thompson }; 8302ac6454SAndrew Thompson 8402ac6454SAndrew Thompson /* 85ee3e3ff5SAndrew Thompson * Private per-device information. 86ee3e3ff5SAndrew Thompson */ 87ee3e3ff5SAndrew Thompson struct usb2_cdev_privdata { 88ee3e3ff5SAndrew Thompson struct usb2_bus *bus; 89ee3e3ff5SAndrew Thompson struct usb2_device *udev; 90ee3e3ff5SAndrew Thompson struct usb2_interface *iface; 91ee3e3ff5SAndrew Thompson struct usb2_fifo *rxfifo; 92ee3e3ff5SAndrew Thompson struct usb2_fifo *txfifo; 93ee3e3ff5SAndrew Thompson int bus_index; /* bus index */ 94ee3e3ff5SAndrew Thompson int dev_index; /* device index */ 95ee3e3ff5SAndrew Thompson int ep_addr; /* endpoint address */ 967214348fSAndrew Thompson int fflags; 97ee3e3ff5SAndrew Thompson uint8_t fifo_index; /* FIFO index */ 98ee3e3ff5SAndrew Thompson uint8_t is_read; /* location has read access */ 99ee3e3ff5SAndrew Thompson uint8_t is_write; /* location has write access */ 100ee3e3ff5SAndrew Thompson uint8_t is_uref; /* USB refcount decr. needed */ 101ee3e3ff5SAndrew Thompson uint8_t is_usbfs; /* USB-FS is active */ 102ee3e3ff5SAndrew Thompson }; 103ee3e3ff5SAndrew Thompson 104ee3e3ff5SAndrew Thompson struct usb2_fs_privdata { 105ee3e3ff5SAndrew Thompson int bus_index; 106ee3e3ff5SAndrew Thompson int dev_index; 107ee3e3ff5SAndrew Thompson int ep_addr; 108ee3e3ff5SAndrew Thompson int mode; 109ee3e3ff5SAndrew Thompson int fifo_index; 110ee3e3ff5SAndrew Thompson struct cdev *cdev; 111ee3e3ff5SAndrew Thompson 112ee3e3ff5SAndrew Thompson LIST_ENTRY(usb2_fs_privdata) pd_next; 113ee3e3ff5SAndrew Thompson }; 114ee3e3ff5SAndrew Thompson 115ee3e3ff5SAndrew Thompson /* 11602ac6454SAndrew Thompson * Most of the fields in the "usb2_fifo" structure are used by the 11702ac6454SAndrew Thompson * generic USB access layer. 11802ac6454SAndrew Thompson */ 11902ac6454SAndrew Thompson struct usb2_fifo { 12002ac6454SAndrew Thompson struct usb2_ifqueue free_q; 12102ac6454SAndrew Thompson struct usb2_ifqueue used_q; 12202ac6454SAndrew Thompson struct selinfo selinfo; 12302ac6454SAndrew Thompson struct cv cv_io; 12402ac6454SAndrew Thompson struct cv cv_drain; 12502ac6454SAndrew Thompson struct usb2_fifo_methods *methods; 12602ac6454SAndrew Thompson struct usb2_symlink *symlink[2];/* our symlinks */ 12702ac6454SAndrew Thompson struct proc *async_p; /* process that wants SIGIO */ 12802ac6454SAndrew Thompson struct usb2_fs_endpoint *fs_ep_ptr; 12902ac6454SAndrew Thompson struct usb2_device *udev; 13002ac6454SAndrew Thompson struct usb2_xfer *xfer[2]; 13102ac6454SAndrew Thompson struct usb2_xfer **fs_xfer; 13202ac6454SAndrew Thompson struct mtx *priv_mtx; /* client data */ 1337214348fSAndrew Thompson /* set if FIFO is opened by a FILE: */ 1347214348fSAndrew Thompson struct usb2_cdev_privdata *curr_cpd; 13502ac6454SAndrew Thompson void *priv_sc0; /* client data */ 13602ac6454SAndrew Thompson void *priv_sc1; /* client data */ 13702ac6454SAndrew Thompson void *queue_data; 13802ac6454SAndrew Thompson uint32_t timeout; /* timeout in milliseconds */ 13902ac6454SAndrew Thompson uint32_t bufsize; /* BULK and INTERRUPT buffer size */ 14002ac6454SAndrew Thompson uint16_t nframes; /* for isochronous mode */ 14102ac6454SAndrew Thompson uint16_t dev_ep_index; /* our device endpoint index */ 14202ac6454SAndrew Thompson uint8_t flag_sleeping; /* set if FIFO is sleeping */ 14302ac6454SAndrew Thompson uint8_t flag_iscomplete; /* set if a USB transfer is complete */ 14402ac6454SAndrew Thompson uint8_t flag_iserror; /* set if FIFO error happened */ 14502ac6454SAndrew Thompson uint8_t flag_isselect; /* set if FIFO is selected */ 14602ac6454SAndrew Thompson uint8_t flag_flushing; /* set if FIFO is flushing data */ 14702ac6454SAndrew Thompson uint8_t flag_short; /* set if short_ok or force_short 14802ac6454SAndrew Thompson * transfer flags should be set */ 14902ac6454SAndrew Thompson uint8_t flag_stall; /* set if clear stall should be run */ 15002ac6454SAndrew Thompson uint8_t iface_index; /* set to the interface we belong to */ 15102ac6454SAndrew Thompson uint8_t fifo_index; /* set to the FIFO index in "struct 15202ac6454SAndrew Thompson * usb2_device" */ 15302ac6454SAndrew Thompson uint8_t fs_ep_max; 15402ac6454SAndrew Thompson uint8_t fifo_zlp; /* zero length packet count */ 15502ac6454SAndrew Thompson uint8_t refcount; 15602ac6454SAndrew Thompson #define USB_FIFO_REF_MAX 0xFF 15702ac6454SAndrew Thompson }; 15802ac6454SAndrew Thompson 15902ac6454SAndrew Thompson struct usb2_fifo_sc { 16002ac6454SAndrew Thompson struct usb2_fifo *fp[2]; 161ee3e3ff5SAndrew Thompson struct cdev* dev; 16202ac6454SAndrew Thompson }; 16302ac6454SAndrew Thompson 164ee3e3ff5SAndrew Thompson extern struct cdevsw usb2_devsw; 165ee3e3ff5SAndrew Thompson 16602ac6454SAndrew Thompson int usb2_fifo_wait(struct usb2_fifo *fifo); 16702ac6454SAndrew Thompson void usb2_fifo_signal(struct usb2_fifo *fifo); 16802ac6454SAndrew Thompson int usb2_fifo_alloc_buffer(struct usb2_fifo *f, uint32_t bufsize, 16902ac6454SAndrew Thompson uint16_t nbuf); 17002ac6454SAndrew Thompson void usb2_fifo_free_buffer(struct usb2_fifo *f); 17102ac6454SAndrew Thompson int usb2_fifo_attach(struct usb2_device *udev, void *priv_sc, 17202ac6454SAndrew Thompson struct mtx *priv_mtx, struct usb2_fifo_methods *pm, 17302ac6454SAndrew Thompson struct usb2_fifo_sc *f_sc, uint16_t unit, uint16_t subunit, 174ee3e3ff5SAndrew Thompson uint8_t iface_index, uid_t uid, gid_t gid, int mode); 17502ac6454SAndrew Thompson void usb2_fifo_detach(struct usb2_fifo_sc *f_sc); 17602ac6454SAndrew Thompson uint32_t usb2_fifo_put_bytes_max(struct usb2_fifo *fifo); 17702ac6454SAndrew Thompson void usb2_fifo_put_data(struct usb2_fifo *fifo, struct usb2_page_cache *pc, 17802ac6454SAndrew Thompson uint32_t offset, uint32_t len, uint8_t what); 17902ac6454SAndrew Thompson void usb2_fifo_put_data_linear(struct usb2_fifo *fifo, void *ptr, 18002ac6454SAndrew Thompson uint32_t len, uint8_t what); 18102ac6454SAndrew Thompson uint8_t usb2_fifo_put_data_buffer(struct usb2_fifo *f, void *ptr, uint32_t len); 18202ac6454SAndrew Thompson void usb2_fifo_put_data_error(struct usb2_fifo *fifo); 18302ac6454SAndrew Thompson uint8_t usb2_fifo_get_data(struct usb2_fifo *fifo, struct usb2_page_cache *pc, 18402ac6454SAndrew Thompson uint32_t offset, uint32_t len, uint32_t *actlen, uint8_t what); 18502ac6454SAndrew Thompson uint8_t usb2_fifo_get_data_linear(struct usb2_fifo *fifo, void *ptr, 18602ac6454SAndrew Thompson uint32_t len, uint32_t *actlen, uint8_t what); 18702ac6454SAndrew Thompson uint8_t usb2_fifo_get_data_buffer(struct usb2_fifo *f, void **pptr, 18802ac6454SAndrew Thompson uint32_t *plen); 18902ac6454SAndrew Thompson void usb2_fifo_get_data_error(struct usb2_fifo *fifo); 19002ac6454SAndrew Thompson uint8_t usb2_fifo_opened(struct usb2_fifo *fifo); 19102ac6454SAndrew Thompson void usb2_fifo_free(struct usb2_fifo *f); 19202ac6454SAndrew Thompson void usb2_fifo_reset(struct usb2_fifo *f); 19302ac6454SAndrew Thompson void usb2_fifo_wakeup(struct usb2_fifo *f); 194ee3e3ff5SAndrew Thompson struct usb2_symlink *usb2_alloc_symlink(const char *target); 19502ac6454SAndrew Thompson void usb2_free_symlink(struct usb2_symlink *ps); 19602ac6454SAndrew Thompson int usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry, 19702ac6454SAndrew Thompson uint32_t user_len); 1987214348fSAndrew Thompson void usb2_fifo_set_close_zlp(struct usb2_fifo *, uint8_t); 19902ac6454SAndrew Thompson 20002ac6454SAndrew Thompson #endif /* _USB2_DEV_H_ */ 201