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 4402ac6454SAndrew Thompson typedef int (usb2_fifo_open_t)(struct usb2_fifo *fifo, int fflags, struct thread *td); 4502ac6454SAndrew Thompson typedef void (usb2_fifo_close_t)(struct usb2_fifo *fifo, int fflags, struct thread *td); 4602ac6454SAndrew Thompson typedef int (usb2_fifo_ioctl_t)(struct usb2_fifo *fifo, u_long cmd, void *addr, int fflags, struct thread *td); 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 /* 8502ac6454SAndrew Thompson * Most of the fields in the "usb2_fifo" structure are used by the 8602ac6454SAndrew Thompson * generic USB access layer. 8702ac6454SAndrew Thompson */ 8802ac6454SAndrew Thompson struct usb2_fifo { 8902ac6454SAndrew Thompson struct usb2_ifqueue free_q; 9002ac6454SAndrew Thompson struct usb2_ifqueue used_q; 9102ac6454SAndrew Thompson struct selinfo selinfo; 9202ac6454SAndrew Thompson struct cv cv_io; 9302ac6454SAndrew Thompson struct cv cv_drain; 9402ac6454SAndrew Thompson struct usb2_fifo_methods *methods; 9502ac6454SAndrew Thompson struct usb2_symlink *symlink[2];/* our symlinks */ 9602ac6454SAndrew Thompson struct proc *async_p; /* process that wants SIGIO */ 9702ac6454SAndrew Thompson struct usb2_fs_endpoint *fs_ep_ptr; 9802ac6454SAndrew Thompson struct usb2_device *udev; 9902ac6454SAndrew Thompson struct usb2_xfer *xfer[2]; 10002ac6454SAndrew Thompson struct usb2_xfer **fs_xfer; 10102ac6454SAndrew Thompson struct mtx *priv_mtx; /* client data */ 10202ac6454SAndrew Thompson struct file *curr_file; /* set if FIFO is opened by a FILE */ 10302ac6454SAndrew Thompson void *priv_sc0; /* client data */ 10402ac6454SAndrew Thompson void *priv_sc1; /* client data */ 10502ac6454SAndrew Thompson void *queue_data; 10602ac6454SAndrew Thompson uint32_t timeout; /* timeout in milliseconds */ 10702ac6454SAndrew Thompson uint32_t bufsize; /* BULK and INTERRUPT buffer size */ 10802ac6454SAndrew Thompson uint16_t nframes; /* for isochronous mode */ 10902ac6454SAndrew Thompson uint16_t dev_ep_index; /* our device endpoint index */ 11002ac6454SAndrew Thompson uint8_t flag_sleeping; /* set if FIFO is sleeping */ 11102ac6454SAndrew Thompson uint8_t flag_iscomplete; /* set if a USB transfer is complete */ 11202ac6454SAndrew Thompson uint8_t flag_iserror; /* set if FIFO error happened */ 11302ac6454SAndrew Thompson uint8_t flag_isselect; /* set if FIFO is selected */ 11402ac6454SAndrew Thompson uint8_t flag_flushing; /* set if FIFO is flushing data */ 11502ac6454SAndrew Thompson uint8_t flag_short; /* set if short_ok or force_short 11602ac6454SAndrew Thompson * transfer flags should be set */ 11702ac6454SAndrew Thompson uint8_t flag_stall; /* set if clear stall should be run */ 11802ac6454SAndrew Thompson uint8_t iface_index; /* set to the interface we belong to */ 11902ac6454SAndrew Thompson uint8_t fifo_index; /* set to the FIFO index in "struct 12002ac6454SAndrew Thompson * usb2_device" */ 12102ac6454SAndrew Thompson uint8_t fs_ep_max; 12202ac6454SAndrew Thompson uint8_t fifo_zlp; /* zero length packet count */ 12302ac6454SAndrew Thompson uint8_t refcount; 12402ac6454SAndrew Thompson #define USB_FIFO_REF_MAX 0xFF 12502ac6454SAndrew Thompson }; 12602ac6454SAndrew Thompson 12702ac6454SAndrew Thompson struct usb2_fifo_sc { 12802ac6454SAndrew Thompson struct usb2_fifo *fp[2]; 12902ac6454SAndrew Thompson }; 13002ac6454SAndrew Thompson 13102ac6454SAndrew Thompson int usb2_fifo_wait(struct usb2_fifo *fifo); 13202ac6454SAndrew Thompson void usb2_fifo_signal(struct usb2_fifo *fifo); 13302ac6454SAndrew Thompson int usb2_fifo_alloc_buffer(struct usb2_fifo *f, uint32_t bufsize, 13402ac6454SAndrew Thompson uint16_t nbuf); 13502ac6454SAndrew Thompson void usb2_fifo_free_buffer(struct usb2_fifo *f); 13602ac6454SAndrew Thompson int usb2_fifo_attach(struct usb2_device *udev, void *priv_sc, 13702ac6454SAndrew Thompson struct mtx *priv_mtx, struct usb2_fifo_methods *pm, 13802ac6454SAndrew Thompson struct usb2_fifo_sc *f_sc, uint16_t unit, uint16_t subunit, 13902ac6454SAndrew Thompson uint8_t iface_index); 14002ac6454SAndrew Thompson void usb2_fifo_detach(struct usb2_fifo_sc *f_sc); 14102ac6454SAndrew Thompson uint32_t usb2_fifo_put_bytes_max(struct usb2_fifo *fifo); 14202ac6454SAndrew Thompson void usb2_fifo_put_data(struct usb2_fifo *fifo, struct usb2_page_cache *pc, 14302ac6454SAndrew Thompson uint32_t offset, uint32_t len, uint8_t what); 14402ac6454SAndrew Thompson void usb2_fifo_put_data_linear(struct usb2_fifo *fifo, void *ptr, 14502ac6454SAndrew Thompson uint32_t len, uint8_t what); 14602ac6454SAndrew Thompson uint8_t usb2_fifo_put_data_buffer(struct usb2_fifo *f, void *ptr, uint32_t len); 14702ac6454SAndrew Thompson void usb2_fifo_put_data_error(struct usb2_fifo *fifo); 14802ac6454SAndrew Thompson uint8_t usb2_fifo_get_data(struct usb2_fifo *fifo, struct usb2_page_cache *pc, 14902ac6454SAndrew Thompson uint32_t offset, uint32_t len, uint32_t *actlen, uint8_t what); 15002ac6454SAndrew Thompson uint8_t usb2_fifo_get_data_linear(struct usb2_fifo *fifo, void *ptr, 15102ac6454SAndrew Thompson uint32_t len, uint32_t *actlen, uint8_t what); 15202ac6454SAndrew Thompson uint8_t usb2_fifo_get_data_buffer(struct usb2_fifo *f, void **pptr, 15302ac6454SAndrew Thompson uint32_t *plen); 15402ac6454SAndrew Thompson void usb2_fifo_get_data_error(struct usb2_fifo *fifo); 15502ac6454SAndrew Thompson uint8_t usb2_fifo_opened(struct usb2_fifo *fifo); 15602ac6454SAndrew Thompson void usb2_fifo_free(struct usb2_fifo *f); 15702ac6454SAndrew Thompson void usb2_fifo_reset(struct usb2_fifo *f); 15802ac6454SAndrew Thompson int usb2_check_thread_perm(struct usb2_device *udev, struct thread *td, 15902ac6454SAndrew Thompson int fflags, uint8_t iface_index, uint8_t ep_index); 16002ac6454SAndrew Thompson void usb2_fifo_wakeup(struct usb2_fifo *f); 16102ac6454SAndrew Thompson struct usb2_symlink *usb2_alloc_symlink(const char *target, 16202ac6454SAndrew Thompson const char *fmt,...); 16302ac6454SAndrew Thompson void usb2_free_symlink(struct usb2_symlink *ps); 16402ac6454SAndrew Thompson uint32_t usb2_lookup_symlink(const char *src_ptr, uint8_t src_len); 16502ac6454SAndrew Thompson int usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry, 16602ac6454SAndrew Thompson uint32_t user_len); 16702ac6454SAndrew Thompson 16802ac6454SAndrew Thompson #endif /* _USB2_DEV_H_ */ 169