|
|
#!/bin/gawk -f # # Usually I'd write this in perl. But this should also work on a system # with no perl installed, so it's in awk ...
function debug(text) { if ( print_debug ) print text > "/dev/stderr"; }
function autocomplete(mod, id) { driver_initrd[id] = 1;
if ( mod ~ /^snd-/ ) { driver_mod[id] = driver_mod[id] \ " snd-pcm-oss snd-seq-oss snd-mixer-oss"; driver_initrd[id] = 0; }
if ( modidx[mod] ~ "/video/" ) { driver_cmd[id] = driver_cmd[id] \ "\n:touch /dev/vc/{1,2,3,4,5,6}" \ "\n:fbset -a 800x600-60" \ "\nchvt 2; sleep 1; chvt 1"; driver_initrd[id] = 0; } }
function get_pci_drivers() { debug("Reading /lib/modules/" kernel "/modules.pcimap."); while ( (getline < ("/lib/modules/" kernel "/modules.pcimap")) > 0 ) { id = sprintf( "%04x%04x", and(strtonum($2),0xffff), and(strtonum($3),0xffff)); # always prefer ALSA drivers if available if ( id in pci_driver && pci_driver[id] ~ /^snd-/ ) continue; pci_driver[id] = $1; }
while ( (getline < "/usr/share/pci.ids") > 0 ) { if ( /^\t\t/ ) { id = $1 $2; sub("^\t+[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+", ""); pci_descs[id] = vendor_name " " $0; } else if ( /^\t/ ) { id = vendor_id $1; sub("^\t+[0-9a-f]+[ \t]+", ""); pci_descs[id] = vendor_name " " $0; } else { vendor_id = $1; sub("^[0-9a-f]+[ \t]+", ""); vendor_name = $0; } } while ( (getline < "/proc/bus/pci/devices") > 0 ) { id = "pci" $1 " (Device " $2 ")"; driver_mod[id] = pci_driver[$2]; driver_dsc[id] = pci_descs[$2]; driver_cmd[id] = ""; drivers[id] = id; autocomplete(pci_driver[$2], id); } }
function get_isapnp_drivers() { debug("Reading /lib/modules/" kernel "/modules.isapnpmap."); while ( (getline < ("/lib/modules/" kernel "/modules.isapnpmap")) > 0 ) { vendor = strtonum($2); device = strtonum($3);
# ugly mangling performed in the kernel ... id = sprintf ("%c%c%c%x%x%x%x", 65 + and (vendor / 4, 0x3f) - 1, 65 + or (and (vendor, 3) * 8, and (vendor / 8192, 7) ) - 1, 65 + and (vendor / 256, 0x1f) - 1, and (device / 16, 0x0f), and (device, 0x0f), and (device / 4096, 0x0f), and (device / 256, 0x0f) );
isapnp_driver[id] = $1; }
while ( (getline < "/proc/bus/isapnp/devices") > 0 ) { id = substr ($2,0,7); iid = "isapnp" id; driver_mod[iid] = isapnp_driver[id]; driver_dsc[iid] = "ISA PnP (" id ")"; #isapnp_descs[id]; driver_cmd[iid] = ""; drivers[iid] = iid; autocomplete(isapnp_driver[id], iid); } }
function match_usb_dev() { if ( usb_device[ "Vendor" ] == 0 && usb_device[ "ProdID" ] == 0 ) return; usbmap_idx[ "Vendor" ] = 1; usbmap_idx[ "ProdID" ] = 2; usbmap_idx[ "DevLo" ] = 4; usbmap_idx[ "DevHi" ] = 8; usbmap_idx[ "DevCls" ] = 16; usbmap_idx[ "DevSub" ] = 32; usbmap_idx[ "DevProt" ] = 64; usbmap_idx[ "IfCls" ] = 128; usbmap_idx[ "IfSub" ] = 256; usbmap_idx[ "IfProt" ] = 512; usbmap_idx[ "DrvInfo" ] = 1024; usb_modlist="";
for ( usb_driver_id=0; usb_driver_id < usb_driver_c; usb_driver_id++ ) { found=1; for ( usbmap_idx_id in usbmap_idx ) { if ( and(usb_driver[usb_driver_id, "match"], usbmap_idx[usbmap_idx_id]) ) { if ( (usb_driver[usb_driver_id, usbmap_idx_id] != \ usb_device[usbmap_idx_id]) ) found=0; } } if (found) { if ( usb_modlist != "" ) usb_modlist = usb_modlist " "; usb_modlist = usb_modlist usb_driver[usb_driver_id, "mod"]; } } if ( usb_modlist != "" ) { id = "usb-device " usb_device[ "Vendor" ] ":" usb_device[ "ProdID" ] " (" usb_modlist ")"; driver_mod[id] = usb_modlist; driver_dsc[id] = usb_device[ "Desc" ] " (" usb_modlist ")"; gsub(" +", " ", driver_dsc[id]); driver_cmd[id] = ""; drivers[id] = id; autocomplete(pci_driver[$2], id); } }
function get_usb_flag(name) { split($0, usb_flags, " +"); for ( usb_flag_id in usb_flags ) { split(usb_flags[usb_flag_id], usb_flag, "[=(]"); if ( usb_flag[1] == name ) return strtonum("0x" usb_flag[2]); } return 0; }
function get_usb_drivers() { while ( ("lspci -v" | getline) > 0 ) { if ( / USB Controller: / ) { usb_ctrl_desc=""; if ( /prog-if.*OHCI/ ) { usb_ctrl_driver="usb-ohci"; usb_ctrl_desc="OHCI"; } if ( /prog-if.*UHCI/ ) { usb_ctrl_driver="usb-uhci"; usb_ctrl_desc="UHCI"; } if ( usb_ctrl_desc != "" ) { sub("^[^ ]*", ""); sub("\\(rev .*$", ""); usb_ctrl_desc = usb_ctrl_desc $0; break; } } } if ( usb_ctrl_driver && modidx[usb_ctrl_driver] ) { debug("Found USB " usb_ctrl_driver " device in lspci output."); id = "usb-controller (PCI " usb_ctrl_driver ")"; driver_mod[id] = usb_ctrl_driver; driver_dsc[id] = usb_ctrl_desc; driver_cmd[id] = "\nmount -t usbfs none /proc/bus/usb"; drivers[id] = id; autocomplete(usb_ctrl_driver, id); }
debug("Reading /lib/modules/" kernel "/modules.usbmap."); for ( usb_driver_c=0; (getline < ("/lib/modules/" kernel "/modules.usbmap")) > 0; usb_driver_c++ ) { if ( $1 == "#" ) { usb_driver_c--; continue; } usb_driver[usb_driver_c, "mod" ] = $1; usb_driver[usb_driver_c, "match" ] = strtonum($2); usb_driver[usb_driver_c, "Vendor" ] = strtonum($3); usb_driver[usb_driver_c, "ProdID" ] = strtonum($4); usb_driver[usb_driver_c, "DevLo" ] = strtonum($5); usb_driver[usb_driver_c, "DevHi" ] = strtonum($6); usb_driver[usb_driver_c, "DevCls" ] = strtonum($7); usb_driver[usb_driver_c, "DevSub" ] = strtonum($8); usb_driver[usb_driver_c, "DevProt" ] = strtonum($9); usb_driver[usb_driver_c, "IfCls" ] = strtonum($10); usb_driver[usb_driver_c, "IfSub" ] = strtonum($11); usb_driver[usb_driver_c, "IfProt" ] = strtonum($12); usb_driver[usb_driver_c, "DrvInfo" ] = strtonum($13); }
while ( (getline < "/proc/bus/usb/devices") > 0 ) { if ( $1 == "T:" ) { if ( usb_device["Vendor"] != "" ) match_usb_dev(); usb_device[ "Vendor" ] = 0; usb_device[ "ProdID" ] = 0; usb_device[ "DevLo" ] = 0; # FIXME: Where is this value in bus/usb/devices? usb_device[ "DevHi" ] = 0; # FIXME: Where is this value in bus/usb/devices? usb_device[ "DevCls" ] = 0; usb_device[ "DevSub" ] = 0; usb_device[ "DevProt" ] = 0; usb_device[ "IfCls" ] = 0; usb_device[ "IfSub" ] = 0; usb_device[ "IfProt" ] = 0; usb_device[ "DrvInfo" ] = 0; # FIXME: Where is this value in bus/usb/devices? usb_device[ "Desc" ] = "USB:"; } if ( $1 == "P:" ) { usb_device[ "Vendor" ] = get_usb_flag("Vendor"); usb_device[ "ProdID" ] = get_usb_flag("ProdID"); } if ( $1 == "D:" ) { usb_device[ "DevCls" ] = get_usb_flag("Cls"); usb_device[ "DevSub" ] = get_usb_flag("Sub"); usb_device[ "DevProt" ] = get_usb_flag("Sub"); } if ( $1 == "I:" ) { usb_device[ "IfCls" ] = get_usb_flag("Cls"); usb_device[ "IfSub" ] = get_usb_flag("Sub"); usb_device[ "IfProt" ] = get_usb_flag("Prot"); } if ( $1 == "S:" ) { if ( ! match($0, "SerialNumber") ) { sub(".*=", ""); usb_device[ "Desc" ] = usb_device[ "Desc" ] " " $0; } } } if ( usb_device["Vendor"] != "" ) match_usb_dev(); }
function print_driver(id) { if ( driver_initrd[id] ) { tmp = driver_mod[id]; gsub(" +", "\nmodprobe ", tmp); tmp = "modprobe " tmp driver_cmd[id]; } else { tmp = driver_mod[id] "\t#no-initrd"; gsub(" +", "\t#no-initrd\nmodprobe ", tmp); tmp = "modprobe " tmp driver_cmd[id]; }
if ( disable_default ) { gsub("\n", "\n#", tmp); tmp = "#" tmp; }
if ( driver_dsc[id] == "" ) { tmp2 = driver_mod[id]; gsub(" .*", "", tmp2); driver_dsc[id] = "Unkown device for driver " tmp2; }
if ( file ) { print "New Device: " id; print "\n### " id " ###" >> file; print "# " driver_dsc[id] >> file; if ( print_echos ) print "echo '" driver_dsc[id] "'" >> file; print tmp >> file; } else { print "\n### " id " ###"; print "# " driver_dsc[id]; if ( print_echos ) print "echo '" driver_dsc[id] "'"; print tmp; } }
BEGIN { for (i=1; i<ARGC; i++) { if ( ARGV[i] == "-k" ) kernel = ARGV[++i]; else if ( ARGV[i] == "-s" ) file = ARGV[++i]; else if ( ARGV[i] == "-d" ) disable_default = 1; else if ( ARGV[i] == "-D" ) print_debug = 1; else if ( ARGV[i] == "-V" ) print_echos = 1; else { print "\n" \ "HWScan - ROCK Linux (www.rocklinux.org)" "\n" \ "Copyright 2003 Clifford Wolf <clifford@clifford.at>" "\n" \ "This is free software with ABSOLUTELY NO WARRANTY." "\n" \ "\n" \ "Usage: hwscan [ [--] options ]" "\n" \ "\n" \ " -k <kernel-version> ......... use /lib/modules/<thisvalue>/" "\n" \ " -s <hw-init-script> ......... e.g. /etc/conf/kernel" "\n" \ " -d .......................... disable new driver on default" "\n" \ " -D .......................... debug (print auto-detected values)" "\n" \ " -V .......................... verbose (add echo's)" "\n"; exit 1; } }
if ( ! kernel ) { if ( ("cat /proc/version" | getline) > 0 ) { kernel = $3; } else { kernel = "*"; } debug("Auto-detected kernel version: " kernel); }
for ( c=0; (("find /lib/modules/" kernel \ "/. -name '*.o' -printf '%P %f\n'") | getline) > 0; c++ ) { sub("\\.o$", ""); modidx[$2] = $1; } debug("Found " c " modules in /lib/modules/" kernel ".");
while ( file && (getline < file) > 0 ) { if ( /^### .* ###$/ ) { sub("^### ", ""); sub(" ###$", ""); skip[$0] = 1; debug("Mark existing driver " $0 " to be skipped."); } }
get_pci_drivers(); get_isapnp_drivers(); get_usb_drivers();
asort(drivers); for (i in drivers) { id = drivers[i]; if ( driver_mod[id] && ! skip[id] ) { print_driver(id); } } }
|