From owner-p4-projects@FreeBSD.ORG Tue Jun 23 14:50:27 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B77F41065715; Tue, 23 Jun 2009 14:50:26 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 70A94106570A for ; Tue, 23 Jun 2009 14:50:26 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 5E71A8FC08 for ; Tue, 23 Jun 2009 14:50:26 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5NEoQNa013545 for ; Tue, 23 Jun 2009 14:50:26 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5NEoQ3P013543 for perforce@freebsd.org; Tue, 23 Jun 2009 14:50:26 GMT (envelope-from hselasky@FreeBSD.org) Date: Tue, 23 Jun 2009 14:50:26 GMT Message-Id: <200906231450.n5NEoQ3P013543@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 164969 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2009 14:50:27 -0000 http://perforce.freebsd.org/chv.cgi?CH=164969 Change 164969 by hselasky@hselasky_laptop001 on 2009/06/23 14:50:18 USB CORE: New device side mode feature: - make sure the USB_HANDLE_REQUEST() device method can return information about short control read transfers. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/net/if_cdce.c#17 edit .. //depot/projects/usb/src/sys/dev/usb/storage/ustorage_fs.c#23 edit .. //depot/projects/usb/src/sys/dev/usb/usb_handle_request.c#15 edit .. //depot/projects/usb/src/sys/dev/usb/usb_if.m#10 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/net/if_cdce.c#17 (text+ko) ==== @@ -764,7 +764,7 @@ static int cdce_handle_request(device_t dev, const void *req, void **pptr, uint16_t *plen, - uint16_t offset, uint8_t is_complete) + uint16_t offset, uint8_t *pstate) { return (ENXIO); /* use builtin handler */ } ==== //depot/projects/usb/src/sys/dev/usb/storage/ustorage_fs.c#23 (text+ko) ==== @@ -475,10 +475,11 @@ static int ustorage_fs_handle_request(device_t dev, const void *preq, void **pptr, uint16_t *plen, - uint16_t offset, uint8_t is_complete) + uint16_t offset, uint8_t *pstate) { struct ustorage_fs_softc *sc = device_get_softc(dev); const struct usb_device_request *req = preq; + uint8_t is_complete = *pstate; if (!is_complete) { if ((req->bmRequestType == UT_WRITE_CLASS_INTERFACE) && ==== //depot/projects/usb/src/sys/dev/usb/usb_handle_request.c#15 (text+ko) ==== @@ -198,6 +198,7 @@ struct usb_device *udev = xfer->xroot->udev; int error; uint8_t iface_index; + uint8_t temp_state; if ((req.bmRequestType & 0x1F) == UT_INTERFACE) { iface_index = req.wIndex[0]; /* unicast */ @@ -222,6 +223,10 @@ /* end of interfaces non-existing interface */ goto tr_stalled; } + /* set initial state */ + + temp_state = state; + /* forward request to interface, if any */ if ((error != 0) && @@ -233,7 +238,7 @@ #endif error = USB_HANDLE_REQUEST(iface->subdev, &req, ppdata, plen, - off, state); + off, &temp_state); } iface_parent = usbd_get_iface(udev, iface->parent_iface_index); @@ -252,14 +257,18 @@ (iface_parent->subdev != iface->subdev) && device_is_attached(iface_parent->subdev)) { error = USB_HANDLE_REQUEST(iface_parent->subdev, - &req, ppdata, plen, off, - state); + &req, ppdata, plen, off, &temp_state); } if (error == 0) { /* negativly adjust pointer and length */ *ppdata = ((uint8_t *)(*ppdata)) - off; *plen += off; - goto tr_valid; + + if ((state == USB_HR_NOT_COMPLETE) && + (temp_state == USB_HR_COMPLETE_OK)) + goto tr_short; + else + goto tr_valid; } else if (error == ENOTTY) { goto tr_stalled; } @@ -337,6 +346,12 @@ USB_XFER_LOCK(xfer); return (0); +tr_short: + mtx_unlock(&Giant); + sx_unlock(udev->default_sx + 1); + USB_XFER_LOCK(xfer); + return (USB_ERR_SHORT_XFER); + tr_stalled: mtx_unlock(&Giant); sx_unlock(udev->default_sx + 1); @@ -444,6 +459,7 @@ uint16_t wValue; uint16_t wIndex; uint8_t state; + uint8_t is_complete = 1; usb_error_t err; union { uWord wStatus; @@ -596,7 +612,10 @@ USB_ADD_BYTES(&src_zcopy, 0), &max_len, req, off, state); if (err == 0) { + is_complete = 0; goto tr_valid; + } else if (err == USB_ERR_SHORT_XFER) { + goto tr_valid; } /* * Reset zero-copy pointer and max length @@ -735,7 +754,7 @@ if (rem > xfer->max_data_length) { rem = usbd_xfer_max_len(xfer); } - if (rem != max_len) { + if ((rem != max_len) && (is_complete != 0)) { /* * If we don't transfer the data we can transfer, then * the transfer is short ! ==== //depot/projects/usb/src/sys/dev/usb/usb_if.m#10 (text+ko) ==== @@ -36,6 +36,11 @@ # The device received a control request # +# The value pointed to by "pstate" can be updated to +# "USB_HR_COMPLETE_OK" to indicate that the control +# read transfer is complete, in case of short USB +# control transfers. +# # Return values: # 0: Success # ENOTTY: Transaction stalled @@ -47,5 +52,5 @@ void **pptr; /* data pointer */ uint16_t *plen; /* maximum transfer length */ uint16_t offset; /* data offset */ - uint8_t is_complete; /* set if transfer is complete, see USB_HR_XXX */ + uint8_t *pstate; /* set if transfer is complete, see USB_HR_XXX */ };