Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Dec 2007 15:04:32 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 132103 for review
Message-ID:  <200712301504.lBUF4WoI004020@repoman.freebsd.org>

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

Change 132103 by hselasky@hselasky_laptop001 on 2007/12/30 15:04:26

	
	Fix the "uchcom" interrupt endpoint callback(s).

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/uchcom.c#11 edit

Differences ...

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

@@ -894,34 +894,60 @@
 /* ----------------------------------------------------------------------
  * callback when the modem status is changed.
  */
-void
-uchcom_intr(usbd_xfer_handle xfer, usbd_private_handle priv,
-	    usbd_status status)
+static void
+uchcom_intr_callback(struct usbd_xfer *xfer)
 {
-	struct uchcom_softc *sc = priv;
-	u_char *buf = sc->sc_intr_buf;
+	struct uchcom_softc *sc = xfer->priv_sc;
+	uint8_t buf[UCHCOM_INTR_LEAST];
+
+	switch (USBD_GET_STATE(xfer)) {
+	case USBD_ST_TRANSFERRED:
 
-	if (sc->sc_ucom.sc_dying)
-		return;
+		DPRINTF(0, "actlen = %u\n", xfer->actlen);
 
-	if (status != USBD_NORMAL_COMPLETION) {
-		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
-			return;
+		if (xfer->actlen >= UCHCOM_INTR_LEAST) {
+			usbd_copy_out(xfer->frbuffers + 0, 0, buf, 
+			    UCHCOM_INTR_LEAST);
 
-		DPRINTFN(0, "abnormal status: %s\n",
-		    usbd_errstr(status));
-		usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
-		return;
-	}
-	DPRINTFN(0, "intr: 0x%02X 0x%02X 0x%02X 0x%02X "
-		 "0x%02X 0x%02X 0x%02X 0x%02X\n",
+		DPRINTFN(0, "data = 0x%02X 0x%02X 0x%02X 0x%02X\n"
 		 (unsigned)buf[0], (unsigned)buf[1],
-		 (unsigned)buf[2], (unsigned)buf[3],
-		 (unsigned)buf[4], (unsigned)buf[5],
-		 (unsigned)buf[6], (unsigned)buf[7]);
+		 (unsigned)buf[2], (unsigned)buf[3]);
 
 	uchcom_convert_status(sc, buf[UCHCOM_INTR_STAT1]);
 	ucom_status_change(&sc->sc_ucom);
+		}
+
+	case USBD_ST_SETUP:
+		if (sc->sc_flag & UCHCOM_FLAG_INTR_STALL) {
+			usbd_transfer_start(sc->sc_xfer[5]);
+		} else {
+			xfer->frlengths[0] = xfer->max_data_length;
+			usbd_start_hardware(xfer);
+		}
+		break;
+
+	default:			/* Error */
+		if (xfer->error != USBD_CANCELLED) {
+			sc->sc_flag |= UCHCOM_FLAG_INTR_STALL;
+			usbd_transfer_start(sc->sc_xfer[5]);
+		}
+		break;
+	}
+	return;
+}
+
+static void
+uchcom_intr_clear_stall_callback(struct usbd_xfer *xfer)
+{
+	struct uchcom_softc *sc = xfer->priv_sc;
+	struct usbd_xfer *xfer_other = sc->sc_xfer[4];
+
+	if (usbd_clear_stall_callback(xfer, xfer_other)) {
+		DPRINTF(0, "stall cleared\n");
+		sc->sc_flag &= ~UCHCOM_FLAG_INTR_STALL;
+		usbd_transfer_start(xfer_other);
+	}
+	return;
 }
 
 static device_method_t uchcom_methods[] = {



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