|
Lines 18-155
Link Here
|
| 18 |
<para>Information here about how the PCI bus code iterates through |
18 |
<para>Information here about how the PCI bus code iterates through |
| 19 |
the unattached devices and see if a newly loaded kld will attach |
19 |
the unattached devices and see if a newly loaded kld will attach |
| 20 |
to any of them.</para> |
20 |
to any of them.</para> |
|
|
21 |
<sect2> |
| 22 |
<title>Sample code:</title> |
| 21 |
|
23 |
|
| 22 |
<programlisting>/* |
24 |
<programlisting>/* |
| 23 |
* Simple KLD to play with the PCI functions. |
25 |
* Simple KLD to play with the PCI functions. |
| 24 |
* |
26 |
* |
| 25 |
* Murray Stokely |
27 |
* Murray Stokely |
| 26 |
*/ |
28 |
*/ |
| 27 |
|
29 |
|
| 28 |
#define MIN(a,b) (((a) < (b)) ? (a) : (b)) |
|
|
| 29 |
|
| 30 |
#include <sys/param.h> /* defines used in kernel.h */ |
30 |
#include <sys/param.h> /* defines used in kernel.h */ |
| 31 |
#include <sys/module.h> |
31 |
#include <sys/module.h> |
| 32 |
#include <sys/systm.h> |
32 |
#include <sys/systm.h> |
| 33 |
#include <sys/errno.h> |
33 |
#include <sys/errno.h> /* ENXIO */ |
| 34 |
#include <sys/kernel.h> /* types used in module initialization */ |
34 |
#include <sys/kernel.h> /* types used in module initialization */ |
| 35 |
#include <sys/conf.h> /* cdevsw struct */ |
35 |
#include <sys/conf.h> /* cdevsw struct */ |
| 36 |
#include <sys/uio.h> /* uio struct */ |
36 |
#include <sys/uio.h> /* uio struct */ |
| 37 |
#include <sys/malloc.h> |
37 |
#include <sys/malloc.h> |
| 38 |
#include <sys/bus.h> /* structs, prototypes for pci bus stuff */ |
38 |
#include <sys/bus.h> /* structs, prototypes for pci bus stuff */ |
| 39 |
|
39 |
|
| 40 |
#include <machine/bus.h> |
40 |
#include <machine/bus.h> |
| 41 |
#include <sys/rman.h> |
41 |
#include <sys/rman.h> |
| 42 |
#include <machine/resource.h> |
42 |
#include <machine/resource.h> |
| 43 |
|
43 |
|
| 44 |
#include <dev/pci/pcivar.h> /* For get_pci macros! */ |
44 |
#include <dev/pci/pcivar.h> /* For pci_get macros! */ |
| 45 |
#include <dev/pci/pcireg.h> |
45 |
#include <dev/pci/pcireg.h> |
| 46 |
|
46 |
|
| 47 |
/* Function prototypes */ |
47 |
/* Function prototypes */ |
| 48 |
d_open_t mypci_open; |
48 |
static d_open_t mypci_open; |
| 49 |
d_close_t mypci_close; |
49 |
static d_close_t mypci_close; |
| 50 |
d_read_t mypci_read; |
50 |
static d_read_t mypci_read; |
| 51 |
d_write_t mypci_write; |
51 |
static d_write_t mypci_write; |
| 52 |
|
52 |
|
| 53 |
/* Character device entry points */ |
53 |
/* Character device entry points */ |
| 54 |
|
|
|
| 55 |
static struct cdevsw mypci_cdevsw = { |
54 |
static struct cdevsw mypci_cdevsw = { |
| 56 |
.d_open = mypci_open, |
55 |
.d_open = mypci_open, |
| 57 |
.d_close = mypci_close, |
56 |
.d_close = mypci_close, |
| 58 |
.d_read = mypci_read, |
57 |
.d_read = mypci_read, |
| 59 |
.d_write = mypci_write, |
58 |
.d_write = mypci_write, |
| 60 |
.d_name = "mypci", |
59 |
.d_name = "mypci" |
| 61 |
}; |
60 |
}; |
| 62 |
|
61 |
|
| 63 |
/* vars */ |
62 |
/* vars */ |
| 64 |
static dev_t sdev; |
63 |
static struct cdev *mypci_dev; /* for make_dev */ |
| 65 |
|
64 |
|
| 66 |
/* We're more interested in probe/attach than with |
65 |
/* |
| 67 |
open/close/read/write at this point */ |
66 |
* We're more interested in probe/attach than with |
|
|
67 |
* open/close/read/write at this point |
| 68 |
*/ |
| 68 |
|
69 |
|
| 69 |
int |
70 |
static int |
| 70 |
mypci_open(dev_t dev, int oflags, int devtype, d_thread_t *td) |
71 |
mypci_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td) |
| 71 |
{ |
72 |
{ |
| 72 |
int err = 0; |
73 |
printf("mypci: open!\n"); |
| 73 |
|
74 |
return (0); |
| 74 |
printf("Opened device \"mypci\" successfully.\n"); |
|
|
| 75 |
return (err); |
| 76 |
} |
75 |
} |
| 77 |
|
76 |
|
| 78 |
int |
77 |
static int |
| 79 |
mypci_close(dev_t dev, int fflag, int devtype, d_thread_t *td) |
78 |
mypci_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td) |
| 80 |
{ |
79 |
{ |
| 81 |
int err = 0; |
80 |
printf("mypci: close!\n"); |
| 82 |
|
81 |
return (0); |
| 83 |
printf("Closing device \"mypci.\"\n"); |
|
|
| 84 |
return (err); |
| 85 |
} |
82 |
} |
| 86 |
|
83 |
|
| 87 |
int |
84 |
static int |
| 88 |
mypci_read(dev_t dev, struct uio *uio, int ioflag) |
85 |
mypci_read(struct cdev *dev, struct uio *uio, int ioflag) |
| 89 |
{ |
86 |
{ |
| 90 |
int err = 0; |
87 |
printf("mypci: read!\n"); |
| 91 |
|
88 |
return (0); |
| 92 |
printf("mypci read!\n"); |
|
|
| 93 |
return (err); |
| 94 |
} |
89 |
} |
| 95 |
|
90 |
|
| 96 |
int |
91 |
static int |
| 97 |
mypci_write(dev_t dev, struct uio *uio, int ioflag) |
92 |
mypci_write(struct cdev *dev, struct uio *uio, int ioflag) |
| 98 |
{ |
93 |
{ |
| 99 |
int err = 0; |
94 |
printf("mypci: write!\n"); |
| 100 |
|
95 |
return (0); |
| 101 |
printf("mypci write!\n"); |
|
|
| 102 |
return (err); |
| 103 |
} |
96 |
} |
| 104 |
|
97 |
|
| 105 |
/* PCI Support Functions */ |
98 |
/* PCI Support Functions */ |
| 106 |
|
99 |
|
| 107 |
/* |
100 |
/* |
| 108 |
* Return identification string if this is device is ours. |
101 |
* Print identification string if this device is ours. |
| 109 |
*/ |
102 |
*/ |
| 110 |
static int |
103 |
static int |
| 111 |
mypci_probe(device_t dev) |
104 |
mypci_probe(device_t dev) |
| 112 |
{ |
105 |
{ |
| 113 |
device_printf(dev, "MyPCI Probe\nVendor ID : 0x%x\nDevice ID : 0x%x\n", |
106 |
device_printf(dev, "probe: VendorID: 0x%04x DeviceID: 0x%04x\n", |
| 114 |
pci_get_vendor(dev), pci_get_device(dev)); |
107 |
pci_get_vendor(dev), pci_get_device(dev)); |
| 115 |
|
108 |
|
| 116 |
if (pci_get_vendor(dev) == 0x11c1) { |
109 |
if (pci_get_vendor(dev) == 0x11c1) { |
| 117 |
printf("We've got the Winmodem, probe successful!\n"); |
110 |
device_printf(dev, "We've got the Winmodem, probe successful!\n"); |
| 118 |
return (0); |
111 |
device_set_desc(dev, "Winmodem"); |
|
|
112 |
return (BUS_PROBE_DEFAULT); |
| 119 |
} |
113 |
} |
| 120 |
return (ENXIO); |
114 |
return (ENXIO); |
| 121 |
} |
115 |
} |
| 122 |
|
116 |
|
| 123 |
/* Attach function is only called if the probe is successful */ |
117 |
/* |
| 124 |
|
118 |
* Attach function is only called if the probe is successful. |
|
|
119 |
*/ |
| 125 |
static int |
120 |
static int |
| 126 |
mypci_attach(device_t dev) |
121 |
mypci_attach(device_t dev) |
| 127 |
{ |
122 |
{ |
| 128 |
|
123 |
device_printf(dev, "attach: DeviceID: 0x%04x\n", pci_get_device(dev)); |
| 129 |
printf("MyPCI Attach for : deviceID : 0x%x\n",pci_get_vendor(dev)); |
124 |
mypci_dev = make_dev(<literal>&</literal>mypci_cdevsw, 0, UID_ROOT, |
| 130 |
sdev = make_dev(<literal>&</literal>mypci_cdevsw, 0, UID_ROOT, |
|
|
| 131 |
GID_WHEEL, 0600, "mypci"); |
125 |
GID_WHEEL, 0600, "mypci"); |
| 132 |
printf("Mypci device loaded.\n"); |
126 |
return (0); |
| 133 |
return (ENXIO); |
|
|
| 134 |
} |
127 |
} |
| 135 |
|
128 |
|
| 136 |
/* Detach device. */ |
129 |
/* |
| 137 |
|
130 |
* Detach device. |
|
|
131 |
*/ |
| 138 |
static int |
132 |
static int |
| 139 |
mypci_detach(device_t dev) |
133 |
mypci_detach(device_t dev) |
| 140 |
{ |
134 |
{ |
| 141 |
|
135 |
device_printf(dev, "detach!\n"); |
| 142 |
printf("Mypci detach!\n"); |
|
|
| 143 |
return (0); |
136 |
return (0); |
| 144 |
} |
137 |
} |
| 145 |
|
138 |
|
| 146 |
/* Called during system shutdown after sync. */ |
139 |
/* |
| 147 |
|
140 |
* Called during system shutdown after sync. |
|
|
141 |
*/ |
| 148 |
static int |
142 |
static int |
| 149 |
mypci_shutdown(device_t dev) |
143 |
mypci_shutdown(device_t dev) |
| 150 |
{ |
144 |
{ |
| 151 |
|
145 |
device_printf(dev, "shutdown!\n"); |
| 152 |
printf("Mypci shutdown!\n"); |
|
|
| 153 |
return (0); |
146 |
return (0); |
| 154 |
} |
147 |
} |
| 155 |
|
148 |
|
|
Lines 159-178
Link Here
|
| 159 |
static int |
152 |
static int |
| 160 |
mypci_suspend(device_t dev) |
153 |
mypci_suspend(device_t dev) |
| 161 |
{ |
154 |
{ |
| 162 |
|
155 |
device_printf(dev, "suspend!\n"); |
| 163 |
printf("Mypci suspend!\n"); |
|
|
| 164 |
return (0); |
156 |
return (0); |
| 165 |
} |
157 |
} |
| 166 |
|
158 |
|
| 167 |
/* |
159 |
/* |
| 168 |
* Device resume routine. |
160 |
* Device resume routine. |
| 169 |
*/ |
161 |
*/ |
| 170 |
|
|
|
| 171 |
static int |
162 |
static int |
| 172 |
mypci_resume(device_t dev) |
163 |
mypci_resume(device_t dev) |
| 173 |
{ |
164 |
{ |
| 174 |
|
165 |
device_printf(dev, "resume!\n"); |
| 175 |
printf("Mypci resume!\n"); |
|
|
| 176 |
return (0); |
166 |
return (0); |
| 177 |
} |
167 |
} |
| 178 |
|
168 |
|
|
Lines 191-214
Link Here
|
| 191 |
static driver_t mypci_driver = { |
181 |
static driver_t mypci_driver = { |
| 192 |
"mypci", |
182 |
"mypci", |
| 193 |
mypci_methods, |
183 |
mypci_methods, |
| 194 |
0, |
184 |
0 /* sizeof(struct mypci_softc) */ |
| 195 |
/* sizeof(struct mypci_softc), */ |
|
|
| 196 |
}; |
185 |
}; |
| 197 |
|
186 |
|
| 198 |
static devclass_t mypci_devclass; |
187 |
static devclass_t mypci_devclass; |
| 199 |
|
188 |
|
| 200 |
DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);</programlisting> |
189 |
DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);</programlisting> |
| 201 |
|
190 |
|
| 202 |
<para>Additional Resources |
191 |
</sect2> |
| 203 |
<itemizedlist> |
192 |
<sect2> |
| 204 |
<listitem><simpara><ulink url="http://www.pcisig.org/">PCI |
193 |
<title>Makefile</title> |
| 205 |
Special Interest Group</ulink></simpara></listitem> |
194 |
|
|
|
195 |
<programlisting>KMOD=mypci |
| 196 |
SRCS=mypci.c |
| 197 |
SRCS+=device_if.h bus_if.h pci_if.h |
| 198 |
|
| 199 |
.include <bsd.kmod.mk></programlisting> |
| 200 |
|
| 201 |
<para>Simply running <command>make</command> with the above |
| 202 |
<filename>Makefile</filename> |
| 203 |
will create a file <filename>mypci.ko</filename> that can |
| 204 |
be loaded into your system by typing: |
| 205 |
<screen>&prompt.root; <userinput>kldload ./mypci.ko</userinput></screen> |
| 206 |
</para> |
| 207 |
</sect2> |
| 208 |
<sect2> |
| 209 |
<title>Additional Resources</title> |
| 210 |
<itemizedlist> |
| 211 |
<listitem><simpara><ulink url="http://www.pcisig.org/">PCI |
| 212 |
Special Interest Group</ulink></simpara></listitem> |
| 206 |
|
213 |
|
| 207 |
<listitem><simpara>PCI System Architecture, Fourth Edition by |
214 |
<listitem><simpara>PCI System Architecture, Fourth Edition by |
| 208 |
Tom Shanley, et al.</simpara></listitem> |
215 |
Tom Shanley, et al.</simpara></listitem> |
| 209 |
|
216 |
|
| 210 |
</itemizedlist> |
217 |
</itemizedlist> |
| 211 |
</para> |
218 |
</sect2> |
| 212 |
</sect1> |
219 |
</sect1> |
| 213 |
|
220 |
|
| 214 |
<sect1 id="pci-bus"> |
221 |
<sect1 id="pci-bus"> |