📄 serial.c
字号:
<a name=L283 href="source/kernel/chr_drv/serial.c?v=0.97#L283">283</a> }<a name=L284 href="source/kernel/chr_drv/serial.c?v=0.97#L284">284</a> <a name=L285 href="source/kernel/chr_drv/serial.c?v=0.97#L285">285</a> void <a href="ident?v=0.97;i=serial_close">serial_close</a>(unsigned line, struct <a href="ident?v=0.97;i=file">file</a> * filp)<a name=L286 href="source/kernel/chr_drv/serial.c?v=0.97#L286">286</a> {<a name=L287 href="source/kernel/chr_drv/serial.c?v=0.97#L287">287</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=L288 href="source/kernel/chr_drv/serial.c?v=0.97#L288">288</a> int irq;<a name=L289 href="source/kernel/chr_drv/serial.c?v=0.97#L289">289</a> <a name=L290 href="source/kernel/chr_drv/serial.c?v=0.97#L290">290</a> if (line >= <a href="ident?v=0.97;i=NR_SERIALS">NR_SERIALS</a>)<a name=L291 href="source/kernel/chr_drv/serial.c?v=0.97#L291">291</a> return;<a name=L292 href="source/kernel/chr_drv/serial.c?v=0.97#L292">292</a> <a href="ident?v=0.97;i=info">info</a> = <a href="ident?v=0.97;i=serial_table">serial_table</a> + line;<a name=L293 href="source/kernel/chr_drv/serial.c?v=0.97#L293">293</a> if (!<a href="ident?v=0.97;i=info">info</a>->port)<a name=L294 href="source/kernel/chr_drv/serial.c?v=0.97#L294">294</a> return;<a name=L295 href="source/kernel/chr_drv/serial.c?v=0.97#L295">295</a> <a href="ident?v=0.97;i=outb">outb</a>(0x00,<a href="ident?v=0.97;i=info">info</a>->port+4); <b><i>/* reset DTR, RTS, */</i></b><a name=L296 href="source/kernel/chr_drv/serial.c?v=0.97#L296">296</a> irq = <a href="ident?v=0.97;i=info">info</a>->irq;<a name=L297 href="source/kernel/chr_drv/serial.c?v=0.97#L297">297</a> if (irq == 2)<a name=L298 href="source/kernel/chr_drv/serial.c?v=0.97#L298">298</a> irq = 9;<a name=L299 href="source/kernel/chr_drv/serial.c?v=0.97#L299">299</a> <a href="ident?v=0.97;i=free_irq">free_irq</a>(irq);<a name=L300 href="source/kernel/chr_drv/serial.c?v=0.97#L300">300</a> }<a name=L301 href="source/kernel/chr_drv/serial.c?v=0.97#L301">301</a> <a name=L302 href="source/kernel/chr_drv/serial.c?v=0.97#L302">302</a> static void <a href="ident?v=0.97;i=startup">startup</a>(unsigned short port)<a name=L303 href="source/kernel/chr_drv/serial.c?v=0.97#L303">303</a> {<a name=L304 href="source/kernel/chr_drv/serial.c?v=0.97#L304">304</a> int i;<a name=L305 href="source/kernel/chr_drv/serial.c?v=0.97#L305">305</a> <a name=L306 href="source/kernel/chr_drv/serial.c?v=0.97#L306">306</a> <a href="ident?v=0.97;i=outb_p">outb_p</a>(0x03,port+3); <b><i>/* reset DLAB */</i></b><a name=L307 href="source/kernel/chr_drv/serial.c?v=0.97#L307">307</a> <a href="ident?v=0.97;i=outb_p">outb_p</a>(0x0b,port+4); <b><i>/* set DTR,RTS, OUT_2 */</i></b><a name=L308 href="source/kernel/chr_drv/serial.c?v=0.97#L308">308</a> <a href="ident?v=0.97;i=outb_p">outb_p</a>(0x0f,port+1); <b><i>/* enable all intrs */</i></b><a name=L309 href="source/kernel/chr_drv/serial.c?v=0.97#L309">309</a> <a href="ident?v=0.97;i=inb_p">inb_p</a>(port+2);<a name=L310 href="source/kernel/chr_drv/serial.c?v=0.97#L310">310</a> <a href="ident?v=0.97;i=inb_p">inb_p</a>(port+6);<a name=L311 href="source/kernel/chr_drv/serial.c?v=0.97#L311">311</a> <a href="ident?v=0.97;i=inb_p">inb_p</a>(port+2);<a name=L312 href="source/kernel/chr_drv/serial.c?v=0.97#L312">312</a> <a href="ident?v=0.97;i=inb_p">inb_p</a>(port+5);<a name=L313 href="source/kernel/chr_drv/serial.c?v=0.97#L313">313</a> for (i = 0; i < 16 ; i++) {<a name=L314 href="source/kernel/chr_drv/serial.c?v=0.97#L314">314</a> <a href="ident?v=0.97;i=inb_p">inb_p</a>(port+0);<a name=L315 href="source/kernel/chr_drv/serial.c?v=0.97#L315">315</a> if (!(<a href="ident?v=0.97;i=inb_p">inb_p</a>(port+5) & 1))<a name=L316 href="source/kernel/chr_drv/serial.c?v=0.97#L316">316</a> break;<a name=L317 href="source/kernel/chr_drv/serial.c?v=0.97#L317">317</a> }<a name=L318 href="source/kernel/chr_drv/serial.c?v=0.97#L318">318</a> <a href="ident?v=0.97;i=inb_p">inb_p</a>(port+2);<a name=L319 href="source/kernel/chr_drv/serial.c?v=0.97#L319">319</a> <a href="ident?v=0.97;i=inb_p">inb_p</a>(port+5);<a name=L320 href="source/kernel/chr_drv/serial.c?v=0.97#L320">320</a> }<a name=L321 href="source/kernel/chr_drv/serial.c?v=0.97#L321">321</a> <a name=L322 href="source/kernel/chr_drv/serial.c?v=0.97#L322">322</a> void <a href="ident?v=0.97;i=change_speed">change_speed</a>(unsigned int line)<a name=L323 href="source/kernel/chr_drv/serial.c?v=0.97#L323">323</a> {<a name=L324 href="source/kernel/chr_drv/serial.c?v=0.97#L324">324</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=L325 href="source/kernel/chr_drv/serial.c?v=0.97#L325">325</a> unsigned short port,quot;<a name=L326 href="source/kernel/chr_drv/serial.c?v=0.97#L326">326</a> unsigned cflag,cval;<a name=L327 href="source/kernel/chr_drv/serial.c?v=0.97#L327">327</a> static unsigned short quotient[] = {<a name=L328 href="source/kernel/chr_drv/serial.c?v=0.97#L328">328</a> 0, 2304, 1536, 1047, 857,<a name=L329 href="source/kernel/chr_drv/serial.c?v=0.97#L329">329</a> 768, 576, 384, 192, 96,<a name=L330 href="source/kernel/chr_drv/serial.c?v=0.97#L330">330</a> 64, 48, 24, 12, 6, 3<a name=L331 href="source/kernel/chr_drv/serial.c?v=0.97#L331">331</a> };<a name=L332 href="source/kernel/chr_drv/serial.c?v=0.97#L332">332</a> <a name=L333 href="source/kernel/chr_drv/serial.c?v=0.97#L333">333</a> if (line >= <a href="ident?v=0.97;i=NR_SERIALS">NR_SERIALS</a>)<a name=L334 href="source/kernel/chr_drv/serial.c?v=0.97#L334">334</a> return;<a name=L335 href="source/kernel/chr_drv/serial.c?v=0.97#L335">335</a> <a href="ident?v=0.97;i=info">info</a> = <a href="ident?v=0.97;i=serial_table">serial_table</a> + line;<a name=L336 href="source/kernel/chr_drv/serial.c?v=0.97#L336">336</a> cflag = <a href="ident?v=0.97;i=info">info</a>->tty-><a href="ident?v=0.97;i=termios">termios</a>.c_cflag;<a name=L337 href="source/kernel/chr_drv/serial.c?v=0.97#L337">337</a> if (!(port = <a href="ident?v=0.97;i=info">info</a>->port))<a name=L338 href="source/kernel/chr_drv/serial.c?v=0.97#L338">338</a> return;<a name=L339 href="source/kernel/chr_drv/serial.c?v=0.97#L339">339</a> quot = quotient[cflag & <a href="ident?v=0.97;i=CBAUD">CBAUD</a>];<a name=L340 href="source/kernel/chr_drv/serial.c?v=0.97#L340">340</a> if (!quot)<a name=L341 href="source/kernel/chr_drv/serial.c?v=0.97#L341">341</a> <a href="ident?v=0.97;i=outb">outb</a>(0x00,port+4);<a name=L342 href="source/kernel/chr_drv/serial.c?v=0.97#L342">342</a> else if (!<a href="ident?v=0.97;i=inb">inb</a>(port+4))<a name=L343 href="source/kernel/chr_drv/serial.c?v=0.97#L343">343</a> <a href="ident?v=0.97;i=startup">startup</a>(port);<a name=L344 href="source/kernel/chr_drv/serial.c?v=0.97#L344">344</a> <b><i>/* byte size and parity */</i></b><a name=L345 href="source/kernel/chr_drv/serial.c?v=0.97#L345">345</a> cval = cflag & (<a href="ident?v=0.97;i=CSIZE">CSIZE</a> | <a href="ident?v=0.97;i=CSTOPB">CSTOPB</a>);<a name=L346 href="source/kernel/chr_drv/serial.c?v=0.97#L346">346</a> cval >>= 4;<a name=L347 href="source/kernel/chr_drv/serial.c?v=0.97#L347">347</a> if (cflag & <a href="ident?v=0.97;i=PARENB">PARENB</a>)<a name=L348 href="source/kernel/chr_drv/serial.c?v=0.97#L348">348</a> cval |= 8;<a name=L349 href="source/kernel/chr_drv/serial.c?v=0.97#L349">349</a> if (!(cflag & <a href="ident?v=0.97;i=PARODD">PARODD</a>))<a name=L350 href="source/kernel/chr_drv/serial.c?v=0.97#L350">350</a> cval |= 16;<a name=L351 href="source/kernel/chr_drv/serial.c?v=0.97#L351">351</a> <a href="ident?v=0.97;i=cli">cli</a>();<a name=L352 href="source/kernel/chr_drv/serial.c?v=0.97#L352">352</a> <a href="ident?v=0.97;i=outb_p">outb_p</a>(cval | 0x80,port+3); <b><i>/* set DLAB */</i></b><a name=L353 href="source/kernel/chr_drv/serial.c?v=0.97#L353">353</a> <a href="ident?v=0.97;i=outb_p">outb_p</a>(quot & 0xff,port); <b><i>/* LS of divisor */</i></b><a name=L354 href="source/kernel/chr_drv/serial.c?v=0.97#L354">354</a> <a href="ident?v=0.97;i=outb_p">outb_p</a>(quot >> 8,port+1); <b><i>/* MS of divisor */</i></b><a name=L355 href="source/kernel/chr_drv/serial.c?v=0.97#L355">355</a> <a href="ident?v=0.97;i=outb">outb</a>(cval,port+3); <b><i>/* reset DLAB */</i></b><a name=L356 href="source/kernel/chr_drv/serial.c?v=0.97#L356">356</a> <a href="ident?v=0.97;i=sti">sti</a>();<a name=L357 href="source/kernel/chr_drv/serial.c?v=0.97#L357">357</a> }<a name=L358 href="source/kernel/chr_drv/serial.c?v=0.97#L358">358</a> <a name=L359 href="source/kernel/chr_drv/serial.c?v=0.97#L359">359</a> static void (*<a href="ident?v=0.97;i=serial_handler">serial_handler</a>[<a href="ident?v=0.97;i=NR_SERIALS">NR_SERIALS</a>])(int) = {<a name=L360 href="source/kernel/chr_drv/serial.c?v=0.97#L360">360</a> <a href="ident?v=0.97;i=com1_IRQ">com1_IRQ</a>,<a href="ident?v=0.97;i=com2_IRQ">com2_IRQ</a>,<a href="ident?v=0.97;i=com3_IRQ">com3_IRQ</a>,<a href="ident?v=0.97;i=com4_IRQ">com4_IRQ</a><a name=L361 href="source/kernel/chr_drv/serial.c?v=0.97#L361">361</a> };<a name=L362 href="source/kernel/chr_drv/serial.c?v=0.97#L362">362</a> <a name=L363 href="source/kernel/chr_drv/serial.c?v=0.97#L363">363</a> <b><i>/*</i></b><a name=L364 href="source/kernel/chr_drv/serial.c?v=0.97#L364">364</a> <b><i> * this routine enables interrupts on 'line', and disables them for any</i></b><a name=L365 href="source/kernel/chr_drv/serial.c?v=0.97#L365">365</a> <b><i> * other serial line that shared the same IRQ. Braindamaged AT hardware.</i></b><a name=L366 href="source/kernel/chr_drv/serial.c?v=0.97#L366">366</a> <b><i> */</i></b><a name=L367 href="source/kernel/chr_drv/serial.c?v=0.97#L367">367</a> int <a href="ident?v=0.97;i=serial_open">serial_open</a>(unsigned line, struct <a href="ident?v=0.97;i=file">file</a> * filp)<a name=L368 href="source/kernel/chr_drv/serial.c?v=0.97#L368">368</a> {<a name=L369 href="source/kernel/chr_drv/serial.c?v=0.97#L369">369</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=L370 href="source/kernel/chr_drv/serial.c?v=0.97#L370">370</a> int irq,retval;<a name=L371 href="source/kernel/chr_drv/serial.c?v=0.97#L371">371</a> unsigned short port;<a name=L372 href="source/kernel/chr_drv/serial.c?v=0.97#L372">372</a> struct <a href="ident?v=0.97;i=sigaction">sigaction</a> sa;<a name=L373 href="source/kernel/chr_drv/serial.c?v=0.97#L373">373</a> <a name=L374 href="source/kernel/chr_drv/serial.c?v=0.97#L374">374</a> sa.sa_handler = <a href="ident?v=0.97;i=serial_handler">serial_handler</a>[line];<a name=L375 href="source/kernel/chr_drv/serial.c?v=0.97#L375">375</a> sa.sa_flags = <a href="ident?v=0.97;i=SA_INTERRUPT">SA_INTERRUPT</a>;<a name=L376 href="source/kernel/chr_drv/serial.c?v=0.97#L376">376</a> sa.sa_mask = 0;<a name=L377 href="source/kernel/chr_drv/serial.c?v=0.97#L377">377</a> sa.sa_restorer = <a href="ident?v=0.97;i=NULL">NULL</a>;<a name=L378 href="source/kernel/chr_drv/serial.c?v=0.97#L378">378</a> if (line >= <a href="ident?v=0.97;i=NR_SERIALS">NR_SERIALS</a>)<a name=L379 href="source/kernel/chr_drv/serial.c?v=0.97#L379">379</a> return -<a href="ident?v=0.97;i=ENODEV">ENODEV</a>;<a name=L380 href="source/kernel/chr_drv/serial.c?v=0.97#L380">380</a> <a href="ident?v=0.97;i=info">info</a> = <a href="ident?v=0.97;i=serial_table">serial_table</a> + line;<a name=L381 href="source/kernel/chr_drv/serial.c?v=0.97#L381">381</a> if (!(port = <a href="ident?v=0.97;i=info">info</a>->port))<a name=L382 href="source/kernel/chr_drv/serial.c?v=0.97#L382">382</a> return -<a href="ident?v=0.97;i=ENODEV">ENODEV</a>;<a name=L383 href="source/kernel/chr_drv/serial.c?v=0.97#L383">383</a> irq = <a href="ident?v=0.97;i=info">info</a>->irq;<a name=L384 href="source/kernel/chr_drv/serial.c?v=0.97#L384">384</a> if (irq == 2)<a name=L385 href="source/kernel/chr_drv/serial.c?v=0.97#L385">385</a> irq = 9;<a name=L386 href="source/kernel/chr_drv/serial.c?v=0.97#L386">386</a> if (retval = <a href="ident?v=0.97;i=irqaction">irqaction</a>(irq,&sa))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -