bt_dev_dbg(hdev, "Failed to set pattern");
 }
 
+static void hci_devcd_dump(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+       u32 size;
+
+       bt_dev_dbg(hdev, "state %d", hdev->dump.state);
+
+       size = hdev->dump.tail - hdev->dump.head;
+
+       /* Emit a devcoredump with the available data */
+       dev_coredumpv(&hdev->dev, hdev->dump.head, size, GFP_KERNEL);
+
+       /* Send a copy to monitor as a diagnostic packet */
+       skb = bt_skb_alloc(size, GFP_ATOMIC);
+       if (skb) {
+               skb_put_data(skb, hdev->dump.head, size);
+               hci_recv_diag(hdev, skb);
+       }
+}
+
 static void hci_devcd_handle_pkt_complete(struct hci_dev *hdev,
                                          struct sk_buff *skb)
 {
        bt_dev_dbg(hdev, "complete with size %u (expect %zu)", dump_size,
                   hdev->dump.alloc_size);
 
-       dev_coredumpv(&hdev->dev, hdev->dump.head, dump_size, GFP_KERNEL);
+       hci_devcd_dump(hdev);
 }
 
 static void hci_devcd_handle_pkt_abort(struct hci_dev *hdev,
        bt_dev_dbg(hdev, "aborted with size %u (expect %zu)", dump_size,
                   hdev->dump.alloc_size);
 
-       /* Emit a devcoredump with the available data */
-       dev_coredumpv(&hdev->dev, hdev->dump.head, dump_size, GFP_KERNEL);
+       hci_devcd_dump(hdev);
 }
 
 /* Bluetooth devcoredump state machine.
        bt_dev_dbg(hdev, "timeout with size %u (expect %zu)", dump_size,
                   hdev->dump.alloc_size);
 
-       /* Emit a devcoredump with the available data */
-       dev_coredumpv(&hdev->dev, hdev->dump.head, dump_size, GFP_KERNEL);
+       hci_devcd_dump(hdev);
 
        hci_devcd_reset(hdev);