PERFORCE change 135146 for review

Hans Petter Selasky hselasky at FreeBSD.org
Sun Feb 10 03:53:27 PST 2008


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

Change 135146 by hselasky at hselasky_laptop001 on 2008/02/10 11:53:05

	
	Add more documentation to "usb_transfer.c".

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#112 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#112 (text+ko) ====

@@ -68,6 +68,11 @@
 
 
 #ifdef USB_DEBUG
+/*------------------------------------------------------------------------*
+ *	usbd_dump_iface
+ *
+ * This function dumps information about an USB interface.
+ *------------------------------------------------------------------------*/
 void
 usbd_dump_iface(struct usbd_interface *iface)
 {
@@ -80,6 +85,11 @@
 	return;
 }
 
+/*------------------------------------------------------------------------*
+ *	usbd_dump_device
+ *
+ * This function dumps information about an USB device.
+ *------------------------------------------------------------------------*/
 void
 usbd_dump_device(struct usbd_device *udev)
 {
@@ -96,6 +106,11 @@
 	return;
 }
 
+/*------------------------------------------------------------------------*
+ *	usbd_dump_queue
+ *
+ * This function dumps the USB transfer that are queued up on an USB pipe.
+ *------------------------------------------------------------------------*/
 void
 usbd_dump_queue(struct usbd_pipe *pipe)
 {
@@ -108,6 +123,11 @@
 	return;
 }
 
+/*------------------------------------------------------------------------*
+ *	usbd_dump_pipe
+ *
+ * This function dumps information about an USB pipe.
+ *------------------------------------------------------------------------*/
 void
 usbd_dump_pipe(struct usbd_pipe *pipe)
 {
@@ -129,6 +149,11 @@
 	return;
 }
 
+/*------------------------------------------------------------------------*
+ *	usbd_dump_xfer
+ *
+ * This function dumps information about an USB transfer.
+ *------------------------------------------------------------------------*/
 void
 usbd_dump_xfer(struct usbd_xfer *xfer)
 {
@@ -182,8 +207,16 @@
 		EA_MASK = (UE_DIR_IN | UE_DIR_OUT | UE_ADDR),
 	};
 
+	/*
+	 * According to the USB specification not all bits are used
+	 * for the endpoint address. Mask away the reserved bits:
+	 */
 	ea_val &= EA_MASK;
 
+	/*
+	 * Iterate accross all the USB pipes searching for a match
+	 * based on the endpoint address:
+	 */
 	for (; pipe != pipe_end; pipe++) {
 
 		if (pipe->edesc == NULL) {
@@ -195,7 +228,9 @@
 		}
 	}
 
-	/* do the mask and check the value */
+	/*
+	 * The default pipe is always present and is checked separately:
+	 */
 	if ((udev->default_pipe.edesc) &&
 	    ((udev->default_pipe.edesc->bEndpointAddress & EA_MASK) == ea_val)) {
 		pipe = &udev->default_pipe;
@@ -272,8 +307,11 @@
 		type_val = (setup->type & UE_XFERTYPE);
 	}
 
-	/* NOTE: pipes are searched from the beginning */
-
+	/*
+	 * Iterate accross all the USB pipes searching for a match
+	 * based on the endpoint address. Note that we are searching
+	 * the pipes from the beginning of the "udev->pipes" array.
+	 */
 	for (; pipe != pipe_end; pipe++) {
 
 		if ((pipe->edesc == NULL) ||
@@ -393,7 +431,13 @@
 }
 
 /*------------------------------------------------------------------------*
- *  usbd_transfer_setup_sub - transfer setup subroutine
+ *	usbd_transfer_setup_sub - transfer setup subroutine
+ *
+ * This function must be called from the "xfer_setup" callback of the
+ * USB Host or Device controller driver when setting up an USB
+ * transfer. This function will setup correct packet sizes, buffer
+ * sizes, flags and more, that are stored in the "usbd_xfer"
+ * structure.
  *------------------------------------------------------------------------*/
 void
 usbd_transfer_setup_sub(struct usbd_setup_params *parm)
@@ -412,8 +456,10 @@
 	uint8_t type;
 	uint8_t zmps;
 
-	/* sanity check */
-
+	/*
+	 * Sanity check. The following parameters must be initialized before
+	 * calling this function.
+	 */
 	if ((parm->hc_max_packet_size == 0) ||
 	    (parm->hc_max_packet_count == 0) ||
 	    (parm->hc_max_frame_size == 0)) {
@@ -779,10 +825,15 @@
 /*------------------------------------------------------------------------*
  *	usbd_transfer_setup - setup an array of USB transfers
  *
- * NOTE: must always call unsetup after setup
+ * NOTE: You must always call "usbd_transfer_unsetup" after calling
+ * "usbd_transfer_setup" if success was returned.
+ *
+ * The idea is that the USB device driver should pre-allocate all its
+ * transfers by one call to this function.
  *
- * The idea is that the USB device driver should pre-allocate all
- * its transfers by one call to this function.
+ * Return values:
+ *    0: Success
+ * Else: Failure
  *------------------------------------------------------------------------*/
 usbd_status_t
 usbd_transfer_setup(struct usbd_device *udev,
@@ -856,7 +907,10 @@
 	while (1) {
 
 		if (buf) {
-
+			/*
+			 * Initialize the "usbd_memory_info" structure,
+			 * which is common for all our USB transfers.
+			 */
 			info = USBD_ADD_BYTES(buf, 0);
 
 			info->memory_base = buf;
@@ -875,6 +929,8 @@
 
 			LIST_INIT(&(info->done_head));
 
+			/* create a callback thread */
+
 			if (usb_thread_create
 			    (&usbd_callback_intr_td, info,
 			    &(info->done_thread), "USB interrupt thread")) {
@@ -898,12 +954,8 @@
 			} else {
 				parm.curr_setup_sub = &(setup->md);
 			}
-
+			/* skip USB transfers without callbacks: */
 			if (parm.curr_setup_sub->callback == NULL) {
-				/*
-				 * Skip USB transfers without
-				 * callbacks !
-				 */
 				continue;
 			}
 			/* see if there is a matching endpoint */
@@ -920,11 +972,15 @@
 			/* store current setup pointer */
 			parm.curr_setup = setup;
 
-			/* align data to 8 byte boundary */
+			/* align data properly */
 			parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
 
 			if (buf) {
 
+				/*
+				 * Common initialization of the
+				 * "usbd_xfer" structure.
+				 */
 				xfer = USBD_ADD_BYTES(buf, parm.size[0]);
 
 				ppxfer[n] = xfer;
@@ -940,7 +996,13 @@
 				usb_callout_init_mtx(&xfer->timeout_handle, xfer->usb_mtx,
 				    CALLOUT_RETURNUNLOCKED);
 			} else {
-				/* dummy xfer */
+				/*
+				 * Setup a dummy xfer, hence we are
+				 * writing to the "usbd_xfer"
+				 * structure pointed to by "xfer"
+				 * before we have allocated any
+				 * memory:
+				 */
 				xfer = &dummy;
 				bzero(&dummy, sizeof(dummy));
 				refcount++;
@@ -951,11 +1013,24 @@
 			xfer->pipe = pipe;
 
 			if (buf) {
+				/*
+				 * Increment the pipe refcount. This
+				 * basically prevents setting a new
+				 * configuration and alternate setting
+				 * when USB transfers are in use on
+				 * the given interface. Search the USB
+				 * code for "pipe->refcount" if you
+				 * want more information.
+				 */
 				xfer->pipe->refcount++;
 			}
 			parm.methods = xfer->pipe->methods;
 			parm.curr_xfer = xfer;
 
+			/*
+			 * Call the Host or Device controller transfer setup
+			 * routine:
+			 */
 			(udev->bus->methods->xfer_setup) (&parm);
 
 			if (parm.err) {
@@ -970,7 +1045,7 @@
 			/* no transfers - nothing to do ! */
 			goto done;
 		}
-		/* align data to 8 byte boundary */
+		/* align data properly */
 		parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
 
 		/* store offset temporarily */
@@ -992,7 +1067,7 @@
 		parm.size[0] += ((uint8_t *)parm.dma_tag_p) -
 		    ((uint8_t *)0);
 
-		/* align data to 8 byte boundary */
+		/* align data properly */
 		parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
 
 		/* store offset temporarily */
@@ -1001,7 +1076,7 @@
 		parm.size[0] += ((uint8_t *)parm.dma_page_ptr) -
 		    ((uint8_t *)0);
 
-		/* align data to 8 byte boundary */
+		/* align data properly */
 		parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
 
 		/* store offset temporarily */
@@ -1020,7 +1095,7 @@
 
 		parm.size[2] = parm.size[0];
 
-		/* align data to 8 byte boundary */
+		/* align data properly */
 		parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
 
 		parm.size[6] = parm.size[0];
@@ -1028,7 +1103,7 @@
 		parm.size[0] += ((uint8_t *)parm.xfer_length_ptr) -
 		    ((uint8_t *)0);
 
-		/* align data to 8 byte boundary */
+		/* align data properly */
 		parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
 
 		/* allocate zeroed memory */
@@ -1084,7 +1159,10 @@
 
 	if (bus->methods->get_dma_delay) {
 		(bus->methods->get_dma_delay) (bus, &temp);
-		/* round up and convert to milliseconds */
+		/*
+		 * Round up and convert to milliseconds. Note that we use
+		 * 1024 milliseconds per second. to save a division.
+		 */
 		temp += 0x3FF;
 		temp /= 0x400;
 	}
@@ -1125,10 +1203,7 @@
 		pc++;
 	}
 
-	/*
-	 * free DMA maps in all
-	 * "xfer->frbuffers"
-	 */
+	/* free DMA maps in all "xfer->frbuffers" */
 	pc = info->xfer_page_cache_start;
 	while (pc != info->xfer_page_cache_end) {
 		usbd_pc_dmamap_destroy(pc);
@@ -1140,10 +1215,8 @@
 	    info->dma_tag_max);
 
 	/*
-	 * free the "memory_base" last,
-	 * hence the "info" structure is
-	 * contained within the
-	 * "memory_base"!
+	 * free the "memory_base" last, hence the "info" structure is
+	 * contained within the "memory_base"!
 	 */
 	free(info->memory_base, M_USB);
 	return;
@@ -1152,9 +1225,9 @@
 /*------------------------------------------------------------------------*
  *	usbd_transfer_unsetup - unsetup/free an array of USB transfers
  *
- * NOTE: if the transfer was in progress, the callback will
- * called with "xfer->error=USBD_ERR_CANCELLED", before this
- * function returns
+ * NOTE: All USB transfers in progress will get called back passing
+ * the error code "USBD_ERR_CANCELLED" before this function
+ * returns.
  *------------------------------------------------------------------------*/
 void
 usbd_transfer_unsetup(struct usbd_xfer **pxfer, uint16_t n_setup)
@@ -1245,6 +1318,16 @@
 
 /*------------------------------------------------------------------------*
  *	usbd_std_root_transfer - factored out code
+ *
+ * This function is basically used for the Virtual Root HUB, end can
+ * emulate control, bulk and interrupt endpoints. Data is exchanged
+ * using the "std->ptr" and "std->len" fields, that allows kernel
+ * virtual memory to be transferred. All state is kept in the
+ * structure pointed to by the "std" argument passed to this
+ * function. The "func" argument points to a function that is called
+ * back in the various states, so that the application using this
+ * function can get a chance to select the outcome. The "func"
+ * function is allowed to sleep, exiting all mutexes.
  *------------------------------------------------------------------------*/
 void
 usbd_std_root_transfer(struct usbd_std_root_transfer *std,
@@ -1270,7 +1353,9 @@
 	/* signal that we plan to do the callback */
 	xfer->usb_thread = td;
 
+	/* check for control transfer */
 	if (xfer->flags_int.control_xfr) {
+		/* check if we are transferring the SETUP packet */
 		if (xfer->flags_int.control_hdr) {
 
 			/* copy out the USB request */
@@ -1314,8 +1399,7 @@
 	if (std->err) {
 		goto done;
 	}
-	/* transfer data */
-
+	/* Transfer data. Iterate accross all frames. */
 	while (xfer->aframes != xfer->nframes) {
 
 		len = xfer->frlengths[xfer->aframes];
@@ -1355,6 +1439,7 @@
 	if (std->err) {
 		goto done;
 	}
+	/* check if the control transfer is complete */
 	if (xfer->flags_int.control_xfr &&
 	    !xfer->flags_int.control_act) {
 
@@ -1385,7 +1470,15 @@
 }
 
 /*------------------------------------------------------------------------*
- *	usbd_control_transfer_init
+ *	usbd_control_transfer_init - factored out code
+ *
+ * In USB Device Mode we have to wait for the SETUP packet which
+ * containst the "usb_device_request_t" structure, before we can
+ * transfer any data. In USB Host Mode we already have the SETUP
+ * packet at the moment the USB transfer is started. This leads us to
+ * having to setup the USB transfer at two different places in
+ * time. This function just contains factored out control transfer
+ * initialisation code, so that we don't duplicate the code.
  *------------------------------------------------------------------------*/
 static void
 usbd_control_transfer_init(struct usbd_xfer *xfer)
@@ -1412,8 +1505,13 @@
 /*------------------------------------------------------------------------*
  *	usbd_start_hardware_sub
  *
- * To support split control transfers we need a special wrapper which
- * this function implements.
+ * This function handles initialisation of control transfers. Control
+ * transfers are special in that regard that they can both transmit
+ * and receive data.
+ *
+ * Return values:
+ *    0: Success
+ * Else: Failure
  *------------------------------------------------------------------------*/
 static uint8_t
 usbd_start_hardware_sub(struct usbd_xfer *xfer)
@@ -1530,10 +1628,10 @@
 		/* time to execute the STATUS stage */
 		xfer->flags_int.control_act = 0;
 	}
-	return (0);
+	return (0);			/* success */
 
 error:
-	return (1);
+	return (1);			/* failure */
 }
 
 /*------------------------------------------------------------------------*
@@ -1556,6 +1654,8 @@
 
 /*------------------------------------------------------------------------*
  *	usbd_start_hardware - start USB hardware for the given transfer
+ *
+ * This function should only be called from the USB callback.
  *------------------------------------------------------------------------*/
 void
 usbd_start_hardware(struct usbd_xfer *xfer)
@@ -1874,6 +1974,9 @@
 
 /*------------------------------------------------------------------------*
  *	usbd_bdma_pre_sync
+ *
+ * This function handles DMA synchronisation that must be done before
+ * an USB transfer is started.
  *------------------------------------------------------------------------*/
 void
 usbd_bdma_pre_sync(struct usbd_xfer *xfer)
@@ -1908,6 +2011,9 @@
 
 /*------------------------------------------------------------------------*
  *	usbd_bdma_post_sync
+ *
+ * This function handles DMA synchronisation that must be done after
+ * an USB transfer is complete.
  *------------------------------------------------------------------------*/
 void
 usbd_bdma_post_sync(struct usbd_xfer *xfer)
@@ -1943,7 +2049,7 @@
  * NOTE: Calling this function more than one time will only
  *       result in a single transfer start, until the USB transfer
  *       completes.
- * NOTE: if "use_polling" is set in "xfer->flags", then this
+ * NOTE: If "use_polling" is set in "xfer->flags", then this
  *       function will spin until transfer is completed
  *------------------------------------------------------------------------*/
 void
@@ -2848,6 +2954,9 @@
 
 /*------------------------------------------------------------------------*
  *	usbd_do_request_callback
+ *
+ * This function is the USB callback for generic USB Host control
+ * transfers.
  *------------------------------------------------------------------------*/
 static void
 usbd_do_request_callback(struct usbd_xfer *xfer)
@@ -2869,6 +2978,9 @@
 
 /*------------------------------------------------------------------------*
  *	usbd_handle_request_callback
+ *
+ * This function is the USB callback for generic USB Device control
+ * transfers.
  *------------------------------------------------------------------------*/
 static void
 usbd_handle_request_callback(struct usbd_xfer *xfer)
@@ -3897,7 +4009,7 @@
 /*------------------------------------------------------------------------*
  *	usbd_clear_data_toggle - factored out code
  *
- * NOTE: the job of this function is not to reset the hardware data toggle.
+ * NOTE: the intention of this function is not to reset the hardware data toggle.
  *------------------------------------------------------------------------*/
 void
 usbd_clear_data_toggle(struct usbd_device *udev, struct usbd_pipe *pipe)
@@ -3922,6 +4034,22 @@
  * Return values:
  *   0: In progress
  *   Else: Finished
+ *
+ * Clear stall config example:
+ *
+ * static const struct usbd_config my_clearstall =  {
+ *	.type = UE_CONTROL,
+ *	.endpoint = 0,
+ *	.direction = UE_DIR_ANY,
+ *	.interval = 50, //50 milliseconds
+ *	.bufsize = sizeof(usb_device_request_t),
+ *	.mh.timeout = 1000, //1.000 seconds
+ *	.mh.flags = { },
+ *	.mh.callback = &my_clear_stall_callback, //**
+ * };
+ *
+ * ** "my_clear_stall_callback" calls "usbd_clear_stall_callback"
+ * passing the correct parameters.
  *------------------------------------------------------------------------*/
 uint8_t
 usbd_clear_stall_callback(struct usbd_xfer *xfer1,
@@ -3988,20 +4116,6 @@
 	return (1);			/* Clear Stall Finished */
 }
 
-/* Clear stall config (example):
- *
- * static const struct usbd_config my_clearstall =  {
- *	.type = UE_CONTROL,
- *	.endpoint = 0,
- *	.direction = UE_DIR_ANY,
- *	.interval = 50, //50 milliseconds
- *	.bufsize = sizeof(usb_device_request_t),
- *	.mh.timeout = 1000, //1.000 seconds
- *	.mh.flags = { },
- *	.mh.callback = &my_clear_stall_callback,
- * };
- */
-
 /*------------------------------------------------------------------------*
  *	usbd_do_poll
  *


More information about the p4-projects mailing list