103 if (dinfo->res_agent == NULL) { 104 device_printf(dev, "failed allocating agent register " 105 "block for core %d\n", i); 106 error = ENXIO; 107 goto cleanup; 108 } 109 } 110 111cleanup: 112 free(devs, M_BHND); 113 if (error) 114 return (error); 115 116 return (bhnd_generic_attach(dev)); 117} 118 119int 120bcma_detach(device_t dev) 121{ 122 return (bhnd_generic_detach(dev)); 123} 124 125static int 126bcma_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) 127{ 128 const struct bcma_devinfo *dinfo; 129 const struct bhnd_core_info *ci; 130 131 dinfo = device_get_ivars(child); 132 ci = &dinfo->corecfg->core_info; 133 134 switch (index) { 135 case BHND_IVAR_VENDOR: 136 *result = ci->vendor; 137 return (0); 138 case BHND_IVAR_DEVICE: 139 *result = ci->device; 140 return (0); 141 case BHND_IVAR_HWREV: 142 *result = ci->hwrev; 143 return (0); 144 case BHND_IVAR_DEVICE_CLASS: 145 *result = bhnd_core_class(ci); 146 return (0); 147 case BHND_IVAR_VENDOR_NAME: 148 *result = (uintptr_t) bhnd_vendor_name(ci->vendor); 149 return (0); 150 case BHND_IVAR_DEVICE_NAME: 151 *result = (uintptr_t) bhnd_core_name(ci); 152 return (0); 153 case BHND_IVAR_CORE_INDEX: 154 *result = ci->core_idx; 155 return (0); 156 case BHND_IVAR_CORE_UNIT: 157 *result = ci->unit; 158 return (0); 159 default: 160 return (ENOENT); 161 } 162} 163 164static int 165bcma_write_ivar(device_t dev, device_t child, int index, uintptr_t value) 166{ 167 switch (index) { 168 case BHND_IVAR_VENDOR: 169 case BHND_IVAR_DEVICE: 170 case BHND_IVAR_HWREV: 171 case BHND_IVAR_DEVICE_CLASS: 172 case BHND_IVAR_VENDOR_NAME: 173 case BHND_IVAR_DEVICE_NAME: 174 case BHND_IVAR_CORE_INDEX: 175 case BHND_IVAR_CORE_UNIT: 176 return (EINVAL); 177 default: 178 return (ENOENT); 179 } 180} 181 182static void 183bcma_child_deleted(device_t dev, device_t child) 184{ 185 struct bcma_devinfo *dinfo = device_get_ivars(child); 186 if (dinfo != NULL) 187 bcma_free_dinfo(dev, dinfo); 188} 189 190static struct resource_list * 191bcma_get_resource_list(device_t dev, device_t child) 192{ 193 struct bcma_devinfo *dinfo = device_get_ivars(child); 194 return (&dinfo->resources); 195} 196 197static device_t 198bcma_find_hostb_device(device_t dev) 199{ 200 struct bcma_softc *sc = device_get_softc(dev); 201 202 /* This is set (or not) by the concrete bcma driver subclass. */ 203 return (sc->hostb_dev); 204} 205 206static int 207bcma_reset_core(device_t dev, device_t child, uint16_t flags) 208{ 209 struct bcma_devinfo *dinfo; 210 211 if (device_get_parent(child) != dev) 212 BHND_BUS_RESET_CORE(device_get_parent(dev), child, flags); 213 214 dinfo = device_get_ivars(child); 215 216 /* Can't reset the core without access to the agent registers */ 217 if (dinfo->res_agent == NULL) 218 return (ENODEV); 219 220 // TODO - perform reset 221 222 return (ENXIO); 223} 224 225static int 226bcma_suspend_core(device_t dev, device_t child) 227{ 228 struct bcma_devinfo *dinfo; 229 230 if (device_get_parent(child) != dev) 231 BHND_BUS_SUSPEND_CORE(device_get_parent(dev), child); 232 233 dinfo = device_get_ivars(child); 234 235 /* Can't suspend the core without access to the agent registers */ 236 if (dinfo->res_agent == NULL) 237 return (ENODEV); 238 239 // TODO - perform suspend 240 241 return (ENXIO); 242} 243 244static u_int 245bcma_get_port_count(device_t dev, device_t child, bhnd_port_type type) 246{ 247 struct bcma_devinfo *dinfo; 248 249 /* delegate non-bus-attached devices to our parent */ 250 if (device_get_parent(child) != dev) 251 return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), child, 252 type)); 253 254 dinfo = device_get_ivars(child); 255 switch (type) { 256 case BHND_PORT_DEVICE: 257 return (dinfo->corecfg->num_dev_ports); 258 case BHND_PORT_BRIDGE: 259 return (dinfo->corecfg->num_bridge_ports); 260 case BHND_PORT_AGENT: 261 return (dinfo->corecfg->num_wrapper_ports); 262 default: 263 device_printf(dev, "%s: unknown type (%d)\n", 264 __func__, 265 type); 266 return (0); 267 } 268} 269 270static u_int 271bcma_get_region_count(device_t dev, device_t child, bhnd_port_type type, 272 u_int port_num) 273{ 274 struct bcma_devinfo *dinfo; 275 struct bcma_sport_list *ports; 276 struct bcma_sport *port; 277 278 /* delegate non-bus-attached devices to our parent */ 279 if (device_get_parent(child) != dev) 280 return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), child, 281 type, port_num)); 282 283 dinfo = device_get_ivars(child); 284 ports = bcma_corecfg_get_port_list(dinfo->corecfg, type); 285 286 STAILQ_FOREACH(port, ports, sp_link) { 287 if (port->sp_num == port_num) 288 return (port->sp_num_maps); 289 } 290 291 /* not found */ 292 return (0); 293} 294 295static int 296bcma_get_port_rid(device_t dev, device_t child, bhnd_port_type port_type, 297 u_int port_num, u_int region_num) 298{ 299 struct bcma_devinfo *dinfo; 300 struct bcma_map *map; 301 struct bcma_sport_list *ports; 302 struct bcma_sport *port; 303 304 dinfo = device_get_ivars(child); 305 ports = bcma_corecfg_get_port_list(dinfo->corecfg, port_type); 306 307 STAILQ_FOREACH(port, ports, sp_link) { 308 if (port->sp_num != port_num) 309 continue; 310 311 STAILQ_FOREACH(map, &port->sp_maps, m_link) 312 if (map->m_region_num == region_num) 313 return map->m_rid; 314 } 315 316 return -1; 317} 318 319static int 320bcma_decode_port_rid(device_t dev, device_t child, int type, int rid, 321 bhnd_port_type *port_type, u_int *port_num, u_int *region_num) 322{ 323 struct bcma_devinfo *dinfo; 324 struct bcma_map *map; 325 struct bcma_sport_list *ports; 326 struct bcma_sport *port; 327 328 dinfo = device_get_ivars(child); 329 330 /* Ports are always memory mapped */ 331 if (type != SYS_RES_MEMORY) 332 return (EINVAL); 333 334 /* Starting with the most likely device list, search all three port 335 * lists */ 336 bhnd_port_type types[] = { 337 BHND_PORT_DEVICE, 338 BHND_PORT_AGENT, 339 BHND_PORT_BRIDGE 340 }; 341 342 for (int i = 0; i < nitems(types); i++) { 343 ports = bcma_corecfg_get_port_list(dinfo->corecfg, types[i]); 344 345 STAILQ_FOREACH(port, ports, sp_link) { 346 STAILQ_FOREACH(map, &port->sp_maps, m_link) { 347 if (map->m_rid != rid) 348 continue; 349 350 *port_type = port->sp_type; 351 *port_num = port->sp_num; 352 *region_num = map->m_region_num; 353 return (0); 354 } 355 } 356 } 357 358 return (ENOENT); 359} 360 361static int 362bcma_get_region_addr(device_t dev, device_t child, bhnd_port_type port_type, 363 u_int port_num, u_int region_num, bhnd_addr_t *addr, bhnd_size_t *size) 364{ 365 struct bcma_devinfo *dinfo; 366 struct bcma_map *map; 367 struct bcma_sport_list *ports; 368 struct bcma_sport *port; 369 370 dinfo = device_get_ivars(child); 371 ports = bcma_corecfg_get_port_list(dinfo->corecfg, port_type); 372 373 /* Search the port list */ 374 STAILQ_FOREACH(port, ports, sp_link) { 375 if (port->sp_num != port_num) 376 continue; 377 378 STAILQ_FOREACH(map, &port->sp_maps, m_link) { 379 if (map->m_region_num != region_num) 380 continue; 381 382 /* Found! */ 383 *addr = map->m_base; 384 *size = map->m_size; 385 return (0); 386 } 387 } 388 389 return (ENOENT); 390} 391 392/** 393 * Scan a device enumeration ROM table, adding all valid discovered cores to 394 * the bus. 395 * 396 * @param bus The bcma bus. 397 * @param erom_res An active resource mapping the EROM core. 398 * @param erom_offset Base offset of the EROM core's register mapping. 399 */ 400int 401bcma_add_children(device_t bus, struct resource *erom_res, bus_size_t erom_offset) 402{ 403 struct bcma_erom erom; 404 struct bcma_corecfg *corecfg; 405 struct bcma_devinfo *dinfo; 406 device_t child; 407 int error; 408 409 dinfo = NULL; 410 corecfg = NULL; 411 412 /* Initialize our reader */ 413 error = bcma_erom_open(&erom, erom_res, erom_offset); 414 if (error) 415 return (error); 416 417 /* Add all cores. */ 418 while (!error) { 419 /* Parse next core */ 420 error = bcma_erom_parse_corecfg(&erom, &corecfg); 421 if (error && error == ENOENT) { 422 return (0); 423 } else if (error) { 424 goto failed; 425 } 426 427 /* Allocate per-device bus info */ 428 dinfo = bcma_alloc_dinfo(bus, corecfg); 429 if (dinfo == NULL) { 430 error = ENXIO; 431 goto failed; 432 } 433 434 /* The dinfo instance now owns the corecfg value */ 435 corecfg = NULL; 436 437 /* Add the child device */ 438 child = device_add_child(bus, NULL, -1); 439 if (child == NULL) { 440 error = ENXIO; 441 goto failed; 442 } 443 444 /* The child device now owns the dinfo pointer */ 445 device_set_ivars(child, dinfo); 446 dinfo = NULL; 447 448 /* If pins are floating or the hardware is otherwise 449 * unpopulated, the device shouldn't be used. */ 450 if (bhnd_is_hw_disabled(child)) 451 device_disable(child); 452 } 453 454 /* Hit EOF parsing cores? */ 455 if (error == ENOENT) 456 return (0); 457 458failed: 459 if (dinfo != NULL) 460 bcma_free_dinfo(bus, dinfo); 461 462 if (corecfg != NULL) 463 bcma_free_corecfg(corecfg); 464 465 return (error); 466} 467 468 469static device_method_t bcma_methods[] = { 470 /* Device interface */ 471 DEVMETHOD(device_probe, bcma_probe), 472 DEVMETHOD(device_attach, bcma_attach), 473 DEVMETHOD(device_detach, bcma_detach), 474 475 /* Bus interface */ 476 DEVMETHOD(bus_child_deleted, bcma_child_deleted), 477 DEVMETHOD(bus_read_ivar, bcma_read_ivar), 478 DEVMETHOD(bus_write_ivar, bcma_write_ivar), 479 DEVMETHOD(bus_get_resource_list, bcma_get_resource_list), 480 481 /* BHND interface */ 482 DEVMETHOD(bhnd_bus_find_hostb_device, bcma_find_hostb_device), 483 DEVMETHOD(bhnd_bus_reset_core, bcma_reset_core), 484 DEVMETHOD(bhnd_bus_suspend_core, bcma_suspend_core), 485 DEVMETHOD(bhnd_bus_get_port_count, bcma_get_port_count), 486 DEVMETHOD(bhnd_bus_get_region_count, bcma_get_region_count), 487 DEVMETHOD(bhnd_bus_get_port_rid, bcma_get_port_rid), 488 DEVMETHOD(bhnd_bus_decode_port_rid, bcma_decode_port_rid), 489 DEVMETHOD(bhnd_bus_get_region_addr, bcma_get_region_addr), 490 491 DEVMETHOD_END 492}; 493 494DEFINE_CLASS_1(bhnd, bcma_driver, bcma_methods, sizeof(struct bcma_softc), bhnd_driver); 495MODULE_VERSION(bcma, 1); 496MODULE_DEPEND(bcma, bhnd, 1, 1, 1);
| 104 if (dinfo->res_agent == NULL) { 105 device_printf(dev, "failed allocating agent register " 106 "block for core %d\n", i); 107 error = ENXIO; 108 goto cleanup; 109 } 110 } 111 112cleanup: 113 free(devs, M_BHND); 114 if (error) 115 return (error); 116 117 return (bhnd_generic_attach(dev)); 118} 119 120int 121bcma_detach(device_t dev) 122{ 123 return (bhnd_generic_detach(dev)); 124} 125 126static int 127bcma_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) 128{ 129 const struct bcma_devinfo *dinfo; 130 const struct bhnd_core_info *ci; 131 132 dinfo = device_get_ivars(child); 133 ci = &dinfo->corecfg->core_info; 134 135 switch (index) { 136 case BHND_IVAR_VENDOR: 137 *result = ci->vendor; 138 return (0); 139 case BHND_IVAR_DEVICE: 140 *result = ci->device; 141 return (0); 142 case BHND_IVAR_HWREV: 143 *result = ci->hwrev; 144 return (0); 145 case BHND_IVAR_DEVICE_CLASS: 146 *result = bhnd_core_class(ci); 147 return (0); 148 case BHND_IVAR_VENDOR_NAME: 149 *result = (uintptr_t) bhnd_vendor_name(ci->vendor); 150 return (0); 151 case BHND_IVAR_DEVICE_NAME: 152 *result = (uintptr_t) bhnd_core_name(ci); 153 return (0); 154 case BHND_IVAR_CORE_INDEX: 155 *result = ci->core_idx; 156 return (0); 157 case BHND_IVAR_CORE_UNIT: 158 *result = ci->unit; 159 return (0); 160 default: 161 return (ENOENT); 162 } 163} 164 165static int 166bcma_write_ivar(device_t dev, device_t child, int index, uintptr_t value) 167{ 168 switch (index) { 169 case BHND_IVAR_VENDOR: 170 case BHND_IVAR_DEVICE: 171 case BHND_IVAR_HWREV: 172 case BHND_IVAR_DEVICE_CLASS: 173 case BHND_IVAR_VENDOR_NAME: 174 case BHND_IVAR_DEVICE_NAME: 175 case BHND_IVAR_CORE_INDEX: 176 case BHND_IVAR_CORE_UNIT: 177 return (EINVAL); 178 default: 179 return (ENOENT); 180 } 181} 182 183static void 184bcma_child_deleted(device_t dev, device_t child) 185{ 186 struct bcma_devinfo *dinfo = device_get_ivars(child); 187 if (dinfo != NULL) 188 bcma_free_dinfo(dev, dinfo); 189} 190 191static struct resource_list * 192bcma_get_resource_list(device_t dev, device_t child) 193{ 194 struct bcma_devinfo *dinfo = device_get_ivars(child); 195 return (&dinfo->resources); 196} 197 198static device_t 199bcma_find_hostb_device(device_t dev) 200{ 201 struct bcma_softc *sc = device_get_softc(dev); 202 203 /* This is set (or not) by the concrete bcma driver subclass. */ 204 return (sc->hostb_dev); 205} 206 207static int 208bcma_reset_core(device_t dev, device_t child, uint16_t flags) 209{ 210 struct bcma_devinfo *dinfo; 211 212 if (device_get_parent(child) != dev) 213 BHND_BUS_RESET_CORE(device_get_parent(dev), child, flags); 214 215 dinfo = device_get_ivars(child); 216 217 /* Can't reset the core without access to the agent registers */ 218 if (dinfo->res_agent == NULL) 219 return (ENODEV); 220 221 // TODO - perform reset 222 223 return (ENXIO); 224} 225 226static int 227bcma_suspend_core(device_t dev, device_t child) 228{ 229 struct bcma_devinfo *dinfo; 230 231 if (device_get_parent(child) != dev) 232 BHND_BUS_SUSPEND_CORE(device_get_parent(dev), child); 233 234 dinfo = device_get_ivars(child); 235 236 /* Can't suspend the core without access to the agent registers */ 237 if (dinfo->res_agent == NULL) 238 return (ENODEV); 239 240 // TODO - perform suspend 241 242 return (ENXIO); 243} 244 245static u_int 246bcma_get_port_count(device_t dev, device_t child, bhnd_port_type type) 247{ 248 struct bcma_devinfo *dinfo; 249 250 /* delegate non-bus-attached devices to our parent */ 251 if (device_get_parent(child) != dev) 252 return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), child, 253 type)); 254 255 dinfo = device_get_ivars(child); 256 switch (type) { 257 case BHND_PORT_DEVICE: 258 return (dinfo->corecfg->num_dev_ports); 259 case BHND_PORT_BRIDGE: 260 return (dinfo->corecfg->num_bridge_ports); 261 case BHND_PORT_AGENT: 262 return (dinfo->corecfg->num_wrapper_ports); 263 default: 264 device_printf(dev, "%s: unknown type (%d)\n", 265 __func__, 266 type); 267 return (0); 268 } 269} 270 271static u_int 272bcma_get_region_count(device_t dev, device_t child, bhnd_port_type type, 273 u_int port_num) 274{ 275 struct bcma_devinfo *dinfo; 276 struct bcma_sport_list *ports; 277 struct bcma_sport *port; 278 279 /* delegate non-bus-attached devices to our parent */ 280 if (device_get_parent(child) != dev) 281 return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), child, 282 type, port_num)); 283 284 dinfo = device_get_ivars(child); 285 ports = bcma_corecfg_get_port_list(dinfo->corecfg, type); 286 287 STAILQ_FOREACH(port, ports, sp_link) { 288 if (port->sp_num == port_num) 289 return (port->sp_num_maps); 290 } 291 292 /* not found */ 293 return (0); 294} 295 296static int 297bcma_get_port_rid(device_t dev, device_t child, bhnd_port_type port_type, 298 u_int port_num, u_int region_num) 299{ 300 struct bcma_devinfo *dinfo; 301 struct bcma_map *map; 302 struct bcma_sport_list *ports; 303 struct bcma_sport *port; 304 305 dinfo = device_get_ivars(child); 306 ports = bcma_corecfg_get_port_list(dinfo->corecfg, port_type); 307 308 STAILQ_FOREACH(port, ports, sp_link) { 309 if (port->sp_num != port_num) 310 continue; 311 312 STAILQ_FOREACH(map, &port->sp_maps, m_link) 313 if (map->m_region_num == region_num) 314 return map->m_rid; 315 } 316 317 return -1; 318} 319 320static int 321bcma_decode_port_rid(device_t dev, device_t child, int type, int rid, 322 bhnd_port_type *port_type, u_int *port_num, u_int *region_num) 323{ 324 struct bcma_devinfo *dinfo; 325 struct bcma_map *map; 326 struct bcma_sport_list *ports; 327 struct bcma_sport *port; 328 329 dinfo = device_get_ivars(child); 330 331 /* Ports are always memory mapped */ 332 if (type != SYS_RES_MEMORY) 333 return (EINVAL); 334 335 /* Starting with the most likely device list, search all three port 336 * lists */ 337 bhnd_port_type types[] = { 338 BHND_PORT_DEVICE, 339 BHND_PORT_AGENT, 340 BHND_PORT_BRIDGE 341 }; 342 343 for (int i = 0; i < nitems(types); i++) { 344 ports = bcma_corecfg_get_port_list(dinfo->corecfg, types[i]); 345 346 STAILQ_FOREACH(port, ports, sp_link) { 347 STAILQ_FOREACH(map, &port->sp_maps, m_link) { 348 if (map->m_rid != rid) 349 continue; 350 351 *port_type = port->sp_type; 352 *port_num = port->sp_num; 353 *region_num = map->m_region_num; 354 return (0); 355 } 356 } 357 } 358 359 return (ENOENT); 360} 361 362static int 363bcma_get_region_addr(device_t dev, device_t child, bhnd_port_type port_type, 364 u_int port_num, u_int region_num, bhnd_addr_t *addr, bhnd_size_t *size) 365{ 366 struct bcma_devinfo *dinfo; 367 struct bcma_map *map; 368 struct bcma_sport_list *ports; 369 struct bcma_sport *port; 370 371 dinfo = device_get_ivars(child); 372 ports = bcma_corecfg_get_port_list(dinfo->corecfg, port_type); 373 374 /* Search the port list */ 375 STAILQ_FOREACH(port, ports, sp_link) { 376 if (port->sp_num != port_num) 377 continue; 378 379 STAILQ_FOREACH(map, &port->sp_maps, m_link) { 380 if (map->m_region_num != region_num) 381 continue; 382 383 /* Found! */ 384 *addr = map->m_base; 385 *size = map->m_size; 386 return (0); 387 } 388 } 389 390 return (ENOENT); 391} 392 393/** 394 * Scan a device enumeration ROM table, adding all valid discovered cores to 395 * the bus. 396 * 397 * @param bus The bcma bus. 398 * @param erom_res An active resource mapping the EROM core. 399 * @param erom_offset Base offset of the EROM core's register mapping. 400 */ 401int 402bcma_add_children(device_t bus, struct resource *erom_res, bus_size_t erom_offset) 403{ 404 struct bcma_erom erom; 405 struct bcma_corecfg *corecfg; 406 struct bcma_devinfo *dinfo; 407 device_t child; 408 int error; 409 410 dinfo = NULL; 411 corecfg = NULL; 412 413 /* Initialize our reader */ 414 error = bcma_erom_open(&erom, erom_res, erom_offset); 415 if (error) 416 return (error); 417 418 /* Add all cores. */ 419 while (!error) { 420 /* Parse next core */ 421 error = bcma_erom_parse_corecfg(&erom, &corecfg); 422 if (error && error == ENOENT) { 423 return (0); 424 } else if (error) { 425 goto failed; 426 } 427 428 /* Allocate per-device bus info */ 429 dinfo = bcma_alloc_dinfo(bus, corecfg); 430 if (dinfo == NULL) { 431 error = ENXIO; 432 goto failed; 433 } 434 435 /* The dinfo instance now owns the corecfg value */ 436 corecfg = NULL; 437 438 /* Add the child device */ 439 child = device_add_child(bus, NULL, -1); 440 if (child == NULL) { 441 error = ENXIO; 442 goto failed; 443 } 444 445 /* The child device now owns the dinfo pointer */ 446 device_set_ivars(child, dinfo); 447 dinfo = NULL; 448 449 /* If pins are floating or the hardware is otherwise 450 * unpopulated, the device shouldn't be used. */ 451 if (bhnd_is_hw_disabled(child)) 452 device_disable(child); 453 } 454 455 /* Hit EOF parsing cores? */ 456 if (error == ENOENT) 457 return (0); 458 459failed: 460 if (dinfo != NULL) 461 bcma_free_dinfo(bus, dinfo); 462 463 if (corecfg != NULL) 464 bcma_free_corecfg(corecfg); 465 466 return (error); 467} 468 469 470static device_method_t bcma_methods[] = { 471 /* Device interface */ 472 DEVMETHOD(device_probe, bcma_probe), 473 DEVMETHOD(device_attach, bcma_attach), 474 DEVMETHOD(device_detach, bcma_detach), 475 476 /* Bus interface */ 477 DEVMETHOD(bus_child_deleted, bcma_child_deleted), 478 DEVMETHOD(bus_read_ivar, bcma_read_ivar), 479 DEVMETHOD(bus_write_ivar, bcma_write_ivar), 480 DEVMETHOD(bus_get_resource_list, bcma_get_resource_list), 481 482 /* BHND interface */ 483 DEVMETHOD(bhnd_bus_find_hostb_device, bcma_find_hostb_device), 484 DEVMETHOD(bhnd_bus_reset_core, bcma_reset_core), 485 DEVMETHOD(bhnd_bus_suspend_core, bcma_suspend_core), 486 DEVMETHOD(bhnd_bus_get_port_count, bcma_get_port_count), 487 DEVMETHOD(bhnd_bus_get_region_count, bcma_get_region_count), 488 DEVMETHOD(bhnd_bus_get_port_rid, bcma_get_port_rid), 489 DEVMETHOD(bhnd_bus_decode_port_rid, bcma_decode_port_rid), 490 DEVMETHOD(bhnd_bus_get_region_addr, bcma_get_region_addr), 491 492 DEVMETHOD_END 493}; 494 495DEFINE_CLASS_1(bhnd, bcma_driver, bcma_methods, sizeof(struct bcma_softc), bhnd_driver); 496MODULE_VERSION(bcma, 1); 497MODULE_DEPEND(bcma, bhnd, 1, 1, 1);
|