PERFORCE change 129925 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Dec 1 16:11:46 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=129925
Change 129925 by hselasky at hselasky_laptop001 on 2007/12/02 00:11:06
This commit finishes change 129799 with regard to
"usb_subr.h".
The USBD_BDMA state has been removed, hence I was
able to simplify the statemachine.
New bus method "xfer_unsetup". Currently unused.
Struct "usbd_page" has been simplified to only
contain the physical address.
Struct "usbd_page_cache" now contains the
BUS-DMA "tag" and "map".
New structure "usbd_dma_tag" which is used to
cache DMA-tags.
"buf_data" field in "struct usbd_xfer" was
replaced by "frbuffers + 0".
Some new prototypes.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#62 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#62 (text+ko) ====
@@ -73,8 +73,14 @@
#define USBD_GET_STATE(xfer) ((xfer)->usb_state)
#define USBD_GET_DATA_ISREAD(xfer) ((xfer)->flags_int.is_dci ? \
-((xfer->endpoint & UE_DIR_IN) ? 0 : 1) : \
- ((xfer->endpoint & UE_DIR_IN) ? 1 : 0))
+ ((xfer->endpoint & UE_DIR_IN) ? 0 : 1) : \
+ ((xfer->endpoint & UE_DIR_IN) ? 1 : 0))
+
+#undef LIST_PREV
+#define LIST_PREV(head,elm,field) \
+ (((elm) == LIST_FIRST(head)) ? ((__typeof(elm))0) : \
+ ((__typeof(elm))(((uint8_t *)((elm)->field.le_prev)) - \
+ ((uint8_t *)&LIST_NEXT((__typeof(elm))0,field)))))
/* USB transfer states */
@@ -84,20 +90,6 @@
USBD_ST_ERROR,
};
-/*
- * USB BUS-DMA transfer states
- *
- * Hence the BUS-DMA framework does not support DMA load abort we need
- * to keep track of the BUS-DMA state in the USB transfer.
- */
-
-enum {
- USBD_BDMA_ST_IDLE,
- USBD_BDMA_ST_LOADING,
- USBD_BDMA_ST_CANCELLING,
- USBD_BDMA_ST_CANCEL_AND_LOAD,
-};
-
struct usbd_xfer;
struct usbd_pipe;
struct usbd_bus;
@@ -115,9 +107,6 @@
struct proc;
struct usb_device; /* Linux compat */
struct cdev;
-struct ehci_hw_softc;
-struct uhci_hw_softc;
-struct ohci_hw_softc;
typedef uint8_t usbd_status;
@@ -139,6 +128,7 @@
void (*pipe_init) (struct usbd_device *udev, usb_endpoint_descriptor_t *edesc, struct usbd_pipe *pipe);
void (*do_poll) (struct usbd_bus *);
void (*xfer_setup) (struct usbd_setup_params *parm);
+ void (*xfer_unsetup) (struct usbd_xfer *xfer);
};
struct usbd_pipe_methods {
@@ -183,8 +173,16 @@
};
struct usbd_page {
+ bus_size_t physaddr;
+};
+
+struct usbd_page_search {
void *buffer;
bus_size_t physaddr;
+ uint32_t length;
+};
+
+struct usbd_page_cache {
#ifdef __FreeBSD__
bus_dma_tag_t tag;
@@ -192,72 +190,62 @@
#endif
#ifdef __NetBSD__
+ bus_dma_segment_t seg;
bus_dma_tag_t tag;
bus_dmamap_t map;
- bus_dma_segment_t seg;
int32_t seg_count;
#endif
- uint32_t length;
-};
-
-struct usbd_page_search {
- void *buffer;
- struct usbd_page *page;
- bus_size_t physaddr;
- uint32_t length;
-};
-
-struct usbd_page_cache {
struct usbd_page *page_start;
- struct usbd_xfer *p_xfer; /* this backpointer to the USB
- * transfer is used when loading
- * virtual buffers into DMA */
- void *p_buffer; /* virtual buffer to be loaded by
- * BUS-DMA */
+ struct usbd_xfer *xfer; /* if set, backpointer to USB transfer */
+ void *buffer; /* virtual buffer pointer */
uint32_t page_offset_buf;
uint32_t page_offset_end;
uint8_t isread:1;
};
struct usbd_setup_params {
- struct usbd_page_cache pc;
-
+ struct usbd_dma_tag *dma_tag_p;
struct usbd_page *dma_page_ptr;
- struct usbd_page *page_ptr;
+ struct usbd_page_cache *dma_page_cache_ptr; /* these will be
+ * auto-freed */
+ struct usbd_page_cache *xfer_page_cache_ptr; /* these will not be
+ * auto-freed */
struct usbd_device *udev;
struct usbd_xfer *curr_xfer;
const struct usbd_config *curr_setup;
const struct usbd_pipe_methods *methods;
void *buf;
+ uint32_t *xfer_length_ptr;
- uint32_t size[4];
- uint32_t total_size[3];
+ uint32_t size[7];
uint32_t bufsize;
+ uint32_t bufsize_max;
uint32_t hc_max_frame_size;
uint16_t hc_max_packet_size;
uint8_t hc_max_packet_count;
uint8_t speed;
+ uint8_t dma_tag_max;
usbd_status err;
};
+struct usbd_dma_tag {
+ bus_dma_tag_t tag;
+ uint32_t align;
+ uint32_t size;
+};
+
+#define USB_BUS_DMA_TAG_MAX 8
+
struct usbd_bus {
struct usb_device_stats stats;
struct mtx mtx;
- struct usbd_page hw_page;
+
+ device_t bdev; /* filled by HC driver */
- union {
- struct ehci_hw_softc *ehci;
- struct uhci_hw_softc *uhci;
- struct ohci_hw_softc *ohci;
- void *data;
- } hw_ptr;
+ struct usbd_dma_tag dma_tags[USB_BUS_DMA_TAG_MAX];
+ bus_dma_tag_t dma_tag_parent;
- device_t bdev; /* filled by HC driver */
- bus_dma_tag_t dma_tag_1b; /* 1 byte aligned DMA-tag, filled by
- * HC driver */
- bus_dma_tag_t dma_tag_ps; /* page size aligned DMA-tag, filled
- * by HC driver */
eventhandler_tag usb_clone_tag;
struct usbd_bus_methods *methods; /* filled by HC driver */
struct usbd_device *devices[USB_MAX_DEVICES];
@@ -269,6 +257,7 @@
uint16_t isoc_time_last; /* ms */
+ uint8_t alloc_failed; /* Set if memory allocation failed. */
uint8_t is_exploring;
uint8_t wait_explore;
uint8_t needs_explore; /* Set if a hub signalled a change.
@@ -385,11 +374,6 @@
uint8_t ext_buffer:1; /* uses external DMA buffer */
uint8_t manual_status:1; /* non automatic status stage on
* control transfers */
- uint8_t bdma_enable:1; /* setting this flag allows you to
- * load buffers directly into DMA for
- * the USB transfer the flag belongs
- * to. The flag can not be changed
- * during operation. */
};
struct usbd_xfer_flags_int {
@@ -407,11 +391,11 @@
uint8_t short_frames_ok:1; /* filtered version */
uint8_t short_xfer_ok:1; /* filtered version */
- uint8_t bdma_state:2; /* BUS-DMA state */
- uint8_t bdma_error:1; /* BUS-DMA error flag */
uint8_t bdma_enable:1; /* filtered version (only set if
* hardware supports DMA) */
- uint8_t bdma_draining:1;
+ uint8_t bdma_no_post_sync:1; /* set if the USB callback wrapper
+ * should not do the BUS-DMA post sync
+ * operation */
uint8_t isochronous_xfr:1; /* set if isochronous transfer */
uint8_t is_dci:1; /* set if hardware is a device
* controller interface */
@@ -437,17 +421,15 @@
struct usbd_xfer {
struct usb_callout timeout_handle;
- struct usbd_page_cache buf_data;/* buffer page cache */
- struct usbd_page_cache buf_fixup; /* fixup buffer */
+ struct usbd_page_cache *buf_fixup; /* fixup buffer(s) */
LIST_ENTRY(usbd_xfer) interrupt_list; /* used by HC driver */
LIST_ENTRY(usbd_xfer) pipe_list; /* used by HC driver */
+ LIST_ENTRY(usbd_xfer) dma_list;/* used by BUS-DMA */
- bus_dmamap_t dma_rx_map;
- bus_dmamap_t dma_tx_map;
struct usbd_page *dma_page_ptr;
struct usbd_pipe *pipe;
struct usbd_device *udev;
- struct mtx *priv_mtx;
+ struct mtx *priv_mtx; /* cannot be changed during operation */
struct mtx *usb_mtx; /* used by HC driver */
struct usbd_memory_info *usb_root; /* used by HC driver */
struct thread *usb_thread; /* used by HC driver */
@@ -459,11 +441,11 @@
void *td_transfer_cache; /* used by HC driver */
void *priv_sc;
void *priv_fifo;
+ void *local_buffer;
uint32_t *frlengths;
struct usbd_page_cache *frbuffers;
usbd_callback_t *callback;
- uint32_t dma_refcount;
uint32_t max_usb_frame_size;
uint32_t max_data_length;
uint32_t sumlen; /* sum of all lengths in bytes */
@@ -496,22 +478,33 @@
struct usbd_xfer_flags_int flags_int;
};
-struct usbd_dma_load_mem_info {
- struct usbd_page *page_ptr;
- struct usbd_page_cache *page_cache;
- uint32_t frame_length;
-};
+struct usbd_memory_info {
+ LIST_HEAD(, usbd_xfer) dma_head;
-struct usbd_memory_info {
void *memory_base;
struct mtx *priv_mtx;
struct mtx *usb_mtx;
- struct usbd_page *page_base;
+ struct usbd_page_cache *dma_page_cache_start;
+ struct usbd_page_cache *dma_page_cache_end;
+ struct usbd_page_cache *xfer_page_cache_start;
+ struct usbd_page_cache *xfer_page_cache_end;
+ struct usbd_xfer *dma_curr_xfer;
+ struct usbd_dma_tag *dma_tag_p;
uint32_t memory_size;
uint32_t memory_refcount;
uint32_t setup_refcount;
uint32_t page_size;
+ uint32_t dma_refcount;
+
+ uint8_t dma_error; /* set if virtual memory could not be
+ * loaded */
+ uint8_t dma_draining; /* set if someone is waiting for a
+ * BUS-DMA load operation to complete */
+ uint8_t dma_no_callback; /* set if callback should not be
+ * called */
+
+ uint8_t dma_tag_max;
};
struct usbd_mbuf {
@@ -667,6 +660,9 @@
#endif
#endif
+typedef void (usbd_bus_mem_sub_cb_t)(struct usbd_bus *bus, struct usbd_page_cache *pc, struct usbd_page *pg, uint32_t size, uint32_t align);
+typedef void (usbd_bus_mem_cb_t)(struct usbd_bus *bus, usbd_bus_mem_sub_cb_t *scb);
+
void usbd_devinfo(struct usbd_device *udev, char *dst_ptr, uint16_t dst_len);
const char *usbd_errstr(usbd_status err);
void usb_delay_ms(struct usbd_bus *bus, uint32_t ms);
@@ -700,29 +696,20 @@
int usbd_uiomove(struct usbd_page_cache *pc, struct uio *uio, uint32_t pc_offset, uint32_t len);
void usbd_copy_out(struct usbd_page_cache *cache, uint32_t offset, void *ptr, uint32_t len);
void usbd_bzero(struct usbd_page_cache *cache, uint32_t offset, uint32_t len);
-uint8_t usbd_page_alloc(bus_dma_tag_t tag, struct usbd_page *page, uint32_t npages);
-void usbd_page_free(struct usbd_page *page, uint32_t npages);
-void usbd_page_cache_init(struct usbd_page_cache *pc, struct usbd_page *page_ptr, uint32_t offset, uint32_t size);
-uint32_t usbd_page_fit_obj(uint32_t size, uint32_t obj_len);
-void *usbd_mem_alloc(bus_dma_tag_t parent, struct usbd_page *page, uint32_t size, uint8_t align_power);
-void usbd_mem_free(struct usbd_page *page);
-bus_dma_tag_t usbd_dma_tag_alloc(bus_dma_tag_t parent, uint32_t seg_size, uint32_t alignment, uint32_t max_size, uint8_t single_seg);
-void usbd_dma_tag_free(bus_dma_tag_t tag);
-void *usbd_mem_alloc_sub(bus_dma_tag_t tag, struct usbd_page *page, uint32_t size, uint32_t alignment);
-void usbd_mem_free_sub(struct usbd_page *page);
-void usbd_dma_load_setup(struct usbd_setup_params *parm);
-void usbd_dma_load_unsetup(struct usbd_xfer *xfer);
-void usbd_dma_load_pre_sync(struct usbd_xfer *xfer);
-void usbd_dma_load_post_sync(struct usbd_xfer *xfer);
-void usbd_page_cpu_invalidate(struct usbd_page *page);
-void usbd_page_cpu_flush(struct usbd_page *page);
-void usbd_pio_load_mem(struct usbd_xfer *xfer, struct usbd_dma_load_mem_info *info);
+bus_dma_tag_t usbd_dma_tag_create(bus_dma_tag_t tag_parent, uint32_t size, uint32_t align);
+void usbd_dma_tag_destroy(bus_dma_tag_t tag);
+uint8_t usbd_pc_alloc_mem(bus_dma_tag_t parent_tag, struct usbd_dma_tag *utag, struct usbd_page_cache *pc, struct usbd_page *pg, uint32_t size, uint32_t align, uint8_t utag_max);
+void usbd_pc_free_mem(struct usbd_page_cache *pc);
+void usbd_pc_load_mem(struct usbd_page_cache *pc, uint32_t size);
+void usbd_pc_cpu_invalidate(struct usbd_page_cache *pc);
+void usbd_pc_cpu_flush(struct usbd_page_cache *pc);
+uint8_t usbd_pc_dmamap_create(struct usbd_page_cache *pc, uint32_t size);
+void usbd_pc_dmamap_destroy(struct usbd_page_cache *pc);
uint8_t usbd_make_str_desc(void *ptr, uint16_t max_len, const char *s);
uint32_t mtx_drop_recurse(struct mtx *mtx);
void mtx_pickup_recurse(struct mtx *mtx, uint32_t recurse_level);
uint8_t usbd_config_td_setup(struct usbd_config_td *ctd, void *priv_sc, struct mtx *priv_mtx, usbd_config_td_end_of_commands_t *p_func_eoc, uint16_t item_size, uint16_t item_count);
void usbd_config_td_stop(struct usbd_config_td *ctd);
-void usbd_transfer_drain(struct usbd_xfer *xfer);
void usbd_config_td_unsetup(struct usbd_config_td *ctd);
void usbd_config_td_queue_command(struct usbd_config_td *ctd, usbd_config_td_command_t *pre_func, usbd_config_td_command_t *post_func, uint16_t command_qcount, uint16_t command_ref);
uint8_t usbd_config_td_is_gone(struct usbd_config_td *ctd);
@@ -730,9 +717,12 @@
struct mbuf *usbd_ether_get_mbuf(void);
int32_t device_delete_all_children(device_t dev);
uint16_t usbd_isoc_time_expand(struct usbd_bus *bus, uint16_t isoc_time_curr);
-void usbd_dma_load_mem(struct usbd_xfer *xfer, struct usbd_dma_load_mem_info *info);
-uint8_t usbd_bus_mem_setup(struct usbd_bus *bus, bus_dma_tag_t parent_tag, uint32_t hw_mem_size, uint8_t hw_addr_lines, uint8_t hw_align_power);
-void usbd_bus_mem_unsetup(struct usbd_bus *bus);
+bus_dma_tag_t usbd_dma_tag_setup(bus_dma_tag_t tag_parent, struct usbd_dma_tag *udt, uint32_t size, uint32_t align, uint8_t nudt);
+void usbd_dma_tag_unsetup(struct usbd_dma_tag *udt, uint8_t nudt);
+void usbd_bus_mem_flush_all(struct usbd_bus *bus, usbd_bus_mem_cb_t *cb);
+uint8_t usbd_bus_mem_alloc_all(struct usbd_bus *bus, usbd_bus_mem_cb_t *cb);
+void usbd_bus_mem_free_all(struct usbd_bus *bus, usbd_bus_mem_cb_t *cb);
+uint8_t usbd_transfer_setup_sub_malloc(struct usbd_setup_params *parm, struct usbd_page_search *info, struct usbd_page_cache **ppc, uint32_t size, uint32_t align);
/* prototypes from usb.c */
@@ -768,9 +758,12 @@
void usbd_transfer_unsetup(struct usbd_xfer **pxfer, uint16_t n_setup);
uint8_t usbd_std_root_transfer(struct usbd_std_root_transfer *std, struct thread *ctd, usbd_std_root_transfer_func_t *func);
void usbd_start_hardware(struct usbd_xfer *xfer);
-void usbd_bdma_done_event(struct usbd_xfer *xfer);
+void usbd_bdma_done_event(struct usbd_memory_info *info);
+void usbd_bdma_pre_sync(struct usbd_xfer *xfer);
+void usbd_bdma_post_sync(struct usbd_xfer *xfer);
void usbd_transfer_start(struct usbd_xfer *xfer);
void usbd_transfer_stop(struct usbd_xfer *xfer);
+void usbd_transfer_drain(struct usbd_xfer *xfer);
void usbd_set_frame_data(struct usbd_xfer *xfer, void *ptr, uint32_t len, uint32_t frindex);
void usbd_set_frame_offset(struct usbd_xfer *xfer, uint32_t offset, uint32_t frindex);
void usbd_callback_wrapper(struct usbd_xfer *xfer);
More information about the p4-projects
mailing list