Advertisement
Guest User

Untitled

a guest
Mar 26th, 2012
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.05 KB | None | 0 0
  1. diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
  2. index 8bea09e..6d6509b 100644
  3. --- a/arch/arm/mach-msm/smd_tty.c
  4. +++ b/arch/arm/mach-msm/smd_tty.c
  5. @@ -30,6 +30,7 @@
  6. #include <asm/mach-types.h>
  7.  
  8. #define MAX_SMD_TTYS 32
  9. +#define SMD_BUF_SIZE (16 * 1024)
  10.  
  11. static DEFINE_MUTEX(smd_tty_lock);
  12.  
  13. @@ -38,7 +39,8 @@ struct smd_tty_info {
  14. struct tty_struct *tty;
  15. struct wake_lock wake_lock;
  16. int open_count;
  17. - struct work_struct tty_work;
  18. + struct delayed_work tty_delayed_work;
  19. + unsigned char *rx_buffer;
  20. };
  21.  
  22. static struct smd_tty_info smd_tty[MAX_SMD_TTYS];
  23. @@ -69,10 +71,19 @@ static void smd_readx_cb(void *data, int count, void *ctxt)
  24.  
  25. static void smd_tty_work_func(struct work_struct *work)
  26. {
  27. - int avail;
  28. - struct smd_tty_info *info = container_of(work,
  29. - struct smd_tty_info,
  30. - tty_work);
  31. + unsigned char *ptr;
  32. + int avail;
  33. + int fail_cnt=0;
  34. + int exit_loop=0;
  35. +
  36. + struct delayed_work *delayed_work = container_of(work,
  37. + struct delayed_work,
  38. + work);
  39. +
  40. + struct smd_tty_info *info = container_of(delayed_work,
  41. + struct smd_tty_info,
  42. + tty_delayed_work);
  43. +
  44. struct tty_struct *tty = info->tty;
  45.  
  46. if (!tty)
  47. @@ -94,15 +105,59 @@ static void smd_tty_work_func(struct work_struct *work)
  48. break;
  49. }
  50.  
  51. - if (smd_readx(info->ch, avail, smd_readx_cb, (void *)tty) != avail) {
  52. - /* shouldn't be possible since we're in interrupt
  53. - ** context here and nobody else could 'steal' our
  54. - ** characters.
  55. - */
  56. - printk(KERN_ERR "OOPS - smd_tty_buffer mismatch?!\n");
  57. - }
  58. + if(tty->index==7)
  59. + {
  60. + if (smd_readx(info->ch, avail, smd_readx_cb, (void *)tty) != avail) {
  61. + /* shouldn't be possible since we're in interrupt
  62. + ** context here and nobody else could 'steal' our
  63. + ** characters.
  64. + */
  65. + printk(KERN_ERR "OOPS - smd_tty_buffer mismatch?!\n");
  66. + }
  67. + }else{
  68. + avail = tty_prepare_flip_string(tty, &ptr, avail);
  69. + if ( avail == 0)
  70. + {
  71. + if(fail_cnt)
  72. + {
  73. + if(smd_read_avail(info->ch) > 2048)
  74. + avail = tty_prepare_flip_string(tty, &ptr, 2048);
  75. + //TODO: this is nice but it can cause the the size of the required tty realloc to get bigger
  76. + // and bigger since our smd channel is collecting more and more bytes but we have failed to
  77. + // deliver any of them to userland. Leading to permanent failure of the smd channel.
  78. + // we should probably try to send smaller chunks to prevent the realloc all togeather.
  79. +
  80. +
  81. + //We have had about enough
  82. + //need to get started up later because we have already been notified of a non empty
  83. + //buffer, unforunately the SLAB is not going to give in atm
  84. + queue_delayed_work(smd_tty_wq, &info->tty_delayed_work,HZ/50);
  85. + printk("SMD%s: tty induced slab failure. high probability of smd pipe freeze. chan %d, needed %d, smallish %d\n",__func__, tty->index, smd_read_avail(info->ch),avail);
  86. + if(avail==0)
  87. + exit_loop=1;
  88. + }
  89. + fail_cnt++;
  90. + }
  91. +
  92. + if (avail && smd_read(info->ch, ptr, avail) != avail) {
  93. + /* shouldn't be possible since we're in interrupt
  94. + ** context here and nobody else could 'steal' our
  95. + ** characters.
  96. + */
  97. + printk(KERN_ERR "OOPS - smd_tty_buffer mismatch?!");
  98. + }
  99. + }
  100. +
  101. wake_lock_timeout(&info->wake_lock, HZ / 2);
  102. mutex_unlock(&smd_tty_lock);
  103. +
  104. + if(tty->index!=7)
  105. + {
  106. + tty_flip_buffer_push(tty);
  107. + if(exit_loop)
  108. + break;
  109. +
  110. + }
  111. }
  112.  
  113. /* XXX only when writable and necessary */
  114. @@ -118,7 +173,8 @@ static void smd_tty_notify(void *priv, unsigned event)
  115. if (event != SMD_EVENT_DATA)
  116. return;
  117.  
  118. - queue_work(smd_tty_wq, &info->tty_work);
  119. + queue_delayed_work(smd_tty_wq, &info->tty_delayed_work,0);
  120. +
  121. }
  122.  
  123. static int smd_tty_open(struct tty_struct *tty, struct file *f)
  124. @@ -217,7 +273,7 @@ static int smd_tty_chars_in_buffer(struct tty_struct *tty)
  125. static void smd_tty_unthrottle(struct tty_struct *tty)
  126. {
  127. struct smd_tty_info *info = tty->driver_data;
  128. - queue_work(smd_tty_wq, &info->tty_work);
  129. + queue_delayed_work(smd_tty_wq, &info->tty_delayed_work,0);
  130. return;
  131. }
  132.  
  133. @@ -267,13 +323,17 @@ static int __init smd_tty_init(void)
  134.  
  135. /* this should be dynamic */
  136. tty_register_device(smd_tty_driver, 0, 0);
  137. - INIT_WORK(&smd_tty[0].tty_work, smd_tty_work_func);
  138. + INIT_DELAYED_WORK(&smd_tty[0].tty_delayed_work, smd_tty_work_func);
  139. + smd_tty[1].rx_buffer = (unsigned char *)kmalloc(SMD_BUF_SIZE,GFP_KERNEL);
  140. tty_register_device(smd_tty_driver, 1, 0);
  141. - INIT_WORK(&smd_tty[1].tty_work, smd_tty_work_func);
  142. + INIT_DELAYED_WORK(&smd_tty[1].tty_delayed_work, smd_tty_work_func);
  143. + smd_tty[1].rx_buffer = (unsigned char *)kmalloc(SMD_BUF_SIZE,GFP_KERNEL);
  144. tty_register_device(smd_tty_driver, 7, 0);
  145. - INIT_WORK(&smd_tty[7].tty_work, smd_tty_work_func);
  146. + INIT_DELAYED_WORK(&smd_tty[7].tty_delayed_work, smd_tty_work_func);
  147. + smd_tty[7].rx_buffer = (unsigned char *)kmalloc(SMD_BUF_SIZE,GFP_KERNEL);
  148. tty_register_device(smd_tty_driver, 27, 0);
  149. - INIT_WORK(&smd_tty[27].tty_work, smd_tty_work_func);
  150. + INIT_DELAYED_WORK(&smd_tty[27].tty_delayed_work, smd_tty_work_func);
  151. + smd_tty[27].rx_buffer = (unsigned char *)kmalloc(SMD_BUF_SIZE,GFP_KERNEL);
  152.  
  153. return 0;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement