diff options
-rw-r--r-- | drivers/misc/ti-st/st_core.c | 355 | ||||
-rw-r--r-- | drivers/misc/ti-st/st_kim.c | 56 | ||||
-rw-r--r-- | include/linux/ti_wilink_st.h | 40 |
3 files changed, 167 insertions, 284 deletions
diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index f9aad06d1ae5..84d73c5cb74d 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c | |||
@@ -25,10 +25,9 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
27 | 27 | ||
28 | /* understand BT, FM and GPS for now */ | 28 | #include <linux/seq_file.h> |
29 | #include <net/bluetooth/bluetooth.h> | 29 | #include <linux/skbuff.h> |
30 | #include <net/bluetooth/hci_core.h> | 30 | |
31 | #include <net/bluetooth/hci.h> | ||
32 | #include <linux/ti_wilink_st.h> | 31 | #include <linux/ti_wilink_st.h> |
33 | 32 | ||
34 | /* function pointer pointing to either, | 33 | /* function pointer pointing to either, |
@@ -38,21 +37,20 @@ | |||
38 | void (*st_recv) (void*, const unsigned char*, long); | 37 | void (*st_recv) (void*, const unsigned char*, long); |
39 | 38 | ||
40 | /********************************************************************/ | 39 | /********************************************************************/ |
41 | #if 0 | 40 | static void add_channel_to_table(struct st_data_s *st_gdata, |
42 | /* internal misc functions */ | 41 | struct st_proto_s *new_proto) |
43 | bool is_protocol_list_empty(void) | ||
44 | { | 42 | { |
45 | unsigned char i = 0; | 43 | pr_info("%s: id %d\n", __func__, new_proto->chnl_id); |
46 | pr_debug(" %s ", __func__); | 44 | /* list now has the channel id as index itself */ |
47 | for (i = 0; i < ST_MAX; i++) { | 45 | st_gdata->list[new_proto->chnl_id] = new_proto; |
48 | if (st_gdata->list[i] != NULL) | 46 | } |
49 | return ST_NOTEMPTY; | 47 | |
50 | /* not empty */ | 48 | static void remove_channel_from_table(struct st_data_s *st_gdata, |
51 | } | 49 | struct st_proto_s *proto) |
52 | /* list empty */ | 50 | { |
53 | return ST_EMPTY; | 51 | pr_info("%s: id %d\n", __func__, proto->chnl_id); |
52 | st_gdata->list[proto->chnl_id] = NULL; | ||
54 | } | 53 | } |
55 | #endif | ||
56 | 54 | ||
57 | /* can be called in from | 55 | /* can be called in from |
58 | * -- KIM (during fw download) | 56 | * -- KIM (during fw download) |
@@ -82,15 +80,15 @@ int st_int_write(struct st_data_s *st_gdata, | |||
82 | * push the skb received to relevant | 80 | * push the skb received to relevant |
83 | * protocol stacks | 81 | * protocol stacks |
84 | */ | 82 | */ |
85 | void st_send_frame(enum proto_type protoid, struct st_data_s *st_gdata) | 83 | void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata) |
86 | { | 84 | { |
87 | pr_info(" %s(prot:%d) ", __func__, protoid); | 85 | pr_info(" %s(prot:%d) ", __func__, chnl_id); |
88 | 86 | ||
89 | if (unlikely | 87 | if (unlikely |
90 | (st_gdata == NULL || st_gdata->rx_skb == NULL | 88 | (st_gdata == NULL || st_gdata->rx_skb == NULL |
91 | || st_gdata->list[protoid] == NULL)) { | 89 | || st_gdata->list[chnl_id] == NULL)) { |
92 | pr_err("protocol %d not registered, no data to send?", | 90 | pr_err("chnl_id %d not registered, no data to send?", |
93 | protoid); | 91 | chnl_id); |
94 | kfree_skb(st_gdata->rx_skb); | 92 | kfree_skb(st_gdata->rx_skb); |
95 | return; | 93 | return; |
96 | } | 94 | } |
@@ -99,17 +97,17 @@ void st_send_frame(enum proto_type protoid, struct st_data_s *st_gdata) | |||
99 | * - should be just skb_queue_tail for the | 97 | * - should be just skb_queue_tail for the |
100 | * protocol stack driver | 98 | * protocol stack driver |
101 | */ | 99 | */ |
102 | if (likely(st_gdata->list[protoid]->recv != NULL)) { | 100 | if (likely(st_gdata->list[chnl_id]->recv != NULL)) { |
103 | if (unlikely | 101 | if (unlikely |
104 | (st_gdata->list[protoid]->recv | 102 | (st_gdata->list[chnl_id]->recv |
105 | (st_gdata->list[protoid]->priv_data, st_gdata->rx_skb) | 103 | (st_gdata->list[chnl_id]->priv_data, st_gdata->rx_skb) |
106 | != 0)) { | 104 | != 0)) { |
107 | pr_err(" proto stack %d's ->recv failed", protoid); | 105 | pr_err(" proto stack %d's ->recv failed", chnl_id); |
108 | kfree_skb(st_gdata->rx_skb); | 106 | kfree_skb(st_gdata->rx_skb); |
109 | return; | 107 | return; |
110 | } | 108 | } |
111 | } else { | 109 | } else { |
112 | pr_err(" proto stack %d's ->recv null", protoid); | 110 | pr_err(" proto stack %d's ->recv null", chnl_id); |
113 | kfree_skb(st_gdata->rx_skb); | 111 | kfree_skb(st_gdata->rx_skb); |
114 | } | 112 | } |
115 | return; | 113 | return; |
@@ -124,7 +122,7 @@ void st_reg_complete(struct st_data_s *st_gdata, char err) | |||
124 | { | 122 | { |
125 | unsigned char i = 0; | 123 | unsigned char i = 0; |
126 | pr_info(" %s ", __func__); | 124 | pr_info(" %s ", __func__); |
127 | for (i = 0; i < ST_MAX; i++) { | 125 | for (i = 0; i < ST_MAX_CHANNELS; i++) { |
128 | if (likely(st_gdata != NULL && st_gdata->list[i] != NULL && | 126 | if (likely(st_gdata != NULL && st_gdata->list[i] != NULL && |
129 | st_gdata->list[i]->reg_complete_cb != NULL)) | 127 | st_gdata->list[i]->reg_complete_cb != NULL)) |
130 | st_gdata->list[i]->reg_complete_cb | 128 | st_gdata->list[i]->reg_complete_cb |
@@ -133,7 +131,7 @@ void st_reg_complete(struct st_data_s *st_gdata, char err) | |||
133 | } | 131 | } |
134 | 132 | ||
135 | static inline int st_check_data_len(struct st_data_s *st_gdata, | 133 | static inline int st_check_data_len(struct st_data_s *st_gdata, |
136 | int protoid, int len) | 134 | unsigned char chnl_id, int len) |
137 | { | 135 | { |
138 | int room = skb_tailroom(st_gdata->rx_skb); | 136 | int room = skb_tailroom(st_gdata->rx_skb); |
139 | 137 | ||
@@ -144,7 +142,7 @@ static inline int st_check_data_len(struct st_data_s *st_gdata, | |||
144 | * has zero length payload. So, ask ST CORE to | 142 | * has zero length payload. So, ask ST CORE to |
145 | * forward the packet to protocol driver (BT/FM/GPS) | 143 | * forward the packet to protocol driver (BT/FM/GPS) |
146 | */ | 144 | */ |
147 | st_send_frame(protoid, st_gdata); | 145 | st_send_frame(chnl_id, st_gdata); |
148 | 146 | ||
149 | } else if (len > room) { | 147 | } else if (len > room) { |
150 | /* Received packet's payload length is larger. | 148 | /* Received packet's payload length is larger. |
@@ -157,7 +155,7 @@ static inline int st_check_data_len(struct st_data_s *st_gdata, | |||
157 | /* Packet header has non-zero payload length and | 155 | /* Packet header has non-zero payload length and |
158 | * we have enough space in created skb. Lets read | 156 | * we have enough space in created skb. Lets read |
159 | * payload data */ | 157 | * payload data */ |
160 | st_gdata->rx_state = ST_BT_W4_DATA; | 158 | st_gdata->rx_state = ST_W4_DATA; |
161 | st_gdata->rx_count = len; | 159 | st_gdata->rx_count = len; |
162 | return len; | 160 | return len; |
163 | } | 161 | } |
@@ -167,6 +165,7 @@ static inline int st_check_data_len(struct st_data_s *st_gdata, | |||
167 | st_gdata->rx_state = ST_W4_PACKET_TYPE; | 165 | st_gdata->rx_state = ST_W4_PACKET_TYPE; |
168 | st_gdata->rx_skb = NULL; | 166 | st_gdata->rx_skb = NULL; |
169 | st_gdata->rx_count = 0; | 167 | st_gdata->rx_count = 0; |
168 | st_gdata->rx_chnl = 0; | ||
170 | 169 | ||
171 | return 0; | 170 | return 0; |
172 | } | 171 | } |
@@ -208,13 +207,10 @@ void st_int_recv(void *disc_data, | |||
208 | const unsigned char *data, long count) | 207 | const unsigned char *data, long count) |
209 | { | 208 | { |
210 | char *ptr; | 209 | char *ptr; |
211 | struct hci_event_hdr *eh; | 210 | struct st_proto_s *proto; |
212 | struct hci_acl_hdr *ah; | 211 | unsigned short payload_len = 0; |
213 | struct hci_sco_hdr *sh; | 212 | int len = 0, type = 0; |
214 | struct fm_event_hdr *fm; | 213 | unsigned char *plen; |
215 | struct gps_event_hdr *gps; | ||
216 | int len = 0, type = 0, dlen = 0; | ||
217 | static enum proto_type protoid = ST_MAX; | ||
218 | struct st_data_s *st_gdata = (struct st_data_s *)disc_data; | 214 | struct st_data_s *st_gdata = (struct st_data_s *)disc_data; |
219 | 215 | ||
220 | ptr = (char *)data; | 216 | ptr = (char *)data; |
@@ -242,64 +238,36 @@ void st_int_recv(void *disc_data, | |||
242 | 238 | ||
243 | /* Check ST RX state machine , where are we? */ | 239 | /* Check ST RX state machine , where are we? */ |
244 | switch (st_gdata->rx_state) { | 240 | switch (st_gdata->rx_state) { |
245 | 241 | /* Waiting for complete packet ? */ | |
246 | /* Waiting for complete packet ? */ | 242 | case ST_W4_DATA: |
247 | case ST_BT_W4_DATA: | ||
248 | pr_debug("Complete pkt received"); | 243 | pr_debug("Complete pkt received"); |
249 | |||
250 | /* Ask ST CORE to forward | 244 | /* Ask ST CORE to forward |
251 | * the packet to protocol driver */ | 245 | * the packet to protocol driver */ |
252 | st_send_frame(protoid, st_gdata); | 246 | st_send_frame(st_gdata->rx_chnl, st_gdata); |
253 | 247 | ||
254 | st_gdata->rx_state = ST_W4_PACKET_TYPE; | 248 | st_gdata->rx_state = ST_W4_PACKET_TYPE; |
255 | st_gdata->rx_skb = NULL; | 249 | st_gdata->rx_skb = NULL; |
256 | protoid = ST_MAX; /* is this required ? */ | ||
257 | continue; | ||
258 | |||
259 | /* Waiting for Bluetooth event header ? */ | ||
260 | case ST_BT_W4_EVENT_HDR: | ||
261 | eh = (struct hci_event_hdr *)st_gdata->rx_skb-> | ||
262 | data; | ||
263 | |||
264 | pr_debug("Event header: evt 0x%2.2x" | ||
265 | "plen %d", eh->evt, eh->plen); | ||
266 | |||
267 | st_check_data_len(st_gdata, protoid, eh->plen); | ||
268 | continue; | ||
269 | |||
270 | /* Waiting for Bluetooth acl header ? */ | ||
271 | case ST_BT_W4_ACL_HDR: | ||
272 | ah = (struct hci_acl_hdr *)st_gdata->rx_skb-> | ||
273 | data; | ||
274 | dlen = __le16_to_cpu(ah->dlen); | ||
275 | |||
276 | pr_info("ACL header: dlen %d", dlen); | ||
277 | |||
278 | st_check_data_len(st_gdata, protoid, dlen); | ||
279 | continue; | ||
280 | |||
281 | /* Waiting for Bluetooth sco header ? */ | ||
282 | case ST_BT_W4_SCO_HDR: | ||
283 | sh = (struct hci_sco_hdr *)st_gdata->rx_skb-> | ||
284 | data; | ||
285 | |||
286 | pr_info("SCO header: dlen %d", sh->dlen); | ||
287 | |||
288 | st_check_data_len(st_gdata, protoid, sh->dlen); | ||
289 | continue; | ||
290 | case ST_FM_W4_EVENT_HDR: | ||
291 | fm = (struct fm_event_hdr *)st_gdata->rx_skb-> | ||
292 | data; | ||
293 | pr_info("FM Header: "); | ||
294 | st_check_data_len(st_gdata, ST_FM, fm->plen); | ||
295 | continue; | 250 | continue; |
296 | /* TODO : Add GPS packet machine logic here */ | 251 | /* parse the header to know details */ |
297 | case ST_GPS_W4_EVENT_HDR: | 252 | case ST_W4_HEADER: |
298 | /* [0x09 pkt hdr][R/W byte][2 byte len] */ | 253 | proto = st_gdata->list[st_gdata->rx_chnl]; |
299 | gps = (struct gps_event_hdr *)st_gdata->rx_skb-> | 254 | plen = |
300 | data; | 255 | &st_gdata->rx_skb->data |
301 | pr_info("GPS Header: "); | 256 | [proto->offset_len_in_hdr]; |
302 | st_check_data_len(st_gdata, ST_GPS, gps->plen); | 257 | pr_info("plen pointing to %x\n", *plen); |
258 | if (proto->len_size == 1)/* 1 byte len field */ | ||
259 | payload_len = *(unsigned char *)plen; | ||
260 | else if (proto->len_size == 2) | ||
261 | payload_len = | ||
262 | __le16_to_cpu(*(unsigned short *)plen); | ||
263 | else | ||
264 | pr_info("%s: invalid length " | ||
265 | "for id %d\n", | ||
266 | __func__, proto->chnl_id); | ||
267 | st_check_data_len(st_gdata, proto->chnl_id, | ||
268 | payload_len); | ||
269 | pr_info("off %d, pay len %d\n", | ||
270 | proto->offset_len_in_hdr, payload_len); | ||
303 | continue; | 271 | continue; |
304 | } /* end of switch rx_state */ | 272 | } /* end of switch rx_state */ |
305 | } | 273 | } |
@@ -308,51 +276,6 @@ void st_int_recv(void *disc_data, | |||
308 | /* Check first byte of packet and identify module | 276 | /* Check first byte of packet and identify module |
309 | * owner (BT/FM/GPS) */ | 277 | * owner (BT/FM/GPS) */ |
310 | switch (*ptr) { | 278 | switch (*ptr) { |
311 | |||
312 | /* Bluetooth event packet? */ | ||
313 | case HCI_EVENT_PKT: | ||
314 | pr_info("Event packet"); | ||
315 | st_gdata->rx_state = ST_BT_W4_EVENT_HDR; | ||
316 | st_gdata->rx_count = HCI_EVENT_HDR_SIZE; | ||
317 | type = HCI_EVENT_PKT; | ||
318 | protoid = ST_BT; | ||
319 | break; | ||
320 | |||
321 | /* Bluetooth acl packet? */ | ||
322 | case HCI_ACLDATA_PKT: | ||
323 | pr_info("ACL packet"); | ||
324 | st_gdata->rx_state = ST_BT_W4_ACL_HDR; | ||
325 | st_gdata->rx_count = HCI_ACL_HDR_SIZE; | ||
326 | type = HCI_ACLDATA_PKT; | ||
327 | protoid = ST_BT; | ||
328 | break; | ||
329 | |||
330 | /* Bluetooth sco packet? */ | ||
331 | case HCI_SCODATA_PKT: | ||
332 | pr_info("SCO packet"); | ||
333 | st_gdata->rx_state = ST_BT_W4_SCO_HDR; | ||
334 | st_gdata->rx_count = HCI_SCO_HDR_SIZE; | ||
335 | type = HCI_SCODATA_PKT; | ||
336 | protoid = ST_BT; | ||
337 | break; | ||
338 | |||
339 | /* Channel 8(FM) packet? */ | ||
340 | case ST_FM_CH8_PKT: | ||
341 | pr_info("FM CH8 packet"); | ||
342 | type = ST_FM_CH8_PKT; | ||
343 | st_gdata->rx_state = ST_FM_W4_EVENT_HDR; | ||
344 | st_gdata->rx_count = FM_EVENT_HDR_SIZE; | ||
345 | protoid = ST_FM; | ||
346 | break; | ||
347 | |||
348 | /* Channel 9(GPS) packet? */ | ||
349 | case 0x9: /*ST_LL_GPS_CH9_PKT */ | ||
350 | pr_info("GPS CH9 packet"); | ||
351 | type = 0x9; /* ST_LL_GPS_CH9_PKT; */ | ||
352 | protoid = ST_GPS; | ||
353 | st_gdata->rx_state = ST_GPS_W4_EVENT_HDR; | ||
354 | st_gdata->rx_count = 3; /* GPS_EVENT_HDR_SIZE -1*/ | ||
355 | break; | ||
356 | case LL_SLEEP_IND: | 279 | case LL_SLEEP_IND: |
357 | case LL_SLEEP_ACK: | 280 | case LL_SLEEP_ACK: |
358 | case LL_WAKE_UP_IND: | 281 | case LL_WAKE_UP_IND: |
@@ -373,57 +296,22 @@ void st_int_recv(void *disc_data, | |||
373 | continue; | 296 | continue; |
374 | /* Unknow packet? */ | 297 | /* Unknow packet? */ |
375 | default: | 298 | default: |
376 | pr_err("Unknown packet type %2.2x", (__u8) *ptr); | 299 | type = *ptr; |
377 | ptr++; | 300 | st_gdata->rx_skb = alloc_skb( |
378 | count--; | 301 | st_gdata->list[type]->max_frame_size, |
379 | continue; | 302 | GFP_ATOMIC); |
303 | skb_reserve(st_gdata->rx_skb, | ||
304 | st_gdata->list[type]->reserve); | ||
305 | /* next 2 required for BT only */ | ||
306 | st_gdata->rx_skb->cb[0] = type; /*pkt_type*/ | ||
307 | st_gdata->rx_skb->cb[1] = 0; /*incoming*/ | ||
308 | st_gdata->rx_chnl = *ptr; | ||
309 | st_gdata->rx_state = ST_W4_HEADER; | ||
310 | st_gdata->rx_count = st_gdata->list[type]->hdr_len; | ||
311 | pr_info("rx_count %ld\n", st_gdata->rx_count); | ||
380 | }; | 312 | }; |
381 | ptr++; | 313 | ptr++; |
382 | count--; | 314 | count--; |
383 | |||
384 | switch (protoid) { | ||
385 | case ST_BT: | ||
386 | /* Allocate new packet to hold received data */ | ||
387 | st_gdata->rx_skb = | ||
388 | bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); | ||
389 | if (!st_gdata->rx_skb) { | ||
390 | pr_err("Can't allocate mem for new packet"); | ||
391 | st_gdata->rx_state = ST_W4_PACKET_TYPE; | ||
392 | st_gdata->rx_count = 0; | ||
393 | return; | ||
394 | } | ||
395 | bt_cb(st_gdata->rx_skb)->pkt_type = type; | ||
396 | break; | ||
397 | case ST_FM: /* for FM */ | ||
398 | st_gdata->rx_skb = | ||
399 | alloc_skb(FM_MAX_FRAME_SIZE, GFP_ATOMIC); | ||
400 | if (!st_gdata->rx_skb) { | ||
401 | pr_err("Can't allocate mem for new packet"); | ||
402 | st_gdata->rx_state = ST_W4_PACKET_TYPE; | ||
403 | st_gdata->rx_count = 0; | ||
404 | return; | ||
405 | } | ||
406 | /* place holder 0x08 */ | ||
407 | skb_reserve(st_gdata->rx_skb, 1); | ||
408 | st_gdata->rx_skb->cb[0] = ST_FM_CH8_PKT; | ||
409 | break; | ||
410 | case ST_GPS: | ||
411 | /* for GPS */ | ||
412 | st_gdata->rx_skb = | ||
413 | alloc_skb(100 /*GPS_MAX_FRAME_SIZE */ , GFP_ATOMIC); | ||
414 | if (!st_gdata->rx_skb) { | ||
415 | pr_err("Can't allocate mem for new packet"); | ||
416 | st_gdata->rx_state = ST_W4_PACKET_TYPE; | ||
417 | st_gdata->rx_count = 0; | ||
418 | return; | ||
419 | } | ||
420 | /* place holder 0x09 */ | ||
421 | skb_reserve(st_gdata->rx_skb, 1); | ||
422 | st_gdata->rx_skb->cb[0] = 0x09; /*ST_GPS_CH9_PKT; */ | ||
423 | break; | ||
424 | case ST_MAX: | ||
425 | break; | ||
426 | } | ||
427 | } | 315 | } |
428 | pr_debug("done %s", __func__); | 316 | pr_debug("done %s", __func__); |
429 | return; | 317 | return; |
@@ -565,20 +453,28 @@ long st_register(struct st_proto_s *new_proto) | |||
565 | unsigned long flags = 0; | 453 | unsigned long flags = 0; |
566 | 454 | ||
567 | st_kim_ref(&st_gdata, 0); | 455 | st_kim_ref(&st_gdata, 0); |
568 | pr_info("%s(%d) ", __func__, new_proto->type); | 456 | pr_info("%s(%d) ", __func__, new_proto->chnl_id); |
569 | if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL | 457 | if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL |
570 | || new_proto->reg_complete_cb == NULL) { | 458 | || new_proto->reg_complete_cb == NULL) { |
571 | pr_err("gdata/new_proto/recv or reg_complete_cb not ready"); | 459 | pr_err("gdata/new_proto/recv or reg_complete_cb not ready"); |
460 | if (st_gdata == NULL) | ||
461 | pr_err("error 1\n"); | ||
462 | if (new_proto == NULL) | ||
463 | pr_err("error 2\n"); | ||
464 | if (new_proto->recv == NULL) | ||
465 | pr_err("error 3\n"); | ||
466 | if (new_proto->reg_complete_cb == NULL) | ||
467 | pr_err("erro 4\n"); | ||
572 | return -1; | 468 | return -1; |
573 | } | 469 | } |
574 | 470 | ||
575 | if (new_proto->type < ST_BT || new_proto->type >= ST_MAX) { | 471 | if (new_proto->chnl_id >= ST_MAX_CHANNELS) { |
576 | pr_err("protocol %d not supported", new_proto->type); | 472 | pr_err("chnl_id %d not supported", new_proto->chnl_id); |
577 | return -EPROTONOSUPPORT; | 473 | return -EPROTONOSUPPORT; |
578 | } | 474 | } |
579 | 475 | ||
580 | if (st_gdata->list[new_proto->type] != NULL) { | 476 | if (st_gdata->list[new_proto->chnl_id] != NULL) { |
581 | pr_err("protocol %d already registered", new_proto->type); | 477 | pr_err("chnl_id %d already registered", new_proto->chnl_id); |
582 | return -EALREADY; | 478 | return -EALREADY; |
583 | } | 479 | } |
584 | 480 | ||
@@ -586,11 +482,11 @@ long st_register(struct st_proto_s *new_proto) | |||
586 | spin_lock_irqsave(&st_gdata->lock, flags); | 482 | spin_lock_irqsave(&st_gdata->lock, flags); |
587 | 483 | ||
588 | if (test_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state)) { | 484 | if (test_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state)) { |
589 | pr_info(" ST_REG_IN_PROGRESS:%d ", new_proto->type); | 485 | pr_info(" ST_REG_IN_PROGRESS:%d ", new_proto->chnl_id); |
590 | /* fw download in progress */ | 486 | /* fw download in progress */ |
591 | st_kim_chip_toggle(new_proto->type, KIM_GPIO_ACTIVE); | 487 | st_kim_chip_toggle(new_proto->chnl_id, KIM_GPIO_ACTIVE); |
592 | 488 | ||
593 | st_gdata->list[new_proto->type] = new_proto; | 489 | add_channel_to_table(st_gdata, new_proto); |
594 | st_gdata->protos_registered++; | 490 | st_gdata->protos_registered++; |
595 | new_proto->write = st_write; | 491 | new_proto->write = st_write; |
596 | 492 | ||
@@ -598,7 +494,7 @@ long st_register(struct st_proto_s *new_proto) | |||
598 | spin_unlock_irqrestore(&st_gdata->lock, flags); | 494 | spin_unlock_irqrestore(&st_gdata->lock, flags); |
599 | return -EINPROGRESS; | 495 | return -EINPROGRESS; |
600 | } else if (st_gdata->protos_registered == ST_EMPTY) { | 496 | } else if (st_gdata->protos_registered == ST_EMPTY) { |
601 | pr_info(" protocol list empty :%d ", new_proto->type); | 497 | pr_info(" chnl_id list empty :%d ", new_proto->chnl_id); |
602 | set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); | 498 | set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); |
603 | st_recv = st_kim_recv; | 499 | st_recv = st_kim_recv; |
604 | 500 | ||
@@ -622,9 +518,9 @@ long st_register(struct st_proto_s *new_proto) | |||
622 | return -1; | 518 | return -1; |
623 | } | 519 | } |
624 | 520 | ||
625 | /* the protocol might require other gpios to be toggled | 521 | /* the chnl_id might require other gpios to be toggled |
626 | */ | 522 | */ |
627 | st_kim_chip_toggle(new_proto->type, KIM_GPIO_ACTIVE); | 523 | st_kim_chip_toggle(new_proto->chnl_id, KIM_GPIO_ACTIVE); |
628 | 524 | ||
629 | clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); | 525 | clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); |
630 | st_recv = st_int_recv; | 526 | st_recv = st_int_recv; |
@@ -642,14 +538,14 @@ long st_register(struct st_proto_s *new_proto) | |||
642 | /* check for already registered once more, | 538 | /* check for already registered once more, |
643 | * since the above check is old | 539 | * since the above check is old |
644 | */ | 540 | */ |
645 | if (st_gdata->list[new_proto->type] != NULL) { | 541 | if (st_gdata->list[new_proto->chnl_id] != NULL) { |
646 | pr_err(" proto %d already registered ", | 542 | pr_err(" proto %d already registered ", |
647 | new_proto->type); | 543 | new_proto->chnl_id); |
648 | return -EALREADY; | 544 | return -EALREADY; |
649 | } | 545 | } |
650 | 546 | ||
651 | spin_lock_irqsave(&st_gdata->lock, flags); | 547 | spin_lock_irqsave(&st_gdata->lock, flags); |
652 | st_gdata->list[new_proto->type] = new_proto; | 548 | add_channel_to_table(st_gdata, new_proto); |
653 | st_gdata->protos_registered++; | 549 | st_gdata->protos_registered++; |
654 | new_proto->write = st_write; | 550 | new_proto->write = st_write; |
655 | spin_unlock_irqrestore(&st_gdata->lock, flags); | 551 | spin_unlock_irqrestore(&st_gdata->lock, flags); |
@@ -657,22 +553,7 @@ long st_register(struct st_proto_s *new_proto) | |||
657 | } | 553 | } |
658 | /* if fw is already downloaded & new stack registers protocol */ | 554 | /* if fw is already downloaded & new stack registers protocol */ |
659 | else { | 555 | else { |
660 | switch (new_proto->type) { | 556 | add_channel_to_table(st_gdata, new_proto); |
661 | case ST_BT: | ||
662 | /* do nothing */ | ||
663 | break; | ||
664 | case ST_FM: | ||
665 | case ST_GPS: | ||
666 | st_kim_chip_toggle(new_proto->type, KIM_GPIO_ACTIVE); | ||
667 | break; | ||
668 | case ST_MAX: | ||
669 | default: | ||
670 | pr_err("%d protocol not supported", | ||
671 | new_proto->type); | ||
672 | spin_unlock_irqrestore(&st_gdata->lock, flags); | ||
673 | return -EPROTONOSUPPORT; | ||
674 | } | ||
675 | st_gdata->list[new_proto->type] = new_proto; | ||
676 | st_gdata->protos_registered++; | 557 | st_gdata->protos_registered++; |
677 | new_proto->write = st_write; | 558 | new_proto->write = st_write; |
678 | 559 | ||
@@ -680,48 +561,48 @@ long st_register(struct st_proto_s *new_proto) | |||
680 | spin_unlock_irqrestore(&st_gdata->lock, flags); | 561 | spin_unlock_irqrestore(&st_gdata->lock, flags); |
681 | return err; | 562 | return err; |
682 | } | 563 | } |
683 | pr_debug("done %s(%d) ", __func__, new_proto->type); | 564 | pr_debug("done %s(%d) ", __func__, new_proto->chnl_id); |
684 | } | 565 | } |
685 | EXPORT_SYMBOL_GPL(st_register); | 566 | EXPORT_SYMBOL_GPL(st_register); |
686 | 567 | ||
687 | /* to unregister a protocol - | 568 | /* to unregister a protocol - |
688 | * to be called from protocol stack driver | 569 | * to be called from protocol stack driver |
689 | */ | 570 | */ |
690 | long st_unregister(enum proto_type type) | 571 | long st_unregister(struct st_proto_s *proto) |
691 | { | 572 | { |
692 | long err = 0; | 573 | long err = 0; |
693 | unsigned long flags = 0; | 574 | unsigned long flags = 0; |
694 | struct st_data_s *st_gdata; | 575 | struct st_data_s *st_gdata; |
695 | 576 | ||
696 | pr_debug("%s: %d ", __func__, type); | 577 | pr_debug("%s: %d ", __func__, proto->chnl_id); |
697 | 578 | ||
698 | st_kim_ref(&st_gdata, 0); | 579 | st_kim_ref(&st_gdata, 0); |
699 | if (type < ST_BT || type >= ST_MAX) { | 580 | if (proto->chnl_id >= ST_MAX_CHANNELS) { |
700 | pr_err(" protocol %d not supported", type); | 581 | pr_err(" chnl_id %d not supported", proto->chnl_id); |
701 | return -EPROTONOSUPPORT; | 582 | return -EPROTONOSUPPORT; |
702 | } | 583 | } |
703 | 584 | ||
704 | spin_lock_irqsave(&st_gdata->lock, flags); | 585 | spin_lock_irqsave(&st_gdata->lock, flags); |
705 | 586 | ||
706 | if (st_gdata->list[type] == NULL) { | 587 | if (st_gdata->list[proto->chnl_id] == NULL) { |
707 | pr_err(" protocol %d not registered", type); | 588 | pr_err(" chnl_id %d not registered", proto->chnl_id); |
708 | spin_unlock_irqrestore(&st_gdata->lock, flags); | 589 | spin_unlock_irqrestore(&st_gdata->lock, flags); |
709 | return -EPROTONOSUPPORT; | 590 | return -EPROTONOSUPPORT; |
710 | } | 591 | } |
711 | 592 | ||
712 | st_gdata->protos_registered--; | 593 | st_gdata->protos_registered--; |
713 | st_gdata->list[type] = NULL; | 594 | remove_channel_from_table(st_gdata, proto); |
714 | 595 | ||
715 | /* kim ignores BT in the below function | 596 | /* kim ignores BT in the below function |
716 | * and handles the rest, BT is toggled | 597 | * and handles the rest, BT is toggled |
717 | * only in kim_start and kim_stop | 598 | * only in kim_start and kim_stop |
718 | */ | 599 | */ |
719 | st_kim_chip_toggle(type, KIM_GPIO_INACTIVE); | 600 | st_kim_chip_toggle(proto->chnl_id, KIM_GPIO_INACTIVE); |
720 | spin_unlock_irqrestore(&st_gdata->lock, flags); | 601 | spin_unlock_irqrestore(&st_gdata->lock, flags); |
721 | 602 | ||
722 | if ((st_gdata->protos_registered == ST_EMPTY) && | 603 | if ((st_gdata->protos_registered == ST_EMPTY) && |
723 | (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { | 604 | (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { |
724 | pr_info(" all protocols unregistered "); | 605 | pr_info(" all chnl_ids unregistered "); |
725 | 606 | ||
726 | /* stop traffic on tty */ | 607 | /* stop traffic on tty */ |
727 | if (st_gdata->tty) { | 608 | if (st_gdata->tty) { |
@@ -729,7 +610,7 @@ long st_unregister(enum proto_type type) | |||
729 | stop_tty(st_gdata->tty); | 610 | stop_tty(st_gdata->tty); |
730 | } | 611 | } |
731 | 612 | ||
732 | /* all protocols now unregistered */ | 613 | /* all chnl_ids now unregistered */ |
733 | st_kim_stop(st_gdata->kim_data); | 614 | st_kim_stop(st_gdata->kim_data); |
734 | /* disable ST LL */ | 615 | /* disable ST LL */ |
735 | st_ll_disable(st_gdata); | 616 | st_ll_disable(st_gdata); |
@@ -745,7 +626,7 @@ long st_write(struct sk_buff *skb) | |||
745 | { | 626 | { |
746 | struct st_data_s *st_gdata; | 627 | struct st_data_s *st_gdata; |
747 | #ifdef DEBUG | 628 | #ifdef DEBUG |
748 | enum proto_type protoid = ST_MAX; | 629 | unsigned char chnl_id = ST_MAX_CHANNELS; |
749 | #endif | 630 | #endif |
750 | long len; | 631 | long len; |
751 | 632 | ||
@@ -756,22 +637,10 @@ long st_write(struct sk_buff *skb) | |||
756 | return -1; | 637 | return -1; |
757 | } | 638 | } |
758 | #ifdef DEBUG /* open-up skb to read the 1st byte */ | 639 | #ifdef DEBUG /* open-up skb to read the 1st byte */ |
759 | switch (skb->data[0]) { | 640 | chnl_id = skb->data[0]; |
760 | case HCI_COMMAND_PKT: | 641 | if (unlikely(st_gdata->list[chnl_id] == NULL)) { |
761 | case HCI_ACLDATA_PKT: | 642 | pr_err(" chnl_id %d not registered, and writing? ", |
762 | case HCI_SCODATA_PKT: | 643 | chnl_id); |
763 | protoid = ST_BT; | ||
764 | break; | ||
765 | case ST_FM_CH8_PKT: | ||
766 | protoid = ST_FM; | ||
767 | break; | ||
768 | case 0x09: | ||
769 | protoid = ST_GPS; | ||
770 | break; | ||
771 | } | ||
772 | if (unlikely(st_gdata->list[protoid] == NULL)) { | ||
773 | pr_err(" protocol %d not registered, and writing? ", | ||
774 | protoid); | ||
775 | return -1; | 644 | return -1; |
776 | } | 645 | } |
777 | #endif | 646 | #endif |
@@ -824,7 +693,7 @@ static int st_tty_open(struct tty_struct *tty) | |||
824 | 693 | ||
825 | static void st_tty_close(struct tty_struct *tty) | 694 | static void st_tty_close(struct tty_struct *tty) |
826 | { | 695 | { |
827 | unsigned char i = ST_MAX; | 696 | unsigned char i = ST_MAX_CHANNELS; |
828 | unsigned long flags = 0; | 697 | unsigned long flags = 0; |
829 | struct st_data_s *st_gdata = tty->disc_data; | 698 | struct st_data_s *st_gdata = tty->disc_data; |
830 | 699 | ||
@@ -835,7 +704,7 @@ static void st_tty_close(struct tty_struct *tty) | |||
835 | * un-installed for some reason - what should be done ? | 704 | * un-installed for some reason - what should be done ? |
836 | */ | 705 | */ |
837 | spin_lock_irqsave(&st_gdata->lock, flags); | 706 | spin_lock_irqsave(&st_gdata->lock, flags); |
838 | for (i = ST_BT; i < ST_MAX; i++) { | 707 | for (i = ST_BT; i < ST_MAX_CHANNELS; i++) { |
839 | if (st_gdata->list[i] != NULL) | 708 | if (st_gdata->list[i] != NULL) |
840 | pr_err("%d not un-registered", i); | 709 | pr_err("%d not un-registered", i); |
841 | st_gdata->list[i] = NULL; | 710 | st_gdata->list[i] = NULL; |
@@ -869,7 +738,7 @@ static void st_tty_close(struct tty_struct *tty) | |||
869 | static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, | 738 | static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, |
870 | char *tty_flags, int count) | 739 | char *tty_flags, int count) |
871 | { | 740 | { |
872 | 741 | #define VERBOSE | |
873 | #ifdef VERBOSE | 742 | #ifdef VERBOSE |
874 | print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, | 743 | print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, |
875 | 16, 1, data, count, 0); | 744 | 16, 1, data, count, 0); |
diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 73b6c8b0e869..707c85826417 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c | |||
@@ -32,11 +32,7 @@ | |||
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <linux/rfkill.h> | 33 | #include <linux/rfkill.h> |
34 | 34 | ||
35 | /* understand BT events for fw response */ | 35 | #include <linux/skbuff.h> |
36 | #include <net/bluetooth/bluetooth.h> | ||
37 | #include <net/bluetooth/hci_core.h> | ||
38 | #include <net/bluetooth/hci.h> | ||
39 | |||
40 | #include <linux/ti_wilink_st.h> | 36 | #include <linux/ti_wilink_st.h> |
41 | 37 | ||
42 | 38 | ||
@@ -134,7 +130,7 @@ static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len) | |||
134 | /* Packet header has non-zero payload length and | 130 | /* Packet header has non-zero payload length and |
135 | * we have enough space in created skb. Lets read | 131 | * we have enough space in created skb. Lets read |
136 | * payload data */ | 132 | * payload data */ |
137 | kim_gdata->rx_state = ST_BT_W4_DATA; | 133 | kim_gdata->rx_state = ST_W4_DATA; |
138 | kim_gdata->rx_count = len; | 134 | kim_gdata->rx_count = len; |
139 | return len; | 135 | return len; |
140 | } | 136 | } |
@@ -158,8 +154,8 @@ void kim_int_recv(struct kim_data_s *kim_gdata, | |||
158 | const unsigned char *data, long count) | 154 | const unsigned char *data, long count) |
159 | { | 155 | { |
160 | const unsigned char *ptr; | 156 | const unsigned char *ptr; |
161 | struct hci_event_hdr *eh; | ||
162 | int len = 0, type = 0; | 157 | int len = 0, type = 0; |
158 | unsigned char *plen; | ||
163 | 159 | ||
164 | pr_debug("%s", __func__); | 160 | pr_debug("%s", __func__); |
165 | /* Decode received bytes here */ | 161 | /* Decode received bytes here */ |
@@ -183,29 +179,27 @@ void kim_int_recv(struct kim_data_s *kim_gdata, | |||
183 | /* Check ST RX state machine , where are we? */ | 179 | /* Check ST RX state machine , where are we? */ |
184 | switch (kim_gdata->rx_state) { | 180 | switch (kim_gdata->rx_state) { |
185 | /* Waiting for complete packet ? */ | 181 | /* Waiting for complete packet ? */ |
186 | case ST_BT_W4_DATA: | 182 | case ST_W4_DATA: |
187 | pr_debug("Complete pkt received"); | 183 | pr_debug("Complete pkt received"); |
188 | validate_firmware_response(kim_gdata); | 184 | validate_firmware_response(kim_gdata); |
189 | kim_gdata->rx_state = ST_W4_PACKET_TYPE; | 185 | kim_gdata->rx_state = ST_W4_PACKET_TYPE; |
190 | kim_gdata->rx_skb = NULL; | 186 | kim_gdata->rx_skb = NULL; |
191 | continue; | 187 | continue; |
192 | /* Waiting for Bluetooth event header ? */ | 188 | /* Waiting for Bluetooth event header ? */ |
193 | case ST_BT_W4_EVENT_HDR: | 189 | case ST_W4_HEADER: |
194 | eh = (struct hci_event_hdr *)kim_gdata-> | 190 | plen = |
195 | rx_skb->data; | 191 | (unsigned char *)&kim_gdata->rx_skb->data[1]; |
196 | pr_debug("Event header: evt 0x%2.2x" | 192 | pr_debug("event hdr: plen 0x%02x\n", *plen); |
197 | "plen %d", eh->evt, eh->plen); | 193 | kim_check_data_len(kim_gdata, *plen); |
198 | kim_check_data_len(kim_gdata, eh->plen); | ||
199 | continue; | 194 | continue; |
200 | } /* end of switch */ | 195 | } /* end of switch */ |
201 | } /* end of if rx_state */ | 196 | } /* end of if rx_state */ |
202 | switch (*ptr) { | 197 | switch (*ptr) { |
203 | /* Bluetooth event packet? */ | 198 | /* Bluetooth event packet? */ |
204 | case HCI_EVENT_PKT: | 199 | case 0x04: |
205 | pr_info("Event packet"); | 200 | kim_gdata->rx_state = ST_W4_HEADER; |
206 | kim_gdata->rx_state = ST_BT_W4_EVENT_HDR; | 201 | kim_gdata->rx_count = 2; |
207 | kim_gdata->rx_count = HCI_EVENT_HDR_SIZE; | 202 | type = *ptr; |
208 | type = HCI_EVENT_PKT; | ||
209 | break; | 203 | break; |
210 | default: | 204 | default: |
211 | pr_info("unknown packet"); | 205 | pr_info("unknown packet"); |
@@ -216,16 +210,18 @@ void kim_int_recv(struct kim_data_s *kim_gdata, | |||
216 | ptr++; | 210 | ptr++; |
217 | count--; | 211 | count--; |
218 | kim_gdata->rx_skb = | 212 | kim_gdata->rx_skb = |
219 | bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); | 213 | alloc_skb(1024+8, GFP_ATOMIC); |
220 | if (!kim_gdata->rx_skb) { | 214 | if (!kim_gdata->rx_skb) { |
221 | pr_err("can't allocate mem for new packet"); | 215 | pr_err("can't allocate mem for new packet"); |
222 | kim_gdata->rx_state = ST_W4_PACKET_TYPE; | 216 | kim_gdata->rx_state = ST_W4_PACKET_TYPE; |
223 | kim_gdata->rx_count = 0; | 217 | kim_gdata->rx_count = 0; |
224 | return; | 218 | return; |
225 | } | 219 | } |
226 | bt_cb(kim_gdata->rx_skb)->pkt_type = type; | 220 | skb_reserve(kim_gdata->rx_skb, 8); |
221 | kim_gdata->rx_skb->cb[0] = 4; | ||
222 | kim_gdata->rx_skb->cb[1] = 0; | ||
223 | |||
227 | } | 224 | } |
228 | pr_info("done %s", __func__); | ||
229 | return; | 225 | return; |
230 | } | 226 | } |
231 | 227 | ||
@@ -398,7 +394,7 @@ void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state) | |||
398 | gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_LOW); | 394 | gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_LOW); |
399 | break; | 395 | break; |
400 | 396 | ||
401 | case ST_MAX: | 397 | case ST_MAX_CHANNELS: |
402 | default: | 398 | default: |
403 | break; | 399 | break; |
404 | } | 400 | } |
@@ -416,7 +412,6 @@ void st_kim_recv(void *disc_data, const unsigned char *data, long count) | |||
416 | struct st_data_s *st_gdata = (struct st_data_s *)disc_data; | 412 | struct st_data_s *st_gdata = (struct st_data_s *)disc_data; |
417 | struct kim_data_s *kim_gdata = st_gdata->kim_data; | 413 | struct kim_data_s *kim_gdata = st_gdata->kim_data; |
418 | 414 | ||
419 | pr_info(" %s ", __func__); | ||
420 | /* copy to local buffer */ | 415 | /* copy to local buffer */ |
421 | if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) { | 416 | if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) { |
422 | /* must be the read_ver_cmd */ | 417 | /* must be the read_ver_cmd */ |
@@ -578,7 +573,7 @@ static int kim_toggle_radio(void *data, bool blocked) | |||
578 | else | 573 | else |
579 | st_kim_chip_toggle(type, KIM_GPIO_ACTIVE); | 574 | st_kim_chip_toggle(type, KIM_GPIO_ACTIVE); |
580 | break; | 575 | break; |
581 | case ST_MAX: | 576 | case ST_MAX_CHANNELS: |
582 | pr_err(" wrong proto type "); | 577 | pr_err(" wrong proto type "); |
583 | break; | 578 | break; |
584 | } | 579 | } |
@@ -664,12 +659,13 @@ static int kim_probe(struct platform_device *pdev) | |||
664 | /* refer to itself */ | 659 | /* refer to itself */ |
665 | kim_gdata->core_data->kim_data = kim_gdata; | 660 | kim_gdata->core_data->kim_data = kim_gdata; |
666 | 661 | ||
667 | for (proto = 0; proto < ST_MAX; proto++) { | 662 | for (proto = 0; proto < ST_MAX_CHANNELS; proto++) { |
668 | kim_gdata->gpios[proto] = gpios[proto]; | 663 | kim_gdata->gpios[proto] = gpios[proto]; |
669 | pr_info(" %ld gpio to be requested", gpios[proto]); | 664 | pr_info(" %ld gpio to be requested", gpios[proto]); |
670 | } | 665 | } |
671 | 666 | ||
672 | for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) { | 667 | for (proto = 0; (proto < ST_MAX_CHANNELS) |
668 | && (gpios[proto] != -1); proto++) { | ||
673 | /* Claim the Bluetooth/FM/GPIO | 669 | /* Claim the Bluetooth/FM/GPIO |
674 | * nShutdown gpio from the system | 670 | * nShutdown gpio from the system |
675 | */ | 671 | */ |
@@ -704,7 +700,8 @@ static int kim_probe(struct platform_device *pdev) | |||
704 | init_completion(&kim_gdata->kim_rcvd); | 700 | init_completion(&kim_gdata->kim_rcvd); |
705 | init_completion(&kim_gdata->ldisc_installed); | 701 | init_completion(&kim_gdata->ldisc_installed); |
706 | 702 | ||
707 | for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) { | 703 | for (proto = 0; (proto < ST_MAX_CHANNELS) |
704 | && (gpios[proto] != -1); proto++) { | ||
708 | /* TODO: should all types be rfkill_type_bt ? */ | 705 | /* TODO: should all types be rfkill_type_bt ? */ |
709 | kim_gdata->rf_protos[proto] = proto; | 706 | kim_gdata->rf_protos[proto] = proto; |
710 | kim_gdata->rfkill[proto] = rfkill_alloc(protocol_names[proto], | 707 | kim_gdata->rfkill[proto] = rfkill_alloc(protocol_names[proto], |
@@ -752,7 +749,8 @@ static int kim_remove(struct platform_device *pdev) | |||
752 | 749 | ||
753 | kim_gdata = dev_get_drvdata(&pdev->dev); | 750 | kim_gdata = dev_get_drvdata(&pdev->dev); |
754 | 751 | ||
755 | for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) { | 752 | for (proto = 0; (proto < ST_MAX_CHANNELS) |
753 | && (gpios[proto] != -1); proto++) { | ||
756 | /* Claim the Bluetooth/FM/GPIO | 754 | /* Claim the Bluetooth/FM/GPIO |
757 | * nShutdown gpio from the system | 755 | * nShutdown gpio from the system |
758 | */ | 756 | */ |
diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h index 4c7be2263011..1674ca7ab86d 100644 --- a/include/linux/ti_wilink_st.h +++ b/include/linux/ti_wilink_st.h | |||
@@ -42,7 +42,7 @@ enum proto_type { | |||
42 | ST_BT, | 42 | ST_BT, |
43 | ST_FM, | 43 | ST_FM, |
44 | ST_GPS, | 44 | ST_GPS, |
45 | ST_MAX, | 45 | ST_MAX_CHANNELS = 16, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | /** | 48 | /** |
@@ -62,6 +62,17 @@ enum proto_type { | |||
62 | * @priv_data: privdate data holder for the protocol drivers, sent | 62 | * @priv_data: privdate data holder for the protocol drivers, sent |
63 | * from the protocol drivers during registration, and sent back on | 63 | * from the protocol drivers during registration, and sent back on |
64 | * reg_complete_cb and recv. | 64 | * reg_complete_cb and recv. |
65 | * @chnl_id: channel id the protocol driver is interested in, the channel | ||
66 | * id is nothing but the 1st byte of the packet in UART frame. | ||
67 | * @max_frame_size: size of the largest frame the protocol can receive. | ||
68 | * @hdr_len: length of the header structure of the protocol. | ||
69 | * @offset_len_in_hdr: this provides the offset of the length field in the | ||
70 | * header structure of the protocol header, to assist ST to know | ||
71 | * how much to receive, if the data is split across UART frames. | ||
72 | * @len_size: whether the length field inside the header is 2 bytes | ||
73 | * or 1 byte. | ||
74 | * @reserve: the number of bytes ST needs to reserve in the skb being | ||
75 | * prepared for the protocol driver. | ||
65 | */ | 76 | */ |
66 | struct st_proto_s { | 77 | struct st_proto_s { |
67 | enum proto_type type; | 78 | enum proto_type type; |
@@ -70,10 +81,17 @@ struct st_proto_s { | |||
70 | void (*reg_complete_cb) (void *, char data); | 81 | void (*reg_complete_cb) (void *, char data); |
71 | long (*write) (struct sk_buff *skb); | 82 | long (*write) (struct sk_buff *skb); |
72 | void *priv_data; | 83 | void *priv_data; |
84 | |||
85 | unsigned char chnl_id; | ||
86 | unsigned short max_frame_size; | ||
87 | unsigned char hdr_len; | ||
88 | unsigned char offset_len_in_hdr; | ||
89 | unsigned char len_size; | ||
90 | unsigned char reserve; | ||
73 | }; | 91 | }; |
74 | 92 | ||
75 | extern long st_register(struct st_proto_s *); | 93 | extern long st_register(struct st_proto_s *); |
76 | extern long st_unregister(enum proto_type); | 94 | extern long st_unregister(struct st_proto_s *); |
77 | 95 | ||
78 | 96 | ||
79 | /* | 97 | /* |
@@ -114,6 +132,7 @@ extern long st_unregister(enum proto_type); | |||
114 | * @rx_skb: the skb where all data for a protocol gets accumulated, | 132 | * @rx_skb: the skb where all data for a protocol gets accumulated, |
115 | * since tty might not call receive when a complete event packet | 133 | * since tty might not call receive when a complete event packet |
116 | * is received, the states, count and the skb needs to be maintained. | 134 | * is received, the states, count and the skb needs to be maintained. |
135 | * @rx_chnl: the channel ID for which the data is getting accumalated for. | ||
117 | * @txq: the list of skbs which needs to be sent onto the TTY. | 136 | * @txq: the list of skbs which needs to be sent onto the TTY. |
118 | * @tx_waitq: if the chip is not in AWAKE state, the skbs needs to be queued | 137 | * @tx_waitq: if the chip is not in AWAKE state, the skbs needs to be queued |
119 | * up in here, PM(WAKEUP_IND) data needs to be sent and then the skbs | 138 | * up in here, PM(WAKEUP_IND) data needs to be sent and then the skbs |
@@ -135,10 +154,11 @@ struct st_data_s { | |||
135 | #define ST_TX_SENDING 1 | 154 | #define ST_TX_SENDING 1 |
136 | #define ST_TX_WAKEUP 2 | 155 | #define ST_TX_WAKEUP 2 |
137 | unsigned long tx_state; | 156 | unsigned long tx_state; |
138 | struct st_proto_s *list[ST_MAX]; | 157 | struct st_proto_s *list[ST_MAX_CHANNELS]; |
139 | unsigned long rx_state; | 158 | unsigned long rx_state; |
140 | unsigned long rx_count; | 159 | unsigned long rx_count; |
141 | struct sk_buff *rx_skb; | 160 | struct sk_buff *rx_skb; |
161 | unsigned char rx_chnl; | ||
142 | struct sk_buff_head txq, tx_waitq; | 162 | struct sk_buff_head txq, tx_waitq; |
143 | spinlock_t lock; | 163 | spinlock_t lock; |
144 | unsigned char protos_registered; | 164 | unsigned char protos_registered; |
@@ -243,12 +263,12 @@ struct kim_data_s { | |||
243 | struct completion kim_rcvd, ldisc_installed; | 263 | struct completion kim_rcvd, ldisc_installed; |
244 | char resp_buffer[30]; | 264 | char resp_buffer[30]; |
245 | const struct firmware *fw_entry; | 265 | const struct firmware *fw_entry; |
246 | long gpios[ST_MAX]; | 266 | long gpios[ST_MAX_CHANNELS]; |
247 | unsigned long rx_state; | 267 | unsigned long rx_state; |
248 | unsigned long rx_count; | 268 | unsigned long rx_count; |
249 | struct sk_buff *rx_skb; | 269 | struct sk_buff *rx_skb; |
250 | struct rfkill *rfkill[ST_MAX]; | 270 | struct rfkill *rfkill[ST_MAX_CHANNELS]; |
251 | enum proto_type rf_protos[ST_MAX]; | 271 | enum proto_type rf_protos[ST_MAX_CHANNELS]; |
252 | struct st_data_s *core_data; | 272 | struct st_data_s *core_data; |
253 | struct chip_version version; | 273 | struct chip_version version; |
254 | }; | 274 | }; |
@@ -338,12 +358,8 @@ struct hci_command { | |||
338 | 358 | ||
339 | /* ST LL receiver states */ | 359 | /* ST LL receiver states */ |
340 | #define ST_W4_PACKET_TYPE 0 | 360 | #define ST_W4_PACKET_TYPE 0 |
341 | #define ST_BT_W4_EVENT_HDR 1 | 361 | #define ST_W4_HEADER 1 |
342 | #define ST_BT_W4_ACL_HDR 2 | 362 | #define ST_W4_DATA 2 |
343 | #define ST_BT_W4_SCO_HDR 3 | ||
344 | #define ST_BT_W4_DATA 4 | ||
345 | #define ST_FM_W4_EVENT_HDR 5 | ||
346 | #define ST_GPS_W4_EVENT_HDR 6 | ||
347 | 363 | ||
348 | /* ST LL state machines */ | 364 | /* ST LL state machines */ |
349 | #define ST_LL_ASLEEP 0 | 365 | #define ST_LL_ASLEEP 0 |