obio.c revision 1.52 1 /* $NetBSD: obio.c,v 1.52 2022/12/28 07:12:36 macallan Exp $ */
2
3 /*-
4 * Copyright (C) 1998 Internet Research Institute, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by
18 * Internet Research Institute, Inc.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.52 2022/12/28 07:12:36 macallan Exp $");
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/device.h>
41 #include <sys/sysctl.h>
42
43 #include <dev/pci/pcivar.h>
44 #include <dev/pci/pcidevs.h>
45
46 #include <dev/ofw/openfirm.h>
47
48 #include <machine/autoconf.h>
49
50 #include <macppc/dev/obiovar.h>
51
52 #include <powerpc/cpu.h>
53 #include <sys/cpufreq.h>
54
55 #include "opt_obio.h"
56
57 #ifdef OBIO_DEBUG
58 # define DPRINTF printf
59 #else
60 # define DPRINTF while (0) printf
61 #endif
62
63 static void obio_attach(device_t, device_t, void *);
64 static int obio_match(device_t, cfdata_t, void *);
65 static int obio_print(void *, const char *);
66
67 struct obio_softc {
68 device_t sc_dev;
69 bus_space_tag_t sc_tag;
70 bus_space_handle_t sc_bh;
71 int sc_node;
72 #ifdef OBIO_SPEED_CONTROL
73 int sc_voltage;
74 int sc_busspeed;
75 int sc_spd_hi, sc_spd_lo;
76 struct cpufreq sc_cf;
77 #endif
78 };
79
80 static struct obio_softc *obio0 = NULL;
81
82 #ifdef OBIO_SPEED_CONTROL
83 static void obio_setup_gpios(struct obio_softc *, int);
84 static void obio_set_cpu_speed(struct obio_softc *, int);
85 static int obio_get_cpu_speed(struct obio_softc *);
86 static int sysctl_cpuspeed_temp(SYSCTLFN_ARGS);
87 static int sysctl_cpuspeed_cur(SYSCTLFN_ARGS);
88 static int sysctl_cpuspeed_available(SYSCTLFN_ARGS);
89 static void obio_get_freq(void *, void *);
90 static void obio_set_freq(void *, void *);
91 static const char *keylargo[] = {"Keylargo",
92 "AAPL,Keylargo",
93 NULL};
94
95 #endif
96
97 CFATTACH_DECL_NEW(obio, sizeof(struct obio_softc),
98 obio_match, obio_attach, NULL, NULL);
99
100 int
101 obio_match(device_t parent, cfdata_t cf, void *aux)
102 {
103 struct pci_attach_args *pa = aux;
104
105 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_APPLE)
106 switch (PCI_PRODUCT(pa->pa_id)) {
107 case PCI_PRODUCT_APPLE_GC:
108 case PCI_PRODUCT_APPLE_OHARE:
109 case PCI_PRODUCT_APPLE_HEATHROW:
110 case PCI_PRODUCT_APPLE_PADDINGTON:
111 case PCI_PRODUCT_APPLE_KEYLARGO:
112 case PCI_PRODUCT_APPLE_PANGEA_MACIO:
113 case PCI_PRODUCT_APPLE_INTREPID:
114 case PCI_PRODUCT_APPLE_K2:
115 case PCI_PRODUCT_APPLE_SHASTA:
116 return 1;
117 }
118
119 return 0;
120 }
121
122 /*
123 * Attach all the sub-devices we can find
124 */
125 void
126 obio_attach(device_t parent, device_t self, void *aux)
127 {
128 struct obio_softc *sc = device_private(self);
129 struct pci_attach_args *pa = aux;
130 struct confargs ca;
131 bus_space_handle_t bsh;
132 int node, child, namelen, error;
133 u_int reg[20];
134 int intr[6], parent_intr = 0, parent_nintr = 0;
135 int map_size = 0x1000;
136 char name[32];
137 char compat[32];
138
139 sc->sc_dev = self;
140 #ifdef OBIO_SPEED_CONTROL
141 sc->sc_voltage = -1;
142 sc->sc_busspeed = -1;
143 sc->sc_spd_lo = 600;
144 sc->sc_spd_hi = 800;
145 #endif
146
147 switch (PCI_PRODUCT(pa->pa_id)) {
148
149 case PCI_PRODUCT_APPLE_GC:
150 case PCI_PRODUCT_APPLE_OHARE:
151 case PCI_PRODUCT_APPLE_HEATHROW:
152 case PCI_PRODUCT_APPLE_PADDINGTON:
153 case PCI_PRODUCT_APPLE_KEYLARGO:
154 case PCI_PRODUCT_APPLE_PANGEA_MACIO:
155 case PCI_PRODUCT_APPLE_INTREPID:
156 node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag);
157 if (node == -1)
158 node = OF_finddevice("mac-io");
159 if (node == -1)
160 node = OF_finddevice("/pci/mac-io");
161 break;
162 case PCI_PRODUCT_APPLE_K2:
163 case PCI_PRODUCT_APPLE_SHASTA:
164 node = OF_finddevice("mac-io");
165 map_size = 0x10000;
166 break;
167
168 default:
169 node = -1;
170 break;
171 }
172 if (node == -1)
173 panic("macio not found or unknown");
174
175 sc->sc_node = node;
176
177 #if defined (PMAC_G5)
178 if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 20)
179 {
180 return;
181 }
182 #else
183 if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 12)
184 return;
185 #endif /* PMAC_G5 */
186
187 /*
188 * XXX
189 * This relies on the primary obio always attaching first which is
190 * true on the PowerBook 3400c and similar machines but may or may
191 * not work on others. We can't rely on the node name since Apple
192 * didn't follow anything remotely resembling a consistent naming
193 * scheme.
194 */
195 if (obio0 == NULL)
196 obio0 = sc;
197
198 ca.ca_baseaddr = reg[2];
199 ca.ca_tag = pa->pa_memt;
200 sc->sc_tag = pa->pa_memt;
201 error = bus_space_map (pa->pa_memt, ca.ca_baseaddr, map_size, 0, &bsh);
202 if (error)
203 panic(": failed to map mac-io %#x", ca.ca_baseaddr);
204 sc->sc_bh = bsh;
205
206 printf(": addr 0x%x\n", ca.ca_baseaddr);
207
208 /* Enable internal modem (KeyLargo) */
209 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_KEYLARGO) {
210 aprint_normal("%s: enabling KeyLargo internal modem\n",
211 device_xname(self));
212 bus_space_write_4(ca.ca_tag, bsh, 0x40,
213 bus_space_read_4(ca.ca_tag, bsh, 0x40) & ~(1<<25));
214 }
215
216 /* Enable internal modem (Pangea) */
217 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PANGEA_MACIO) {
218 /* set reset */
219 bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x03, 0x04);
220 /* power modem on */
221 bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x02, 0x04);
222 /* unset reset */
223 bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x03, 0x05);
224 }
225
226 /* Gatwick and Paddington use same product ID */
227 namelen = OF_getprop(node, "compatible", compat, sizeof(compat));
228
229 if (strcmp(compat, "gatwick") == 0) {
230 parent_nintr = OF_getprop(node, "AAPL,interrupts", intr,
231 sizeof(intr));
232 parent_intr = intr[0];
233 } else {
234 /* Enable CD and microphone sound input. */
235 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PADDINGTON)
236 bus_space_write_1(ca.ca_tag, bsh, 0x37, 0x03);
237 }
238
239 devhandle_t selfh = device_handle(self);
240 for (child = OF_child(node); child; child = OF_peer(child)) {
241 namelen = OF_getprop(child, "name", name, sizeof(name));
242 if (namelen < 0)
243 continue;
244 if (namelen >= sizeof(name))
245 continue;
246
247 #ifdef OBIO_SPEED_CONTROL
248 if (strcmp(name, "gpio") == 0) {
249
250 obio_setup_gpios(sc, child);
251 continue;
252 }
253 #endif
254
255 name[namelen] = 0;
256 ca.ca_name = name;
257 ca.ca_node = child;
258 ca.ca_tag = pa->pa_memt;
259
260 ca.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg));
261
262 if (strcmp(compat, "gatwick") != 0) {
263 ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr,
264 sizeof(intr));
265 if (ca.ca_nintr == -1)
266 ca.ca_nintr = OF_getprop(child, "interrupts", intr,
267 sizeof(intr));
268 } else {
269 intr[0] = parent_intr;
270 ca.ca_nintr = parent_nintr;
271 }
272 ca.ca_reg = reg;
273 ca.ca_intr = intr;
274
275 config_found(self, &ca, obio_print,
276 CFARGS(.devhandle = devhandle_from_of(selfh, child)));
277 }
278 }
279
280 static const char * const skiplist[] = {
281 "interrupt-controller",
282 "chrp,open-pic",
283 "open-pic",
284 "gpio",
285 "escc-legacy",
286 "timer",
287 "i2c",
288 "power-mgt",
289 "escc",
290 "battery",
291 "backlight"
292
293 };
294
295 #define N_LIST (sizeof(skiplist) / sizeof(skiplist[0]))
296
297 int
298 obio_print(void *aux, const char *obio)
299 {
300 struct confargs *ca = aux;
301 int i;
302
303 for (i = 0; i < N_LIST; i++)
304 if (strcmp(ca->ca_name, skiplist[i]) == 0)
305 return QUIET;
306
307 if (obio)
308 aprint_normal("%s at %s", ca->ca_name, obio);
309
310 if (ca->ca_nreg > 0)
311 aprint_normal(" offset 0x%x", ca->ca_reg[0]);
312
313 return UNCONF;
314 }
315
316 void obio_write_4(int offset, uint32_t value)
317 {
318 if (obio0 == NULL)
319 return;
320 bus_space_write_4(obio0->sc_tag, obio0->sc_bh, offset, value);
321 }
322
323 void obio_write_1(int offset, uint8_t value)
324 {
325 if (obio0 == NULL)
326 return;
327 bus_space_write_1(obio0->sc_tag, obio0->sc_bh, offset, value);
328 }
329
330 uint32_t obio_read_4(int offset)
331 {
332 if (obio0 == NULL)
333 return 0xffffffff;
334 return bus_space_read_4(obio0->sc_tag, obio0->sc_bh, offset);
335 }
336
337 uint8_t obio_read_1(int offset)
338 {
339 if (obio0 == NULL)
340 return 0xff;
341 return bus_space_read_1(obio0->sc_tag, obio0->sc_bh, offset);
342 }
343
344 int
345 obio_space_map(bus_addr_t addr, bus_size_t size, bus_space_handle_t *bh)
346 {
347 if (obio0 == NULL)
348 return 0xff;
349 return bus_space_subregion(obio0->sc_tag, obio0->sc_bh,
350 addr & 0xfffff, size, bh);
351 }
352
353 #ifdef OBIO_SPEED_CONTROL
354
355 static void
356 obio_setup_cpufreq(device_t dev)
357 {
358 struct obio_softc *sc = device_private(dev);
359 int ret;
360
361 ret = cpufreq_register(&sc->sc_cf);
362 if (ret != 0)
363 aprint_error_dev(sc->sc_dev, "cpufreq_register() failed, error %d\n", ret);
364 }
365
366 static void
367 obio_setup_gpios(struct obio_softc *sc, int node)
368 {
369 uint32_t gpio_base, reg[6];
370 const struct sysctlnode *sysctl_node, *me, *freq;
371 struct cpufreq *cf = &sc->sc_cf;
372 char name[32];
373 int child, use_dfs, cpunode, hiclock;
374
375 if (! of_compatible(sc->sc_node, keylargo))
376 return;
377
378 if (OF_getprop(node, "reg", reg, sizeof(reg)) < 4)
379 return;
380
381 gpio_base = reg[0];
382 DPRINTF("gpio_base: %02x\n", gpio_base);
383
384 /* now look for voltage and bus speed gpios */
385 use_dfs = 0;
386 for (child = OF_child(node); child; child = OF_peer(child)) {
387
388 if (OF_getprop(child, "name", name, sizeof(name)) < 1)
389 continue;
390
391 if (OF_getprop(child, "reg", reg, sizeof(reg)) < 4)
392 continue;
393
394 /*
395 * These register offsets either have to be added to the obio
396 * base address or to the gpio base address. This differs
397 * even in the same OF-tree! So we guess the offset is
398 * based on obio when it is larger than the gpio_base.
399 */
400 if (reg[0] >= gpio_base)
401 reg[0] -= gpio_base;
402
403 if (strcmp(name, "frequency-gpio") == 0) {
404 DPRINTF("found frequency_gpio at %02x\n", reg[0]);
405 sc->sc_busspeed = gpio_base + reg[0];
406 }
407 if (strcmp(name, "voltage-gpio") == 0) {
408 DPRINTF("found voltage_gpio at %02x\n", reg[0]);
409 sc->sc_voltage = gpio_base + reg[0];
410 }
411 if (strcmp(name, "cpu-vcore-select") == 0) {
412 DPRINTF("found cpu-vcore-select at %02x\n", reg[0]);
413 sc->sc_voltage = gpio_base + reg[0];
414 /* frequency gpio is not needed, we use cpu's DFS */
415 use_dfs = 1;
416 }
417 }
418
419 if ((sc->sc_voltage < 0) || (sc->sc_busspeed < 0 && !use_dfs))
420 return;
421
422 printf("%s: enabling Intrepid CPU speed control\n",
423 device_xname(sc->sc_dev));
424
425 sc->sc_spd_lo = curcpu()->ci_khz / 1000;
426 hiclock = 0;
427 cpunode = OF_finddevice("/cpus/@0");
428 OF_getprop(cpunode, "clock-frequency", &hiclock, 4);
429 if (hiclock != 0)
430 sc->sc_spd_hi = (hiclock + 500000) / 1000000;
431 printf("hiclock: %d\n", sc->sc_spd_hi);
432 if (use_dfs) sc->sc_spd_lo = sc->sc_spd_hi / 2;
433
434 sysctl_node = NULL;
435
436 if (sysctl_createv(NULL, 0, NULL,
437 &me,
438 CTLFLAG_READWRITE, CTLTYPE_NODE, "cpu", NULL, NULL,
439 0, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL) != 0)
440 printf("couldn't create 'cpu' node\n");
441
442 if (sysctl_createv(NULL, 0, NULL,
443 &freq,
444 CTLFLAG_READWRITE, CTLTYPE_NODE, "frequency", NULL, NULL,
445 0, NULL, 0, CTL_MACHDEP, me->sysctl_num, CTL_CREATE, CTL_EOL) != 0)
446 printf("couldn't create 'frequency' node\n");
447
448 if (sysctl_createv(NULL, 0, NULL,
449 &sysctl_node,
450 CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
451 CTLTYPE_INT, "target", "CPU speed", sysctl_cpuspeed_temp,
452 0, (void *)sc, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num,
453 CTL_CREATE, CTL_EOL) == 0) {
454 } else
455 printf("couldn't create 'target' node\n");
456
457 if (sysctl_createv(NULL, 0, NULL,
458 &sysctl_node,
459 CTLFLAG_READWRITE,
460 CTLTYPE_INT, "current", NULL, sysctl_cpuspeed_cur,
461 1, (void *)sc, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num,
462 CTL_CREATE, CTL_EOL) == 0) {
463 } else
464 printf("couldn't create 'current' node\n");
465
466 if (sysctl_createv(NULL, 0, NULL,
467 &sysctl_node,
468 CTLFLAG_READWRITE,
469 CTLTYPE_STRING, "available", NULL, sysctl_cpuspeed_available,
470 2, (void *)sc, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num,
471 CTL_CREATE, CTL_EOL) == 0) {
472 } else
473 printf("couldn't create 'available' node\n");
474 printf("speed: %d\n", curcpu()->ci_khz);
475
476 /* support cpufreq */
477 snprintf(cf->cf_name, CPUFREQ_NAME_MAX, "Intrepid");
478 cf->cf_state[0].cfs_freq = sc->sc_spd_hi;
479 cf->cf_state[1].cfs_freq = sc->sc_spd_lo;
480 cf->cf_state_count = 2;
481 cf->cf_mp = FALSE;
482 cf->cf_cookie = sc;
483 cf->cf_get_freq = obio_get_freq;
484 cf->cf_set_freq = obio_set_freq;
485 /*
486 * XXX
487 * cpufreq_register() calls xc_broadcast() which relies on kthreads
488 * running so we need to postpone it
489 */
490 config_interrupts(sc->sc_dev, obio_setup_cpufreq);
491 }
492
493 static void
494 obio_set_cpu_speed(struct obio_softc *sc, int fast)
495 {
496
497 if (sc->sc_voltage < 0)
498 return;
499
500 if (sc->sc_busspeed >= 0) {
501 /* set voltage and speed via gpio */
502 if (fast) {
503 bus_space_write_1(sc->sc_tag, sc->sc_bh,
504 sc->sc_voltage, 5);
505 bus_space_write_1(sc->sc_tag, sc->sc_bh,
506 sc->sc_busspeed, 5);
507 } else {
508 bus_space_write_1(sc->sc_tag, sc->sc_bh,
509 sc->sc_busspeed, 4);
510 bus_space_write_1(sc->sc_tag, sc->sc_bh,
511 sc->sc_voltage, 4);
512 }
513 }
514 else {
515 /* set voltage via gpio and speed via the 7447A's DFS bit */
516 if (fast) {
517 bus_space_write_1(sc->sc_tag, sc->sc_bh,
518 sc->sc_voltage, 5);
519 DELAY(1000);
520 }
521
522 /* set DFS for all cpus */
523 cpu_set_dfs(fast ? 1 : 2);
524 DELAY(100);
525
526 if (!fast) {
527 bus_space_write_1(sc->sc_tag, sc->sc_bh,
528 sc->sc_voltage, 4);
529 DELAY(1000);
530 }
531 }
532 }
533
534 static int
535 obio_get_cpu_speed(struct obio_softc *sc)
536 {
537
538 if (sc->sc_voltage < 0)
539 return 0;
540
541 if (sc->sc_busspeed >= 0) {
542 if (bus_space_read_1(sc->sc_tag, sc->sc_bh, sc->sc_busspeed)
543 & 1)
544 return 1;
545 }
546 else
547 return cpu_get_dfs() == 1;
548
549 return 0;
550 }
551
552 static void
553 obio_get_freq(void *cookie, void *spd)
554 {
555 struct obio_softc *sc = cookie;
556 uint32_t *freq;
557
558 freq = spd;
559 if (obio_get_cpu_speed(sc) == 0) {
560 *freq = sc->sc_spd_lo;
561 } else
562 *freq = sc->sc_spd_hi;
563 }
564
565 static void
566 obio_set_freq(void *cookie, void *spd)
567 {
568 struct obio_softc *sc = cookie;
569 uint32_t *freq;
570
571 freq = spd;
572 if (*freq == sc->sc_spd_lo) {
573 obio_set_cpu_speed(sc, 0);
574 } else if (*freq == sc->sc_spd_hi) {
575 obio_set_cpu_speed(sc, 1);
576 } else
577 aprint_error_dev(sc->sc_dev, "%s(%d) bogus CPU speed\n", __func__, *freq);
578 }
579
580 static int
581 sysctl_cpuspeed_temp(SYSCTLFN_ARGS)
582 {
583 struct sysctlnode node = *rnode;
584 struct obio_softc *sc = node.sysctl_data;
585 int speed, mhz;
586
587 speed = obio_get_cpu_speed(sc);
588 switch (speed) {
589 case 0:
590 mhz = sc->sc_spd_lo;
591 break;
592 case 1:
593 mhz = sc->sc_spd_hi;
594 break;
595 default:
596 speed = -1;
597 }
598 node.sysctl_data = &mhz;
599 if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) {
600 int new_reg;
601
602 new_reg = *(int *)node.sysctl_data;
603 if (new_reg == sc->sc_spd_lo) {
604 obio_set_cpu_speed(sc, 0);
605 } else if (new_reg == sc->sc_spd_hi) {
606 obio_set_cpu_speed(sc, 1);
607 } else {
608 printf("%s: new_reg %d\n", __func__, new_reg);
609 return EINVAL;
610 }
611 return 0;
612 }
613 return EINVAL;
614 }
615
616 static int
617 sysctl_cpuspeed_cur(SYSCTLFN_ARGS)
618 {
619 struct sysctlnode node = *rnode;
620 struct obio_softc *sc = node.sysctl_data;
621 int speed, mhz;
622
623 speed = obio_get_cpu_speed(sc);
624 switch (speed) {
625 case 0:
626 mhz = sc->sc_spd_lo;
627 break;
628 case 1:
629 mhz = sc->sc_spd_hi;
630 break;
631 default:
632 speed = -1;
633 }
634 node.sysctl_data = &mhz;
635 return sysctl_lookup(SYSCTLFN_CALL(&node));
636 }
637
638 static int
639 sysctl_cpuspeed_available(SYSCTLFN_ARGS)
640 {
641 struct sysctlnode node = *rnode;
642 struct obio_softc *sc = node.sysctl_data;
643 char buf[128];
644
645 snprintf(buf, 128, "%d %d", sc->sc_spd_lo, sc->sc_spd_hi);
646 node.sysctl_data = buf;
647 return(sysctl_lookup(SYSCTLFN_CALL(&node)));
648 }
649
650 SYSCTL_SETUP(sysctl_ams_setup, "sysctl obio subtree setup")
651 {
652
653 sysctl_createv(NULL, 0, NULL, NULL,
654 CTLFLAG_PERMANENT,
655 CTLTYPE_NODE, "machdep", NULL,
656 NULL, 0, NULL, 0,
657 CTL_MACHDEP, CTL_EOL);
658 }
659
660 #endif /* OBIO_SPEEDCONTROL */
661