From owner-p4-projects@FreeBSD.ORG Tue Oct 21 14:54:32 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 107421065672; Tue, 21 Oct 2008 14:54:32 +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 BF5211065670 for ; Tue, 21 Oct 2008 14:54:31 +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 AE3E98FC1B for ; Tue, 21 Oct 2008 14:54:31 +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 m9LEsVxQ016687 for ; Tue, 21 Oct 2008 14:54:31 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id m9LEsVFs016685 for perforce@freebsd.org; Tue, 21 Oct 2008 14:54:31 GMT (envelope-from hselasky@FreeBSD.org) Date: Tue, 21 Oct 2008 14:54:31 GMT Message-Id: <200810211454.m9LEsVFs016685@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 151664 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, 21 Oct 2008 14:54:32 -0000 http://perforce.freebsd.org/chv.cgi?CH=151664 Change 151664 by hselasky@hselasky_laptop001 on 2008/10/21 14:53:33 Improve UGEN ioctl interface by not returning EBUSY if parameters that should be set do not change value. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#28 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#28 (text+ko) ==== @@ -867,8 +867,9 @@ * Else: No access *------------------------------------------------------------------------*/ static int -ugen_check_request(struct usb2_device_request *req) +ugen_check_request(struct usb2_device *udev, struct usb2_device_request *req) { + struct usb2_pipe *pipe; int error; /* @@ -889,13 +890,21 @@ } } /* - * Clearing the stall this way is not allowed, hence it does - * not update the data toggle value in "struct usb2_pipe" ! + * Special case - handle clearing of stall */ if (req->bmRequestType == UT_WRITE_ENDPOINT) { - error = priv_check(curthread, PRIV_DRIVER); - if (error) { - return (error); + + pipe = usb2_get_pipe_by_addr(udev, req->wIndex[0]); + if (pipe == NULL) { + return (EINVAL); + } + if (usb2_check_thread_perm(udev, curthread, FREAD | FWRITE, + pipe->iface_index, req->wIndex[0] & UE_ADDR)) { + return (EPERM); + } + if ((req->bRequest == UR_CLEAR_FEATURE) && + (UGETW(req->wValue) == UF_ENDPOINT_HALT)) { + usb2_clear_data_toggle(udev, pipe); } } /* TODO: add more checks to verify the interface index */ @@ -914,7 +923,7 @@ /* control endpoint only */ return (EINVAL); } - if (ugen_check_request(&ur->ucr_request)) { + if (ugen_check_request(f->udev, &ur->ucr_request)) { return (EPERM); } len = UGETW(ur->ucr_request.wLength); @@ -1105,7 +1114,7 @@ return (error); } } - if (ugen_check_request(req)) { + if (ugen_check_request(f->udev, req)) { xfer->error = USB_ERR_INVAL; goto complete; } @@ -1652,14 +1661,22 @@ static int ugen_set_short_xfer(struct usb2_fifo *f, void *addr) { + uint8_t t; + + if (*(int *)addr) + t = 1; + else + t = 0; + + if (f->flag_short == t) { + /* same value like before - accept */ + return (0); + } if (f->xfer[0] || f->xfer[1]) { /* cannot change this during transfer */ return (EBUSY); } - if (*(int *)addr) - f->flag_short = 1; - else - f->flag_short = 0; + f->flag_short = t; return (0); } @@ -1688,16 +1705,24 @@ static int ugen_set_buffer_size(struct usb2_fifo *f, void *addr) { + uint32_t t; + + if (*(int *)addr < 1024) + t = 1024; + else if (*(int *)addr < (256 * 1024)) + t = *(int *)addr; + else + t = 256 * 1024; + + if (f->bufsize == t) { + /* same value like before - accept */ + return (0); + } if (f->xfer[0] || f->xfer[1]) { /* cannot change this during transfer */ return (EBUSY); } - if (*(int *)addr < 1024) - f->bufsize = 1024; - else if (*(int *)addr < (256 * 1024)) - f->bufsize = *(int *)addr; - else - f->bufsize = 256 * 1024; + f->bufsize = t; return (0); }