usb/138659: uftdi driver broken in RELENG_8/CURRENT

Pierre-Luc Drouin pldrouin at pldrouin.net
Tue Sep 22 12:57:52 UTC 2009


Hans Petter Selasky wrote:
> On Monday 21 September 2009 20:58:40 Pierre-Luc Drouin wrote:
>   
>> Hans Petter Selasky wrote:
>>     
>>> On Monday 21 September 2009 20:28:58 Pierre-Luc Drouin wrote:
>>>       
>>>> Hans Petter Selasky wrote:
>>>>         
>>>>> On Monday 21 September 2009 19:52:13 Pierre-Luc Drouin wrote:
>>>>>           
>>>>>> Hans Petter Selasky wrote:
>>>>>>             
>>>>>>> On Monday 21 September 2009 19:29:10 Pierre-Luc Drouin wrote:
>>>>>>>               
>>>>>>>> Hans Petter Selasky wrote:
>>>>>>>>                 
>>>>>>>>> On Monday 21 September 2009 03:44:25 Pierre-Luc Drouin wrote:
>>>>>>>>>                   
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> I am also having troubles with the uftdi driver on 8.0-BETA4.
>>>>>>>>>> I am trying to use a fan controller (mCubed bigNG) that uses a
>>>>>>>>>> FT232BL chip and it does not seem to be responding on FreeBSD 8.0
>>>>>>>>>> while the same code works perfectly on Linux (I have not tried the
>>>>>>>>>> code on RELENG_7 yet but I could install it if necessary).
>>>>>>>>>>
>>>>>>>>>> Here is the very simple code I am using for testing:
>>>>>>>>>> #include <termios.h>
>>>>>>>>>> #include <fcntl.h>
>>>>>>>>>> #include <string.h>
>>>>>>>>>> #include <unistd.h>
>>>>>>>>>> #include <stdio.h>
>>>>>>>>>>
>>>>>>>>>> int main();
>>>>>>>>>>
>>>>>>>>>> #define DEV "/dev/ttyU0"
>>>>>>>>>>
>>>>>>>>>> #define TBAN_SER_SOURCE1        0x05 /* Primary source */
>>>>>>>>>> #define TBAN_SER_SOURCE2        0x06 /* Alternative source
>>>>>>>>>> (miniNG...) */
>>>>>>>>>>
>>>>>>>>>> #define TBAN_SER_REQUEST        0x36
>>>>>>>>>>
>>>>>>>>>> int main()
>>>>>>>>>> {
>>>>>>>>>>   int fd;
>>>>>>>>>>   int result;
>>>>>>>>>>   struct termios oldtio, newtio;
>>>>>>>>>>   unsigned char buf[285];
>>>>>>>>>>
>>>>>>>>>>   printf("Opening device\n");
>>>>>>>>>>   fd=open(DEV, O_RDWR | O_NOCTTY);
>>>>>>>>>>
>>>>>>>>>>   if(fd<0) {
>>>>>>>>>>     perror(DEV);
>>>>>>>>>>     return 1;
>>>>>>>>>>   }
>>>>>>>>>>
>>>>>>>>>>   result=tcgetattr(fd,&oldtio);
>>>>>>>>>>   if(result<0) {
>>>>>>>>>>     perror("tcgetattr");
>>>>>>>>>>     return 1;
>>>>>>>>>>   }
>>>>>>>>>>
>>>>>>>>>>   memcpy(&newtio,&oldtio,sizeof(struct termios));
>>>>>>>>>>   newtio.c_cflag = B19200
>>>>>>>>>>
>>>>>>>>>>     | CRTSCTS
>>>>>>>>>>     | CS8
>>>>>>>>>>     | CREAD;
>>>>>>>>>>
>>>>>>>>>>   newtio.c_iflag     = IGNPAR;
>>>>>>>>>>   newtio.c_oflag     = 0;
>>>>>>>>>>   newtio.c_lflag     = 0;
>>>>>>>>>>   newtio.c_cc[VMIN]  = 1;
>>>>>>>>>>   newtio.c_cc[VTIME] = 0;
>>>>>>>>>>
>>>>>>>>>>   result=tcflush(fd, TCIFLUSH);
>>>>>>>>>>   if(result<0) {
>>>>>>>>>>     perror("tcflush");
>>>>>>>>>>     return 1;
>>>>>>>>>>   }
>>>>>>>>>>
>>>>>>>>>>   result=tcsetattr(fd,TCSANOW,&newtio);
>>>>>>>>>>   if(result<0) {
>>>>>>>>>>     perror("tcsetattr");
>>>>>>>>>>     return 1;
>>>>>>>>>>   }
>>>>>>>>>>
>>>>>>>>>>   sleep(1);
>>>>>>>>>>
>>>>>>>>>>   printf("Performing initial query\n");
>>>>>>>>>>   buf[0]=TBAN_SER_SOURCE1;
>>>>>>>>>>   buf[1]=TBAN_SER_REQUEST;
>>>>>>>>>>
>>>>>>>>>>   printf("Requesting status\n");
>>>>>>>>>>   result=write(fd,buf,2);
>>>>>>>>>>   if(result<0) {
>>>>>>>>>>     perror("write");
>>>>>>>>>>     return 1;
>>>>>>>>>>   }
>>>>>>>>>>
>>>>>>>>>>   sleep(1);
>>>>>>>>>>
>>>>>>>>>>   printf("Reading status\n");
>>>>>>>>>>   result=read(fd,buf,32);
>>>>>>>>>>   if(result<0) {
>>>>>>>>>>     perror("read");
>>>>>>>>>>     return 1;
>>>>>>>>>>   }
>>>>>>>>>>
>>>>>>>>>>   result=tcsetattr(fd,TCSANOW,&oldtio);
>>>>>>>>>>   if(result<0) {
>>>>>>>>>>     perror("tcsetattr");
>>>>>>>>>>     return 1;
>>>>>>>>>>   }
>>>>>>>>>>
>>>>>>>>>>   result=close(fd);
>>>>>>>>>>   if(result<0) {
>>>>>>>>>>     perror("close");
>>>>>>>>>>     return 1;
>>>>>>>>>>   }
>>>>>>>>>>   return 0;
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> It hangs while reading independently of the number of bits I am
>>>>>>>>>> reading.
>>>>>>>>>>
>>>>>>>>>> Here is the output from dmesg when I load the uftdi module:
>>>>>>>>>> Sep 20 21:31:31 ldaemon kernel: uftdi0: <USB - Serial> on usbus6
>>>>>>>>>> Sep 20 21:31:31 ldaemon kernel: ucom_attach_tty:317: tp =
>>>>>>>>>> 0xffffff001f12b400, unit = 0 Sep 20 21:31:31 ldaemon kernel:
>>>>>>>>>> ucom_attach_tty:346: ttycreate: U0 Sep 20 21:31:34 ldaemon root:
>>>>>>>>>> Unknown USB device: vendor 0x051d product 0x0002 bus uhub0
>>>>>>>>>>
>>>>>>>>>> Here is the output in /var/log/messages when I enable the debug
>>>>>>>>>> output for ucom and uftdi: Sep 20 21:33:30 ldaemon kernel:
>>>>>>>>>> ucom_open:554: tp = 0xffffff001f12b400 Sep 20 21:33:30 ldaemon
>>>>>>>>>> kernel: ucom_dtr:827: onoff = 1 Sep 20 21:33:30 ldaemon kernel:
>>>>>>>>>> ucom_line_state:799: on=0x01, off=0x00 Sep 20 21:33:30 ldaemon
>>>>>>>>>> kernel: ucom_rts:838: onoff = 1
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: ucom_line_state:799: on=0x02,
>>>>>>>>>> off=0x00 Sep 20 21:33:30 ldaemon kernel: ucom_break:816: onoff = 0
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: ucom_line_state:799: on=0x00,
>>>>>>>>>> off=0x04 Sep 20 21:33:30 ldaemon kernel: ucom_status_change:901:
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: ucom_param:950: sc =
>>>>>>>>>> 0xffffff001f12ac58 Sep 20 21:33:30 ldaemon kernel:
>>>>>>>>>> uftdi_pre_param:653:
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: ucom_dtr:827: onoff = 1
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: ucom_line_state:799: on=0x01,
>>>>>>>>>> off=0x00 Sep 20 21:33:30 ldaemon kernel: ucom_rts:838: onoff = 1
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: ucom_line_state:799: on=0x02,
>>>>>>>>>> off=0x00 Sep 20 21:33:30 ldaemon kernel: ucom_cfg_open:520:
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: uftdi_cfg_open:354:
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: uftdi_read_callback:459: status
>>>>>>>>>> change msr=0xf0 (0x00) lsr=0x60 (0x00) Sep 20 21:33:30 ldaemon
>>>>>>>>>> kernel: ucom_status_change:901:
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: uftdi_cfg_get_status:705: msr=0xf0
>>>>>>>>>> lsr=0x60 Sep 20 21:33:30 ldaemon kernel:
>>>>>>>>>> ucom_cfg_status_change:887: DCD changed to 1 Sep 20 21:33:30
>>>>>>>>>> ldaemon kernel:
>>>>>>>>>> uftdi_cfg_param:672: Sep 20 21:33:30 ldaemon kernel:
>>>>>>>>>> ucom_ioctl:653: cmd = 0x402c7413 Sep 20 21:33:30 ldaemon kernel:
>>>>>>>>>> ucom_ioctl:653: cmd = 0x80047410 Sep 20 21:33:30 ldaemon kernel:
>>>>>>>>>> ucom_ioctl:653: cmd = 0x802c7414 Sep 20 21:33:30 ldaemon kernel:
>>>>>>>>>> ucom_param:950: sc = 0xffffff001f12ac58 Sep 20 21:33:30 ldaemon
>>>>>>>>>> kernel:
>>>>>>>>>> uftdi_pre_param:653:
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: uftdi_cfg_get_status:705: msr=0xf0
>>>>>>>>>> lsr=0x60 Sep 20 21:33:30 ldaemon kernel: uftdi_cfg_param:672:
>>>>>>>>>> Sep 20 21:33:30 ldaemon kernel: ucom_get_data:1064: cnt=0
>>>>>>>>>> Sep 20 21:33:31 ldaemon kernel: ucom_ioctl:653: cmd = 0x80047410
>>>>>>>>>> Sep 20 21:33:32 ldaemon kernel: ucom_outwakeup:1009: sc =
>>>>>>>>>> 0xffffff001f12ac58 Sep 20 21:33:32 ldaemon kernel:
>>>>>>>>>> ucom_get_data:1064: cnt=2
>>>>>>>>>> Sep 20 21:33:32 ldaemon kernel: ucom_get_data:1064: cnt=0
>>>>>>>>>>
>>>>>>>>>> I really need to get this working so I am ready to test things as
>>>>>>>>>> much as I can...
>>>>>>>>>>                     
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> You need to set raw mode for the TTY device I think. Maybe Ed can
>>>>>>>>> give you the function name you need to call to do that?
>>>>>>>>>
>>>>>>>>> --HPS
>>>>>>>>>                   
>>>>>>>> Do I need to do something like that?
>>>>>>>> ioctl(fileno(stdin), TIOCGETP, &tty_org);
>>>>>>>> tty = tty_org;
>>>>>>>>
>>>>>>>> /* set terminal to raw mode ... */
>>>>>>>> tty.sg_flags |= CRMOD;
>>>>>>>> tty.sg_flags &= ~ECHO;
>>>>>>>> tty.sg_flags &= ~XTABS;
>>>>>>>> tty.sg_flags |= RAW;
>>>>>>>>
>>>>>>>> Thanks!
>>>>>>>> Pierre-Luc Drouin
>>>>>>>>                 
>>>>>>> Hi,
>>>>>>>
>>>>>>> You need to call this function:
>>>>>>>
>>>>>>>      void
>>>>>>>      cfmakeraw(struct termios *t);
>>>>>>>
>>>>>>> --HPS
>>>>>>>               
>>>>>> Hi,
>>>>>>
>>>>>> it still does not work. I have added the line
>>>>>> cfmakeraw(&newtio);
>>>>>>
>>>>>> just before the call to tcflush and I get the following output in
>>>>>> /var/log/messages:
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_open:554: tp = 0xffffff001f12b400
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_dtr:827: onoff = 1
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_line_state:799: on=0x01, off=0x00
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_rts:838: onoff = 1
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_line_state:799: on=0x02, off=0x00
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_break:816: onoff = 0
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_line_state:799: on=0x00, off=0x04
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_status_change:901:
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_param:950: sc =
>>>>>> 0xffffff001f12ac58 Sep 21 13:38:46 ldaemon kernel:
>>>>>> uftdi_pre_param:653:
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_dtr:827: onoff = 1
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_line_state:799: on=0x01, off=0x00
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_rts:838: onoff = 1
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_line_state:799: on=0x02, off=0x00
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_cfg_open:520:
>>>>>> Sep 21 13:38:46 ldaemon kernel: uftdi_cfg_open:354:
>>>>>> uftdi_cfg_get_status:705: msr=0xf0 lsr=0x60
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_cfg_status_change:887: DCD
>>>>>> changed to 1 Sep 21 13:38:46 ldaemon kernel: uftdi_cfg_param:672:
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_ioctl:653: cmd = 0x402c7413
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_ioctl:653: cmd = 0x80047410
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_ioctl:653: cmd = 0x802c7414
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_param:950: sc =
>>>>>> 0xffffff001f12ac58 Sep 21 13:38:46 ldaemon kernel:
>>>>>> uftdi_pre_param:653:
>>>>>> Sep 21 13:38:46 ldaemon kernel: uftdi_cfg_param:672:
>>>>>> Sep 21 13:38:46 ldaemon kernel: ucom_get_data:1064: cnt=0
>>>>>> Sep 21 13:38:47 ldaemon kernel: ucom_ioctl:653: cmd = 0x80047410
>>>>>> Sep 21 13:38:48 ldaemon kernel: ucom_outwakeup:1009: sc =
>>>>>> 0xffffff001f12ac58 Sep 21 13:38:48 ldaemon kernel: ucom_get_data:1064:
>>>>>> cnt=2
>>>>>> Sep 21 13:38:48 ldaemon kernel: ucom_get_data:1064: cnt=0
>>>>>>             
>>>>> Can you try adding a delay after setting the baud rate?
>>>>>
>>>>> --HPS
>>>>>           
>>>> The code already sleeps for 1 second after I applying the baud rate (via
>>>> tcsetattr(fd,TCSANOW,&newtio)). I am not sure to understand what you
>>>> mean...
>>>>         
>>> Hi,
>>>
>>> I mean try adding some:
>>>
>>> usleep(1000000);
>>>
>>> To your code to see if that changes anything.
>>>
>>> Also try reading one byte instead of 32.
>>>
>>> Last, try adding a printout to:
>>>
>>> src/sys/dev/usb/serial/uftdi.c
>>>
>>> uftdi_read_callback()
>>>
>>> and printout the actlen variable.
>>>
>>> --HPS
>>>       
>> ok, so I added the usleep statement right after the existing sleep
>> statement. I also tried reading a single byte. It did not make any
>> difference... I added a print statement to print the value of actlen
>> right after it is set via
>> usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
>>
>> Here is the new output in /var/log/messages:
>> Sep 21 14:55:28 ldaemon kernel: ucom_open:554: tp = 0xffffff0139488800
>> Sep 21 14:55:28 ldaemon kernel: ucom_dtr:827: onoff = 1
>> Sep 21 14:55:28 ldaemon kernel: ucom_line_state:799: on=0x01, off=0x00
>> Sep 21 14:55:28 ldaemon kernel: ucom_rts:838: onoff = 1
>> Sep 21 14:55:28 ldaemon kernel: ucom_line_state:799: on=0x02, off=0x00
>> Sep 21 14:55:28 ldaemon kernel: ucom_break:816: onoff = 0
>> Sep 21 14:55:28 ldaemon kernel: ucom_line_state:799: on=0x00, off=0x04
>> Sep 21 14:55:28 ldaemon kernel: ucom_status_change:901:
>> Sep 21 14:55:28 ldaemon kernel: ucom_param:950: sc = 0xffffff013bcac458
>> Sep 21 14:55:28 ldaemon kernel: ucom_dtr:827: onoff = 1
>> Sep 21 14:55:28 ldaemon kernel: ucom_line_state:799: on=0x01, off=0x00
>> Sep 21 14:55:28 ldaemon kernel: ucom_rts:838: onoff = 1
>> Sep 21 14:55:28 ldaemon kernel: ucom_line_state:799: on=0x02, off=0x00
>> Sep 21 14:55:28 ldaemon kernel: ucom_cfg_open:520:
>> Sep 21 14:55:28 ldaemon kernel: actlen is 0
>> Sep 21 14:55:28 ldaemon kernel: actlen is 2
>> Sep 21 14:55:28 ldaemon kernel: actlen is 2
>> Sep 21 14:55:28 ldaemon kernel: ucom_cfg_status_change:887: DCD changed to
>> 1 Sep 21 14:55:28 ldaemon kernel: ucom_ioctl:653: cmd = 0x402c7413
>> Sep 21 14:55:28 ldaemon kernel: ucom_ioctl:653: cmd = 0x80047410
>> Sep 21 14:55:28 ldaemon kernel: ucom_ioctl:653: cmd = 0x802c7414
>> Sep 21 14:55:28 ldaemon kernel: ucom_param:950: sc = 0xffffff013bcac458
>> Sep 21 14:55:28 ldaemon kernel: actlen is 2
>> Sep 21 14:55:28 ldaemon last message repeated 12 times
>> Sep 21 14:55:28 ldaemon kernel: ucom_get_data:1064: cnt=0
>> Sep 21 14:55:28 ldaemon kernel: actlen is 2
>> Sep 21 14:55:30 ldaemon last message repeated 111 times
>> Sep 21 14:55:30 ldaemon kernel: ucom_ioctl:653: cmd = 0x80047410
>> Sep 21 14:55:30 ldaemon kernel: actlen is 2
>> Sep 21 14:55:31 ldaemon last message repeated 62 times
>> Sep 21 14:55:31 ldaemon kernel: ucom_outwakeup:1009: sc =
>> 0xffffff013bcac458 Sep 21 14:55:31 ldaemon kernel: ucom_get_data:1064:
>> cnt=2
>> Sep 21 14:55:31 ldaemon kernel: ucom_get_data:1064: cnt=0
>> Sep 21 14:55:31 ldaemon kernel: actlen is 2
>>     
>
> If actlen is 2 then no modem data is transferred from the device.
>
> --HPS
>   
Hmm, so does it indicate a bug in uftdi? In asynchronous mode, SIGIO is 
generated but when try reading I get error EINTR...

Thanks!


More information about the freebsd-usb mailing list