| 1134 | } |
| 1135 | |
| 1136 | static struct its_dev * |
| 1137 | its_device_get(device_t dev, device_t child, u_int nvecs) |
| 1138 | { |
| 1139 | struct gicv3_its_softc *sc; |
| 1140 | struct its_dev *its_dev; |
| 1141 | vmem_addr_t irq_base; |
| 1142 | size_t esize; |
| 1143 | |
| 1144 | sc = device_get_softc(dev); |
| 1145 | |
| 1146 | its_dev = its_device_find(dev, child); |
| 1147 | if (its_dev != NULL) |
| 1148 | return (its_dev); |
| 1149 | |
| 1150 | its_dev = malloc(sizeof(*its_dev), M_GICV3_ITS, M_NOWAIT | M_ZERO); |
| 1151 | if (its_dev == NULL) |
| 1152 | return (NULL); |
| 1153 | |
| 1154 | its_dev->pci_dev = child; |
| 1155 | its_dev->devid = its_get_devid(child); |
| 1156 | |
| 1157 | its_dev->lpis.lpi_busy = 0; |
| 1158 | its_dev->lpis.lpi_num = nvecs; |
| 1159 | its_dev->lpis.lpi_free = nvecs; |
| 1160 | |
| 1161 | if (vmem_alloc(sc->sc_irq_alloc, nvecs, M_FIRSTFIT | M_NOWAIT, |
| 1162 | &irq_base) != 0) { |
| 1163 | free(its_dev, M_GICV3_ITS); |
| 1164 | return (NULL); |
| 1165 | } |
| 1166 | its_dev->lpis.lpi_base = irq_base; |
| 1167 | |
| 1168 | /* Get ITT entry size */ |
| 1169 | esize = GITS_TYPER_ITTES(gic_its_read_8(sc, GITS_TYPER)); |
| 1170 | |
| 1171 | /* |
| 1172 | * Allocate ITT for this device. |
| 1173 | * PA has to be 256 B aligned. At least two entries for device. |
| 1174 | */ |
| 1175 | its_dev->itt_size = roundup2(MAX(nvecs, 2) * esize, 256); |
| 1176 | its_dev->itt = (vm_offset_t)contigmalloc(its_dev->itt_size, |
| 1177 | M_GICV3_ITS, M_NOWAIT | M_ZERO, 0, LPI_INT_TRANS_TAB_MAX_ADDR, |
| 1178 | LPI_INT_TRANS_TAB_ALIGN, 0); |
| 1179 | if (its_dev->itt == 0) { |
| 1180 | vmem_free(sc->sc_irq_alloc, its_dev->lpis.lpi_base, nvecs); |
| 1181 | free(its_dev, M_GICV3_ITS); |
| 1182 | return (NULL); |
| 1183 | } |
| 1184 | |
| 1185 | mtx_lock_spin(&sc->sc_its_dev_lock); |
| 1186 | TAILQ_INSERT_TAIL(&sc->sc_its_dev_list, its_dev, entry); |
| 1187 | mtx_unlock_spin(&sc->sc_its_dev_lock); |
| 1188 | |
| 1189 | /* Map device to its ITT */ |
| 1190 | its_cmd_mapd(dev, its_dev, 1); |
| 1191 | |
| 1192 | return (its_dev); |
| 1193 | } |
no test coverage detected