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 41760bc48eSAndrew Thompson struct usb_fifo; 42760bc48eSAndrew Thompson struct usb_mbuf; 4302ac6454SAndrew Thompson 44e0a69b51SAndrew Thompson typedef int (usb_fifo_open_t)(struct usb_fifo *fifo, int fflags); 45e0a69b51SAndrew Thompson typedef void (usb_fifo_close_t)(struct usb_fifo *fifo, int fflags); 46e0a69b51SAndrew Thompson typedef int (usb_fifo_ioctl_t)(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags); 47e0a69b51SAndrew Thompson typedef void (usb_fifo_cmd_t)(struct usb_fifo *fifo); 48e0a69b51SAndrew Thompson typedef void (usb_fifo_filter_t)(struct usb_fifo *fifo, struct usb_mbuf *m); 4902ac6454SAndrew Thompson 50760bc48eSAndrew Thompson struct usb_symlink { 51760bc48eSAndrew Thompson TAILQ_ENTRY(usb_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 62e0a69b51SAndrew Thompson * "usb_fifo_cmd_t" and "usb_fifo_filter_t" functions are called 6302ac6454SAndrew Thompson * locked. The others are called unlocked. 6402ac6454SAndrew Thompson */ 65760bc48eSAndrew Thompson struct usb_fifo_methods { 66e0a69b51SAndrew Thompson usb_fifo_open_t *f_open; 67e0a69b51SAndrew Thompson usb_fifo_close_t *f_close; 68e0a69b51SAndrew Thompson usb_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 */ 73e0a69b51SAndrew Thompson usb_fifo_ioctl_t *f_ioctl_post; 74e0a69b51SAndrew Thompson usb_fifo_cmd_t *f_start_read; 75e0a69b51SAndrew Thompson usb_fifo_cmd_t *f_stop_read; 76e0a69b51SAndrew Thompson usb_fifo_cmd_t *f_start_write; 77e0a69b51SAndrew Thompson usb_fifo_cmd_t *f_stop_write; 78e0a69b51SAndrew Thompson usb_fifo_filter_t *f_filter_read; 79e0a69b51SAndrew Thompson usb_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 */ 87760bc48eSAndrew Thompson struct usb_cdev_privdata { 88760bc48eSAndrew Thompson struct usb_bus *bus; 89760bc48eSAndrew Thompson struct usb_device *udev; 90760bc48eSAndrew Thompson struct usb_interface *iface; 91ee3e3ff5SAndrew Thompson int bus_index; /* bus index */ 92ee3e3ff5SAndrew Thompson int dev_index; /* device index */ 93ee3e3ff5SAndrew Thompson int ep_addr; /* endpoint address */ 947214348fSAndrew Thompson int fflags; 95ee3e3ff5SAndrew Thompson uint8_t fifo_index; /* FIFO index */ 96e13e19faSAndrew Thompson }; 97e13e19faSAndrew Thompson 98e13e19faSAndrew Thompson /* 99e13e19faSAndrew Thompson * Private per-device and per-thread reference information 100e13e19faSAndrew Thompson */ 101e13e19faSAndrew Thompson struct usb_cdev_refdata { 102e13e19faSAndrew Thompson struct usb_fifo *rxfifo; 103e13e19faSAndrew Thompson struct usb_fifo *txfifo; 104ee3e3ff5SAndrew Thompson uint8_t is_read; /* location has read access */ 105ee3e3ff5SAndrew Thompson uint8_t is_write; /* location has write access */ 106ee3e3ff5SAndrew Thompson uint8_t is_uref; /* USB refcount decr. needed */ 107ee3e3ff5SAndrew Thompson uint8_t is_usbfs; /* USB-FS is active */ 108ee3e3ff5SAndrew Thompson }; 109ee3e3ff5SAndrew Thompson 110760bc48eSAndrew Thompson struct usb_fs_privdata { 111ee3e3ff5SAndrew Thompson int bus_index; 112ee3e3ff5SAndrew Thompson int dev_index; 113ee3e3ff5SAndrew Thompson int ep_addr; 114ee3e3ff5SAndrew Thompson int mode; 115ee3e3ff5SAndrew Thompson int fifo_index; 116ee3e3ff5SAndrew Thompson struct cdev *cdev; 117ee3e3ff5SAndrew Thompson 118760bc48eSAndrew Thompson LIST_ENTRY(usb_fs_privdata) pd_next; 119ee3e3ff5SAndrew Thompson }; 120ee3e3ff5SAndrew Thompson 121ee3e3ff5SAndrew Thompson /* 122760bc48eSAndrew Thompson * Most of the fields in the "usb_fifo" structure are used by the 12302ac6454SAndrew Thompson * generic USB access layer. 12402ac6454SAndrew Thompson */ 125760bc48eSAndrew Thompson struct usb_fifo { 126760bc48eSAndrew Thompson struct usb_ifqueue free_q; 127760bc48eSAndrew Thompson struct usb_ifqueue used_q; 12802ac6454SAndrew Thompson struct selinfo selinfo; 12902ac6454SAndrew Thompson struct cv cv_io; 13002ac6454SAndrew Thompson struct cv cv_drain; 131760bc48eSAndrew Thompson struct usb_fifo_methods *methods; 132760bc48eSAndrew Thompson struct usb_symlink *symlink[2];/* our symlinks */ 13302ac6454SAndrew Thompson struct proc *async_p; /* process that wants SIGIO */ 134760bc48eSAndrew Thompson struct usb_fs_endpoint *fs_ep_ptr; 135760bc48eSAndrew Thompson struct usb_device *udev; 136760bc48eSAndrew Thompson struct usb_xfer *xfer[2]; 137760bc48eSAndrew Thompson struct usb_xfer **fs_xfer; 13802ac6454SAndrew Thompson struct mtx *priv_mtx; /* client data */ 1397214348fSAndrew Thompson /* set if FIFO is opened by a FILE: */ 140760bc48eSAndrew Thompson struct usb_cdev_privdata *curr_cpd; 14102ac6454SAndrew Thompson void *priv_sc0; /* client data */ 14202ac6454SAndrew Thompson void *priv_sc1; /* client data */ 14302ac6454SAndrew Thompson void *queue_data; 144e0a69b51SAndrew Thompson usb_timeout_t timeout; /* timeout in milliseconds */ 145e0a69b51SAndrew Thompson usb_frlength_t bufsize; /* BULK and INTERRUPT buffer size */ 146e0a69b51SAndrew Thompson usb_frcount_t nframes; /* for isochronous mode */ 14702ac6454SAndrew Thompson uint16_t dev_ep_index; /* our device endpoint index */ 14802ac6454SAndrew Thompson uint8_t flag_sleeping; /* set if FIFO is sleeping */ 14902ac6454SAndrew Thompson uint8_t flag_iscomplete; /* set if a USB transfer is complete */ 15002ac6454SAndrew Thompson uint8_t flag_iserror; /* set if FIFO error happened */ 15102ac6454SAndrew Thompson uint8_t flag_isselect; /* set if FIFO is selected */ 15202ac6454SAndrew Thompson uint8_t flag_flushing; /* set if FIFO is flushing data */ 15302ac6454SAndrew Thompson uint8_t flag_short; /* set if short_ok or force_short 15402ac6454SAndrew Thompson * transfer flags should be set */ 15502ac6454SAndrew Thompson uint8_t flag_stall; /* set if clear stall should be run */ 15602ac6454SAndrew Thompson uint8_t iface_index; /* set to the interface we belong to */ 15702ac6454SAndrew Thompson uint8_t fifo_index; /* set to the FIFO index in "struct 158760bc48eSAndrew Thompson * usb_device" */ 15902ac6454SAndrew Thompson uint8_t fs_ep_max; 16002ac6454SAndrew Thompson uint8_t fifo_zlp; /* zero length packet count */ 16102ac6454SAndrew Thompson uint8_t refcount; 16202ac6454SAndrew Thompson #define USB_FIFO_REF_MAX 0xFF 16302ac6454SAndrew Thompson }; 16402ac6454SAndrew Thompson 165760bc48eSAndrew Thompson struct usb_fifo_sc { 166760bc48eSAndrew Thompson struct usb_fifo *fp[2]; 167ee3e3ff5SAndrew Thompson struct cdev* dev; 16802ac6454SAndrew Thompson }; 16902ac6454SAndrew Thompson 170ee3e3ff5SAndrew Thompson extern struct cdevsw usb2_devsw; 171ee3e3ff5SAndrew Thompson 172760bc48eSAndrew Thompson int usb2_fifo_wait(struct usb_fifo *fifo); 173760bc48eSAndrew Thompson void usb2_fifo_signal(struct usb_fifo *fifo); 174760bc48eSAndrew Thompson int usb2_fifo_alloc_buffer(struct usb_fifo *f, uint32_t bufsize, 17502ac6454SAndrew Thompson uint16_t nbuf); 176760bc48eSAndrew Thompson void usb2_fifo_free_buffer(struct usb_fifo *f); 177760bc48eSAndrew Thompson int usb2_fifo_attach(struct usb_device *udev, void *priv_sc, 178760bc48eSAndrew Thompson struct mtx *priv_mtx, struct usb_fifo_methods *pm, 179760bc48eSAndrew Thompson struct usb_fifo_sc *f_sc, uint16_t unit, uint16_t subunit, 180ee3e3ff5SAndrew Thompson uint8_t iface_index, uid_t uid, gid_t gid, int mode); 181760bc48eSAndrew Thompson void usb2_fifo_detach(struct usb_fifo_sc *f_sc); 182760bc48eSAndrew Thompson uint32_t usb2_fifo_put_bytes_max(struct usb_fifo *fifo); 183760bc48eSAndrew Thompson void usb2_fifo_put_data(struct usb_fifo *fifo, struct usb_page_cache *pc, 184e0a69b51SAndrew Thompson usb_frlength_t offset, usb_frlength_t len, uint8_t what); 185760bc48eSAndrew Thompson void usb2_fifo_put_data_linear(struct usb_fifo *fifo, void *ptr, 186f9cb546cSAndrew Thompson usb_size_t len, uint8_t what); 187f9cb546cSAndrew Thompson uint8_t usb2_fifo_put_data_buffer(struct usb_fifo *f, void *ptr, usb_size_t len); 188760bc48eSAndrew Thompson void usb2_fifo_put_data_error(struct usb_fifo *fifo); 189760bc48eSAndrew Thompson uint8_t usb2_fifo_get_data(struct usb_fifo *fifo, struct usb_page_cache *pc, 190e0a69b51SAndrew Thompson usb_frlength_t offset, usb_frlength_t len, usb_frlength_t *actlen, 191578d0effSAndrew Thompson uint8_t what); 192760bc48eSAndrew Thompson uint8_t usb2_fifo_get_data_linear(struct usb_fifo *fifo, void *ptr, 193f9cb546cSAndrew Thompson usb_size_t len, usb_size_t *actlen, uint8_t what); 194760bc48eSAndrew Thompson uint8_t usb2_fifo_get_data_buffer(struct usb_fifo *f, void **pptr, 195f9cb546cSAndrew Thompson usb_size_t *plen); 196760bc48eSAndrew Thompson void usb2_fifo_get_data_error(struct usb_fifo *fifo); 197760bc48eSAndrew Thompson uint8_t usb2_fifo_opened(struct usb_fifo *fifo); 198760bc48eSAndrew Thompson void usb2_fifo_free(struct usb_fifo *f); 199760bc48eSAndrew Thompson void usb2_fifo_reset(struct usb_fifo *f); 200760bc48eSAndrew Thompson void usb2_fifo_wakeup(struct usb_fifo *f); 201760bc48eSAndrew Thompson struct usb_symlink *usb2_alloc_symlink(const char *target); 202760bc48eSAndrew Thompson void usb2_free_symlink(struct usb_symlink *ps); 20302ac6454SAndrew Thompson int usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry, 20402ac6454SAndrew Thompson uint32_t user_len); 205760bc48eSAndrew Thompson void usb2_fifo_set_close_zlp(struct usb_fifo *, uint8_t); 20602ac6454SAndrew Thompson 20702ac6454SAndrew Thompson #endif /* _USB2_DEV_H_ */ 208