Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Dec 2007 00:11:45 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 129925 for review
Message-ID:  <200712020011.lB20BjmN003859@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=129925

Change 129925 by hselasky@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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712020011.lB20BjmN003859>