subr_bus.c (46743) | subr_bus.c (46913) |
---|---|
1/*- 2 * Copyright (c) 1997,1998 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 1997,1998 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $Id: subr_bus.c,v 1.19 1999/05/08 18:08:59 peter Exp $ | 26 * $Id: subr_bus.c,v 1.20 1999/05/08 21:59:35 dfr Exp $ |
27 */ 28 29#include <sys/param.h> 30#include <sys/queue.h> 31#include <sys/malloc.h> 32#include <sys/kernel.h> 33#include <sys/module.h> 34#include <sys/sysctl.h> --- 60 unchanged lines hidden (view full) --- 95 */ 96static int next_method_offset = 1; 97 98LIST_HEAD(methodlist, method) methods; 99struct method { 100 LIST_ENTRY(method) link; /* linked list of methods */ 101 int offset; /* offset in method table */ 102 int refs; /* count of device_op_desc users */ | 27 */ 28 29#include <sys/param.h> 30#include <sys/queue.h> 31#include <sys/malloc.h> 32#include <sys/kernel.h> 33#include <sys/module.h> 34#include <sys/sysctl.h> --- 60 unchanged lines hidden (view full) --- 95 */ 96static int next_method_offset = 1; 97 98LIST_HEAD(methodlist, method) methods; 99struct method { 100 LIST_ENTRY(method) link; /* linked list of methods */ 101 int offset; /* offset in method table */ 102 int refs; /* count of device_op_desc users */ |
103 devop_t deflt; /* default implementation */ |
|
103 char* name; /* unique name of method */ 104}; 105 106static void 107register_method(struct device_op_desc *desc) 108{ 109 struct method* m; 110 --- 16 unchanged lines hidden (view full) --- 127 m = (struct method *) malloc(sizeof(struct method) 128 + strlen(desc->name) + 1, 129 M_DEVBUF, M_NOWAIT); 130 if (!m) 131 panic("register_method: out of memory"); 132 bzero(m, sizeof(struct method) + strlen(desc->name) + 1); 133 m->offset = next_method_offset++; 134 m->refs = 1; | 104 char* name; /* unique name of method */ 105}; 106 107static void 108register_method(struct device_op_desc *desc) 109{ 110 struct method* m; 111 --- 16 unchanged lines hidden (view full) --- 128 m = (struct method *) malloc(sizeof(struct method) 129 + strlen(desc->name) + 1, 130 M_DEVBUF, M_NOWAIT); 131 if (!m) 132 panic("register_method: out of memory"); 133 bzero(m, sizeof(struct method) + strlen(desc->name) + 1); 134 m->offset = next_method_offset++; 135 m->refs = 1; |
136 m->deflt = desc->deflt; |
|
135 m->name = (char*) (m + 1); 136 strcpy(m->name, desc->name); 137 LIST_INSERT_HEAD(&methods, m, link); 138 139 desc->offset = m->offset; 140 desc->method = m; 141} 142 --- 19 unchanged lines hidden (view full) --- 162 { error_method } 163}; 164 165static void 166compile_methods(driver_t *driver) 167{ 168 device_ops_t ops; 169 struct device_method *m; | 137 m->name = (char*) (m + 1); 138 strcpy(m->name, desc->name); 139 LIST_INSERT_HEAD(&methods, m, link); 140 141 desc->offset = m->offset; 142 desc->method = m; 143} 144 --- 19 unchanged lines hidden (view full) --- 164 { error_method } 165}; 166 167static void 168compile_methods(driver_t *driver) 169{ 170 device_ops_t ops; 171 struct device_method *m; |
172 struct method *cm; |
|
170 int i; 171 172 /* 173 * First register any methods which need it. 174 */ 175 for (i = 0, m = driver->methods; m->desc; i++, m++) 176 register_method(m->desc); 177 178 /* 179 * Then allocate the compiled op table. 180 */ 181 ops = malloc(sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t), 182 M_DEVBUF, M_NOWAIT); 183 if (!ops) 184 panic("compile_methods: out of memory"); 185 bzero(ops, sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t)); 186 187 ops->maxoffset = next_method_offset; | 173 int i; 174 175 /* 176 * First register any methods which need it. 177 */ 178 for (i = 0, m = driver->methods; m->desc; i++, m++) 179 register_method(m->desc); 180 181 /* 182 * Then allocate the compiled op table. 183 */ 184 ops = malloc(sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t), 185 M_DEVBUF, M_NOWAIT); 186 if (!ops) 187 panic("compile_methods: out of memory"); 188 bzero(ops, sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t)); 189 190 ops->maxoffset = next_method_offset; |
191 /* Fill in default methods and then overwrite with driver methods */ |
|
188 for (i = 0; i < next_method_offset; i++) 189 ops->methods[i] = error_method; | 192 for (i = 0; i < next_method_offset; i++) 193 ops->methods[i] = error_method; |
194 for (cm = LIST_FIRST(&methods); cm; cm = LIST_NEXT(cm, link)) { 195 if (cm->deflt) 196 ops->methods[cm->offset] = cm->deflt; 197 } |
|
190 for (i = 0, m = driver->methods; m->desc; i++, m++) 191 ops->methods[m->desc->offset] = m->func; 192 PDEBUG(("%s has %d method%s, wasting %d bytes", 193 DRIVERNAME(driver), i, (i==1?"":"s"), 194 (next_method_offset-i)*sizeof(devop_t))); 195 196 driver->ops = ops; 197} --- 520 unchanged lines hidden (view full) --- 718 } else 719 return TAILQ_NEXT(last, link); 720} 721 722static int 723device_probe_child(device_t dev, device_t child) 724{ 725 devclass_t dc; | 198 for (i = 0, m = driver->methods; m->desc; i++, m++) 199 ops->methods[m->desc->offset] = m->func; 200 PDEBUG(("%s has %d method%s, wasting %d bytes", 201 DRIVERNAME(driver), i, (i==1?"":"s"), 202 (next_method_offset-i)*sizeof(devop_t))); 203 204 driver->ops = ops; 205} --- 520 unchanged lines hidden (view full) --- 726 } else 727 return TAILQ_NEXT(last, link); 728} 729 730static int 731device_probe_child(device_t dev, device_t child) 732{ 733 devclass_t dc; |
734 driverlink_t best = 0; |
|
726 driverlink_t dl; | 735 driverlink_t dl; |
736 int result, pri = 0; |
|
727 728 dc = dev->devclass; 729 if (dc == NULL) 730 panic("device_probe_child: parent device has no devclass"); 731 732 if (child->state == DS_ALIVE) 733 return 0; 734 735 for (dl = first_matching_driver(dc, child); 736 dl; 737 dl = next_matching_driver(dc, child, dl)) { 738 PDEBUG(("Trying %s", DRIVERNAME(dl->driver))); 739 device_set_driver(child, dl->driver); | 737 738 dc = dev->devclass; 739 if (dc == NULL) 740 panic("device_probe_child: parent device has no devclass"); 741 742 if (child->state == DS_ALIVE) 743 return 0; 744 745 for (dl = first_matching_driver(dc, child); 746 dl; 747 dl = next_matching_driver(dc, child, dl)) { 748 PDEBUG(("Trying %s", DRIVERNAME(dl->driver))); 749 device_set_driver(child, dl->driver); |
740 if (DEVICE_PROBE(child) == 0) { 741 if (!child->devclass) 742 device_set_devclass(child, dl->driver->name); 743 child->state = DS_ALIVE; 744 return 0; | 750 result = DEVICE_PROBE(child); 751 752 /* 753 * If the driver returns SUCCESS, there can be no higher match 754 * for this device. 755 */ 756 if (result == 0) { 757 best = dl; 758 pri = 0; 759 break; |
745 } | 760 } |
761 762 /* 763 * The driver returned an error so it certainly doesn't match. 764 */ 765 if (result > 0) 766 continue; 767 768 /* 769 * A priority lower than SUCCESS, remember the best matching 770 * driver. Initialise the value of pri for the first match. 771 */ 772 if (best == 0 || result > pri) { 773 best = dl; 774 pri = result; 775 continue; 776 } |
|
746 } 747 | 777 } 778 |
779 /* 780 * If we found a driver, change state and initialise the devclass. 781 */ 782 if (best) { 783 if (!child->devclass) 784 device_set_devclass(child, best->driver->name); 785 device_set_driver(child, best->driver); 786 if (pri < 0) { 787 /* 788 * A bit bogus. Call the probe method again to make sure 789 * that we have the right description. 790 */ 791 DEVICE_PROBE(child); 792 } 793 child->state = DS_ALIVE; 794 return 0; 795 } 796 |
|
748 return ENXIO; 749} 750 751device_t 752device_get_parent(device_t dev) 753{ 754 return dev->parent; 755} --- 1371 unchanged lines hidden --- | 797 return ENXIO; 798} 799 800device_t 801device_get_parent(device_t dev) 802{ 803 return dev->parent; 804} --- 1371 unchanged lines hidden --- |