| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: main.c,v 1.96 2017/11/27 00:25:46 christos Exp $ */ | | 1 | /* $NetBSD: main.c,v 1.97 2017/11/28 15:31:33 christos Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1992, 1993 | | 4 | * Copyright (c) 1992, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This software was developed by the Computer Systems Engineering group | | 7 | * This software was developed by the Computer Systems Engineering group |
8 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and | | 8 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and |
9 | * contributed to Berkeley. | | 9 | * contributed to Berkeley. |
10 | * | | 10 | * |
11 | * All advertising materials mentioning features or use of this software | | 11 | * All advertising materials mentioning features or use of this software |
12 | * must display the following acknowledgement: | | 12 | * must display the following acknowledgement: |
13 | * This product includes software developed by the University of | | 13 | * This product includes software developed by the University of |
14 | * California, Lawrence Berkeley Laboratories. | | 14 | * California, Lawrence Berkeley Laboratories. |
| @@ -35,27 +35,27 @@ | | | @@ -35,27 +35,27 @@ |
35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
37 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 37 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
38 | * SUCH DAMAGE. | | 38 | * SUCH DAMAGE. |
39 | * | | 39 | * |
40 | * from: @(#)main.c 8.1 (Berkeley) 6/6/93 | | 40 | * from: @(#)main.c 8.1 (Berkeley) 6/6/93 |
41 | */ | | 41 | */ |
42 | | | 42 | |
43 | #if HAVE_NBTOOL_CONFIG_H | | 43 | #if HAVE_NBTOOL_CONFIG_H |
44 | #include "nbtool_config.h" | | 44 | #include "nbtool_config.h" |
45 | #endif | | 45 | #endif |
46 | | | 46 | |
47 | #include <sys/cdefs.h> | | 47 | #include <sys/cdefs.h> |
48 | __RCSID("$NetBSD: main.c,v 1.96 2017/11/27 00:25:46 christos Exp $"); | | 48 | __RCSID("$NetBSD: main.c,v 1.97 2017/11/28 15:31:33 christos Exp $"); |
49 | | | 49 | |
50 | #ifndef MAKE_BOOTSTRAP | | 50 | #ifndef MAKE_BOOTSTRAP |
51 | #include <sys/cdefs.h> | | 51 | #include <sys/cdefs.h> |
52 | #define COPYRIGHT(x) __COPYRIGHT(x) | | 52 | #define COPYRIGHT(x) __COPYRIGHT(x) |
53 | #else | | 53 | #else |
54 | #define COPYRIGHT(x) static const char copyright[] = x | | 54 | #define COPYRIGHT(x) static const char copyright[] = x |
55 | #endif | | 55 | #endif |
56 | | | 56 | |
57 | #ifndef lint | | 57 | #ifndef lint |
58 | COPYRIGHT("@(#) Copyright (c) 1992, 1993\ | | 58 | COPYRIGHT("@(#) Copyright (c) 1992, 1993\ |
59 | The Regents of the University of California. All rights reserved."); | | 59 | The Regents of the University of California. All rights reserved."); |
60 | #endif /* not lint */ | | 60 | #endif /* not lint */ |
61 | | | 61 | |
| @@ -1866,41 +1866,42 @@ check_dead_devi(const char *key, void *v | | | @@ -1866,41 +1866,42 @@ check_dead_devi(const char *key, void *v |
1866 | } | | 1866 | } |
1867 | } | | 1867 | } |
1868 | return 0; | | 1868 | return 0; |
1869 | } | | 1869 | } |
1870 | | | 1870 | |
1871 | static struct devbase root; | | 1871 | static struct devbase root; |
1872 | | | 1872 | |
1873 | static int | | 1873 | static int |
1874 | addlevelparent(struct devbase *d, struct devbase *parent) | | 1874 | addlevelparent(struct devbase *d, struct devbase *parent) |
1875 | { | | 1875 | { |
1876 | struct devbase *p; | | 1876 | struct devbase *p; |
1877 | | | 1877 | |
1878 | if (d == parent) { | | 1878 | if (d == parent) { |
1879 | if (d->d_level++ > 1) | | 1879 | if (d->d_level > 1) |
1880 | return 0; | | 1880 | return 0; |
1881 | return 1; | | 1881 | return 1; |
1882 | } | | 1882 | } |
1883 | | | 1883 | |
1884 | if (d->d_levelparent) { | | 1884 | if (d->d_levelparent) { |
1885 | if (d->d_level++ > 1) | | 1885 | if (d->d_level > 1) |
1886 | return 0; | | 1886 | return 0; |
1887 | return 1; | | 1887 | return 1; |
1888 | } | | 1888 | } |
1889 | | | 1889 | |
1890 | for (p = parent; p != NULL; p = p->d_levelparent) | | 1890 | for (p = parent; p != NULL; p = p->d_levelparent) |
1891 | if (d == p && d->d_level++ > 1) | | 1891 | if (d == p && d->d_level > 1) |
1892 | return 0; | | 1892 | return 0; |
1893 | d->d_levelparent = p ? p : &root; | | 1893 | d->d_levelparent = p ? p : &root; |
| | | 1894 | d->d_level++; |
1894 | return 1; | | 1895 | return 1; |
1895 | } | | 1896 | } |
1896 | | | 1897 | |
1897 | static void | | 1898 | static void |
1898 | do_kill_orphans(struct devbase *d, struct attr *at, struct devbase *parent, | | 1899 | do_kill_orphans(struct devbase *d, struct attr *at, struct devbase *parent, |
1899 | int state) | | 1900 | int state) |
1900 | { | | 1901 | { |
1901 | struct nvlist *nv1; | | 1902 | struct nvlist *nv1; |
1902 | struct attrlist *al; | | 1903 | struct attrlist *al; |
1903 | struct attr *a; | | 1904 | struct attr *a; |
1904 | struct devi *i, *j = NULL; | | 1905 | struct devi *i, *j = NULL; |
1905 | struct pspec *p; | | 1906 | struct pspec *p; |
1906 | int active = 0; | | 1907 | int active = 0; |
| @@ -1916,26 +1917,27 @@ do_kill_orphans(struct devbase *d, struc | | | @@ -1916,26 +1917,27 @@ do_kill_orphans(struct devbase *d, struc |
1916 | * A pseudo device can never be marked DEVI_IGNORED. | | 1917 | * A pseudo device can never be marked DEVI_IGNORED. |
1917 | */ | | 1918 | */ |
1918 | if (d->d_ispseudo) { | | 1919 | if (d->d_ispseudo) { |
1919 | if (d->d_ihead != NULL) | | 1920 | if (d->d_ihead != NULL) |
1920 | d->d_ihead->i_active = active = DEVI_ACTIVE; | | 1921 | d->d_ihead->i_active = active = DEVI_ACTIVE; |
1921 | else { | | 1922 | else { |
1922 | if (ht_lookup(deaddevitab, d->d_name) != NULL) | | 1923 | if (ht_lookup(deaddevitab, d->d_name) != NULL) |
1923 | active = DEVI_IGNORED; | | 1924 | active = DEVI_IGNORED; |
1924 | else | | 1925 | else |
1925 | return; | | 1926 | return; |
1926 | } | | 1927 | } |
1927 | } else { | | 1928 | } else { |
1928 | int seen = 0; | | 1929 | int seen = 0; |
| | | 1930 | int changed = 0; |
1929 | | | 1931 | |
1930 | for (i = d->d_ihead; i != NULL; i = i->i_bsame) { | | 1932 | for (i = d->d_ihead; i != NULL; i = i->i_bsame) { |
1931 | for (j = i; j != NULL; j = j->i_alias) { | | 1933 | for (j = i; j != NULL; j = j->i_alias) { |
1932 | p = j->i_pspec; | | 1934 | p = j->i_pspec; |
1933 | if ((p == NULL && at == NULL) || | | 1935 | if ((p == NULL && at == NULL) || |
1934 | (p != NULL && p->p_iattr == at && | | 1936 | (p != NULL && p->p_iattr == at && |
1935 | (p->p_atdev == NULL || | | 1937 | (p->p_atdev == NULL || |
1936 | p->p_atdev == parent))) { | | 1938 | p->p_atdev == parent))) { |
1937 | if (p != NULL && | | 1939 | if (p != NULL && |
1938 | !devbase_has_any_instance(parent, | | 1940 | !devbase_has_any_instance(parent, |
1939 | p->p_atunit, state, j->i_level)) | | 1941 | p->p_atunit, state, j->i_level)) |
1940 | continue; | | 1942 | continue; |
1941 | /* | | 1943 | /* |
| @@ -1948,26 +1950,27 @@ do_kill_orphans(struct devbase *d, struc | | | @@ -1948,26 +1950,27 @@ do_kill_orphans(struct devbase *d, struc |
1948 | */ | | 1950 | */ |
1949 | if (j->i_active == DEVI_ACTIVE || | | 1951 | if (j->i_active == DEVI_ACTIVE || |
1950 | j->i_active == state) { | | 1952 | j->i_active == state) { |
1951 | /* | | 1953 | /* |
1952 | * Device has already been | | 1954 | * Device has already been |
1953 | * seen. However it might | | 1955 | * seen. However it might |
1954 | * have siblings who still | | 1956 | * have siblings who still |
1955 | * have to be activated or | | 1957 | * have to be activated or |
1956 | * orphaned. | | 1958 | * orphaned. |
1957 | */ | | 1959 | */ |
1958 | seen = 1; | | 1960 | seen = 1; |
1959 | continue; | | 1961 | continue; |
1960 | } | | 1962 | } |
| | | 1963 | changed |= j->i_active != state; |
1961 | j->i_active = active = state; | | 1964 | j->i_active = active = state; |
1962 | if (p != NULL) { | | 1965 | if (p != NULL) { |
1963 | if (state == DEVI_ACTIVE || | | 1966 | if (state == DEVI_ACTIVE || |
1964 | --p->p_ref == 0) | | 1967 | --p->p_ref == 0) |
1965 | p->p_active = state; | | 1968 | p->p_active = state; |
1966 | } | | 1969 | } |
1967 | if (state == DEVI_IGNORED) { | | 1970 | if (state == DEVI_IGNORED) { |
1968 | CFGDBG(5, | | 1971 | CFGDBG(5, |
1969 | "`%s' at '%s' ignored", | | 1972 | "`%s' at '%s' ignored", |
1970 | d->d_name, parent ? | | 1973 | d->d_name, parent ? |
1971 | parent->d_name : "(root)"); | | 1974 | parent->d_name : "(root)"); |
1972 | } | | 1975 | } |
1973 | } | | 1976 | } |
| @@ -1987,28 +1990,29 @@ do_kill_orphans(struct devbase *d, struc | | | @@ -1987,28 +1990,29 @@ do_kill_orphans(struct devbase *d, struc |
1987 | * That device had its instances removed. | | 1990 | * That device had its instances removed. |
1988 | * Continue the loop marking descendants | | 1991 | * Continue the loop marking descendants |
1989 | * with DEVI_IGNORED instead of DEVI_ACTIVE. | | 1992 | * with DEVI_IGNORED instead of DEVI_ACTIVE. |
1990 | * | | 1993 | * |
1991 | * There is one special case for devices that | | 1994 | * There is one special case for devices that |
1992 | * are their own parent: if that instance is | | 1995 | * are their own parent: if that instance is |
1993 | * removed (e.g., no uhub* at uhub?), we don't | | 1996 | * removed (e.g., no uhub* at uhub?), we don't |
1994 | * have to continue looping. | | 1997 | * have to continue looping. |
1995 | */ | | 1998 | */ |
1996 | active = DEVI_IGNORED; | | 1999 | active = DEVI_IGNORED; |
1997 | CFGDBG(5, "`%s' at '%s' ignored", d->d_name, | | 2000 | CFGDBG(5, "`%s' at '%s' ignored", d->d_name, |
1998 | parent ? parent->d_name : "(root)"); | | 2001 | parent ? parent->d_name : "(root)"); |
1999 | | | 2002 | |
2000 | } | | 2003 | } else if (!changed) |
2001 | } | | 2004 | goto out; |
| | | 2005 | } |
2002 | } | | 2006 | } |
2003 | | | 2007 | |
2004 | for (al = d->d_attrs; al != NULL; al = al->al_next) { | | 2008 | for (al = d->d_attrs; al != NULL; al = al->al_next) { |
2005 | a = al->al_this; | | 2009 | a = al->al_this; |
2006 | for (nv1 = a->a_devs; nv1 != NULL; nv1 = nv1->nv_next) { | | 2010 | for (nv1 = a->a_devs; nv1 != NULL; nv1 = nv1->nv_next) { |
2007 | do_kill_orphans(nv1->nv_ptr, a, d, active); | | 2011 | do_kill_orphans(nv1->nv_ptr, a, d, active); |
2008 | } | | 2012 | } |
2009 | } | | 2013 | } |
2010 | out: | | 2014 | out: |
2011 | d->d_levelparent = NULL; | | 2015 | d->d_levelparent = NULL; |
2012 | d->d_level--; | | 2016 | d->d_level--; |
2013 | } | | 2017 | } |
2014 | | | 2018 | |