aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/generic.c4
-rw-r--r--drivers/char/agp/intel-agp.c3
-rw-r--r--drivers/char/amiserial.c62
-rw-r--r--drivers/char/applicom.c1
-rw-r--r--drivers/char/bsr.c2
-rw-r--r--drivers/char/cyclades.c56
-rw-r--r--drivers/char/esp.c2
-rw-r--r--drivers/char/hpet.c24
-rw-r--r--drivers/char/hw_random/timeriomem-rng.c39
-rw-r--r--drivers/char/hw_random/virtio-rng.c4
-rw-r--r--drivers/char/ip2/ip2main.c74
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c223
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c156
-rw-r--r--drivers/char/isicom.c1
-rw-r--r--drivers/char/istallion.c121
-rw-r--r--drivers/char/mem.c27
-rw-r--r--drivers/char/moxa.c9
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/pcmcia/synclink_cs.c73
-rw-r--r--drivers/char/random.c22
-rw-r--r--drivers/char/raw.c1
-rw-r--r--drivers/char/rio/rio_linux.c2
-rw-r--r--drivers/char/riscom8.c2
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/stallion.c126
-rw-r--r--drivers/char/synclink.c98
-rw-r--r--drivers/char/synclink_gt.c132
-rw-r--r--drivers/char/synclinkmp.c74
-rw-r--r--drivers/char/sysrq.c22
-rw-r--r--drivers/char/tty_audit.c2
-rw-r--r--drivers/char/tty_io.c26
-rw-r--r--drivers/char/tty_ldisc.c1
-rw-r--r--drivers/char/vt.c2
-rw-r--r--drivers/char/vt_ioctl.c6
34 files changed, 807 insertions, 592 deletions
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 10d6cbd7c05e..2224b762b7fb 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -1226,7 +1226,7 @@ int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *m
int i, ret = -ENOMEM;
for (i = 0; i < num_pages; i++) {
- page = alloc_page(GFP_KERNEL | GFP_DMA32);
+ page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
/* agp_free_memory() needs gart address */
if (page == NULL)
goto out;
@@ -1257,7 +1257,7 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge)
{
struct page * page;
- page = alloc_page(GFP_KERNEL | GFP_DMA32);
+ page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
if (page == NULL)
return NULL;
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 9d9490e22e07..3686912427ba 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -2131,6 +2131,8 @@ static const struct intel_driver_description {
{ PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, 0, "830M",
&intel_845_driver, &intel_830_driver },
{ PCI_DEVICE_ID_INTEL_82850_HB, 0, 0, "i850", &intel_850_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82854_HB, PCI_DEVICE_ID_INTEL_82854_IG, 0, "854",
+ &intel_845_driver, &intel_830_driver },
{ PCI_DEVICE_ID_INTEL_82855PM_HB, 0, 0, "855PM", &intel_845_driver, NULL },
{ PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, 0, "855GM",
&intel_845_driver, &intel_830_driver },
@@ -2355,6 +2357,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_82845_HB),
ID(PCI_DEVICE_ID_INTEL_82845G_HB),
ID(PCI_DEVICE_ID_INTEL_82850_HB),
+ ID(PCI_DEVICE_ID_INTEL_82854_HB),
ID(PCI_DEVICE_ID_INTEL_82855PM_HB),
ID(PCI_DEVICE_ID_INTEL_82855GM_HB),
ID(PCI_DEVICE_ID_INTEL_82860_HB),
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index a58869ea8513..fd3ebd1be570 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -79,6 +79,7 @@ static char *serial_version = "4.30";
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/bitops.h>
@@ -1825,14 +1826,13 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
* /proc fs routines....
*/
-static inline int line_info(char *buf, struct serial_state *state)
+static inline void line_info(struct seq_file *m, struct serial_state *state)
{
struct async_struct *info = state->info, scr_info;
char stat_buf[30], control, status;
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%d: uart:amiga_builtin",state->line);
+ seq_printf(m, "%d: uart:amiga_builtin",state->line);
/*
* Figure out the current RS-232 lines
@@ -1864,55 +1864,49 @@ static inline int line_info(char *buf, struct serial_state *state)
strcat(stat_buf, "|CD");
if (info->quot) {
- ret += sprintf(buf+ret, " baud:%d",
- state->baud_base / info->quot);
+ seq_printf(m, " baud:%d", state->baud_base / info->quot);
}
- ret += sprintf(buf+ret, " tx:%d rx:%d",
- state->icount.tx, state->icount.rx);
+ seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx);
if (state->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+ seq_printf(m, " fe:%d", state->icount.frame);
if (state->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+ seq_printf(m, " pe:%d", state->icount.parity);
if (state->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
+ seq_printf(m, " brk:%d", state->icount.brk);
if (state->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+ seq_printf(m, " oe:%d", state->icount.overrun);
/*
* Last thing is the RS-232 status lines
*/
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
- return ret;
+ seq_printf(m, " %s\n", stat_buf+1);
}
-static int rs_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
-
- len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
- l = line_info(page + len, &rs_table[0]);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+ seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
+ line_info(m, &rs_table[0]);
+ return 0;
}
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rs_proc_show, NULL);
+}
+
+static const struct file_operations rs_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = rs_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*
* ---------------------------------------------------------------------
* rs_init() and friends
@@ -1951,9 +1945,9 @@ static const struct tty_operations serial_ops = {
.break_ctl = rs_break,
.send_xchar = rs_send_xchar,
.wait_until_sent = rs_wait_until_sent,
- .read_proc = rs_read_proc,
.tiocmget = rs_tiocmget,
.tiocmset = rs_tiocmset,
+ .proc_fops = &rs_proc_fops,
};
/*
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 05674febb0c6..73a0765344b6 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -75,6 +75,7 @@ MODULE_DEVICE_TABLE(pci, applicom_pci_tbl);
MODULE_AUTHOR("David Woodhouse & Applicom International");
MODULE_DESCRIPTION("Driver for Applicom Profibus card");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(AC_MINOR);
MODULE_SUPPORTED_DEVICE("ac");
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index f6094ae0ef33..140ea10ecb88 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -140,7 +140,7 @@ static int bsr_open(struct inode * inode, struct file * filp)
return 0;
}
-const static struct file_operations bsr_fops = {
+static const struct file_operations bsr_fops = {
.owner = THIS_MODULE,
.mmap = bsr_mmap,
.open = bsr_open,
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 6a59f72a9c21..1fdb9f657d8f 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -646,6 +646,7 @@
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/firmware.h>
+#include <linux/device.h>
#include <asm/system.h>
#include <linux/io.h>
@@ -657,6 +658,7 @@
#include <linux/stat.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
static void cy_throttle(struct tty_struct *tty);
static void cy_send_xchar(struct tty_struct *tty, char ch);
@@ -868,8 +870,6 @@ static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
static unsigned detect_isa_irq(void __iomem *);
#endif /* CONFIG_ISA */
-static int cyclades_get_proc_info(char *, char **, off_t, int, int *, void *);
-
#ifndef CONFIG_CYZ_INTR
static void cyz_poll(unsigned long);
@@ -5216,31 +5216,22 @@ static struct pci_driver cy_pci_driver = {
};
#endif
-static int
-cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
- int *eof, void *data)
+static int cyclades_proc_show(struct seq_file *m, void *v)
{
struct cyclades_port *info;
unsigned int i, j;
- int len = 0;
- off_t begin = 0;
- off_t pos = 0;
- int size;
__u32 cur_jifs = jiffies;
- size = sprintf(buf, "Dev TimeOpen BytesOut IdleOut BytesIn "
+ seq_puts(m, "Dev TimeOpen BytesOut IdleOut BytesIn "
"IdleIn Overruns Ldisc\n");
- pos += size;
- len += size;
-
/* Output one line for each known port */
for (i = 0; i < NR_CARDS; i++)
for (j = 0; j < cy_card[i].nports; j++) {
info = &cy_card[i].ports[j];
if (info->port.count)
- size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+ seq_printf(m, "%3d %8lu %10lu %8lu "
"%10lu %8lu %9lu %6ld\n", info->line,
(cur_jifs - info->idle_stats.in_use) /
HZ, info->idle_stats.xmit_bytes,
@@ -5251,30 +5242,26 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
/* FIXME: double check locking */
(long)info->port.tty->ldisc.ops->num);
else
- size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+ seq_printf(m, "%3d %8lu %10lu %8lu "
"%10lu %8lu %9lu %6ld\n",
info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto done;
}
- *eof = 1;
-done:
- *start = buf + (offset - begin); /* Start of wanted data */
- len -= (offset - begin); /* Start slop */
- if (len > length)
- len = length; /* Ending slop */
- if (len < 0)
- len = 0;
- return len;
+ return 0;
+}
+
+static int cyclades_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, cyclades_proc_show, NULL);
}
+static const struct file_operations cyclades_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = cyclades_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/* The serial driver boot-time initialization code!
Hardware I/O ports are mapped to character special devices on a
first found, first allocated manner. That is, this code searches
@@ -5311,9 +5298,9 @@ static const struct tty_operations cy_ops = {
.hangup = cy_hangup,
.break_ctl = cy_break,
.wait_until_sent = cy_wait_until_sent,
- .read_proc = cyclades_get_proc_info,
.tiocmget = cy_tiocmget,
.tiocmset = cy_tiocmset,
+ .proc_fops = &cyclades_proc_fops,
};
static int __init cy_init(void)
@@ -5422,3 +5409,4 @@ module_exit(cy_cleanup_module);
MODULE_LICENSE("GPL");
MODULE_VERSION(CY_VERSION);
+MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR);
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 45ec263ec012..a5c59fc2b0ff 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -2258,7 +2258,7 @@ static int esp_open(struct tty_struct *tty, struct file *filp)
* driver.
*/
-static void show_serial_version(void)
+static void __init show_serial_version(void)
{
printk(KERN_INFO "%s version %s (DMA %u)\n",
serial_name, serial_version, dma);
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 32b8bbf5003e..340ba4f9dc54 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -72,7 +72,7 @@ static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
#ifdef CONFIG_IA64
static void __iomem *hpet_mctr;
-static cycle_t read_hpet(void)
+static cycle_t read_hpet(struct clocksource *cs)
{
return (cycle_t)read_counter((void __iomem *)hpet_mctr);
}
@@ -713,7 +713,7 @@ static struct ctl_table_header *sysctl_header;
*/
#define TICK_CALIBRATE (1000UL)
-static unsigned long hpet_calibrate(struct hpets *hpetp)
+static unsigned long __hpet_calibrate(struct hpets *hpetp)
{
struct hpet_timer __iomem *timer = NULL;
unsigned long t, m, count, i, flags, start;
@@ -750,6 +750,26 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
return (m - start) / i;
}
+static unsigned long hpet_calibrate(struct hpets *hpetp)
+{
+ unsigned long ret = -1;
+ unsigned long tmp;
+
+ /*
+ * Try to calibrate until return value becomes stable small value.
+ * If SMI interruption occurs in calibration loop, the return value
+ * will be big. This avoids its impact.
+ */
+ for ( ; ; ) {
+ tmp = __hpet_calibrate(hpetp);
+ if (ret <= tmp)
+ break;
+ ret = tmp;
+ }
+
+ return ret;
+}
+
int hpet_alloc(struct hpet_data *hdp)
{
u64 cap, mcfg;
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
index 10ad41be5897..dcd352ad0e7f 100644
--- a/drivers/char/hw_random/timeriomem-rng.c
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -90,10 +90,30 @@ static struct hwrng timeriomem_rng_ops = {
static int __init timeriomem_rng_probe(struct platform_device *pdev)
{
+ struct resource *res, *mem;
int ret;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (!res)
+ return -ENOENT;
+
+ mem = request_mem_region(res->start, res->end - res->start + 1,
+ pdev->name);
+ if (mem == NULL)
+ return -EBUSY;
+
+ dev_set_drvdata(&pdev->dev, mem);
+
timeriomem_rng_data = pdev->dev.platform_data;
+ timeriomem_rng_data->address = ioremap(res->start,
+ res->end - res->start + 1);
+ if (!timeriomem_rng_data->address) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
+
if (timeriomem_rng_data->period != 0
&& usecs_to_jiffies(timeriomem_rng_data->period) > 0) {
timeriomem_rng_timer.expires = jiffies;
@@ -104,23 +124,34 @@ static int __init timeriomem_rng_probe(struct platform_device *pdev)
timeriomem_rng_data->present = 1;
ret = hwrng_register(&timeriomem_rng_ops);
- if (ret) {
- dev_err(&pdev->dev, "problem registering\n");
- return ret;
- }
+ if (ret)
+ goto err_register;
dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
timeriomem_rng_data->address,
timeriomem_rng_data->period);
return 0;
+
+err_register:
+ dev_err(&pdev->dev, "problem registering\n");
+ iounmap(timeriomem_rng_data->address);
+err_ioremap:
+ release_resource(mem);
+
+ return ret;
}
static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
{
+ struct resource *mem = dev_get_drvdata(&pdev->dev);
+
del_timer_sync(&timeriomem_rng_timer);
hwrng_unregister(&timeriomem_rng_ops);
+ iounmap(timeriomem_rng_data->address);
+ release_resource(mem);
+
return 0;
}
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index d0e563e4fc39..86e83f883139 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -37,9 +37,9 @@ static void random_recv_done(struct virtqueue *vq)
{
int len;
- /* We never get spurious callbacks. */
+ /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
if (!vq->vq_ops->get_buf(vq, &len))
- BUG();
+ return;
data_left = len / sizeof(random_data[0]);
complete(&have_data);
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 70e0ebc30bd0..afd9247cf082 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -139,7 +139,7 @@
#include <linux/seq_file.h>
static const struct file_operations ip2mem_proc_fops;
-static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
+static const struct file_operations ip2_proc_fops;
/********************/
/* Type Definitions */
@@ -446,9 +446,9 @@ static const struct tty_operations ip2_ops = {
.stop = ip2_stop,
.start = ip2_start,
.hangup = ip2_hangup,
- .read_proc = ip2_read_proc,
.tiocmget = ip2_tiocmget,
.tiocmset = ip2_tiocmset,
+ .proc_fops = &ip2_proc_fops,
};
/******************************************************************************/
@@ -3029,19 +3029,17 @@ static const struct file_operations ip2mem_proc_fops = {
* different sources including ip2mkdev.c and a couple of other drivers.
* The bugs are all mine. :-) =mhw=
*/
-static int ip2_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int ip2_proc_show(struct seq_file *m, void *v)
{
int i, j, box;
- int len = 0;
int boxes = 0;
int ports = 0;
int tports = 0;
- off_t begin = 0;
i2eBordStrPtr pB;
+ char *sep;
- len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
- len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
+ seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion);
+ seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
@@ -3053,7 +3051,8 @@ static int ip2_read_proc(char *page, char **start, off_t off,
switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
{
case POR_ID_FIIEX:
- len += sprintf( page+len, "Board %d: EX ports=", i );
+ seq_printf(m, "Board %d: EX ports=", i);
+ sep = "";
for( box = 0; box < ABS_MAX_BOXES; ++box )
{
ports = 0;
@@ -3065,79 +3064,74 @@ static int ip2_read_proc(char *page, char **start, off_t off,
++ports;
}
}
- len += sprintf( page+len, "%d,", ports );
+ seq_printf(m, "%s%d", sep, ports);
+ sep = ",";
tports += ports;
}
-
- --len; /* Backup over that last comma */
-
- len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
+ seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8);
break;
case POR_ID_II_4:
- len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
+ seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i);
tports = ports = 4;
break;
case POR_ID_II_8:
- len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
+ seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i);
tports = ports = 8;
break;
case POR_ID_II_8R:
- len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
+ seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i);
tports = ports = 8;
break;
default:
- len += sprintf(page+len, "Board %d: unknown", i );
+ seq_printf(m, "Board %d: unknown", i);
/* Don't try and probe for minor numbers */
tports = ports = 0;
}
} else {
/* Don't try and probe for minor numbers */
- len += sprintf(page+len, "Board %d: vacant", i );
+ seq_printf(m, "Board %d: vacant", i);
tports = ports = 0;
}
if( tports ) {
- len += sprintf(page+len, " minors=" );
-
+ seq_puts(m, " minors=");
+ sep = "";
for ( box = 0; box < ABS_MAX_BOXES; ++box )
{
for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
{
if ( pB->i2eChannelMap[box] & (1 << j) )
{
- len += sprintf (page+len,"%d,",
+ seq_printf(m, "%s%d", sep,
j + ABS_BIGGEST_BOX *
(box+i*ABS_MAX_BOXES));
+ sep = ",";
}
}
}
-
- page[ len - 1 ] = '\n'; /* Overwrite that last comma */
- } else {
- len += sprintf (page+len,"\n" );
- }
-
- if (len+begin > off+count)
- break;
- if (len+begin < off) {
- begin += len;
- len = 0;
}
+ seq_putc(m, '\n');
}
+ return 0;
+ }
- if (i >= IP2_MAX_BOARDS)
- *eof = 1;
- if (off >= len+begin)
- return 0;
+static int ip2_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ip2_proc_show, NULL);
+}
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
- }
+static const struct file_operations ip2_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ip2_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
/******************************************************************************/
/* Function: ip2trace() */
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 7a88dfd4427b..aa83a0865ec1 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -285,6 +285,11 @@ enum ipmi_stat_indexes {
/* Events that were received with the proper format. */
IPMI_STAT_events,
+ /* Retransmissions on IPMB that failed. */
+ IPMI_STAT_dropped_rexmit_ipmb_commands,
+
+ /* Retransmissions on LAN that failed. */
+ IPMI_STAT_dropped_rexmit_lan_commands,
/* This *must* remain last, add new values above this. */
IPMI_NUM_STATS
@@ -445,6 +450,20 @@ static DEFINE_MUTEX(smi_watchers_mutex);
#define ipmi_get_stat(intf, stat) \
((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
+static int is_lan_addr(struct ipmi_addr *addr)
+{
+ return addr->addr_type == IPMI_LAN_ADDR_TYPE;
+}
+
+static int is_ipmb_addr(struct ipmi_addr *addr)
+{
+ return addr->addr_type == IPMI_IPMB_ADDR_TYPE;
+}
+
+static int is_ipmb_bcast_addr(struct ipmi_addr *addr)
+{
+ return addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE;
+}
static void free_recv_msg_list(struct list_head *q)
{
@@ -601,8 +620,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
return (smi_addr1->lun == smi_addr2->lun);
}
- if ((addr1->addr_type == IPMI_IPMB_ADDR_TYPE)
- || (addr1->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+ if (is_ipmb_addr(addr1) || is_ipmb_bcast_addr(addr1)) {
struct ipmi_ipmb_addr *ipmb_addr1
= (struct ipmi_ipmb_addr *) addr1;
struct ipmi_ipmb_addr *ipmb_addr2
@@ -612,7 +630,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
&& (ipmb_addr1->lun == ipmb_addr2->lun));
}
- if (addr1->addr_type == IPMI_LAN_ADDR_TYPE) {
+ if (is_lan_addr(addr1)) {
struct ipmi_lan_addr *lan_addr1
= (struct ipmi_lan_addr *) addr1;
struct ipmi_lan_addr *lan_addr2
@@ -644,14 +662,13 @@ int ipmi_validate_addr(struct ipmi_addr *addr, int len)
|| (addr->channel < 0))
return -EINVAL;
- if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
- || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+ if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
if (len < sizeof(struct ipmi_ipmb_addr))
return -EINVAL;
return 0;
}
- if (addr->addr_type == IPMI_LAN_ADDR_TYPE) {
+ if (is_lan_addr(addr)) {
if (len < sizeof(struct ipmi_lan_addr))
return -EINVAL;
return 0;
@@ -1503,8 +1520,7 @@ static int i_ipmi_request(ipmi_user_t user,
memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);
smi_msg->data_size = msg->data_len + 2;
ipmi_inc_stat(intf, sent_local_commands);
- } else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
- || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+ } else if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
struct ipmi_ipmb_addr *ipmb_addr;
unsigned char ipmb_seq;
long seqid;
@@ -1583,8 +1599,6 @@ static int i_ipmi_request(ipmi_user_t user,
spin_lock_irqsave(&(intf->seq_lock), flags);
- ipmi_inc_stat(intf, sent_ipmb_commands);
-
/*
* Create a sequence number with a 1 second
* timeout and 4 retries.
@@ -1606,6 +1620,8 @@ static int i_ipmi_request(ipmi_user_t user,
goto out_err;
}
+ ipmi_inc_stat(intf, sent_ipmb_commands);
+
/*
* Store the sequence number in the message,
* so that when the send message response
@@ -1635,7 +1651,7 @@ static int i_ipmi_request(ipmi_user_t user,
*/
spin_unlock_irqrestore(&(intf->seq_lock), flags);
}
- } else if (addr->addr_type == IPMI_LAN_ADDR_TYPE) {
+ } else if (is_lan_addr(addr)) {
struct ipmi_lan_addr *lan_addr;
unsigned char ipmb_seq;
long seqid;
@@ -1696,8 +1712,6 @@ static int i_ipmi_request(ipmi_user_t user,
spin_lock_irqsave(&(intf->seq_lock), flags);
- ipmi_inc_stat(intf, sent_lan_commands);
-
/*
* Create a sequence number with a 1 second
* timeout and 4 retries.
@@ -1719,6 +1733,8 @@ static int i_ipmi_request(ipmi_user_t user,
goto out_err;
}
+ ipmi_inc_stat(intf, sent_lan_commands);
+
/*
* Store the sequence number in the message,
* so that when the send message response
@@ -1937,6 +1953,10 @@ static int stat_file_read_proc(char *page, char **start, off_t off,
ipmi_get_stat(intf, invalid_events));
out += sprintf(out, "events: %u\n",
ipmi_get_stat(intf, events));
+ out += sprintf(out, "failed rexmit LAN msgs: %u\n",
+ ipmi_get_stat(intf, dropped_rexmit_lan_commands));
+ out += sprintf(out, "failed rexmit IPMB msgs: %u\n",
+ ipmi_get_stat(intf, dropped_rexmit_ipmb_commands));
return (out - ((char *) page));
}
@@ -1944,7 +1964,7 @@ static int stat_file_read_proc(char *page, char **start, off_t off,
int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
read_proc_t *read_proc,
- void *data, struct module *owner)
+ void *data)
{
int rv = 0;
#ifdef CONFIG_PROC_FS
@@ -1970,7 +1990,6 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
} else {
file->data = data;
file->read_proc = read_proc;
- file->owner = owner;
mutex_lock(&smi->proc_entry_lock);
/* Stick it on the list. */
@@ -1993,23 +2012,21 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
if (!smi->proc_dir)
rv = -ENOMEM;
- else
- smi->proc_dir->owner = THIS_MODULE;
if (rv == 0)
rv = ipmi_smi_add_proc_entry(smi, "stats",
stat_file_read_proc,
- smi, THIS_MODULE);
+ smi);
if (rv == 0)
rv = ipmi_smi_add_proc_entry(smi, "ipmb",
ipmb_file_read_proc,
- smi, THIS_MODULE);
+ smi);
if (rv == 0)
rv = ipmi_smi_add_proc_entry(smi, "version",
version_file_read_proc,
- smi, THIS_MODULE);
+ smi);
#endif /* CONFIG_PROC_FS */
return rv;
@@ -3267,6 +3284,114 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
return rv;
}
+/*
+ * This routine will handle "Get Message" command responses with
+ * channels that use an OEM Medium. The message format belongs to
+ * the OEM. See IPMI 2.0 specification, Chapter 6 and
+ * Chapter 22, sections 22.6 and 22.24 for more details.
+ */
+static int handle_oem_get_msg_cmd(ipmi_smi_t intf,
+ struct ipmi_smi_msg *msg)
+{
+ struct cmd_rcvr *rcvr;
+ int rv = 0;
+ unsigned char netfn;
+ unsigned char cmd;
+ unsigned char chan;
+ ipmi_user_t user = NULL;
+ struct ipmi_system_interface_addr *smi_addr;
+ struct ipmi_recv_msg *recv_msg;
+
+ /*
+ * We expect the OEM SW to perform error checking
+ * so we just do some basic sanity checks
+ */
+ if (msg->rsp_size < 4) {
+ /* Message not big enough, just ignore it. */
+ ipmi_inc_stat(intf, invalid_commands);
+ return 0;
+ }
+
+ if (msg->rsp[2] != 0) {
+ /* An error getting the response, just ignore it. */
+ return 0;
+ }
+
+ /*
+ * This is an OEM Message so the OEM needs to know how
+ * handle the message. We do no interpretation.
+ */
+ netfn = msg->rsp[0] >> 2;
+ cmd = msg->rsp[1];
+ chan = msg->rsp[3] & 0xf;
+
+ rcu_read_lock();
+ rcvr = find_cmd_rcvr(intf, netfn, cmd, chan);
+ if (rcvr) {
+ user = rcvr->user;
+ kref_get(&user->refcount);
+ } else
+ user = NULL;
+ rcu_read_unlock();
+
+ if (user == NULL) {
+ /* We didn't find a user, just give up. */
+ ipmi_inc_stat(intf, unhandled_commands);
+
+ /*
+ * Don't do anything with these messages, just allow
+ * them to be freed.
+ */
+
+ rv = 0;
+ } else {
+ /* Deliver the message to the user. */
+ ipmi_inc_stat(intf, handled_commands);
+
+ recv_msg = ipmi_alloc_recv_msg();
+ if (!recv_msg) {
+ /*
+ * We couldn't allocate memory for the
+ * message, so requeue it for handling
+ * later.
+ */
+ rv = 1;
+ kref_put(&user->refcount, free_user);
+ } else {
+ /*
+ * OEM Messages are expected to be delivered via
+ * the system interface to SMS software. We might
+ * need to visit this again depending on OEM
+ * requirements
+ */
+ smi_addr = ((struct ipmi_system_interface_addr *)
+ &(recv_msg->addr));
+ smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+ smi_addr->channel = IPMI_BMC_CHANNEL;
+ smi_addr->lun = msg->rsp[0] & 3;
+
+ recv_msg->user = user;
+ recv_msg->user_msg_data = NULL;
+ recv_msg->recv_type = IPMI_OEM_RECV_TYPE;
+ recv_msg->msg.netfn = msg->rsp[0] >> 2;
+ recv_msg->msg.cmd = msg->rsp[1];
+ recv_msg->msg.data = recv_msg->msg_data;
+
+ /*
+ * The message starts at byte 4 which follows the
+ * the Channel Byte in the "GET MESSAGE" command
+ */
+ recv_msg->msg.data_len = msg->rsp_size - 4;
+ memcpy(recv_msg->msg_data,
+ &(msg->rsp[4]),
+ msg->rsp_size - 4);
+ deliver_response(recv_msg);
+ }
+ }
+
+ return rv;
+}
+
static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg,
struct ipmi_smi_msg *msg)
{
@@ -3522,6 +3647,17 @@ static int handle_new_recv_msg(ipmi_smi_t intf,
goto out;
}
+ /*
+ ** We need to make sure the channels have been initialized.
+ ** The channel_handler routine will set the "curr_channel"
+ ** equal to or greater than IPMI_MAX_CHANNELS when all the
+ ** channels for this interface have been initialized.
+ */
+ if (intf->curr_channel < IPMI_MAX_CHANNELS) {
+ requeue = 1; /* Just put the message back for now */
+ goto out;
+ }
+
switch (intf->channels[chan].medium) {
case IPMI_CHANNEL_MEDIUM_IPMB:
if (msg->rsp[4] & 0x04) {
@@ -3557,11 +3693,20 @@ static int handle_new_recv_msg(ipmi_smi_t intf,
break;
default:
- /*
- * We don't handle the channel type, so just
- * free the message.
- */
- requeue = 0;
+ /* Check for OEM Channels. Clients had better
+ register for these commands. */
+ if ((intf->channels[chan].medium
+ >= IPMI_CHANNEL_MEDIUM_OEM_MIN)
+ && (intf->channels[chan].medium
+ <= IPMI_CHANNEL_MEDIUM_OEM_MAX)) {
+ requeue = handle_oem_get_msg_cmd(intf, msg);
+ } else {
+ /*
+ * We don't handle the channel type, so just
+ * free the message.
+ */
+ requeue = 0;
+ }
}
} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
@@ -3733,7 +3878,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
list_add_tail(&msg->link, timeouts);
if (ent->broadcast)
ipmi_inc_stat(intf, timed_out_ipmb_broadcasts);
- else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
+ else if (is_lan_addr(&ent->recv_msg->addr))
ipmi_inc_stat(intf, timed_out_lan_commands);
else
ipmi_inc_stat(intf, timed_out_ipmb_commands);
@@ -3747,15 +3892,17 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
*/
ent->timeout = MAX_MSG_TIMEOUT;
ent->retries_left--;
- if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
- ipmi_inc_stat(intf, retransmitted_lan_commands);
- else
- ipmi_inc_stat(intf, retransmitted_ipmb_commands);
-
smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
ent->seqid);
- if (!smi_msg)
+ if (!smi_msg) {
+ if (is_lan_addr(&ent->recv_msg->addr))
+ ipmi_inc_stat(intf,
+ dropped_rexmit_lan_commands);
+ else
+ ipmi_inc_stat(intf,
+ dropped_rexmit_ipmb_commands);
return;
+ }
spin_unlock_irqrestore(&intf->seq_lock, *flags);
@@ -3767,10 +3914,17 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
* resent.
*/
handlers = intf->handlers;
- if (handlers)
+ if (handlers) {
+ if (is_lan_addr(&ent->recv_msg->addr))
+ ipmi_inc_stat(intf,
+ retransmitted_lan_commands);
+ else
+ ipmi_inc_stat(intf,
+ retransmitted_ipmb_commands);
+
intf->handlers->sender(intf->send_info,
smi_msg, 0);
- else
+ } else
ipmi_free_smi_msg(smi_msg);
spin_lock_irqsave(&intf->seq_lock, *flags);
@@ -4265,7 +4419,6 @@ static int ipmi_init_msghandler(void)
return -ENOMEM;
}
- proc_ipmi_root->owner = THIS_MODULE;
#endif /* CONFIG_PROC_FS */
setup_timer(&ipmi_timer, ipmi_timeout, 0);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 3000135f2ead..259644646b82 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -82,12 +82,6 @@
#define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a
short timeout */
-/* Bit for BMC global enables. */
-#define IPMI_BMC_RCV_MSG_INTR 0x01
-#define IPMI_BMC_EVT_MSG_INTR 0x02
-#define IPMI_BMC_EVT_MSG_BUFF 0x04
-#define IPMI_BMC_SYS_LOG 0x08
-
enum si_intf_state {
SI_NORMAL,
SI_GETTING_FLAGS,
@@ -220,6 +214,9 @@ struct smi_info {
OEM2_DATA_AVAIL)
unsigned char msg_flags;
+ /* Does the BMC have an event buffer? */
+ char has_event_buffer;
+
/*
* If set to true, this will request events the next time the
* state machine is idle.
@@ -968,7 +965,8 @@ static void request_events(void *send_info)
{
struct smi_info *smi_info = send_info;
- if (atomic_read(&smi_info->stop_operation))
+ if (atomic_read(&smi_info->stop_operation) ||
+ !smi_info->has_event_buffer)
return;
atomic_set(&smi_info->req_events, 1);
@@ -2407,26 +2405,9 @@ static struct of_platform_driver ipmi_of_platform_driver = {
};
#endif /* CONFIG_PPC_OF */
-
-static int try_get_dev_id(struct smi_info *smi_info)
+static int wait_for_msg_done(struct smi_info *smi_info)
{
- unsigned char msg[2];
- unsigned char *resp;
- unsigned long resp_len;
enum si_sm_result smi_result;
- int rv = 0;
-
- resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
- if (!resp)
- return -ENOMEM;
-
- /*
- * Do a Get Device ID command, since it comes back with some
- * useful info.
- */
- msg[0] = IPMI_NETFN_APP_REQUEST << 2;
- msg[1] = IPMI_GET_DEVICE_ID_CMD;
- smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
for (;;) {
@@ -2441,16 +2422,39 @@ static int try_get_dev_id(struct smi_info *smi_info)
} else
break;
}
- if (smi_result == SI_SM_HOSED) {
+ if (smi_result == SI_SM_HOSED)
/*
* We couldn't get the state machine to run, so whatever's at
* the port is probably not an IPMI SMI interface.
*/
- rv = -ENODEV;
+ return -ENODEV;
+
+ return 0;
+}
+
+static int try_get_dev_id(struct smi_info *smi_info)
+{
+ unsigned char msg[2];
+ unsigned char *resp;
+ unsigned long resp_len;
+ int rv = 0;
+
+ resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
+ if (!resp)
+ return -ENOMEM;
+
+ /*
+ * Do a Get Device ID command, since it comes back with some
+ * useful info.
+ */
+ msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+ msg[1] = IPMI_GET_DEVICE_ID_CMD;
+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
+
+ rv = wait_for_msg_done(smi_info);
+ if (rv)
goto out;
- }
- /* Otherwise, we got some data. */
resp_len = smi_info->handlers->get_result(smi_info->si_sm,
resp, IPMI_MAX_MSG_LENGTH);
@@ -2462,6 +2466,88 @@ static int try_get_dev_id(struct smi_info *smi_info)
return rv;
}
+static int try_enable_event_buffer(struct smi_info *smi_info)
+{
+ unsigned char msg[3];
+ unsigned char *resp;
+ unsigned long resp_len;
+ int rv = 0;
+
+ resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
+ if (!resp)
+ return -ENOMEM;
+
+ msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+ msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
+
+ rv = wait_for_msg_done(smi_info);
+ if (rv) {
+ printk(KERN_WARNING
+ "ipmi_si: Error getting response from get global,"
+ " enables command, the event buffer is not"
+ " enabled.\n");
+ goto out;
+ }
+
+ resp_len = smi_info->handlers->get_result(smi_info->si_sm,
+ resp, IPMI_MAX_MSG_LENGTH);
+
+ if (resp_len < 4 ||
+ resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
+ resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD ||
+ resp[2] != 0) {
+ printk(KERN_WARNING
+ "ipmi_si: Invalid return from get global"
+ " enables command, cannot enable the event"
+ " buffer.\n");
+ rv = -EINVAL;
+ goto out;
+ }
+
+ if (resp[3] & IPMI_BMC_EVT_MSG_BUFF)
+ /* buffer is already enabled, nothing to do. */
+ goto out;
+
+ msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+ msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
+ msg[2] = resp[3] | IPMI_BMC_EVT_MSG_BUFF;
+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
+
+ rv = wait_for_msg_done(smi_info);
+ if (rv) {
+ printk(KERN_WARNING
+ "ipmi_si: Error getting response from set global,"
+ " enables command, the event buffer is not"
+ " enabled.\n");
+ goto out;
+ }
+
+ resp_len = smi_info->handlers->get_result(smi_info->si_sm,
+ resp, IPMI_MAX_MSG_LENGTH);
+
+ if (resp_len < 3 ||
+ resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
+ resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) {
+ printk(KERN_WARNING
+ "ipmi_si: Invalid return from get global,"
+ "enables command, not enable the event"
+ " buffer.\n");
+ rv = -EINVAL;
+ goto out;
+ }
+
+ if (resp[2] != 0)
+ /*
+ * An error when setting the event buffer bit means
+ * that the event buffer is not supported.
+ */
+ rv = -ENOENT;
+ out:
+ kfree(resp);
+ return rv;
+}
+
static int type_file_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -2847,6 +2933,10 @@ static int try_smi_init(struct smi_info *new_smi)
new_smi->intf_num = smi_num;
smi_num++;
+ rv = try_enable_event_buffer(new_smi);
+ if (rv == 0)
+ new_smi->has_event_buffer = 1;
+
/*
* Start clearing the flags before we enable interrupts or the
* timer to avoid racing with the timer.
@@ -2863,7 +2953,7 @@ static int try_smi_init(struct smi_info *new_smi)
*/
new_smi->pdev = platform_device_alloc("ipmi_si",
new_smi->intf_num);
- if (rv) {
+ if (!new_smi->pdev) {
printk(KERN_ERR
"ipmi_si_intf:"
" Unable to allocate platform device\n");
@@ -2899,7 +2989,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
type_file_read_proc,
- new_smi, THIS_MODULE);
+ new_smi);
if (rv) {
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
@@ -2909,7 +2999,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
stat_file_read_proc,
- new_smi, THIS_MODULE);
+ new_smi);
if (rv) {
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
@@ -2919,7 +3009,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv = ipmi_smi_add_proc_entry(new_smi->intf, "params",
param_read_proc,
- new_smi, THIS_MODULE);
+ new_smi);
if (rv) {
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 24aa6e88e223..a59eac584d16 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -925,6 +925,7 @@ static void isicom_shutdown_port(struct isi_port *port)
if (!card->count)
isicom_shutdown_board(card);
}
+ tty_kref_put(tty);
}
static void isicom_flush_buffer(struct tty_struct *tty)
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 5c3dc6b8411c..fff19f7e29d2 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -24,6 +24,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
+#include <linux/seq_file.h>
#include <linux/cdk.h>
#include <linux/comstats.h>
#include <linux/istallion.h>
@@ -613,7 +614,6 @@ static int stli_breakctl(struct tty_struct *tty, int state);
static void stli_waituntilsent(struct tty_struct *tty, int timeout);
static void stli_sendxchar(struct tty_struct *tty, char ch);
static void stli_hangup(struct tty_struct *tty);
-static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos);
static int stli_brdinit(struct stlibrd *brdp);
static int stli_startbrd(struct stlibrd *brdp);
@@ -1893,20 +1893,10 @@ static void stli_sendxchar(struct tty_struct *tty, char ch)
stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
}
-/*****************************************************************************/
-
-#define MAXLINE 80
-
-/*
- * Format info for a specified port. The line is deliberately limited
- * to 80 characters. (If it is too long it will be truncated, if too
- * short then padded with spaces).
- */
-
-static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos)
+static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr)
{
- char *sp, *uart;
- int rc, cnt;
+ char *uart;
+ int rc;
rc = stli_portcmdstats(NULL, portp);
@@ -1918,44 +1908,50 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn
default:uart = "CD1400"; break;
}
}
-
- sp = pos;
- sp += sprintf(sp, "%d: uart:%s ", portnr, uart);
+ seq_printf(m, "%d: uart:%s ", portnr, uart);
if ((brdp->state & BST_STARTED) && (rc >= 0)) {
- sp += sprintf(sp, "tx:%d rx:%d", (int) stli_comstats.txtotal,
+ char sep;
+
+ seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal,
(int) stli_comstats.rxtotal);
if (stli_comstats.rxframing)
- sp += sprintf(sp, " fe:%d",
+ seq_printf(m, " fe:%d",
(int) stli_comstats.rxframing);
if (stli_comstats.rxparity)
- sp += sprintf(sp, " pe:%d",
+ seq_printf(m, " pe:%d",
(int) stli_comstats.rxparity);
if (stli_comstats.rxbreaks)
- sp += sprintf(sp, " brk:%d",
+ seq_printf(m, " brk:%d",
(int) stli_comstats.rxbreaks);
if (stli_comstats.rxoverrun)
- sp += sprintf(sp, " oe:%d",
+ seq_printf(m, " oe:%d",
(int) stli_comstats.rxoverrun);
- cnt = sprintf(sp, "%s%s%s%s%s ",
- (stli_comstats.signals & TIOCM_RTS) ? "|RTS" : "",
- (stli_comstats.signals & TIOCM_CTS) ? "|CTS" : "",
- (stli_comstats.signals & TIOCM_DTR) ? "|DTR" : "",
- (stli_comstats.signals & TIOCM_CD) ? "|DCD" : "",
- (stli_comstats.signals & TIOCM_DSR) ? "|DSR" : "");
- *sp = ' ';
- sp += cnt;
+ sep = ' ';
+ if (stli_comstats.signals & TIOCM_RTS) {
+ seq_printf(m, "%c%s", sep, "RTS");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_CTS) {
+ seq_printf(m, "%c%s", sep, "CTS");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_DTR) {
+ seq_printf(m, "%c%s", sep, "DTR");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_CD) {
+ seq_printf(m, "%c%s", sep, "DCD");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_DSR) {
+ seq_printf(m, "%c%s", sep, "DSR");
+ sep = '|';
+ }
}
-
- for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++)
- *sp++ = ' ';
- if (cnt >= MAXLINE)
- pos[(MAXLINE - 2)] = '+';
- pos[(MAXLINE - 1)] = '\n';
-
- return(MAXLINE);
+ seq_putc(m, '\n');
}
/*****************************************************************************/
@@ -1964,26 +1960,15 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn
* Port info, read from the /proc file system.
*/
-static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int stli_proc_show(struct seq_file *m, void *v)
{
struct stlibrd *brdp;
struct stliport *portp;
unsigned int brdnr, portnr, totalport;
- int curoff, maxoff;
- char *pos;
- pos = page;
totalport = 0;
- curoff = 0;
-
- if (off == 0) {
- pos += sprintf(pos, "%s: version %s", stli_drvtitle,
- stli_drvversion);
- while (pos < (page + MAXLINE - 1))
- *pos++ = ' ';
- *pos++ = '\n';
- }
- curoff = MAXLINE;
+
+ seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion);
/*
* We scan through for each board, panel and port. The offset is
@@ -1996,33 +1981,31 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo
if (brdp->state == 0)
continue;
- maxoff = curoff + (brdp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- continue;
- }
-
totalport = brdnr * STL_MAXPORTS;
for (portnr = 0; (portnr < brdp->nrports); portnr++,
totalport++) {
portp = brdp->ports[portnr];
if (portp == NULL)
continue;
- if (off >= (curoff += MAXLINE))
- continue;
- if ((pos - page + MAXLINE) > count)
- goto stli_readdone;
- pos += stli_portinfo(brdp, portp, totalport, pos);
+ stli_portinfo(m, brdp, portp, totalport);
}
}
+ return 0;
+}
- *eof = 1;
-
-stli_readdone:
- *start = page;
- return(pos - page);
+static int stli_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, stli_proc_show, NULL);
}
+static const struct file_operations stli_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = stli_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*****************************************************************************/
/*
@@ -4427,9 +4410,9 @@ static const struct tty_operations stli_ops = {
.break_ctl = stli_breakctl,
.wait_until_sent = stli_waituntilsent,
.send_xchar = stli_sendxchar,
- .read_proc = stli_readproc,
.tiocmget = stli_tiocmget,
.tiocmset = stli_tiocmset,
+ .proc_fops = &stli_proc_fops,
};
static const struct tty_port_operations stli_port_ops = {
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 3586b3b3df3f..8f05c38c2f06 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -301,33 +301,7 @@ static inline int private_mapping_ok(struct vm_area_struct *vma)
}
#endif
-void __attribute__((weak))
-map_devmem(unsigned long pfn, unsigned long len, pgprot_t prot)
-{
- /* nothing. architectures can override. */
-}
-
-void __attribute__((weak))
-unmap_devmem(unsigned long pfn, unsigned long len, pgprot_t prot)
-{
- /* nothing. architectures can override. */
-}
-
-static void mmap_mem_open(struct vm_area_struct *vma)
-{
- map_devmem(vma->vm_pgoff, vma->vm_end - vma->vm_start,
- vma->vm_page_prot);
-}
-
-static void mmap_mem_close(struct vm_area_struct *vma)
-{
- unmap_devmem(vma->vm_pgoff, vma->vm_end - vma->vm_start,
- vma->vm_page_prot);
-}
-
static struct vm_operations_struct mmap_mem_ops = {
- .open = mmap_mem_open,
- .close = mmap_mem_close,
#ifdef CONFIG_HAVE_IOREMAP_PROT
.access = generic_access_phys
#endif
@@ -362,7 +336,6 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
vma->vm_pgoff,
size,
vma->vm_page_prot)) {
- unmap_devmem(vma->vm_pgoff, size, vma->vm_page_prot);
return -EAGAIN;
}
return 0;
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 8b0da97d5293..4a4cab73d0be 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -1486,11 +1486,11 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
}
if (!handle) /* nothing else to do */
- return 0;
+ goto put;
intr = readw(ip); /* port irq status */
if (intr == 0)
- return 0;
+ goto put;
writew(0, ip); /* ACK port */
ofsAddr = p->tableAddr;
@@ -1499,16 +1499,17 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
ofsAddr + HostStat);
if (!inited)
- return 0;
+ goto put;
if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
tty_insert_flip_char(tty, 0, TTY_BREAK);
tty_schedule_flip(tty);
}
- tty_kref_put(tty);
if (intr & IntrLine)
moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
+put:
+ tty_kref_put(tty);
return 0;
}
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 402c9f217f83..a420e8d437dd 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -820,7 +820,6 @@ static void mxser_check_modem_status(struct tty_struct *tty,
wake_up_interruptible(&port->port.open_wait);
}
- tty = tty_port_tty_get(&port->port);
if (port->port.flags & ASYNC_CTS_FLOW) {
if (tty->hw_stopped) {
if (status & UART_MSR_CTS) {
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 5608a1e5a3b3..19d79fc54461 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -51,6 +51,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
@@ -2619,13 +2620,12 @@ cleanup:
* /proc fs routines....
*/
-static inline int line_info(char *buf, MGSLPC_INFO *info)
+static inline void line_info(struct seq_file *m, MGSLPC_INFO *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%s:io:%04X irq:%d",
+ seq_printf(m, "%s:io:%04X irq:%d",
info->device_name, info->io_base, info->irq_level);
/* output current serial signal states */
@@ -2649,75 +2649,70 @@ static inline int line_info(char *buf, MGSLPC_INFO *info)
strcat(stat_buf, "|RI");
if (info->params.mode == MGSL_MODE_HDLC) {
- ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
+ seq_printf(m, " HDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+ seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
+ seq_printf(m, " ASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
-
- return ret;
}
/* Called to print information about devices
*/
-static int mgslpc_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int mgslpc_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
MGSLPC_INFO *info;
- len += sprintf(page, "synclink driver:%s\n", driver_version);
+ seq_printf(m, "synclink driver:%s\n", driver_version);
info = mgslpc_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+static int mgslpc_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mgslpc_proc_show, NULL);
}
+static const struct file_operations mgslpc_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = mgslpc_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static int rx_alloc_buffers(MGSLPC_INFO *info)
{
/* each buffer has header and data */
@@ -2861,13 +2856,13 @@ static const struct tty_operations mgslpc_ops = {
.send_xchar = mgslpc_send_xchar,
.break_ctl = mgslpc_break,
.wait_until_sent = mgslpc_wait_until_sent,
- .read_proc = mgslpc_read_proc,
.set_termios = mgslpc_set_termios,
.stop = tx_pause,
.start = tx_release,
.hangup = mgslpc_hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &mgslpc_proc_fops,
};
static void synclink_cs_cleanup(void)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7c43ae782b26..b2ced39d76b2 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1488,7 +1488,8 @@ static void rekey_seq_generator(struct work_struct *work)
keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS;
smp_wmb();
ip_cnt++;
- schedule_delayed_work(&rekey_work, REKEY_INTERVAL);
+ schedule_delayed_work(&rekey_work,
+ round_jiffies_relative(REKEY_INTERVAL));
}
static inline struct keydata *get_keyptr(void)
@@ -1664,15 +1665,20 @@ EXPORT_SYMBOL(secure_dccp_sequence_number);
* value is not cryptographically secure but for several uses the cost of
* depleting entropy is too high
*/
+DEFINE_PER_CPU(__u32 [4], get_random_int_hash);
unsigned int get_random_int(void)
{
- /*
- * Use IP's RNG. It suits our purpose perfectly: it re-keys itself
- * every second, from the entropy pool (and thus creates a limited
- * drain on it), and uses halfMD4Transform within the second. We
- * also mix it with jiffies and the PID:
- */
- return secure_ip_id((__force __be32)(current->pid + jiffies));
+ struct keydata *keyptr;
+ __u32 *hash = get_cpu_var(get_random_int_hash);
+ int ret;
+
+ keyptr = get_keyptr();
+ hash[0] += current->pid + jiffies + get_cycles() + (int)(long)&ret;
+
+ ret = half_md4_transform(hash, keyptr->secret);
+ put_cpu_var(get_random_int_hash);
+
+ return ret;
}
/*
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 96adf28a17e4..20d90e6a6e50 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -90,6 +90,7 @@ out1:
blkdev_put(bdev, filp->f_mode);
out:
mutex_unlock(&raw_mutex);
+ unlock_kernel();
return err;
}
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 2e8a6eed34be..ce81da5b2da9 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -333,7 +333,7 @@ void rio_copy_to_card(void *from, void __iomem *to, int len)
int rio_minor(struct tty_struct *tty)
{
- return tty->index + (tty->driver == rio_driver) ? 0 : 256;
+ return tty->index + ((tty->driver == rio_driver) ? 0 : 256);
}
static int rio_set_real_termios(void *ptr)
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 9af8d74875bc..217660451237 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -48,6 +48,7 @@
#include <linux/delay.h>
#include <linux/tty_flip.h>
#include <linux/spinlock.h>
+#include <linux/device.h>
#include <linux/uaccess.h>
@@ -1524,6 +1525,7 @@ module_param(iobase2, int, 0);
module_param(iobase3, int, 0);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR);
#endif /* MODULE */
/*
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 3c67c3d83de9..e72be4190a44 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -2365,3 +2365,4 @@ module_init(specialix_init_module);
module_exit(specialix_exit_module);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR);
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index e1e0dd89ac9a..2ad813a801dc 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -32,6 +32,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
+#include <linux/seq_file.h>
#include <linux/cd1400.h>
#include <linux/sc26198.h>
#include <linux/comstats.h>
@@ -1379,52 +1380,47 @@ static void stl_sendxchar(struct tty_struct *tty, char ch)
stl_putchar(tty, ch);
}
-/*****************************************************************************/
-
-#define MAXLINE 80
-
-/*
- * Format info for a specified port. The line is deliberately limited
- * to 80 characters. (If it is too long it will be truncated, if too
- * short then padded with spaces).
- */
-
-static int stl_portinfo(struct stlport *portp, int portnr, char *pos)
+static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr)
{
- char *sp;
- int sigs, cnt;
+ int sigs;
+ char sep;
- sp = pos;
- sp += sprintf(sp, "%d: uart:%s tx:%d rx:%d",
+ seq_printf(m, "%d: uart:%s tx:%d rx:%d",
portnr, (portp->hwid == 1) ? "SC26198" : "CD1400",
(int) portp->stats.txtotal, (int) portp->stats.rxtotal);
if (portp->stats.rxframing)
- sp += sprintf(sp, " fe:%d", (int) portp->stats.rxframing);
+ seq_printf(m, " fe:%d", (int) portp->stats.rxframing);
if (portp->stats.rxparity)
- sp += sprintf(sp, " pe:%d", (int) portp->stats.rxparity);
+ seq_printf(m, " pe:%d", (int) portp->stats.rxparity);
if (portp->stats.rxbreaks)
- sp += sprintf(sp, " brk:%d", (int) portp->stats.rxbreaks);
+ seq_printf(m, " brk:%d", (int) portp->stats.rxbreaks);
if (portp->stats.rxoverrun)
- sp += sprintf(sp, " oe:%d", (int) portp->stats.rxoverrun);
+ seq_printf(m, " oe:%d", (int) portp->stats.rxoverrun);
sigs = stl_getsignals(portp);
- cnt = sprintf(sp, "%s%s%s%s%s ",
- (sigs & TIOCM_RTS) ? "|RTS" : "",
- (sigs & TIOCM_CTS) ? "|CTS" : "",
- (sigs & TIOCM_DTR) ? "|DTR" : "",
- (sigs & TIOCM_CD) ? "|DCD" : "",
- (sigs & TIOCM_DSR) ? "|DSR" : "");
- *sp = ' ';
- sp += cnt;
-
- for (cnt = sp - pos; cnt < (MAXLINE - 1); cnt++)
- *sp++ = ' ';
- if (cnt >= MAXLINE)
- pos[(MAXLINE - 2)] = '+';
- pos[(MAXLINE - 1)] = '\n';
-
- return MAXLINE;
+ sep = ' ';
+ if (sigs & TIOCM_RTS) {
+ seq_printf(m, "%c%s", sep, "RTS");
+ sep = '|';
+ }
+ if (sigs & TIOCM_CTS) {
+ seq_printf(m, "%c%s", sep, "CTS");
+ sep = '|';
+ }
+ if (sigs & TIOCM_DTR) {
+ seq_printf(m, "%c%s", sep, "DTR");
+ sep = '|';
+ }
+ if (sigs & TIOCM_CD) {
+ seq_printf(m, "%c%s", sep, "DCD");
+ sep = '|';
+ }
+ if (sigs & TIOCM_DSR) {
+ seq_printf(m, "%c%s", sep, "DSR");
+ sep = '|';
+ }
+ seq_putc(m, '\n');
}
/*****************************************************************************/
@@ -1433,30 +1429,17 @@ static int stl_portinfo(struct stlport *portp, int portnr, char *pos)
* Port info, read from the /proc file system.
*/
-static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int stl_proc_show(struct seq_file *m, void *v)
{
struct stlbrd *brdp;
struct stlpanel *panelp;
struct stlport *portp;
unsigned int brdnr, panelnr, portnr;
- int totalport, curoff, maxoff;
- char *pos;
+ int totalport;
- pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p,"
- "data=%p\n", page, start, off, count, eof, data);
-
- pos = page;
totalport = 0;
- curoff = 0;
-
- if (off == 0) {
- pos += sprintf(pos, "%s: version %s", stl_drvtitle,
- stl_drvversion);
- while (pos < (page + MAXLINE - 1))
- *pos++ = ' ';
- *pos++ = '\n';
- }
- curoff = MAXLINE;
+
+ seq_printf(m, "%s: version %s\n", stl_drvtitle, stl_drvversion);
/*
* We scan through for each board, panel and port. The offset is
@@ -1469,46 +1452,37 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof
if (brdp->state == 0)
continue;
- maxoff = curoff + (brdp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- continue;
- }
-
totalport = brdnr * STL_MAXPORTS;
for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) {
panelp = brdp->panels[panelnr];
if (panelp == NULL)
continue;
- maxoff = curoff + (panelp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- totalport += panelp->nrports;
- continue;
- }
-
for (portnr = 0; portnr < panelp->nrports; portnr++,
totalport++) {
portp = panelp->ports[portnr];
if (portp == NULL)
continue;
- if (off >= (curoff += MAXLINE))
- continue;
- if ((pos - page + MAXLINE) > count)
- goto stl_readdone;
- pos += stl_portinfo(portp, totalport, pos);
+ stl_portinfo(m, portp, totalport);
}
}
}
+ return 0;
+}
- *eof = 1;
-
-stl_readdone:
- *start = page;
- return pos - page;
+static int stl_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, stl_proc_show, NULL);
}
+static const struct file_operations stl_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = stl_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*****************************************************************************/
/*
@@ -2566,9 +2540,9 @@ static const struct tty_operations stl_ops = {
.break_ctl = stl_breakctl,
.wait_until_sent = stl_waituntilsent,
.send_xchar = stl_sendxchar,
- .read_proc = stl_readproc,
.tiocmget = stl_tiocmget,
.tiocmset = stl_tiocmset,
+ .proc_fops = &stl_proc_fops,
};
static const struct tty_port_operations stl_port_ops = {
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 0057a8f58cb1..afd0b26ca056 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -79,6 +79,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
@@ -3459,18 +3460,17 @@ cleanup:
* /proc fs routines....
*/
-static inline int line_info(char *buf, struct mgsl_struct *info)
+static inline void line_info(struct seq_file *m, struct mgsl_struct *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
if (info->bus_type == MGSL_BUS_TYPE_PCI) {
- ret = sprintf(buf, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
+ seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
info->device_name, info->io_base, info->irq_level,
info->phys_memory_base, info->phys_lcr_base);
} else {
- ret = sprintf(buf, "%s:(E)ISA io:%04X irq:%d dma:%d",
+ seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d",
info->device_name, info->io_base,
info->irq_level, info->dma_level);
}
@@ -3497,37 +3497,37 @@ static inline int line_info(char *buf, struct mgsl_struct *info)
if (info->params.mode == MGSL_MODE_HDLC ||
info->params.mode == MGSL_MODE_RAW ) {
- ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
+ seq_printf(m, " HDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+ seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
+ seq_printf(m, " ASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
@@ -3544,60 +3544,40 @@ static inline int line_info(char *buf, struct mgsl_struct *info)
u16 Tmr = usc_InReg( info, TMR );
u16 Tccr = usc_InReg( info, TCCR );
u16 Ccar = inw( info->io_base + CCAR );
- ret += sprintf(buf+ret, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n"
+ seq_printf(m, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n"
"ricr=%04X icr =%04X dccr=%04X tmr=%04X tccr=%04X ccar=%04X\n",
Tcsr,Tdmr,Ticr,Rscr,Rdmr,Ricr,Icr,Dccr,Tmr,Tccr,Ccar );
}
spin_unlock_irqrestore(&info->irq_spinlock,flags);
-
- return ret;
-
-} /* end of line_info() */
+}
-/* mgsl_read_proc()
- *
- * Called to print information about devices
- *
- * Arguments:
- * page page of memory to hold returned info
- * start
- * off
- * count
- * eof
- * data
- *
- * Return Value:
- */
-static int mgsl_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+/* Called to print information about devices */
+static int mgsl_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
struct mgsl_struct *info;
- len += sprintf(page, "synclink driver:%s\n", driver_version);
+ seq_printf(m, "synclink driver:%s\n", driver_version);
info = mgsl_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
-
-} /* end of mgsl_read_proc() */
+static int mgsl_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mgsl_proc_show, NULL);
+}
+
+static const struct file_operations mgsl_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = mgsl_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
/* mgsl_allocate_dma_buffers()
*
@@ -4335,13 +4315,13 @@ static const struct tty_operations mgsl_ops = {
.send_xchar = mgsl_send_xchar,
.break_ctl = mgsl_break,
.wait_until_sent = mgsl_wait_until_sent,
- .read_proc = mgsl_read_proc,
.set_termios = mgsl_set_termios,
.stop = mgsl_stop,
.start = mgsl_start,
.hangup = mgsl_hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &mgsl_proc_fops,
};
/*
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index efb3dc928a43..5e256494686a 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -60,6 +60,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
@@ -154,7 +155,6 @@ static void tx_hold(struct tty_struct *tty);
static void tx_release(struct tty_struct *tty);
static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
static int chars_in_buffer(struct tty_struct *tty);
static void throttle(struct tty_struct * tty);
static void unthrottle(struct tty_struct * tty);
@@ -298,6 +298,7 @@ struct slgt_info {
unsigned int rbuf_fill_level;
unsigned int if_mode;
+ unsigned int base_clock;
/* device status */
@@ -1156,22 +1157,26 @@ static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *ne
return -EFAULT;
spin_lock(&info->lock);
- info->params.mode = tmp_params.mode;
- info->params.loopback = tmp_params.loopback;
- info->params.flags = tmp_params.flags;
- info->params.encoding = tmp_params.encoding;
- info->params.clock_speed = tmp_params.clock_speed;
- info->params.addr_filter = tmp_params.addr_filter;
- info->params.crc_type = tmp_params.crc_type;
- info->params.preamble_length = tmp_params.preamble_length;
- info->params.preamble = tmp_params.preamble;
- info->params.data_rate = tmp_params.data_rate;
- info->params.data_bits = tmp_params.data_bits;
- info->params.stop_bits = tmp_params.stop_bits;
- info->params.parity = tmp_params.parity;
+ if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) {
+ info->base_clock = tmp_params.clock_speed;
+ } else {
+ info->params.mode = tmp_params.mode;
+ info->params.loopback = tmp_params.loopback;
+ info->params.flags = tmp_params.flags;
+ info->params.encoding = tmp_params.encoding;
+ info->params.clock_speed = tmp_params.clock_speed;
+ info->params.addr_filter = tmp_params.addr_filter;
+ info->params.crc_type = tmp_params.crc_type;
+ info->params.preamble_length = tmp_params.preamble_length;
+ info->params.preamble = tmp_params.preamble;
+ info->params.data_rate = tmp_params.data_rate;
+ info->params.data_bits = tmp_params.data_bits;
+ info->params.stop_bits = tmp_params.stop_bits;
+ info->params.parity = tmp_params.parity;
+ }
spin_unlock(&info->lock);
- change_params(info);
+ program_hw(info);
return 0;
}
@@ -1229,13 +1234,12 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file,
/*
* proc fs support
*/
-static inline int line_info(char *buf, struct slgt_info *info)
+static inline void line_info(struct seq_file *m, struct slgt_info *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
+ seq_printf(m, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
info->device_name, info->phys_reg_addr,
info->irq_level, info->max_frame_size);
@@ -1260,75 +1264,70 @@ static inline int line_info(char *buf, struct slgt_info *info)
strcat(stat_buf, "|RI");
if (info->params.mode != MGSL_MODE_ASYNC) {
- ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+ seq_printf(m, "\tHDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+ seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+ seq_printf(m, "\tASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
-
- return ret;
}
/* Called to print information about devices
*/
-static int read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int synclink_gt_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
struct slgt_info *info;
- len += sprintf(page, "synclink_gt driver\n");
+ seq_puts(m, "synclink_gt driver\n");
info = slgt_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+static int synclink_gt_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, synclink_gt_proc_show, NULL);
}
+static const struct file_operations synclink_gt_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = synclink_gt_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*
* return count of bytes in transmit buffer
*/
@@ -2565,10 +2564,13 @@ static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params)
return -EFAULT;
spin_lock_irqsave(&info->lock, flags);
- memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
+ if (tmp_params.mode == MGSL_MODE_BASE_CLOCK)
+ info->base_clock = tmp_params.clock_speed;
+ else
+ memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
spin_unlock_irqrestore(&info->lock, flags);
- change_params(info);
+ program_hw(info);
return 0;
}
@@ -3438,6 +3440,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
info->magic = MGSL_MAGIC;
INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;
+ info->base_clock = 14745600;
info->rbuf_fill_level = DMABUFSIZE;
info->port.close_delay = 5*HZ/10;
info->port.closing_wait = 30*HZ;
@@ -3562,13 +3565,13 @@ static const struct tty_operations ops = {
.send_xchar = send_xchar,
.break_ctl = set_break,
.wait_until_sent = wait_until_sent,
- .read_proc = read_proc,
.set_termios = set_termios,
.stop = tx_hold,
.start = tx_release,
.hangup = hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &synclink_gt_proc_fops,
};
static void slgt_cleanup(void)
@@ -3785,7 +3788,7 @@ static void enable_loopback(struct slgt_info *info)
static void set_rate(struct slgt_info *info, u32 rate)
{
unsigned int div;
- static unsigned int osc = 14745600;
+ unsigned int osc = info->base_clock;
/* div = osc/rate - 1
*
@@ -4089,18 +4092,27 @@ static void async_mode(struct slgt_info *info)
* 06 CTS IRQ enable
* 05 DCD IRQ enable
* 04 RI IRQ enable
- * 03 reserved, must be zero
+ * 03 0=16x sampling, 1=8x sampling
* 02 1=txd->rxd internal loopback enable
* 01 reserved, must be zero
* 00 1=master IRQ enable
*/
val = BIT15 + BIT14 + BIT0;
+ /* JCR[8] : 1 = x8 async mode feature available */
+ if ((rd_reg32(info, JCR) & BIT8) && info->params.data_rate &&
+ ((info->base_clock < (info->params.data_rate * 16)) ||
+ (info->base_clock % (info->params.data_rate * 16)))) {
+ /* use 8x sampling */
+ val |= BIT3;
+ set_rate(info, info->params.data_rate * 8);
+ } else {
+ /* use 16x sampling */
+ set_rate(info, info->params.data_rate * 16);
+ }
wr_reg16(info, SCR, val);
slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER);
- set_rate(info, info->params.data_rate * 16);
-
if (info->params.loopback)
enable_loopback(info);
}
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 8eb6c89a980e..26de60efe4b2 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -50,6 +50,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
@@ -520,7 +521,6 @@ static void tx_hold(struct tty_struct *tty);
static void tx_release(struct tty_struct *tty);
static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
static int chars_in_buffer(struct tty_struct *tty);
static void throttle(struct tty_struct * tty);
static void unthrottle(struct tty_struct * tty);
@@ -1354,13 +1354,12 @@ static int ioctl(struct tty_struct *tty, struct file *file,
* /proc fs routines....
*/
-static inline int line_info(char *buf, SLMP_INFO *info)
+static inline void line_info(struct seq_file *m, SLMP_INFO *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
+ seq_printf(m, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
"\tIRQ=%d MaxFrameSize=%u\n",
info->device_name,
info->phys_sca_base,
@@ -1391,75 +1390,70 @@ static inline int line_info(char *buf, SLMP_INFO *info)
strcat(stat_buf, "|RI");
if (info->params.mode == MGSL_MODE_HDLC) {
- ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+ seq_printf(m, "\tHDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxcrc);
+ seq_printf(m, " rxlong:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+ seq_printf(m, "\tASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
-
- return ret;
}
/* Called to print information about devices
*/
-static int read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int synclinkmp_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
SLMP_INFO *info;
- len += sprintf(page, "synclinkmp driver:%s\n", driver_version);
+ seq_printf(m, "synclinkmp driver:%s\n", driver_version);
info = synclinkmp_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+static int synclinkmp_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, synclinkmp_proc_show, NULL);
}
+static const struct file_operations synclinkmp_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = synclinkmp_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/* Return the count of bytes in transmit buffer
*/
static int chars_in_buffer(struct tty_struct *tty)
@@ -3905,13 +3899,13 @@ static const struct tty_operations ops = {
.send_xchar = send_xchar,
.break_ctl = set_break,
.wait_until_sent = wait_until_sent,
- .read_proc = read_proc,
.set_termios = set_termios,
.stop = tx_hold,
.start = tx_release,
.hangup = hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &synclinkmp_proc_fops,
};
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 33a9351c896d..b0a6a3e51924 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -35,7 +35,6 @@
#include <linux/vt_kern.h>
#include <linux/workqueue.h>
#include <linux/kexec.h>
-#include <linux/irq.h>
#include <linux/hrtimer.h>
#include <linux/oom.h>
@@ -283,7 +282,7 @@ static void sysrq_ftrace_dump(int key, struct tty_struct *tty)
}
static struct sysrq_key_op sysrq_ftrace_dump_op = {
.handler = sysrq_ftrace_dump,
- .help_msg = "dumpZ-ftrace-buffer",
+ .help_msg = "dump-ftrace-buffer(Z)",
.action_msg = "Dump ftrace buffer",
.enable_mask = SYSRQ_ENABLE_DUMP,
};
@@ -346,6 +345,19 @@ static struct sysrq_key_op sysrq_moom_op = {
.enable_mask = SYSRQ_ENABLE_SIGNAL,
};
+#ifdef CONFIG_BLOCK
+static void sysrq_handle_thaw(int key, struct tty_struct *tty)
+{
+ emergency_thaw_all();
+}
+static struct sysrq_key_op sysrq_thaw_op = {
+ .handler = sysrq_handle_thaw,
+ .help_msg = "thaw-filesystems(J)",
+ .action_msg = "Emergency Thaw of all frozen filesystems",
+ .enable_mask = SYSRQ_ENABLE_SIGNAL,
+};
+#endif
+
static void sysrq_handle_kill(int key, struct tty_struct *tty)
{
send_sig_all(SIGKILL);
@@ -396,9 +408,13 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
&sysrq_moom_op, /* f */
/* g: May be registered by ppc for kgdb */
NULL, /* g */
- NULL, /* h */
+ NULL, /* h - reserved for help */
&sysrq_kill_op, /* i */
+#ifdef CONFIG_BLOCK
+ &sysrq_thaw_op, /* j */
+#else
NULL, /* j */
+#endif
&sysrq_SAK_op, /* k */
#ifdef CONFIG_SMP
&sysrq_showallcpus_op, /* l */
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c
index 34ab6d798f81..55ba6f142883 100644
--- a/drivers/char/tty_audit.c
+++ b/drivers/char/tty_audit.c
@@ -10,8 +10,6 @@
*/
#include <linux/audit.h>
-#include <linux/file.h>
-#include <linux/fdtable.h>
#include <linux/tty.h>
struct tty_audit_buf {
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 224f271d8cbe..66b99a2049e3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -464,7 +464,7 @@ void tty_wakeup(struct tty_struct *tty)
tty_ldisc_deref(ld);
}
}
- wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
}
EXPORT_SYMBOL_GPL(tty_wakeup);
@@ -587,8 +587,8 @@ static void do_tty_hangup(struct work_struct *work)
* FIXME: Once we trust the LDISC code better we can wait here for
* ldisc completion and fix the driver call race
*/
- wake_up_interruptible(&tty->write_wait);
- wake_up_interruptible(&tty->read_wait);
+ wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+ wake_up_interruptible_poll(&tty->read_wait, POLLIN);
/*
* Shutdown the current line discipline, and reset it to
* N_TTY.
@@ -879,7 +879,7 @@ void stop_tty(struct tty_struct *tty)
if (tty->link && tty->link->packet) {
tty->ctrl_status &= ~TIOCPKT_START;
tty->ctrl_status |= TIOCPKT_STOP;
- wake_up_interruptible(&tty->link->read_wait);
+ wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
}
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (tty->ops->stop)
@@ -913,7 +913,7 @@ void start_tty(struct tty_struct *tty)
if (tty->link && tty->link->packet) {
tty->ctrl_status &= ~TIOCPKT_STOP;
tty->ctrl_status |= TIOCPKT_START;
- wake_up_interruptible(&tty->link->read_wait);
+ wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
}
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (tty->ops->start)
@@ -970,7 +970,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
void tty_write_unlock(struct tty_struct *tty)
{
mutex_unlock(&tty->atomic_write_lock);
- wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
}
int tty_write_lock(struct tty_struct *tty, int ndelay)
@@ -1623,21 +1623,21 @@ void tty_release_dev(struct file *filp)
if (tty_closing) {
if (waitqueue_active(&tty->read_wait)) {
- wake_up(&tty->read_wait);
+ wake_up_poll(&tty->read_wait, POLLIN);
do_sleep++;
}
if (waitqueue_active(&tty->write_wait)) {
- wake_up(&tty->write_wait);
+ wake_up_poll(&tty->write_wait, POLLOUT);
do_sleep++;
}
}
if (o_tty_closing) {
if (waitqueue_active(&o_tty->read_wait)) {
- wake_up(&o_tty->read_wait);
+ wake_up_poll(&o_tty->read_wait, POLLIN);
do_sleep++;
}
if (waitqueue_active(&o_tty->write_wait)) {
- wake_up(&o_tty->write_wait);
+ wake_up_poll(&o_tty->write_wait, POLLOUT);
do_sleep++;
}
}
@@ -1758,7 +1758,7 @@ static int __tty_open(struct inode *inode, struct file *filp)
struct tty_driver *driver;
int index;
dev_t device = inode->i_rdev;
- unsigned short saved_flags = filp->f_flags;
+ unsigned saved_flags = filp->f_flags;
nonseekable_open(inode, filp);
@@ -2681,7 +2681,7 @@ void __do_SAK(struct tty_struct *tty)
/* Kill the entire session */
do_each_pid_task(session, PIDTYPE_SID, p) {
printk(KERN_NOTICE "SAK: killed process %d"
- " (%s): task_session_nr(p)==tty->session\n",
+ " (%s): task_session(p)==tty->session\n",
task_pid_nr(p), p->comm);
send_sig(SIGKILL, p, 1);
} while_each_pid_task(session, PIDTYPE_SID, p);
@@ -2691,7 +2691,7 @@ void __do_SAK(struct tty_struct *tty)
do_each_thread(g, p) {
if (p->signal->tty == tty) {
printk(KERN_NOTICE "SAK: killed process %d"
- " (%s): task_session_nr(p)==tty->session\n",
+ " (%s): task_session(p)==tty->session\n",
task_pid_nr(p), p->comm);
send_sig(SIGKILL, p, 1);
continue;
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index 7a84b406a952..f78f5b0127a8 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -10,7 +10,6 @@
#include <linux/tty_flip.h>
#include <linux/devpts_fs.h>
#include <linux/file.h>
-#include <linux/fdtable.h>
#include <linux/console.h>
#include <linux/timer.h>
#include <linux/ctype.h>
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 2c1d133819b5..08151d4de489 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2274,7 +2274,7 @@ rescan_last_byte:
continue; /* nothing to display */
}
/* Glyph not found */
- if ((!(vc->vc_utf && !vc->vc_disp_ctrl) && c < 128) && !(c & ~charmask)) {
+ if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
/* In legacy mode use the glyph we get by a 1:1 mapping.
This would make absolutely no sense with Unicode in mind,
but do this for ASCII characters since a font may lack
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index a2dee0eb6dad..e6ce632a393e 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -400,6 +400,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KIOCSOUND:
if (!perm)
goto eperm;
+ /* FIXME: This is an old broken API but we need to keep it
+ supported and somehow separate the historic advertised
+ tick rate from any real one */
if (arg)
arg = CLOCK_TICK_RATE / arg;
kd_mksound(arg, 0);
@@ -417,6 +420,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/
ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
count = ticks ? (arg & 0xffff) : 0;
+ /* FIXME: This is an old broken API but we need to keep it
+ supported and somehow separate the historic advertised
+ tick rate from any real one */
if (count)
count = CLOCK_TICK_RATE / count;
kd_mksound(count, ticks);