* [ patch 4/7] drivers/serial/jsm: new serial device driver
@ 2005-02-27 23:39 Wen Xiong
2005-02-28 3:21 ` Christoph Hellwig
2005-02-28 6:39 ` Greg KH
0 siblings, 2 replies; 19+ messages in thread
From: Wen Xiong @ 2005-02-27 23:39 UTC (permalink / raw)
To: linux-kernel, linux-serial
[-- Attachment #1: Type: text/plain, Size: 146 bytes --]
This patch is for jsm_proc.c and includes the functions relating to
/proc/jsm entry.
Signed-off-by: Wen Xiong <wendyx@us.ltcfwd.linux.ibm.com>
[-- Attachment #2: patch4.jasmine --]
[-- Type: text/plain, Size: 23737 bytes --]
diff -Nuar linux-2.6.9.orig/drivers/serial/jsm/jsm_proc.c linux-2.6.9.new/drivers/serial/jsm/jsm_proc.c
--- linux-2.6.9.orig/drivers/serial/jsm/jsm_proc.c 1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.9.new/drivers/serial/jsm/jsm_proc.c 2005-02-27 17:13:14.339983544 -0600
@@ -0,0 +1,951 @@
+/*
+ * Copyright 2003 Digi International (www.digi.com)
+ * Scott H Kilau <Scott_Kilau at digi dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
+ *
+ * This is shared code between Digi's CVS archive and the
+ * Linux Kernel sources.
+ * Changing the source just for reformatting needlessly breaks
+ * our CVS diff history.
+ *
+ * Send any bug fixes/changes to: Eng.Linux at digi dot com.
+ * Thank you.
+ *
+ *
+ * $Id: jsm_proc.c,v 1.38 2004/08/30 21:39:40 scottk Exp $
+ */
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/sched.h> /* For jiffies, task states */
+#include <linux/interrupt.h> /* For tasklet and interrupt structs/defines */
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/serial_reg.h>
+#include <linux/sched.h> /* For in_egroup_p() */
+#include <linux/string.h>
+#include <asm/uaccess.h> /* For copy_from_user/copy_to_user */
+
+#include "jsm_driver.h"
+#include "jsm_mgmt.h"
+
+/* The /proc/jsm directory */
+static struct proc_dir_entry *ProcJSM;
+
+static void *jsm_info_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void *jsm_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void jsm_info_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+static int jsm_info_seq_show(struct seq_file *seq, void *v)
+{
+
+ seq_printf(seq, "Driver:\t\t%s\n", "jsm - 1.1-1-INKERNEL");
+ seq_printf(seq, "\n");
+ seq_printf(seq, "Debug:\t\t0x%x\n", jsm_debug);
+ seq_printf(seq, "Rawreadok:\t0x%x\n", jsm_rawreadok);
+ seq_printf(seq, "Max Boards:\t%d\n", MAXBOARDS);
+ seq_printf(seq, "Total Boards:\t%d\n", jsm_NumBoards);
+ seq_printf(seq, "Poll counter:\t%ld\n", jsm_poll_counter);
+ seq_printf(seq, "State:\t\t%s\n", jsm_driver_state_text[jsm_driver_state]);
+ return 0;
+
+}
+
+static struct seq_operations jsm_info_seq_ops = {
+ .start = jsm_info_seq_start,
+ .next = jsm_info_seq_next,
+ .stop = jsm_info_seq_stop,
+ .show = jsm_info_seq_show,
+};
+
+static int jsm_info_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ struct proc_dir_entry *proc;
+ int res;
+
+ res = seq_open(file, &jsm_info_seq_ops);
+ if (!res) {
+ /* recover the pointer buried in proc_dir_entry data */
+ seq = file->private_data;
+ proc = PDE(inode);
+ seq->private = proc->data;
+ }
+ return res;
+}
+
+
+static void *jsm_mknod_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void *jsm_mknod_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void jsm_mknod_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+static int jsm_mknod_seq_show(struct seq_file *seq, void *v)
+{
+ int i;
+ seq_printf(seq, "#\tCreate the management devices.\n");
+
+ for (i = 0; i < MAXMGMTDEVICES; i++) {
+ char tmp[100];
+ sprintf(tmp, "/dev/jsm/mgmt%d", i);
+ seq_printf(seq, "%s\t%d\t%d\t%d\n",
+ tmp, jsm_Major, i, 1);
+ }
+ return 0;
+}
+
+static struct seq_operations jsm_mknod_seq_ops = {
+ .start = jsm_mknod_seq_start,
+ .next = jsm_mknod_seq_next,
+ .stop = jsm_mknod_seq_stop,
+ .show = jsm_mknod_seq_show,
+};
+
+static int jsm_mknod_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ struct proc_dir_entry *proc;
+ int res;
+
+ res = seq_open(file, &jsm_mknod_seq_ops);
+ if (!res) {
+ /* recover the pointer buried in proc_dir_entry data */
+ seq = file->private_data;
+ proc = PDE(inode);
+ seq->private = proc->data;
+ }
+ return res;
+}
+
+static void *jsm_board_info_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void *jsm_board_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void jsm_board_info_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+static int jsm_board_info_seq_show(struct seq_file *seq, void *v)
+{
+ struct board_t *brd = (struct board_t *) seq->private;
+ char *name;
+
+ DPR_PROC(("jsm_proc_brd_info\n"));
+
+ if (!brd || (brd->magic != JSM_BOARD_MAGIC))
+ return 0;
+
+ name = brd->name;
+
+ seq_printf(seq, "Board Name = %s\n", name);
+ seq_printf(seq, "Board Type = %d\n", brd->type);
+ seq_printf(seq, "Number of Ports = %d\n", brd->nasync);
+
+ /*
+ * report some things about the PCI bus that are important
+ * to some applications
+ */
+ seq_printf(seq, "Vendor ID = 0x%x\n", brd->vendor);
+ seq_printf(seq, "Device ID = 0x%x\n", brd->device);
+ seq_printf(seq, "Subvendor ID = 0x%x\n", brd->subvendor);
+ seq_printf(seq, "Subdevice ID = 0x%x\n", brd->subdevice);
+ seq_printf(seq, "Bus = %d\n", brd->pci_bus);
+ seq_printf(seq, "Slot = %d\n", brd->pci_slot);
+
+ /*
+ * report the physical addresses assigned to us when we got
+ * registered
+ */
+ seq_printf(seq, "Memory Base Address = 0x%lx\n", brd->membase);
+ seq_printf(seq, "Remapped Memory Base Address = 0x%p\n", brd->re_map_membase);
+
+ seq_printf(seq, "Current state of board = %s\n", jsm_state_text[brd->state]);
+ seq_printf(seq, "Interrupt #: %d. Times interrupted: %ld\n",
+ brd->irq, brd->intr_count);
+ seq_printf(seq, "Majors allocated to board = TTY: %d PR: %d\n",
+ brd->SerialDriver.major, brd->PrintDriver.major);
+
+ return 0;
+}
+
+static struct seq_operations jsm_board_info_seq_ops = {
+ .start = jsm_board_info_seq_start,
+ .next = jsm_board_info_seq_next,
+ .stop = jsm_board_info_seq_stop,
+ .show = jsm_board_info_seq_show,
+};
+
+static int jsm_board_info_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ struct proc_dir_entry *proc;
+ int res;
+
+ res = seq_open(file, &jsm_board_info_seq_ops);
+ if (!res) {
+ /* recover the pointer buried in proc_dir_entry data */
+ seq = file->private_data;
+ proc = PDE(inode);
+ seq->private = proc->data;
+ }
+ return res;
+}
+
+
+static void *jsm_board_stats_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void *jsm_board_stats_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void jsm_board_stats_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+static int jsm_board_stats_seq_show(struct seq_file *seq, void *v)
+{
+ struct board_t *brd = (struct board_t *) seq->private;
+ int i = 0;
+
+
+ if (!brd || (brd->magic != JSM_BOARD_MAGIC))
+ return 0;
+
+ /* Prepare the Header Labels */
+ seq_printf(seq, "%2s %10s %23s %10s %9s\n",
+ "Ch", "Chars Rx", " Rx Par--Brk--Frm--Ovr",
+ "Chars Tx", "XON XOFF");
+
+ for (i = 0; i < brd->nasync; i++) {
+
+ struct channel_t *ch = brd->channels[i];
+
+ seq_printf(seq, "%2d ", i);
+ seq_printf(seq, "%10ld ", ch->ch_rxcount);
+ seq_printf(seq, "%4ld %4ld %4ld %4ld ", ch->ch_err_parity,
+ ch->ch_err_break, ch->ch_err_frame, ch->ch_err_overrun);
+ seq_printf(seq, "%10ld ", ch->ch_txcount);
+ seq_printf(seq, "%4ld %4ld ", ch->ch_xon_sends, ch->ch_xoff_sends);
+
+ seq_printf(seq, "\n");
+ }
+
+ return 0;
+}
+
+static struct seq_operations jsm_board_stats_seq_ops = {
+ .start = jsm_board_stats_seq_start,
+ .next = jsm_board_stats_seq_next,
+ .stop = jsm_board_stats_seq_stop,
+ .show = jsm_board_stats_seq_show,
+};
+
+static int jsm_board_stats_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ struct proc_dir_entry *proc;
+ int res;
+
+ res = seq_open(file, &jsm_board_stats_seq_ops);
+ if (!res) {
+ /* recover the pointer buried in proc_dir_entry data */
+ seq = file->private_data;
+ proc = PDE(inode);
+ seq->private = proc->data;
+ }
+
+ return res;
+}
+
+
+static void *jsm_board_flags_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void *jsm_board_flags_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void jsm_board_flags_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+static int jsm_board_flags_seq_show(struct seq_file *seq, void *v)
+{
+ struct board_t *brd = (struct board_t *) seq->private;
+ int i = 0;
+
+ DPR_PROC(("jsm_proc_brd_info\n"));
+
+ if (!brd || (brd->magic != JSM_BOARD_MAGIC))
+ return 0;
+
+ /* Prepare the Header Labels */
+ seq_printf(seq, "%2s %5s %5s %5s %5s %5s %10s Line Status Flags\n",
+ "Ch", "CFlag", "IFlag", "OFlag", "LFlag", "DFlag", "Baud");
+
+ for (i = 0; i < brd->nasync; i++) {
+
+ struct channel_t *ch = brd->channels[i];
+
+ seq_printf(seq, "%2d ", i);
+ seq_printf(seq, "%5x ", ch->ch_c_cflag);
+ seq_printf(seq, "%5x ", ch->ch_c_iflag);
+ seq_printf(seq, "%5x ", ch->ch_c_oflag);
+ seq_printf(seq, "%5x ", ch->ch_c_lflag);
+ seq_printf(seq, "%10d ", ch->ch_old_baud);
+
+ if (!ch->ch_open_count)
+ seq_printf(seq, " -- -- -- -- -- -- --") ;
+ else {
+ seq_printf(seq, " op %s %s %s %s %s %s",
+ (ch->ch_mostat & UART_MCR_RTS) ? "rs" : "--",
+ (ch->ch_mistat & UART_MSR_CTS) ? "cs" : "--",
+ (ch->ch_mostat & UART_MCR_DTR) ? "tr" : "--",
+ (ch->ch_mistat & UART_MSR_DSR) ? "mr" : "--",
+ (ch->ch_mistat & UART_MSR_DCD) ? "cd" : "--",
+ (ch->ch_mistat & UART_MSR_RI) ? "ri" : "--");
+ }
+
+ seq_printf(seq, "\n");
+ }
+
+ return 0;
+}
+
+static struct seq_operations jsm_board_flags_seq_ops = {
+ .start = jsm_board_flags_seq_start,
+ .next = jsm_board_flags_seq_next,
+ .stop = jsm_board_flags_seq_stop,
+ .show = jsm_board_flags_seq_show,
+};
+
+static int jsm_board_flags_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ struct proc_dir_entry *proc;
+ int res;
+
+ res = seq_open(file, &jsm_board_flags_seq_ops);
+ if (!res) {
+ /* recover the pointer buried in proc_dir_entry data */
+ seq = file->private_data;
+ proc = PDE(inode);
+ seq->private = proc->data;
+ }
+
+ return res;
+}
+
+
+
+static void *jsm_board_mknod_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void *jsm_board_mknod_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void jsm_board_mknod_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+static int jsm_board_mknod_seq_show(struct seq_file *seq, void *v)
+{
+ struct board_t *brd = (struct board_t *) seq->private;
+ char str[MAXTTYNAMELEN];
+
+ DPR_PROC(("jsm_proc_brd_info\n"));
+
+ if (!brd || (brd->magic != JSM_BOARD_MAGIC))
+ return 0;
+
+ /*
+ * For each board, output the device information in
+ * a handy table format...
+ */
+ seq_printf(seq, "# Create the TTY and PR devices\n");
+
+ /* TTY devices */
+ sprintf(str, "ttyn%d%%p", brd->boardnum + 1);
+ seq_printf(seq, "%s\t\t\t%d\t%d\t%d\n", str,
+ brd->jsm_Serial_Major, 0, brd->maxports);
+
+ /* PR devices */
+ sprintf(str, "prn%d%%p", brd->boardnum + 1);
+ seq_printf(seq, "%s\t\t\t%d\t%d\t%d\n", str,
+ brd->jsm_TransparentPrint_Major, 128, brd->maxports);
+
+ return 0;
+}
+
+static struct seq_operations jsm_board_mknod_seq_ops = {
+ .start = jsm_board_mknod_seq_start,
+ .next = jsm_board_mknod_seq_next,
+ .stop = jsm_board_mknod_seq_stop,
+ .show = jsm_board_mknod_seq_show,
+};
+
+static int jsm_board_mknod_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ struct proc_dir_entry *proc;
+ int res;
+
+ res = seq_open(file, &jsm_board_mknod_seq_ops);
+ if (!res) {
+ /* recover the pointer buried in proc_dir_entry data */
+ seq = file->private_data;
+ proc = PDE(inode);
+ seq->private = proc->data;
+ }
+
+ return res;
+}
+
+
+static void *jsm_channel_info_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void *jsm_channel_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void jsm_channel_info_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+static int jsm_channel_info_seq_show(struct seq_file *seq, void *v)
+{
+ struct channel_t *ch = (struct channel_t *) seq->private;
+
+ DPR_PROC(("jsm_proc_info\n"));
+
+ if (!ch || (ch->magic != JSM_CHANNEL_MAGIC))
+ return 0;
+
+ seq_printf(seq, "Port number:\t\t%d\n", ch->ch_portnum);
+ seq_printf(seq, "\n");
+
+ /* Prepare the Header Labels */
+ seq_printf(seq, "%10s %23s %10s %9s\n",
+ "Chars Rx", " Rx Par--Brk--Frm--Ovr",
+ "Chars Tx", "XON XOFF");
+ seq_printf(seq, "%10ld ", ch->ch_rxcount);
+ seq_printf(seq, "%4ld %4ld %4ld %4ld ", ch->ch_err_parity,
+ ch->ch_err_break, ch->ch_err_frame, ch->ch_err_overrun);
+ seq_printf(seq, "%10ld ", ch->ch_txcount);
+ seq_printf(seq, "%4ld %4ld ", ch->ch_xon_sends, ch->ch_xoff_sends);
+ seq_printf(seq, "\n\n");
+
+ /* Prepare the Header Labels */
+ seq_printf(seq, "%5s %5s %5s %5s %5s %10s Line Status Flags\n",
+ "CFlag", "IFlag", "OFlag", "LFlag", "DFlag", "Baud");
+
+ seq_printf(seq, "%5x ", ch->ch_c_cflag);
+ seq_printf(seq, "%5x ", ch->ch_c_iflag);
+ seq_printf(seq, "%5x ", ch->ch_c_oflag);
+ seq_printf(seq, "%5x ", ch->ch_c_lflag);
+ seq_printf(seq, "%10d ", ch->ch_old_baud);
+ if (!ch->ch_open_count)
+ seq_printf(seq, " -- -- -- -- -- -- --") ;
+ else {
+ seq_printf(seq, " op %s %s %s %s %s %s",
+ (ch->ch_mostat & UART_MCR_RTS) ? "rs" : "--",
+ (ch->ch_mistat & UART_MSR_CTS) ? "cs" : "--",
+ (ch->ch_mostat & UART_MCR_DTR) ? "tr" : "--",
+ (ch->ch_mistat & UART_MSR_DSR) ? "mr" : "--",
+ (ch->ch_mistat & UART_MSR_DCD) ? "cd" : "--",
+ (ch->ch_mistat & UART_MSR_RI) ? "ri" : "--");
+ }
+ seq_printf(seq, "\n\n");
+
+ return 0;
+}
+
+static struct seq_operations jsm_channel_info_seq_ops = {
+ .start = jsm_channel_info_seq_start,
+ .next = jsm_channel_info_seq_next,
+ .stop = jsm_channel_info_seq_stop,
+ .show = jsm_channel_info_seq_show,
+};
+
+static int jsm_channel_info_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ struct proc_dir_entry *proc;
+ int res;
+
+ res = seq_open(file, &jsm_channel_info_seq_ops);
+ if (!res) {
+ /* recover the pointer buried in proc_dir_entry data */
+ seq = file->private_data;
+ proc = PDE(inode);
+ seq->private = proc->data;
+ }
+
+ return res;
+}
+
+
+static void *jsm_channel_sniff_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ ulong lock_flags;
+ struct channel_t *ch = (struct channel_t *) seq->private;
+
+ if (!ch || (ch->magic != JSM_CHANNEL_MAGIC))
+ return NULL;
+
+ ch->ch_sniff_buf = kmalloc(SNIFF_MAX, GFP_KERNEL);
+ memset(ch->ch_sniff_buf, 0, SNIFF_MAX);
+
+ spin_lock_irqsave(&ch->ch_lock, lock_flags);
+ ch->ch_sniff_flags |= SNIFF_OPEN;
+ spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
+
+ return (void *)1;
+}
+
+static void *jsm_channel_sniff_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ if (*pos > 0)
+ return NULL;
+ else
+ return (void *)1;
+}
+
+static void jsm_channel_sniff_seq_stop(struct seq_file *seq, void *v)
+{
+ ulong lock_flags;
+ struct channel_t *ch = (struct channel_t *) seq->private;
+
+ spin_lock_irqsave(&ch->ch_lock, lock_flags);
+ ch->ch_sniff_flags &= ~(SNIFF_OPEN);
+ kfree(ch->ch_sniff_buf);
+ spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
+}
+
+
+static int jsm_channel_sniff_seq_show(struct seq_file *seq, void *v)
+{
+
+ struct channel_t *ch = (struct channel_t *) seq->private;
+ int n;
+ int r;
+ int offset = 0;
+ int res = 0;
+ ssize_t rtn = 0;
+ ulong lock_flags;
+ int count;
+ if (!ch || (ch->magic != JSM_CHANNEL_MAGIC)) {
+ rtn = -ENXIO;
+ goto done;
+ }
+
+ /*
+ * Wait for some data to appear in the buffer.
+ */
+ spin_lock_irqsave(&ch->ch_lock, lock_flags);
+
+ for (;;) {
+ n = (ch->ch_sniff_in - ch->ch_sniff_out) & SNIFF_MASK;
+
+ if (n != 0)
+ break;
+
+ ch->ch_sniff_flags |= SNIFF_WAIT_DATA;
+
+ spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
+
+ /*
+ * Go to sleep waiting until the condition becomes true.
+ */
+ rtn = wait_event_interruptible(ch->ch_sniff_wait,
+ ((ch->ch_sniff_flags & SNIFF_WAIT_DATA) == 0));
+
+ if (rtn)
+ goto done;
+
+ spin_lock_irqsave(&ch->ch_lock, lock_flags);
+ }
+
+ /*
+ * Read whatever is there.
+ */
+
+ res = n;
+
+ r = SNIFF_MAX - ch->ch_sniff_out;
+
+ if (r <= n) {
+ spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
+ if (rtn) {
+ rtn = -EFAULT;
+ goto done;
+ }
+
+ spin_lock_irqsave(&ch->ch_lock, lock_flags);
+
+ ch->ch_sniff_out = 0;
+ n -= r;
+ offset = r;
+ }
+
+ spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
+ seq_printf(seq, "in =%d out=%d\n",ch->ch_sniff_in,ch->ch_sniff_out);
+ seq_printf(seq, "first=%x\n",ch->ch_sniff_buf[5]);
+ seq_printf(seq, "first=%x\n",ch->ch_sniff_buf[6]);
+ for (count = 0; count < n; count++) {
+ seq_printf(seq, "%x ",ch->ch_sniff_buf[ch->ch_sniff_out++]);
+ }
+ if (rtn) {
+ rtn = -EFAULT;
+ goto done;
+ }
+ spin_lock_irqsave(&ch->ch_lock, lock_flags);
+
+ seq_printf(seq,"\n");
+ seq_printf(seq, "in =%d out=%d\n",ch->ch_sniff_in,ch->ch_sniff_out);
+
+ /*
+ * Wakeup any thread waiting for buffer space.
+ */
+
+ if (ch->ch_sniff_flags & SNIFF_WAIT_SPACE) {
+ ch->ch_sniff_flags &= ~SNIFF_WAIT_SPACE;
+ wake_up_interruptible(&ch->ch_sniff_wait);
+ }
+
+ spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
+
+done:
+ return rtn;
+}
+
+static struct seq_operations jsm_channel_sniff_seq_ops = {
+ .start = jsm_channel_sniff_seq_start,
+ .next = jsm_channel_sniff_seq_next,
+ .stop = jsm_channel_sniff_seq_stop,
+ .show = jsm_channel_sniff_seq_show,
+};
+
+static int jsm_channel_sniff_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ struct proc_dir_entry *proc;
+ int res;
+
+ res = seq_open(file, &jsm_channel_sniff_seq_ops);
+ if (!res) {
+ /* recover the pointer buried in proc_dir_entry data */
+ seq = file->private_data;
+ proc = PDE(inode);
+ seq->private = proc->data;
+ }
+
+ return res;
+}
+
+
+static struct file_operations jsm_info_operations = {
+ .open = jsm_info_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations jsm_mknod_operations = {
+ .open = jsm_mknod_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations jsm_board_info_operations = {
+ .open = jsm_board_info_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations jsm_board_stats_operations = {
+ .open = jsm_board_stats_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations jsm_board_flags_operations = {
+ .open = jsm_board_flags_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations jsm_board_mknod_operations = {
+ .open = jsm_board_mknod_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations jsm_channel_info_operations =
+{
+ .open = jsm_channel_info_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations jsm_channel_sniff_operations =
+{
+ .open = jsm_channel_sniff_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+/*
+ * Register the basic /proc/jsm files that appear whenever
+ * the driver is loaded.
+ */
+void jsm_proc_register_basic_prescan(void)
+{
+ /*
+ *Register /proc/jsm
+ */
+
+ struct proc_dir_entry *entry;
+
+ ProcJSM = proc_mkdir("jsm",&proc_root);
+ if (ProcJSM)
+ ProcJSM->owner = THIS_MODULE;
+ else
+ printk(KERN_WARNING "cann't create /proc/net/jsm\n");
+
+ entry = create_proc_entry("info", S_IRUGO, ProcJSM);
+ if (entry)
+ entry->proc_fops = &jsm_info_operations;
+
+ entry = create_proc_entry("mknod", S_IRUGO, ProcJSM);
+ if (entry)
+ entry->proc_fops = &jsm_mknod_operations;
+}
+
+
+/*
+ * Register the basic /proc/jsm files that appear whenever
+ * the driver is loaded.
+ */
+int jsm_proc_register_basic_postscan(int board_num)
+{
+ int i;
+ char board[10];
+ struct proc_dir_entry *e, *board_e, *channel_e;
+ sprintf(board, "%d", board_num);
+
+ /* Set proc board entry pointer */
+ board_e = jsm_Board[board_num]->proc_entry_pointer = proc_mkdir(board, ProcJSM);
+
+ e = create_proc_entry("info", S_IRUGO, board_e);
+ if (!e)
+ return -ENOMEM;
+ e->proc_fops = &jsm_board_info_operations;
+ e->data = jsm_Board[board_num];
+
+
+ e = create_proc_entry("stats", S_IRUGO, board_e);
+ if (!e)
+ return -ENOMEM;
+ e->proc_fops = &jsm_board_stats_operations;
+ e->data = jsm_Board[board_num];
+
+ e = create_proc_entry("flags", S_IRUGO, board_e);
+ if (!e)
+ return -ENOMEM;
+ e->proc_fops = &jsm_board_flags_operations;
+ e->data = jsm_Board[board_num];
+
+ e = create_proc_entry("mknod", S_IRUGO, board_e);
+ if (!e)
+ return -ENOMEM;
+ e->proc_fops = &jsm_board_mknod_operations;
+ e->data = jsm_Board[board_num];
+
+ /*
+ * Add new entries for each port.
+ */
+ for (i = 0; i < jsm_Board[board_num]->nasync; i++) {
+
+ char channel[10];
+ sprintf(channel, "%d", i);
+
+ channel_e = jsm_Board[board_num]->channels[i]->proc_entry_pointer = proc_mkdir(channel,board_e);
+
+ e = create_proc_entry("info", S_IRUGO, channel_e);
+ if (!e)
+ return -ENOMEM;
+ e->proc_fops = &jsm_channel_info_operations;
+ e->data = jsm_Board[board_num]->channels[i];
+
+ e = create_proc_entry("sniff", S_IRUGO, channel_e);
+ if (!e)
+ return -ENOMEM;
+ e->proc_fops = &jsm_channel_sniff_operations;
+ e->data = jsm_Board[board_num]->channels[i];
+
+ }
+
+ return 0;
+}
+
+
+
+void jsm_proc_unregister_brd(int brd_number)
+{
+ int i = 0, j = 0;
+
+ i = brd_number;
+
+ char board_number[16];
+ sprintf(board_number,"%d",i);
+
+
+ for (j = 0; j < jsm_Board[i]->nasync; j++) {
+
+ char channel_number[16];
+ sprintf(channel_number,"%d",j);
+
+ remove_proc_entry("info",jsm_Board[i]->channels[j]->proc_entry_pointer);
+ remove_proc_entry("sniff",jsm_Board[i]->channels[j]->proc_entry_pointer);
+ remove_proc_entry(channel_number,jsm_Board[i]->proc_entry_pointer);
+
+ }
+
+ remove_proc_entry("info",jsm_Board[i]->proc_entry_pointer);
+ remove_proc_entry("mknod",jsm_Board[i]->proc_entry_pointer);
+ remove_proc_entry("flags",jsm_Board[i]->proc_entry_pointer);
+ remove_proc_entry("stats",jsm_Board[i]->proc_entry_pointer);
+ remove_proc_entry(board_number,ProcJSM);
+
+}
+
+void jsm_proc_unregister_all(void)
+{
+
+ /* Blow away the top proc entry */
+ remove_proc_entry("info",ProcJSM);
+ remove_proc_entry("mknod",ProcJSM);
+ remove_proc_entry("jsm", &proc_root);
+}
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-02-27 23:39 Wen Xiong
@ 2005-02-28 3:21 ` Christoph Hellwig
2005-02-28 6:39 ` Greg KH
1 sibling, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2005-02-28 3:21 UTC (permalink / raw)
To: Wen Xiong; +Cc: linux-kernel, linux-serial
On Sun, Feb 27, 2005 at 06:39:51PM -0500, Wen Xiong wrote:
> This patch is for jsm_proc.c and includes the functions relating to
> /proc/jsm entry.
please don't put in more procfs driver interfaces.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-02-27 23:39 Wen Xiong
2005-02-28 3:21 ` Christoph Hellwig
@ 2005-02-28 6:39 ` Greg KH
2005-03-04 21:08 ` Wen Xiong
1 sibling, 1 reply; 19+ messages in thread
From: Greg KH @ 2005-02-28 6:39 UTC (permalink / raw)
To: Wen Xiong; +Cc: linux-kernel, linux-serial
On Sun, Feb 27, 2005 at 06:39:51PM -0500, Wen Xiong wrote:
> This patch is for jsm_proc.c and includes the functions relating to
> /proc/jsm entry.
No, don't add new /proc stuff. Use sysfs, and if you want to spit out
more data, use debugfs.
What is the need for these files?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-02-28 6:39 ` Greg KH
@ 2005-03-04 21:08 ` Wen Xiong
2005-03-04 22:01 ` Greg KH
0 siblings, 1 reply; 19+ messages in thread
From: Wen Xiong @ 2005-03-04 21:08 UTC (permalink / raw)
To: Greg KH; +Cc: Wen Xiong, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 682 bytes --]
Greg KH wrote:
>On Sun, Feb 27, 2005 at 06:39:51PM -0500, Wen Xiong wrote:
>
>
>>This patch is for jsm_proc.c and includes the functions relating to
>>/proc/jsm entry.
>>
>>
>
>No, don't add new /proc stuff. Use sysfs, and if you want to spit out
>more data, use debugfs.
>
>What is the need for these files?
>
>thanks,
>
>greg k-h
>-
>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/
>
>
>
Changed to use sysfs.
Signed-off-by: Wen Xiong <wendyx@us.ltcfwd.linux.ibm.com>
[-- Attachment #2: patch4.jasmine --]
[-- Type: text/plain, Size: 14983 bytes --]
diff -Nuar linux-2.6.11.org/drivers/serial/jsm/jsm_sysfs.c linux-2.6.11.new/drivers/serial/jsm/jsm_sysfs.c
--- linux-2.6.11.org/drivers/serial/jsm/jsm_sysfs.c 1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.11.new/drivers/serial/jsm/jsm_sysfs.c 2005-03-04 11:24:37.962944848 -0600
@@ -0,0 +1,463 @@
+/************************************************************************
+ * Copyright 2003 Digi International (www.digi.com)
+ *
+ * Copyright (C) 2004 IBM Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 * Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ *
+ * Contact Information:
+ * Scott H Kilau <Scott_Kilau@digi.com>
+ * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com>
+ *
+ ***********************************************************************/
+
+#include "jsm_driver.h"
+
+static struct class_simple *jsm_tty_class;
+
+int get_jsm_board_number(void)
+{
+ struct list_head *tmp;
+ struct jsm_board *cur_board_entry;
+ int adapter_count = 0;
+ u64 lock_flags;
+
+ spin_lock_irqsave(&jsm_board_head_lock, lock_flags);
+ list_for_each(tmp, &jsm_board_head) {
+ cur_board_entry =
+ list_entry(tmp, struct jsm_board,
+ jsm_board_entry);
+ adapter_count++;
+ }
+ spin_unlock_irqrestore(&jsm_board_head_lock, lock_flags);
+
+ return adapter_count;
+}
+
+static ssize_t jsm_driver_version_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "jsm_version: %s\n", "jsm: 1.1-1-INKERNEL");
+}
+static DRIVER_ATTR(version, S_IRUSR, jsm_driver_version_show, NULL);
+
+static ssize_t jsm_driver_boards_show(struct device_driver *ddp, char *buf)
+{
+ int adapter_count = 0;
+ adapter_count = get_jsm_board_number();
+ return snprintf(buf, PAGE_SIZE, "jsm_board_number: %d\n", adapter_count);
+}
+static DRIVER_ATTR(boards, S_IRUSR, jsm_driver_boards_show, NULL);
+
+static ssize_t jsm_driver_state_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "jsm_state: %s\n", jsm_driver_state_text[jsm_driver_state]);
+}
+static DRIVER_ATTR(state, S_IRUSR, jsm_driver_state_show, NULL);
+
+static ssize_t jsm_driver_debug_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", debug);
+}
+
+static ssize_t jsm_driver_debug_store(struct device_driver *ddp, const char *buf, size_t count)
+{
+ sscanf(buf, "0x%x\n", &debug);
+ return count;
+}
+static DRIVER_ATTR(debug, (S_IRUSR | S_IWUSR), jsm_driver_debug_show, jsm_driver_debug_store);
+
+
+static ssize_t jsm_driver_rawreadok_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", rawreadok);
+}
+
+static ssize_t jsm_driver_rawreadok_store(struct device_driver *ddp, const char *buf, size_t count)
+{
+ sscanf(buf, "0x%x\n", &rawreadok);
+ return count;
+}
+static DRIVER_ATTR(rawreadok, (S_IRUSR | S_IWUSR), jsm_driver_rawreadok_show, jsm_driver_rawreadok_store);
+
+void jsm_create_driver_sysfiles(struct device_driver *driverfs)
+{
+ driver_create_file(driverfs, &driver_attr_version);
+ driver_create_file(driverfs, &driver_attr_boards);
+ driver_create_file(driverfs, &driver_attr_debug);
+ driver_create_file(driverfs, &driver_attr_rawreadok);
+ driver_create_file(driverfs, &driver_attr_state);
+}
+
+void jsm_remove_driver_sysfiles(struct device_driver *driverfs)
+{
+ driver_remove_file(driverfs, &driver_attr_version);
+ driver_remove_file(driverfs, &driver_attr_boards);
+ driver_remove_file(driverfs, &driver_attr_debug);
+ driver_remove_file(driverfs, &driver_attr_rawreadok);
+ driver_remove_file(driverfs, &driver_attr_state);
+}
+
+#define JSM_VERIFY_BOARD(p, bd) \
+ if (!p) \
+ return 0; \
+ bd = (struct jsm_board *)dev_get_drvdata(p); \
+ if (!bd) \
+ return 0; \
+ if (bd->state != BOARD_READY) \
+ return 0; \
+
+static ssize_t jsm_ports_state_show(struct device *p, char *buf)
+{
+ struct jsm_board *bd;
+ int count = 0;
+ int i = 0;
+
+ JSM_VERIFY_BOARD(p, bd);
+
+ for (i = 0; i < bd->nasync; i++) {
+ count += snprintf(buf + count, PAGE_SIZE - count,
+ "%d %s\n", bd->channels[i]->ch_portnum,
+ bd->channels[i]->ch_open_count ? "Open" : "Closed");
+ }
+ return count;
+}
+static DEVICE_ATTR(ports_state, S_IRUSR, jsm_ports_state_show, NULL);
+
+static ssize_t jsm_ports_baud_show(struct device *p, char *buf)
+{
+ struct jsm_board *bd;
+ int count = 0;
+ int i = 0;
+
+ JSM_VERIFY_BOARD(p, bd);
+
+ for (i = 0; i < bd->nasync; i++) {
+ count += snprintf(buf + count, PAGE_SIZE - count,
+ "%d %d\n", bd->channels[i]->ch_portnum, bd->channels[i]->ch_old_baud);
+ }
+ return count;
+}
+static DEVICE_ATTR(ports_baud, S_IRUSR, jsm_ports_baud_show, NULL);
+
+static ssize_t jsm_ports_msignals_show(struct device *p, char *buf)
+{
+ struct jsm_board *bd;
+ int count = 0;
+ int i = 0;
+
+ JSM_VERIFY_BOARD(p, bd);
+
+ for (i = 0; i < bd->nasync; i++) {
+ if (bd->channels[i]->ch_open_count) {
+ count += snprintf(buf + count, PAGE_SIZE - count,
+ "%d %s %s %s %s %s %s\n", bd->channels[i]->ch_portnum,
+ (bd->channels[i]->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
+ (bd->channels[i]->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
+ (bd->channels[i]->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
+ (bd->channels[i]->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
+ (bd->channels[i]->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
+ (bd->channels[i]->ch_mistat & UART_MSR_RI) ? "RI" : "");
+ } else {
+ count += snprintf(buf + count, PAGE_SIZE - count,
+ "%d\n", bd->channels[i]->ch_portnum);
+ }
+ }
+ return count;
+}
+static DEVICE_ATTR(ports_msignals, S_IRUSR, jsm_ports_msignals_show, NULL);
+
+static ssize_t jsm_ports_iflag_show(struct device *p, char *buf)
+{
+ struct jsm_board *bd;
+ int count = 0;
+ int i = 0;
+
+ JSM_VERIFY_BOARD(p, bd);
+
+ for (i = 0; i < bd->nasync; i++) {
+ count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
+ bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_iflag);
+ }
+ return count;
+}
+static DEVICE_ATTR(ports_iflag, S_IRUSR, jsm_ports_iflag_show, NULL);
+
+static ssize_t jsm_ports_cflag_show(struct device *p, char *buf)
+{
+ struct jsm_board *bd;
+ int count = 0;
+ int i = 0;
+
+ JSM_VERIFY_BOARD(p, bd);
+
+ for (i = 0; i < bd->nasync; i++) {
+ count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
+ bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_cflag);
+ }
+ return count;
+}
+static DEVICE_ATTR(ports_cflag, S_IRUSR, jsm_ports_cflag_show, NULL);
+
+static ssize_t jsm_ports_oflag_show(struct device *p, char *buf)
+{
+ struct jsm_board *bd;
+ int count = 0;
+ int i = 0;
+
+ JSM_VERIFY_BOARD(p, bd);
+
+ for (i = 0; i < bd->nasync; i++) {
+ count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
+ bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_oflag);
+ }
+ return count;
+}
+static DEVICE_ATTR(ports_oflag, S_IRUSR, jsm_ports_oflag_show, NULL);
+
+static ssize_t jsm_ports_lflag_show(struct device *p, char *buf)
+{
+ struct jsm_board *bd;
+ int count = 0;
+ int i = 0;
+
+ JSM_VERIFY_BOARD(p, bd);
+
+ for (i = 0; i < bd->nasync; i++) {
+ count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
+ bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_lflag);
+ }
+ return count;
+}
+static DEVICE_ATTR(ports_lflag, S_IRUSR, jsm_ports_lflag_show, NULL);
+
+static ssize_t jsm_ports_rxcount_show(struct device *p, char *buf)
+{
+ struct jsm_board *bd;
+ int count = 0;
+ int i = 0;
+
+ JSM_VERIFY_BOARD(p, bd);
+
+ for (i = 0; i < bd->nasync; i++) {
+ count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
+ bd->channels[i]->ch_portnum, bd->channels[i]->ch_rxcount);
+ }
+ return count;
+}
+static DEVICE_ATTR(ports_rxcount, S_IRUSR, jsm_ports_rxcount_show, NULL);
+
+static ssize_t jsm_ports_txcount_show(struct device *p, char *buf)
+{
+ struct jsm_board *bd;
+ int count = 0;
+ int i = 0;
+
+ JSM_VERIFY_BOARD(p, bd);
+
+ for (i = 0; i < bd->nasync; i++) {
+ count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
+ bd->channels[i]->ch_portnum, bd->channels[i]->ch_txcount);
+ }
+ return count;
+}
+static DEVICE_ATTR(ports_txcount, S_IRUSR, jsm_ports_txcount_show, NULL);
+
+/* this function creates the sys files that will export each signal status
+ * to sysfs each value will be put in a separate filename
+ */
+void jsm_create_ports_sysfiles(struct jsm_board *bd, struct device *devicefs)
+{
+ dev_set_drvdata(devicefs, bd);
+ device_create_file(devicefs, &dev_attr_ports_state);
+ device_create_file(devicefs, &dev_attr_ports_baud);
+ device_create_file(devicefs, &dev_attr_ports_msignals);
+ device_create_file(devicefs, &dev_attr_ports_iflag);
+ device_create_file(devicefs, &dev_attr_ports_cflag);
+ device_create_file(devicefs, &dev_attr_ports_oflag);
+ device_create_file(devicefs, &dev_attr_ports_lflag);
+ device_create_file(devicefs, &dev_attr_ports_rxcount);
+ device_create_file(devicefs, &dev_attr_ports_txcount);
+}
+
+/* removes all the sys files created for that port */
+void jsm_remove_ports_sysfiles(struct jsm_board *bd, struct device *devicefs)
+{
+ device_remove_file(devicefs, &dev_attr_ports_state);
+ device_remove_file(devicefs, &dev_attr_ports_baud);
+ device_remove_file(devicefs, &dev_attr_ports_msignals);
+ device_remove_file(devicefs, &dev_attr_ports_iflag);
+ device_remove_file(devicefs, &dev_attr_ports_cflag);
+ device_remove_file(devicefs, &dev_attr_ports_oflag);
+ device_remove_file(devicefs, &dev_attr_ports_lflag);
+ device_remove_file(devicefs, &dev_attr_ports_rxcount);
+ device_remove_file(devicefs, &dev_attr_ports_txcount);
+}
+
+
+int jsm_tty_class_init(void)
+{
+ jsm_tty_class = class_simple_create(THIS_MODULE, "jsm_tty");
+ if (IS_ERR(jsm_tty_class))
+ return PTR_ERR(jsm_tty_class);
+
+ return 0;
+}
+
+int jsm_tty_class_destroy(void)
+{
+ if (IS_ERR(jsm_tty_class))
+ return PTR_ERR(jsm_tty_class);
+
+ class_simple_destroy(jsm_tty_class);
+ return 0;
+}
+
+#define JSM_VERIFY_CHANNEL(p, ch) \
+ if (!p) \
+ return 0; \
+ ch = (struct jsm_channel *)class_get_devdata(p);\
+ if (!ch) \
+ return 0; \
+ if (ch->ch_bd->state != BOARD_READY) \
+ return 0; \
+
+static ssize_t jsm_tty_state_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ JSM_VERIFY_CHANNEL(class_dev, ch);
+ return snprintf(buf, PAGE_SIZE, "%s\n", ch->ch_open_count ? "Open" : "Closed");
+}
+static CLASS_DEVICE_ATTR(state, S_IRUGO, jsm_tty_state_show, NULL);
+
+
+static ssize_t jsm_tty_baud_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ JSM_VERIFY_CHANNEL(class_dev, ch);
+ return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
+}
+static CLASS_DEVICE_ATTR(baud, S_IRUGO, jsm_tty_baud_show, NULL);
+
+
+static ssize_t jsm_tty_msignals_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ JSM_VERIFY_CHANNEL(class_dev, ch);
+ if (ch->ch_open_count) {
+ return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
+ (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
+ (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
+ (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
+ (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
+ (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
+ (ch->ch_mistat & UART_MSR_RI) ? "RI" : "");
+ }
+ return 0;
+}
+static CLASS_DEVICE_ATTR(msignals, S_IRUGO, jsm_tty_msignals_show, NULL);
+
+static ssize_t jsm_tty_iflag_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ JSM_VERIFY_CHANNEL(class_dev, ch);
+ return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
+}
+static CLASS_DEVICE_ATTR(iflag, S_IRUGO, jsm_tty_iflag_show, NULL);
+
+
+static ssize_t jsm_tty_cflag_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ JSM_VERIFY_CHANNEL(class_dev, ch);
+ return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
+}
+static CLASS_DEVICE_ATTR(cflag, S_IRUGO, jsm_tty_cflag_show, NULL);
+
+static ssize_t jsm_tty_oflag_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ JSM_VERIFY_CHANNEL(class_dev, ch);
+ return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
+}
+static CLASS_DEVICE_ATTR(oflag, S_IRUGO, jsm_tty_oflag_show, NULL);
+
+static ssize_t jsm_tty_lflag_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ JSM_VERIFY_CHANNEL(class_dev, ch);
+ return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
+}
+static CLASS_DEVICE_ATTR(lflag, S_IRUGO, jsm_tty_lflag_show, NULL);
+
+static ssize_t jsm_tty_rxcount_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ JSM_VERIFY_CHANNEL(class_dev, ch);
+ return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
+}
+static CLASS_DEVICE_ATTR(rxcount, S_IRUGO, jsm_tty_rxcount_show, NULL);
+
+static ssize_t jsm_tty_txcount_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ JSM_VERIFY_CHANNEL(class_dev, ch);
+ return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
+}
+static CLASS_DEVICE_ATTR(txcount, S_IRUGO, jsm_tty_txcount_show, NULL);
+
+void jsm_tty_register_device(struct jsm_channel *ch, struct device *device)
+{
+ struct class_device *jsm_class_member;
+ dev_t dev;
+
+ dev = MKDEV(ch->ch_bd->jsm_serial_major,
+ ch->ch_portnum + ch->ch_bd->boardnum * 2);
+
+ jsm_class_member = class_simple_device_add(jsm_tty_class, dev, device,
+ "ttyn%d", ch->ch_portnum + ch->ch_bd->boardnum*2);
+
+ if (IS_ERR(jsm_class_member))
+ return;
+
+ class_set_devdata(jsm_class_member, ch);
+ class_device_create_file(jsm_class_member, &class_device_attr_state);
+ class_device_create_file(jsm_class_member, &class_device_attr_baud);
+ class_device_create_file(jsm_class_member, &class_device_attr_msignals);
+ class_device_create_file(jsm_class_member, &class_device_attr_iflag);
+ class_device_create_file(jsm_class_member, &class_device_attr_cflag);
+ class_device_create_file(jsm_class_member, &class_device_attr_oflag);
+ class_device_create_file(jsm_class_member, &class_device_attr_lflag);
+ class_device_create_file(jsm_class_member, &class_device_attr_rxcount);
+ class_device_create_file(jsm_class_member, &class_device_attr_txcount);
+}
+
+void jsm_tty_unregister_device(struct jsm_channel *ch)
+{
+
+ class_simple_device_remove(MKDEV(ch->ch_bd->jsm_serial_major,
+ ch->ch_portnum + ch->ch_bd->boardnum * 2));
+}
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-04 21:08 ` Wen Xiong
@ 2005-03-04 22:01 ` Greg KH
2005-03-07 22:46 ` Wen Xiong
0 siblings, 1 reply; 19+ messages in thread
From: Greg KH @ 2005-03-04 22:01 UTC (permalink / raw)
To: Wen Xiong; +Cc: linux-kernel
On Fri, Mar 04, 2005 at 04:08:17PM -0500, Wen Xiong wrote:
> +int get_jsm_board_number(void)
> +{
> + struct list_head *tmp;
> + struct jsm_board *cur_board_entry;
> + int adapter_count = 0;
> + u64 lock_flags;
> +
> + spin_lock_irqsave(&jsm_board_head_lock, lock_flags);
> + list_for_each(tmp, &jsm_board_head) {
> + cur_board_entry =
> + list_entry(tmp, struct jsm_board,
> + jsm_board_entry);
> + adapter_count++;
> + }
> + spin_unlock_irqrestore(&jsm_board_head_lock, lock_flags);
> +
> + return adapter_count;
> +}
Should this be static?
And it's returning the number of boards, not the current board number,
right?
And you have a indenting error in the list_for_each() section...
> +static ssize_t jsm_driver_version_show(struct device_driver *ddp, char *buf)
> +{
> + return snprintf(buf, PAGE_SIZE, "jsm_version: %s\n", "jsm: 1.1-1-INKERNEL");
Shouldn't that value also be in MODULE_VERSION()? And if so, it should
be a #define somewhere.
Also, don't put "jsm:" in your sysfs files, the file name describes what
the value should be. That goes for a lot of your sysfs files.
> +static ssize_t jsm_driver_debug_show(struct device_driver *ddp, char *buf)
> +{
> + return snprintf(buf, PAGE_SIZE, "0x%x\n", debug);
> +}
"debug" is not a nice variable to have in the global namespace :(
Also, why not just make this a module paramater, that way it can be
modified through that interface, and you don't have to create your own?
> +#define JSM_VERIFY_BOARD(p, bd) \
> + if (!p) \
> + return 0; \
> + bd = (struct jsm_board *)dev_get_drvdata(p); \
Cast is not needed.
> + if (!bd) \
> + return 0; \
> + if (bd->state != BOARD_READY) \
> + return 0; \
Don't break out of functions from within a macro. Will cause headaches
for people reviewing your code in the future.
And shouldn't you be returning an error if one of these checks fail?
> +static ssize_t jsm_ports_state_show(struct device *p, char *buf)
> +{
> + struct jsm_board *bd;
> + int count = 0;
> + int i = 0;
> +
> + JSM_VERIFY_BOARD(p, bd);
> +
> + for (i = 0; i < bd->nasync; i++) {
> + count += snprintf(buf + count, PAGE_SIZE - count,
> + "%d %s\n", bd->channels[i]->ch_portnum,
> + bd->channels[i]->ch_open_count ? "Open" : "Closed");
> + }
> + return count;
No, make this a per-port value. You are showing more than one value in
a single file. You do this for a few other sysfs files :(
And who cares about this value?
> +static ssize_t jsm_ports_baud_show(struct device *p, char *buf)
> +{
> + struct jsm_board *bd;
> + int count = 0;
> + int i = 0;
> +
> + JSM_VERIFY_BOARD(p, bd);
> +
> + for (i = 0; i < bd->nasync; i++) {
> + count += snprintf(buf + count, PAGE_SIZE - count,
> + "%d %d\n", bd->channels[i]->ch_portnum, bd->channels[i]->ch_old_baud);
> + }
> + return count;
> +}
> +static DEVICE_ATTR(ports_baud, S_IRUSR, jsm_ports_baud_show, NULL);
What's wrong with the standard tty ioctls that return this value, and
the other values you are exporting through sysfs? What is all of this
data needed for?
> +#define JSM_VERIFY_CHANNEL(p, ch) \
> + if (!p) \
> + return 0; \
> + ch = (struct jsm_channel *)class_get_devdata(p);\
> + if (!ch) \
> + return 0; \
> + if (ch->ch_bd->state != BOARD_READY) \
> + return 0; \
Again, don't put return in a macro, and return an error if there really
is one.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-04 22:01 ` Greg KH
@ 2005-03-07 22:46 ` Wen Xiong
2005-03-08 6:44 ` Greg KH
0 siblings, 1 reply; 19+ messages in thread
From: Wen Xiong @ 2005-03-07 22:46 UTC (permalink / raw)
To: Greg KH; +Cc: Wen Xiong, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 4076 bytes --]
Greg KH wrote:
>On Fri, Mar 04, 2005 at 04:08:17PM -0500, Wen Xiong wrote:
>
>
>>+int get_jsm_board_number(void)
>>+{
>>+ struct list_head *tmp;
>>+ struct jsm_board *cur_board_entry;
>>+ int adapter_count = 0;
>>+ u64 lock_flags;
>>+
>>+ spin_lock_irqsave(&jsm_board_head_lock, lock_flags);
>>+ list_for_each(tmp, &jsm_board_head) {
>>+ cur_board_entry =
>>+ list_entry(tmp, struct jsm_board,
>>+ jsm_board_entry);
>>+ adapter_count++;
>>+ }
>>+ spin_unlock_irqrestore(&jsm_board_head_lock, lock_flags);
>>+
>>+ return adapter_count;
>>+}
>>
>>
>
>Should this be static?
>
>And it's returning the number of boards, not the current board number,
>right?
>
>And you have a indenting error in the list_for_each() section...
>
>
>
>>+static ssize_t jsm_driver_version_show(struct device_driver *ddp, char *buf)
>>+{
>>+ return snprintf(buf, PAGE_SIZE, "jsm_version: %s\n", "jsm: 1.1-1-INKERNEL");
>>
>>
>
>Shouldn't that value also be in MODULE_VERSION()? And if so, it should
>be a #define somewhere.
>
>Also, don't put "jsm:" in your sysfs files, the file name describes what
>the value should be. That goes for a lot of your sysfs files.
>
>
>
>>+static ssize_t jsm_driver_debug_show(struct device_driver *ddp, char *buf)
>>+{
>>+ return snprintf(buf, PAGE_SIZE, "0x%x\n", debug);
>>+}
>>
>>
>
>"debug" is not a nice variable to have in the global namespace :(
>
>Also, why not just make this a module paramater, that way it can be
>modified through that interface, and you don't have to create your own?
>
>
>
>>+#define JSM_VERIFY_BOARD(p, bd) \
>>+ if (!p) \
>>+ return 0; \
>>+ bd = (struct jsm_board *)dev_get_drvdata(p); \
>>
>>
>
>Cast is not needed.
>
>
>
>>+ if (!bd) \
>>+ return 0; \
>>+ if (bd->state != BOARD_READY) \
>>+ return 0; \
>>
>>
>
>Don't break out of functions from within a macro. Will cause headaches
>for people reviewing your code in the future.
>
>And shouldn't you be returning an error if one of these checks fail?
>
>
>
>>+static ssize_t jsm_ports_state_show(struct device *p, char *buf)
>>+{
>>+ struct jsm_board *bd;
>>+ int count = 0;
>>+ int i = 0;
>>+
>>+ JSM_VERIFY_BOARD(p, bd);
>>+
>>+ for (i = 0; i < bd->nasync; i++) {
>>+ count += snprintf(buf + count, PAGE_SIZE - count,
>>+ "%d %s\n", bd->channels[i]->ch_portnum,
>>+ bd->channels[i]->ch_open_count ? "Open" : "Closed");
>>+ }
>>+ return count;
>>
>>
>
>No, make this a per-port value. You are showing more than one value in
>a single file. You do this for a few other sysfs files :(
>
>And who cares about this value?
>
>
>
>>+static ssize_t jsm_ports_baud_show(struct device *p, char *buf)
>>+{
>>+ struct jsm_board *bd;
>>+ int count = 0;
>>+ int i = 0;
>>+
>>+ JSM_VERIFY_BOARD(p, bd);
>>+
>>+ for (i = 0; i < bd->nasync; i++) {
>>+ count += snprintf(buf + count, PAGE_SIZE - count,
>>+ "%d %d\n", bd->channels[i]->ch_portnum, bd->channels[i]->ch_old_baud);
>>+ }
>>+ return count;
>>+}
>>+static DEVICE_ATTR(ports_baud, S_IRUSR, jsm_ports_baud_show, NULL);
>>
>>
>
>What's wrong with the standard tty ioctls that return this value, and
>the other values you are exporting through sysfs? What is all of this
>data needed for?
>
>
>
>>+#define JSM_VERIFY_CHANNEL(p, ch) \
>>+ if (!p) \
>>+ return 0; \
>>+ ch = (struct jsm_channel *)class_get_devdata(p);\
>>+ if (!ch) \
>>+ return 0; \
>>+ if (ch->ch_bd->state != BOARD_READY) \
>>+ return 0; \
>>
>>
>
>Again, don't put return in a macro, and return an error if there really
>is one.
>
>thanks,
>
>greg k-h
>-
>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/
>
>
>
Hi Greg,
Since some tools in Digi need some new ioctls, so I still keep some new
ioctls.
Thanks for your reviewing!
wendy
[-- Attachment #2: patch4.jasmine --]
[-- Type: text/plain, Size: 9252 bytes --]
diff -Nuar linux-2.6.11.org/drivers/serial/jsm/jsm_sysfs.c linux-2.6.11.new/drivers/serial/jsm/jsm_sysfs.c
--- linux-2.6.11.org/drivers/serial/jsm/jsm_sysfs.c 1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.11.new/drivers/serial/jsm/jsm_sysfs.c 2005-03-07 16:27:47.293998096 -0600
@@ -0,0 +1,289 @@
+/************************************************************************
+ * Copyright 2003 Digi International (www.digi.com)
+ *
+ * Copyright (C) 2004 IBM Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 * Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ *
+ * Contact Information:
+ * Scott H Kilau <Scott_Kilau@digi.com>
+ * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com>
+ *
+ ***********************************************************************/
+
+#include <linux/device.h>
+#include <linux/serial_reg.h>
+
+#include "jsm_driver.h"
+
+static struct class_simple *jsm_tty_class;
+
+int jsm_total_boardnum(void)
+{
+ struct list_head *tmp;
+ struct jsm_board *cur_board_entry;
+ int adapter_count = 0;
+ u64 lock_flags;
+
+ spin_lock_irqsave(&jsm_board_head_lock, lock_flags);
+ list_for_each(tmp, &jsm_board_head) {
+ cur_board_entry =
+ list_entry(tmp, struct jsm_board,
+ jsm_board_entry);
+ adapter_count++;
+ }
+ spin_unlock_irqrestore(&jsm_board_head_lock, lock_flags);
+
+ return adapter_count;
+}
+
+static ssize_t jsm_driver_version_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "jsm_version: %s\n", JSM_VERSION);
+}
+static DRIVER_ATTR(version, S_IRUSR, jsm_driver_version_show, NULL);
+
+static ssize_t jsm_driver_boards_show(struct device_driver *ddp, char *buf)
+{
+ int adapter_count = 0;
+ adapter_count = jsm_total_boardnum();
+ return snprintf(buf, PAGE_SIZE, "jsm_board_number: %d\n", adapter_count);
+}
+static DRIVER_ATTR(boards, S_IRUSR, jsm_driver_boards_show, NULL);
+
+static ssize_t jsm_driver_state_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "jsm_state: %s\n", jsm_driver_state_text[jsm_driver_state]);
+}
+static DRIVER_ATTR(state, S_IRUSR, jsm_driver_state_show, NULL);
+
+static ssize_t jsm_driver_debug_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", jsm_debug);
+}
+static DRIVER_ATTR(debug, S_IRUSR, jsm_driver_debug_show, NULL);
+
+
+static ssize_t jsm_driver_rawreadok_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", jsm_rawreadok);
+}
+static DRIVER_ATTR(rawreadok, S_IRUSR, jsm_driver_rawreadok_show, NULL);
+
+void jsm_create_driver_sysfiles(struct device_driver *driverfs)
+{
+ driver_create_file(driverfs, &driver_attr_version);
+ driver_create_file(driverfs, &driver_attr_boards);
+ driver_create_file(driverfs, &driver_attr_debug);
+ driver_create_file(driverfs, &driver_attr_rawreadok);
+ driver_create_file(driverfs, &driver_attr_state);
+}
+
+void jsm_remove_driver_sysfiles(struct device_driver *driverfs)
+{
+ driver_remove_file(driverfs, &driver_attr_version);
+ driver_remove_file(driverfs, &driver_attr_boards);
+ driver_remove_file(driverfs, &driver_attr_debug);
+ driver_remove_file(driverfs, &driver_attr_rawreadok);
+ driver_remove_file(driverfs, &driver_attr_state);
+}
+
+int jsm_tty_class_init(void)
+{
+ jsm_tty_class = class_simple_create(THIS_MODULE, "jsm_tty");
+ if (IS_ERR(jsm_tty_class))
+ return PTR_ERR(jsm_tty_class);
+
+ return 0;
+}
+
+int jsm_tty_class_destroy(void)
+{
+ if (IS_ERR(jsm_tty_class))
+ return PTR_ERR(jsm_tty_class);
+
+ class_simple_destroy(jsm_tty_class);
+ return 0;
+}
+
+static ssize_t jsm_tty_state_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ if (class_dev) {
+ ch = class_get_devdata(class_dev);
+ if ( ch && (ch->ch_bd->state == BOARD_READY))
+ return snprintf(buf, PAGE_SIZE, "%s\n", ch->ch_open_count ? "Open" : "Closed");
+ }
+
+ return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(state, S_IRUGO, jsm_tty_state_show, NULL);
+
+
+static ssize_t jsm_tty_baud_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ if (class_dev) {
+ ch = class_get_devdata(class_dev);
+ if ( ch && (ch->ch_bd->state == BOARD_READY))
+ return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
+ }
+
+ return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(baud, S_IRUGO, jsm_tty_baud_show, NULL);
+
+static ssize_t jsm_tty_msignals_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ if (class_dev) {
+ ch = class_get_devdata(class_dev);
+ if ( ch && (ch->ch_bd->state == BOARD_READY))
+ if (ch->ch_open_count) {
+ return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
+ (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
+ (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
+ (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
+ (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
+ (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
+ (ch->ch_mistat & UART_MSR_RI) ? "RI" : "");
+ }
+ }
+
+ return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(msignals, S_IRUGO, jsm_tty_msignals_show, NULL);
+
+static ssize_t jsm_tty_iflag_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ if (class_dev) {
+ ch = class_get_devdata(class_dev);
+ if ( ch && (ch->ch_bd->state == BOARD_READY))
+ return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
+ }
+
+ return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(iflag, S_IRUGO, jsm_tty_iflag_show, NULL);
+
+
+static ssize_t jsm_tty_cflag_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ if (class_dev) {
+ ch = class_get_devdata(class_dev);
+ if ( ch && (ch->ch_bd->state == BOARD_READY))
+ return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
+ }
+
+ return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(cflag, S_IRUGO, jsm_tty_cflag_show, NULL);
+
+static ssize_t jsm_tty_oflag_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ if (class_dev) {
+ ch = class_get_devdata(class_dev);
+ if ( ch && (ch->ch_bd->state == BOARD_READY))
+ return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
+ }
+
+ return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(oflag, S_IRUGO, jsm_tty_oflag_show, NULL);
+
+static ssize_t jsm_tty_lflag_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ if (class_dev) {
+ ch = class_get_devdata(class_dev);
+ if ( ch && (ch->ch_bd->state == BOARD_READY))
+ return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
+ }
+
+ return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(lflag, S_IRUGO, jsm_tty_lflag_show, NULL);
+
+static ssize_t jsm_tty_rxcount_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ if (class_dev) {
+ ch = class_get_devdata(class_dev);
+ if ( ch && (ch->ch_bd->state == BOARD_READY))
+ return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
+ }
+
+ return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(rxcount, S_IRUGO, jsm_tty_rxcount_show, NULL);
+
+static ssize_t jsm_tty_txcount_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+
+ if (class_dev) {
+ ch = class_get_devdata(class_dev);
+ if ( ch && (ch->ch_bd->state == BOARD_READY))
+ return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
+ }
+
+ return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(txcount, S_IRUGO, jsm_tty_txcount_show, NULL);
+
+void jsm_tty_register_device(struct jsm_channel *ch, struct device *device)
+{
+ struct class_device *jsm_class_member;
+ dev_t dev;
+
+ dev = MKDEV(ch->ch_bd->jsm_serial_major,
+ ch->ch_portnum + ch->ch_bd->boardnum * 2);
+
+ jsm_class_member = class_simple_device_add(jsm_tty_class, dev, device,
+ "ttyn%d", ch->ch_portnum + ch->ch_bd->boardnum*2);
+
+ if (IS_ERR(jsm_class_member))
+ return;
+
+ class_set_devdata(jsm_class_member, ch);
+ class_device_create_file(jsm_class_member, &class_device_attr_state);
+ class_device_create_file(jsm_class_member, &class_device_attr_baud);
+ class_device_create_file(jsm_class_member, &class_device_attr_msignals);
+ class_device_create_file(jsm_class_member, &class_device_attr_iflag);
+ class_device_create_file(jsm_class_member, &class_device_attr_cflag);
+ class_device_create_file(jsm_class_member, &class_device_attr_oflag);
+ class_device_create_file(jsm_class_member, &class_device_attr_lflag);
+ class_device_create_file(jsm_class_member, &class_device_attr_rxcount);
+ class_device_create_file(jsm_class_member, &class_device_attr_txcount);
+}
+
+void jsm_tty_unregister_device(struct jsm_channel *ch)
+{
+
+ class_simple_device_remove(MKDEV(ch->ch_bd->jsm_serial_major,
+ ch->ch_portnum + ch->ch_bd->boardnum * 2));
+}
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-07 22:46 ` Wen Xiong
@ 2005-03-08 6:44 ` Greg KH
2005-03-08 18:55 ` Wen Xiong
2005-03-09 16:11 ` Russell King
0 siblings, 2 replies; 19+ messages in thread
From: Greg KH @ 2005-03-08 6:44 UTC (permalink / raw)
To: Wen Xiong; +Cc: linux-kernel
On Mon, Mar 07, 2005 at 05:46:51PM -0500, Wen Xiong wrote:
> +static ssize_t jsm_driver_version_show(struct device_driver *ddp, char *buf)
> +{
> + return snprintf(buf, PAGE_SIZE, "jsm_version: %s\n", JSM_VERSION);
Again, drop the "prefix:" from every sysfs file, it should not be there
(the data type is inferred by the name of the file, you do not have to
repeat it again.)
> +static ssize_t jsm_tty_state_show(struct class_device *class_dev, char *buf)
> +{
> + struct jsm_channel *ch;
> +
> + if (class_dev) {
> + ch = class_get_devdata(class_dev);
> + if ( ch && (ch->ch_bd->state == BOARD_READY))
> + return snprintf(buf, PAGE_SIZE, "%s\n", ch->ch_open_count ? "Open" : "Closed");
> + }
> +
> + return -EINVAL;
> +}
> +static CLASS_DEVICE_ATTR(state, S_IRUGO, jsm_tty_state_show, NULL);
Who needs to know if a port is open or not?
> +static ssize_t jsm_tty_baud_show(struct class_device *class_dev, char *buf)
> +{
> + struct jsm_channel *ch;
> +
> + if (class_dev) {
> + ch = class_get_devdata(class_dev);
> + if ( ch && (ch->ch_bd->state == BOARD_READY))
> + return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
> + }
> +
> + return -EINVAL;
> +}
> +static CLASS_DEVICE_ATTR(baud, S_IRUGO, jsm_tty_baud_show, NULL);
No, please delete these, and the other sysfs files that duplicate the
same info that you can get by using the standard Linux termios calls.
There is no need for them here.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-08 6:44 ` Greg KH
@ 2005-03-08 18:55 ` Wen Xiong
2005-03-08 23:58 ` Greg KH
2005-03-09 16:11 ` Russell King
1 sibling, 1 reply; 19+ messages in thread
From: Wen Xiong @ 2005-03-08 18:55 UTC (permalink / raw)
To: Greg KH; +Cc: Wen Xiong, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1616 bytes --]
Greg KH wrote:
>On Mon, Mar 07, 2005 at 05:46:51PM -0500, Wen Xiong wrote:
>
>
>>+static ssize_t jsm_driver_version_show(struct device_driver *ddp, char *buf)
>>+{
>>+ return snprintf(buf, PAGE_SIZE, "jsm_version: %s\n", JSM_VERSION);
>>
>>
>
>Again, drop the "prefix:" from every sysfs file, it should not be there
>(the data type is inferred by the name of the file, you do not have to
>repeat it again.)
>
>
>
>>+static ssize_t jsm_tty_state_show(struct class_device *class_dev, char *buf)
>>+{
>>+ struct jsm_channel *ch;
>>+
>>+ if (class_dev) {
>>+ ch = class_get_devdata(class_dev);
>>+ if ( ch && (ch->ch_bd->state == BOARD_READY))
>>+ return snprintf(buf, PAGE_SIZE, "%s\n", ch->ch_open_count ? "Open" : "Closed");
>>+ }
>>+
>>+ return -EINVAL;
>>+}
>>+static CLASS_DEVICE_ATTR(state, S_IRUGO, jsm_tty_state_show, NULL);
>>
>>
>
>Who needs to know if a port is open or not?
>
>
>
>>+static ssize_t jsm_tty_baud_show(struct class_device *class_dev, char *buf)
>>+{
>>+ struct jsm_channel *ch;
>>+
>>+ if (class_dev) {
>>+ ch = class_get_devdata(class_dev);
>>+ if ( ch && (ch->ch_bd->state == BOARD_READY))
>>+ return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
>>+ }
>>+
>>+ return -EINVAL;
>>+}
>>+static CLASS_DEVICE_ATTR(baud, S_IRUGO, jsm_tty_baud_show, NULL);
>>
>>
>
>No, please delete these, and the other sysfs files that duplicate the
>same info that you can get by using the standard Linux termios calls.
>There is no need for them here.
>
>thanks,
>
>greg k-h
>
>
>
Hi Greg,
Removed some codes in jsm_sysfs.c.
Thanks for your reviewing the code.
wendy
[-- Attachment #2: patch4.jasmine --]
[-- Type: text/plain, Size: 3790 bytes --]
diff -Nuar linux-2.6.11.org/drivers/serial/jsm/jsm_sysfs.c linux-2.6.11.new/drivers/serial/jsm/jsm_sysfs.c
--- linux-2.6.11.org/drivers/serial/jsm/jsm_sysfs.c 1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.11.new/drivers/serial/jsm/jsm_sysfs.c 2005-03-08 12:19:57.498967368 -0600
@@ -0,0 +1,98 @@
+/************************************************************************
+ * Copyright 2003 Digi International (www.digi.com)
+ *
+ * Copyright (C) 2004 IBM Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 * Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ *
+ * Contact Information:
+ * Scott H Kilau <Scott_Kilau@digi.com>
+ * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com>
+ *
+ ***********************************************************************/
+#include <linux/device.h>
+#include <linux/serial_reg.h>
+
+#include "jsm_driver.h"
+
+int jsm_total_boardnum(void)
+{
+ struct list_head *tmp;
+ struct jsm_board *cur_board_entry;
+ int adapter_count = 0;
+ u64 lock_flags;
+
+ spin_lock_irqsave(&jsm_board_head_lock, lock_flags);
+ list_for_each(tmp, &jsm_board_head) {
+ cur_board_entry =
+ list_entry(tmp, struct jsm_board,
+ jsm_board_entry);
+ adapter_count++;
+ }
+ spin_unlock_irqrestore(&jsm_board_head_lock, lock_flags);
+
+ return adapter_count;
+}
+
+static ssize_t jsm_driver_version_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", JSM_VERSION);
+}
+static DRIVER_ATTR(version, S_IRUSR, jsm_driver_version_show, NULL);
+
+static ssize_t jsm_driver_boards_show(struct device_driver *ddp, char *buf)
+{
+ int adapter_count = 0;
+ adapter_count = jsm_total_boardnum();
+ return snprintf(buf, PAGE_SIZE, "%d\n", adapter_count);
+}
+static DRIVER_ATTR(boards, S_IRUSR, jsm_driver_boards_show, NULL);
+
+static ssize_t jsm_driver_state_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", jsm_driver_state_text[jsm_driver_state]);
+}
+static DRIVER_ATTR(state, S_IRUSR, jsm_driver_state_show, NULL);
+
+static ssize_t jsm_driver_debug_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", jsm_debug);
+}
+static DRIVER_ATTR(debug, S_IRUSR, jsm_driver_debug_show, NULL);
+
+static ssize_t jsm_driver_rawreadok_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", jsm_rawreadok);
+}
+static DRIVER_ATTR(rawreadok, S_IRUSR, jsm_driver_rawreadok_show, NULL);
+
+void jsm_create_driver_sysfiles(struct device_driver *driverfs)
+{
+ driver_create_file(driverfs, &driver_attr_version);
+ driver_create_file(driverfs, &driver_attr_boards);
+ driver_create_file(driverfs, &driver_attr_debug);
+ driver_create_file(driverfs, &driver_attr_rawreadok);
+ driver_create_file(driverfs, &driver_attr_state);
+}
+
+void jsm_remove_driver_sysfiles(struct device_driver *driverfs)
+{
+ driver_remove_file(driverfs, &driver_attr_version);
+ driver_remove_file(driverfs, &driver_attr_boards);
+ driver_remove_file(driverfs, &driver_attr_debug);
+ driver_remove_file(driverfs, &driver_attr_rawreadok);
+ driver_remove_file(driverfs, &driver_attr_state);
+}
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
@ 2005-03-08 21:47 Kilau, Scott
2005-03-09 0:02 ` Greg KH
2005-03-09 16:16 ` Russell King
0 siblings, 2 replies; 19+ messages in thread
From: Kilau, Scott @ 2005-03-08 21:47 UTC (permalink / raw)
To: linux-kernel; +Cc: greg, Wen Xiong
> Who needs to know if a port is open or not?
>
<snipped some code>
>
> +static ssize_t jsm_tty_baud_show(struct class_device *class_dev, char
*buf)
> No, please delete these, and the other sysfs files that duplicate the
> same info that you can get by using the standard Linux termios calls.
> There is no need for them here.
>
> thanks,
> greg k-h
Hi Greg, Wendy, all,
Our serial port monitoring tools need to know these things, and to
find them out *without* opening up the serial port to do an ioctl().
For example, lets say a customer has a modem connected to a serial port.
If you were to open up the port with an "stty -a" to get the current
settings and signals, you would unintentionally raise RTS and DTR.
Now the modem sees DTR raised, and might react to it by mistake.
Usually raising and dropping RTS/DTR quickly on a modem won't hurt
anything,
but its not particularly a "good" when the modem is not expecting it.
This is why we export the various signals/stats/signals to sysfs (used
to be proc),
so our management tools can get the information about the serial port
without being
intrusive by opening up the port.
Scott
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-08 18:55 ` Wen Xiong
@ 2005-03-08 23:58 ` Greg KH
2005-03-09 15:47 ` Wen Xiong
0 siblings, 1 reply; 19+ messages in thread
From: Greg KH @ 2005-03-08 23:58 UTC (permalink / raw)
To: Wen Xiong; +Cc: linux-kernel
On Tue, Mar 08, 2005 at 01:55:33PM -0500, Wen Xiong wrote:
> +static ssize_t jsm_driver_boards_show(struct device_driver *ddp, char *buf)
> +{
> + int adapter_count = 0;
> + adapter_count = jsm_total_boardnum();
> + return snprintf(buf, PAGE_SIZE, "%d\n", adapter_count);
> +}
> +static DRIVER_ATTR(boards, S_IRUSR, jsm_driver_boards_show, NULL);
Why is this file even needed? You can just look at the number of sysfs
directories attached to this device, right?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-08 21:47 Kilau, Scott
@ 2005-03-09 0:02 ` Greg KH
2005-03-09 16:16 ` Russell King
1 sibling, 0 replies; 19+ messages in thread
From: Greg KH @ 2005-03-09 0:02 UTC (permalink / raw)
To: Kilau, Scott; +Cc: linux-kernel, Wen Xiong
On Tue, Mar 08, 2005 at 03:47:45PM -0600, Kilau, Scott wrote:
> > Who needs to know if a port is open or not?
> >
> <snipped some code>
> >
> > +static ssize_t jsm_tty_baud_show(struct class_device *class_dev, char *buf)
>
> > No, please delete these, and the other sysfs files that duplicate the
> > same info that you can get by using the standard Linux termios calls.
> > There is no need for them here.
>
> Our serial port monitoring tools need to know these things, and to
> find them out *without* opening up the serial port to do an ioctl().
>
> For example, lets say a customer has a modem connected to a serial port.
>
> If you were to open up the port with an "stty -a" to get the current
> settings and signals, you would unintentionally raise RTS and DTR.
Why not fix the driver to not change the current line settings if it is
not being opened for the first time? That seems like a much simpler way
to solve this, and probably the saner way, as you don't want any user to
be able to mess up your modem...
thanks,
greg k-h
^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: [ patch 4/7] drivers/serial/jsm: new serial device driver
@ 2005-03-09 2:36 Kilau, Scott
2005-03-09 5:50 ` Greg KH
0 siblings, 1 reply; 19+ messages in thread
From: Kilau, Scott @ 2005-03-09 2:36 UTC (permalink / raw)
To: Greg KH; +Cc: linux-kernel, Wen Xiong
> >
> > If you were to open up the port with an "stty -a" to get the current
> > settings and signals, you would unintentionally raise RTS and DTR.
>
> Why not fix the driver to not change the current line settings if it
is
> not being opened for the first time? That seems like a much simpler
way
> to solve this, and probably the saner way, as you don't want any user
to
> be able to mess up your modem...
>
> thanks,
>
> greg k-h
Oh, when the port is already open, the driver correctly would not muck
with DTR/RTS.
I am talking about when the port is currently not open.
On first port open, DTR (and usually RTS) will always be raised.
The serial device would see this DTR raise, and under some
circumstances,
react to it...
We have customers that use *really* *really* old serial devices on
our products, (we are talking 110 baud and even 50 baud (!!!)),
where an unintentional raise of DTR/RTS will freak the device out.
At any rate, that's the reason I exported the values to sysfs in the
original "dgnc" (outside-the-kernel-sources) driver.
Thanks,
Scott
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-09 2:36 [ patch 4/7] drivers/serial/jsm: new serial device driver Kilau, Scott
@ 2005-03-09 5:50 ` Greg KH
0 siblings, 0 replies; 19+ messages in thread
From: Greg KH @ 2005-03-09 5:50 UTC (permalink / raw)
To: Kilau, Scott; +Cc: linux-kernel, Wen Xiong
On Tue, Mar 08, 2005 at 08:36:57PM -0600, Kilau, Scott wrote:
> > >
> > > If you were to open up the port with an "stty -a" to get the current
>
> > > settings and signals, you would unintentionally raise RTS and DTR.
> >
> > Why not fix the driver to not change the current line settings if it
> is
> > not being opened for the first time? That seems like a much simpler
> way
> > to solve this, and probably the saner way, as you don't want any user
> to
> > be able to mess up your modem...
> >
>
> Oh, when the port is already open, the driver correctly would not muck
> with DTR/RTS.
>
> I am talking about when the port is currently not open.
>
> On first port open, DTR (and usually RTS) will always be raised.
> The serial device would see this DTR raise, and under some
> circumstances, react to it...
Ok, well, that sounds like something that all serial devices should
support, right? And if so, why not add this to the serial core for
everyone to benifit?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-08 23:58 ` Greg KH
@ 2005-03-09 15:47 ` Wen Xiong
2005-03-09 16:35 ` Greg KH
0 siblings, 1 reply; 19+ messages in thread
From: Wen Xiong @ 2005-03-09 15:47 UTC (permalink / raw)
To: Greg KH; +Cc: Wen Xiong, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 728 bytes --]
Greg KH wrote:
>On Tue, Mar 08, 2005 at 01:55:33PM -0500, Wen Xiong wrote:
>
>
>>+static ssize_t jsm_driver_boards_show(struct device_driver *ddp, char *buf)
>>+{
>>+ int adapter_count = 0;
>>+ adapter_count = jsm_total_boardnum();
>>+ return snprintf(buf, PAGE_SIZE, "%d\n", adapter_count);
>>+}
>>+static DRIVER_ATTR(boards, S_IRUSR, jsm_driver_boards_show, NULL);
>>
>>
>
>Why is this file even needed? You can just look at the number of sysfs
>directories attached to this device, right?
>
>thanks,
>
>greg k-h
>
>
>
We can find out the number of adapters in several ways in linux. But we
are not sure the end customer really know how to find out.
Anyway, attatched the new patch4.jasmine for you.
Thanks,
wendy
[-- Attachment #2: patch4.jasmine --]
[-- Type: text/plain, Size: 2977 bytes --]
diff -Nuar linux-2.6.11.org/drivers/serial/jsm/jsm_sysfs.c linux-2.6.11.new/drivers/serial/jsm/jsm_sysfs.c
--- linux-2.6.11.org/drivers/serial/jsm/jsm_sysfs.c 1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.11.new/drivers/serial/jsm/jsm_sysfs.c 2005-03-09 09:37:00.520967448 -0600
@@ -0,0 +1,69 @@
+/************************************************************************
+ * Copyright 2003 Digi International (www.digi.com)
+ *
+ * Copyright (C) 2004 IBM Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 * Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ *
+ * Contact Information:
+ * Scott H Kilau <Scott_Kilau@digi.com>
+ * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com>
+ *
+ ***********************************************************************/
+#include <linux/device.h>
+#include <linux/serial_reg.h>
+
+#include "jsm_driver.h"
+
+static ssize_t jsm_driver_version_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", JSM_VERSION);
+}
+static DRIVER_ATTR(version, S_IRUSR, jsm_driver_version_show, NULL);
+
+static ssize_t jsm_driver_state_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", jsm_driver_state_text[jsm_driver_state]);
+}
+static DRIVER_ATTR(state, S_IRUSR, jsm_driver_state_show, NULL);
+
+static ssize_t jsm_driver_debug_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", jsm_debug);
+}
+static DRIVER_ATTR(debug, S_IRUSR, jsm_driver_debug_show, NULL);
+
+static ssize_t jsm_driver_rawreadok_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", jsm_rawreadok);
+}
+static DRIVER_ATTR(rawreadok, S_IRUSR, jsm_driver_rawreadok_show, NULL);
+
+void jsm_create_driver_sysfiles(struct device_driver *driverfs)
+{
+ driver_create_file(driverfs, &driver_attr_version);
+ driver_create_file(driverfs, &driver_attr_debug);
+ driver_create_file(driverfs, &driver_attr_rawreadok);
+ driver_create_file(driverfs, &driver_attr_state);
+}
+
+void jsm_remove_driver_sysfiles(struct device_driver *driverfs)
+{
+ driver_remove_file(driverfs, &driver_attr_version);
+ driver_remove_file(driverfs, &driver_attr_debug);
+ driver_remove_file(driverfs, &driver_attr_rawreadok);
+ driver_remove_file(driverfs, &driver_attr_state);
+}
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-08 6:44 ` Greg KH
2005-03-08 18:55 ` Wen Xiong
@ 2005-03-09 16:11 ` Russell King
1 sibling, 0 replies; 19+ messages in thread
From: Russell King @ 2005-03-09 16:11 UTC (permalink / raw)
To: Greg KH; +Cc: Wen Xiong, linux-kernel
On Mon, Mar 07, 2005 at 10:44:25PM -0800, Greg KH wrote:
> On Mon, Mar 07, 2005 at 05:46:51PM -0500, Wen Xiong wrote:
> > +static ssize_t jsm_tty_baud_show(struct class_device *class_dev, char *buf)
> > +{
> > + struct jsm_channel *ch;
> > +
> > + if (class_dev) {
> > + ch = class_get_devdata(class_dev);
> > + if ( ch && (ch->ch_bd->state == BOARD_READY))
> > + return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
> > + }
> > +
> > + return -EINVAL;
> > +}
> > +static CLASS_DEVICE_ATTR(baud, S_IRUGO, jsm_tty_baud_show, NULL);
>
> No, please delete these, and the other sysfs files that duplicate the
> same info that you can get by using the standard Linux termios calls.
> There is no need for them here.
Greg, there's several other points about why the above is Bad(tm).
"class_dev" will always be non-null.
Note that this (and similar code) is racy. Consider what happens when
the class device is removed (and the class devdata is NULL'd or kfree'd)
while another process on another CPU reads from one of these sysfs files.
*BANG*.
Also, if a class device attribute method is going to access data outside
the same allocation which the class device is a part of, you *absolutely*
*must* have some form of locking.
Also note that the formatting of these snippets of code is abismal.
There is a missing tab which makes it very non-readable.
With all of the above comments, it should be something like:
+static ssize_t jsm_tty_baud_show(struct class_device *class_dev, char *buf)
+{
+ struct jsm_channel *ch;
+ int ret = -EINVAL;
+
+ down(&some_lock);
+ ch = class_get_devdata(class_dev);
+ if (ch && (ch->ch_bd->state == BOARD_READY))
+ ret = snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
+ up(&some_lock);
+
+ return ret;
+}
+static CLASS_DEVICE_ATTR(baud, S_IRUGO, jsm_tty_baud_show, NULL);
where "some_lock" is also taken in the device unregistration path, at
the point where the class devdata is NULL'd out. (which the driver is
also missing.)
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-08 21:47 Kilau, Scott
2005-03-09 0:02 ` Greg KH
@ 2005-03-09 16:16 ` Russell King
1 sibling, 0 replies; 19+ messages in thread
From: Russell King @ 2005-03-09 16:16 UTC (permalink / raw)
To: Kilau, Scott; +Cc: linux-kernel, greg, Wen Xiong
On Tue, Mar 08, 2005 at 03:47:45PM -0600, Kilau, Scott wrote:
> For example, lets say a customer has a modem connected to a serial port.
>
> If you were to open up the port with an "stty -a" to get the current
> settings and signals, you would unintentionally raise RTS and DTR.
That isn't special to this driver though. Maybe it should be fixed for
all serial drivers, since the situation you mention above is not limited
to just this driver.
As you say, you may have a modem connected, which may have been configured
to automatically dial a predetermined number when DTR is raised.
Maybe we need a solution which applies to all drivers?
> This is why we export the various signals/stats/signals to sysfs (used
> to be proc), so our management tools can get the information about the
> serial port without being intrusive by opening up the port.
Note that exporting statistics can be a security bug, especially if that
includes the number of bytes sent/received. For an explaination of this,
please lookup the reason why the /proc/tty/driver directory was made
unreadable to userspace.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-09 15:47 ` Wen Xiong
@ 2005-03-09 16:35 ` Greg KH
2005-03-09 17:18 ` Wen Xiong
0 siblings, 1 reply; 19+ messages in thread
From: Greg KH @ 2005-03-09 16:35 UTC (permalink / raw)
To: Wen Xiong; +Cc: linux-kernel
On Wed, Mar 09, 2005 at 10:47:22AM -0500, Wen Xiong wrote:
> +static ssize_t jsm_driver_debug_show(struct device_driver *ddp, char *buf)
> +{
> + return snprintf(buf, PAGE_SIZE, "0x%x\n", jsm_debug);
> +}
> +static DRIVER_ATTR(debug, S_IRUSR, jsm_driver_debug_show, NULL);
Should just be a module paramater, right? So you can drop this too...
This file is getting quite small now :)
thanks,
greg k-h
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-09 16:35 ` Greg KH
@ 2005-03-09 17:18 ` Wen Xiong
2005-03-09 18:58 ` Greg KH
0 siblings, 1 reply; 19+ messages in thread
From: Wen Xiong @ 2005-03-09 17:18 UTC (permalink / raw)
To: Greg KH; +Cc: Wen Xiong, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 568 bytes --]
Greg KH wrote:
>On Wed, Mar 09, 2005 at 10:47:22AM -0500, Wen Xiong wrote:
>
>
>>+static ssize_t jsm_driver_debug_show(struct device_driver *ddp, char *buf)
>>+{
>>+ return snprintf(buf, PAGE_SIZE, "0x%x\n", jsm_debug);
>>+}
>>+static DRIVER_ATTR(debug, S_IRUSR, jsm_driver_debug_show, NULL);
>>
>>
>
>Should just be a module paramater, right? So you can drop this too...
>
>This file is getting quite small now :)
>
>thanks,
>
>greg k-h
>
>
>
If I removed two module paramaters, only two files left: version and state.
Removed all of them?
Thanks,
wendy
[-- Attachment #2: patch4.jasmine --]
[-- Type: text/plain, Size: 2332 bytes --]
diff -Nuar linux-2.6.11.org/drivers/serial/jsm/jsm_sysfs.c linux-2.6.11.new/drivers/serial/jsm/jsm_sysfs.c
--- linux-2.6.11.org/drivers/serial/jsm/jsm_sysfs.c 1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.11.new/drivers/serial/jsm/jsm_sysfs.c 2005-03-09 11:17:37.055947624 -0600
@@ -0,0 +1,53 @@
+/************************************************************************
+ * Copyright 2003 Digi International (www.digi.com)
+ *
+ * Copyright (C) 2004 IBM Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 * Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ *
+ * Contact Information:
+ * Scott H Kilau <Scott_Kilau@digi.com>
+ * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com>
+ *
+ ***********************************************************************/
+#include <linux/device.h>
+#include <linux/serial_reg.h>
+
+#include "jsm_driver.h"
+
+static ssize_t jsm_driver_version_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", JSM_VERSION);
+}
+static DRIVER_ATTR(version, S_IRUSR, jsm_driver_version_show, NULL);
+
+static ssize_t jsm_driver_state_show(struct device_driver *ddp, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", jsm_driver_state_text[jsm_driver_state]);
+}
+static DRIVER_ATTR(state, S_IRUSR, jsm_driver_state_show, NULL);
+
+void jsm_create_driver_sysfiles(struct device_driver *driverfs)
+{
+ driver_create_file(driverfs, &driver_attr_version);
+ driver_create_file(driverfs, &driver_attr_state);
+}
+
+void jsm_remove_driver_sysfiles(struct device_driver *driverfs)
+{
+ driver_remove_file(driverfs, &driver_attr_version);
+ driver_remove_file(driverfs, &driver_attr_state);
+}
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ patch 4/7] drivers/serial/jsm: new serial device driver
2005-03-09 17:18 ` Wen Xiong
@ 2005-03-09 18:58 ` Greg KH
0 siblings, 0 replies; 19+ messages in thread
From: Greg KH @ 2005-03-09 18:58 UTC (permalink / raw)
To: Wen Xiong; +Cc: linux-kernel
On Wed, Mar 09, 2005 at 12:18:21PM -0500, Wen Xiong wrote:
> Greg KH wrote:
>
> >On Wed, Mar 09, 2005 at 10:47:22AM -0500, Wen Xiong wrote:
> >
> >
> >>+static ssize_t jsm_driver_debug_show(struct device_driver *ddp, char
> >>*buf)
> >>+{
> >>+ return snprintf(buf, PAGE_SIZE, "0x%x\n", jsm_debug);
> >>+}
> >>+static DRIVER_ATTR(debug, S_IRUSR, jsm_driver_debug_show, NULL);
> >>
> >>
> >
> >Should just be a module paramater, right? So you can drop this too...
> >
> >This file is getting quite small now :)
> >
> If I removed two module paramaters, only two files left: version and state.
> Removed all of them?
Move them to a different file?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2005-03-09 18:59 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-09 2:36 [ patch 4/7] drivers/serial/jsm: new serial device driver Kilau, Scott
2005-03-09 5:50 ` Greg KH
-- strict thread matches above, loose matches on Subject: below --
2005-03-08 21:47 Kilau, Scott
2005-03-09 0:02 ` Greg KH
2005-03-09 16:16 ` Russell King
2005-02-27 23:39 Wen Xiong
2005-02-28 3:21 ` Christoph Hellwig
2005-02-28 6:39 ` Greg KH
2005-03-04 21:08 ` Wen Xiong
2005-03-04 22:01 ` Greg KH
2005-03-07 22:46 ` Wen Xiong
2005-03-08 6:44 ` Greg KH
2005-03-08 18:55 ` Wen Xiong
2005-03-08 23:58 ` Greg KH
2005-03-09 15:47 ` Wen Xiong
2005-03-09 16:35 ` Greg KH
2005-03-09 17:18 ` Wen Xiong
2005-03-09 18:58 ` Greg KH
2005-03-09 16:11 ` Russell King
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox