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