Lines Matching +full:frame +full:- +full:buffer
17 * tty device drivers that support bit-synchronous HDLC communications.
19 * All HDLC data is frame oriented which means:
21 * 1. tty write calls represent one complete transmit frame of data
22 * The device driver should accept the complete frame or none of
23 * the frame (busy) in the write method. Each write call should have
24 * a byte count in the range of 2-65535 bytes (2 is min HDLC frame
27 * CCITT CRC32, 4 crc bytes are required, so the maximum size frame
29 * CRC16, the maximum application frame size would be 65533.
33 * one received frame. The device driver should bypass
34 * the tty flip buffer and call the line discipline receive
42 * 3. tty read calls returns an entire frame of data or nothing.
50 * otherwise the count of the next available frame is returned.
51 * (instead of the sum of all received frame counts).
55 * this line discipline (or another line discipline that is frame
65 * and frame orientation of HDLC communications.
133 * struct n_hdlc - per device instance data structure
134 * @magic - magic value for structure
135 * @flags - miscellaneous control flags
136 * @tty - ptr to TTY structure
137 * @backup_tty - TTY to use if tty gets closed
138 * @tbusy - reentrancy flag for tx wakeup code
139 * @woke_up - FIXME: describe this field
140 * @tbuf - currently transmitting tx buffer
141 * @tx_buf_list - list of pending transmit frame buffers
142 * @rx_buf_list - list of received frame buffers
143 * @tx_free_buf_list - list unused transmit frame buffers
144 * @rx_free_buf_list - list unused received frame buffers
161 * HDLC buffer list manipulation functions
176 /* max frame size for memory allocations */
197 #define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
198 #define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty)
205 while ((buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list))) in flush_rx_queue()
206 n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, buf); in flush_rx_queue()
215 while ((buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list))) in flush_tx_queue()
216 n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, buf); in flush_tx_queue()
217 spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags); in flush_tx_queue()
218 if (n_hdlc->tbuf) { in flush_tx_queue()
219 n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, n_hdlc->tbuf); in flush_tx_queue()
220 n_hdlc->tbuf = NULL; in flush_tx_queue()
222 spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); in flush_tx_queue()
241 * n_hdlc_release - release an n_hdlc per device line discipline info structure
242 * @n_hdlc - per device line discipline info structure
253 wake_up_interruptible (&tty->read_wait); in n_hdlc_release()
254 wake_up_interruptible (&tty->write_wait); in n_hdlc_release()
256 if (tty->disc_data == n_hdlc) in n_hdlc_release()
257 tty->disc_data = NULL; /* Break the tty->n_hdlc link */ in n_hdlc_release()
261 buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list); in n_hdlc_release()
268 buf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list); in n_hdlc_release()
275 buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); in n_hdlc_release()
282 buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list); in n_hdlc_release()
288 kfree(n_hdlc->tbuf); in n_hdlc_release()
294 * n_hdlc_tty_close - line discipline close
295 * @tty - pointer to tty info structure
308 if (n_hdlc->magic != HDLC_MAGIC) { in n_hdlc_tty_close()
313 clear_bit(TTY_NO_WRITE_SPLIT,&tty->flags); in n_hdlc_tty_close()
315 tty->disc_data = NULL; in n_hdlc_tty_close()
316 if (tty == n_hdlc->backup_tty) in n_hdlc_tty_close()
317 n_hdlc->backup_tty = NULL; in n_hdlc_tty_close()
318 if (tty != n_hdlc->tty) in n_hdlc_tty_close()
320 if (n_hdlc->backup_tty) { in n_hdlc_tty_close()
321 n_hdlc->tty = n_hdlc->backup_tty; in n_hdlc_tty_close()
333 * n_hdlc_tty_open - called when line discipline changed to n_hdlc
334 * @tty - pointer to tty info structure
345 tty->name); in n_hdlc_tty_open()
350 return -EEXIST; in n_hdlc_tty_open()
356 return -ENFILE; in n_hdlc_tty_open()
359 tty->disc_data = n_hdlc; in n_hdlc_tty_open()
360 n_hdlc->tty = tty; in n_hdlc_tty_open()
361 tty->receive_room = 65536; in n_hdlc_tty_open()
365 set_bit(TTY_NO_WRITE_SPLIT,&tty->flags); in n_hdlc_tty_open()
379 * n_hdlc_send_frames - send frames on pending send buffer list
380 * @n_hdlc - pointer to ldisc instance data
381 * @tty - pointer to tty instance data
383 * Send frames on pending send buffer list until the driver does not accept a
384 * frame (busy) this function is called after adding a frame to the send buffer
397 spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags); in n_hdlc_send_frames()
398 if (n_hdlc->tbusy) { in n_hdlc_send_frames()
399 n_hdlc->woke_up = 1; in n_hdlc_send_frames()
400 spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); in n_hdlc_send_frames()
403 n_hdlc->tbusy = 1; in n_hdlc_send_frames()
404 n_hdlc->woke_up = 0; in n_hdlc_send_frames()
405 spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); in n_hdlc_send_frames()
407 /* get current transmit buffer or get new transmit */ in n_hdlc_send_frames()
408 /* buffer from list of pending transmit buffers */ in n_hdlc_send_frames()
410 tbuf = n_hdlc->tbuf; in n_hdlc_send_frames()
412 tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list); in n_hdlc_send_frames()
416 printk("%s(%d)sending frame %p, count=%d\n", in n_hdlc_send_frames()
417 __FILE__,__LINE__,tbuf,tbuf->count); in n_hdlc_send_frames()
420 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); in n_hdlc_send_frames()
421 actual = tty->ops->write(tty, tbuf->buf, tbuf->count); in n_hdlc_send_frames()
424 if (actual == -ERESTARTSYS) { in n_hdlc_send_frames()
425 n_hdlc->tbuf = tbuf; in n_hdlc_send_frames()
428 /* if transmit error, throw frame away by */ in n_hdlc_send_frames()
431 actual = tbuf->count; in n_hdlc_send_frames()
433 if (actual == tbuf->count) { in n_hdlc_send_frames()
435 printk("%s(%d)frame %p completed\n", in n_hdlc_send_frames()
438 /* free current transmit buffer */ in n_hdlc_send_frames()
439 n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf); in n_hdlc_send_frames()
441 /* this tx buffer is done */ in n_hdlc_send_frames()
442 n_hdlc->tbuf = NULL; in n_hdlc_send_frames()
445 wake_up_interruptible(&tty->write_wait); in n_hdlc_send_frames()
447 /* get next pending transmit buffer */ in n_hdlc_send_frames()
448 tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list); in n_hdlc_send_frames()
451 printk("%s(%d)frame %p pending\n", in n_hdlc_send_frames()
454 /* buffer not accepted by driver */ in n_hdlc_send_frames()
455 /* set this buffer as pending buffer */ in n_hdlc_send_frames()
456 n_hdlc->tbuf = tbuf; in n_hdlc_send_frames()
462 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); in n_hdlc_send_frames()
464 /* Clear the re-entry flag */ in n_hdlc_send_frames()
465 spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags); in n_hdlc_send_frames()
466 n_hdlc->tbusy = 0; in n_hdlc_send_frames()
467 spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); in n_hdlc_send_frames()
469 if (n_hdlc->woke_up) in n_hdlc_send_frames()
478 * n_hdlc_tty_wakeup - Callback for transmit wakeup
479 * @tty - pointer to associated tty instance data
493 if (tty != n_hdlc->tty) { in n_hdlc_tty_wakeup()
494 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); in n_hdlc_tty_wakeup()
503 * n_hdlc_tty_receive - Called by tty driver when receive data is available
504 * @tty - pointer to tty instance data
505 * @data - pointer to received data
506 * @flags - pointer to flags for data
507 * @count - count of received data in bytes
510 * interpreted as one HDLC frame.
523 if (!n_hdlc || tty != n_hdlc->tty) in n_hdlc_tty_receive()
527 if (n_hdlc->magic != HDLC_MAGIC) { in n_hdlc_tty_receive()
540 /* get a free HDLC buffer */ in n_hdlc_tty_receive()
541 buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list); in n_hdlc_tty_receive()
543 /* no buffers in free list, attempt to allocate another rx buffer */ in n_hdlc_tty_receive()
545 if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT) in n_hdlc_tty_receive()
556 /* copy received data to HDLC buffer */ in n_hdlc_tty_receive()
557 memcpy(buf->buf,data,count); in n_hdlc_tty_receive()
558 buf->count=count; in n_hdlc_tty_receive()
560 /* add HDLC buffer to list of received frames */ in n_hdlc_tty_receive()
561 n_hdlc_buf_put(&n_hdlc->rx_buf_list, buf); in n_hdlc_tty_receive()
564 wake_up_interruptible (&tty->read_wait); in n_hdlc_tty_receive()
565 if (n_hdlc->tty->fasync != NULL) in n_hdlc_tty_receive()
566 kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN); in n_hdlc_tty_receive()
571 * n_hdlc_tty_read - Called to retrieve one frame of data (if available)
572 * @tty - pointer to tty instance data
573 * @file - pointer to open file object
574 * @buf - pointer to returned data buffer
575 * @nr - size of returned data buffer
592 return -EIO; in n_hdlc_tty_read()
594 /* verify user access to buffer */ in n_hdlc_tty_read()
597 "buffer\n", __FILE__, __LINE__); in n_hdlc_tty_read()
598 return -EFAULT; in n_hdlc_tty_read()
601 add_wait_queue(&tty->read_wait, &wait); in n_hdlc_tty_read()
604 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { in n_hdlc_tty_read()
605 ret = -EIO; in n_hdlc_tty_read()
613 rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); in n_hdlc_tty_read()
615 if (rbuf->count > nr) { in n_hdlc_tty_read()
616 /* too large for caller's buffer */ in n_hdlc_tty_read()
617 ret = -EOVERFLOW; in n_hdlc_tty_read()
619 if (copy_to_user(buf, rbuf->buf, rbuf->count)) in n_hdlc_tty_read()
620 ret = -EFAULT; in n_hdlc_tty_read()
622 ret = rbuf->count; in n_hdlc_tty_read()
625 if (n_hdlc->rx_free_buf_list.count > in n_hdlc_tty_read()
629 n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, rbuf); in n_hdlc_tty_read()
634 if (file->f_flags & O_NONBLOCK) { in n_hdlc_tty_read()
635 ret = -EAGAIN; in n_hdlc_tty_read()
642 ret = -EINTR; in n_hdlc_tty_read()
647 remove_wait_queue(&tty->read_wait, &wait); in n_hdlc_tty_read()
655 * n_hdlc_tty_write - write a single frame of data to device
656 * @tty - pointer to associated tty device instance data
657 * @file - pointer to file object data
658 * @data - pointer to transmit data (one frame)
659 * @count - size of transmit frame in bytes
677 return -EIO; in n_hdlc_tty_write()
679 if (n_hdlc->magic != HDLC_MAGIC) in n_hdlc_tty_write()
680 return -EIO; in n_hdlc_tty_write()
682 /* verify frame size */ in n_hdlc_tty_write()
692 add_wait_queue(&tty->write_wait, &wait); in n_hdlc_tty_write()
697 tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list); in n_hdlc_tty_write()
701 if (file->f_flags & O_NONBLOCK) { in n_hdlc_tty_write()
702 error = -EAGAIN; in n_hdlc_tty_write()
708 if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || in n_hdlc_tty_write()
709 tty != n_hdlc->tty) { in n_hdlc_tty_write()
711 error = -EIO; in n_hdlc_tty_write()
716 error = -EINTR; in n_hdlc_tty_write()
722 remove_wait_queue(&tty->write_wait, &wait); in n_hdlc_tty_write()
725 /* Retrieve the user's buffer */ in n_hdlc_tty_write()
726 memcpy(tbuf->buf, data, count); in n_hdlc_tty_write()
729 tbuf->count = error = count; in n_hdlc_tty_write()
730 n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); in n_hdlc_tty_write()
739 * n_hdlc_tty_ioctl - process IOCTL system call for the tty device.
740 * @tty - pointer to tty instance data
741 * @file - pointer to open file object for device
742 * @cmd - IOCTL command code
743 * @arg - argument for IOCTL call (cmd dependent)
760 if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC) in n_hdlc_tty_ioctl()
761 return -EBADF; in n_hdlc_tty_ioctl()
766 /* in next available frame (if any) */ in n_hdlc_tty_ioctl()
767 spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags); in n_hdlc_tty_ioctl()
768 if (n_hdlc->rx_buf_list.head) in n_hdlc_tty_ioctl()
769 count = n_hdlc->rx_buf_list.head->count; in n_hdlc_tty_ioctl()
772 spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags); in n_hdlc_tty_ioctl()
779 /* add size of next output frame in queue */ in n_hdlc_tty_ioctl()
780 spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags); in n_hdlc_tty_ioctl()
781 if (n_hdlc->tx_buf_list.head) in n_hdlc_tty_ioctl()
782 count += n_hdlc->tx_buf_list.head->count; in n_hdlc_tty_ioctl()
783 spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags); in n_hdlc_tty_ioctl()
804 * n_hdlc_tty_poll - TTY callback for poll system call
805 * @tty - pointer to tty instance data
806 * @filp - pointer to open file object for device
807 * @poll_table - wait queue for operations
822 if (n_hdlc && n_hdlc->magic == HDLC_MAGIC && tty == n_hdlc->tty) { in n_hdlc_tty_poll()
826 poll_wait(filp, &tty->read_wait, wait); in n_hdlc_tty_poll()
827 poll_wait(filp, &tty->write_wait, wait); in n_hdlc_tty_poll()
830 if (n_hdlc->rx_buf_list.head) in n_hdlc_tty_poll()
832 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) in n_hdlc_tty_poll()
837 n_hdlc->tx_free_buf_list.head) in n_hdlc_tty_poll()
844 * n_hdlc_alloc - allocate an n_hdlc instance data structure
859 n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list); in n_hdlc_alloc()
860 n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list); in n_hdlc_alloc()
861 n_hdlc_buf_list_init(&n_hdlc->rx_buf_list); in n_hdlc_alloc()
862 n_hdlc_buf_list_init(&n_hdlc->tx_buf_list); in n_hdlc_alloc()
864 /* allocate free rx buffer list */ in n_hdlc_alloc()
868 n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf); in n_hdlc_alloc()
870 printk("%s(%d)n_hdlc_alloc(), kalloc() failed for rx buffer %d\n",__FILE__,__LINE__, i); in n_hdlc_alloc()
873 /* allocate free tx buffer list */ in n_hdlc_alloc()
877 n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf); in n_hdlc_alloc()
879 printk("%s(%d)n_hdlc_alloc(), kalloc() failed for tx buffer %d\n",__FILE__,__LINE__, i); in n_hdlc_alloc()
883 n_hdlc->magic = HDLC_MAGIC; in n_hdlc_alloc()
884 n_hdlc->flags = 0; in n_hdlc_alloc()
891 * n_hdlc_buf_list_init - initialize specified HDLC buffer list
892 * @list - pointer to buffer list
897 spin_lock_init(&list->spinlock); in n_hdlc_buf_list_init()
901 * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
902 * @list - pointer to buffer list
903 * @buf - pointer to buffer
909 spin_lock_irqsave(&list->spinlock,flags); in n_hdlc_buf_put()
911 buf->link=NULL; in n_hdlc_buf_put()
912 if (list->tail) in n_hdlc_buf_put()
913 list->tail->link = buf; in n_hdlc_buf_put()
915 list->head = buf; in n_hdlc_buf_put()
916 list->tail = buf; in n_hdlc_buf_put()
917 (list->count)++; in n_hdlc_buf_put()
919 spin_unlock_irqrestore(&list->spinlock,flags); in n_hdlc_buf_put()
924 * n_hdlc_buf_get - remove and return an HDLC buffer from list
925 * @list - pointer to HDLC buffer list
927 * Remove and return an HDLC buffer from the head of the specified HDLC buffer
929 * Returns a pointer to HDLC buffer if available, otherwise %NULL.
935 spin_lock_irqsave(&list->spinlock,flags); in n_hdlc_buf_get()
937 buf = list->head; in n_hdlc_buf_get()
939 list->head = buf->link; in n_hdlc_buf_get()
940 (list->count)--; in n_hdlc_buf_get()
942 if (!list->head) in n_hdlc_buf_get()
943 list->tail = NULL; in n_hdlc_buf_get()
945 spin_unlock_irqrestore(&list->spinlock,flags); in n_hdlc_buf_get()