linux/drivers/staging/dgrp/dgrp_ports_ops.c
<<
>>
Prefs
   1/*
   2 *
   3 * Copyright 1999-2000 Digi International (www.digi.com)
   4 *     James Puzzo <jamesp at digi dot com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2, or (at your option)
   9 * any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
  13 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  14 * PURPOSE.  See the GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 *
  20 */
  21
  22/*
  23 *
  24 *  Filename:
  25 *
  26 *     dgrp_ports_ops.c
  27 *
  28 *  Description:
  29 *
  30 *     Handle the file operations required for the /proc/dgrp/ports/...
  31 *     devices.  Basically gathers tty status for the node and returns it.
  32 *
  33 *  Author:
  34 *
  35 *     James A. Puzzo
  36 *
  37 */
  38
  39#include <linux/module.h>
  40#include <linux/proc_fs.h>
  41#include <linux/tty.h>
  42#include <linux/sched.h>
  43#include <linux/seq_file.h>
  44
  45#include "dgrp_common.h"
  46
  47/* File operation declarations */
  48static int dgrp_ports_open(struct inode *, struct file *);
  49
  50const struct file_operations dgrp_ports_ops = {
  51        .owner   = THIS_MODULE,
  52        .open    = dgrp_ports_open,
  53        .read    = seq_read,
  54        .llseek  = seq_lseek,
  55        .release = seq_release
  56};
  57
  58static void *dgrp_ports_seq_start(struct seq_file *seq, loff_t *pos)
  59{
  60        if (*pos == 0)
  61                seq_puts(seq, "#num tty_open pr_open tot_wait MSTAT  IFLAG  OFLAG  CFLAG  BPS    DIGIFLAGS\n");
  62
  63        return pos;
  64}
  65
  66static void *dgrp_ports_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  67{
  68        struct nd_struct *nd = seq->private;
  69
  70        if (*pos >= nd->nd_chan_count)
  71                return NULL;
  72
  73        *pos += 1;
  74
  75        return pos;
  76}
  77
  78static void dgrp_ports_seq_stop(struct seq_file *seq, void *v)
  79{
  80}
  81
  82static int dgrp_ports_seq_show(struct seq_file *seq, void *v)
  83{
  84        loff_t *pos = v;
  85        struct nd_struct *nd;
  86        struct ch_struct *ch;
  87        struct un_struct *tun, *pun;
  88        unsigned int totcnt;
  89
  90        nd = seq->private;
  91        if (!nd)
  92                return 0;
  93
  94        if (*pos >= nd->nd_chan_count)
  95                return 0;
  96
  97        ch = &nd->nd_chan[*pos];
  98        tun = &ch->ch_tun;
  99        pun = &ch->ch_pun;
 100
 101        /*
 102         * If port is not open and no one is waiting to
 103         * open it, the modem signal values can't be
 104         * trusted, and will be zeroed.
 105         */
 106        totcnt = tun->un_open_count +
 107                pun->un_open_count +
 108                ch->ch_wait_count[0] +
 109                ch->ch_wait_count[1] +
 110                ch->ch_wait_count[2];
 111
 112        seq_printf(seq, "%02d      %02d      %02d      %02d     0x%04X 0x%04X 0x%04X 0x%04X %-6d 0x%04X\n",
 113                   (int) *pos,
 114                   tun->un_open_count,
 115                   pun->un_open_count,
 116                   ch->ch_wait_count[0] +
 117                   ch->ch_wait_count[1] +
 118                   ch->ch_wait_count[2],
 119                   (totcnt ? ch->ch_s_mlast : 0),
 120                   ch->ch_s_iflag,
 121                   ch->ch_s_oflag,
 122                   ch->ch_s_cflag,
 123                   (ch->ch_s_brate ? (1843200 / ch->ch_s_brate) : 0),
 124                   ch->ch_digi.digi_flags);
 125
 126        return 0;
 127}
 128
 129static const struct seq_operations ports_seq_ops = {
 130        .start = dgrp_ports_seq_start,
 131        .next  = dgrp_ports_seq_next,
 132        .stop  = dgrp_ports_seq_stop,
 133        .show  = dgrp_ports_seq_show,
 134};
 135
 136/**
 137 * dgrp_ports_open -- open the /proc/dgrp/ports/... device
 138 * @inode: struct inode *
 139 * @file: struct file *
 140 *
 141 * Open function to open the /proc/dgrp/ports device for a PortServer.
 142 * This is the open function for struct file_operations
 143 */
 144static int dgrp_ports_open(struct inode *inode, struct file *file)
 145{
 146        struct seq_file *seq;
 147        int rtn;
 148
 149        rtn = seq_open(file, &ports_seq_ops);
 150        if (!rtn) {
 151                seq = file->private_data;
 152                seq->private = PDE_DATA(inode);
 153        }
 154
 155        return rtn;
 156}
 157