Personnal line discipline difficulties

From: Laurent Hugé (laurent.huge_at_wanadoo.fr)
Date: 08/25/03

  • Next message: Ingo Molnar: "Re: [patch 2.6.0t4] 1 cpu/node scheduler fix"
    To: linux-kernel@vger.kernel.org
    Date:	Mon, 25 Aug 2003 10:18:58 +0200
    
    

    Hi,

    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) {
                    return;
            }

            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");
                            return;
                    }
                    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));
                    printk("\n");
                    return;
            }

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

            struct tty_ldisc sport_ldisc= {
                    magic : TTY_LDISC_MAGIC,
                    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;
                    usleep(300*1000);
                }
                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]);
                    exit(1);
                }
                if( (fd=open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY)) == -1){
                    fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1],
    strerror(errno));
                    exit(1);
                }
                configure(fd,0);
                close(fd);
                if ((fd=open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY)) == -1){
                   fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1],
    strerror(errno));
                    exit(1);
                }
                configure(fd,1);
                i = N_TTY;
                ioctl(fd, TIOCSETD, &i);
                while (1) sleep(INT_MAX);
                exit(0);
            }

    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 majordomo@vger.kernel.org
    More majordomo info at  http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at  http://www.tux.org/lkml/
    

  • Next message: Ingo Molnar: "Re: [patch 2.6.0t4] 1 cpu/node scheduler fix"

    Relevant Pages

    • How to write a new line discipline?
      ... cards via the puc driver instead of having to use a custom driver. ... It was suggested a while ago by phk that a line discipline would ... control and read the parity information, and to set various control lines ... for Genesis Software - http://www.gsoft.com.au ...
      (freebsd-hackers)
    • [PATCH 3/3] gigaset: documentation update
      ... and for setting the UNDOCREQ kernel configuration option. ... - which drives the device through the regular serial line driver. ... This will open the device file, set its line discipline to N_GIGASET_M101, ...
      (Linux-Kernel)
    • Re: [PATCH] Add the ability to layer another driver over the serial driver
      ... It is called a line discipline. ... The probe function depends on the driver, ... but most I have seen are in task context. ...
      (Linux-Kernel)
    • Re: [alsa-devel] [RFC] [PATCH 1/3] ASoC: Add support for Conexant CX20442-11 voice modem cod
      ... for use by the ASoC board driver for Amstrad E3 videophone. ... This patch is basically fine from an ASoC point of view so I've applied ... the actual code is much more machine than codec specific. ... It was much easier to update the codec structure instance with machine's provided hw_writerather than fiddle with adding a new member to the structure definition for passing a machine callback to the line discipline functions. ...
      (Linux-Kernel)
    • Re: My thoughts on the "new development model"
      ... |>>> 2.6 tree is great for gentoo users who like gcc consuming all CPU ... |>> that after a month or so of fixes etc it will be a very stable kernel ... driver for 2.6.7 for an ADSL card; a development driver for 2.6.5 for a ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)