H A D | st_core.c | 41 static void add_channel_to_table(struct st_data_s *st_gdata, add_channel_to_table() argument 46 st_gdata->list[new_proto->chnl_id] = new_proto; add_channel_to_table() 47 st_gdata->is_registered[new_proto->chnl_id] = true; add_channel_to_table() 50 static void remove_channel_from_table(struct st_data_s *st_gdata, remove_channel_from_table() argument 54 /* st_gdata->list[proto->chnl_id] = NULL; */ remove_channel_from_table() 55 st_gdata->is_registered[proto->chnl_id] = false; remove_channel_from_table() 65 int st_get_uart_wr_room(struct st_data_s *st_gdata) st_get_uart_wr_room() argument 68 if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) { st_get_uart_wr_room() 72 tty = st_gdata->tty; st_get_uart_wr_room() 83 int st_int_write(struct st_data_s *st_gdata, st_int_write() argument 87 if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) { st_int_write() 91 tty = st_gdata->tty; st_int_write() 104 static void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata) st_send_frame() argument 109 (st_gdata == NULL || st_gdata->rx_skb == NULL st_send_frame() 110 || st_gdata->is_registered[chnl_id] == false)) { st_send_frame() 113 kfree_skb(st_gdata->rx_skb); st_send_frame() 121 if (likely(st_gdata->list[chnl_id]->recv != NULL)) { st_send_frame() 123 (st_gdata->list[chnl_id]->recv st_send_frame() 124 (st_gdata->list[chnl_id]->priv_data, st_gdata->rx_skb) st_send_frame() 127 kfree_skb(st_gdata->rx_skb); st_send_frame() 132 kfree_skb(st_gdata->rx_skb); st_send_frame() 144 static void st_reg_complete(struct st_data_s *st_gdata, char err) st_reg_complete() argument 149 if (likely(st_gdata != NULL && st_reg_complete() 150 st_gdata->is_registered[i] == true && st_reg_complete() 151 st_gdata->list[i]->reg_complete_cb != NULL)) { st_reg_complete() 152 st_gdata->list[i]->reg_complete_cb st_reg_complete() 153 (st_gdata->list[i]->priv_data, err); st_reg_complete() 156 st_gdata->is_registered[i] = false; st_reg_complete() 157 if (st_gdata->protos_registered) st_reg_complete() 158 st_gdata->protos_registered--; st_reg_complete() 164 static inline int st_check_data_len(struct st_data_s *st_gdata, st_check_data_len() argument 167 int room = skb_tailroom(st_gdata->rx_skb); st_check_data_len() 176 st_send_frame(chnl_id, st_gdata); st_check_data_len() 184 kfree_skb(st_gdata->rx_skb); st_check_data_len() 189 st_gdata->rx_state = ST_W4_DATA; st_check_data_len() 190 st_gdata->rx_count = len; st_check_data_len() 196 st_gdata->rx_state = ST_W4_PACKET_TYPE; st_check_data_len() 197 st_gdata->rx_skb = NULL; st_check_data_len() 198 st_gdata->rx_count = 0; st_check_data_len() 199 st_gdata->rx_chnl = 0; st_check_data_len() 208 static inline void st_wakeup_ack(struct st_data_s *st_gdata, st_wakeup_ack() argument 214 spin_lock_irqsave(&st_gdata->lock, flags); st_wakeup_ack() 218 while ((waiting_skb = skb_dequeue(&st_gdata->tx_waitq))) st_wakeup_ack() 219 skb_queue_tail(&st_gdata->txq, waiting_skb); st_wakeup_ack() 222 st_ll_sleep_state(st_gdata, (unsigned long)cmd); st_wakeup_ack() 223 spin_unlock_irqrestore(&st_gdata->lock, flags); st_wakeup_ack() 226 st_tx_wakeup(st_gdata); st_wakeup_ack() 246 struct st_data_s *st_gdata = (struct st_data_s *)disc_data; st_int_recv() local 251 if (unlikely(ptr == NULL) || (st_gdata == NULL)) { st_int_recv() 257 "rx_count %ld", count, st_gdata->rx_state, st_int_recv() 258 st_gdata->rx_count); st_int_recv() 260 spin_lock_irqsave(&st_gdata->lock, flags); st_int_recv() 263 if (st_gdata->rx_count) { st_int_recv() 264 len = min_t(unsigned int, st_gdata->rx_count, count); st_int_recv() 265 memcpy(skb_put(st_gdata->rx_skb, len), ptr, len); st_int_recv() 266 st_gdata->rx_count -= len; st_int_recv() 270 if (st_gdata->rx_count) st_int_recv() 274 switch (st_gdata->rx_state) { st_int_recv() 280 st_send_frame(st_gdata->rx_chnl, st_gdata); st_int_recv() 282 st_gdata->rx_state = ST_W4_PACKET_TYPE; st_int_recv() 283 st_gdata->rx_skb = NULL; st_int_recv() 287 proto = st_gdata->list[st_gdata->rx_chnl]; st_int_recv() 289 &st_gdata->rx_skb->data st_int_recv() 301 st_check_data_len(st_gdata, proto->chnl_id, st_int_recv() 320 st_ll_sleep_state(st_gdata, *ptr); st_int_recv() 324 spin_unlock_irqrestore(&st_gdata->lock, flags); st_int_recv() 325 if (st_ll_getstate(st_gdata) == ST_LL_AWAKE) st_int_recv() 326 st_wakeup_ack(st_gdata, LL_WAKE_UP_ACK); st_int_recv() 327 spin_lock_irqsave(&st_gdata->lock, flags); st_int_recv() 335 spin_unlock_irqrestore(&st_gdata->lock, flags); st_int_recv() 337 st_wakeup_ack(st_gdata, *ptr); st_int_recv() 338 spin_lock_irqsave(&st_gdata->lock, flags); st_int_recv() 352 * "st_gdata->list[type] == NULL)" are supported st_int_recv() 359 (st_gdata->list[type] == NULL)) { st_int_recv() 366 st_gdata->rx_skb = alloc_skb( st_int_recv() 367 st_gdata->list[type]->max_frame_size, st_int_recv() 369 if (st_gdata->rx_skb == NULL) { st_int_recv() 374 skb_reserve(st_gdata->rx_skb, st_int_recv() 375 st_gdata->list[type]->reserve); st_int_recv() 377 st_gdata->rx_skb->cb[0] = type; /*pkt_type*/ st_int_recv() 378 st_gdata->rx_skb->cb[1] = 0; /*incoming*/ st_int_recv() 379 st_gdata->rx_chnl = *ptr; st_int_recv() 380 st_gdata->rx_state = ST_W4_HEADER; st_int_recv() 381 st_gdata->rx_count = st_gdata->list[type]->hdr_len; st_int_recv() 382 pr_debug("rx_count %ld\n", st_gdata->rx_count); st_int_recv() 388 spin_unlock_irqrestore(&st_gdata->lock, flags); st_int_recv() 399 static struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata) st_int_dequeue() argument 404 if (st_gdata->tx_skb != NULL) { st_int_dequeue() 405 returning_skb = st_gdata->tx_skb; st_int_dequeue() 406 st_gdata->tx_skb = NULL; st_int_dequeue() 409 return skb_dequeue(&st_gdata->txq); st_int_dequeue() 421 static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb) st_int_enqueue() argument 426 spin_lock_irqsave(&st_gdata->lock, flags); st_int_enqueue() 428 switch (st_ll_getstate(st_gdata)) { st_int_enqueue() 431 skb_queue_tail(&st_gdata->txq, skb); st_int_enqueue() 434 skb_queue_tail(&st_gdata->tx_waitq, skb); st_int_enqueue() 438 "purging received skb.", st_ll_getstate(st_gdata)); st_int_enqueue() 442 skb_queue_tail(&st_gdata->tx_waitq, skb); st_int_enqueue() 443 st_ll_wakeup(st_gdata); st_int_enqueue() 447 "purging received skb.", st_ll_getstate(st_gdata)); st_int_enqueue() 452 spin_unlock_irqrestore(&st_gdata->lock, flags); st_int_enqueue() 465 struct st_data_s *st_gdata = container_of(work, struct st_data_s, work_fn_write_wakeup() local 468 st_tx_wakeup((void *)st_gdata); work_fn_write_wakeup() 515 void kim_st_list_protocols(struct st_data_s *st_gdata, void *buf) kim_st_list_protocols() argument 518 st_gdata->protos_registered, kim_st_list_protocols() 519 st_gdata->is_registered[0x04] == true ? 'R' : 'U', kim_st_list_protocols() 520 st_gdata->is_registered[0x08] == true ? 'R' : 'U', kim_st_list_protocols() 521 st_gdata->is_registered[0x09] == true ? 'R' : 'U'); kim_st_list_protocols() 531 struct st_data_s *st_gdata; st_register() local 535 st_kim_ref(&st_gdata, 0); st_register() 536 if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL st_register() 547 if (st_gdata->is_registered[new_proto->chnl_id] == true) { st_register() 553 spin_lock_irqsave(&st_gdata->lock, flags); st_register() 555 if (test_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state)) { st_register() 559 add_channel_to_table(st_gdata, new_proto); st_register() 560 st_gdata->protos_registered++; st_register() 563 set_bit(ST_REG_PENDING, &st_gdata->st_state); st_register() 564 spin_unlock_irqrestore(&st_gdata->lock, flags); st_register() 566 } else if (st_gdata->protos_registered == ST_EMPTY) { st_register() 568 set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); st_register() 572 st_ll_enable(st_gdata); st_register() 575 spin_unlock_irqrestore(&st_gdata->lock, flags); st_register() 580 err = st_kim_start(st_gdata->kim_data); st_register() 582 clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); st_register() 583 if ((st_gdata->protos_registered != ST_EMPTY) && st_register() 584 (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { st_register() 586 spin_lock_irqsave(&st_gdata->lock, flags); st_register() 587 st_reg_complete(st_gdata, err); st_register() 588 spin_unlock_irqrestore(&st_gdata->lock, flags); st_register() 589 clear_bit(ST_REG_PENDING, &st_gdata->st_state); st_register() 594 spin_lock_irqsave(&st_gdata->lock, flags); st_register() 596 clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); st_register() 602 if ((st_gdata->protos_registered != ST_EMPTY) && st_register() 603 (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { st_register() 605 st_reg_complete(st_gdata, 0); st_register() 607 clear_bit(ST_REG_PENDING, &st_gdata->st_state); st_register() 612 if (st_gdata->is_registered[new_proto->chnl_id] == true) { st_register() 615 spin_unlock_irqrestore(&st_gdata->lock, flags); st_register() 619 add_channel_to_table(st_gdata, new_proto); st_register() 620 st_gdata->protos_registered++; st_register() 622 spin_unlock_irqrestore(&st_gdata->lock, flags); st_register() 627 add_channel_to_table(st_gdata, new_proto); st_register() 628 st_gdata->protos_registered++; st_register() 632 spin_unlock_irqrestore(&st_gdata->lock, flags); st_register() 646 struct st_data_s *st_gdata; st_unregister() local 650 st_kim_ref(&st_gdata, 0); st_unregister() 651 if (!st_gdata || proto->chnl_id >= ST_MAX_CHANNELS) { st_unregister() 656 spin_lock_irqsave(&st_gdata->lock, flags); st_unregister() 658 if (st_gdata->is_registered[proto->chnl_id] == false) { st_unregister() 660 spin_unlock_irqrestore(&st_gdata->lock, flags); st_unregister() 664 if (st_gdata->protos_registered) st_unregister() 665 st_gdata->protos_registered--; st_unregister() 667 remove_channel_from_table(st_gdata, proto); st_unregister() 668 spin_unlock_irqrestore(&st_gdata->lock, flags); st_unregister() 670 if ((st_gdata->protos_registered == ST_EMPTY) && st_unregister() 671 (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { st_unregister() 675 if (st_gdata->tty) { st_unregister() 676 tty_ldisc_flush(st_gdata->tty); st_unregister() 677 stop_tty(st_gdata->tty); st_unregister() 681 st_kim_stop(st_gdata->kim_data); st_unregister() 683 st_ll_disable(st_gdata); st_unregister() 694 struct st_data_s *st_gdata; st_write() local 697 st_kim_ref(&st_gdata, 0); st_write() 698 if (unlikely(skb == NULL || st_gdata == NULL st_write() 699 || st_gdata->tty == NULL)) { st_write() 708 st_int_enqueue(st_gdata, skb); st_write() 710 st_tx_wakeup(st_gdata); st_write() 726 struct st_data_s *st_gdata; st_tty_open() local 729 st_kim_ref(&st_gdata, 0); st_tty_open() 730 st_gdata->tty = tty; st_tty_open() 731 tty->disc_data = st_gdata; st_tty_open() 746 st_kim_complete(st_gdata->kim_data); st_tty_open() 755 struct st_data_s *st_gdata = tty->disc_data; st_tty_close() local 763 spin_lock_irqsave(&st_gdata->lock, flags); st_tty_close() 765 if (st_gdata->is_registered[i] == true) st_tty_close() 767 st_gdata->list[i] = NULL; st_tty_close() 768 st_gdata->is_registered[i] = false; st_tty_close() 770 st_gdata->protos_registered = 0; st_tty_close() 771 spin_unlock_irqrestore(&st_gdata->lock, flags); st_tty_close() 776 st_kim_complete(st_gdata->kim_data); st_tty_close() 777 st_gdata->tty = NULL; st_tty_close() 782 spin_lock_irqsave(&st_gdata->lock, flags); st_tty_close() 784 skb_queue_purge(&st_gdata->txq); st_tty_close() 785 skb_queue_purge(&st_gdata->tx_waitq); st_tty_close() 787 st_gdata->rx_count = 0; st_tty_close() 788 st_gdata->rx_state = ST_W4_PACKET_TYPE; st_tty_close() 789 kfree_skb(st_gdata->rx_skb); st_tty_close() 790 st_gdata->rx_skb = NULL; st_tty_close() 791 spin_unlock_irqrestore(&st_gdata->lock, flags); st_tty_close() 817 struct st_data_s *st_gdata = tty->disc_data; st_tty_wakeup() local 827 schedule_work(&st_gdata->work_write_wakeup); st_tty_wakeup() 832 struct st_data_s *st_gdata = tty->disc_data; st_tty_flush_buffer() local 835 kfree_skb(st_gdata->tx_skb); st_tty_flush_buffer() 836 st_gdata->tx_skb = NULL; st_tty_flush_buffer() 856 struct st_data_s *st_gdata; st_core_init() local 867 st_gdata = kzalloc(sizeof(struct st_data_s), GFP_KERNEL); st_core_init() 868 if (!st_gdata) { st_core_init() 880 skb_queue_head_init(&st_gdata->txq); st_core_init() 881 skb_queue_head_init(&st_gdata->tx_waitq); st_core_init() 884 spin_lock_init(&st_gdata->lock); st_core_init() 886 err = st_ll_init(st_gdata); st_core_init() 889 kfree(st_gdata); st_core_init() 896 INIT_WORK(&st_gdata->work_write_wakeup, work_fn_write_wakeup); st_core_init() 898 *core_data = st_gdata; st_core_init() 902 void st_core_exit(struct st_data_s *st_gdata) st_core_exit() argument 906 err = st_ll_deinit(st_gdata); st_core_exit() 910 if (st_gdata != NULL) { st_core_exit() 912 skb_queue_purge(&st_gdata->txq); st_core_exit() 913 skb_queue_purge(&st_gdata->tx_waitq); st_core_exit() 914 kfree_skb(st_gdata->rx_skb); st_core_exit() 915 kfree_skb(st_gdata->tx_skb); st_core_exit() 921 kfree(st_gdata); st_core_exit()
|