2 Kernel module for the dp83820 flash write utility. This code was written
3 by Dave Ashley for NXTV, Inc.
4 Copyright 2004 by NXTV, Inc.
5 Written 20040219 by Dave Ashley.
7 This code is released under the terms of the GPL. No warranty.
9 THEORY: The dp83820 bootrom interface is flawed in that you can't
10 read or write a single byte at a time, and this is required in order
11 to write to flash devices like the AT29C512. So the workaround is
12 to use the chips ability to map into memory the bootrom, then the cpu
13 can directly do byte accesses.
15 The problem is that a "feature" of the dp83820 is that when you map
16 in the bootrom, you conveniently lose access to the PCI registers.
17 So we need to do this in kernel space and wrap every access to the
18 bootrom within interrupt_disable/restore, in case a network interrupt
21 This kernel module is very simple, it just creates a proc file
23 If you write 3 bytes to this file you are doing a write to the flashrom:
28 If you write 2 bytes to this file you are doing a read from the flashrom:
31 Then the next read from the file will return a single byte of what
34 You only get one shot at accessing the proc file, you need to then
35 close/open if you want to do another access. This could probably be
36 cleaned up pretty easily so more accesses can be done without having
37 to close/open the file.
42 #include <linux/config.h>
43 #include <linux/kernel.h>
44 #include <linux/sched.h>
45 #include <linux/errno.h>
46 #include <linux/ioport.h>
47 #include <linux/interrupt.h>
48 #include <linux/pci.h>
49 #include <linux/spinlock.h>
50 #include <linux/proc_fs.h>
51 #include <linux/module.h>
54 #define PROCNAME "dp83820"
56 struct pci_dev
*mydev
=0;
58 unsigned char *addr
=0;
60 unsigned char lastread
;
63 int my_read_proc(char *buf
, char **start
,off_t offset
,int count
, int *eof
,void *data
)
78 int my_write_proc(struct file
*file
, const char *buffer
, unsigned long count
,
88 pci_write_config_dword(mydev
, 0x30, loc
| 1);
93 lastread
=addr
[msg
[0] | (msg
[1]<<8)];
96 addr
[msg
[0] | (msg
[1]<<8)] = msg
[2];
99 pci_write_config_dword(mydev
, 0x30, loc
);
100 restore_flags(flags
);
105 struct proc_dir_entry
*de
=0;
107 int __init
init_module(void)
111 pci_for_each_dev(mydev
)
113 if(mydev
->vendor
==0x100b && mydev
->device
==0x0022)
121 printk("Could not find DP83820 network device\n");
125 de
=create_proc_entry(PROCNAME
,0,0);
129 de
->read_proc
=my_read_proc
;
130 de
->write_proc
=my_write_proc
;
132 loc
=mydev
->resource
[PCI_ROM_RESOURCE
].start
;
133 addr
=ioremap_nocache(loc
,0x10000);
139 void cleanup_module(void)
143 remove_proc_entry(PROCNAME
,0);