/** * kim_int_recv - receive function called during firmware download * firmware download responses on different UART drivers * have been observed to come in bursts of different * tty_receive and hence the logic */ void kim_int_recv(struct kim_data_s *kim_gdata, const unsigned char *data, long count) { const unsigned char *ptr; int len = 0, type = 0; unsigned char *plen; pr_debug("%s", __func__); /* Decode received bytes here */ ptr = data; if (unlikely(ptr == NULL)) { pr_err(" received null from TTY "); return; } while (count) { if (kim_gdata->rx_count) { len = min_t(unsigned int, kim_gdata->rx_count, count); memcpy(skb_put(kim_gdata->rx_skb, len), ptr, len); kim_gdata->rx_count -= len; count -= len; ptr += len; if (kim_gdata->rx_count) continue; /* Check ST RX state machine , where are we? */ switch (kim_gdata->rx_state) { /* Waiting for complete packet ? */ case ST_W4_DATA: pr_debug("Complete pkt received"); validate_firmware_response(kim_gdata); kim_gdata->rx_state = ST_W4_PACKET_TYPE; kim_gdata->rx_skb = NULL; continue; /* Waiting for Bluetooth event header ? */ case ST_W4_HEADER: plen = (unsigned char *)&kim_gdata->rx_skb->data[1]; pr_debug("event hdr: plen 0x%02x\n", *plen); kim_check_data_len(kim_gdata, *plen); continue; } /* end of switch */ } /* end of if rx_state */ switch (*ptr) { /* Bluetooth event packet? */ case 0x04: kim_gdata->rx_state = ST_W4_HEADER; kim_gdata->rx_count = 2; type = *ptr; break; default: pr_info("unknown packet"); ptr++; count--; continue; } ptr++; count--; kim_gdata->rx_skb = alloc_skb(1024+8, GFP_ATOMIC); if (!kim_gdata->rx_skb) { pr_err("can't allocate mem for new packet"); kim_gdata->rx_state = ST_W4_PACKET_TYPE; kim_gdata->rx_count = 0; return; } skb_reserve(kim_gdata->rx_skb, 8); kim_gdata->rx_skb->cb[0] = 4; kim_gdata->rx_skb->cb[1] = 0; }
/* receive function called during firmware download * - firmware download responses on different UART drivers * have been observed to come in bursts of different * tty_receive and hence the logic */ void kim_int_recv(const unsigned char *data, long count) { register char *ptr; struct hci_event_hdr *eh; register int len = 0, type = 0; ST_KIM_DBG("%s", __func__); /* Decode received bytes here */ ptr = (char *)data; if (unlikely(ptr == NULL)) { ST_KIM_ERR(" received null from TTY "); return; } while (count) { if (kim_gdata->rx_count) { len = min_t(unsigned int, kim_gdata->rx_count, count); memcpy(skb_put(kim_gdata->rx_skb, len), ptr, len); kim_gdata->rx_count -= len; count -= len; ptr += len; if (kim_gdata->rx_count) continue; /* Check ST RX state machine , where are we? */ switch (kim_gdata->rx_state) { /* Waiting for complete packet ? */ case ST_BT_W4_DATA: ST_KIM_DBG("Complete pkt received"); validate_firmware_response(kim_gdata->rx_skb); kim_gdata->rx_state = ST_W4_PACKET_TYPE; kim_gdata->rx_skb = NULL; continue; /* Waiting for Bluetooth event header ? */ case ST_BT_W4_EVENT_HDR: eh = (struct hci_event_hdr *)kim_gdata-> rx_skb->data; ST_KIM_DBG("Event header: evt 0x%2.2x " "plen %d", eh->evt, eh->plen); kim_check_data_len(eh->plen); continue; } /* end of switch */ } /* end of if rx_state */ switch (*ptr) { /* Bluetooth event packet? */ case HCI_EVENT_PKT: ST_KIM_DBG("Event packet"); kim_gdata->rx_state = ST_BT_W4_EVENT_HDR; kim_gdata->rx_count = HCI_EVENT_HDR_SIZE; type = HCI_EVENT_PKT; break; default: ST_KIM_DBG("unknown packet"); ptr++; count--; continue; } /* end of switch *ptr */ ptr++; count--; kim_gdata->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); if (!kim_gdata->rx_skb) { ST_KIM_ERR("can't allocate mem for new packet"); kim_gdata->rx_state = ST_W4_PACKET_TYPE; kim_gdata->rx_count = 0; return; } /* not necessary in this case */ bt_cb(kim_gdata->rx_skb)->pkt_type = type; } /* end of while count */