| 1028 | } |
| 1029 | |
| 1030 | int |
| 1031 | intr_setup_irq(device_t dev, struct resource *res, driver_filter_t filt, |
| 1032 | driver_intr_t hand, void *arg, int flags, void **cookiep) |
| 1033 | { |
| 1034 | int error; |
| 1035 | struct intr_map_data *data; |
| 1036 | struct intr_irqsrc *isrc; |
| 1037 | const char *name; |
| 1038 | u_int res_id; |
| 1039 | |
| 1040 | KASSERT(rman_get_start(res) == rman_get_end(res), |
| 1041 | ("%s: more interrupts in resource", __func__)); |
| 1042 | |
| 1043 | res_id = (u_int)rman_get_start(res); |
| 1044 | isrc = intr_map_get_isrc(res_id); |
| 1045 | if (isrc == NULL) { |
| 1046 | /* XXX TODO DISCONECTED PICs */ |
| 1047 | return (EINVAL); |
| 1048 | } |
| 1049 | |
| 1050 | data = rman_get_virtual(res); |
| 1051 | name = device_get_nameunit(dev); |
| 1052 | |
| 1053 | #ifdef INTR_SOLO |
| 1054 | /* |
| 1055 | * Standard handling is done through MI interrupt framework. However, |
| 1056 | * some interrupts could request solely own special handling. This |
| 1057 | * non standard handling can be used for interrupt controllers without |
| 1058 | * handler (filter only), so in case that interrupt controllers are |
| 1059 | * chained, MI interrupt framework is called only in leaf controller. |
| 1060 | * |
| 1061 | * Note that root interrupt controller routine is served as well, |
| 1062 | * however in intr_irq_handler(), i.e. main system dispatch routine. |
| 1063 | */ |
| 1064 | if (flags & INTR_SOLO && hand != NULL) { |
| 1065 | debugf("irq %u cannot solo on %s\n", irq, name); |
| 1066 | return (EINVAL); |
| 1067 | } |
| 1068 | |
| 1069 | if (flags & INTR_SOLO) { |
| 1070 | error = iscr_setup_filter(isrc, name, (intr_irq_filter_t *)filt, |
| 1071 | arg, cookiep); |
| 1072 | debugf("irq %u setup filter error %d on %s\n", isrc->isrc_irq, error, |
| 1073 | name); |
| 1074 | } else |
| 1075 | #endif |
| 1076 | { |
| 1077 | error = isrc_add_handler(isrc, name, filt, hand, arg, flags, |
| 1078 | cookiep); |
| 1079 | debugf("irq %u add handler error %d on %s\n", isrc->isrc_irq, error, name); |
| 1080 | } |
| 1081 | if (error != 0) |
| 1082 | return (error); |
| 1083 | |
| 1084 | mtx_lock(&isrc_table_lock); |
| 1085 | error = PIC_SETUP_INTR(isrc->isrc_dev, isrc, res, data); |
| 1086 | if (error == 0) { |
| 1087 | isrc->isrc_handlers++; |
no test coverage detected