Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: ucom(4) hang up



Hi! Steve,


From: Steve Woodford <scw%NetBSD.org@localhost>
Date: Fri, 19 Feb 2010 14:29:14 +0000

> On Friday 19 February 2010 12:56:25 KIYOHARA Takashi wrote:
> 
> > I understood this problem.
> > uftdi(4) might receive state information only, not the data part.
> > uftdi_read() will return cp+2 and set 0 to cc.
> > And, neither uc_index nor uc_len never become the same though
> > ucomreadcb() calls ucom_read_complete().
> 
> Thanks for the analysis. Can you test if the patch, below, fixes the 
> problem?

Oops,  your patch not clear this problem.
If uftdi receives three data (msr, lsr, data), uftdi_read() will be
set to cp+2 and cc=1. In this case, ucom_read_complete() will never
call rint().

> @@ -1167,7 +1167,7 @@
>  
>               splx(s);
>  
> -             if (ub->ub_index == ub->ub_len) {
> +             if (ub->ub_index >= ub->ub_len) {
>                       SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_full, ub_link);
>  
>                       ucomsubmitread(sc, ub);


I propose two methods. We should choose either.

1. sc_methods->ucom_read() returns the data total count received to
   variable cc.  If 'ub_index < ub_len', ucom_read_complete() calls
   rint.

Index: uftdi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/uftdi.c,v
retrieving revision 1.45
diff -u -r1.45 uftdi.c
--- uftdi.c     18 Jan 2010 20:57:13 -0000      1.45
+++ uftdi.c     20 Feb 2010 06:36:33 -0000
@@ -428,7 +429,6 @@

        /* Pick up status and adjust data part. */
        *ptr += 2;
-       *count -= 2;
 }

 Static void


2. If 'ub_len > 0', calls rint() in ucom_read_complete().  Perhaps,
   this is equal to ucom before 1.81.

Index: ucom.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ucom.c,v
retrieving revision 1.82
diff -u -r1.82 ucom.c
--- ucom.c      6 Jan 2010 20:37:56 -0000       1.82
+++ ucom.c      20 Feb 2010 06:56:44 -0000
@@ -1156,18 +1156,21 @@

                s = spltty();

-               while (ub->ub_index < ub->ub_len && !sc->sc_rx_stopped) {
+               while (ub->ub_len > 0 && !sc->sc_rx_stopped) {
                        /* Give characters to tty layer. */
                        if ((*rint)(ub->ub_data[ub->ub_index], tp) == -1) {
                                /* Overflow: drop remainder */
-                               ub->ub_index = ub->ub_len;
-                       } else
+                               ub->ub_index += ub->ub_len;
+                               ub->ub_len = 0;
+                       } else {
                                ub->ub_index++;
+                               ub->ub_len--;
+                       }
                }

                splx(s);

-               if (ub->ub_index == ub->ub_len) {
+               if (ub->ub_len == 0) {
                        SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_full, ub_link);

                        ucomsubmitread(sc, ub);


I recommend the latter.

Thanks,
--
kiyohara


Home | Main Index | Thread Index | Old Index