Index: sys/kern/subr_intr.c =================================================================== --- sys/kern/subr_intr.c +++ sys/kern/subr_intr.c @@ -107,6 +107,7 @@ device_t pic_dev; #define FLAG_PIC (1 << 0) #define FLAG_MSI (1 << 1) +#define FLAG_TYPE_MASK (FLAG_PIC | FLAG_MSI) u_int pic_flags; struct mtx pic_child_lock; SLIST_HEAD(, intr_pic_child) pic_children; @@ -115,7 +116,7 @@ static struct mtx pic_list_lock; static SLIST_HEAD(, intr_pic) pic_list; -static struct intr_pic *pic_lookup(device_t dev, intptr_t xref); +static struct intr_pic *pic_lookup(device_t dev, intptr_t xref, int flags); /* Interrupt source definition. */ static struct mtx isrc_table_lock; @@ -688,25 +689,33 @@ * Lookup interrupt controller locked. */ static inline struct intr_pic * -pic_lookup_locked(device_t dev, intptr_t xref) +pic_lookup_locked(device_t dev, intptr_t xref, int flags) { struct intr_pic *pic; mtx_assert(&pic_list_lock, MA_OWNED); - if (dev == NULL && xref == 0) - return (NULL); + KASSERT(dev != NULL || xref != -1, + ("pic_lookup_locked: Either the device or the xref must be valid")); /* Note that pic->pic_dev is never NULL on registered PIC. */ SLIST_FOREACH(pic, &pic_list, pic_next) { + if ((pic->pic_flags & FLAG_TYPE_MASK) != + (flags & FLAG_TYPE_MASK)) + continue; + if (dev == NULL) { + /* No dev, check the xref */ if (xref == pic->pic_xref) return (pic); - } else if (xref == 0 || pic->pic_xref == 0) { + } else if (xref == -1) { + /* No xref, check the dev */ if (dev == pic->pic_dev) return (pic); - } else if (xref == pic->pic_xref && dev == pic->pic_dev) - return (pic); + } else if (xref == pic->pic_xref && dev == pic->pic_dev) { + /* Have both, check both */ + return (pic); + } } return (NULL); } @@ -715,12 +724,12 @@ * Lookup interrupt controller. */ static struct intr_pic * -pic_lookup(device_t dev, intptr_t xref) +pic_lookup(device_t dev, intptr_t xref, int flags) { struct intr_pic *pic; mtx_lock(&pic_list_lock); - pic = pic_lookup_locked(dev, xref); + pic = pic_lookup_locked(dev, xref, flags); mtx_unlock(&pic_list_lock); return (pic); } @@ -729,12 +738,14 @@ * Create interrupt controller. */ static struct intr_pic * -pic_create(device_t dev, intptr_t xref) +pic_create(device_t dev, intptr_t xref, int flags) { struct intr_pic *pic; + KASSERT(xref != -1, ("%s: Invalid xref", __func__)); + mtx_lock(&pic_list_lock); - pic = pic_lookup_locked(dev, xref); + pic = pic_lookup_locked(dev, xref, flags & FLAG_TYPE_MASK); if (pic != NULL) { mtx_unlock(&pic_list_lock); return (pic); @@ -746,6 +757,7 @@ } pic->pic_xref = xref; pic->pic_dev = dev; + pic->pic_flags = flags; mtx_init(&pic->pic_child_lock, "pic child lock", NULL, MTX_SPIN); SLIST_INSERT_HEAD(&pic_list, pic, pic_next); mtx_unlock(&pic_list_lock); @@ -761,6 +773,8 @@ { struct intr_pic *pic; + KASSERT(xref != -1, ("%s: Invalid xref", __func__)); + mtx_lock(&pic_list_lock); pic = pic_lookup_locked(dev, xref); if (pic == NULL) { @@ -783,12 +797,10 @@ if (dev == NULL) return (NULL); - pic = pic_create(dev, xref); + pic = pic_create(dev, xref, FLAG_PIC); if (pic == NULL) return (NULL); - pic->pic_flags |= FLAG_PIC; - debugf("PIC %p registered for %s \n", pic, device_get_nameunit(dev), dev, xref); return (pic); @@ -822,13 +834,14 @@ { struct intr_pic *pic; - pic = pic_lookup(dev, xref); + KASSERT(xref != -1, ("%s: Invalid xref", __func__)); + pic = pic_lookup(dev, xref, FLAG_PIC); if (pic == NULL) { device_printf(dev, "not registered\n"); return (EINVAL); } - KASSERT((pic->pic_flags & FLAG_PIC) != 0, + KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_PIC, ("%s: Found a non-PIC controller: %s", __func__, device_get_name(pic->pic_dev))); @@ -870,7 +883,7 @@ struct intr_pic_child *child; #endif - parent_pic = pic_lookup(parent, 0); + parent_pic = pic_lookup(parent, -1, FLAG_PIC); if (parent_pic == NULL) return (NULL); @@ -904,13 +917,15 @@ if (data == NULL) return (EINVAL); - pic = pic_lookup(dev, xref); + KASSERT(xref != -1, ("%s: Invalid xref", __func__)); + pic = pic_lookup(dev, xref, + (data->type == INTR_MAP_DATA_MSI) ? FLAG_MSI : FLAG_PIC); if (pic == NULL) return (ESRCH); switch (data->type) { case INTR_MAP_DATA_MSI: - KASSERT((pic->pic_flags & FLAG_MSI) != 0, + KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI, ("%s: Found a non-MSI controller: %s", __func__, device_get_name(pic->pic_dev))); msi = (struct intr_map_data_msi *)data; @@ -918,7 +933,7 @@ return (0); default: - KASSERT((pic->pic_flags & FLAG_PIC) != 0, + KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_PIC, ("%s: Found a non-PIC controller: %s", __func__, device_get_name(pic->pic_dev))); return (PIC_MAP_INTR(pic->pic_dev, data, isrc)); @@ -1255,12 +1270,10 @@ if (dev == NULL) return (EINVAL); - pic = pic_create(dev, xref); + pic = pic_create(dev, xref, FLAG_MSI); if (pic == NULL) return (ENOMEM); - pic->pic_flags |= FLAG_MSI; - debugf("PIC %p registered for %s \n", pic, device_get_nameunit(dev), dev, (uintmax_t)xref); return (0); @@ -1276,11 +1289,12 @@ struct intr_map_data_msi *msi; int err, i; - pic = pic_lookup(NULL, xref); + KASSERT(xref != -1, ("%s: Invalid xref", __func__)); + pic = pic_lookup(NULL, xref, FLAG_MSI); if (pic == NULL) return (ESRCH); - KASSERT((pic->pic_flags & FLAG_MSI) != 0, + KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI, ("%s: Found a non-MSI controller: %s", __func__, device_get_name(pic->pic_dev))); @@ -1313,11 +1327,12 @@ struct intr_map_data_msi *msi; int i, err; - pic = pic_lookup(NULL, xref); + KASSERT(xref != -1, ("%s: Invalid xref", __func__)); + pic = pic_lookup(NULL, xref, FLAG_MSI); if (pic == NULL) return (ESRCH); - KASSERT((pic->pic_flags & FLAG_MSI) != 0, + KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI, ("%s: Found a non-MSI controller: %s", __func__, device_get_name(pic->pic_dev))); @@ -1352,11 +1367,12 @@ struct intr_map_data_msi *msi; int err; - pic = pic_lookup(NULL, xref); + KASSERT(xref != -1, ("%s: Invalid xref", __func__)); + pic = pic_lookup(NULL, xref, FLAG_MSI); if (pic == NULL) return (ESRCH); - KASSERT((pic->pic_flags & FLAG_MSI) != 0, + KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI, ("%s: Found a non-MSI controller: %s", __func__, device_get_name(pic->pic_dev))); @@ -1380,11 +1396,12 @@ struct intr_map_data_msi *msi; int err; - pic = pic_lookup(NULL, xref); + KASSERT(xref != -1, ("%s: Invalid xref", __func__)); + pic = pic_lookup(NULL, xref, FLAG_MSI); if (pic == NULL) return (ESRCH); - KASSERT((pic->pic_flags & FLAG_MSI) != 0, + KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI, ("%s: Found a non-MSI controller: %s", __func__, device_get_name(pic->pic_dev))); @@ -1413,11 +1430,12 @@ struct intr_pic *pic; int err; - pic = pic_lookup(NULL, xref); + KASSERT(xref != -1, ("%s: Invalid xref", __func__)); + pic = pic_lookup(NULL, xref, FLAG_MSI); if (pic == NULL) return (ESRCH); - KASSERT((pic->pic_flags & FLAG_MSI) != 0, + KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI, ("%s: Found a non-MSI controller: %s", __func__, device_get_name(pic->pic_dev)));