1package main 2 3import ( 4 "errors" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "log" 9 "os" 10 "os/exec" 11 "strings" 12 "bytes" 13) 14 15func TryRunAndSave(output string, name string, arg []string) error { 16 cmd := exec.Command(name, arg...) 17 18 f, err := os.Create(output) 19 if err != nil { 20 log.Fatal(err) 21 } 22 23 cmd.Stdout = f 24 cmd.Stderr = f 25 26 err = cmd.Start() 27 if err != nil { 28 return err 29 } 30 cmd.Wait() 31 return nil 32} 33 34func RunAndSave(output string, name string, arg ...string) { 35 err := TryRunAndSave(output, name, arg) 36 if err == nil { 37 return 38 } 39 idx := strings.LastIndex(name, "/") 40 relname := name 41 if idx >= 0 { 42 relname = name[idx+1:] 43 } 44 relname = "./" + relname 45 err = TryRunAndSave(output, relname, arg) 46 if err != nil { 47 log.Fatal(err) 48 } 49} 50 51const MAXPROMPTRETRY = 3 52 53func PromptUser(prompt string, opts []string) (match string, err error) { 54 for i := 1; i < MAXPROMPTRETRY; i++ { 55 fmt.Printf("%s. (%s) Default:%s\n", prompt, 56 strings.Join(opts, "/"), opts[0]) 57 var usrInput string 58 fmt.Scanln(&usrInput) 59 60 // Check for default entry 61 if usrInput == "" { 62 match = opts[0] 63 return 64 } 65 66 for _, opt := range opts { 67 if opt == usrInput { 68 match = opt 69 return 70 } 71 } 72 } 73 err = errors.New("max retries exceeded") 74 fmt.Fprintln(os.Stderr, "ERROR: max retries exceeded") 75 return 76} 77 78func AppendYesNo(yesFirst bool, yeah []string, nope []string) []string { 79 if yesFirst { 80 return append(yeah, nope...) 81 } else { 82 return append(nope, yeah...) 83 } 84} 85 86func PromptUserBool(prompt string, fallback bool) bool { 87 yeah := []string{"y", "yes"} 88 nope := []string{"n", "no"} 89 90 opt, err := PromptUser(prompt, AppendYesNo(fallback, yeah, nope)) 91 if err != nil { 92 // Continue even if there is an error 93 return fallback 94 } 95 for _, val := range yeah { 96 if opt == val { 97 return true 98 } 99 } 100 return false 101} 102 103func MakeHDALogs(outDir string, cardName string) { 104 SysDir := "/sys/class/sound/" + cardName + "/" 105 files, _ := ioutil.ReadDir(SysDir) 106 for _, f := range files { 107 if (strings.HasPrefix(f.Name(), "hw") || strings.HasPrefix(f.Name(), "hdaudio")) && f.IsDir() { 108 in, err := os.Open(SysDir + f.Name() + "/init_pin_configs") 109 defer in.Close() 110 if err != nil { 111 log.Fatal(err) 112 } 113 out, err := os.Create(outDir + "/pin_" + strings.Replace(f.Name(), "hdaudio", "hw", -1)) 114 if err != nil { 115 log.Fatal(err) 116 } 117 defer out.Close() 118 io.Copy(out, in) 119 } 120 } 121 122 ProcDir := "/proc/asound/" + cardName + "/" 123 files, _ = ioutil.ReadDir(ProcDir) 124 for _, f := range files { 125 if strings.HasPrefix(f.Name(), "codec#") && !f.IsDir() { 126 in, err := os.Open(ProcDir + f.Name()) 127 defer in.Close() 128 if err != nil { 129 log.Fatal(err) 130 } 131 out, err := os.Create(outDir + "/" + f.Name()) 132 if err != nil { 133 log.Fatal(err) 134 } 135 defer out.Close() 136 io.Copy(out, in) 137 } 138 } 139} 140 141func MakeLogs(outDir string) { 142 os.MkdirAll(outDir, 0700) 143 RunAndSave(outDir+"/lspci.log", "lspci", "-nnvvvxxxx") 144 RunAndSave(outDir+"/dmidecode.log", "dmidecode") 145 RunAndSave(outDir+"/acpidump.log", "acpidump") 146 147 probeGFX := PromptUserBool("WARNING: The following tool MAY cause your system to hang when it attempts "+ 148 "to probe for graphics registers. Having the graphics registers will help create a better port. "+ 149 "Should autoport probe these registers?", 150 true) 151 152 inteltoolArgs := "-a" 153 if probeGFX { 154 inteltoolArgs += "f" 155 } 156 157 RunAndSave(outDir+"/inteltool.log", "../inteltool/inteltool", inteltoolArgs) 158 RunAndSave(outDir+"/ectool.log", "../ectool/ectool", "-pd") 159 RunAndSave(outDir+"/superiotool.log", "../superiotool/superiotool", "-ade") 160 161 SysSound := "/sys/class/sound/" 162 card := "" 163 cards, _ := ioutil.ReadDir(SysSound) 164 for _, f := range cards { 165 if strings.HasPrefix(f.Name(), "card") { 166 cid, err := ioutil.ReadFile(SysSound + f.Name() + "/id") 167 if err == nil && bytes.Equal(cid, []byte("PCH\n")) { 168 fmt.Fprintln(os.Stderr, "PCH sound card is", f.Name()) 169 card = f.Name() 170 } 171 } 172 } 173 174 if card != "" { 175 MakeHDALogs(outDir, card) 176 } else { 177 fmt.Fprintln(os.Stderr, "HDAudio not found on PCH.") 178 } 179 180 for _, fname := range []string{"cpuinfo", "ioports"} { 181 in, err := os.Open("/proc/" + fname) 182 defer in.Close() 183 if err != nil { 184 log.Fatal(err) 185 } 186 out, err := os.Create(outDir + "/" + fname + ".log") 187 if err != nil { 188 log.Fatal(err) 189 } 190 defer out.Close() 191 io.Copy(out, in) 192 } 193 194 out, err := os.Create(outDir + "/input_bustypes.log") 195 if err != nil { 196 log.Fatal(err) 197 } 198 defer out.Close() 199 200 ClassInputDir := "/sys/class/input/" 201 files, _ := ioutil.ReadDir(ClassInputDir) 202 for _, f := range files { 203 if strings.HasPrefix(f.Name(), "input") && !f.Mode().IsRegular() { /* Allow both dirs and symlinks. */ 204 in, err := os.Open(ClassInputDir + f.Name() + "/id/bustype") 205 defer in.Close() 206 if err != nil { 207 log.Fatal(err) 208 } 209 io.Copy(out, in) 210 } 211 } 212} 213