summaryrefslogblamecommitdiffstats
path: root/modules-available/passthrough/page.inc.php
blob: 89ee7719cbfd8782636e07a296b1426db9bf1edf (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12











                                                  

                                                        







                                                          
                                                     






























                                                                                                                                             























                                                                                                                                            








                                                  

                                                       




                                                                      

                                                                          
                       
           




                                                                              
                                           


                                                    
                                                             





















                                                                                                                           

                                                                               

                                                                                                                           
                                                        



                                                                                                                    
                                                                   







                                                                                       
                                                                                                



                                                                                                    

         






                                                                                   















                                                                                                                                     


                                                        
                                                                         


                   









                                   
<?php

class Page_Passthrough extends Page
{

	protected function doPreprocess()
	{
		User::load();
		User::assertPermission('view');
		$action = Request::post('action');
		if ($action === 'save-hwlist') {
			$this->saveHwList();
		} elseif ($action === 'save-location') {
			$this->saveLocation();
		}
		if (Request::isPost()) {
			Util::redirect('?do=passthrough');
		}
	}

	private function saveHwList()
	{
		User::assertPermission('edit.group');
		$newgroups = Request::post('newgroup', [], 'array');
		foreach ($newgroups as $id => $title) {
			$id = strtoupper(preg_replace('/[^a-z0-9_\-]/i', '', $id));
			if (empty($id))
				continue;
			Database::exec("INSERT IGNORE INTO passthrough_group (groupid, title)
				VALUES (:group, :title)",
				['group' => $id, 'title' => $title]);
		}
		$groups = Request::post('ptgroup', Request::REQUIRED, 'array');
		$insert = [];
		$delete = [];
		foreach ($groups as $hwid => $group) {
			if (empty($group)) {
				$delete[] = $hwid;
			} else {
				$insert[] = [$hwid, '@PASSTHROUGH', $group];
			}
		}
		if (!empty($insert)) {
			Database::exec("INSERT INTO statistic_hw_prop (hwid, prop, `value`) VALUES :list
				ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)",
				['list' => $insert]);
		}
		if (!empty($delete)) {
			Database::exec("DELETE FROM statistic_hw_prop WHERE hwid IN (:list) AND prop = '@PASSTHROUGH'", ['list' => $delete]);
		}
		Message::addSuccess('list-updated');
		Util::redirect('?do=passthrough&show=hwlist');
	}

	private function saveLocation()
	{
		$locationId = Request::post('locationid', Request::REQUIRED, 'int');
		User::assertPermission('edit.location', $locationId);
		$list = [];
		$groups = [];
		foreach (Request::post('enabled', [], 'array') as $groupId) {
			$groupId = (string)$groupId;
			$list[] = [$groupId, $locationId];
			$groups[] = $groupId;
		}
		if (!empty($list)) {
			Database::exec("INSERT IGNORE INTO passthrough_group_x_location (groupid, locationid)
					VALUES :list", ['list' => $list]);
			Database::exec("DELETE FROM passthrough_group_x_location
					WHERE locationid = :lid AND groupid NOT IN (:groups)", ['lid' => $locationId, 'groups' => $groups]);
		} else {
			Database::exec("DELETE FROM passthrough_group_x_location
					WHERE locationid = :lid", ['lid' => $locationId]);
		}
		Message::addSuccess('location-updated', Location::getName($locationId));
		Util::redirect('?do=passthrough&show=assignlocation&locationid=' . $locationId);
	}

	/*
	 *
	 */

	protected function doRender()
	{
		$show = Request::get('show');
		if ($show === 'hwlist') {
			$this->showHardwareList();
		} elseif ($show === 'assignlocation') {
			$this->showLocationMapping();
		} else {
			Util::redirect('?do=passthrough&show=hwlist');
		}
	}

	/**
	 * Show all the hardware that is known. Start with video adapters.
	 * @return void
	 */
	private function showHardwareList()
	{
		$q = new HardwareQuery(HardwareInfo::PCI_DEVICE, null, false);
		$q->addGlobalColumn('vendor');
		$q->addGlobalColumn('device');
		$q->addGlobalColumn('rev');
		$q->addGlobalColumn('class');
		$q->addGlobalColumn('@PASSTHROUGH');
		$rows = [];
		foreach ($q->query('`shw`.`hwid`') as $row) {
			$row['ptlist'] = Passthrough::getGroupDropdown($row);
			$rows[] = $row;
		}
		// Sort Graphics Cards first, rest by class, vendor, device
		usort($rows, function ($row1, $row2) {
			$a = $row1['class'];
			$b = $row2['class'];
			if ($a === $b)
				return hexdec($row1['vendor'].$row1['device']) - hexdec($row2['vendor'] . $row2['device']);
			if ($a === '0300')
				return -1;
			if ($b === '0300')
				return 1;
			return hexdec($a) - hexdec($b);
		});
		$finalRows = [];
		$missing = [];
		$lastClass = '';
		foreach ($rows as $row) {
			if ($row['class'] !== $lastClass) {
				// Add class row header
				$lastClass = $row['class'];
				$finalRows[$lastClass] = [
					'collapse' => $row['class'] !== '0300',
					'class' => $row['class'],
					'class_name' => PciId::getPciId(PciId::DEVCLASS, $row['class'], true) ?: 'Unknown',
					'devlist' => [],
				];
			}
			$row['vendor_name'] = PciId::getPciId(PciId::VENDOR, $row['vendor'] ?? '');
			$row['device_name'] = PciId::getPciId(PciId::DEVICE, $row['vendor'] . ':' . $row['device']);
			$finalRows[$lastClass]['devlist'][] = $row;
			// Build up query
			if ($row['vendor_name'] === false) {
				$missing[$row['vendor']] = true;
			}
			if ($row['device_name'] === false) {
				$missing[$row['vendor'] . ':' . $row['device']] = true;
			}
		}
		Render::addTemplate('hardware-list', ['classlist' => array_values($finalRows)]);
		if (!empty($missing)) {
			Render::addTemplate('js-pciquery',
				['missing_ids' => json_encode(array_keys($missing))], 'statistics');
		}
	}

	/**
	 * Show mapping between specific location and passthrough groups.
	 * @return void
	 */
	private function showLocationMapping()
	{
		$locationId = Request::get('locationid', Request::REQUIRED, 'int');
		$locationIds = Location::getLocationRootChain($locationId);
		$res = Database::queryAll("SELECT g.groupid, g.title, GROUP_CONCAT(gxl.locationid) AS lids FROM passthrough_group g
				LEFT JOIN passthrough_group_x_location gxl ON (g.groupid = gxl.groupid AND gxl.locationid IN (:lids))
				GROUP BY groupid, title 
				ORDER BY lids ASC",
			['lids' => $locationIds]);
		foreach ($res as &$item) {
			if ($item['lids'] === null)
				continue;
			$item['checked'] = 'checked';
			$list = explode(',', $item['lids']);
			if (!in_array($locationId, $list)) {
				$item['disabled'] = true;
				$item['parent_location'] = Location::getName($list[0]);
			}
		}
		Render::addTemplate('location-assign', [
			'list' => array_reverse($res),
			'locationid' => $locationId,
			'locationname' => Location::getName($locationId),
		]);
	}

	/*
	 *
	 */

	protected function doAjax()
	{
		//
	}

}
linux.git/blame/MAINTAINERS?id=1bb67c2582f4271488721001a707124fd0af347e'>^
8b58be884a9f ^
8b59a454c421 ^
5ca92bd96a4d ^
8b59a454c421 ^
679655daffdd ^
1da177e4c3f4
8b59a454c421 ^
8b58be884a9f ^
8b59a454c421 ^
5ca92bd96a4d ^
8b59a454c421 ^
679655daffdd ^
998be20fdff1 ^
359acec8cd78 ^
8b58be884a9f ^
8b59a454c421 ^
5ca92bd96a4d ^
8b59a454c421 ^
679655daffdd ^
998be20fdff1 ^
bff431e49ff5 ^
d094485323a1 ^
5b9272594b51 ^
679655daffdd ^
bff431e49ff5 ^
2f39d51981e2 ^
8b58be884a9f ^
795fb7e74dff ^


679655daffdd ^
2f39d51981e2 ^
527a1a83cc1b ^

a3f531ac556d ^
a4edbc101151 ^
527a1a83cc1b ^




a3f531ac556d ^
a4edbc101151 ^
527a1a83cc1b ^




a3f531ac556d ^
a4edbc101151 ^
527a1a83cc1b ^




a3f531ac556d ^
a4edbc101151 ^
527a1a83cc1b ^




a3f531ac556d ^
a4edbc101151 ^
527a1a83cc1b ^


1330b0dcf876 ^



1da177e4c3f4
7c81c60f3789 ^
cc0b07ed479f ^
1da177e4c3f4
679655daffdd ^

1da177e4c3f4
cae2caae7825 ^
8b58be884a9f ^
cae2caae7825 ^

679655daffdd ^
cae2caae7825 ^
cc0b88cf5ecf ^
cc0b88cf5ecf ^
491b26b40222 ^
e71bcbd0a149 ^
679655daffdd ^
cc0b88cf5ecf ^
e8e31622a17e ^






527a1a83cc1b ^

a3f531ac556d ^
a4edbc101151 ^
527a1a83cc1b ^


45b4e0d54bdb ^
77278d50e04b ^
527a1a83cc1b ^



a3f531ac556d ^
a4edbc101151 ^
527a1a83cc1b ^

77278d50e04b ^
527a1a83cc1b ^


a3f531ac556d ^
a4edbc101151 ^
527a1a83cc1b ^


8c22a8f57516 ^







1da177e4c3f4
8b58be884a9f ^
1da177e4c3f4
679655daffdd ^
1da177e4c3f4
b058b8596136 ^
7c81c60f3789 ^
b058b8596136 ^




527a1a83cc1b ^

a3f531ac556d ^
a4edbc101151 ^
527a1a83cc1b ^


8c6af9e174ab ^
8b58be884a9f ^
8c6af9e174ab ^

679655daffdd ^

8c6af9e174ab ^
1da177e4c3f4
8b58be884a9f ^
1da177e4c3f4
679655daffdd ^
1da177e4c3f4
91952bc0b48a ^



















1da177e4c3f4
6cf515e113fc ^

679655daffdd ^

1da177e4c3f4
e2d1d6c0a5d3 ^
8b58be884a9f ^
e2d1d6c0a5d3 ^

679655daffdd ^


e2d1d6c0a5d3 ^
1da177e4c3f4
8b58be884a9f ^
54e5881d0cd7 ^
1da177e4c3f4
679655daffdd ^

c117ab842001 ^
1da177e4c3f4

8b58be884a9f ^
1da177e4c3f4

679655daffdd ^

1da177e4c3f4
64624d4f46d5 ^
8b58be884a9f ^
64624d4f46d5 ^
1da177e4c3f4
679655daffdd ^
1da177e4c3f4
450500ad1d58 ^







e2d1d6c0a5d3 ^
8b58be884a9f ^
e2d1d6c0a5d3 ^

679655daffdd ^

e2d1d6c0a5d3 ^
1da177e4c3f4
8b58be884a9f ^
6372594ac177 ^
1da177e4c3f4

679655daffdd ^

1da177e4c3f4
272f133afb20 ^
8b58be884a9f ^
08fcb7208c4a ^
679655daffdd ^
272f133afb20 ^
4a4e5787e0b7 ^
8b58be884a9f ^
846557d3ceb6 ^
4a4e5787e0b7 ^
679655daffdd ^

4a4e5787e0b7 ^
1da177e4c3f4
8b58be884a9f ^
8b58be884a9f ^
abd4d609057d ^
c89f4f9a611a ^
a94066992b30 ^
679655daffdd ^
1da177e4c3f4
adf9251fe9b8 ^









f4875e12f3dd ^






512d1027a6c5 ^
d034fbf08b6f ^
512d1027a6c5 ^




167a675a8caa ^
8b58be884a9f ^
67d7671036e6 ^
167a675a8caa ^
679655daffdd ^
167a675a8caa ^
f90b8116032f ^
6900609612d2 ^
67d7671036e6 ^
f90b8116032f ^

679655daffdd ^



f90b8116032f ^
919ee7dd9a66 ^
e41105687b90 ^
919ee7dd9a66 ^
525b233c7188 ^
e41105687b90 ^
b2c1639135c0 ^

919ee7dd9a66 ^
e7f5b309c9bd ^
943482d07e92 ^
7d2c86b5a048 ^
943482d07e92 ^
679655daffdd ^
e7f5b309c9bd ^
284f42b627c0 ^
8b58be884a9f ^
284f42b627c0 ^
bd5f47ec9615 ^
284f42b627c0 ^
f94b533d091a ^
8b58be884a9f ^

e6cc0fd1e31c ^
f94b533d091a ^
679655daffdd ^
f94b533d091a ^
531fca1649da ^





c40ddfa34add ^





531fca1649da ^





c40ddfa34add ^





527a1a83cc1b ^
535bd16f4190 ^
4bdef3bd7e59 ^
a3f531ac556d ^
a4edbc101151 ^
4bdef3bd7e59 ^
39c9d199ce67 ^
cc52688a0888 ^
4bdef3bd7e59 ^
ae48f5efb8b3 ^
4bdef3bd7e59 ^
40216ce7aa88 ^
4bdef3bd7e59 ^
527a1a83cc1b ^
a4edbc101151 ^
527a1a83cc1b ^




422690636117 ^
8b58be884a9f ^
a4724ed6f084 ^
93711660086d ^
422690636117 ^
679655daffdd ^
422690636117 ^
1da177e4c3f4
81024fc41a93 ^

679655daffdd ^

c117ab842001 ^
81024fc41a93 ^
1da177e4c3f4
bd7aa4b2dafd ^
8b58be884a9f ^
bd7aa4b2dafd ^

679655daffdd ^
bd7aa4b2dafd ^
6f2fad748ccc ^
d618540fb3e5 ^

6f2fad748ccc ^
679655daffdd ^
6f2fad748ccc ^
1da177e4c3f4
8b58be884a9f ^
1da177e4c3f4
679655daffdd ^

1da177e4c3f4
62a37dc7a273 ^





a480167b23ef ^
2d8a3b3d926e ^
a480167b23ef ^




1154ea7dcd8e ^
8b58be884a9f ^
1154ea7dcd8e ^
679655daffdd ^

1154ea7dcd8e ^
1da177e4c3f4
8b58be884a9f ^
1da177e4c3f4
679655daffdd ^

1da177e4c3f4
6f96521fab97 ^




6f96521fab97 ^



d4275354993e ^
8b58be884a9f ^
efc03ecb9d67 ^
d4275354993e ^



d323c243d9e6 ^

56ca9d98772c ^
d323c243d9e6 ^



cefbf4ea6294 ^















2761f5c2ea80 ^
08a5c9a2bb5d ^

679655daffdd ^
2f748aaad7f4 ^
2761f5c2ea80 ^
1b4304e5ca4e ^




2761f5c2ea80 ^
cefbf4ea6294 ^





2b7a52a459cb ^
8b58be884a9f ^
efc03ecb9d67 ^
2b7a52a459cb ^

9c784f958d01 ^
8b58be884a9f ^
efc03ecb9d67 ^
9c784f958d01 ^

2b7a52a459cb ^
8b58be884a9f ^
efc03ecb9d67 ^
2b7a52a459cb ^

1b106699647b ^



60b0f380beed ^





1b106699647b ^
c1fc8675c9e3 ^
8b58be884a9f ^
c1fc8675c9e3 ^

efc03ecb9d67 ^
795fb7e74dff ^
c1fc8675c9e3 ^


70e389cc7fed ^



d4a89c7d2788 ^
986cf2e91968 ^
5d3ad8a63844 ^
986cf2e91968 ^



d94f944e108d ^
9d5e2a023eee ^
d94f944e108d ^



386ab5168bbf ^





2b7a52a459cb ^
ddd559b13f6d ^
1c5454eed85a ^
efc03ecb9d67 ^
2b7a52a459cb ^
d19d36672ee3 ^

2b7a52a459cb ^

8b58be884a9f ^
efc03ecb9d67 ^
2b7a52a459cb ^

d4275354993e ^
8b58be884a9f ^
efc03ecb9d67 ^
37417046b903 ^
d4275354993e ^
4fa2651db463 ^
d4275354993e ^
d48134e709d5 ^
8b58be884a9f ^
efc03ecb9d67 ^
a9da4f7ed6a7 ^

941500954470 ^




1da177e4c3f4
8b58be884a9f ^
1da177e4c3f4

881a95f976e6 ^
162500b3a3ff ^
efc03ecb9d67 ^
162500b3a3ff ^

f49afbb572d5 ^
881a95f976e6 ^
a990cbd88758 ^
5abf58bf4cd0 ^
a990cbd88758 ^
85529d14d58a ^
a990cbd88758 ^

05f30e8dfa70 ^


47ac3e44cfd2 ^

05f30e8dfa70 ^

b3b665b0a9d1 ^
6f73349d7960 ^