PERFORCE change 130731 for review

Hans Petter Selasky hselasky at FreeBSD.org
Wed Dec 12 12:54:20 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=130731

Change 130731 by hselasky at hselasky_laptop001 on 2007/12/12 20:53:32

	
	This commit is related to USB device side support.
	
	This commit outlines the coming changes which will almost
	finalize the symmetry in the USB stack. That means there 
	is very little difference between setting up a Device Side
	driver versus a Host Side driver - it's symmetric !
	
	NOTE: The P4 project will not build during these updates.
	
	FYI: The comments below follow the diff.
	
	o Add to new USB error codes. 
	
	o Add new callbacks that will set and
	  clear endpoint stall in hardware.
	
	o The term "device_index" is used to address
	  an USB device from userland, hence the
	  device address can change!
	
	o Some new fields in "struct usbd_port".
	
	o We now store the number of ports in
	  "struct usbd_hub" in the "nports" variable
	  so that we can add software constraints to
	  the number of ports later.
	
	o The USB explore system has been reworked
	  and simplified. Define a set of USB explore
	  commands. See "USB_BUS_EXPLORE_XXX".
	
	o USB BUS "need_xxx" variables moved into
	  a separate structure.
	
	o The "driver_added_refcount" is not stored in
	  "struct usbd_bus" and we no longer need the
	  Global USB lock to read and write it.
	
	o "struct usbd_interface" now contains a pointer
	  to its belonging subdevice if any.
	
	o "struct usbd_device_flags" contains all the 
	  USB device flags.
	
	o New predefined size: USB_MAX_INTERFACES (see "usb.h")
	  which gives the maximum number of USB interfaces
	  supported.
	
	o The parent device_t is not stored in
	  "struct usbd_device" in the variable "parent_dev".
	
	o New field "global_dev" in "struct usbd_device"
	  which points to the USB specific, that means
	  non-interface probed USB device.
	
	o "USBD_PROBED_GENERIC_AND_FOUND" was merged 
	  with "USBD_PROBED_SPECIFIC_AND_FOUND".
	
	o New USB transfer flag "stall_pipe". (see README for 
	  a detailed description)
	
	o Updated and added some prototypes.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#73 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#73 (text+ko) ====

@@ -66,6 +66,8 @@
 m(USBD_STALLED,)\
 m(USBD_INTERRUPTED,)\
 m(USBD_DMA_LOAD_FAILED,)\
+m(USBD_BAD_CONTEXT,)\
+m(USBD_NO_ROOT_HUB,)\
 					/**/
 
 MAKE_ENUM(USBD_STATUS,
@@ -165,17 +167,26 @@
 };
 
 struct usbd_pipe_methods {
+
+	/* USB Device and Host mode: */
+
 	void    (*open) (struct usbd_xfer *xfer);
 	void    (*close) (struct usbd_xfer *xfer);
 	void    (*enter) (struct usbd_xfer *xfer);
 	void    (*start) (struct usbd_xfer *xfer);
+
+	/* USB Device mode only: */
+
+	void    (*set_stall) (struct usbd_device *udev, struct usbd_xfer *xfer, struct usbd_pipe *pipe);
+	void    (*clear_stall) (struct usbd_device *udev, struct usbd_pipe *pipe);
 };
 
 struct usbd_port {
-	usb_port_status_t status;
 	uint8_t	restartcnt;
-	uint8_t	device_addr;		/* zero means unused */
 #define	USBD_RESTART_MAX 5
+	uint8_t	device_index;		/* zero means not valid */
+	uint8_t	usb_mode:1;		/* current USB mode */
+	uint8_t	unused:7;
 };
 
 struct usbd_fs_isoc_schedule {
@@ -195,13 +206,13 @@
 
 struct usbd_hub {
 	struct usbd_fs_isoc_schedule fs_isoc_schedule[USB_ISOC_TIME_MAX];
-	usb_hub_descriptor_t hubdesc;
 	struct usbd_device *hubudev;	/* the HUB device */
 	usbd_status_t (*explore) (struct usbd_device *hub);
 	void   *hubsoftc;
 	uint32_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];
 	uint16_t portpower;		/* mA per USB port */
 	uint8_t	isoc_last_time;
+	uint8_t	nports;
 	struct usbd_port ports[0];
 };
 
@@ -268,8 +279,27 @@
 	uint32_t size;
 };
 
+/* USB BUS explore commands */
+
+#define	USB_BUS_EXPLORE_TREE 0
+#define	USB_BUS_EXPLORE_PROBE 1
+#define	USB_BUS_EXPLORE_STOP 2
+#define	USB_BUS_EXPLORE_SYNC 3
+
 #define	USB_BUS_DMA_TAG_MAX 8
 
+struct usbd_bus_needs {
+	uint8_t	sync:1;			/* Set if explore thread sync is
+					 * needed. */
+	uint8_t	wakeup:1;		/* Set if explore thread is sleeping. */
+	uint8_t	explore:1;		/* Set if a HUB signalled a change. */
+	uint8_t	probe_attach:1;		/* Set if a HUB signalled that a new
+					 * USB driver was loaded. */
+	uint8_t	teardown:1;		/* Set if we are tearing down the
+					 * explore thread */
+	uint8_t	unused:3;
+};
+
 struct usbd_bus {
 	struct usb_device_stats stats;
 	struct mtx mtx;
@@ -288,14 +318,12 @@
 
 	uint32_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];
 
-	uint16_t isoc_time_last;	/* ms */
+	uint16_t isoc_time_last;	/* in milliseconds */
+
+	struct usbd_bus_needs needs;	/* write protected by "bus->mtx" */
 
 	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.
-					 * This variable is protected by
-					 * "usb_global_lock" */
+	uint8_t	driver_added_refcount;	/* Current driver generation count */
 	uint8_t	usbrev;			/* USB revision */
 	uint8_t	usb_clone_count;
 #define	USB_BUS_MAX_CLONES 128
@@ -312,6 +340,7 @@
 
 struct usbd_interface {
 	usb_interface_descriptor_t *idesc;
+	device_t subdev;
 	uint8_t	alt_index;
 };
 
@@ -324,18 +353,30 @@
 	uint16_t isoc_next;
 	uint16_t refcount;
 
-	uint8_t	toggle_next;
+	uint8_t	toggle_next:1;		/* next data toggle value */
+	uint8_t	is_stalled:1;		/* set if pipe is stalled */
+	uint8_t	unused:6;
 	uint8_t	iface_index;		/* not used by "default pipe" */
 };
 
+struct usbd_device_flags {
+	uint8_t	usb_mode:1;		/* USB mode (see USB_MODE_XXX) */
+	uint8_t	self_powered:1;		/* set if USB device is self powered */
+	uint8_t	suspended:1;		/* set if USB device is suspended */
+	uint8_t	no_strings:1;		/* set if USB device does not support
+					 * strings */
+	uint8_t	detaching:1;		/* set if USB device is detaching */
+	uint8_t	unused:3;
+};
+
 struct usbd_device {
 	struct sx default_sx[1];
 	struct mtx default_mtx[1];
 
-	struct usbd_interface ifaces[USB_MAX_ENDPOINTS];
+	struct usbd_interface ifaces[USB_MAX_INTERFACES];
 	struct usbd_interface ifaces_end[0];
 
-	struct usbd_pipe default_pipe;	/* pipe 0 */
+	struct usbd_pipe default_pipe;	/* Control Endpoint 0 */
 	struct usbd_pipe pipes[USB_MAX_ENDPOINTS];
 	struct usbd_pipe pipes_end[0];
 
@@ -344,12 +385,12 @@
 #endif
 
 	struct usbd_bus *bus;		/* our controller */
+	device_t parent_dev;		/* parent device */
 	struct usbd_device *parent_hub;
 	const struct usbd_quirks *quirks;	/* device quirks, always set */
 	usb_config_descriptor_t *cdesc;	/* full config descr */
 	struct usbd_hub *hub;		/* only if this is a hub */
-	device_t subdevs[USB_MAX_ENDPOINTS];
-	device_t subdevs_end[0];
+	device_t global_dev;
 	struct usb_device *linux_dev;
 	struct usbd_xfer *default_xfer[1];
 	void   *usb_template_ptr;
@@ -362,22 +403,23 @@
 	uint16_t langid;		/* language for strings */
 
 	uint8_t	address;		/* device addess */
-	uint8_t	config;			/* current configuration # */
+	uint8_t	curr_config_no;		/* current configuration # */
 	uint8_t	depth;			/* distance from root HUB */
 	uint8_t	speed;			/* low/full/high speed */
-	uint8_t	self_powered;		/* flag for self powered */
 	uint8_t	port_index;		/* parent HUB port index */
 	uint8_t	port_no;		/* parent HUB port number */
 	uint8_t	hs_hub_addr;		/* high-speed HUB address */
 	uint8_t	hs_port_no;		/* high-speed HUB port number */
-	uint8_t	driver_added_refcount;
-	uint8_t	usb_mode:1;		/* USB mode (see USB_MODE_XXX) */
-	uint8_t	unused:7;
+	uint8_t	driver_added_refcount;	/* our driver added generation count */
+
+	/* the "flags" field is write-protected by "bus->mtx" */
+
+	struct usbd_device_flags flags;
 
 	usb_endpoint_descriptor_t default_ep_desc;	/* for pipe 0 */
 	usb_device_descriptor_t ddesc;	/* device descriptor */
 
-	uint8_t	ifaces_no_probe[(USB_MAX_ENDPOINTS + 7) / 8];
+	uint8_t	ifaces_no_probe[(USB_MAX_INTERFACES + 7) / 8];
 #define	USBD_SET_IFACE_NO_PROBE(udev, ii) \
   { (udev)->ifaces_no_probe[(ii) >> 3] |= (1 << ((ii) & 7)); }
 #define	USBD_CLR_IFACE_NO_PROBE(udev, ii) \
@@ -389,7 +431,6 @@
 #define	USBD_PROBED_NOTHING              0	/* default value */
 #define	USBD_PROBED_SPECIFIC_AND_FOUND   1
 #define	USBD_PROBED_IFACE_AND_FOUND      2
-#define	USBD_PROBED_GENERIC_AND_FOUND    3
 
 	uint8_t	serial[64];		/* serial number */
 	uint8_t	manufacturer[64];	/* manufacturer string */
@@ -399,9 +440,6 @@
 		struct usbd_temp_setup temp_setup[1];
 		uint8_t	data[128];
 	}	scratch[1];
-
-	uint8_t	detaching;
-	uint8_t	no_strings;		/* flag for no strings */
 };
 
 struct usbd_xfer_flags {
@@ -418,6 +456,9 @@
 					 * control transfers */
 	uint8_t	no_pipe_ok:1;		/* set if "USBD_NO_PIPE" error can be
 					 * ignored */
+	uint8_t	stall_pipe:1;		/* set if the endpoint belonging to
+					 * this USB transfer should be stalled
+					 * before starting this transfer! */
 };
 
 struct usbd_xfer_flags_int {
@@ -657,10 +698,9 @@
 #define	USB_PRODUCT_ANY		0xffff
 
 struct usb_attach_arg {
+	device_t temp_dev;		/* for internal use */
 	struct usbd_device *device;	/* current device */
 	struct usbd_interface *iface;	/* current interface */
-	struct usbd_interface *ifaces_start;	/* all interfaces */
-	struct usbd_interface *ifaces_end;	/* exclusive */
 
 	uint16_t vendor;
 	uint16_t product;
@@ -727,10 +767,13 @@
 usbd_status_t usbd_set_config_index(struct usbd_device *udev, uint8_t index, uint8_t msg);
 usbd_status_t usbd_set_alt_interface_index(struct usbd_device *udev, uint8_t iface_index, uint8_t alt_index);
 int	usbd_fill_deviceinfo(struct usbd_device *udev, struct usb_device_info *di);
+void	usbd_detach_device(struct usbd_device *udev, uint8_t iface_index, uint8_t free_subdev);
+usbd_status_t usbd_probe_and_attach(struct usbd_device *udev, uint8_t iface_index);
+usbd_status_t usbd_suspend_resume(struct usbd_device *udev, uint8_t do_suspend);
+
+struct usbd_device *usbd_alloc_device(device_t parent_dev, struct usbd_bus *bus, struct usbd_device *parent_hub, uint8_t depth, uint8_t port_index, uint8_t port_no, uint8_t speed, uint8_t usb_mode);
+void	usbd_free_device(struct usbd_device *udev);
 usbd_status_t usbd_fill_iface_data(struct usbd_device *udev, uint8_t iface_index, uint8_t alt_index);
-usbd_status_t usbd_probe_and_attach(device_t parent, struct usbd_device *udev);
-usbd_status_t usbd_new_device(device_t parent, struct usbd_bus *bus, struct usbd_device *parent_hub, uint8_t depth, uint8_t speed, uint8_t port_index, uint8_t port_no);
-void	usbd_free_device(struct usbd_device *udev, uint8_t free_subdev);
 struct usbd_device *usbd_ref_device(struct usbd_bus *bus, uint8_t addr);
 void	usbd_unref_device(struct usbd_device *udev);
 struct usbd_interface *usbd_get_iface(struct usbd_device *udev, uint8_t iface_index);
@@ -770,6 +813,8 @@
 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);
+struct usbd_device *usbd_bus_port_get_device(struct usbd_bus *bus, struct usbd_port *up);
+void	usbd_bus_port_set_device(struct usbd_bus *bus, struct usbd_port *up, struct usbd_device *udev, uint8_t device_index);
 
 /* prototypes from usb.c */
 
@@ -781,9 +826,7 @@
 #define	usb_global_lock Giant
 #endif
 
-extern uint8_t usb_driver_added_refcount;
-
-void	usb_needs_explore(struct usbd_device *udev);
+void	usb_needs_explore(struct usbd_bus *bus, uint8_t what);
 void	usb_needs_probe_and_attach(void);
 
 /* prototypes from usb_template.c */
@@ -805,6 +848,7 @@
 #endif
 
 uint32_t usb_get_devid(device_t dev);
+struct usbd_pipe *usbd_get_pipe_by_addr(struct usbd_device *udev, uint8_t ea_val);
 struct usbd_pipe *usbd_get_pipe(struct usbd_device *udev, uint8_t iface_index, const struct usbd_config *setup);
 usbd_status_t usbd_interface_count(struct usbd_device *udev, uint8_t *count);
 void	usbd_transfer_setup_sub(struct usbd_setup_params *parm);
@@ -836,7 +880,7 @@
 
 /* prototypes from usb_requests.c */
 
-usbd_status_t usbreq_reset_port(struct usbd_device *udev, struct mtx *mtx, usb_port_status_t *ps, uint8_t port);
+usbd_status_t usbreq_reset_port(struct usbd_device *udev, struct mtx *mtx, uint8_t port);
 usbd_status_t usbreq_get_desc(struct usbd_device *udev, struct mtx *mtx, void *desc, uint16_t min_len, uint16_t max_len, uint16_t id, uint8_t type, uint8_t index, uint8_t retries);
 usbd_status_t usbreq_get_string_any(struct usbd_device *udev, struct mtx *mtx, char *buf, uint16_t len, uint8_t string_index);
 usbd_status_t usbreq_get_string_desc(struct usbd_device *udev, struct mtx *mtx, void *sdesc, uint16_t max_len, uint16_t lang_id, uint8_t string_index);


More information about the p4-projects mailing list