subr_intr.c (e707c8be4e8d5f4d542a1344dc6d96bcc08d0b4f) subr_intr.c (f32f0095e9da8188a3865aaa310f547ee9e0c20b)
1/*-
2 * Copyright (c) 2015-2016 Svatopluk Kraus
3 * Copyright (c) 2015-2016 Michal Meloun
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 1283 unchanged lines hidden (view full) ---

1292 device_get_nameunit(dev), dev, (uintmax_t)xref);
1293 return (0);
1294}
1295
1296int
1297intr_alloc_msi(device_t pci, device_t child, intptr_t xref, int count,
1298 int maxcount, int *irqs)
1299{
1/*-
2 * Copyright (c) 2015-2016 Svatopluk Kraus
3 * Copyright (c) 2015-2016 Michal Meloun
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 1283 unchanged lines hidden (view full) ---

1292 device_get_nameunit(dev), dev, (uintmax_t)xref);
1293 return (0);
1294}
1295
1296int
1297intr_alloc_msi(device_t pci, device_t child, intptr_t xref, int count,
1298 int maxcount, int *irqs)
1299{
1300#ifdef IOMMU
1301 struct iommu_domain *domain;
1300 struct iommu_domain *domain;
1302#endif
1303 struct intr_irqsrc **isrc;
1304 struct intr_pic *pic;
1305 device_t pdev;
1306 struct intr_map_data_msi *msi;
1307 int err, i;
1308
1309 pic = pic_lookup(NULL, xref, FLAG_MSI);
1310 if (pic == NULL)
1311 return (ESRCH);
1312
1313 KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI,
1314 ("%s: Found a non-MSI controller: %s", __func__,
1315 device_get_name(pic->pic_dev)));
1316
1301 struct intr_irqsrc **isrc;
1302 struct intr_pic *pic;
1303 device_t pdev;
1304 struct intr_map_data_msi *msi;
1305 int err, i;
1306
1307 pic = pic_lookup(NULL, xref, FLAG_MSI);
1308 if (pic == NULL)
1309 return (ESRCH);
1310
1311 KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI,
1312 ("%s: Found a non-MSI controller: %s", __func__,
1313 device_get_name(pic->pic_dev)));
1314
1317#ifdef IOMMU
1318 /*
1319 * If this is the first time we have used this context ask the
1320 * interrupt controller to map memory the msi source will need.
1321 */
1322 err = MSI_IOMMU_INIT(pic->pic_dev, child, &domain);
1323 if (err != 0)
1324 return (err);
1315 /*
1316 * If this is the first time we have used this context ask the
1317 * interrupt controller to map memory the msi source will need.
1318 */
1319 err = MSI_IOMMU_INIT(pic->pic_dev, child, &domain);
1320 if (err != 0)
1321 return (err);
1325#endif
1326
1327 isrc = malloc(sizeof(*isrc) * count, M_INTRNG, M_WAITOK);
1328 err = MSI_ALLOC_MSI(pic->pic_dev, child, count, maxcount, &pdev, isrc);
1329 if (err != 0) {
1330 free(isrc, M_INTRNG);
1331 return (err);
1332 }
1333
1334 for (i = 0; i < count; i++) {
1322
1323 isrc = malloc(sizeof(*isrc) * count, M_INTRNG, M_WAITOK);
1324 err = MSI_ALLOC_MSI(pic->pic_dev, child, count, maxcount, &pdev, isrc);
1325 if (err != 0) {
1326 free(isrc, M_INTRNG);
1327 return (err);
1328 }
1329
1330 for (i = 0; i < count; i++) {
1335#ifdef IOMMU
1336 isrc[i]->isrc_iommu = domain;
1331 isrc[i]->isrc_iommu = domain;
1337#endif
1338 msi = (struct intr_map_data_msi *)intr_alloc_map_data(
1339 INTR_MAP_DATA_MSI, sizeof(*msi), M_WAITOK | M_ZERO);
1340 msi-> isrc = isrc[i];
1341
1342 irqs[i] = intr_map_irq(pic->pic_dev, xref,
1343 (struct intr_map_data *)msi);
1344 }
1345 free(isrc, M_INTRNG);

--- 24 unchanged lines hidden (view full) ---

1370 msi = (struct intr_map_data_msi *)
1371 intr_map_get_map_data(irqs[i]);
1372 KASSERT(msi->hdr.type == INTR_MAP_DATA_MSI,
1373 ("%s: irq %d map data is not MSI", __func__,
1374 irqs[i]));
1375 isrc[i] = msi->isrc;
1376 }
1377
1332 msi = (struct intr_map_data_msi *)intr_alloc_map_data(
1333 INTR_MAP_DATA_MSI, sizeof(*msi), M_WAITOK | M_ZERO);
1334 msi-> isrc = isrc[i];
1335
1336 irqs[i] = intr_map_irq(pic->pic_dev, xref,
1337 (struct intr_map_data *)msi);
1338 }
1339 free(isrc, M_INTRNG);

--- 24 unchanged lines hidden (view full) ---

1364 msi = (struct intr_map_data_msi *)
1365 intr_map_get_map_data(irqs[i]);
1366 KASSERT(msi->hdr.type == INTR_MAP_DATA_MSI,
1367 ("%s: irq %d map data is not MSI", __func__,
1368 irqs[i]));
1369 isrc[i] = msi->isrc;
1370 }
1371
1372 MSI_IOMMU_DEINIT(pic->pic_dev, child);
1373
1378 err = MSI_RELEASE_MSI(pic->pic_dev, child, count, isrc);
1379
1380 for (i = 0; i < count; i++) {
1381 if (isrc[i] != NULL)
1382 intr_unmap_irq(irqs[i]);
1383 }
1384
1385 free(isrc, M_INTRNG);
1386 return (err);
1387}
1388
1389int
1390intr_alloc_msix(device_t pci, device_t child, intptr_t xref, int *irq)
1391{
1374 err = MSI_RELEASE_MSI(pic->pic_dev, child, count, isrc);
1375
1376 for (i = 0; i < count; i++) {
1377 if (isrc[i] != NULL)
1378 intr_unmap_irq(irqs[i]);
1379 }
1380
1381 free(isrc, M_INTRNG);
1382 return (err);
1383}
1384
1385int
1386intr_alloc_msix(device_t pci, device_t child, intptr_t xref, int *irq)
1387{
1392#ifdef IOMMU
1393 struct iommu_domain *domain;
1388 struct iommu_domain *domain;
1394#endif
1395 struct intr_irqsrc *isrc;
1396 struct intr_pic *pic;
1397 device_t pdev;
1398 struct intr_map_data_msi *msi;
1399 int err;
1400
1401 pic = pic_lookup(NULL, xref, FLAG_MSI);
1402 if (pic == NULL)
1403 return (ESRCH);
1404
1405 KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI,
1406 ("%s: Found a non-MSI controller: %s", __func__,
1407 device_get_name(pic->pic_dev)));
1408
1389 struct intr_irqsrc *isrc;
1390 struct intr_pic *pic;
1391 device_t pdev;
1392 struct intr_map_data_msi *msi;
1393 int err;
1394
1395 pic = pic_lookup(NULL, xref, FLAG_MSI);
1396 if (pic == NULL)
1397 return (ESRCH);
1398
1399 KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI,
1400 ("%s: Found a non-MSI controller: %s", __func__,
1401 device_get_name(pic->pic_dev)));
1402
1409#ifdef IOMMU
1410 /*
1411 * If this is the first time we have used this context ask the
1412 * interrupt controller to map memory the msi source will need.
1413 */
1414 err = MSI_IOMMU_INIT(pic->pic_dev, child, &domain);
1415 if (err != 0)
1416 return (err);
1403 /*
1404 * If this is the first time we have used this context ask the
1405 * interrupt controller to map memory the msi source will need.
1406 */
1407 err = MSI_IOMMU_INIT(pic->pic_dev, child, &domain);
1408 if (err != 0)
1409 return (err);
1417#endif
1418
1419 err = MSI_ALLOC_MSIX(pic->pic_dev, child, &pdev, &isrc);
1420 if (err != 0)
1421 return (err);
1422
1410
1411 err = MSI_ALLOC_MSIX(pic->pic_dev, child, &pdev, &isrc);
1412 if (err != 0)
1413 return (err);
1414
1423#ifdef IOMMU
1424 isrc->isrc_iommu = domain;
1415 isrc->isrc_iommu = domain;
1425#endif
1426 msi = (struct intr_map_data_msi *)intr_alloc_map_data(
1427 INTR_MAP_DATA_MSI, sizeof(*msi), M_WAITOK | M_ZERO);
1428 msi->isrc = isrc;
1429 *irq = intr_map_irq(pic->pic_dev, xref, (struct intr_map_data *)msi);
1430 return (0);
1431}
1432
1433int

--- 18 unchanged lines hidden (view full) ---

1452 ("%s: irq %d map data is not MSI", __func__,
1453 irq));
1454 isrc = msi->isrc;
1455 if (isrc == NULL) {
1456 intr_unmap_irq(irq);
1457 return (EINVAL);
1458 }
1459
1416 msi = (struct intr_map_data_msi *)intr_alloc_map_data(
1417 INTR_MAP_DATA_MSI, sizeof(*msi), M_WAITOK | M_ZERO);
1418 msi->isrc = isrc;
1419 *irq = intr_map_irq(pic->pic_dev, xref, (struct intr_map_data *)msi);
1420 return (0);
1421}
1422
1423int

--- 18 unchanged lines hidden (view full) ---

1442 ("%s: irq %d map data is not MSI", __func__,
1443 irq));
1444 isrc = msi->isrc;
1445 if (isrc == NULL) {
1446 intr_unmap_irq(irq);
1447 return (EINVAL);
1448 }
1449
1450 MSI_IOMMU_DEINIT(pic->pic_dev, child);
1451
1460 err = MSI_RELEASE_MSIX(pic->pic_dev, child, isrc);
1461 intr_unmap_irq(irq);
1462
1463 return (err);
1464}
1465
1466int
1467intr_map_msi(device_t pci, device_t child, intptr_t xref, int irq,

--- 245 unchanged lines hidden ---
1452 err = MSI_RELEASE_MSIX(pic->pic_dev, child, isrc);
1453 intr_unmap_irq(irq);
1454
1455 return (err);
1456}
1457
1458int
1459intr_map_msi(device_t pci, device_t child, intptr_t xref, int irq,

--- 245 unchanged lines hidden ---