#!/usr/bin/perl -w

# This script will add the PCIDevice IDs of ASA72xx family
# of iSCSI Initiator HBAs into pci.ids file. This will let
# the Initiator HBAs be reported with proper strings upon
# running the lspci command.

my $companyname = "Adaptec";
my $devicename = "ASA-7211";
my $friendlyname1 = "ASA-7210/7211 iSCSI Initiator";
my $friendlyname2 = "ASA-7210/7211 PCI Bridge";
my $friendlyname3 = "ASA-7210 iSCSI Initiator 1Gb Optical";
my $friendlyname4 = "ASA-7211 iSCSI Initiator 1Gb Copper";

my $pcifile1 = "/usr/share/pci.ids";
my $pcifile2 = "/usr/share/hwdata/pci.ids";
my $pcifile = "";

my $pcivendor = "9005";				
my $pcidevice1 = "564a";					
my $pcidevice2 = "ba01";					
my $subsystem1 = "7210";					
my $subsystem2 = "7211";					

my @deviceids=("564a","ba01");
my @linestoinsert=(0,0);

# probe for PCI file location 
if (-f $pcifile1)
{
	$pcifile = $pcifile1;
}
else
{
	if (-f $pcifile2)
	{
		$pcifile = $pcifile2;
	}
	else
	{
		print "Warning:\n";
		print "The $pcifile1 or $pcifile2 files were not found.\n";
		print "lspci will report Unknown Device.\n";
		exit;
	}
}

# slurp the PCI file
my @pcilines;
my $pcilinecount = 0;
if (open PCIFILE, "< $pcifile")
{
	while(<PCIFILE>)
	{
		$pcilines[$pcilinecount] = $_;
		$pcilinecount ++;
	}
	close PCIFILE;
}
else
{
	print "Warning:\n";
	print "The $pcifile file could not be read.\n";
	print "lspci will report Unknown Device.\n";
	exit;
}

# analyze the PCI file, and find where to insert our line
# (note that the PCI file must be kept sorted!)

my $index = 0;
my $pciinsertline = -1;		# marker for not found

for($i=0; $i<2; $i++) {
	my $line = "";
	my $tab1 = "";
	my $tab2 = "";
	my $sub = "";
	my $field1 = "";
	my $field2 = "";
	my $leftover = "";
	my $inourvendor = 0;

	$index = 0;

	while ($index < $pcilinecount)
	{
		# parse vendor ID
		$line = $pcilines[$index];
		($tab1, $tab2, $leftover) = split /\t/, $line;
		if (defined($tab1))
		{
			($field1, $leftover) = split / /, $tab1;
		}

		if ($inourvendor == 1)
		{
			if (defined($tab1))
			{
				# vendor's area will always start with a tab so empty here
				if ($tab1 eq "")
				{
					if (defined($tab2))
					{
						# parse device ID
						($field2, $leftover) = split / /, $tab2;
						if (defined($field2))
						{
							if ($field2 eq $deviceids[$i])
							{
								# already added to this file!
								$pciinsertline = -2;		# marker for already in
								goto done;
							}
							else
							{
								if ($field2 gt $deviceids[$i])
								{
									# got it!
									# this is the proper place to insert at
							
									$pciinsertline = $index;
									$linestoinsert[$i] = $index;
								}
							}
						}
					}
				}
				else
				{
					$sub = substr($tab1, 0, 1);
					if ($sub ne "#")
					{
						# found start of another vendor
						last;
					}
				}
			}
		}
		else
		{
			if (defined($field1))
			{
				if ($field1 eq $pcivendor)
				{
					# found our vendor
					$inourvendor = 1;
				}
			}
		}
	
		$index ++;
	}
	if($linestoinsert[$i] == 0) {
		$linestoinsert[$i]=$index;
	}
}

if ($pciinsertline == -2)
{
	# Nothing to be done.
	goto done;
}

if ($pciinsertline == -1)
{
	# got it!
	# this is the proper place to insert at
	# when our DeviceId is last in the list
							
	$pciinsertline = $index;
}

# write out the PCI file if necessary
my $count = 0;
if ($pciinsertline >= 0)
{
	if (open PCIFILE, "> $pcifile")
	{
		while($count < $pcilinecount)
		{
			if ($count == $linestoinsert[0])
			{
				# insert first device line
				print PCIFILE "\t";
				print PCIFILE $pcidevice1;
				print PCIFILE "  ";
				print PCIFILE $friendlyname1;
				print PCIFILE "\n";
				print PCIFILE "\t";
				print PCIFILE "\t";
				print PCIFILE $pcivendor;
				print PCIFILE " ";
				print PCIFILE $subsystem1;
				print PCIFILE " ";
				print PCIFILE $friendlyname3;
				print PCIFILE "\n";
				print PCIFILE "\t";
				print PCIFILE "\t";
				print PCIFILE $pcivendor;
				print PCIFILE " ";
				print PCIFILE $subsystem2;
				print PCIFILE " ";
				print PCIFILE $friendlyname4;
				print PCIFILE "\n";
			}
			if ($count == $linestoinsert[1])
			{
				
				# insert second device line
				print PCIFILE "\t";
				print PCIFILE $pcidevice2;
				print PCIFILE "  ";
				print PCIFILE $friendlyname2;
				print PCIFILE "\n";
			}
			print PCIFILE $pcilines[$count];
			$count ++;
		}
		close PCIFILE;
	}
	else
	{
		print "Warning:\n";
		print "The $pcifile file could not be opened for writing.\n";
		print "Check for root permissions.\n";
		exit;
	}
}

# done
done:
exit;
