2 * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
3 * Author: Fuxin Zhang, zhangfx@lemote.com
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
11 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
13 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
16 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/errno.h>
30 #include <linux/pci.h>
31 #include <linux/init.h>
32 #include <linux/proc_fs.h>
33 #include <asm/uaccess.h>
36 static ssize_t
mipsdha_proc_read(struct file
*file
, char *buf
, size_t len
, loff_t
*ppos
);
38 static ssize_t
mipsdha_proc_write(struct file
*file
, const char *buf
, size_t len
, loff_t
*ppos
);
41 static struct proc_dir_entry
*mipsdha_proc_entry
;
43 #define INFO_SIZE 4096
44 static char info_buf
[INFO_SIZE
];
46 static struct file_operations mipsdha_fops
=
49 read
: mipsdha_proc_read
,
50 write
: mipsdha_proc_write
,
53 static enum {CMD_ERR
, CMD_GIB
, CMD_GPI
} cmd
;
55 typedef struct pciinfo_s
58 unsigned short command
;
59 unsigned short vendor
,device
;
60 unsigned base0
,base1
,base2
,baserom
;
64 extern struct proc_dir_entry proc_root
;
66 static int __init
mipsdha_proc_init(void)
68 mipsdha_proc_entry
= create_proc_entry("mipsdha", S_IWUSR
| S_IRUGO
, &proc_root
);
69 if (mipsdha_proc_entry
== NULL
) {
70 printk("MIPSDHA: register /proc/mipsdha failed!\n");
74 mipsdha_proc_entry
->proc_fops
= &mipsdha_fops
;
80 static ssize_t
mipsdha_proc_write (struct file
*file
, const char *buf
, size_t len
, loff_t
*ppos
)
82 char cmd_gib
[]="GET IO BASE";
83 char cmd_gpi
[]="GET PCI INFO";
85 if (len
>= INFO_SIZE
) return -ENOMEM
;
87 if (copy_from_user(info_buf
, buf
, len
)) return -EFAULT
;
90 if (strncmp(info_buf
, cmd_gib
, sizeof(cmd_gib
)-1)==0) {
93 } else if (strncmp(info_buf
, cmd_gpi
, sizeof(cmd_gpi
)-1)==0) {
101 static ssize_t
mipsdha_proc_read (struct file
*file
, char *buf
, size_t len
, loff_t
*ppos
)
105 struct pci_dev
*dev
= NULL
;
109 printk("MIPSDHA: BUG found in function %s!(cmd=%d)\n",
119 *(unsigned long *)info_buf
=
120 virt_to_phys((void *) mips_io_port_base
);
121 info_cnt
=sizeof(unsigned long);
126 pciinfo
= (pciinfo_t
*) info_buf
;
128 for_each_pci_dev(dev
) {
130 if (info_cnt
+sizeof(pciinfo_t
)>INFO_SIZE
) return -ENOMEM
;
132 pciinfo
->bus
= dev
->bus
->number
;
133 pciinfo
->card
= PCI_SLOT(dev
->devfn
);
134 pciinfo
->func
= PCI_FUNC(dev
->devfn
);
136 if (pci_read_config_word(dev
, PCI_COMMAND
, &pciinfo
->command
)
137 != PCIBIOS_SUCCESSFUL
) {
138 printk("MIPSDHA: BUG found in function %s!\n",
143 pciinfo
->vendor
= dev
->vendor
;
144 pciinfo
->device
= dev
->device
;
146 pciinfo
->base0
= (dev
->resource
[0]).start
;
147 pciinfo
->base1
= (dev
->resource
[1]).start
;
148 pciinfo
->base2
= (dev
->resource
[2]).start
;
149 pciinfo
->baserom
= (dev
->resource
[PCI_ROM_RESOURCE
]).start
;
152 info_cnt
+= sizeof(pciinfo_t
);
157 if (len
< info_cnt
) return -ENOMEM
;
158 if (copy_to_user(buf
, info_buf
, info_cnt
)) return -EFAULT
;
163 __initcall(mipsdha_proc_init
);