PERFORCE change 166072 for review

Sylvestre Gallon syl at FreeBSD.org
Tue Jul 14 09:08:35 UTC 2009


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

Change 166072 by syl at syl_pablo on 2009/07/14 09:08:11

	Implement s3c24dci_timeout.
	Implement s3c24dci_standard_done_sub.
	Implement s3c24dci_standard_done.
	Implement s3c24dci_xfer_do_fifo.
	Implement s3c24dci_start_standard_chain.

Affected files ...

.. //depot/projects/soc2009/syl_usb/src/sys/dev/usb/controller/s3c24xxdci.c#10 edit

Differences ...

==== //depot/projects/soc2009/syl_usb/src/sys/dev/usb/controller/s3c24xxdci.c#10 (text+ko) ====

@@ -161,14 +161,193 @@
 }
 
 static void
-s3c24dci_setup_standard_chain(struct usb_xfer *xfer)
+s3c24dci_timeout(void *arg)
+{
+	struct usb_xfer *xfer = arg;
+
+	DPRINTFN("xfer=%p\n", xfer);
+
+	USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
+
+	/* transfer is transferred */
+	s3c24dci_device_done(xfer, USB_ERR_TIMEOUT);
+}
+
+static usb_error_t
+s3c24dci_standard_done_sub(struct usb_xfer *xfer)
+{
+	struct s3c24dci_td *td;
+	uint32_t len;
+	uint8_t error;
+
+	DPRINTFN(9, "\n");
+
+	td = xfer->td_transfer_cache;
+
+	do {
+		len = td->remainder;
+
+		if (xfer->aframes != xfer->nframes) {
+			/*
+		         * Verify the length and subtract
+		         * the remainder from "frlengths[]":
+		         */
+			if (len > xfer->frlengths[xfer->aframes]) {
+				td->error = 1;
+			} else {
+				xfer->frlengths[xfer->aframes] -= len;
+			}
+		}
+		/* Check for transfer error */
+		if (td->error) {
+			/* the transfer is finished */
+			error = 1;
+			td = NULL;
+			break;
+		}
+		/* Check for short transfer */
+		if (len > 0) {
+			if (xfer->flags_int.short_frames_ok) {
+				/* follow alt next */
+				if (td->alt_next) {
+					td = td->obj_next;
+				} else {
+					td = NULL;
+				}
+			} else {
+				/* the transfer is finished */
+				td = NULL;
+			}
+			error = 0;
+			break;
+		}
+		td = td->obj_next;
+
+		/* this USB frame is complete */
+		error = 0;
+		break;
+
+	} while (0);
+
+	/* update transfer cache */
+
+	xfer->td_transfer_cache = td;
+
+	return (error ?
+	    USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
+}
+
+static void
+static void
+s3c24dci_standard_done(struct usb_xfer *xfer)
+{
+	usb_error_t err = 0;
+
+	DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n",
+	   xfer, xfer->endpoint);
+
+	/* reset scanner */
+
+	xfer->td_transfer_cache = xfer->td_transfer_first;
+
+	if (xfer->flags_int.control_xfr) {
+		if (xfer->flags_int.control_hdr) {
+			err = s3c24dci_standard_done_sub(xfer);
+		}
+		xfer->aframes = 1;
+		if (xfer->td_transfer_cache == NULL) {
+			goto done;
+		}
+	}
+	while (xfer->aframes != xfer->nframes) {
+		err = s3c24dci_standard_done_sub(xfer);
+		xfer->aframes++;
+
+		if (xfer->td_transfer_cache == NULL) {
+			goto done;
+		}
+	}
+
+	if (xfer->flags_int.control_xfer &&
+	    !xfer->flags_int.control_act) {
+		err = s3c24dci_standard_done_sub(xfer);
+	}
+done:
+	s3c24dci_device_done(xfer, err);
+}
+
+static uint8_t
+s3c24dci_xfer_do_fifo(struct usb_xfer *xfer)
 {
+	struct s3c24dci_softc *sc;
+	struct s3c24dci_td *td;
 
+	DPRINTFN(9, "\n");
+
+	td = xfer->td_transfer_cache;
+	while (1) {
+		if ((td->func)(td)) {
+			/* operation in progress */
+			break ;
+		}
+		if (((void *)td) == xfer->td_transfer_last) {
+			goto done;
+		} else if (td->remainder > 0) {
+			/*
+			 * We had a short transfer. If there is no alternate
+			 * next, stop processing !
+			 */
+			if (!td->alt_next) {
+				goto done;
+			}
+			/* 
+			 * Fetch the next transfer descriptor and transfer
+			 * some flags to the next transfer descriptor.
+			 */
+			td = td->obj_next;
+			xfer->td_transfer_cache = td;
+		}
+		return (1);
+done:
+		s3c24dci_standard_done(xfer);
 }
 
 static void
 s3c24dci_start_standard_chain(struct usb_xfer *xfer)
 {
+	DPRINTFN(9, "\n");
+
+	/* poll one time */
+	if (s3c24dci_xfer_do_fifo(xfer)) {
+		struct at91dci_softc *sc = S3C24_DCI_BUS2SC(xfer->xroot->bus);
+		uint8_t ep_no = xfer->endpointno & UE_ADDR;
+		uint32_t ittmp;
+
+		/*
+		 * Only enable the endpoint interrupt when we are actually
+		 * waiting for data, hence we are dealing with level
+		 * triggered interrupts !
+		 */
+		ittmp = S3C24XX_DCI_READ_4(sc, S3C24_DCI_EP_INT_EN);
+		ittmp |= (1<<ep_no);
+		S3C24XX_DCI_WRITE_4(sc, S3C24_DCI_EP_INT_EN, ittmp);	
+
+		DPRINTFN(15, "enable interrupts on endpoint %d\n", ep_no);
+
+		/* put transfer on interrupt queue */
+		usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
+
+		/* start timeout, if any */
+		if (xfer->timeout != 0) {
+			usbd_transfer_timeout_ms(xfer,
+			    &s3c24dci_timeout, xfer->timeout);
+		}
+	}
+}
+
+static void
+s3c24dci_setup_standard_chain(struct usb_xfer *xfer)
+{
 
 }
 


More information about the p4-projects mailing list