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 --- |