Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: btintel_pcie: Refactor Device Coredump

As device coredumps are not HCI traces, maintain the device coredump at
the driver level and eliminate the dependency on hdev_devcd*()

Signed-off-by: Kiran K <kiran.k@intel.com>
Fixes: 07e6bddb54b4 ("Bluetooth: btintel_pcie: Add support for device coredump")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Kiran K and committed by
Luiz Augusto von Dentz
58fddb36 5967c085

+76 -144
+74 -144
drivers/bluetooth/btintel_pcie.c
··· 15 15 #include <linux/interrupt.h> 16 16 17 17 #include <linux/unaligned.h> 18 + #include <linux/devcoredump.h> 18 19 19 20 #include <net/bluetooth/bluetooth.h> 20 21 #include <net/bluetooth/hci_core.h> ··· 560 559 btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg); 561 560 } 562 561 563 - static int btintel_pcie_add_dmp_data(struct hci_dev *hdev, const void *data, int size) 564 - { 565 - struct sk_buff *skb; 566 - int err; 567 - 568 - skb = alloc_skb(size, GFP_ATOMIC); 569 - if (!skb) 570 - return -ENOMEM; 571 - 572 - skb_put_data(skb, data, size); 573 - err = hci_devcd_append(hdev, skb); 574 - if (err) { 575 - bt_dev_err(hdev, "Failed to append data in the coredump"); 576 - return err; 577 - } 578 - 579 - return 0; 580 - } 581 - 582 562 static int btintel_pcie_get_mac_access(struct btintel_pcie_data *data) 583 563 { 584 564 u32 reg; ··· 604 622 btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg); 605 623 } 606 624 607 - static void btintel_pcie_copy_tlv(struct sk_buff *skb, enum btintel_pcie_tlv_type type, 608 - void *data, int size) 625 + static void *btintel_pcie_copy_tlv(void *dest, enum btintel_pcie_tlv_type type, 626 + void *data, size_t size) 609 627 { 610 628 struct intel_tlv *tlv; 611 629 612 - tlv = skb_put(skb, sizeof(*tlv) + size); 630 + tlv = dest; 613 631 tlv->type = type; 614 632 tlv->len = size; 615 633 memcpy(tlv->val, data, tlv->len); 634 + return dest + sizeof(*tlv) + size; 616 635 } 617 636 618 637 static int btintel_pcie_read_dram_buffers(struct btintel_pcie_data *data) 619 638 { 620 - u32 offset, prev_size, wr_ptr_status, dump_size, i; 639 + u32 offset, prev_size, wr_ptr_status, dump_size, data_len; 621 640 struct btintel_pcie_dbgc *dbgc = &data->dbgc; 622 - u8 buf_idx, dump_time_len, fw_build; 623 641 struct hci_dev *hdev = data->hdev; 642 + u8 *pdata, *p, buf_idx; 624 643 struct intel_tlv *tlv; 625 644 struct timespec64 now; 626 - struct sk_buff *skb; 627 645 struct tm tm_now; 628 - char buf[256]; 629 - u16 hdr_len; 630 - int ret; 646 + char fw_build[128]; 647 + char ts[128]; 648 + char vendor[64]; 649 + char driver[64]; 650 + 651 + if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) 652 + return -EOPNOTSUPP; 653 + 631 654 632 655 wr_ptr_status = btintel_pcie_rd_dev_mem(data, BTINTEL_PCIE_DBGC_CUR_DBGBUFF_STATUS); 633 656 offset = wr_ptr_status & BTINTEL_PCIE_DBG_OFFSET_BIT_MASK; ··· 649 662 else 650 663 return -EINVAL; 651 664 665 + snprintf(vendor, sizeof(vendor), "Vendor: Intel\n"); 666 + snprintf(driver, sizeof(driver), "Driver: %s\n", 667 + data->dmp_hdr.driver_name); 668 + 652 669 ktime_get_real_ts64(&now); 653 670 time64_to_tm(now.tv_sec, 0, &tm_now); 654 - dump_time_len = snprintf(buf, sizeof(buf), "Dump Time: %02d-%02d-%04ld %02d:%02d:%02d", 671 + snprintf(ts, sizeof(ts), "Dump Time: %02d-%02d-%04ld %02d:%02d:%02d", 655 672 tm_now.tm_mday, tm_now.tm_mon + 1, tm_now.tm_year + 1900, 656 673 tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec); 657 674 658 - fw_build = snprintf(buf + dump_time_len, sizeof(buf) - dump_time_len, 675 + snprintf(fw_build, sizeof(fw_build), 659 676 "Firmware Timestamp: Year %u WW %02u buildtype %u build %u", 660 677 2000 + (data->dmp_hdr.fw_timestamp >> 8), 661 678 data->dmp_hdr.fw_timestamp & 0xff, data->dmp_hdr.fw_build_type, 662 679 data->dmp_hdr.fw_build_num); 663 680 664 - hdr_len = sizeof(*tlv) + sizeof(data->dmp_hdr.cnvi_bt) + 665 - sizeof(*tlv) + sizeof(data->dmp_hdr.write_ptr) + 666 - sizeof(*tlv) + sizeof(data->dmp_hdr.wrap_ctr) + 667 - sizeof(*tlv) + sizeof(data->dmp_hdr.trigger_reason) + 668 - sizeof(*tlv) + sizeof(data->dmp_hdr.fw_git_sha1) + 669 - sizeof(*tlv) + sizeof(data->dmp_hdr.cnvr_top) + 670 - sizeof(*tlv) + sizeof(data->dmp_hdr.cnvi_top) + 671 - sizeof(*tlv) + dump_time_len + 672 - sizeof(*tlv) + fw_build; 681 + data_len = sizeof(*tlv) + sizeof(data->dmp_hdr.cnvi_bt) + 682 + sizeof(*tlv) + sizeof(data->dmp_hdr.write_ptr) + 683 + sizeof(*tlv) + sizeof(data->dmp_hdr.wrap_ctr) + 684 + sizeof(*tlv) + sizeof(data->dmp_hdr.trigger_reason) + 685 + sizeof(*tlv) + sizeof(data->dmp_hdr.fw_git_sha1) + 686 + sizeof(*tlv) + sizeof(data->dmp_hdr.cnvr_top) + 687 + sizeof(*tlv) + sizeof(data->dmp_hdr.cnvi_top) + 688 + sizeof(*tlv) + strlen(ts) + 689 + sizeof(*tlv) + strlen(fw_build) + 690 + sizeof(*tlv) + strlen(vendor) + 691 + sizeof(*tlv) + strlen(driver); 673 692 674 - dump_size = hdr_len + sizeof(hdr_len); 693 + /* 694 + * sizeof(u32) - signature 695 + * sizeof(data_len) - to store tlv data size 696 + * data_len - TLV data 697 + */ 698 + dump_size = sizeof(u32) + sizeof(data_len) + data_len; 675 699 676 - skb = alloc_skb(dump_size, GFP_KERNEL); 677 - if (!skb) 678 - return -ENOMEM; 679 700 680 701 /* Add debug buffers data length to dump size */ 681 702 dump_size += BTINTEL_PCIE_DBGC_BUFFER_SIZE * dbgc->count; 682 703 683 - ret = hci_devcd_init(hdev, dump_size); 684 - if (ret) { 685 - bt_dev_err(hdev, "Failed to init devcoredump, err %d", ret); 686 - kfree_skb(skb); 687 - return ret; 688 - } 704 + pdata = vmalloc(dump_size); 705 + if (!pdata) 706 + return -ENOMEM; 707 + p = pdata; 689 708 690 - skb_put_data(skb, &hdr_len, sizeof(hdr_len)); 709 + *(u32 *)p = BTINTEL_PCIE_MAGIC_NUM; 710 + p += sizeof(u32); 691 711 692 - btintel_pcie_copy_tlv(skb, BTINTEL_CNVI_BT, &data->dmp_hdr.cnvi_bt, 693 - sizeof(data->dmp_hdr.cnvi_bt)); 712 + *(u32 *)p = data_len; 713 + p += sizeof(u32); 694 714 695 - btintel_pcie_copy_tlv(skb, BTINTEL_WRITE_PTR, &data->dmp_hdr.write_ptr, 696 - sizeof(data->dmp_hdr.write_ptr)); 715 + 716 + p = btintel_pcie_copy_tlv(p, BTINTEL_VENDOR, vendor, strlen(vendor)); 717 + p = btintel_pcie_copy_tlv(p, BTINTEL_DRIVER, driver, strlen(driver)); 718 + p = btintel_pcie_copy_tlv(p, BTINTEL_DUMP_TIME, ts, strlen(ts)); 719 + p = btintel_pcie_copy_tlv(p, BTINTEL_FW_BUILD, fw_build, 720 + strlen(fw_build)); 721 + p = btintel_pcie_copy_tlv(p, BTINTEL_CNVI_BT, &data->dmp_hdr.cnvi_bt, 722 + sizeof(data->dmp_hdr.cnvi_bt)); 723 + p = btintel_pcie_copy_tlv(p, BTINTEL_WRITE_PTR, &data->dmp_hdr.write_ptr, 724 + sizeof(data->dmp_hdr.write_ptr)); 725 + p = btintel_pcie_copy_tlv(p, BTINTEL_WRAP_CTR, &data->dmp_hdr.wrap_ctr, 726 + sizeof(data->dmp_hdr.wrap_ctr)); 697 727 698 728 data->dmp_hdr.wrap_ctr = btintel_pcie_rd_dev_mem(data, 699 729 BTINTEL_PCIE_DBGC_DBGBUFF_WRAP_ARND); 700 730 701 - btintel_pcie_copy_tlv(skb, BTINTEL_WRAP_CTR, &data->dmp_hdr.wrap_ctr, 702 - sizeof(data->dmp_hdr.wrap_ctr)); 731 + p = btintel_pcie_copy_tlv(p, BTINTEL_TRIGGER_REASON, &data->dmp_hdr.trigger_reason, 732 + sizeof(data->dmp_hdr.trigger_reason)); 733 + p = btintel_pcie_copy_tlv(p, BTINTEL_FW_SHA, &data->dmp_hdr.fw_git_sha1, 734 + sizeof(data->dmp_hdr.fw_git_sha1)); 735 + p = btintel_pcie_copy_tlv(p, BTINTEL_CNVR_TOP, &data->dmp_hdr.cnvr_top, 736 + sizeof(data->dmp_hdr.cnvr_top)); 737 + p = btintel_pcie_copy_tlv(p, BTINTEL_CNVI_TOP, &data->dmp_hdr.cnvi_top, 738 + sizeof(data->dmp_hdr.cnvi_top)); 703 739 704 - btintel_pcie_copy_tlv(skb, BTINTEL_TRIGGER_REASON, &data->dmp_hdr.trigger_reason, 705 - sizeof(data->dmp_hdr.trigger_reason)); 706 - 707 - btintel_pcie_copy_tlv(skb, BTINTEL_FW_SHA, &data->dmp_hdr.fw_git_sha1, 708 - sizeof(data->dmp_hdr.fw_git_sha1)); 709 - 710 - btintel_pcie_copy_tlv(skb, BTINTEL_CNVR_TOP, &data->dmp_hdr.cnvr_top, 711 - sizeof(data->dmp_hdr.cnvr_top)); 712 - 713 - btintel_pcie_copy_tlv(skb, BTINTEL_CNVI_TOP, &data->dmp_hdr.cnvi_top, 714 - sizeof(data->dmp_hdr.cnvi_top)); 715 - 716 - btintel_pcie_copy_tlv(skb, BTINTEL_DUMP_TIME, buf, dump_time_len); 717 - 718 - btintel_pcie_copy_tlv(skb, BTINTEL_FW_BUILD, buf + dump_time_len, fw_build); 719 - 720 - ret = hci_devcd_append(hdev, skb); 721 - if (ret) 722 - goto exit_err; 723 - 724 - for (i = 0; i < dbgc->count; i++) { 725 - ret = btintel_pcie_add_dmp_data(hdev, dbgc->bufs[i].data, 726 - BTINTEL_PCIE_DBGC_BUFFER_SIZE); 727 - if (ret) 728 - break; 729 - } 730 - 731 - exit_err: 732 - hci_devcd_complete(hdev); 733 - return ret; 740 + memcpy(p, dbgc->bufs[0].data, dbgc->count * BTINTEL_PCIE_DBGC_BUFFER_SIZE); 741 + dev_coredumpv(&hdev->dev, pdata, dump_size, GFP_KERNEL); 742 + return 0; 734 743 } 735 744 736 745 static void btintel_pcie_dump_traces(struct hci_dev *hdev) ··· 746 763 747 764 if (ret) 748 765 bt_dev_err(hdev, "Failed to dump traces: (%d)", ret); 749 - } 750 - 751 - static void btintel_pcie_dump_hdr(struct hci_dev *hdev, struct sk_buff *skb) 752 - { 753 - struct btintel_pcie_data *data = hci_get_drvdata(hdev); 754 - u16 len = skb->len; 755 - u16 *hdrlen_ptr; 756 - char buf[80]; 757 - 758 - hdrlen_ptr = skb_put_zero(skb, sizeof(len)); 759 - 760 - snprintf(buf, sizeof(buf), "Controller Name: 0x%X\n", 761 - INTEL_HW_VARIANT(data->dmp_hdr.cnvi_bt)); 762 - skb_put_data(skb, buf, strlen(buf)); 763 - 764 - snprintf(buf, sizeof(buf), "Firmware Build Number: %u\n", 765 - data->dmp_hdr.fw_build_num); 766 - skb_put_data(skb, buf, strlen(buf)); 767 - 768 - snprintf(buf, sizeof(buf), "Driver: %s\n", data->dmp_hdr.driver_name); 769 - skb_put_data(skb, buf, strlen(buf)); 770 - 771 - snprintf(buf, sizeof(buf), "Vendor: Intel\n"); 772 - skb_put_data(skb, buf, strlen(buf)); 773 - 774 - *hdrlen_ptr = skb->len - len; 775 - } 776 - 777 - static void btintel_pcie_dump_notify(struct hci_dev *hdev, int state) 778 - { 779 - struct btintel_pcie_data *data = hci_get_drvdata(hdev); 780 - 781 - switch (state) { 782 - case HCI_DEVCOREDUMP_IDLE: 783 - data->dmp_hdr.state = HCI_DEVCOREDUMP_IDLE; 784 - break; 785 - case HCI_DEVCOREDUMP_ACTIVE: 786 - data->dmp_hdr.state = HCI_DEVCOREDUMP_ACTIVE; 787 - break; 788 - case HCI_DEVCOREDUMP_TIMEOUT: 789 - case HCI_DEVCOREDUMP_ABORT: 790 - case HCI_DEVCOREDUMP_DONE: 791 - data->dmp_hdr.state = HCI_DEVCOREDUMP_IDLE; 792 - break; 793 - } 794 766 } 795 767 796 768 /* This function enables BT function by setting BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT bit in ··· 1321 1383 struct btintel_pcie_data, rx_work); 1322 1384 struct sk_buff *skb; 1323 1385 1386 + if (test_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags)) { 1387 + btintel_pcie_dump_traces(data->hdev); 1388 + clear_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags); 1389 + } 1390 + 1324 1391 if (test_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags)) { 1325 1392 /* Unlike usb products, controller will not send hardware 1326 1393 * exception event on exception. Instead controller writes the ··· 1336 1393 */ 1337 1394 btintel_pcie_read_hwexp(data); 1338 1395 clear_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags); 1339 - } 1340 - 1341 - if (test_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags)) { 1342 - btintel_pcie_dump_traces(data->hdev); 1343 - clear_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags); 1344 1396 } 1345 1397 1346 1398 /* Process the sk_buf in queue and send to the HCI layer */ ··· 2128 2190 if (ver_tlv.img_type == 0x02 || ver_tlv.img_type == 0x03) 2129 2191 data->dmp_hdr.fw_git_sha1 = ver_tlv.git_sha1; 2130 2192 2131 - err = hci_devcd_register(hdev, btintel_pcie_dump_traces, btintel_pcie_dump_hdr, 2132 - btintel_pcie_dump_notify); 2133 - if (err) { 2134 - bt_dev_err(hdev, "Failed to register coredump (%d)", err); 2135 - goto exit_error; 2136 - } 2137 - 2138 2193 btintel_print_fseq_info(hdev); 2139 2194 exit_error: 2140 2195 kfree_skb(skb); ··· 2257 2326 btintel_pcie_synchronize_irqs(data); 2258 2327 2259 2328 flush_work(&data->rx_work); 2260 - flush_work(&data->hdev->dump.dump_rx); 2261 2329 2262 2330 bt_dev_dbg(data->hdev, "Release bluetooth interface"); 2263 2331 btintel_pcie_release_hdev(data);
+2
drivers/bluetooth/btintel_pcie.h
··· 132 132 BTINTEL_CNVI_TOP, 133 133 BTINTEL_DUMP_TIME, 134 134 BTINTEL_FW_BUILD, 135 + BTINTEL_VENDOR, 136 + BTINTEL_DRIVER 135 137 }; 136 138 137 139 /* causes for the MBOX interrupts */