* [PATCH] hamradio/scc -
@ 2003-09-15 23:23 Stephen Hemminger
2003-09-16 20:53 ` Jeroen Vreeken
2003-09-17 6:35 ` Martijn Hijdra
0 siblings, 2 replies; 3+ messages in thread
From: Stephen Hemminger @ 2003-09-15 23:23 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-hams, netdev
Update hamradio/scc for 2.6.0-test5
- use seq_file for /proc
- get rid of dev_get()
- use alloc_netdev
Don't have hardware, but can load/unload the module fine.
diff -Nru a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
--- a/drivers/net/hamradio/scc.c Mon Sep 15 16:20:49 2003
+++ b/drivers/net/hamradio/scc.c Mon Sep 15 16:20:49 2003
@@ -171,6 +171,7 @@
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <net/ax25.h>
@@ -202,8 +203,8 @@
static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs);
static void scc_init_timer(struct scc_channel *scc);
-static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev);
-static int scc_net_init(struct net_device *dev);
+static int scc_net_alloc(const char *name, struct scc_channel *scc);
+static void scc_net_setup(struct net_device *dev);
static int scc_net_open(struct net_device *dev);
static int scc_net_close(struct net_device *dev);
static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb);
@@ -235,7 +236,7 @@
/* These provide interrupt save 2-step access to the Z8530 registers */
-static spinlock_t iolock; /* Guards paired accesses */
+static spinlock_t iolock = SPIN_LOCK_UNLOCKED; /* Guards paired accesses */
static inline unsigned char InReg(io_port port, unsigned char reg)
{
@@ -1512,34 +1513,28 @@
* Allocate device structure, err, instance, and register driver
*/
-static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev)
+static int scc_net_alloc(const char *name, struct scc_channel *scc)
{
+ int err;
struct net_device *dev;
- if (dev_get(name))
- {
- printk(KERN_INFO "Z8530drv: device %s already exists.\n", name);
- return -EEXIST;
- }
-
- if ((scc->dev = (struct net_device *) kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL)
+ dev = alloc_netdev(0, name, scc_net_setup);
+ if (!dev)
return -ENOMEM;
- dev = scc->dev;
- memset(dev, 0, sizeof(struct net_device));
-
- strcpy(dev->name, name);
- dev->priv = (void *) scc;
- dev->init = scc_net_init;
-
+ dev->priv = scc;
+ scc->dev = dev;
spin_lock_init(&scc->lock);
-
- if ((addev? register_netdevice(dev) : register_netdev(dev)) != 0) {
- kfree(dev);
- return -EIO;
- }
- SET_MODULE_OWNER(dev);
+ err = register_netdev(dev);
+ if (err) {
+ printk(KERN_ERR "%s: can't register network device (%d)\n",
+ name, err);
+ free_netdev(dev);
+ scc->dev = NULL;
+ return err;
+ }
+
return 0;
}
@@ -1556,8 +1551,9 @@
/* ----> Initialize device <----- */
-static int scc_net_init(struct net_device *dev)
+static void scc_net_setup(struct net_device *dev)
{
+ SET_MODULE_OWNER(dev);
dev->tx_queue_len = 16; /* should be enough... */
dev->open = scc_net_open;
@@ -1581,7 +1577,6 @@
dev->mtu = AX25_DEF_PACLEN;
dev->addr_len = AX25_ADDR_LEN;
- return 0;
}
/* ----> open network device <---- */
@@ -1719,10 +1714,10 @@
struct scc_mem_config memcfg;
struct scc_hw_config hwcfg;
struct scc_calibrate cal;
+ struct scc_channel *scc;
int chan;
- unsigned char device_name[10];
+ unsigned char device_name[IFNAMSIZ];
void *arg;
- struct scc_channel *scc;
scc = (struct scc_channel *) dev->priv;
arg = (void *) ifr->ifr_data;
@@ -1828,8 +1823,10 @@
{
request_region(SCC_Info[2*Nchips+chan].ctrl, 1, "scc ctrl");
request_region(SCC_Info[2*Nchips+chan].data, 1, "scc data");
- if (Nchips+chan != 0)
- scc_net_setup(&SCC_Info[2*Nchips+chan], device_name, 1);
+ if (Nchips+chan != 0 &&
+ scc_net_alloc(device_name,
+ &SCC_Info[2*Nchips+chan]))
+ return -EINVAL;
}
}
@@ -1978,39 +1975,58 @@
/* * dump statistics to /proc/net/z8530drv * */
/* ******************************************************************** */
+#ifdef CONFIG_PROC_FS
-static int scc_net_get_info(char *buffer, char **start, off_t offset, int length)
+static inline struct scc_channel *scc_net_seq_idx(loff_t pos)
{
- struct scc_channel *scc;
- struct scc_kiss *kiss;
- struct scc_stat *stat;
- int len = 0;
- off_t pos = 0;
- off_t begin = 0;
int k;
- len += sprintf(buffer, "z8530drv-"VERSION"\n");
-
- if (!Driver_Initialized)
- {
- len += sprintf(buffer+len, "not initialized\n");
- goto done;
+ for (k = 0; k < Nchips*2; ++k) {
+ if (!SCC_Info[k].init)
+ continue;
+ if (pos-- == 0)
+ return &SCC_Info[k];
}
+ return NULL;
+}
- if (!Nchips)
- {
- len += sprintf(buffer+len, "chips missing\n");
- goto done;
+static void *scc_net_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ return *pos ? scc_net_seq_idx(*pos - 1) : SEQ_START_TOKEN;
+
+}
+
+static void *scc_net_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ unsigned k;
+ struct scc_channel *scc = v;
+ ++*pos;
+
+ for (k = (v == SEQ_START_TOKEN) ? 0 : (scc - SCC_Info)+1;
+ k < Nchips*2; ++k) {
+ if (SCC_Info[k].init)
+ return &SCC_Info[k];
}
+ return NULL;
+}
- for (k = 0; k < Nchips*2; k++)
- {
- scc = &SCC_Info[k];
- stat = &scc->stat;
- kiss = &scc->kiss;
+static void scc_net_seq_stop(struct seq_file *seq, void *v)
+{
+}
+
+static int scc_net_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "z8530drv-"VERSION"\n");
+ } else if (!Driver_Initialized) {
+ seq_puts(seq, "not initialized\n");
+ } else if (!Nchips) {
+ seq_puts(seq, "chips missing\n");
+ } else {
+ const struct scc_channel *scc = v;
+ const struct scc_stat *stat = &scc->stat;
+ const struct scc_kiss *kiss = &scc->kiss;
- if (!scc->init)
- continue;
/* dev data ctrl irq clock brand enh vector special option
* baud nrz clocksrc softdcd bufsize
@@ -2021,24 +2037,24 @@
* R ## ## XX ## ## ## ## ## XX ## ## ## ## ## ## ##
*/
- len += sprintf(buffer+len, "%s\t%3.3lx %3.3lx %d %lu %2.2x %d %3.3lx %3.3lx %d\n",
+ seq_printf(seq, "%s\t%3.3lx %3.3lx %d %lu %2.2x %d %3.3lx %3.3lx %d\n",
scc->dev->name,
scc->data, scc->ctrl, scc->irq, scc->clock, scc->brand,
scc->enhanced, Vector_Latch, scc->special,
scc->option);
- len += sprintf(buffer+len, "\t%lu %d %d %d %d\n",
+ seq_printf(seq, "\t%lu %d %d %d %d\n",
scc->modem.speed, scc->modem.nrz,
scc->modem.clocksrc, kiss->softdcd,
stat->bufsize);
- len += sprintf(buffer+len, "\t%lu %lu %lu %lu\n",
+ seq_printf(seq, "\t%lu %lu %lu %lu\n",
stat->rxints, stat->txints, stat->exints, stat->spints);
- len += sprintf(buffer+len, "\t%lu %lu %d / %lu %lu %d / %d %d\n",
+ seq_printf(seq, "\t%lu %lu %d / %lu %lu %d / %d %d\n",
stat->rxframes, stat->rxerrs, stat->rx_over,
stat->txframes, stat->txerrs, stat->tx_under,
stat->nospace, stat->tx_state);
#define K(x) kiss->x
- len += sprintf(buffer+len, "\t%d %d %d %d %d %d %d %d %d %d %d %d\n",
+ seq_printf(seq, "\t%d %d %d %d %d %d %d %d %d %d %d %d\n",
K(txdelay), K(persist), K(slottime), K(tailtime),
K(fulldup), K(waittime), K(mintime), K(maxkeyup),
K(idletime), K(maxdefer), K(tx_inhibit), K(group));
@@ -2047,43 +2063,49 @@
{
int reg;
- len += sprintf(buffer+len, "\tW ");
+ seq_printf(seq, "\tW ");
for (reg = 0; reg < 16; reg++)
- len += sprintf(buffer+len, "%2.2x ", scc->wreg[reg]);
- len += sprintf(buffer+len, "\n");
+ seq_printf(seq, "%2.2x ", scc->wreg[reg]);
+ seq_printf(seq, "\n");
- len += sprintf(buffer+len, "\tR %2.2x %2.2x XX ", InReg(scc->ctrl,R0), InReg(scc->ctrl,R1));
+ seq_printf(seq, "\tR %2.2x %2.2x XX ", InReg(scc->ctrl,R0), InReg(scc->ctrl,R1));
for (reg = 3; reg < 8; reg++)
- len += sprintf(buffer+len, "%2.2x ", InReg(scc->ctrl, reg));
- len += sprintf(buffer+len, "XX ");
+ seq_printf(seq, "%2.2x ", InReg(scc->ctrl, reg));
+ seq_printf(seq, "XX ");
for (reg = 9; reg < 16; reg++)
- len += sprintf(buffer+len, "%2.2x ", InReg(scc->ctrl, reg));
- len += sprintf(buffer+len, "\n");
+ seq_printf(seq, "%2.2x ", InReg(scc->ctrl, reg));
+ seq_printf(seq, "\n");
}
#endif
- len += sprintf(buffer+len, "\n");
-
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
-
- if (pos > offset + length)
- break;
+ seq_putc(seq, '\n');
}
-done:
+ return 0;
+}
- *start = buffer + (offset - begin);
- len -= (offset - begin);
+static struct seq_operations scc_net_seq_ops = {
+ .start = scc_net_seq_start,
+ .next = scc_net_seq_next,
+ .stop = scc_net_seq_stop,
+ .show = scc_net_seq_show,
+};
- if (len > length) len = length;
- return len;
+static int scc_net_seq_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &scc_net_seq_ops);
}
+static struct file_operations scc_net_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = scc_net_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+};
+
+#endif /* CONFIG_PROC_FS */
+
/* ******************************************************************** */
/* * Init SCC driver * */
@@ -2091,23 +2113,18 @@
static int __init scc_init_driver (void)
{
- int result;
- char devname[10];
+ char devname[IFNAMSIZ];
printk(banner);
- spin_lock_init(&iolock);
-
sprintf(devname,"%s0", SCC_DriverName);
- result = scc_net_setup(SCC_Info, devname, 0);
- if (result)
- {
+ if (scc_net_alloc(devname, SCC_Info)) {
printk(KERN_ERR "z8530drv: cannot initialize module\n");
- return result;
+ return -EIO;
}
- proc_net_create("z8530drv", 0, scc_net_get_info);
+ proc_net_fops_create("z8530drv", 0, &scc_net_seq_fops);
return 0;
}
@@ -2117,11 +2134,12 @@
io_port ctrl;
int k;
struct scc_channel *scc;
+ struct net_device *dev;
- if (Nchips == 0)
+ if (Nchips == 0 && (dev = SCC_Info[0].dev))
{
- unregister_netdev(SCC_Info[0].dev);
- free_netdev(SCC_Info[0].dev);
+ unregister_netdev(dev);
+ free_netdev(dev);
}
/* Guard against chip prattle */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] hamradio/scc -
2003-09-15 23:23 [PATCH] hamradio/scc - Stephen Hemminger
@ 2003-09-16 20:53 ` Jeroen Vreeken
2003-09-17 6:35 ` Martijn Hijdra
1 sibling, 0 replies; 3+ messages in thread
From: Jeroen Vreeken @ 2003-09-16 20:53 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-hams, netdev, Stephen Hemminger
[-- Attachment #1: Type: text/plain, Size: 597 bytes --]
On 2003.09.16 01:23:35 +0200 Stephen Hemminger wrote:
> Update hamradio/scc for 2.6.0-test5
> - use seq_file for /proc
> - get rid of dev_get()
> - use alloc_netdev
I have a little adition of my own (should apply nicely next to this patch).
The probe function uses the not yet initialized scc struct for requesting
its io region.
The second patch is against the bpqethernet driver.
This has a debug printk that seems to be untouched since somewhere early
2.1 kernels.
The if statement it debugs seems to work perfectly and its only use at the
moment is to annoy the hell out of me :)
Jeroen
[-- Attachment #2: scc-2.6.0.t5.rxq.diff --]
[-- Type: application/octet-stream, Size: 581 bytes --]
--- linux-2.6.0-test5/drivers/net/hamradio/scc.c Mon Sep 8 21:50:22 2003
+++ linux-2.6.0-test5.rxq/drivers/net/hamradio/scc.c Tue Sep 16 22:41:36 2003
@@ -1767,7 +1767,7 @@
#ifndef SCC_DONT_CHECK
- if(request_region(scc->ctrl, 1, "scc-probe"))
+ if(request_region(hwcfg.ctrl_a, 1, "scc-probe"))
{
disable_irq(hwcfg.irq);
Outb(hwcfg.ctrl_a, 0);
@@ -1779,7 +1779,7 @@
if (InReg(hwcfg.ctrl_a,R13) != 0x55)
found = 0;
enable_irq(hwcfg.irq);
- release_region(scc->ctrl, 1);
+ release_region(hwcfg.ctrl_a, 1);
}
else
found = 0;
[-- Attachment #3: bpqether-2.6.0.t5.rxq.diff --]
[-- Type: application/octet-stream, Size: 551 bytes --]
--- linux-2.6.0-test5/drivers/net/hamradio/bpqether.c Mon Sep 8 21:50:03 2003
+++ linux-2.6.0-test5.rxq/drivers/net/hamradio/bpqether.c Mon Sep 15 15:40:16 2003
@@ -189,10 +189,8 @@
bpq = (struct bpqdev *)dev->priv;
- if (!(bpq->acpt_addr[0] & 0x01) && memcmp(eth->h_source, bpq->acpt_addr, ETH_ALEN)) {
- printk(KERN_DEBUG "bpqether: wrong dest %s\n", bpq_print_ethaddr(eth->h_source));
+ if (!(bpq->acpt_addr[0] & 0x01) && memcmp(eth->h_source, bpq->acpt_addr, ETH_ALEN))
goto drop;
- }
len = skb->data[0] + skb->data[1] * 256 - 5;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] hamradio/scc -
2003-09-15 23:23 [PATCH] hamradio/scc - Stephen Hemminger
2003-09-16 20:53 ` Jeroen Vreeken
@ 2003-09-17 6:35 ` Martijn Hijdra
1 sibling, 0 replies; 3+ messages in thread
From: Martijn Hijdra @ 2003-09-17 6:35 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-hams, netdev
[-- Attachment #1: Type: text/plain, Size: 365 bytes --]
On Tue, 2003-09-16 at 01:23, Stephen Hemminger wrote:
> Update hamradio/scc for 2.6.0-test5
> - use seq_file for /proc
> - get rid of dev_get()
> - use alloc_netdev
>
Hi, and another small patch for hamradio/scc to
fill the statistics counters for the scc driver.
(see output of ifconfig RX bytes and TX bytes)
--
Martijn Hijdra <martijn@esrac.ele.tue.nl>
[-- Attachment #2: scc_260t5.diff --]
[-- Type: text/x-patch, Size: 1198 bytes --]
--- drivers/net/hamradio/scc.c.orig 2003-08-23 01:58:57.000000000 +0200
+++ drivers/net/hamradio/scc.c 2003-09-03 08:57:50.000000000 +0200
@@ -1635,6 +1635,7 @@
}
scc->dev_stat.rx_packets++;
+ scc->dev_stat.rx_bytes += skb->len;
skb->dev = scc->dev;
skb->protocol = htons(ETH_P_AX25);
@@ -1661,6 +1662,7 @@
}
scc->dev_stat.tx_packets++;
+ scc->dev_stat.tx_bytes += skb->len;
scc->stat.txframes++;
kisscmd = *skb->data & 0x1f;
--- include/linux/scc.h.orig 2003-09-03 09:13:26.000000000 +0200
+++ include/linux/scc.h 2003-09-03 09:13:55.000000000 +0200
@@ -200,7 +200,7 @@
unsigned char fulldup; /* Full Duplex mode 0=CSMA 1=DUP 2=ALWAYS KEYED */
unsigned char waittime; /* Waittime before any transmit attempt */
unsigned int maxkeyup; /* Maximum time to transmit (seconds) */
- unsigned char mintime; /* Minimal offtime after MAXKEYUP timeout (seconds) */
+ unsigned int mintime; /* Minimal offtime after MAXKEYUP timeout (seconds) */
unsigned int idletime; /* Maximum idle time in ALWAYS KEYED mode (seconds) */
unsigned int maxdefer; /* Timer for CSMA channel busy limit */
unsigned char tx_inhibit; /* Transmit is not allowed when set */
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-09-17 6:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-09-15 23:23 [PATCH] hamradio/scc - Stephen Hemminger
2003-09-16 20:53 ` Jeroen Vreeken
2003-09-17 6:35 ` Martijn Hijdra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).