[lkml]   [2003]   [Aug]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
SubjectPersonnal line discipline difficulties

Please be kind to advise me if I don't post on the right mailing-list.

I'm trying to implement a driver to a specific network peripherial (not
commercial) ; this peripherial uses both parallel and serial ports to connect
to one PC. I've succeeded in managing the parallel port, but the serial one
still raises some difficulties (yet, I've used Linux Device Drivers book from
Rubini, I've looked sources of bluetooth and n_tty drivers, searched Internet
and eventually asked on kernelnewbies mailing-list with no solution).

My serial involved module code is :
int ccsds_sport_ldisc_attach(struct tty_struct *tty) {
return 0;

void ccsds_sport_ldisc_detach(struct tty_struct *tty) {

void ccsds_sport_receive_buf(struct tty_struct *tty, const unsigned
char *cp, char *fp, int count) {
struct sk_buff *skb;
int i;

skb = dev_alloc_skb(count);
if (!skb) {
printk("<4>low memory\n");
memcpy(skb_put(skb, count), cp, count);
printk("<7>Size = %i\n", count);
printk("<7>Data : ");
for (i=0; i<count; i++)
printk(" %.2X(%2X)",*(cp+i), *(fp+i));

int ccsds_sport_ldisc_receive_room(struct tty_struct *tty) {
return 248; /* Hardware property */

struct tty_ldisc sport_ldisc= {
name : "ccsds_sport_ldisc",
flags : 0,
open : ccsds_sport_ldisc_attach,
close : ccsds_sport_ldisc_detach,
receive_buf : ccsds_sport_receive_buf,
receive_room : ccsds_sport_ldisc_receive_room,
and call of
result=tty_register_ldisc(N_TTY, &sport_ldisc);
in module_init (which returns no error).

To activate the line discipline, I use a modified version of the kirkrun from
Rubini :
int configure(int fd, int toggle)
struct termios newTermIo;
unsigned int bits;
if (toggle) {
/* First of all, toggle RTS and DTR */
if (ioctl(fd,TIOCMGET,&bits)) return -1;
bits &= ~(TIOCM_RTS | TIOCM_DTR);
if (ioctl(fd,TIOCMSET,&bits)) return -1;
usleep(300*1000); bits |= (TIOCM_RTS | TIOCM_DTR);
if (ioctl(fd,TIOCMSET,&bits)) return -1;
memset(&newTermIo, 0, sizeof(struct termios));
newTermIo.c_iflag = IGNBRK |IGNPAR;
newTermIo.c_oflag = 0;
newTermIo.c_cflag = CS8 | CREAD | HUPCL | CLOCAL | CRTSCTS;
newTermIo.c_lflag = 0;
newTermIo.c_cc[VMIN] = 1;
newTermIo.c_cc[VTIME] = 0;
if (cfsetispeed(&newTermIo, B115200) < 0)
return -1;
if (tcsetattr(fd, TCSANOW, &newTermIo) < 0)
return -1;
tcflush(fd, TCIOFLUSH);
fcntl(fd, F_SETFL, 0); /* clear ndelay */
return 0;

int main(int argc, char **argv)
int fd, i;

if (argc != 2) {
fprintf(stderr, "%s: Use \"%s <dev>\"\n", argv[0], argv[0]);
if( (fd=open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY)) == -1){
fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1],
if ((fd=open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY)) == -1){
fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1],
i = N_TTY;
ioctl(fd, TIOCSETD, &i);
while (1) sleep(INT_MAX);

I tried my driver with
echo 123456789 > /dev/ttyS0
from another PC (with the same line parameters according to setserial), but
the result is not constant : sometimes, the line discipline receive the 11
caracters (including the 0D and 0A termination), but most of the time, it
receive firstly 8 the 3 caracters. The *fp value is always 0 (so there's no
error !).
Following a piece of advice from kernelnewbies mailing-list, I've used minicom
for testing, but the result is worst : I receiva each time only 1 caracter
(99% of time FF), and there's still a zero value of *fp.

The fact is that I do need to receive an accurate count of emitted caracters
(since the protocol used doesn't carry the size of PDU).

Does anyone know what I've fogotten in the line discipline ?
Thanks in advance,
Laurent Hugé.

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at
Please read the FAQ at

 \ /
  Last update: 2005-03-22 13:48    [W:0.060 / U:0.536 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site