1/*- 2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3 * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer as 11 * the first lines of this file unmodified. 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * from: FreeBSD: src/sys/isa/atkbdc_isa.c,v 1.31 2005/05/29 04:42:28 nyan 28 */ 29 30#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3 * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer as 11 * the first lines of this file unmodified. 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * from: FreeBSD: src/sys/isa/atkbdc_isa.c,v 1.31 2005/05/29 04:42:28 nyan 28 */ 29 30#include <sys/cdefs.h>
|
32 33#include "opt_kbd.h" 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <sys/bus.h> 40#include <sys/kbio.h> 41#include <sys/malloc.h> 42 43#include <dev/ofw/ofw_bus.h> 44 45#include <machine/resource.h> 46#include <machine/ver.h> 47 48#include <sys/rman.h> 49 50#include <dev/kbd/kbdreg.h> 51#include <dev/atkbdc/atkbdreg.h> 52#include <dev/atkbdc/atkbdc_subr.h> 53#include <dev/atkbdc/atkbdcreg.h> 54#include <dev/atkbdc/psm.h> 55 56static device_probe_t atkbdc_ebus_probe; 57static device_attach_t atkbdc_ebus_attach; 58 59static device_method_t atkbdc_ebus_methods[] = { 60 DEVMETHOD(device_probe, atkbdc_ebus_probe), 61 DEVMETHOD(device_attach, atkbdc_ebus_attach), 62 DEVMETHOD(device_suspend, bus_generic_suspend), 63 DEVMETHOD(device_resume, bus_generic_resume), 64 65 DEVMETHOD(bus_print_child, atkbdc_print_child), 66 DEVMETHOD(bus_read_ivar, atkbdc_read_ivar), 67 DEVMETHOD(bus_write_ivar, atkbdc_write_ivar), 68 DEVMETHOD(bus_get_resource_list,atkbdc_get_resource_list), 69 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 70 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 71 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 72 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 73 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 74 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 75 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 76 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 77 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 78 79 { 0, 0 } 80}; 81 82static driver_t atkbdc_ebus_driver = { 83 ATKBDC_DRIVER_NAME, 84 atkbdc_ebus_methods, 85 sizeof(atkbdc_softc_t *), 86}; 87 88DRIVER_MODULE(atkbdc, ebus, atkbdc_ebus_driver, atkbdc_devclass, 0, 0); 89 90static int 91atkbdc_ebus_probe(device_t dev) 92{ 93 struct resource *port0, *port1; 94 u_long count, start; 95 int error, rid; 96 97 if (strcmp(ofw_bus_get_name(dev), "8042") != 0) 98 return (ENXIO); 99 100 /* 101 * On AXi and AXmp boards the NS16550 (used to connect keyboard/ 102 * mouse) share their IRQ lines with the i8042. Any IRQ activity 103 * (typically during attach) of the NS16550 used to connect the 104 * keyboard when actually the PS/2 keyboard is selected in OFW 105 * causes interaction with the OBP i8042 driver resulting in a 106 * hang and vice versa. As RS232 keyboards and mice obviously 107 * aren't meant to be used in parallel with PS/2 ones on these 108 * boards don't attach to the i8042 in case the PS/2 keyboard 109 * isn't selected in order to prevent such hangs. 110 * Note that it's not sufficient here to rely on the '8042' node 111 * only showing up when a PS/2 keyboard is actually connected as 112 * the user still might have adjusted the 'keyboard' alias to 113 * point to the RS232 keyboard. 114 */ 115 if ((!strcmp(sparc64_model, "SUNW,UltraAX-MP") || 116 !strcmp(sparc64_model, "SUNW,UltraSPARC-IIi-Engine")) && 117 OF_finddevice("keyboard") != ofw_bus_get_node(dev)) { 118 device_disable(dev); 119 return (ENXIO); 120 } 121 122 device_set_desc(dev, "Keyboard controller (i8042)"); 123 124 /* 125 * The '8042' node has two identical 8 addresses wide resources 126 * which are apparently meant to be used one for the keyboard 127 * half and the other one for the mouse half. To simplify matters 128 * we use one for the command/data port resource and the other 129 * one for the status port resource as the atkbdc(4) back-end 130 * expects two struct resource rather than two bus space handles. 131 */ 132 rid = 0; 133 if (bus_get_resource(dev, SYS_RES_MEMORY, rid, &start, &count) != 0) { 134 device_printf(dev, 135 "cannot determine command/data port resource\n"); 136 return (ENXIO); 137 } 138 port0 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 1, 139 RF_ACTIVE); 140 if (port0 == NULL) { 141 device_printf(dev, 142 "cannot allocate command/data port resource\n"); 143 return (ENXIO); 144 } 145 146 rid = 1; 147 if (bus_get_resource(dev, SYS_RES_MEMORY, rid, &start, &count) != 0) { 148 device_printf(dev, "cannot determine status port resource\n"); 149 error = ENXIO; 150 goto fail_port0; 151 } 152 start += KBD_STATUS_PORT; 153 port1 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 1, 154 RF_ACTIVE); 155 if (port1 == NULL) { 156 device_printf(dev, "cannot allocate status port resource\n"); 157 error = ENXIO; 158 goto fail_port0; 159 } 160 161 error = atkbdc_probe_unit(device_get_unit(dev), port0, port1); 162 if (error != 0) 163 device_printf(dev, "atkbdc_porbe_unit failed\n"); 164 165 bus_release_resource(dev, SYS_RES_MEMORY, 1, port1); 166 fail_port0: 167 bus_release_resource(dev, SYS_RES_MEMORY, 0, port0); 168 169 return (error); 170} 171 172static int 173atkbdc_ebus_attach(device_t dev) 174{ 175 atkbdc_softc_t *sc; 176 atkbdc_device_t *adi; 177 device_t cdev; 178 phandle_t child; 179 u_long count, intr, start; 180 int children, error, rid, unit; 181 char *cname, *dname; 182 183 unit = device_get_unit(dev); 184 sc = *(atkbdc_softc_t **)device_get_softc(dev); 185 if (sc == NULL) { 186 /* 187 * We have to maintain two copies of the kbdc_softc struct, 188 * as the low-level console needs to have access to the 189 * keyboard controller before kbdc is probed and attached. 190 * kbdc_soft[] contains the default entry for that purpose. 191 * See atkbdc.c. XXX 192 */ 193 sc = atkbdc_get_softc(unit); 194 if (sc == NULL) 195 return (ENOMEM); 196 device_set_softc(dev, sc); 197 } 198 199 rid = 0; 200 if (bus_get_resource(dev, SYS_RES_MEMORY, rid, &start, &count) != 0) { 201 device_printf(dev, 202 "cannot determine command/data port resource\n"); 203 return (ENXIO); 204 }
| 32 33#include "opt_kbd.h" 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <sys/bus.h> 40#include <sys/kbio.h> 41#include <sys/malloc.h> 42 43#include <dev/ofw/ofw_bus.h> 44 45#include <machine/resource.h> 46#include <machine/ver.h> 47 48#include <sys/rman.h> 49 50#include <dev/kbd/kbdreg.h> 51#include <dev/atkbdc/atkbdreg.h> 52#include <dev/atkbdc/atkbdc_subr.h> 53#include <dev/atkbdc/atkbdcreg.h> 54#include <dev/atkbdc/psm.h> 55 56static device_probe_t atkbdc_ebus_probe; 57static device_attach_t atkbdc_ebus_attach; 58 59static device_method_t atkbdc_ebus_methods[] = { 60 DEVMETHOD(device_probe, atkbdc_ebus_probe), 61 DEVMETHOD(device_attach, atkbdc_ebus_attach), 62 DEVMETHOD(device_suspend, bus_generic_suspend), 63 DEVMETHOD(device_resume, bus_generic_resume), 64 65 DEVMETHOD(bus_print_child, atkbdc_print_child), 66 DEVMETHOD(bus_read_ivar, atkbdc_read_ivar), 67 DEVMETHOD(bus_write_ivar, atkbdc_write_ivar), 68 DEVMETHOD(bus_get_resource_list,atkbdc_get_resource_list), 69 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 70 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 71 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 72 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 73 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 74 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 75 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 76 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 77 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 78 79 { 0, 0 } 80}; 81 82static driver_t atkbdc_ebus_driver = { 83 ATKBDC_DRIVER_NAME, 84 atkbdc_ebus_methods, 85 sizeof(atkbdc_softc_t *), 86}; 87 88DRIVER_MODULE(atkbdc, ebus, atkbdc_ebus_driver, atkbdc_devclass, 0, 0); 89 90static int 91atkbdc_ebus_probe(device_t dev) 92{ 93 struct resource *port0, *port1; 94 u_long count, start; 95 int error, rid; 96 97 if (strcmp(ofw_bus_get_name(dev), "8042") != 0) 98 return (ENXIO); 99 100 /* 101 * On AXi and AXmp boards the NS16550 (used to connect keyboard/ 102 * mouse) share their IRQ lines with the i8042. Any IRQ activity 103 * (typically during attach) of the NS16550 used to connect the 104 * keyboard when actually the PS/2 keyboard is selected in OFW 105 * causes interaction with the OBP i8042 driver resulting in a 106 * hang and vice versa. As RS232 keyboards and mice obviously 107 * aren't meant to be used in parallel with PS/2 ones on these 108 * boards don't attach to the i8042 in case the PS/2 keyboard 109 * isn't selected in order to prevent such hangs. 110 * Note that it's not sufficient here to rely on the '8042' node 111 * only showing up when a PS/2 keyboard is actually connected as 112 * the user still might have adjusted the 'keyboard' alias to 113 * point to the RS232 keyboard. 114 */ 115 if ((!strcmp(sparc64_model, "SUNW,UltraAX-MP") || 116 !strcmp(sparc64_model, "SUNW,UltraSPARC-IIi-Engine")) && 117 OF_finddevice("keyboard") != ofw_bus_get_node(dev)) { 118 device_disable(dev); 119 return (ENXIO); 120 } 121 122 device_set_desc(dev, "Keyboard controller (i8042)"); 123 124 /* 125 * The '8042' node has two identical 8 addresses wide resources 126 * which are apparently meant to be used one for the keyboard 127 * half and the other one for the mouse half. To simplify matters 128 * we use one for the command/data port resource and the other 129 * one for the status port resource as the atkbdc(4) back-end 130 * expects two struct resource rather than two bus space handles. 131 */ 132 rid = 0; 133 if (bus_get_resource(dev, SYS_RES_MEMORY, rid, &start, &count) != 0) { 134 device_printf(dev, 135 "cannot determine command/data port resource\n"); 136 return (ENXIO); 137 } 138 port0 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 1, 139 RF_ACTIVE); 140 if (port0 == NULL) { 141 device_printf(dev, 142 "cannot allocate command/data port resource\n"); 143 return (ENXIO); 144 } 145 146 rid = 1; 147 if (bus_get_resource(dev, SYS_RES_MEMORY, rid, &start, &count) != 0) { 148 device_printf(dev, "cannot determine status port resource\n"); 149 error = ENXIO; 150 goto fail_port0; 151 } 152 start += KBD_STATUS_PORT; 153 port1 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 1, 154 RF_ACTIVE); 155 if (port1 == NULL) { 156 device_printf(dev, "cannot allocate status port resource\n"); 157 error = ENXIO; 158 goto fail_port0; 159 } 160 161 error = atkbdc_probe_unit(device_get_unit(dev), port0, port1); 162 if (error != 0) 163 device_printf(dev, "atkbdc_porbe_unit failed\n"); 164 165 bus_release_resource(dev, SYS_RES_MEMORY, 1, port1); 166 fail_port0: 167 bus_release_resource(dev, SYS_RES_MEMORY, 0, port0); 168 169 return (error); 170} 171 172static int 173atkbdc_ebus_attach(device_t dev) 174{ 175 atkbdc_softc_t *sc; 176 atkbdc_device_t *adi; 177 device_t cdev; 178 phandle_t child; 179 u_long count, intr, start; 180 int children, error, rid, unit; 181 char *cname, *dname; 182 183 unit = device_get_unit(dev); 184 sc = *(atkbdc_softc_t **)device_get_softc(dev); 185 if (sc == NULL) { 186 /* 187 * We have to maintain two copies of the kbdc_softc struct, 188 * as the low-level console needs to have access to the 189 * keyboard controller before kbdc is probed and attached. 190 * kbdc_soft[] contains the default entry for that purpose. 191 * See atkbdc.c. XXX 192 */ 193 sc = atkbdc_get_softc(unit); 194 if (sc == NULL) 195 return (ENOMEM); 196 device_set_softc(dev, sc); 197 } 198 199 rid = 0; 200 if (bus_get_resource(dev, SYS_RES_MEMORY, rid, &start, &count) != 0) { 201 device_printf(dev, 202 "cannot determine command/data port resource\n"); 203 return (ENXIO); 204 }
|
205 sc->port0 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 206 1, RF_ACTIVE); 207 if (sc->port0 == NULL) { 208 device_printf(dev, 209 "cannot allocate command/data port resource\n"); 210 return (ENXIO); 211 } 212 213 rid = 1; 214 if (bus_get_resource(dev, SYS_RES_MEMORY, rid, &start, &count) != 0) { 215 device_printf(dev, "cannot determine status port resource\n"); 216 error = ENXIO; 217 goto fail_port0; 218 } 219 start += KBD_STATUS_PORT; 220 sc->port1 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 221 1, RF_ACTIVE); 222 if (sc->port1 == NULL) { 223 device_printf(dev, "cannot allocate status port resource\n"); 224 error = ENXIO; 225 goto fail_port0; 226 } 227 228 error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1); 229 if (error != 0) { 230 device_printf(dev, "atkbdc_attach_unit failed\n"); 231 goto fail_port1; 232 } 233 234 /* Attach children. */ 235 children = 0; 236 for (child = OF_child(ofw_bus_get_node(dev)); child != 0; 237 child = OF_peer(child)) { 238 if ((OF_getprop_alloc(child, "name", 1, (void **)&cname)) == -1) 239 continue; 240 if (children >= 2) { 241 device_printf(dev, 242 "<%s>: only two children per 8042 supported\n", 243 cname); 244 free(cname, M_OFWPROP); 245 continue; 246 } 247 adi = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV, 248 M_NOWAIT | M_ZERO); 249 if (adi == NULL) { 250 device_printf(dev, "<%s>: malloc failed\n", cname); 251 free(cname, M_OFWPROP); 252 continue; 253 } 254 if (strcmp(cname, "kb_ps2") == 0) { 255 adi->rid = KBDC_RID_KBD; 256 dname = ATKBD_DRIVER_NAME; 257 } else if (strcmp(cname, "kdmouse") == 0) { 258 adi->rid = KBDC_RID_AUX; 259 dname = PSM_DRIVER_NAME; 260 } else { 261 device_printf(dev, "<%s>: unknown device\n", cname); 262 free(adi, M_ATKBDDEV); 263 free(cname, M_OFWPROP); 264 continue; 265 } 266 intr = bus_get_resource_start(dev, SYS_RES_IRQ, adi->rid); 267 if (intr == 0) { 268 device_printf(dev, 269 "<%s>: cannot determine interrupt resource\n", 270 cname); 271 free(adi, M_ATKBDDEV); 272 free(cname, M_OFWPROP); 273 continue; 274 } 275 resource_list_init(&adi->resources); 276 resource_list_add(&adi->resources, SYS_RES_IRQ, adi->rid, 277 intr, intr, 1); 278 if ((cdev = device_add_child(dev, dname, -1)) == NULL) { 279 device_printf(dev, "<%s>: device_add_child failed\n", 280 cname); 281 resource_list_free(&adi->resources); 282 free(adi, M_ATKBDDEV); 283 free(cname, M_OFWPROP); 284 continue; 285 } 286 device_set_ivars(cdev, adi); 287 children++; 288 } 289 290 error = bus_generic_attach(dev); 291 if (error != 0) { 292 device_printf(dev, "bus_generic_attach failed\n"); 293 goto fail_port1; 294 } 295 296 return (0); 297 298 fail_port1: 299 bus_release_resource(dev, SYS_RES_MEMORY, 1, sc->port1); 300 fail_port0: 301 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->port0); 302 303 return (error); 304}
| 206 sc->port0 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 207 1, RF_ACTIVE); 208 if (sc->port0 == NULL) { 209 device_printf(dev, 210 "cannot allocate command/data port resource\n"); 211 return (ENXIO); 212 } 213 214 rid = 1; 215 if (bus_get_resource(dev, SYS_RES_MEMORY, rid, &start, &count) != 0) { 216 device_printf(dev, "cannot determine status port resource\n"); 217 error = ENXIO; 218 goto fail_port0; 219 } 220 start += KBD_STATUS_PORT; 221 sc->port1 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 222 1, RF_ACTIVE); 223 if (sc->port1 == NULL) { 224 device_printf(dev, "cannot allocate status port resource\n"); 225 error = ENXIO; 226 goto fail_port0; 227 } 228 229 error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1); 230 if (error != 0) { 231 device_printf(dev, "atkbdc_attach_unit failed\n"); 232 goto fail_port1; 233 } 234 235 /* Attach children. */ 236 children = 0; 237 for (child = OF_child(ofw_bus_get_node(dev)); child != 0; 238 child = OF_peer(child)) { 239 if ((OF_getprop_alloc(child, "name", 1, (void **)&cname)) == -1) 240 continue; 241 if (children >= 2) { 242 device_printf(dev, 243 "<%s>: only two children per 8042 supported\n", 244 cname); 245 free(cname, M_OFWPROP); 246 continue; 247 } 248 adi = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV, 249 M_NOWAIT | M_ZERO); 250 if (adi == NULL) { 251 device_printf(dev, "<%s>: malloc failed\n", cname); 252 free(cname, M_OFWPROP); 253 continue; 254 } 255 if (strcmp(cname, "kb_ps2") == 0) { 256 adi->rid = KBDC_RID_KBD; 257 dname = ATKBD_DRIVER_NAME; 258 } else if (strcmp(cname, "kdmouse") == 0) { 259 adi->rid = KBDC_RID_AUX; 260 dname = PSM_DRIVER_NAME; 261 } else { 262 device_printf(dev, "<%s>: unknown device\n", cname); 263 free(adi, M_ATKBDDEV); 264 free(cname, M_OFWPROP); 265 continue; 266 } 267 intr = bus_get_resource_start(dev, SYS_RES_IRQ, adi->rid); 268 if (intr == 0) { 269 device_printf(dev, 270 "<%s>: cannot determine interrupt resource\n", 271 cname); 272 free(adi, M_ATKBDDEV); 273 free(cname, M_OFWPROP); 274 continue; 275 } 276 resource_list_init(&adi->resources); 277 resource_list_add(&adi->resources, SYS_RES_IRQ, adi->rid, 278 intr, intr, 1); 279 if ((cdev = device_add_child(dev, dname, -1)) == NULL) { 280 device_printf(dev, "<%s>: device_add_child failed\n", 281 cname); 282 resource_list_free(&adi->resources); 283 free(adi, M_ATKBDDEV); 284 free(cname, M_OFWPROP); 285 continue; 286 } 287 device_set_ivars(cdev, adi); 288 children++; 289 } 290 291 error = bus_generic_attach(dev); 292 if (error != 0) { 293 device_printf(dev, "bus_generic_attach failed\n"); 294 goto fail_port1; 295 } 296 297 return (0); 298 299 fail_port1: 300 bus_release_resource(dev, SYS_RES_MEMORY, 1, sc->port1); 301 fail_port0: 302 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->port0); 303 304 return (error); 305}
|