From owner-freebsd-usb@FreeBSD.ORG Thu Aug 4 19:10:17 2005 Return-Path: X-Original-To: freebsd-usb@hub.freebsd.org Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5DBC016A41F for ; Thu, 4 Aug 2005 19:10:17 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1D24143D45 for ; Thu, 4 Aug 2005 19:10:17 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.3/8.13.3) with ESMTP id j74JAGWG027802 for ; Thu, 4 Aug 2005 19:10:16 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.3/8.13.1/Submit) id j74JAGnY027801; Thu, 4 Aug 2005 19:10:16 GMT (envelope-from gnats) Date: Thu, 4 Aug 2005 19:10:16 GMT Message-Id: <200508041910.j74JAGnY027801@freefall.freebsd.org> To: freebsd-usb@FreeBSD.org From: Hans Petter Selasky Cc: Subject: Re: usb/83863: Communication problem between opensc/openct via USB with e-gate smart-card. X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Hans Petter Selasky List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Aug 2005 19:10:17 -0000 The following reply was made to PR usb/83863; it has been noted by GNATS. From: Hans Petter Selasky To: Mohacsi Janos Cc: bug-followup@freebsd.org, janos.mohacsi@bsd.hu Subject: Re: usb/83863: Communication problem between opensc/openct via USB with e-gate smart-card. Date: Thu, 4 Aug 2005 21:04:19 +0200 --Boundary-00=_1am8Czaqof+Hkbv Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline On Thursday 04 August 2005 16:39, Mohacsi Janos wrote: > Hi Hans, > Here it is: - (Sorry, it is large... - should I omit > bug-followup next time?) I think it is ok. It is not so much. Stalled means that the data-toggle has the wrong value. The data toggle can have two values, either 1 or 0, and is marked "D=" in the debugging output. Control transfers always start with D=0, and end with D=1. I cannot see anything wrong. The 8-bytes are the request header, and that is accepted. Then the 5-bytes are the data to write, and that is not accepted. > uhci_check_transfer: xfer=0xc1bb3000 active Aug 4 15:48:10 scone kernel: > uhci_non_isoc_done: xfer=0xc1bb3000 pipe=0xc1ca3004 transfer done Aug 4 > 15:48:10 scone kernel: uhci_dump_td: TD(0xc1bb31f0) at 002071f4 = > link=0x00207214 status=0x1c000007 token=0x00e07e2d buffer=0x002071d4 Aug 4 > 15:48:10 scone kernel: uhci_dump_td: 207214 > 1c000007,errcnt=3,actlen=8 pid=2d,addr=126,endpt=0,D=0,maxlen=8 Aug 4 > 15:48:10 scone kernel: uhci_dump_td: TD(0xc1bb3210) at 00207214 = > link=0x00207234 status=0x3c400004 token=0x00887ee1 buffer=0x002071dc Aug 4 > 15:48:10 scone kernel: uhci_dump_td: 207234 > 3c400004,errcnt=3,actlen=5 > pid=e1,addr=126,endpt=0,D=1,maxlen=5 Aug 4 15:48:10 scone kernel: > uhci_dump_td: TD(0xc1bb3230) at 00207234 = link=0x00000001 > status=0x3d8003ff token=0xffe87e69 buffer=0x00000000 Aug 4 15:48:10 scone > kernel: uhci_dump_td: 1 3d8003ff,errcnt=3,actlen=0 > pid=69,addr=126,endpt=0,D=1,maxlen=0 Aug 4 15:48:10 scone kernel: > uhci_non_isoc_done: actlen=13 > Aug 4 15:48:10 scone kernel: uhci_non_isoc_done: error, addr=126, > endpt=0x00, status 400000 Aug 4 15:48:10 scone kernel: > uhci_device_done: xfer=0xc1bb3000, pipe=0xc1ca3004 length=13 error=22 Aug > 4 15:48:10 scone kernel: _uhci_remove_qh: 0xc1bb3270 from 0xc1bb3270 Aug 4 > 15:48:10 scone kernel: uhci_device_done: xfer=0xc1bb3000, pipe=0xc1ca3004 > length=13 error=5 Aug 4 15:48:10 scone kernel: _uhci_remove_qh: 0xc1bb3270 > from 0xdd6c5000 Aug 4 15:48:10 scone ifdhandler[808]: usb_do_request > failed: Input/output error (5) Aug 4 15:48:11 scone kernel: > uhci_root_intr_start: xfer=0xc1be6c00 len=32 > > > 3. the usb handler routine is attached sys-bsd.c. You will find the > usb_do_request ioctl in the function ifd_sysdep_usb_control() - I am not > sure usb device handled properly there - timeout? USBD_SHORT_XFER_OK > option? I think USBD_SHORT_XFER_OK is valid for control transfers. Setting the timeout is valid too. > > 4. The relevant part of the egate driver also included. For some reason > it does not like the EGATE_CMD_SEND_APDU (0x80): > ifd_usb_control() actually after some debug printing and setting timeout > to 10000 if <0, invokes ifd_sysdep_usb_control() > The best I can come up with, is that we issue a clear stall request on the control endpoint, and then repeat the transfer. See if you can apply the attached patch: cd directory_where_files_are cat sys-bsd.c.diff | patch Post debugging output again. --HPS --Boundary-00=_1am8Czaqof+Hkbv Content-Type: text/x-diff; charset="iso-8859-1"; name="sys-bsd.c.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="sys-bsd.c.diff" *** sys-bsd.c.ref Thu Aug 4 20:33:40 2005 --- sys-bsd.c Thu Aug 4 20:59:59 2005 *************** *** 215,220 **** --- 215,251 ---- return 0; } + static void + ifd_sysdep_usb_clearstall(ifd_device_t *dev, u_int8_t endpoint) + { + struct usb_ctl_request ctrl; + int rc, val; + + bzero(&ctrl, sizeof(ctrl)); + + ctrl.ucr_request.bmRequestType = UT_WRITE_ENDPOINT; + ctrl.ucr_request.bRequest = UR_CLEAR_FEATURE; + USETW(ctrl.ucr_request.wValue, UF_ENDPOINT_HALT); + USETW(ctrl.ucr_request.wIndex, endpoint); + USETW(ctrl.ucr_request.wLength, 0); + + val = 1000; + if ((rc = ioctl(dev->fd, USB_SET_TIMEOUT, &val)) < 0) { + ifd_debug(1,"USB_SET_TIMEOUT failed: %d", rc); + ct_error("usb_set_timeout failed: %s(%d)", + strerror(errno), errno); + return; + } + + if ((rc = ioctl(dev->fd, USB_DO_REQUEST, &ctrl)) < 0) { + ifd_debug(1, "USB_DO_REQUEST failed: %d", rc); + ct_error("usb_do_request failed: %s (%d)", + strerror(errno), errno); + return; + } + return; + } + /* * USB control command */ *************** *** 228,233 **** --- 259,265 ---- { struct usb_ctl_request ctrl; int rc,val; + int count = 1; ifd_debug(1, "BSD: ifd_sysdep_usb_control(0x%x)", request); memset(&ctrl, 0, sizeof(ctrl)); *************** *** 247,252 **** --- 279,286 ---- if(len) ifd_debug(5, "BSD: CTRL SEND data %s", ct_hexdump(data,len)); + repeat: + val = timeout; if ((rc = ioctl(dev->fd, USB_SET_TIMEOUT, &val)) < 0) { ifd_debug(1,"USB_SET_TIMEOUT failed: %d", rc); *************** *** 259,264 **** --- 293,307 ---- ifd_debug(1, "USB_DO_REQUEST failed: %d", rc); ct_error("usb_do_request failed: %s (%d)", strerror(errno), errno); + if(count) + { + count--; + + ifd_debug(1, "trying to clear stall ..."); + + ifd_sysdep_usb_clearstall(dev, 0); + goto repeat; + } return IFD_ERROR_COMM_ERROR; } --Boundary-00=_1am8Czaqof+Hkbv--