__u8    data[HCI_MAX_AMP_ASSOC_SIZE];
 };
 
+#define HCI_MAX_PAGES  2
+
 #define NUM_REASSEMBLY 4
 struct hci_dev {
        struct list_head list;
        __u8            dev_class[3];
        __u8            major_class;
        __u8            minor_class;
-       __u8            features[8];
-       __u8            host_features[8];
+       __u8            features[HCI_MAX_PAGES][8];
        __u8            le_features[8];
        __u8            le_white_list_size;
        __u8            le_states[8];
        bool            out;
        __u8            attempt;
        __u8            dev_class[3];
-       __u8            features[8];
+       __u8            features[HCI_MAX_PAGES][8];
        __u16           interval;
        __u16           pkt_type;
        __u16           link_policy;
 #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev))
 
 /* ----- LMP capabilities ----- */
-#define lmp_encrypt_capable(dev)   ((dev)->features[0] & LMP_ENCRYPT)
-#define lmp_rswitch_capable(dev)   ((dev)->features[0] & LMP_RSWITCH)
-#define lmp_hold_capable(dev)      ((dev)->features[0] & LMP_HOLD)
-#define lmp_sniff_capable(dev)     ((dev)->features[0] & LMP_SNIFF)
-#define lmp_park_capable(dev)      ((dev)->features[1] & LMP_PARK)
-#define lmp_inq_rssi_capable(dev)  ((dev)->features[3] & LMP_RSSI_INQ)
-#define lmp_esco_capable(dev)      ((dev)->features[3] & LMP_ESCO)
-#define lmp_bredr_capable(dev)     (!((dev)->features[4] & LMP_NO_BREDR))
-#define lmp_le_capable(dev)        ((dev)->features[4] & LMP_LE)
-#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
-#define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC)
-#define lmp_ext_inq_capable(dev)   ((dev)->features[6] & LMP_EXT_INQ)
-#define lmp_le_br_capable(dev)     !!((dev)->features[6] & LMP_SIMUL_LE_BR)
-#define lmp_ssp_capable(dev)       ((dev)->features[6] & LMP_SIMPLE_PAIR)
-#define lmp_no_flush_capable(dev)  ((dev)->features[6] & LMP_NO_FLUSH)
-#define lmp_lsto_capable(dev)      ((dev)->features[7] & LMP_LSTO)
-#define lmp_inq_tx_pwr_capable(dev) ((dev)->features[7] & LMP_INQ_TX_PWR)
-#define lmp_ext_feat_capable(dev)  ((dev)->features[7] & LMP_EXTFEATURES)
+#define lmp_encrypt_capable(dev)   ((dev)->features[0][0] & LMP_ENCRYPT)
+#define lmp_rswitch_capable(dev)   ((dev)->features[0][0] & LMP_RSWITCH)
+#define lmp_hold_capable(dev)      ((dev)->features[0][0] & LMP_HOLD)
+#define lmp_sniff_capable(dev)     ((dev)->features[0][0] & LMP_SNIFF)
+#define lmp_park_capable(dev)      ((dev)->features[0][1] & LMP_PARK)
+#define lmp_inq_rssi_capable(dev)  ((dev)->features[0][3] & LMP_RSSI_INQ)
+#define lmp_esco_capable(dev)      ((dev)->features[0][3] & LMP_ESCO)
+#define lmp_bredr_capable(dev)     (!((dev)->features[0][4] & LMP_NO_BREDR))
+#define lmp_le_capable(dev)        ((dev)->features[0][4] & LMP_LE)
+#define lmp_sniffsubr_capable(dev) ((dev)->features[0][5] & LMP_SNIFF_SUBR)
+#define lmp_pause_enc_capable(dev) ((dev)->features[0][5] & LMP_PAUSE_ENC)
+#define lmp_ext_inq_capable(dev)   ((dev)->features[0][6] & LMP_EXT_INQ)
+#define lmp_le_br_capable(dev)     (!!((dev)->features[0][6] & LMP_SIMUL_LE_BR))
+#define lmp_ssp_capable(dev)       ((dev)->features[0][6] & LMP_SIMPLE_PAIR)
+#define lmp_no_flush_capable(dev)  ((dev)->features[0][6] & LMP_NO_FLUSH)
+#define lmp_lsto_capable(dev)      ((dev)->features[0][7] & LMP_LSTO)
+#define lmp_inq_tx_pwr_capable(dev) ((dev)->features[0][7] & LMP_INQ_TX_PWR)
+#define lmp_ext_feat_capable(dev)  ((dev)->features[0][7] & LMP_EXTFEATURES)
 
 /* ----- Extended LMP capabilities ----- */
-#define lmp_host_ssp_capable(dev)  ((dev)->host_features[0] & LMP_HOST_SSP)
-#define lmp_host_le_capable(dev)   !!((dev)->host_features[0] & LMP_HOST_LE)
-#define lmp_host_le_br_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE_BREDR)
+#define lmp_host_ssp_capable(dev)  ((dev)->features[1][0] & LMP_HOST_SSP)
+#define lmp_host_le_capable(dev)   (!!((dev)->features[1][0] & LMP_HOST_LE))
+#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))
 
 /* returns true if at least one AMP active */
 static inline bool hci_amp_capable(void)
 
 
        if (!status) {
                if (sent->mode)
-                       hdev->host_features[0] |= LMP_HOST_SSP;
+                       hdev->features[1][0] |= LMP_HOST_SSP;
                else
-                       hdev->host_features[0] &= ~LMP_HOST_SSP;
+                       hdev->features[1][0] &= ~LMP_HOST_SSP;
        }
 
        if (test_bit(HCI_MGMT, &hdev->dev_flags))
        /* Adjust default settings according to features
         * supported by device. */
 
-       if (hdev->features[0] & LMP_3SLOT)
+       if (hdev->features[0][0] & LMP_3SLOT)
                hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
 
-       if (hdev->features[0] & LMP_5SLOT)
+       if (hdev->features[0][0] & LMP_5SLOT)
                hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
 
-       if (hdev->features[1] & LMP_HV2) {
+       if (hdev->features[0][1] & LMP_HV2) {
                hdev->pkt_type  |= (HCI_HV2);
                hdev->esco_type |= (ESCO_HV2);
        }
 
-       if (hdev->features[1] & LMP_HV3) {
+       if (hdev->features[0][1] & LMP_HV3) {
                hdev->pkt_type  |= (HCI_HV3);
                hdev->esco_type |= (ESCO_HV3);
        }
        if (lmp_esco_capable(hdev))
                hdev->esco_type |= (ESCO_EV3);
 
-       if (hdev->features[4] & LMP_EV4)
+       if (hdev->features[0][4] & LMP_EV4)
                hdev->esco_type |= (ESCO_EV4);
 
-       if (hdev->features[4] & LMP_EV5)
+       if (hdev->features[0][4] & LMP_EV5)
                hdev->esco_type |= (ESCO_EV5);
 
-       if (hdev->features[5] & LMP_EDR_ESCO_2M)
+       if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
                hdev->esco_type |= (ESCO_2EV3);
 
-       if (hdev->features[5] & LMP_EDR_ESCO_3M)
+       if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
                hdev->esco_type |= (ESCO_3EV3);
 
-       if (hdev->features[5] & LMP_EDR_3S_ESCO)
+       if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
                hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
 
        BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
-              hdev->features[0], hdev->features[1],
-              hdev->features[2], hdev->features[3],
-              hdev->features[4], hdev->features[5],
-              hdev->features[6], hdev->features[7]);
+              hdev->features[0][0], hdev->features[0][1],
+              hdev->features[0][2], hdev->features[0][3],
+              hdev->features[0][4], hdev->features[0][5],
+              hdev->features[0][6], hdev->features[0][7]);
 }
 
 static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
        if (rp->status)
                return;
 
-       switch (rp->page) {
-       case 0:
-               memcpy(hdev->features, rp->features, 8);
-               break;
-       case 1:
-               memcpy(hdev->host_features, rp->features, 8);
-               break;
-       }
+       if (rp->page < HCI_MAX_PAGES)
+               memcpy(hdev->features[rp->page], rp->features, 8);
 }
 
 static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
 
        if (!status) {
                if (sent->le)
-                       hdev->host_features[0] |= LMP_HOST_LE;
+                       hdev->features[1][0] |= LMP_HOST_LE;
                else
-                       hdev->host_features[0] &= ~LMP_HOST_LE;
+                       hdev->features[1][0] &= ~LMP_HOST_LE;
 
                if (sent->simul)
-                       hdev->host_features[0] |= LMP_HOST_LE_BREDR;
+                       hdev->features[1][0] |= LMP_HOST_LE_BREDR;
                else
-                       hdev->host_features[0] &= ~LMP_HOST_LE_BREDR;
+                       hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
        }
 
        if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
                goto unlock;
 
        if (!ev->status)
-               memcpy(conn->features, ev->features, 8);
+               memcpy(conn->features[0], ev->features, 8);
 
        if (conn->state != BT_CONFIG)
                goto unlock;
        if (!conn)
                goto unlock;
 
+       if (ev->page < HCI_MAX_PAGES)
+               memcpy(conn->features[ev->page], ev->features, 8);
+
        if (!ev->status && ev->page == 0x01) {
                struct inquiry_entry *ie;
 
 {
        struct hci_ev_remote_host_features *ev = (void *) skb->data;
        struct inquiry_entry *ie;
+       struct hci_conn *conn;
 
        BT_DBG("%s", hdev->name);
 
        hci_dev_lock(hdev);
 
+       conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+       if (conn)
+               memcpy(conn->features[1], ev->features, 8);
+
        ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
        if (ie)
                ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
 
        struct hci_conn *conn = to_hci_conn(dev);
 
        return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-                      conn->features[0], conn->features[1],
-                      conn->features[2], conn->features[3],
-                      conn->features[4], conn->features[5],
-                      conn->features[6], conn->features[7]);
+                      conn->features[0][0], conn->features[0][1],
+                      conn->features[0][2], conn->features[0][3],
+                      conn->features[0][4], conn->features[0][5],
+                      conn->features[0][6], conn->features[0][7]);
 }
 
 #define LINK_ATTR(_name, _mode, _show, _store) \
        struct hci_dev *hdev = to_hci_dev(dev);
 
        return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-                      hdev->features[0], hdev->features[1],
-                      hdev->features[2], hdev->features[3],
-                      hdev->features[4], hdev->features[5],
-                      hdev->features[6], hdev->features[7]);
+                      hdev->features[0][0], hdev->features[0][1],
+                      hdev->features[0][2], hdev->features[0][3],
+                      hdev->features[0][4], hdev->features[0][5],
+                      hdev->features[0][6], hdev->features[0][7]);
 }
 
 static ssize_t show_manufacturer(struct device *dev,