/* * Minimal BPF JIT image disassembler * * Disassembles BPF JIT compiler emitted opcodes back to asm insn's for * debugging or verification purposes. * * There is no Makefile. Compile with * * `gcc -Wall -O2 bpf_jit_disasm.c -o bpf_jit_disasm -lopcodes -lbfd -ldl` * * or similar. * * To get the disassembly of the JIT code, do the following: * * 1) `echo 2 > /proc/sys/net/core/bpf_jit_enable` * 2) Load a BPF filter (e.g. `tcpdump -p -n -s 0 -i eth1 host 192.168.20.0/24`) * 3) Run e.g. `bpf_jit_disasm -o` to read out the last JIT code * * Copyright 2013 Daniel Borkmann * Licensed under the GNU General Public License, version 2.0 (GPLv2) * * Note: this is part of the Linux kernel and can be found under tools/net/. */ #include #include #include #include #include #include #include #include #include #include #include static void get_exec_path(char *tpath, size_t size) { char *path; ssize_t len; snprintf(tpath, size, "/proc/%d/exe", (int) getpid()); tpath[size - 1] = 0; path = strdup(tpath); assert(path); len = readlink(path, tpath, size); tpath[len] = 0; free(path); } static void get_asm_insns(uint8_t *image, size_t len, unsigned long base, int opcodes) { int count, i, pc = 0; char tpath[256]; struct disassemble_info info; disassembler_ftype disassemble; bfd *bfdf; memset(tpath, 0, sizeof(tpath)); get_exec_path(tpath, sizeof(tpath)); bfdf = bfd_openr(tpath, NULL); assert(bfdf); assert(bfd_check_format(bfdf, bfd_object)); init_disassemble_info(&info, stdout, (fprintf_ftype) fprintf); info.arch = bfd_get_arch(bfdf); info.mach = bfd_get_mach(bfdf); info.buffer = image; info.buffer_length = len; disassemble_init_for_target(&info); disassemble = disassembler(bfdf); assert(disassemble); do { printf("%4x:\t", pc); count = disassemble(pc, &info); if (opcodes) { printf("\n\t"); for (i = 0; i < count; ++i) printf("%02x ", (uint8_t) image[pc + i]); } printf("\n"); pc += count; } while(count > 0 && pc < len); bfd_close(bfdf); } static char *get_klog_buff(int *klen) { int ret, len = klogctl(10, NULL, 0); char *buff = malloc(len); assert(buff && klen); ret = klogctl(3, buff, len); assert(ret >= 0); *klen = ret; return buff; } static void put_klog_buff(char *buff) { free(buff); } static int get_last_jit_image(char *haystack, size_t hlen, uint8_t *image, size_t ilen, unsigned long *base) { char *ptr, *pptr, *tmp; off_t off = 0; int ret, flen, proglen, pass, ulen = 0; regmatch_t pmatch[1]; regex_t regex; if (hlen == 0) return 0; ret = regcomp(®ex, "flen=[[:alnum:]]+ proglen=[[:digit:]]+ " "pass=[[:digit:]]+ image=[[:xdigit:]]+", REG_EXTENDED); assert(ret == 0); ptr = haystack; while (1) { ret = regexec(®ex, ptr, 1, pmatch, 0); if (ret == 0) { ptr += pmatch[0].rm_eo; off += pmatch[0].rm_eo; assert(off < hlen); } else break; } ptr = haystack + off - (pmatch[0].rm_eo - pmatch[0].rm_so); ret = sscanf(ptr, "flen=%d proglen=%d pass=%d image=%lx", &flen, &proglen, &pass, base); if (ret != 4) return 0; tmp = ptr = haystack + off; while ((ptr = strtok(tmp, "\n")) != NULL && ulen < ilen) { tmp = NULL; if (!strstr(ptr, "JIT code")) continue; pptr = ptr; while ((ptr = strstr(pptr, ":"))) pptr = ptr + 1; ptr = pptr; do { image[ulen++] = (uint8_t) strtoul(pptr, &pptr, 16); if (ptr == pptr || ulen >= ilen) { ulen--; break; } ptr = pptr; } while (1); } assert(ulen == proglen); printf("%d bytes emitted from JIT compiler (pass:%d, flen:%d)\n", proglen, pass, flen); printf("%lx + :\n", *base); regfree(®ex); return ulen; } int main(int argc, char **argv) { int len, klen, opcodes = 0; char *kbuff; unsigned long base; uint8_t image[4096]; if (argc > 1) { if (!strncmp("-o", argv[argc - 1], 2)) { opcodes = 1; } else { printf("usage: bpf_jit_disasm [-o: show opcodes]\n"); exit(0); } } bfd_init(); memset(image, 0, sizeof(image)); kbuff = get_klog_buff(&klen); len = get_last_jit_image(kbuff, klen, image, sizeof(image), &base); if (len > 0 && base > 0) get_asm_insns(image, len, base, opcodes); put_klog_buff(kbuff); return 0; } art@linux.intel.com>2016-12-13 09:29:03 -0800 commit8023eff10e7b0327898f17f0b553d2e45c71cef3 (patch) treea18bb7bf57c8adb3c299fe3b5d3831627120cc69 parentb4aca383f9afb5f84b05de272656e6d4a919d995 (diff)
platform/x86: asus-wmi: Set specified XUSB2PR value for X550LB
The bluetooth adapter Atheros AR3012 can't be enumerated and make the bluetooth function broken. T: Bus=02 Lev=01 Prnt=01 Port=05 Cnt=02 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3362 Rev=00.02 S: Manufacturer=Atheros Communications S: Product=Bluetooth USB Host Controller S: SerialNumber=Alaska Day 2006 C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb The error is: usb 2-6: device not accepting address 7, error -62 usb usb2-port6: unable to enumerate USB device It is caused by adapter's connected port is mapped to xHC controller, but the xHCI is not supported by the usb device. The output of 'sudo lspci -nnxxx -s 00:14.0': 00:14.0 USB controller [0c03]: Intel Corporation 8 Series USB xHCI HC [8086:9c31] (rev 04) 00: 86 80 31 9c 06 04 90 02 04 30 03 0c 00 00 00 00 10: 04 00 a0 f7 00 00 00 00 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 43 10 1f 20 30: 00 00 00 00 70 00 00 00 00 00 00 00 0b 01 00 00 40: fd 01 36 80 89 c6 0f 80 00 00 00 00 00 00 00 00 50: 5f 2e ce 0f 00 00 00 00 00 00 00 00 00 00 00 00 60: 30 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70: 01 80 c2 c1 08 00 00 00 00 00 00 00 00 00 00 00 80: 05 00 87 00 0c a0 e0 fe 00 00 00 00 a1 41 00 00 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a0: 00 01 04 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 0f 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 03 c0 30 00 00 00 00 00 03 0c 00 00 00 00 00 00 d0: f9 01 00 00 f9 01 00 00 0f 00 00 00 0f 00 00 00 e0: 00 08 00 00 00 00 00 00 00 00 00 00 d8 d8 00 00 f0: 00 00 00 00 00 00 00 00 b1 0f 04 08 00 00 00 00 By referencing Intel Platform Controller Hub(PCH) datasheet, the xHC USB 2.0 Port Routing(XUSB2PR) at offset 0xD0-0xD3h decides the setting of mapping the port to EHCI controller or xHC controller. And the port mapped to xHC will enable xHCI during bus resume. The setting of disabling bluetooth adapter's connected port is 0x000001D9. The value can be obtained by few times 1 bit flip operation. The suited configuration should have the 'lsusb -t' result with bluetooth using ehci: /: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/9p, 480M |__ Port 5: Dev 2, If 0, Class=Video, Driver=uvcvideo, 480M |__ Port 5: Dev 2, If 1, Class=Video, Driver=uvcvideo, 480M /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M |__ Port 6: Dev 3, If 0, Class=Wireless, Driver=btusb, 12M |__ Port 6: Dev 3, If 1, Class=Wireless, Driver=btusb, 12M Signed-off-by: Kai-Chuan Hsieh <kai.chiuan@gmail.com> Acked-by: Corentin Chary <corentin.chary@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> [andy: resolve merge conflict in asus-wmi.h] Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>