summaryrefslogtreecommitdiffstats
path: root/rtemsbsd/include/rtems/bsd/local/bus_if.h
blob: cc15dcadbccd127b2172ab554ccf37b05c5a8f65 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
/*
 * This file is produced automatically.
 * Do not modify anything in here by hand.
 *
 * Created from source file
 *   freebsd-org/sys/kern/bus_if.m
 * with
 *   makeobjops.awk
 *
 * See the source file for legal information
 */

/**
 * @defgroup BUS bus - KObj methods for drivers of devices with children
 * @brief A set of methods required device drivers that support
 * child devices.
 * @{
 */

#ifndef _bus_if_h_
#define _bus_if_h_

/** @brief Unique descriptor for the BUS_PRINT_CHILD() method */
extern struct kobjop_desc bus_print_child_desc;
/** @brief A function implementing the BUS_PRINT_CHILD() method */
typedef int bus_print_child_t(device_t _dev, device_t _child);
/**
 * @brief Print a description of a child device
 *
 * This is called from system code which prints out a description of a
 * device. It should describe the attachment that the child has with
 * the parent. For instance the TurboLaser bus prints which node the
 * device is attached to. See bus_generic_print_child() for more 
 * information.
 *
 * @param _dev		the device whose child is being printed
 * @param _child	the child device to describe
 *
 * @returns		the number of characters output.
 */

static __inline int BUS_PRINT_CHILD(device_t _dev, device_t _child)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_print_child);
	rc = ((bus_print_child_t *) _m)(_dev, _child);
	return (rc);
}

/** @brief Unique descriptor for the BUS_PROBE_NOMATCH() method */
extern struct kobjop_desc bus_probe_nomatch_desc;
/** @brief A function implementing the BUS_PROBE_NOMATCH() method */
typedef void bus_probe_nomatch_t(device_t _dev, device_t _child);
/**
 * @brief Print a notification about an unprobed child device.
 *
 * Called for each child device that did not succeed in probing for a
 * driver.
 *
 * @param _dev		the device whose child was being probed
 * @param _child	the child device which failed to probe
 */   

static __inline void BUS_PROBE_NOMATCH(device_t _dev, device_t _child)
{
	kobjop_t _m;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_probe_nomatch);
	((bus_probe_nomatch_t *) _m)(_dev, _child);
}

/** @brief Unique descriptor for the BUS_READ_IVAR() method */
extern struct kobjop_desc bus_read_ivar_desc;
/** @brief A function implementing the BUS_READ_IVAR() method */
typedef int bus_read_ivar_t(device_t _dev, device_t _child, int _index,
                            uintptr_t *_result);
/**
 * @brief Read the value of a bus-specific attribute of a device
 *
 * This method, along with BUS_WRITE_IVAR() manages a bus-specific set
 * of instance variables of a child device.  The intention is that
 * each different type of bus defines a set of appropriate instance
 * variables (such as ports and irqs for ISA bus etc.)
 *
 * This information could be given to the child device as a struct but
 * that makes it hard for a bus to add or remove variables without
 * forcing an edit and recompile for all drivers which may not be
 * possible for vendor supplied binary drivers.
 *
 * This method copies the value of an instance variable to the
 * location specified by @p *_result.
 * 
 * @param _dev		the device whose child was being examined
 * @param _child	the child device whose instance variable is
 *			being read
 * @param _index	the instance variable to read
 * @param _result	a location to receive the instance variable
 *			value
 * 
 * @retval 0		success
 * @retval ENOENT	no such instance variable is supported by @p
 *			_dev 
 */

static __inline int BUS_READ_IVAR(device_t _dev, device_t _child, int _index,
                                  uintptr_t *_result)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_read_ivar);
	rc = ((bus_read_ivar_t *) _m)(_dev, _child, _index, _result);
	return (rc);
}

/** @brief Unique descriptor for the BUS_WRITE_IVAR() method */
extern struct kobjop_desc bus_write_ivar_desc;
/** @brief A function implementing the BUS_WRITE_IVAR() method */
typedef int bus_write_ivar_t(device_t _dev, device_t _child, int _indx,
                             uintptr_t _value);
/**
 * @brief Write the value of a bus-specific attribute of a device
 * 
 * This method sets the value of an instance variable to @p _value.
 * 
 * @param _dev		the device whose child was being updated
 * @param _child	the child device whose instance variable is
 *			being written
 * @param _index	the instance variable to write
 * @param _value	the value to write to that instance variable
 * 
 * @retval 0		success
 * @retval ENOENT	no such instance variable is supported by @p
 *			_dev 
 * @retval EINVAL	the instance variable was recognised but
 *			contains a read-only value
 */

static __inline int BUS_WRITE_IVAR(device_t _dev, device_t _child, int _indx,
                                   uintptr_t _value)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_write_ivar);
	rc = ((bus_write_ivar_t *) _m)(_dev, _child, _indx, _value);
	return (rc);
}

/** @brief Unique descriptor for the BUS_CHILD_DELETED() method */
extern struct kobjop_desc bus_child_deleted_desc;
/** @brief A function implementing the BUS_CHILD_DELETED() method */
typedef void bus_child_deleted_t(device_t _dev, device_t _child);
/**
 * @brief Notify a bus that a child was deleted
 *
 * Called at the beginning of device_delete_child() to allow the parent
 * to teardown any bus-specific state for the child.
 * 
 * @param _dev		the device whose child is being deleted
 * @param _child	the child device which is being deleted
 */

static __inline void BUS_CHILD_DELETED(device_t _dev, device_t _child)
{
	kobjop_t _m;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_child_deleted);
	((bus_child_deleted_t *) _m)(_dev, _child);
}

/** @brief Unique descriptor for the BUS_CHILD_DETACHED() method */
extern struct kobjop_desc bus_child_detached_desc;
/** @brief A function implementing the BUS_CHILD_DETACHED() method */
typedef void bus_child_detached_t(device_t _dev, device_t _child);
/**
 * @brief Notify a bus that a child was detached
 *
 * Called after the child's DEVICE_DETACH() method to allow the parent
 * to reclaim any resources allocated on behalf of the child.
 * 
 * @param _dev		the device whose child changed state
 * @param _child	the child device which changed state
 */

static __inline void BUS_CHILD_DETACHED(device_t _dev, device_t _child)
{
	kobjop_t _m;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_child_detached);
	((bus_child_detached_t *) _m)(_dev, _child);
}

/** @brief Unique descriptor for the BUS_DRIVER_ADDED() method */
extern struct kobjop_desc bus_driver_added_desc;
/** @brief A function implementing the BUS_DRIVER_ADDED() method */
typedef void bus_driver_added_t(device_t _dev, driver_t *_driver);
/**
 * @brief Notify a bus that a new driver was added
 * 
 * Called when a new driver is added to the devclass which owns this
 * bus. The generic implementation of this method attempts to probe and
 * attach any un-matched children of the bus.
 * 
 * @param _dev		the device whose devclass had a new driver
 *			added to it
 * @param _driver	the new driver which was added
 */

static __inline void BUS_DRIVER_ADDED(device_t _dev, driver_t *_driver)
{
	kobjop_t _m;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_driver_added);
	((bus_driver_added_t *) _m)(_dev, _driver);
}

/** @brief Unique descriptor for the BUS_ADD_CHILD() method */
extern struct kobjop_desc bus_add_child_desc;
/** @brief A function implementing the BUS_ADD_CHILD() method */
typedef device_t bus_add_child_t(device_t _dev, u_int _order, const char *_name,
                                 int _unit);
/**
 * @brief Create a new child device
 *
 * For buses which use use drivers supporting DEVICE_IDENTIFY() to
 * enumerate their devices, this method is used to create new
 * device instances. The new device will be added after the last
 * existing child with the same order. Implementations of bus_add_child
 * call device_add_child_ordered to add the child and often add
 * a suitable ivar to the device specific to that bus.
 * 
 * @param _dev		the bus device which will be the parent of the
 *			new child device
 * @param _order	a value which is used to partially sort the
 *			children of @p _dev - devices created using
 *			lower values of @p _order appear first in @p
 *			_dev's list of children
 * @param _name		devclass name for new device or @c NULL if not
 *			specified
 * @param _unit		unit number for new device or @c -1 if not
 *			specified
 */

static __inline device_t BUS_ADD_CHILD(device_t _dev, u_int _order,
                                       const char *_name, int _unit)
{
	kobjop_t _m;
	device_t rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_add_child);
	rc = ((bus_add_child_t *) _m)(_dev, _order, _name, _unit);
	return (rc);
}

/** @brief Unique descriptor for the BUS_RESCAN() method */
extern struct kobjop_desc bus_rescan_desc;
/** @brief A function implementing the BUS_RESCAN() method */
typedef int bus_rescan_t(device_t _dev);
/**
 * @brief Rescan the bus
 *
 * This method is called by a parent bridge or devctl to trigger a bus
 * rescan.  The rescan should delete devices no longer present and
 * enumerate devices that have newly arrived.
 *
 * @param _dev		the bus device
 */

static __inline int BUS_RESCAN(device_t _dev)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_rescan);
	rc = ((bus_rescan_t *) _m)(_dev);
	return (rc);
}

/** @brief Unique descriptor for the BUS_ALLOC_RESOURCE() method */
extern struct kobjop_desc bus_alloc_resource_desc;
/** @brief A function implementing the BUS_ALLOC_RESOURCE() method */
typedef struct resource * bus_alloc_resource_t(device_t _dev, device_t _child,
                                               int _type, int *_rid,
                                               rman_res_t _start,
                                               rman_res_t _end,
                                               rman_res_t _count, u_int _flags);
/**
 * @brief Allocate a system resource
 *
 * This method is called by child devices of a bus to allocate resources.
 * The types are defined in <machine/resource.h>; the meaning of the
 * resource-ID field varies from bus to bus (but @p *rid == 0 is always
 * valid if the resource type is). If a resource was allocated and the
 * caller did not use the RF_ACTIVE to specify that it should be
 * activated immediately, the caller is responsible for calling
 * BUS_ACTIVATE_RESOURCE() when it actually uses the resource.
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device which is requesting an allocation
 * @param _type		the type of resource to allocate
 * @param _rid		a pointer to the resource identifier
 * @param _start	hint at the start of the resource range - pass
 *			@c 0 for any start address
 * @param _end		hint at the end of the resource range - pass
 *			@c ~0 for any end address
 * @param _count	hint at the size of range required - pass @c 1
 *			for any size
 * @param _flags	any extra flags to control the resource
 *			allocation - see @c RF_XXX flags in
 *			<sys/rman.h> for details
 * 
 * @returns		the resource which was allocated or @c NULL if no
 *			resource could be allocated
 */

static __inline struct resource * BUS_ALLOC_RESOURCE(device_t _dev,
                                                     device_t _child, int _type,
                                                     int *_rid,
                                                     rman_res_t _start,
                                                     rman_res_t _end,
                                                     rman_res_t _count,
                                                     u_int _flags)
{
	kobjop_t _m;
	struct resource * rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_alloc_resource);
	rc = ((bus_alloc_resource_t *) _m)(_dev, _child, _type, _rid, _start, _end, _count, _flags);
	return (rc);
}

/** @brief Unique descriptor for the BUS_ACTIVATE_RESOURCE() method */
extern struct kobjop_desc bus_activate_resource_desc;
/** @brief A function implementing the BUS_ACTIVATE_RESOURCE() method */
typedef int bus_activate_resource_t(device_t _dev, device_t _child, int _type,
                                    int _rid, struct resource *_r);
/**
 * @brief Activate a resource
 *
 * Activate a resource previously allocated with
 * BUS_ALLOC_RESOURCE().  This may enable decoding of this resource in a
 * device for instance.  It will also establish a mapping for the resource
 * unless RF_UNMAPPED was set when allocating the resource.
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _type		the type of resource
 * @param _rid		the resource identifier
 * @param _r		the resource to activate
 */

static __inline int BUS_ACTIVATE_RESOURCE(device_t _dev, device_t _child,
                                          int _type, int _rid,
                                          struct resource *_r)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_activate_resource);
	rc = ((bus_activate_resource_t *) _m)(_dev, _child, _type, _rid, _r);
	return (rc);
}

/** @brief Unique descriptor for the BUS_MAP_RESOURCE() method */
extern struct kobjop_desc bus_map_resource_desc;
/** @brief A function implementing the BUS_MAP_RESOURCE() method */
typedef int bus_map_resource_t(device_t _dev, device_t _child, int _type,
                               struct resource *_r,
                               struct resource_map_request *_args,
                               struct resource_map *_map);
/**
 * @brief Map a resource
 *
 * Allocate a mapping for a range of an active resource.  The mapping
 * is described by a struct resource_map object.  This may for instance
 * map a memory region into the kernel's virtual address space.
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _type		the type of resource
 * @param _r		the resource to map
 * @param _args		optional attributes of the mapping
 * @param _map		the mapping
 */

static __inline int BUS_MAP_RESOURCE(device_t _dev, device_t _child, int _type,
                                     struct resource *_r,
                                     struct resource_map_request *_args,
                                     struct resource_map *_map)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_map_resource);
	rc = ((bus_map_resource_t *) _m)(_dev, _child, _type, _r, _args, _map);
	return (rc);
}

/** @brief Unique descriptor for the BUS_UNMAP_RESOURCE() method */
extern struct kobjop_desc bus_unmap_resource_desc;
/** @brief A function implementing the BUS_UNMAP_RESOURCE() method */
typedef int bus_unmap_resource_t(device_t _dev, device_t _child, int _type,
                                 struct resource *_r,
                                 struct resource_map *_map);
/**
 * @brief Unmap a resource
 *
 * Release a mapping previously allocated with
 * BUS_MAP_RESOURCE(). This may for instance unmap a memory region
 * from the kernel's virtual address space.
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _type		the type of resource
 * @param _r		the resource
 * @param _map		the mapping to release
 */

static __inline int BUS_UNMAP_RESOURCE(device_t _dev, device_t _child,
                                       int _type, struct resource *_r,
                                       struct resource_map *_map)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_unmap_resource);
	rc = ((bus_unmap_resource_t *) _m)(_dev, _child, _type, _r, _map);
	return (rc);
}

/** @brief Unique descriptor for the BUS_DEACTIVATE_RESOURCE() method */
extern struct kobjop_desc bus_deactivate_resource_desc;
/** @brief A function implementing the BUS_DEACTIVATE_RESOURCE() method */
typedef int bus_deactivate_resource_t(device_t _dev, device_t _child, int _type,
                                      int _rid, struct resource *_r);
/**
 * @brief Deactivate a resource
 *
 * Deactivate a resource previously allocated with
 * BUS_ALLOC_RESOURCE(). 
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _type		the type of resource
 * @param _rid		the resource identifier
 * @param _r		the resource to deactivate
 */

static __inline int BUS_DEACTIVATE_RESOURCE(device_t _dev, device_t _child,
                                            int _type, int _rid,
                                            struct resource *_r)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_deactivate_resource);
	rc = ((bus_deactivate_resource_t *) _m)(_dev, _child, _type, _rid, _r);
	return (rc);
}

/** @brief Unique descriptor for the BUS_ADJUST_RESOURCE() method */
extern struct kobjop_desc bus_adjust_resource_desc;
/** @brief A function implementing the BUS_ADJUST_RESOURCE() method */
typedef int bus_adjust_resource_t(device_t _dev, device_t _child, int _type,
                                  struct resource *_res, rman_res_t _start,
                                  rman_res_t _end);
/**
 * @brief Adjust a resource
 *
 * Adjust the start and/or end of a resource allocated by
 * BUS_ALLOC_RESOURCE.  At least part of the new address range must overlap
 * with the existing address range.  If the successful, the resource's range
 * will be adjusted to [start, end] on return.
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _type		the type of resource
 * @param _res		the resource to adjust
 * @param _start	the new starting address of the resource range
 * @param _end		the new ending address of the resource range
 */

static __inline int BUS_ADJUST_RESOURCE(device_t _dev, device_t _child,
                                        int _type, struct resource *_res,
                                        rman_res_t _start, rman_res_t _end)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_adjust_resource);
	rc = ((bus_adjust_resource_t *) _m)(_dev, _child, _type, _res, _start, _end);
	return (rc);
}

/** @brief Unique descriptor for the BUS_RELEASE_RESOURCE() method */
extern struct kobjop_desc bus_release_resource_desc;
/** @brief A function implementing the BUS_RELEASE_RESOURCE() method */
typedef int bus_release_resource_t(device_t _dev, device_t _child, int _type,
                                   int _rid, struct resource *_res);
/**
 * @brief Release a resource
 *
 * Free a resource allocated by the BUS_ALLOC_RESOURCE.  The @p _rid
 * value must be the same as the one returned by BUS_ALLOC_RESOURCE()
 * (which is not necessarily the same as the one the client passed).
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _type		the type of resource
 * @param _rid		the resource identifier
 * @param _r		the resource to release
 */

static __inline int BUS_RELEASE_RESOURCE(device_t _dev, device_t _child,
                                         int _type, int _rid,
                                         struct resource *_res)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_release_resource);
	rc = ((bus_release_resource_t *) _m)(_dev, _child, _type, _rid, _res);
	return (rc);
}

/** @brief Unique descriptor for the BUS_SETUP_INTR() method */
extern struct kobjop_desc bus_setup_intr_desc;
/** @brief A function implementing the BUS_SETUP_INTR() method */
typedef int bus_setup_intr_t(device_t _dev, device_t _child,
                             struct resource *_irq, int _flags,
                             driver_filter_t *_filter, driver_intr_t *_intr,
                             void *_arg, void **_cookiep);
/**
 * @brief Install an interrupt handler
 *
 * This method is used to associate an interrupt handler function with
 * an irq resource. When the interrupt triggers, the function @p _intr
 * will be called with the value of @p _arg as its single
 * argument. The value returned in @p *_cookiep is used to cancel the
 * interrupt handler - the caller should save this value to use in a
 * future call to BUS_TEARDOWN_INTR().
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _irq		the resource representing the interrupt
 * @param _flags	a set of bits from enum intr_type specifying
 *			the class of interrupt
 * @param _intr		the function to call when the interrupt
 *			triggers
 * @param _arg		a value to use as the single argument in calls
 *			to @p _intr
 * @param _cookiep	a pointer to a location to receive a cookie
 *			value that may be used to remove the interrupt
 *			handler
 */

static __inline int BUS_SETUP_INTR(device_t _dev, device_t _child,
                                   struct resource *_irq, int _flags,
                                   driver_filter_t *_filter,
                                   driver_intr_t *_intr, void *_arg,
                                   void **_cookiep)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_setup_intr);
	rc = ((bus_setup_intr_t *) _m)(_dev, _child, _irq, _flags, _filter, _intr, _arg, _cookiep);
	return (rc);
}

/** @brief Unique descriptor for the BUS_TEARDOWN_INTR() method */
extern struct kobjop_desc bus_teardown_intr_desc;
/** @brief A function implementing the BUS_TEARDOWN_INTR() method */
typedef int bus_teardown_intr_t(device_t _dev, device_t _child,
                                struct resource *_irq, void *_cookie);
/**
 * @brief Uninstall an interrupt handler
 *
 * This method is used to disassociate an interrupt handler function
 * with an irq resource. The value of @p _cookie must be the value
 * returned from a previous call to BUS_SETUP_INTR().
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _irq		the resource representing the interrupt
 * @param _cookie	the cookie value returned when the interrupt
 *			was originally registered
 */

static __inline int BUS_TEARDOWN_INTR(device_t _dev, device_t _child,
                                      struct resource *_irq, void *_cookie)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_teardown_intr);
	rc = ((bus_teardown_intr_t *) _m)(_dev, _child, _irq, _cookie);
	return (rc);
}

/** @brief Unique descriptor for the BUS_SUSPEND_INTR() method */
extern struct kobjop_desc bus_suspend_intr_desc;
/** @brief A function implementing the BUS_SUSPEND_INTR() method */
typedef int bus_suspend_intr_t(device_t _dev, device_t _child,
                               struct resource *_irq);
/**
 * @brief Suspend an interrupt handler
 *
 * This method is used to mark a handler as suspended in the case
 * that the associated device is powered down and cannot be a source
 * for the, typically shared, interrupt.
 * The value of @p _irq must be the interrupt resource passed
 * to a previous call to BUS_SETUP_INTR().
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _irq		the resource representing the interrupt
 */

static __inline int BUS_SUSPEND_INTR(device_t _dev, device_t _child,
                                     struct resource *_irq)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_suspend_intr);
	rc = ((bus_suspend_intr_t *) _m)(_dev, _child, _irq);
	return (rc);
}

/** @brief Unique descriptor for the BUS_RESUME_INTR() method */
extern struct kobjop_desc bus_resume_intr_desc;
/** @brief A function implementing the BUS_RESUME_INTR() method */
typedef int bus_resume_intr_t(device_t _dev, device_t _child,
                              struct resource *_irq);
/**
 * @brief Resume an interrupt handler
 *
 * This method is used to clear suspended state of a handler when
 * the associated device is powered up and can be an interrupt source
 * again.
 * The value of @p _irq must be the interrupt resource passed
 * to a previous call to BUS_SETUP_INTR().
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _irq		the resource representing the interrupt
 */

static __inline int BUS_RESUME_INTR(device_t _dev, device_t _child,
                                    struct resource *_irq)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_resume_intr);
	rc = ((bus_resume_intr_t *) _m)(_dev, _child, _irq);
	return (rc);
}

/** @brief Unique descriptor for the BUS_SET_RESOURCE() method */
extern struct kobjop_desc bus_set_resource_desc;
/** @brief A function implementing the BUS_SET_RESOURCE() method */
typedef int bus_set_resource_t(device_t _dev, device_t _child, int _type,
                               int _rid, rman_res_t _start, rman_res_t _count);
/**
 * @brief Define a resource which can be allocated with
 * BUS_ALLOC_RESOURCE().
 *
 * This method is used by some buses (typically ISA) to allow a
 * driver to describe a resource range that it would like to
 * allocate. The resource defined by @p _type and @p _rid is defined
 * to start at @p _start and to include @p _count indices in its
 * range.
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which owns the resource
 * @param _type		the type of resource
 * @param _rid		the resource identifier
 * @param _start	the start of the resource range
 * @param _count	the size of the resource range
 */

static __inline int BUS_SET_RESOURCE(device_t _dev, device_t _child, int _type,
                                     int _rid, rman_res_t _start,
                                     rman_res_t _count)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_set_resource);
	rc = ((bus_set_resource_t *) _m)(_dev, _child, _type, _rid, _start, _count);
	return (rc);
}

/** @brief Unique descriptor for the BUS_GET_RESOURCE() method */
extern struct kobjop_desc bus_get_resource_desc;
/** @brief A function implementing the BUS_GET_RESOURCE() method */
typedef int bus_get_resource_t(device_t _dev, device_t _child, int _type,
                               int _rid, rman_res_t *_startp,
                               rman_res_t *_countp);
/**
 * @brief Describe a resource
 *
 * This method allows a driver to examine the range used for a given
 * resource without actually allocating it.
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which owns the resource
 * @param _type		the type of resource
 * @param _rid		the resource identifier
 * @param _start	the address of a location to receive the start
 *			index of the resource range
 * @param _count	the address of a location to receive the size
 *			of the resource range
 */

static __inline int BUS_GET_RESOURCE(device_t _dev, device_t _child, int _type,
                                     int _rid, rman_res_t *_startp,
                                     rman_res_t *_countp)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_resource);
	rc = ((bus_get_resource_t *) _m)(_dev, _child, _type, _rid, _startp, _countp);
	return (rc);
}

/** @brief Unique descriptor for the BUS_DELETE_RESOURCE() method */
extern struct kobjop_desc bus_delete_resource_desc;
/** @brief A function implementing the BUS_DELETE_RESOURCE() method */
typedef void bus_delete_resource_t(device_t _dev, device_t _child, int _type,
                                   int _rid);
/**
 * @brief Delete a resource.
 * 
 * Use this to delete a resource (possibly one previously added with
 * BUS_SET_RESOURCE()).
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which owns the resource
 * @param _type		the type of resource
 * @param _rid		the resource identifier
 */

static __inline void BUS_DELETE_RESOURCE(device_t _dev, device_t _child,
                                         int _type, int _rid)
{
	kobjop_t _m;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_delete_resource);
	((bus_delete_resource_t *) _m)(_dev, _child, _type, _rid);
}

/** @brief Unique descriptor for the BUS_GET_RESOURCE_LIST() method */
extern struct kobjop_desc bus_get_resource_list_desc;
/** @brief A function implementing the BUS_GET_RESOURCE_LIST() method */
typedef struct resource_list * bus_get_resource_list_t(device_t _dev,
                                                       device_t _child);
/**
 * @brief Return a struct resource_list.
 *
 * Used by drivers which use bus_generic_rl_alloc_resource() etc. to
 * implement their resource handling. It should return the resource
 * list of the given child device.
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which owns the resource list
 */

static __inline struct resource_list * BUS_GET_RESOURCE_LIST(device_t _dev,
                                                             device_t _child)
{
	kobjop_t _m;
	struct resource_list * rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_resource_list);
	rc = ((bus_get_resource_list_t *) _m)(_dev, _child);
	return (rc);
}

/** @brief Unique descriptor for the BUS_CHILD_PRESENT() method */
extern struct kobjop_desc bus_child_present_desc;
/** @brief A function implementing the BUS_CHILD_PRESENT() method */
typedef int bus_child_present_t(device_t _dev, device_t _child);
/**
 * @brief Is the hardware described by @p _child still attached to the
 * system?
 *
 * This method should return 0 if the device is not present.  It
 * should return -1 if it is present.  Any errors in determining
 * should be returned as a normal errno value.  Client drivers are to
 * assume that the device is present, even if there is an error
 * determining if it is there.  Buses are to try to avoid returning
 * errors, but newcard will return an error if the device fails to
 * implement this method.
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which is being examined
 */

static __inline int BUS_CHILD_PRESENT(device_t _dev, device_t _child)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_child_present);
	rc = ((bus_child_present_t *) _m)(_dev, _child);
	return (rc);
}

/** @brief Unique descriptor for the BUS_CHILD_PNPINFO_STR() method */
extern struct kobjop_desc bus_child_pnpinfo_str_desc;
/** @brief A function implementing the BUS_CHILD_PNPINFO_STR() method */
typedef int bus_child_pnpinfo_str_t(device_t _dev, device_t _child, char *_buf,
                                    size_t _buflen);
/**
 * @brief Returns the pnp info for this device.
 *
 * Return it as a string.  If the storage is insufficient for the
 * string, then return EOVERFLOW.
 *
 * The string must be formatted as a space-separated list of
 * name=value pairs.  Names may only contain alphanumeric characters,
 * underscores ('_') and hyphens ('-').  Values can contain any
 * non-whitespace characters.  Values containing whitespace can be
 * quoted with double quotes ('"').  Double quotes and backslashes in
 * quoted values can be escaped with backslashes ('\').
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which is being examined
 * @param _buf		the address of a buffer to receive the pnp
 *			string
 * @param _buflen	the size of the buffer pointed to by @p _buf
 */

static __inline int BUS_CHILD_PNPINFO_STR(device_t _dev, device_t _child,
                                          char *_buf, size_t _buflen)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_child_pnpinfo_str);
	rc = ((bus_child_pnpinfo_str_t *) _m)(_dev, _child, _buf, _buflen);
	return (rc);
}

/** @brief Unique descriptor for the BUS_CHILD_LOCATION_STR() method */
extern struct kobjop_desc bus_child_location_str_desc;
/** @brief A function implementing the BUS_CHILD_LOCATION_STR() method */
typedef int bus_child_location_str_t(device_t _dev, device_t _child, char *_buf,
                                     size_t _buflen);
/**
 * @brief Returns the location for this device.
 *
 * Return it as a string.  If the storage is insufficient for the
 * string, then return EOVERFLOW.
 *
 * The string must be formatted as a space-separated list of
 * name=value pairs.  Names may only contain alphanumeric characters,
 * underscores ('_') and hyphens ('-').  Values can contain any
 * non-whitespace characters.  Values containing whitespace can be
 * quoted with double quotes ('"').  Double quotes and backslashes in
 * quoted values can be escaped with backslashes ('\').
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device which is being examined
 * @param _buf		the address of a buffer to receive the location
 *			string
 * @param _buflen	the size of the buffer pointed to by @p _buf
 */

static __inline int BUS_CHILD_LOCATION_STR(device_t _dev, device_t _child,
                                           char *_buf, size_t _buflen)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_child_location_str);
	rc = ((bus_child_location_str_t *) _m)(_dev, _child, _buf, _buflen);
	return (rc);
}

/** @brief Unique descriptor for the BUS_BIND_INTR() method */
extern struct kobjop_desc bus_bind_intr_desc;
/** @brief A function implementing the BUS_BIND_INTR() method */
typedef int bus_bind_intr_t(device_t _dev, device_t _child,
                            struct resource *_irq, int _cpu);
/**
 * @brief Allow drivers to request that an interrupt be bound to a specific
 * CPU.
 * 
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _irq		the resource representing the interrupt
 * @param _cpu		the CPU to bind the interrupt to
 */

static __inline int BUS_BIND_INTR(device_t _dev, device_t _child,
                                  struct resource *_irq, int _cpu)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_bind_intr);
	rc = ((bus_bind_intr_t *) _m)(_dev, _child, _irq, _cpu);
	return (rc);
}

/** @brief Unique descriptor for the BUS_CONFIG_INTR() method */
extern struct kobjop_desc bus_config_intr_desc;
/** @brief A function implementing the BUS_CONFIG_INTR() method */
typedef int bus_config_intr_t(device_t _dev, int _irq, enum intr_trigger _trig,
                              enum intr_polarity _pol);
/**
 * @brief Allow (bus) drivers to specify the trigger mode and polarity
 * of the specified interrupt.
 * 
 * @param _dev		the bus device
 * @param _irq		the interrupt number to modify
 * @param _trig		the trigger mode required
 * @param _pol		the interrupt polarity required
 */

static __inline int BUS_CONFIG_INTR(device_t _dev, int _irq,
                                    enum intr_trigger _trig,
                                    enum intr_polarity _pol)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_config_intr);
	rc = ((bus_config_intr_t *) _m)(_dev, _irq, _trig, _pol);
	return (rc);
}

/** @brief Unique descriptor for the BUS_DESCRIBE_INTR() method */
extern struct kobjop_desc bus_describe_intr_desc;
/** @brief A function implementing the BUS_DESCRIBE_INTR() method */
typedef int bus_describe_intr_t(device_t _dev, device_t _child,
                                struct resource *_irq, void *_cookie,
                                const char *_descr);
/**
 * @brief Allow drivers to associate a description with an active
 * interrupt handler.
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device which allocated the resource
 * @param _irq		the resource representing the interrupt
 * @param _cookie	the cookie value returned when the interrupt
 *			was originally registered
 * @param _descr	the description to associate with the interrupt
 */

static __inline int BUS_DESCRIBE_INTR(device_t _dev, device_t _child,
                                      struct resource *_irq, void *_cookie,
                                      const char *_descr)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_describe_intr);
	rc = ((bus_describe_intr_t *) _m)(_dev, _child, _irq, _cookie, _descr);
	return (rc);
}

/** @brief Unique descriptor for the BUS_HINTED_CHILD() method */
extern struct kobjop_desc bus_hinted_child_desc;
/** @brief A function implementing the BUS_HINTED_CHILD() method */
typedef void bus_hinted_child_t(device_t _dev, const char *_dname, int _dunit);
/**
 * @brief Notify a (bus) driver about a child that the hints mechanism
 * believes it has discovered.
 *
 * The bus is responsible for then adding the child in the right order
 * and discovering other things about the child.  The bus driver is
 * free to ignore this hint, to do special things, etc.  It is all up
 * to the bus driver to interpret.
 *
 * This method is only called in response to the parent bus asking for
 * hinted devices to be enumerated.
 *
 * @param _dev		the bus device
 * @param _dname	the name of the device w/o unit numbers
 * @param _dunit	the unit number of the device
 */

static __inline void BUS_HINTED_CHILD(device_t _dev, const char *_dname,
                                      int _dunit)
{
	kobjop_t _m;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_hinted_child);
	((bus_hinted_child_t *) _m)(_dev, _dname, _dunit);
}

/** @brief Unique descriptor for the BUS_GET_DMA_TAG() method */
extern struct kobjop_desc bus_get_dma_tag_desc;
/** @brief A function implementing the BUS_GET_DMA_TAG() method */
typedef bus_dma_tag_t bus_get_dma_tag_t(device_t _dev, device_t _child);
/**
 * @brief Returns bus_dma_tag_t for use w/ devices on the bus.
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device to which the tag will belong
 */

static __inline bus_dma_tag_t BUS_GET_DMA_TAG(device_t _dev, device_t _child)
{
	kobjop_t _m;
	bus_dma_tag_t rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_dma_tag);
	rc = ((bus_get_dma_tag_t *) _m)(_dev, _child);
	return (rc);
}

/** @brief Unique descriptor for the BUS_GET_BUS_TAG() method */
extern struct kobjop_desc bus_get_bus_tag_desc;
/** @brief A function implementing the BUS_GET_BUS_TAG() method */
typedef bus_space_tag_t bus_get_bus_tag_t(device_t _dev, device_t _child);
/**
 * @brief Returns bus_space_tag_t for use w/ devices on the bus.
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device to which the tag will belong
 */

static __inline bus_space_tag_t BUS_GET_BUS_TAG(device_t _dev, device_t _child)
{
	kobjop_t _m;
	bus_space_tag_t rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_bus_tag);
	rc = ((bus_get_bus_tag_t *) _m)(_dev, _child);
	return (rc);
}

/** @brief Unique descriptor for the BUS_HINT_DEVICE_UNIT() method */
extern struct kobjop_desc bus_hint_device_unit_desc;
/** @brief A function implementing the BUS_HINT_DEVICE_UNIT() method */
typedef void bus_hint_device_unit_t(device_t _dev, device_t _child,
                                    const char *_name, int *_unitp);
/**
 * @brief Allow the bus to determine the unit number of a device.
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device whose unit is to be wired
 * @param _name		the name of the device's new devclass
 * @param _unitp	a pointer to the device's new unit value
 */

static __inline void BUS_HINT_DEVICE_UNIT(device_t _dev, device_t _child,
                                          const char *_name, int *_unitp)
{
	kobjop_t _m;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_hint_device_unit);
	((bus_hint_device_unit_t *) _m)(_dev, _child, _name, _unitp);
}

/** @brief Unique descriptor for the BUS_NEW_PASS() method */
extern struct kobjop_desc bus_new_pass_desc;
/** @brief A function implementing the BUS_NEW_PASS() method */
typedef void bus_new_pass_t(device_t _dev);
/**
 * @brief Notify a bus that the bus pass level has been changed
 *
 * @param _dev		the bus device
 */

static __inline void BUS_NEW_PASS(device_t _dev)
{
	kobjop_t _m;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_new_pass);
	((bus_new_pass_t *) _m)(_dev);
}

/** @brief Unique descriptor for the BUS_REMAP_INTR() method */
extern struct kobjop_desc bus_remap_intr_desc;
/** @brief A function implementing the BUS_REMAP_INTR() method */
typedef int bus_remap_intr_t(device_t _dev, device_t _child, u_int _irq);
/**
 * @brief Notify a bus that specified child's IRQ should be remapped.
 *
 * @param _dev		the bus device
 * @param _child	the child device
 * @param _irq		the irq number
 */

static __inline int BUS_REMAP_INTR(device_t _dev, device_t _child, u_int _irq)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_remap_intr);
	rc = ((bus_remap_intr_t *) _m)(_dev, _child, _irq);
	return (rc);
}

/** @brief Unique descriptor for the BUS_SUSPEND_CHILD() method */
extern struct kobjop_desc bus_suspend_child_desc;
/** @brief A function implementing the BUS_SUSPEND_CHILD() method */
typedef int bus_suspend_child_t(device_t _dev, device_t _child);
/**
 * @brief Suspend a given child
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device to suspend
 */

static __inline int BUS_SUSPEND_CHILD(device_t _dev, device_t _child)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_suspend_child);
	rc = ((bus_suspend_child_t *) _m)(_dev, _child);
	return (rc);
}

/** @brief Unique descriptor for the BUS_RESUME_CHILD() method */
extern struct kobjop_desc bus_resume_child_desc;
/** @brief A function implementing the BUS_RESUME_CHILD() method */
typedef int bus_resume_child_t(device_t _dev, device_t _child);
/**
 * @brief Resume a given child
 *
 * @param _dev		the parent device of @p _child
 * @param _child	the device to resume
 */

static __inline int BUS_RESUME_CHILD(device_t _dev, device_t _child)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_resume_child);
	rc = ((bus_resume_child_t *) _m)(_dev, _child);
	return (rc);
}

/** @brief Unique descriptor for the BUS_GET_DOMAIN() method */
extern struct kobjop_desc bus_get_domain_desc;
/** @brief A function implementing the BUS_GET_DOMAIN() method */
typedef int bus_get_domain_t(device_t _dev, device_t _child, int *_domain);
/**
 * @brief Get the VM domain handle for the given bus and child.
 *
 * @param _dev		the bus device
 * @param _child	the child device
 * @param _domain	a pointer to the bus's domain handle identifier
 */

static __inline int BUS_GET_DOMAIN(device_t _dev, device_t _child, int *_domain)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_domain);
	rc = ((bus_get_domain_t *) _m)(_dev, _child, _domain);
	return (rc);
}

/** @brief Unique descriptor for the BUS_GET_CPUS() method */
extern struct kobjop_desc bus_get_cpus_desc;
/** @brief A function implementing the BUS_GET_CPUS() method */
typedef int bus_get_cpus_t(device_t _dev, device_t _child, enum cpu_sets _op,
                           size_t _setsize, cpuset_t *_cpuset);
/**
 * @brief Request a set of CPUs
 *
 * @param _dev		the bus device
 * @param _child	the child device
 * @param _op		type of CPUs to request
 * @param _setsize	the size of the set passed in _cpuset
 * @param _cpuset	a pointer to a cpuset to receive the requested
 *			set of CPUs
 */

static __inline int BUS_GET_CPUS(device_t _dev, device_t _child,
                                 enum cpu_sets _op, size_t _setsize,
                                 cpuset_t *_cpuset)
{
	kobjop_t _m;
	int rc;
	KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_cpus);
	rc = ((bus_get_cpus_t *) _m)(_dev, _child, _op, _setsize, _cpuset);
	return (rc);
}

#endif /* _bus_if_h_ */