usb_core.h revision 263644
1219820Sjeff/* $FreeBSD: stable/9/sys/dev/usb/usb_core.h 263644 2014-03-22 17:20:10Z hselasky $ */ 2219820Sjeff/*- 3219820Sjeff * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 4219820Sjeff * 5294839Shselasky * Redistribution and use in source and binary forms, with or without 6289580Shselasky * modification, are permitted provided that the following conditions 7219820Sjeff * are met: 8219820Sjeff * 1. Redistributions of source code must retain the above copyright 9219820Sjeff * notice, this list of conditions and the following disclaimer. 10219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright 11219820Sjeff * notice, this list of conditions and the following disclaimer in the 12219820Sjeff * documentation and/or other materials provided with the distribution. 13219820Sjeff * 14219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15219820Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16219820Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17219820Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18219820Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19219820Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20219820Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22219820Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23219820Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24219820Sjeff * SUCH DAMAGE. 25219820Sjeff */ 26219820Sjeff 27219820Sjeff/* 28219820Sjeff * Including this file is mandatory for all USB related c-files in the kernel. 29289644Shselasky */ 30289644Shselasky 31219820Sjeff#ifndef _USB_CORE_H_ 32219820Sjeff#define _USB_CORE_H_ 33219820Sjeff 34219820Sjeff/* 35277396Shselasky * The following macro will tell if an USB transfer is currently 36277396Shselasky * receiving or transferring data. 37219820Sjeff */ 38219820Sjeff#define USB_GET_DATA_ISREAD(xfer) ((xfer)->flags_int.usb_mode == \ 39219820Sjeff USB_MODE_DEVICE ? (((xfer)->endpointno & UE_DIR_IN) ? 0 : 1) : \ 40219820Sjeff (((xfer)->endpointno & UE_DIR_IN) ? 1 : 0)) 41219820Sjeff 42270710Shselasky/* macros */ 43276749Shselasky 44328653Shselasky#define USB_BUS_LOCK(_b) mtx_lock(&(_b)->bus_mtx) 45219820Sjeff#define USB_BUS_UNLOCK(_b) mtx_unlock(&(_b)->bus_mtx) 46219820Sjeff#define USB_BUS_LOCK_ASSERT(_b, _t) mtx_assert(&(_b)->bus_mtx, _t) 47219820Sjeff#define USB_XFER_LOCK(_x) mtx_lock((_x)->xroot->xfer_mtx) 48219820Sjeff#define USB_XFER_UNLOCK(_x) mtx_unlock((_x)->xroot->xfer_mtx) 49328653Shselasky#define USB_XFER_LOCK_ASSERT(_x, _t) mtx_assert((_x)->xroot->xfer_mtx, _t) 50219820Sjeff 51219820Sjeff/* helper for converting pointers to integers */ 52331756Semaste#define USB_P2U(ptr) \ 53335433Shselasky (((const uint8_t *)(ptr)) - ((const uint8_t *)0)) 54219820Sjeff 55335433Shselasky/* helper for computing offsets */ 56219820Sjeff#define USB_ADD_BYTES(ptr,size) \ 57300500Shselasky ((void *)(USB_P2U(ptr) + (size))) 58300500Shselasky 59255932Salfred/* debug macro */ 60219820Sjeff#define USB_ASSERT KASSERT 61219820Sjeff 62219820Sjeff/* structure prototypes */ 63219820Sjeff 64219820Sjeffstruct file; 65219820Sjeffstruct usb_bus; 66219820Sjeffstruct usb_device; 67219820Sjeffstruct usb_device_request; 68219820Sjeffstruct usb_page; 69299653Shselaskystruct usb_page_cache; 70299653Shselaskystruct usb_xfer; 71299653Shselaskystruct usb_xfer_root; 72299653Shselasky 73299653Shselasky/* typedefs */ 74299653Shselasky 75299653Shselasky/* structures */ 76299653Shselasky 77299653Shselasky/* 78299653Shselasky * The following structure defines a set of internal USB transfer 79299653Shselasky * flags. 80299653Shselasky */ 81299653Shselaskystruct usb_xfer_flags_int { 82299653Shselasky 83299653Shselasky enum usb_hc_mode usb_mode; /* shadow copy of "udev->usb_mode" */ 84299653Shselasky uint16_t control_rem; /* remainder in bytes */ 85299653Shselasky 86299653Shselasky uint8_t open:1; /* set if USB pipe has been opened */ 87299653Shselasky uint8_t transferring:1; /* set if an USB transfer is in 88299653Shselasky * progress */ 89299653Shselasky uint8_t did_dma_delay:1; /* set if we waited for HW DMA */ 90299653Shselasky uint8_t did_close:1; /* set if we closed the USB transfer */ 91330858Shselasky uint8_t draining:1; /* set if we are draining an USB 92328653Shselasky * transfer */ 93328653Shselasky uint8_t started:1; /* keeps track of started or stopped */ 94328653Shselasky uint8_t bandwidth_reclaimed:1; 95329980Shselasky uint8_t control_xfr:1; /* set if control transfer */ 96277396Shselasky uint8_t control_hdr:1; /* set if control header should be 97362315Shselasky * sent */ 98362315Shselasky uint8_t control_act:1; /* set if control transfer is active */ 99362315Shselasky uint8_t control_stall:1; /* set if control transfer should be stalled */ 100299653Shselasky 101299653Shselasky uint8_t short_frames_ok:1; /* filtered version */ 102299653Shselasky uint8_t short_xfer_ok:1; /* filtered version */ 103299653Shselasky#if USB_HAVE_BUSDMA 104299653Shselasky uint8_t bdma_enable:1; /* filtered version (only set if 105299653Shselasky * hardware supports DMA) */ 106299653Shselasky uint8_t bdma_no_post_sync:1; /* set if the USB callback wrapper 107219820Sjeff * should not do the BUS-DMA post sync 108299653Shselasky * operation */ 109299653Shselasky uint8_t bdma_setup:1; /* set if BUS-DMA has been setup */ 110299653Shselasky#endif 111299653Shselasky uint8_t isochronous_xfr:1; /* set if isochronous transfer */ 112299653Shselasky uint8_t curr_dma_set:1; /* used by USB HC/DC driver */ 113299653Shselasky uint8_t can_cancel_immed:1; /* set if USB transfer can be 114299653Shselasky * cancelled immediately */ 115299653Shselasky uint8_t doing_callback:1; /* set if executing the callback */ 116299653Shselasky uint8_t maxp_was_clamped:1; /* set if the max packet size 117299653Shselasky * was outside its allowed range */ 118299653Shselasky}; 119299653Shselasky 120299653Shselasky/* 121299653Shselasky * The following structure defines an USB transfer. 122299653Shselasky */ 123299653Shselaskystruct usb_xfer { 124299653Shselasky struct usb_callout timeout_handle; 125299653Shselasky TAILQ_ENTRY(usb_xfer) wait_entry; /* used at various places */ 126299653Shselasky 127299653Shselasky struct usb_page_cache *buf_fixup; /* fixup buffer(s) */ 128299653Shselasky struct usb_xfer_queue *wait_queue; /* pointer to queue that we 129299653Shselasky * are waiting on */ 130328653Shselasky struct usb_page *dma_page_ptr; 131328653Shselasky struct usb_endpoint *endpoint; /* our USB endpoint */ 132219820Sjeff struct usb_xfer_root *xroot; /* used by HC driver */ 133219820Sjeff void *qh_start[2]; /* used by HC driver */ 134279587Shselasky void *td_start[2]; /* used by HC driver */ 135279587Shselasky void *td_transfer_first; /* used by HC driver */ 136289580Shselasky void *td_transfer_last; /* used by HC driver */ 137339997Shselasky void *td_transfer_cache; /* used by HC driver */ 138289580Shselasky void *priv_sc; /* device driver data pointer 1 */ 139278681Shselasky void *priv_fifo; /* device driver data pointer 2 */ 140219820Sjeff void *local_buffer; 141300500Shselasky usb_frlength_t *frlengths; 142300500Shselasky struct usb_page_cache *frbuffers; 143276749Shselasky usb_callback_t *callback; 144340945Shselasky 145340945Shselasky usb_frlength_t max_hc_frame_size; 146340003Shselasky usb_frlength_t max_data_length; 147340003Shselasky usb_frlength_t sumlen; /* sum of all lengths in bytes */ 148340003Shselasky usb_frlength_t actlen; /* actual length in bytes */ 149300500Shselasky usb_timeout_t timeout; /* milliseconds */ 150300500Shselasky 151300500Shselasky usb_frcount_t max_frame_count; /* initial value of "nframes" after 152300500Shselasky * setup */ 153300500Shselasky usb_frcount_t nframes; /* number of USB frames to transfer */ 154300500Shselasky usb_frcount_t aframes; /* actual number of USB frames 155300500Shselasky * transferred */ 156300500Shselasky 157300500Shselasky uint16_t max_packet_size; 158300500Shselasky uint16_t max_frame_size; 159300500Shselasky uint16_t qh_pos; 160300500Shselasky uint16_t isoc_time_complete; /* in ms */ 161300500Shselasky usb_timeout_t interval; /* milliseconds */ 162300500Shselasky 163300500Shselasky uint8_t address; /* physical USB address */ 164300500Shselasky uint8_t endpointno; /* physical USB endpoint */ 165300500Shselasky uint8_t max_packet_count; 166300500Shselasky uint8_t usb_state; 167300500Shselasky uint8_t fps_shift; /* down shift of FPS, 0..3 */ 168300500Shselasky 169300500Shselasky usb_error_t error; 170300500Shselasky 171300500Shselasky struct usb_xfer_flags flags; 172300500Shselasky struct usb_xfer_flags_int flags_int; 173300500Shselasky}; 174300500Shselasky 175300500Shselasky/* external variables */ 176300500Shselasky 177300500Shselaskyextern struct mtx usb_ref_lock; 178276749Shselasky 179276749Shselasky/* typedefs */ 180276749Shselasky 181276749Shselaskytypedef struct malloc_type *usb_malloc_type; 182276749Shselasky 183347791Shselasky/* prototypes */ 184347791Shselasky 185347791Shselasky#endif /* _USB_CORE_H_ */ 186347791Shselasky