Lines Matching refs:chan
162 struct channel_data *chan; member
273 static void cosa_enable_rx(struct channel_data *chan);
274 static void cosa_disable_rx(struct channel_data *chan);
277 static int cosa_dma_able(struct channel_data *chan, char *buf, int data);
418 unregister_hdlc_device(cosa->chan[i].netdev); in cosa_exit()
419 free_netdev(cosa->chan[i].netdev); in cosa_exit()
422 kfree(cosa->chan); in cosa_exit()
562 cosa->chan = kcalloc(cosa->nchannels, sizeof(struct channel_data), GFP_KERNEL); in cosa_probe()
563 if (!cosa->chan) { in cosa_probe()
569 struct channel_data *chan = &cosa->chan[i]; in cosa_probe() local
571 chan->cosa = cosa; in cosa_probe()
572 chan->num = i; in cosa_probe()
573 sprintf(chan->name, "cosa%dc%d", chan->cosa->num, i); in cosa_probe()
576 mutex_init(&chan->rlock); in cosa_probe()
577 sema_init(&chan->wsem, 1); in cosa_probe()
580 if (!(chan->netdev = alloc_hdlcdev(chan))) { in cosa_probe()
581 pr_warn("%s: alloc_hdlcdev failed\n", chan->name); in cosa_probe()
585 dev_to_hdlc(chan->netdev)->attach = cosa_net_attach; in cosa_probe()
586 dev_to_hdlc(chan->netdev)->xmit = cosa_net_tx; in cosa_probe()
587 chan->netdev->netdev_ops = &cosa_ops; in cosa_probe()
588 chan->netdev->watchdog_timeo = TX_TIMEOUT; in cosa_probe()
589 chan->netdev->base_addr = chan->cosa->datareg; in cosa_probe()
590 chan->netdev->irq = chan->cosa->irq; in cosa_probe()
591 chan->netdev->dma = chan->cosa->dma; in cosa_probe()
592 err = register_hdlc_device(chan->netdev); in cosa_probe()
594 netdev_warn(chan->netdev, in cosa_probe()
596 free_netdev(chan->netdev); in cosa_probe()
609 unregister_hdlc_device(cosa->chan[i].netdev); in cosa_probe()
610 free_netdev(cosa->chan[i].netdev); in cosa_probe()
612 kfree(cosa->chan); in cosa_probe()
638 struct channel_data *chan = dev_to_chan(dev); in cosa_net_open() local
642 if (!(chan->cosa->firmware_status & COSA_FW_START)) { in cosa_net_open()
644 chan->cosa->name, chan->cosa->firmware_status); in cosa_net_open()
647 spin_lock_irqsave(&chan->cosa->lock, flags); in cosa_net_open()
648 if (chan->usage != 0) { in cosa_net_open()
650 chan->name, chan->usage); in cosa_net_open()
651 spin_unlock_irqrestore(&chan->cosa->lock, flags); in cosa_net_open()
654 chan->setup_rx = cosa_net_setup_rx; in cosa_net_open()
655 chan->tx_done = cosa_net_tx_done; in cosa_net_open()
656 chan->rx_done = cosa_net_rx_done; in cosa_net_open()
657 chan->usage = -1; in cosa_net_open()
658 chan->cosa->usage++; in cosa_net_open()
659 spin_unlock_irqrestore(&chan->cosa->lock, flags); in cosa_net_open()
663 spin_lock_irqsave(&chan->cosa->lock, flags); in cosa_net_open()
664 chan->usage = 0; in cosa_net_open()
665 chan->cosa->usage--; in cosa_net_open()
666 spin_unlock_irqrestore(&chan->cosa->lock, flags); in cosa_net_open()
671 cosa_enable_rx(chan); in cosa_net_open()
678 struct channel_data *chan = dev_to_chan(dev); in cosa_net_tx() local
682 chan->tx_skb = skb; in cosa_net_tx()
683 cosa_start_tx(chan, skb->data, skb->len); in cosa_net_tx()
689 struct channel_data *chan = dev_to_chan(dev); in cosa_net_timeout() local
691 if (test_bit(RXBIT, &chan->cosa->rxtx)) { in cosa_net_timeout()
692 chan->netdev->stats.rx_errors++; in cosa_net_timeout()
693 chan->netdev->stats.rx_missed_errors++; in cosa_net_timeout()
695 chan->netdev->stats.tx_errors++; in cosa_net_timeout()
696 chan->netdev->stats.tx_aborted_errors++; in cosa_net_timeout()
698 cosa_kick(chan->cosa); in cosa_net_timeout()
699 if (chan->tx_skb) { in cosa_net_timeout()
700 dev_kfree_skb(chan->tx_skb); in cosa_net_timeout()
701 chan->tx_skb = NULL; in cosa_net_timeout()
708 struct channel_data *chan = dev_to_chan(dev); in cosa_net_close() local
713 cosa_disable_rx(chan); in cosa_net_close()
714 spin_lock_irqsave(&chan->cosa->lock, flags); in cosa_net_close()
715 if (chan->rx_skb) { in cosa_net_close()
716 kfree_skb(chan->rx_skb); in cosa_net_close()
717 chan->rx_skb = NULL; in cosa_net_close()
719 if (chan->tx_skb) { in cosa_net_close()
720 kfree_skb(chan->tx_skb); in cosa_net_close()
721 chan->tx_skb = NULL; in cosa_net_close()
723 chan->usage = 0; in cosa_net_close()
724 chan->cosa->usage--; in cosa_net_close()
725 spin_unlock_irqrestore(&chan->cosa->lock, flags); in cosa_net_close()
729 static char *cosa_net_setup_rx(struct channel_data *chan, int size) in cosa_net_setup_rx() argument
735 kfree_skb(chan->rx_skb); in cosa_net_setup_rx()
736 chan->rx_skb = dev_alloc_skb(size); in cosa_net_setup_rx()
737 if (chan->rx_skb == NULL) { in cosa_net_setup_rx()
738 pr_notice("%s: Memory squeeze, dropping packet\n", chan->name); in cosa_net_setup_rx()
739 chan->netdev->stats.rx_dropped++; in cosa_net_setup_rx()
742 chan->netdev->trans_start = jiffies; in cosa_net_setup_rx()
743 return skb_put(chan->rx_skb, size); in cosa_net_setup_rx()
746 static int cosa_net_rx_done(struct channel_data *chan) in cosa_net_rx_done() argument
748 if (!chan->rx_skb) { in cosa_net_rx_done()
749 pr_warn("%s: rx_done with empty skb!\n", chan->name); in cosa_net_rx_done()
750 chan->netdev->stats.rx_errors++; in cosa_net_rx_done()
751 chan->netdev->stats.rx_frame_errors++; in cosa_net_rx_done()
754 chan->rx_skb->protocol = hdlc_type_trans(chan->rx_skb, chan->netdev); in cosa_net_rx_done()
755 chan->rx_skb->dev = chan->netdev; in cosa_net_rx_done()
756 skb_reset_mac_header(chan->rx_skb); in cosa_net_rx_done()
757 chan->netdev->stats.rx_packets++; in cosa_net_rx_done()
758 chan->netdev->stats.rx_bytes += chan->cosa->rxsize; in cosa_net_rx_done()
759 netif_rx(chan->rx_skb); in cosa_net_rx_done()
760 chan->rx_skb = NULL; in cosa_net_rx_done()
765 static int cosa_net_tx_done(struct channel_data *chan, int size) in cosa_net_tx_done() argument
767 if (!chan->tx_skb) { in cosa_net_tx_done()
768 pr_warn("%s: tx_done with empty skb!\n", chan->name); in cosa_net_tx_done()
769 chan->netdev->stats.tx_errors++; in cosa_net_tx_done()
770 chan->netdev->stats.tx_aborted_errors++; in cosa_net_tx_done()
773 dev_kfree_skb_irq(chan->tx_skb); in cosa_net_tx_done()
774 chan->tx_skb = NULL; in cosa_net_tx_done()
775 chan->netdev->stats.tx_packets++; in cosa_net_tx_done()
776 chan->netdev->stats.tx_bytes += size; in cosa_net_tx_done()
777 netif_wake_queue(chan->netdev); in cosa_net_tx_done()
788 struct channel_data *chan = file->private_data; in cosa_read() local
789 struct cosa_data *cosa = chan->cosa; in cosa_read()
797 if (mutex_lock_interruptible(&chan->rlock)) in cosa_read()
800 chan->rxdata = kmalloc(COSA_MTU, GFP_DMA|GFP_KERNEL); in cosa_read()
801 if (chan->rxdata == NULL) { in cosa_read()
802 mutex_unlock(&chan->rlock); in cosa_read()
806 chan->rx_status = 0; in cosa_read()
807 cosa_enable_rx(chan); in cosa_read()
809 add_wait_queue(&chan->rxwaitq, &wait); in cosa_read()
810 while (!chan->rx_status) { in cosa_read()
815 if (signal_pending(current) && chan->rx_status == 0) { in cosa_read()
816 chan->rx_status = 1; in cosa_read()
817 remove_wait_queue(&chan->rxwaitq, &wait); in cosa_read()
820 mutex_unlock(&chan->rlock); in cosa_read()
824 remove_wait_queue(&chan->rxwaitq, &wait); in cosa_read()
826 kbuf = chan->rxdata; in cosa_read()
827 count = chan->rxsize; in cosa_read()
829 mutex_unlock(&chan->rlock); in cosa_read()
839 static char *chrdev_setup_rx(struct channel_data *chan, int size) in chrdev_setup_rx() argument
842 chan->rxsize = size; in chrdev_setup_rx()
843 return chan->rxdata; in chrdev_setup_rx()
846 static int chrdev_rx_done(struct channel_data *chan) in chrdev_rx_done() argument
848 if (chan->rx_status) { /* Reader has died */ in chrdev_rx_done()
849 kfree(chan->rxdata); in chrdev_rx_done()
850 up(&chan->wsem); in chrdev_rx_done()
852 chan->rx_status = 1; in chrdev_rx_done()
853 wake_up_interruptible(&chan->rxwaitq); in chrdev_rx_done()
862 struct channel_data *chan = file->private_data; in cosa_write() local
863 struct cosa_data *cosa = chan->cosa; in cosa_write()
872 if (down_interruptible(&chan->wsem)) in cosa_write()
881 up(&chan->wsem); in cosa_write()
885 up(&chan->wsem); in cosa_write()
889 chan->tx_status=0; in cosa_write()
890 cosa_start_tx(chan, kbuf, count); in cosa_write()
893 add_wait_queue(&chan->txwaitq, &wait); in cosa_write()
894 while (!chan->tx_status) { in cosa_write()
899 if (signal_pending(current) && chan->tx_status == 0) { in cosa_write()
900 chan->tx_status = 1; in cosa_write()
901 remove_wait_queue(&chan->txwaitq, &wait); in cosa_write()
903 chan->tx_status = 1; in cosa_write()
905 up(&chan->wsem); in cosa_write()
909 remove_wait_queue(&chan->txwaitq, &wait); in cosa_write()
911 up(&chan->wsem); in cosa_write()
917 static int chrdev_tx_done(struct channel_data *chan, int size) in chrdev_tx_done() argument
919 if (chan->tx_status) { /* Writer was interrupted */ in chrdev_tx_done()
920 kfree(chan->txbuf); in chrdev_tx_done()
921 up(&chan->wsem); in chrdev_tx_done()
923 chan->tx_status = 1; in chrdev_tx_done()
924 wake_up_interruptible(&chan->txwaitq); in chrdev_tx_done()
937 struct channel_data *chan; in cosa_open() local
955 chan = cosa->chan + n; in cosa_open()
957 file->private_data = chan; in cosa_open()
961 if (chan->usage < 0) { /* in netdev mode */ in cosa_open()
967 chan->usage++; in cosa_open()
969 chan->tx_done = chrdev_tx_done; in cosa_open()
970 chan->setup_rx = chrdev_setup_rx; in cosa_open()
971 chan->rx_done = chrdev_rx_done; in cosa_open()
1191 struct channel_data *chan = dev_to_chan(dev); in cosa_net_ioctl() local
1192 rv = cosa_ioctl_common(chan->cosa, chan, cmd, in cosa_net_ioctl()
1220 static void cosa_enable_rx(struct channel_data *chan) in cosa_enable_rx() argument
1222 struct cosa_data *cosa = chan->cosa; in cosa_enable_rx()
1224 if (!test_and_set_bit(chan->num, &cosa->rxbitmap)) in cosa_enable_rx()
1228 static void cosa_disable_rx(struct channel_data *chan) in cosa_disable_rx() argument
1230 struct cosa_data *cosa = chan->cosa; in cosa_disable_rx()
1232 if (test_and_clear_bit(chan->num, &cosa->rxbitmap)) in cosa_disable_rx()
1242 static int cosa_start_tx(struct channel_data *chan, char *buf, int len) in cosa_start_tx() argument
1244 struct cosa_data *cosa = chan->cosa; in cosa_start_tx()
1250 chan->cosa->num, chan->num, len); in cosa_start_tx()
1256 chan->txbuf = buf; in cosa_start_tx()
1257 chan->txsize = len; in cosa_start_tx()
1259 chan->txsize = COSA_MTU; in cosa_start_tx()
1263 set_bit(chan->num, &cosa->txbitmap); in cosa_start_tx()
1373 static int cosa_dma_able(struct channel_data *chan, char *buf, int len) in cosa_dma_able() argument
1382 chan->name); in cosa_dma_able()
1713 cosa->txsize = cosa->chan[cosa->txchan].txsize; in tx_interrupt()
1714 if (cosa_dma_able(cosa->chan+cosa->txchan, in tx_interrupt()
1715 cosa->chan[cosa->txchan].txbuf, cosa->txsize)) { in tx_interrupt()
1716 cosa->txbuf = cosa->chan[cosa->txchan].txbuf; in tx_interrupt()
1718 memcpy(cosa->bouncebuf, cosa->chan[cosa->txchan].txbuf, in tx_interrupt()
1855 cosa->rxchan = cosa->chan + ((cosa->rxsize & 0xe000) >> 13); in rx_interrupt()
1904 struct channel_data *chan = cosa->chan+cosa->txchan; in eot_interrupt() local
1905 if (chan->tx_done) in eot_interrupt()
1906 if (chan->tx_done(chan, cosa->txsize)) in eot_interrupt()
1907 clear_bit(chan->num, &cosa->txbitmap); in eot_interrupt()