usb/83863: Communication problem between opensc/openct via USB
with e-gate smart-card.
Hans Petter Selasky
hselasky at c2i.net
Thu Aug 4 19:10:17 GMT 2005
The following reply was made to PR usb/83863; it has been noted by GNATS.
From: Hans Petter Selasky <hselasky at c2i.net>
To: Mohacsi Janos <mohacsi at niif.hu>
Cc: bug-followup at freebsd.org,
janos.mohacsi at 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<VF>
> 1c000007<LS>,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<VF>
> 3c400004<STALLED,LS,SPD>,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<T> 3d8003ff<ACTIVE,IOC,LS,SPD>,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<STALLED> 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--
More information about the freebsd-usb
mailing list