package sbus_probing::main; # $Id$ use c; use log; use common qw(:common); use modules; my %sbus_table_network = ( hme => [ "Sun Happy Meal Ethernet", "sunhme" ], le => [ "Sun Lance Ethernet", "ignore:lance" ], qe => [ "Sun Quad Ethernet", "sunqe" ], mlanai => [ "MyriCOM MyriNET Gigabit Ethernet", "myri_sbus" ], myri => [ "MyriCOM MyriNET Gigabit Ethernet", "myri_sbus" ], ); my %sbus_table_scsi = ( soc => [ "Sun SPARCStorage Array", "fc4:soc:pluto" ], socal => [ "Sun Enterprise Network Array", "fc4:socal:fcal" ], esp => [ "Sun Enhanced SCSI Processor (ESP)", "ignore:esp" ], fas => [ "Sun Swift (ESP)", "ignore:esp" ], ptisp => [ "Performance Technologies ISP", "qlogicpti" ], isp => [ "QLogic ISP", "qlogicpti" ], ); my %sbus_table_audio = ( audio => [ "AMD7930", "amd7930" ], CS4231 => [ "CS4231 APC DMA (SBUS)", "cs4231" ], CS4231_PCI => [ "CS4231 EB2 DMA (PCI)", "cs4231" ], ); my %sbus_table_video = ( bwtwo => [ "Sun|Monochrome (bwtwo)", "Server:SunMono" ], cgthree => [ "Sun|Color3 (cgthree)", "Server:Sun" ], cgeight => [ "Sun|CG8/RasterOps", "Server:Sun" ], cgtwelve => [ "Sun|GS (cgtwelve)", "Server:Sun24" ], gt => [ "Sun|Graphics Tower", "Server:Sun24" ], mgx => [ "Sun|Quantum 3D MGXplus", "Server:Sun24" ], mgx_4M => [ "Sun|Quantum 3D MGXplus with 4M VRAM", "Server:Sun24" ], cgsix => [ "Sun|Unknown GX", "Server:Sun" ], cgsix_dbl => [ "Sun|Double Width GX", "Server:Sun" ], cgsix_sgl => [ "Sun|Single Width GX", "Server:Sun" ], cgsix_t1M => [ "Sun|Turbo GX with 1M VSIMM", "Server:Sun" ], cgsix_tp => [ "Sun|Turbo GX Plus", "Server:Sun" ], cgsix_t => [ "Sun|Turbo GX", "Server:Sun" ], cgfourteen => [ "Sun|SX", "Server:Sun24" ], cgfourteen_4M => [ "Sun|SX with 4M VSIMM", "Server:Sun24" ], cgfourteen_8M => [ "Sun|SX with 8M VSIMM", "Server:Sun24" ], leo => [ "Sun|ZX or Turbo ZX", "Server:Sun24" ], leo_t => [ "Sun|Turbo ZX", "Server:Sun24" ], tcx => [ "Sun|TCX (S24)", "Server:Sun24" ], tcx_8b => [ "Sun|TCX (8bit)", "Server:Sun" ], afb => [ "Sun|Elite3D", "Server:Sun24" ], afb_btx03 => [ "Sun|Elite3D-M6 Horizontal", "Server:Sun24" ], ffb => [ "Sun|FFB", "Server:Sun24" ], ffb_btx08 => [ "Sun|FFB 67Mhz Creator", "Server:Sun24" ], ffb_btx0b => [ "Sun|FFB 67Mhz Creator 3D", "Server:Sun24" ], ffb_btx1b => [ "Sun|FFB 75Mhz Creator 3D", "Server:Sun24" ], ffb_btx20 => [ "Sun|FFB2 Vertical Creator", "Server:Sun24" ], ffb_btx28 => [ "Sun|FFB2 Vertical Creator", "Server:Sun24" ], ffb_btx23 => [ "Sun|FFB2 Vertical Creator 3D", "Server:Sun24" ], ffb_btx2b => [ "Sun|FFB2 Vertical Creator 3D", "Server:Sun24" ], ffb_btx30 => [ "Sun|FFB2+ Vertical Creator", "Server:Sun24" ], ffb_btx33 => [ "Sun|FFB2+ Vertical Creator 3D", "Server:Sun24" ], ffb_btx40 => [ "Sun|FFB2 Horizontal Creator", "Server:Sun24" ], ffb_btx48 => [ "Sun|FFB2 Horizontal Creator", "Server:Sun24" ], ffb_btx43 => [ "Sun|FFB2 Horizontal Creator 3D", "Server:Sun24" ], ffb_btx4b => [ "Sun|FFB2 Horizontal Creator 3D", "Server:Sun24" ], ); 1; sub prom_getint($) { unpack "I", c::prom_getproperty($_[0]) } #- update $@sbus_probed according to SBUS detection. sub prom_walk($$$$) { my ($sbus_probed, $node, $sbus, $ebus) = @_; my ($prob_name, $prob_type) = (c::prom_getstring("name"), c::prom_getstring("device_type")); my ($nextnode, $nsbus, $nebus) = (undef, $sbus, $ebus); #- probe for network devices. if ($sbus && $prob_type eq 'network') { $prob_name =~ s/[A-Z,]*(.*)/$1/; $sbus_table_network{$prob_name} and push @$sbus_probed, [ "NETWORK", @{$sbus_table_network{$prob_name}} ]; #- TODO for Sun Quad Ethernet (qe) } #- probe for scsi devices. if ($sbus && ($prob_type eq 'scsi' || $prob_name =~ /^(soc|socal)$/)) { $prob_name =~ s/[A-Z,]*(.*)/$1/; $sbus_table_scsi{$prob_name} and push @$sbus_probed, [ "SCSI", @{$sbus_table_scsi{$prob_name}} ]; } #- probe for audio devices, there are no type to check here. if ($sbus_table_audio{$prob_name}) { $prob_name =~ /,/ and $prob_name =~ s/[A-Z,]*(.*)/$1/; my $ext = $prob_name eq 'CS4231' && $ebus && "_PCI"; $sbus_table_audio{$prob_name . $ext} ? push @$sbus_probed, [ "AUDIO", @{$sbus_table_audio{$prob_name . $ext}} ] : push @$sbus_probed, [ "AUDIO", @{$sbus_table_audio{$prob_name}} ]; } #- probe for video devices. if ($prob_type eq 'display' && ($sbus || $prob_name =~ /^(ffb|afb|cgfourteen)$/)) { $prob_name =~ s/[A-Z,]*(.*)/$1/; my $ext = ($prob_name eq 'mgx' && prom_getint('fb_size') == 0x400000 && '_4M' || $prob_name eq 'cgsix' && do { my ($chiprev, $vmsize) = (prom_getint('chiprev'), prom_getint('vmsize')); my $result = ''; $chiprev >= 1 && $chiprev <= 4 and $result = '_dbl'; $chiprev >= 5 && $chiprev <= 9 and $result = '_sgl'; $chiprev == 11 && $vmsize == 2 and $result = '_t1M'; $chiprev == 11 && $vmsize == 4 and $result = '_tp'; $chiprev == 11 && !$result and $result = '_t'; $result; } || $prob_name eq 'leo' && c::prom_getstring('model') =~ /501-2503/ && '_t' || $prob_name eq 'tcx' && c::prom_getbool('tcx-8-bit') && '_8b' || $prob_name eq 'afb' && sprintf "_btx%x", prom_getint('board_type') || $prob_name eq 'ffb' && sprintf "_btx%x", prom_getint('board_type')); $sbus_table_video{$prob_name . $ext} ? push @$sbus_probed, [ "VIDEO", @{$sbus_table_video{$prob_name . $ext}} ] : push @$sbus_probed, [ "VIDEO", @{$sbus_table_video{$prob_name}} ]; } #- parse prom tree. $prob_name eq 'sbus' || $prob_name eq 'sbi' and $nsbus = 1; $prob_name eq 'ebus' and $nebus = 1; $nextnode = c::prom_getchild($node) and prom_walk($sbus_probed, $nextnode, $nsbus, $nebus); $nextnode = c::prom_getsibling($node) and prom_walk($sbus_probed, $nextnode, $sbus, $ebus); } sub probe { eval { modules::load("openprom") } if arch() =~ /sparc/; my $root_node = c::prom_open(); my @l; prom_walk(\@l, $root_node, 0, 0); c::prom_close(); map { my %l; @l{qw(type description drivers)} = @$_ } @l; }