root / hw / char / serial-pci.c @ f53f81e0
History | View | Annotate | Download (8.5 kB)
1 | 419ad672 | Gerd Hoffmann | /*
|
---|---|---|---|
2 | 419ad672 | Gerd Hoffmann | * QEMU 16550A UART emulation
|
3 | 419ad672 | Gerd Hoffmann | *
|
4 | 419ad672 | Gerd Hoffmann | * Copyright (c) 2003-2004 Fabrice Bellard
|
5 | 419ad672 | Gerd Hoffmann | * Copyright (c) 2008 Citrix Systems, Inc.
|
6 | 419ad672 | Gerd Hoffmann | *
|
7 | 419ad672 | Gerd Hoffmann | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 | 419ad672 | Gerd Hoffmann | * of this software and associated documentation files (the "Software"), to deal
|
9 | 419ad672 | Gerd Hoffmann | * in the Software without restriction, including without limitation the rights
|
10 | 419ad672 | Gerd Hoffmann | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 | 419ad672 | Gerd Hoffmann | * copies of the Software, and to permit persons to whom the Software is
|
12 | 419ad672 | Gerd Hoffmann | * furnished to do so, subject to the following conditions:
|
13 | 419ad672 | Gerd Hoffmann | *
|
14 | 419ad672 | Gerd Hoffmann | * The above copyright notice and this permission notice shall be included in
|
15 | 419ad672 | Gerd Hoffmann | * all copies or substantial portions of the Software.
|
16 | 419ad672 | Gerd Hoffmann | *
|
17 | 419ad672 | Gerd Hoffmann | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 | 419ad672 | Gerd Hoffmann | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 | 419ad672 | Gerd Hoffmann | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
20 | 419ad672 | Gerd Hoffmann | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 | 419ad672 | Gerd Hoffmann | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 | 419ad672 | Gerd Hoffmann | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 | 419ad672 | Gerd Hoffmann | * THE SOFTWARE.
|
24 | 419ad672 | Gerd Hoffmann | */
|
25 | 419ad672 | Gerd Hoffmann | |
26 | 90734e02 | Gerd Hoffmann | /* see docs/specs/pci-serial.txt */
|
27 | 90734e02 | Gerd Hoffmann | |
28 | 0d09e41a | Paolo Bonzini | #include "hw/char/serial.h" |
29 | 83c9f4ca | Paolo Bonzini | #include "hw/pci/pci.h" |
30 | db895a1e | Andreas Färber | #include "qapi/qmp/qerror.h" |
31 | 419ad672 | Gerd Hoffmann | |
32 | d66bbea4 | Gerd Hoffmann | #define PCI_SERIAL_MAX_PORTS 4 |
33 | d66bbea4 | Gerd Hoffmann | |
34 | 419ad672 | Gerd Hoffmann | typedef struct PCISerialState { |
35 | 419ad672 | Gerd Hoffmann | PCIDevice dev; |
36 | 419ad672 | Gerd Hoffmann | SerialState state; |
37 | 419ad672 | Gerd Hoffmann | } PCISerialState; |
38 | 419ad672 | Gerd Hoffmann | |
39 | d66bbea4 | Gerd Hoffmann | typedef struct PCIMultiSerialState { |
40 | d66bbea4 | Gerd Hoffmann | PCIDevice dev; |
41 | d66bbea4 | Gerd Hoffmann | MemoryRegion iobar; |
42 | d66bbea4 | Gerd Hoffmann | uint32_t ports; |
43 | d66bbea4 | Gerd Hoffmann | char *name[PCI_SERIAL_MAX_PORTS];
|
44 | d66bbea4 | Gerd Hoffmann | SerialState state[PCI_SERIAL_MAX_PORTS]; |
45 | d66bbea4 | Gerd Hoffmann | uint32_t level[PCI_SERIAL_MAX_PORTS]; |
46 | d66bbea4 | Gerd Hoffmann | qemu_irq *irqs; |
47 | d66bbea4 | Gerd Hoffmann | } PCIMultiSerialState; |
48 | d66bbea4 | Gerd Hoffmann | |
49 | 419ad672 | Gerd Hoffmann | static int serial_pci_init(PCIDevice *dev) |
50 | 419ad672 | Gerd Hoffmann | { |
51 | 419ad672 | Gerd Hoffmann | PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev); |
52 | 419ad672 | Gerd Hoffmann | SerialState *s = &pci->state; |
53 | db895a1e | Andreas Färber | Error *err = NULL;
|
54 | 419ad672 | Gerd Hoffmann | |
55 | 419ad672 | Gerd Hoffmann | s->baudbase = 115200;
|
56 | db895a1e | Andreas Färber | serial_realize_core(s, &err); |
57 | db895a1e | Andreas Färber | if (err != NULL) { |
58 | db895a1e | Andreas Färber | qerror_report_err(err); |
59 | db895a1e | Andreas Färber | error_free(err); |
60 | db895a1e | Andreas Färber | return -1; |
61 | db895a1e | Andreas Färber | } |
62 | 419ad672 | Gerd Hoffmann | |
63 | 419ad672 | Gerd Hoffmann | pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
|
64 | 9e64f8a3 | Marcel Apfelbaum | s->irq = pci_allocate_irq(&pci->dev); |
65 | 419ad672 | Gerd Hoffmann | |
66 | 300b1fc6 | Paolo Bonzini | memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s, "serial", 8); |
67 | 419ad672 | Gerd Hoffmann | pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
|
68 | 419ad672 | Gerd Hoffmann | return 0; |
69 | 419ad672 | Gerd Hoffmann | } |
70 | 419ad672 | Gerd Hoffmann | |
71 | d66bbea4 | Gerd Hoffmann | static void multi_serial_irq_mux(void *opaque, int n, int level) |
72 | d66bbea4 | Gerd Hoffmann | { |
73 | d66bbea4 | Gerd Hoffmann | PCIMultiSerialState *pci = opaque; |
74 | d66bbea4 | Gerd Hoffmann | int i, pending = 0; |
75 | d66bbea4 | Gerd Hoffmann | |
76 | d66bbea4 | Gerd Hoffmann | pci->level[n] = level; |
77 | d66bbea4 | Gerd Hoffmann | for (i = 0; i < pci->ports; i++) { |
78 | d66bbea4 | Gerd Hoffmann | if (pci->level[i]) {
|
79 | d66bbea4 | Gerd Hoffmann | pending = 1;
|
80 | d66bbea4 | Gerd Hoffmann | } |
81 | d66bbea4 | Gerd Hoffmann | } |
82 | 9e64f8a3 | Marcel Apfelbaum | pci_set_irq(&pci->dev, pending); |
83 | d66bbea4 | Gerd Hoffmann | } |
84 | d66bbea4 | Gerd Hoffmann | |
85 | d66bbea4 | Gerd Hoffmann | static int multi_serial_pci_init(PCIDevice *dev) |
86 | d66bbea4 | Gerd Hoffmann | { |
87 | d66bbea4 | Gerd Hoffmann | PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); |
88 | d66bbea4 | Gerd Hoffmann | PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev); |
89 | d66bbea4 | Gerd Hoffmann | SerialState *s; |
90 | db895a1e | Andreas Färber | Error *err = NULL;
|
91 | d66bbea4 | Gerd Hoffmann | int i;
|
92 | d66bbea4 | Gerd Hoffmann | |
93 | d66bbea4 | Gerd Hoffmann | switch (pc->device_id) {
|
94 | d66bbea4 | Gerd Hoffmann | case 0x0003: |
95 | d66bbea4 | Gerd Hoffmann | pci->ports = 2;
|
96 | d66bbea4 | Gerd Hoffmann | break;
|
97 | d66bbea4 | Gerd Hoffmann | case 0x0004: |
98 | d66bbea4 | Gerd Hoffmann | pci->ports = 4;
|
99 | d66bbea4 | Gerd Hoffmann | break;
|
100 | d66bbea4 | Gerd Hoffmann | } |
101 | d66bbea4 | Gerd Hoffmann | assert(pci->ports > 0);
|
102 | d66bbea4 | Gerd Hoffmann | assert(pci->ports <= PCI_SERIAL_MAX_PORTS); |
103 | d66bbea4 | Gerd Hoffmann | |
104 | d66bbea4 | Gerd Hoffmann | pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
|
105 | 300b1fc6 | Paolo Bonzini | memory_region_init(&pci->iobar, OBJECT(pci), "multiserial", 8 * pci->ports); |
106 | d66bbea4 | Gerd Hoffmann | pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->iobar);
|
107 | d66bbea4 | Gerd Hoffmann | pci->irqs = qemu_allocate_irqs(multi_serial_irq_mux, pci, |
108 | d66bbea4 | Gerd Hoffmann | pci->ports); |
109 | d66bbea4 | Gerd Hoffmann | |
110 | d66bbea4 | Gerd Hoffmann | for (i = 0; i < pci->ports; i++) { |
111 | d66bbea4 | Gerd Hoffmann | s = pci->state + i; |
112 | d66bbea4 | Gerd Hoffmann | s->baudbase = 115200;
|
113 | db895a1e | Andreas Färber | serial_realize_core(s, &err); |
114 | db895a1e | Andreas Färber | if (err != NULL) { |
115 | db895a1e | Andreas Färber | qerror_report_err(err); |
116 | db895a1e | Andreas Färber | error_free(err); |
117 | db895a1e | Andreas Färber | return -1; |
118 | db895a1e | Andreas Färber | } |
119 | d66bbea4 | Gerd Hoffmann | s->irq = pci->irqs[i]; |
120 | d66bbea4 | Gerd Hoffmann | pci->name[i] = g_strdup_printf("uart #%d", i+1); |
121 | 300b1fc6 | Paolo Bonzini | memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s, |
122 | 300b1fc6 | Paolo Bonzini | pci->name[i], 8);
|
123 | d66bbea4 | Gerd Hoffmann | memory_region_add_subregion(&pci->iobar, 8 * i, &s->io);
|
124 | d66bbea4 | Gerd Hoffmann | } |
125 | d66bbea4 | Gerd Hoffmann | return 0; |
126 | d66bbea4 | Gerd Hoffmann | } |
127 | d66bbea4 | Gerd Hoffmann | |
128 | 419ad672 | Gerd Hoffmann | static void serial_pci_exit(PCIDevice *dev) |
129 | 419ad672 | Gerd Hoffmann | { |
130 | 419ad672 | Gerd Hoffmann | PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev); |
131 | 419ad672 | Gerd Hoffmann | SerialState *s = &pci->state; |
132 | 419ad672 | Gerd Hoffmann | |
133 | 419ad672 | Gerd Hoffmann | serial_exit_core(s); |
134 | 419ad672 | Gerd Hoffmann | memory_region_destroy(&s->io); |
135 | 9e64f8a3 | Marcel Apfelbaum | qemu_free_irq(s->irq); |
136 | 419ad672 | Gerd Hoffmann | } |
137 | 419ad672 | Gerd Hoffmann | |
138 | d66bbea4 | Gerd Hoffmann | static void multi_serial_pci_exit(PCIDevice *dev) |
139 | d66bbea4 | Gerd Hoffmann | { |
140 | d66bbea4 | Gerd Hoffmann | PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev); |
141 | d66bbea4 | Gerd Hoffmann | SerialState *s; |
142 | d66bbea4 | Gerd Hoffmann | int i;
|
143 | d66bbea4 | Gerd Hoffmann | |
144 | d66bbea4 | Gerd Hoffmann | for (i = 0; i < pci->ports; i++) { |
145 | d66bbea4 | Gerd Hoffmann | s = pci->state + i; |
146 | d66bbea4 | Gerd Hoffmann | serial_exit_core(s); |
147 | d66bbea4 | Gerd Hoffmann | memory_region_destroy(&s->io); |
148 | d66bbea4 | Gerd Hoffmann | g_free(pci->name[i]); |
149 | d66bbea4 | Gerd Hoffmann | } |
150 | d66bbea4 | Gerd Hoffmann | memory_region_destroy(&pci->iobar); |
151 | d66bbea4 | Gerd Hoffmann | qemu_free_irqs(pci->irqs); |
152 | d66bbea4 | Gerd Hoffmann | } |
153 | d66bbea4 | Gerd Hoffmann | |
154 | 419ad672 | Gerd Hoffmann | static const VMStateDescription vmstate_pci_serial = { |
155 | 419ad672 | Gerd Hoffmann | .name = "pci-serial",
|
156 | 419ad672 | Gerd Hoffmann | .version_id = 1,
|
157 | 419ad672 | Gerd Hoffmann | .minimum_version_id = 1,
|
158 | 419ad672 | Gerd Hoffmann | .fields = (VMStateField[]) { |
159 | 419ad672 | Gerd Hoffmann | VMSTATE_PCI_DEVICE(dev, PCISerialState), |
160 | 419ad672 | Gerd Hoffmann | VMSTATE_STRUCT(state, PCISerialState, 0, vmstate_serial, SerialState),
|
161 | 419ad672 | Gerd Hoffmann | VMSTATE_END_OF_LIST() |
162 | 419ad672 | Gerd Hoffmann | } |
163 | 419ad672 | Gerd Hoffmann | }; |
164 | 419ad672 | Gerd Hoffmann | |
165 | d66bbea4 | Gerd Hoffmann | static const VMStateDescription vmstate_pci_multi_serial = { |
166 | d66bbea4 | Gerd Hoffmann | .name = "pci-serial-multi",
|
167 | d66bbea4 | Gerd Hoffmann | .version_id = 1,
|
168 | d66bbea4 | Gerd Hoffmann | .minimum_version_id = 1,
|
169 | d66bbea4 | Gerd Hoffmann | .fields = (VMStateField[]) { |
170 | d66bbea4 | Gerd Hoffmann | VMSTATE_PCI_DEVICE(dev, PCIMultiSerialState), |
171 | d66bbea4 | Gerd Hoffmann | VMSTATE_STRUCT_ARRAY(state, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS, |
172 | d66bbea4 | Gerd Hoffmann | 0, vmstate_serial, SerialState),
|
173 | d66bbea4 | Gerd Hoffmann | VMSTATE_UINT32_ARRAY(level, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS), |
174 | d66bbea4 | Gerd Hoffmann | VMSTATE_END_OF_LIST() |
175 | d66bbea4 | Gerd Hoffmann | } |
176 | d66bbea4 | Gerd Hoffmann | }; |
177 | d66bbea4 | Gerd Hoffmann | |
178 | 419ad672 | Gerd Hoffmann | static Property serial_pci_properties[] = {
|
179 | 419ad672 | Gerd Hoffmann | DEFINE_PROP_CHR("chardev", PCISerialState, state.chr),
|
180 | 419ad672 | Gerd Hoffmann | DEFINE_PROP_END_OF_LIST(), |
181 | 419ad672 | Gerd Hoffmann | }; |
182 | 419ad672 | Gerd Hoffmann | |
183 | d66bbea4 | Gerd Hoffmann | static Property multi_2x_serial_pci_properties[] = {
|
184 | d66bbea4 | Gerd Hoffmann | DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr), |
185 | d66bbea4 | Gerd Hoffmann | DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr), |
186 | d66bbea4 | Gerd Hoffmann | DEFINE_PROP_END_OF_LIST(), |
187 | d66bbea4 | Gerd Hoffmann | }; |
188 | d66bbea4 | Gerd Hoffmann | |
189 | d66bbea4 | Gerd Hoffmann | static Property multi_4x_serial_pci_properties[] = {
|
190 | d66bbea4 | Gerd Hoffmann | DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr), |
191 | d66bbea4 | Gerd Hoffmann | DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr), |
192 | d66bbea4 | Gerd Hoffmann | DEFINE_PROP_CHR("chardev3", PCIMultiSerialState, state[2].chr), |
193 | d66bbea4 | Gerd Hoffmann | DEFINE_PROP_CHR("chardev4", PCIMultiSerialState, state[3].chr), |
194 | d66bbea4 | Gerd Hoffmann | DEFINE_PROP_END_OF_LIST(), |
195 | d66bbea4 | Gerd Hoffmann | }; |
196 | d66bbea4 | Gerd Hoffmann | |
197 | 419ad672 | Gerd Hoffmann | static void serial_pci_class_initfn(ObjectClass *klass, void *data) |
198 | 419ad672 | Gerd Hoffmann | { |
199 | 419ad672 | Gerd Hoffmann | DeviceClass *dc = DEVICE_CLASS(klass); |
200 | 419ad672 | Gerd Hoffmann | PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); |
201 | 419ad672 | Gerd Hoffmann | pc->init = serial_pci_init; |
202 | 419ad672 | Gerd Hoffmann | pc->exit = serial_pci_exit; |
203 | 5c03a254 | Paolo Bonzini | pc->vendor_id = PCI_VENDOR_ID_REDHAT; |
204 | 5c03a254 | Paolo Bonzini | pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL; |
205 | 419ad672 | Gerd Hoffmann | pc->revision = 1;
|
206 | 419ad672 | Gerd Hoffmann | pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL; |
207 | 419ad672 | Gerd Hoffmann | dc->vmsd = &vmstate_pci_serial; |
208 | 419ad672 | Gerd Hoffmann | dc->props = serial_pci_properties; |
209 | 125ee0ed | Marcel Apfelbaum | set_bit(DEVICE_CATEGORY_INPUT, dc->categories); |
210 | 419ad672 | Gerd Hoffmann | } |
211 | 419ad672 | Gerd Hoffmann | |
212 | d66bbea4 | Gerd Hoffmann | static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data) |
213 | d66bbea4 | Gerd Hoffmann | { |
214 | d66bbea4 | Gerd Hoffmann | DeviceClass *dc = DEVICE_CLASS(klass); |
215 | d66bbea4 | Gerd Hoffmann | PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); |
216 | d66bbea4 | Gerd Hoffmann | pc->init = multi_serial_pci_init; |
217 | d66bbea4 | Gerd Hoffmann | pc->exit = multi_serial_pci_exit; |
218 | 5c03a254 | Paolo Bonzini | pc->vendor_id = PCI_VENDOR_ID_REDHAT; |
219 | 5c03a254 | Paolo Bonzini | pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL2; |
220 | d66bbea4 | Gerd Hoffmann | pc->revision = 1;
|
221 | d66bbea4 | Gerd Hoffmann | pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL; |
222 | d66bbea4 | Gerd Hoffmann | dc->vmsd = &vmstate_pci_multi_serial; |
223 | d66bbea4 | Gerd Hoffmann | dc->props = multi_2x_serial_pci_properties; |
224 | 125ee0ed | Marcel Apfelbaum | set_bit(DEVICE_CATEGORY_INPUT, dc->categories); |
225 | d66bbea4 | Gerd Hoffmann | } |
226 | d66bbea4 | Gerd Hoffmann | |
227 | d66bbea4 | Gerd Hoffmann | static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data) |
228 | d66bbea4 | Gerd Hoffmann | { |
229 | d66bbea4 | Gerd Hoffmann | DeviceClass *dc = DEVICE_CLASS(klass); |
230 | d66bbea4 | Gerd Hoffmann | PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); |
231 | d66bbea4 | Gerd Hoffmann | pc->init = multi_serial_pci_init; |
232 | d66bbea4 | Gerd Hoffmann | pc->exit = multi_serial_pci_exit; |
233 | 5c03a254 | Paolo Bonzini | pc->vendor_id = PCI_VENDOR_ID_REDHAT; |
234 | 5c03a254 | Paolo Bonzini | pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL4; |
235 | d66bbea4 | Gerd Hoffmann | pc->revision = 1;
|
236 | d66bbea4 | Gerd Hoffmann | pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL; |
237 | d66bbea4 | Gerd Hoffmann | dc->vmsd = &vmstate_pci_multi_serial; |
238 | d66bbea4 | Gerd Hoffmann | dc->props = multi_4x_serial_pci_properties; |
239 | 125ee0ed | Marcel Apfelbaum | set_bit(DEVICE_CATEGORY_INPUT, dc->categories); |
240 | d66bbea4 | Gerd Hoffmann | } |
241 | d66bbea4 | Gerd Hoffmann | |
242 | 8c43a6f0 | Andreas Färber | static const TypeInfo serial_pci_info = { |
243 | 419ad672 | Gerd Hoffmann | .name = "pci-serial",
|
244 | 419ad672 | Gerd Hoffmann | .parent = TYPE_PCI_DEVICE, |
245 | 419ad672 | Gerd Hoffmann | .instance_size = sizeof(PCISerialState),
|
246 | 419ad672 | Gerd Hoffmann | .class_init = serial_pci_class_initfn, |
247 | 419ad672 | Gerd Hoffmann | }; |
248 | 419ad672 | Gerd Hoffmann | |
249 | 8c43a6f0 | Andreas Färber | static const TypeInfo multi_2x_serial_pci_info = { |
250 | d66bbea4 | Gerd Hoffmann | .name = "pci-serial-2x",
|
251 | d66bbea4 | Gerd Hoffmann | .parent = TYPE_PCI_DEVICE, |
252 | d66bbea4 | Gerd Hoffmann | .instance_size = sizeof(PCIMultiSerialState),
|
253 | d66bbea4 | Gerd Hoffmann | .class_init = multi_2x_serial_pci_class_initfn, |
254 | d66bbea4 | Gerd Hoffmann | }; |
255 | d66bbea4 | Gerd Hoffmann | |
256 | 8c43a6f0 | Andreas Färber | static const TypeInfo multi_4x_serial_pci_info = { |
257 | d66bbea4 | Gerd Hoffmann | .name = "pci-serial-4x",
|
258 | d66bbea4 | Gerd Hoffmann | .parent = TYPE_PCI_DEVICE, |
259 | d66bbea4 | Gerd Hoffmann | .instance_size = sizeof(PCIMultiSerialState),
|
260 | d66bbea4 | Gerd Hoffmann | .class_init = multi_4x_serial_pci_class_initfn, |
261 | d66bbea4 | Gerd Hoffmann | }; |
262 | d66bbea4 | Gerd Hoffmann | |
263 | 419ad672 | Gerd Hoffmann | static void serial_pci_register_types(void) |
264 | 419ad672 | Gerd Hoffmann | { |
265 | 419ad672 | Gerd Hoffmann | type_register_static(&serial_pci_info); |
266 | d66bbea4 | Gerd Hoffmann | type_register_static(&multi_2x_serial_pci_info); |
267 | d66bbea4 | Gerd Hoffmann | type_register_static(&multi_4x_serial_pci_info); |
268 | 419ad672 | Gerd Hoffmann | } |
269 | 419ad672 | Gerd Hoffmann | |
270 | 419ad672 | Gerd Hoffmann | type_init(serial_pci_register_types) |