⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.c

📁 linux字符驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 <a name=L75 href="source/kernel/chr_drv/serial.c?v=0.97#L75">75</a>                 c = queue-&gt;<a href="ident?v=0.97;i=buf">buf</a>[queue-&gt;tail]; <a name=L76 href="source/kernel/chr_drv/serial.c?v=0.97#L76">76</a>                 queue-&gt;tail++; <a name=L77 href="source/kernel/chr_drv/serial.c?v=0.97#L77">77</a>                 queue-&gt;tail &amp;= <a href="ident?v=0.97;i=TTY_BUF_SIZE">TTY_BUF_SIZE</a>-1; <a name=L78 href="source/kernel/chr_drv/serial.c?v=0.97#L78">78</a>                 <a href="ident?v=0.97;i=outb">outb</a>(c,port); <a name=L79 href="source/kernel/chr_drv/serial.c?v=0.97#L79">79</a>                 if ((<a href="ident?v=0.97;i=info">info</a>-&gt;type != <a href="ident?v=0.97;i=PORT_16550A">PORT_16550A</a>) || (++i &gt;= 14) || <a href="ident?v=0.97;i=info">info</a>-&gt;tty-&gt;stopped) <a name=L80 href="source/kernel/chr_drv/serial.c?v=0.97#L80">80</a>                         break; <a name=L81 href="source/kernel/chr_drv/serial.c?v=0.97#L81">81</a>         } <a name=L82 href="source/kernel/chr_drv/serial.c?v=0.97#L82">82</a>         <a href="ident?v=0.97;i=timer_table">timer_table</a>[timer].expires = <a href="ident?v=0.97;i=jiffies">jiffies</a> + 10; <a name=L83 href="source/kernel/chr_drv/serial.c?v=0.97#L83">83</a>         <a href="ident?v=0.97;i=timer_active">timer_active</a> |= 1 &lt;&lt; timer; <a name=L84 href="source/kernel/chr_drv/serial.c?v=0.97#L84">84</a> end_send: <a name=L85 href="source/kernel/chr_drv/serial.c?v=0.97#L85">85</a>         if (<a href="ident?v=0.97;i=LEFT">LEFT</a>(queue) &gt; <a href="ident?v=0.97;i=WAKEUP_CHARS">WAKEUP_CHARS</a>) <a name=L86 href="source/kernel/chr_drv/serial.c?v=0.97#L86">86</a>                 <a href="ident?v=0.97;i=wake_up">wake_up</a>(&amp;queue-&gt;proc_list); <a name=L87 href="source/kernel/chr_drv/serial.c?v=0.97#L87">87</a> } <a name=L88 href="source/kernel/chr_drv/serial.c?v=0.97#L88">88</a>  <a name=L89 href="source/kernel/chr_drv/serial.c?v=0.97#L89">89</a> static void <a href="ident?v=0.97;i=receive_intr">receive_intr</a>(struct <a href="ident?v=0.97;i=serial_struct">serial_struct</a> * <a href="ident?v=0.97;i=info">info</a>) <a name=L90 href="source/kernel/chr_drv/serial.c?v=0.97#L90">90</a> { <a name=L91 href="source/kernel/chr_drv/serial.c?v=0.97#L91">91</a>         unsigned short port = <a href="ident?v=0.97;i=info">info</a>-&gt;port; <a name=L92 href="source/kernel/chr_drv/serial.c?v=0.97#L92">92</a>         struct <a href="ident?v=0.97;i=tty_queue">tty_queue</a> * queue = <a href="ident?v=0.97;i=info">info</a>-&gt;tty-&gt;read_q; <a name=L93 href="source/kernel/chr_drv/serial.c?v=0.97#L93">93</a>         int <a href="ident?v=0.97;i=head">head</a> = queue-&gt;<a href="ident?v=0.97;i=head">head</a>; <a name=L94 href="source/kernel/chr_drv/serial.c?v=0.97#L94">94</a>         int maxhead = (queue-&gt;tail-1) &amp; (<a href="ident?v=0.97;i=TTY_BUF_SIZE">TTY_BUF_SIZE</a>-1); <a name=L95 href="source/kernel/chr_drv/serial.c?v=0.97#L95">95</a>  <a name=L96 href="source/kernel/chr_drv/serial.c?v=0.97#L96">96</a>         <a href="ident?v=0.97;i=timer_active">timer_active</a> &amp;= ~((1&lt;&lt;<a href="ident?v=0.97;i=SER1_TIMER">SER1_TIMER</a>)&lt;&lt;<a href="ident?v=0.97;i=info">info</a>-&gt;line); <a name=L97 href="source/kernel/chr_drv/serial.c?v=0.97#L97">97</a>         do { <a name=L98 href="source/kernel/chr_drv/serial.c?v=0.97#L98">98</a>                 queue-&gt;<a href="ident?v=0.97;i=buf">buf</a>[<a href="ident?v=0.97;i=head">head</a>] = <a href="ident?v=0.97;i=inb">inb</a>(port); <a name=L99 href="source/kernel/chr_drv/serial.c?v=0.97#L99">99</a>                 if (<a href="ident?v=0.97;i=head">head</a> != maxhead) {<a name=L100 href="source/kernel/chr_drv/serial.c?v=0.97#L100">100</a>                         <a href="ident?v=0.97;i=head">head</a>++;<a name=L101 href="source/kernel/chr_drv/serial.c?v=0.97#L101">101</a>                         <a href="ident?v=0.97;i=head">head</a> &amp;= <a href="ident?v=0.97;i=TTY_BUF_SIZE">TTY_BUF_SIZE</a>-1;<a name=L102 href="source/kernel/chr_drv/serial.c?v=0.97#L102">102</a>                 }<a name=L103 href="source/kernel/chr_drv/serial.c?v=0.97#L103">103</a>         } while (<a href="ident?v=0.97;i=inb">inb</a>(port+5) &amp; 1);<a name=L104 href="source/kernel/chr_drv/serial.c?v=0.97#L104">104</a>         queue-&gt;<a href="ident?v=0.97;i=head">head</a> = <a href="ident?v=0.97;i=head">head</a>;<a name=L105 href="source/kernel/chr_drv/serial.c?v=0.97#L105">105</a>         <a href="ident?v=0.97;i=timer_active">timer_active</a> |= (1&lt;&lt;<a href="ident?v=0.97;i=SER1_TIMER">SER1_TIMER</a>)&lt;&lt;<a href="ident?v=0.97;i=info">info</a>-&gt;line;<a name=L106 href="source/kernel/chr_drv/serial.c?v=0.97#L106">106</a> }<a name=L107 href="source/kernel/chr_drv/serial.c?v=0.97#L107">107</a> <a name=L108 href="source/kernel/chr_drv/serial.c?v=0.97#L108">108</a> static void <a href="ident?v=0.97;i=line_status_intr">line_status_intr</a>(struct <a href="ident?v=0.97;i=serial_struct">serial_struct</a> * <a href="ident?v=0.97;i=info">info</a>)<a name=L109 href="source/kernel/chr_drv/serial.c?v=0.97#L109">109</a> {<a name=L110 href="source/kernel/chr_drv/serial.c?v=0.97#L110">110</a>         unsigned char status = <a href="ident?v=0.97;i=inb">inb</a>(<a href="ident?v=0.97;i=info">info</a>-&gt;port+5);<a name=L111 href="source/kernel/chr_drv/serial.c?v=0.97#L111">111</a> <a name=L112 href="source/kernel/chr_drv/serial.c?v=0.97#L112">112</a> <b><i>/*      printk("line status: %02x\n",status); */</i></b><a name=L113 href="source/kernel/chr_drv/serial.c?v=0.97#L113">113</a> }<a name=L114 href="source/kernel/chr_drv/serial.c?v=0.97#L114">114</a> <a name=L115 href="source/kernel/chr_drv/serial.c?v=0.97#L115">115</a> static void <a href="ident?v=0.97;i=modem_status_intr">modem_status_intr</a>(struct <a href="ident?v=0.97;i=serial_struct">serial_struct</a> * <a href="ident?v=0.97;i=info">info</a>)<a name=L116 href="source/kernel/chr_drv/serial.c?v=0.97#L116">116</a> {<a name=L117 href="source/kernel/chr_drv/serial.c?v=0.97#L117">117</a>         unsigned char status = <a href="ident?v=0.97;i=inb">inb</a>(<a href="ident?v=0.97;i=info">info</a>-&gt;port+6);<a name=L118 href="source/kernel/chr_drv/serial.c?v=0.97#L118">118</a> <a name=L119 href="source/kernel/chr_drv/serial.c?v=0.97#L119">119</a>         if (!(<a href="ident?v=0.97;i=info">info</a>-&gt;tty-&gt;<a href="ident?v=0.97;i=termios">termios</a>.c_cflag &amp; <a href="ident?v=0.97;i=CLOCAL">CLOCAL</a>)) {<a name=L120 href="source/kernel/chr_drv/serial.c?v=0.97#L120">120</a>                 if ((status &amp; 0x88) == 0x08 &amp;&amp; <a href="ident?v=0.97;i=info">info</a>-&gt;tty-&gt;pgrp &gt; 0)<a name=L121 href="source/kernel/chr_drv/serial.c?v=0.97#L121">121</a>                         <a href="ident?v=0.97;i=kill_pg">kill_pg</a>(<a href="ident?v=0.97;i=info">info</a>-&gt;tty-&gt;pgrp,<a href="ident?v=0.97;i=SIGHUP">SIGHUP</a>,1);<a name=L122 href="source/kernel/chr_drv/serial.c?v=0.97#L122">122</a> <a name=L123 href="source/kernel/chr_drv/serial.c?v=0.97#L123">123</a>                 if (<a href="ident?v=0.97;i=info">info</a>-&gt;tty-&gt;<a href="ident?v=0.97;i=termios">termios</a>.c_cflag &amp; <a href="ident?v=0.97;i=CRTSCTS">CRTSCTS</a>)<a name=L124 href="source/kernel/chr_drv/serial.c?v=0.97#L124">124</a>                         <a href="ident?v=0.97;i=info">info</a>-&gt;tty-&gt;stopped = !(status &amp; 0x10);<a name=L125 href="source/kernel/chr_drv/serial.c?v=0.97#L125">125</a> <a name=L126 href="source/kernel/chr_drv/serial.c?v=0.97#L126">126</a>                 if (!<a href="ident?v=0.97;i=info">info</a>-&gt;tty-&gt;stopped)<a name=L127 href="source/kernel/chr_drv/serial.c?v=0.97#L127">127</a>                         <a href="ident?v=0.97;i=send_intr">send_intr</a>(<a href="ident?v=0.97;i=info">info</a>);<a name=L128 href="source/kernel/chr_drv/serial.c?v=0.97#L128">128</a>         }<a name=L129 href="source/kernel/chr_drv/serial.c?v=0.97#L129">129</a> }<a name=L130 href="source/kernel/chr_drv/serial.c?v=0.97#L130">130</a> <a name=L131 href="source/kernel/chr_drv/serial.c?v=0.97#L131">131</a> static void (*<a href="ident?v=0.97;i=jmp_table">jmp_table</a>[4])(struct <a href="ident?v=0.97;i=serial_struct">serial_struct</a> *) = {<a name=L132 href="source/kernel/chr_drv/serial.c?v=0.97#L132">132</a>         <a href="ident?v=0.97;i=modem_status_intr">modem_status_intr</a>,<a name=L133 href="source/kernel/chr_drv/serial.c?v=0.97#L133">133</a>         <a href="ident?v=0.97;i=send_intr">send_intr</a>,<a name=L134 href="source/kernel/chr_drv/serial.c?v=0.97#L134">134</a>         <a href="ident?v=0.97;i=receive_intr">receive_intr</a>,<a name=L135 href="source/kernel/chr_drv/serial.c?v=0.97#L135">135</a>         <a href="ident?v=0.97;i=line_status_intr">line_status_intr</a><a name=L136 href="source/kernel/chr_drv/serial.c?v=0.97#L136">136</a> };<a name=L137 href="source/kernel/chr_drv/serial.c?v=0.97#L137">137</a> <a name=L138 href="source/kernel/chr_drv/serial.c?v=0.97#L138">138</a> static void <a href="ident?v=0.97;i=check_tty">check_tty</a>(struct <a href="ident?v=0.97;i=serial_struct">serial_struct</a> * <a href="ident?v=0.97;i=info">info</a>)<a name=L139 href="source/kernel/chr_drv/serial.c?v=0.97#L139">139</a> {<a name=L140 href="source/kernel/chr_drv/serial.c?v=0.97#L140">140</a>         unsigned char ident;<a name=L141 href="source/kernel/chr_drv/serial.c?v=0.97#L141">141</a> <a name=L142 href="source/kernel/chr_drv/serial.c?v=0.97#L142">142</a>         if (!<a href="ident?v=0.97;i=info">info</a> || !<a href="ident?v=0.97;i=info">info</a>-&gt;tty || !<a href="ident?v=0.97;i=info">info</a>-&gt;port)<a name=L143 href="source/kernel/chr_drv/serial.c?v=0.97#L143">143</a>                 return;<a name=L144 href="source/kernel/chr_drv/serial.c?v=0.97#L144">144</a>         while (1) {<a name=L145 href="source/kernel/chr_drv/serial.c?v=0.97#L145">145</a>                 ident = <a href="ident?v=0.97;i=inb">inb</a>(<a href="ident?v=0.97;i=info">info</a>-&gt;port+2) &amp; 7;<a name=L146 href="source/kernel/chr_drv/serial.c?v=0.97#L146">146</a>                 if (ident &amp; 1)<a name=L147 href="source/kernel/chr_drv/serial.c?v=0.97#L147">147</a>                         return;<a name=L148 href="source/kernel/chr_drv/serial.c?v=0.97#L148">148</a>                 ident &gt;&gt;= 1;<a name=L149 href="source/kernel/chr_drv/serial.c?v=0.97#L149">149</a>                 if (ident &gt; 3)<a name=L150 href="source/kernel/chr_drv/serial.c?v=0.97#L150">150</a>                         return;<a name=L151 href="source/kernel/chr_drv/serial.c?v=0.97#L151">151</a>                 <a href="ident?v=0.97;i=jmp_table">jmp_table</a>[ident](<a href="ident?v=0.97;i=info">info</a>);<a name=L152 href="source/kernel/chr_drv/serial.c?v=0.97#L152">152</a>         }<a name=L153 href="source/kernel/chr_drv/serial.c?v=0.97#L153">153</a> }<a name=L154 href="source/kernel/chr_drv/serial.c?v=0.97#L154">154</a> <a name=L155 href="source/kernel/chr_drv/serial.c?v=0.97#L155">155</a> <b><i>/*</i></b><a name=L156 href="source/kernel/chr_drv/serial.c?v=0.97#L156">156</a> <b><i> * Again, we disable interrupts to be sure there aren't any races:</i></b><a name=L157 href="source/kernel/chr_drv/serial.c?v=0.97#L157">157</a> <b><i> * see send_intr for details.</i></b><a name=L158 href="source/kernel/chr_drv/serial.c?v=0.97#L158">158</a> <b><i> */</i></b><a name=L159 href="source/kernel/chr_drv/serial.c?v=0.97#L159">159</a> static inline void <a href="ident?v=0.97;i=do_rs_write">do_rs_write</a>(struct <a href="ident?v=0.97;i=serial_struct">serial_struct</a> * <a href="ident?v=0.97;i=info">info</a>)<a name=L160 href="source/kernel/chr_drv/serial.c?v=0.97#L160">160</a> {<a name=L161 href="source/kernel/chr_drv/serial.c?v=0.97#L161">161</a>         if (!<a href="ident?v=0.97;i=info">info</a>-&gt;tty || !<a href="ident?v=0.97;i=info">info</a>-&gt;port)<a name=L162 href="source/kernel/chr_drv/serial.c?v=0.97#L162">162</a>                 return;<a name=L163 href="source/kernel/chr_drv/serial.c?v=0.97#L163">163</a>         if (!<a href="ident?v=0.97;i=info">info</a>-&gt;tty-&gt;write_q || <a href="ident?v=0.97;i=EMPTY">EMPTY</a>(<a href="ident?v=0.97;i=info">info</a>-&gt;tty-&gt;write_q))<a name=L164 href="source/kernel/chr_drv/serial.c?v=0.97#L164">164</a>                 return;<a name=L165 href="source/kernel/chr_drv/serial.c?v=0.97#L165">165</a>         <a href="ident?v=0.97;i=cli">cli</a>();<a name=L166 href="source/kernel/chr_drv/serial.c?v=0.97#L166">166</a>         <a href="ident?v=0.97;i=send_intr">send_intr</a>(<a href="ident?v=0.97;i=info">info</a>);<a name=L167 href="source/kernel/chr_drv/serial.c?v=0.97#L167">167</a>         <a href="ident?v=0.97;i=sti">sti</a>();<a name=L168 href="source/kernel/chr_drv/serial.c?v=0.97#L168">168</a> }<a name=L169 href="source/kernel/chr_drv/serial.c?v=0.97#L169">169</a> <a name=L170 href="source/kernel/chr_drv/serial.c?v=0.97#L170">170</a> <b><i>/*</i></b><a name=L171 href="source/kernel/chr_drv/serial.c?v=0.97#L171">171</a> <b><i> * IRQ routines: one per line</i></b><a name=L172 href="source/kernel/chr_drv/serial.c?v=0.97#L172">172</a> <b><i> */</i></b><a name=L173 href="source/kernel/chr_drv/serial.c?v=0.97#L173">173</a> static void <a href="ident?v=0.97;i=com1_IRQ">com1_IRQ</a>(int unused)<a name=L174 href="source/kernel/chr_drv/serial.c?v=0.97#L174">174</a> {<a name=L175 href="source/kernel/chr_drv/serial.c?v=0.97#L175">175</a>         <a href="ident?v=0.97;i=check_tty">check_tty</a>(<a href="ident?v=0.97;i=serial_table">serial_table</a>+0);<a name=L176 href="source/kernel/chr_drv/serial.c?v=0.97#L176">176</a> }<a name=L177 href="source/kernel/chr_drv/serial.c?v=0.97#L177">177</a> <a name=L178 href="source/kernel/chr_drv/serial.c?v=0.97#L178">178</a> static void <a href="ident?v=0.97;i=com2_IRQ">com2_IRQ</a>(int unused)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -