home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3533 < prev    next >
Encoding:
Internet Message Format  |  1991-06-24  |  60.8 KB

  1. From: gemini@geminix.in-berlin.de (Uwe Doering)
  2. Newsgroups: comp.unix.sysv386,comp.unix.xenix.sco,alt.sources
  3. Subject: FAS 2.09 async driver, part 2/4
  4. Message-ID: <7Q6RLMD@geminix.in-berlin.de>
  5. Date: 23 Jun 91 20:29:01 GMT
  6.  
  7. Submitted-by: gemini@geminix.in-berlin.de
  8. Archive-name: fas209/part02
  9.  
  10. #!/bin/sh
  11. # this is fas209.02 (part 2 of fas209)
  12. # do not concatenate these parts, unpack them in order with /bin/sh
  13. # file README continued
  14. #
  15. if test ! -r _shar_seq_.tmp; then
  16.     echo 'Please unpack part 1 first!'
  17.     exit 1
  18. fi
  19. (read Scheck
  20.  if test "$Scheck" != 2; then
  21.     echo Please unpack part "$Scheck" next!
  22.     exit 1
  23.  else
  24.     exit 0
  25.  fi
  26. ) < _shar_seq_.tmp || exit 1
  27. if test ! -f _shar_wnt_.tmp; then
  28.     echo 'x - still skipping README'
  29. else
  30. echo 'x - continuing file README'
  31. sed 's/^X//' << 'SHAR_EOF' >> 'README' &&
  32. X
  33. X     Makefile.ISC   A makefile for ISC 386/ix systems.  This is generic
  34. X                    and should work for all configurations of lines
  35. X                    and interrupts.
  36. X
  37. X     Makefile.ESIX  A makefile for ESIX systems.  This is generic
  38. X                    and should work for all configurations of lines
  39. X                    and interrupts.
  40. X
  41. X     Makefile.BELL  A makefile for Bell Tech/Intel UNIX 3.2 systems.  This
  42. X                    is generic and should work for all configurations of
  43. X                    lines and interrupts.
  44. X
  45. X     Makefile.SCO   A makefile for SCO UNIX 386 systems.  This is generic
  46. X                    and should work for all configurations of lines
  47. X                    and interrupts.
  48. X
  49. X     Makefile.X386  A makefile for SCO Xenix 386 systems.  This is generic
  50. X                    and should work for all configurations of lines
  51. X                    and interrupts.
  52. X
  53. X     Makefile.X286  A makefile for SCO Xenix 286 systems.  This is generic
  54. X                    and should work for all configurations of lines
  55. X                    and interrupts.
  56. X
  57. X     Makefile.ATT   A makefile for AT&T UNIX 386 systems.  This is generic
  58. X                    and should work for all configurations of lines
  59. X                    and interrupts.
  60. X
  61. X     Makefile.SVR4  A makefile for SysVr4 UNIX 386 systems.  This is generic
  62. X                    and should work for all configurations of lines
  63. X                    and interrupts.
  64. X
  65. X------------------------------------------------------------------------
  66. X
  67. XWhat you will need to use this package:
  68. X
  69. X     You will need one of the above mentioned UNIX systems with the
  70. X     kernel link kit and the software development package.
  71. X
  72. X------------------------------------------------------------------------
  73. X
  74. XThe original asy replacement driver for Microport UNIX/386 (FAS' predecessor)
  75. Xwas developed by
  76. X
  77. XJim Murray              INET            jjm%jjmhome@m2c.m2c.org
  78. X2 Mohawk Circle         UUCP            harvard!m2c!jjmhome!jjm
  79. XWestboro Mass 01581     
  80. XUSA                                     voice (508) 366-2813
  81. X
  82. XCredits to him for releasing this great driver to the Usenet community.
  83. XBut if you have problems with FAS please don't contact him because he
  84. Xwasn't involved in the developement of FAS.
  85. X
  86. XFAS was developed by
  87. X
  88. XUwe Doering             INET : gemini@geminix.in-berlin.de
  89. XBillstedter Pfad 17 b   UUCP : ...!unido!fub!geminix.in-berlin.de!gemini
  90. X1000 Berlin 20
  91. XGermany
  92. X
  93. X    ^    ^    ^    ^    ^    ^    ^    ^    ^    ^
  94. XSend your questions and bug reports to this address.
  95. SHAR_EOF
  96. echo 'File README is complete' &&
  97. true || echo 'restore of README failed'
  98. rm -f _shar_wnt_.tmp
  99. fi
  100. # ============= RELEASENOTES ==============
  101. if test -f 'RELEASENOTES' -a X"$1" != X"-c"; then
  102.     echo 'x - skipping RELEASENOTES (File already exists)'
  103.     rm -f _shar_wnt_.tmp
  104. else
  105. > _shar_wnt_.tmp
  106. echo 'x - extracting RELEASENOTES (Text)'
  107. sed 's/^X//' << 'SHAR_EOF' > 'RELEASENOTES' &&
  108. X     release 1.1a Sat Nov 11, 1989
  109. X
  110. X     This is an unofficial release as I'm not the original author
  111. X     of this async driver.
  112. X
  113. X     Uwe Doering             INET : gemini@geminix.in-berlin.de
  114. X     Billstedter Pfad 17 b   UUCP : ...!unido!fub!geminix.in-berlin.de!gemini
  115. X     1000 Berlin 20
  116. X     Germany
  117. X
  118. X     New Features:
  119. X
  120. X          Added a third minor tty device number for every physical
  121. X          port. See description preceding the asyopen function in
  122. X          asy.c. Changed the behavior of ttyxx, too.
  123. X
  124. X          Added output hardware handshake support for DSR. Now you
  125. X          can do handshake with CTS, DSR or both. Input hardware
  126. X          handshake is on if you use at least one of the output
  127. X          handshake signals.
  128. X
  129. X          More flexible support of additional interrupt registers
  130. X          on mux boards. This is fully configurable now.
  131. X
  132. X          Added support for the CREAD flag. If not set, receiver
  133. X          interrupts are still serviced, but the received characters
  134. X          are simply thrown away. This is not as elegant as disabeling
  135. X          the interrupts themselves, but with the already existing
  136. X          driver it was the easiest way, and the most new-bugs-preventing,
  137. X          too.
  138. X
  139. X          Added a lot of comments to the source so that the curious
  140. X          user can understand why and how things are done.
  141. X
  142. X
  143. X     Bug Fixes:
  144. X
  145. X          The hang-up-on-last-close flag (HUPCL) was ignored. DTR
  146. X          was asserted regardless of this flag.
  147. X
  148. X          Made the detection of CTS and DCD more bullet-proof.
  149. X          Especially because between a close and the next open of
  150. X          a line, where interrupts are ignored, the software copys of
  151. X          CTS and DCD must be set up propperly in the asyopen function
  152. X          or the tty line would be blocked under certain circum-
  153. X          stances. For similar reasons, there is also a setup in the
  154. X          asyparam function.
  155. X
  156. X          Rewrote the input character processing function to work
  157. X          according to the TERMIO(7) man page.
  158. X
  159. X          Changed the behavior of BREAK generation to let the
  160. X          transmitter drain before TX is set to low.
  161. X
  162. X          Changed line hangup procedure so that the closing
  163. X          process returns immediately and doesn't sleep during
  164. X          the hangup delay/time. Instead, if an other process tries
  165. X          to open the line while hangup is still in progress, this
  166. X          process will sleep until hangup is competed.
  167. X
  168. X          With DOS Merge, on MicroPort V/386 3.0e the linker was
  169. X          missing the function `init8250'. Reengineered this from
  170. X          a disassembler listing of MicroPort's original driver and
  171. X          modified it to work with the NS16550A 16-byte FIFO. This
  172. X          funktion was added simply to be able to link the kernel.
  173. X          DOS Merge's virtual COM ports are still unusable with this
  174. X          release, though. To include this function, add a `-DMERGE'
  175. X          to the CFLAGS line in your makefile.
  176. X
  177. X          Made a lot of other corrections and enhancements in both
  178. X          speed and functionallity. As a result of all my effords
  179. X          I think this driver is slightly faster, more versatile
  180. X          and much more stable than the original release.
  181. X
  182. X     ------------------------------------------------------------
  183. X          
  184. X     release 1.1b Sat Nov 25, 1989
  185. X
  186. X     New Features:
  187. X
  188. X          Changed the minor device number scheme again.
  189. X          There are now two main groups: The unblocked open
  190. X          and the blocked open. Every group has four sub-modes
  191. X          and an additional hardware handshake flag. All this
  192. X          is coded in the higher four bits of the minor device
  193. X          number. Because of this, the maximum of 32 ports was
  194. X          reduced to 16 ports so that the port number fits into
  195. X          the remaining lower four bits of the minor device number.
  196. X          32 dumb ports in a single machine would have been overkill
  197. X          anyway. For more details refer to the description in the
  198. X          README file.
  199. X
  200. X     ------------------------------------------------------------
  201. X          
  202. X     release 2.00 Mon Nov 27, 1989
  203. X
  204. X     As this release differs so much from the original version I got,
  205. X     I now declare this as independant from the original author
  206. X     Jim Murray. This allows me to introduce new release levels
  207. X     without wondering whether they will collide with Jim's releases.
  208. X     Of course many credits to Jim for writing this software in the
  209. X     first place. Without his driver as a base I never would have
  210. X     been able to do such kernel driver development.
  211. X
  212. X     Bug Fixes:
  213. X
  214. X          If there were glitches on the hardware handshake lines
  215. X          and the DCD line a getty on this port would sometimes
  216. X          hang and become an immortal process. I think this was
  217. X          because the output buffer wasn't flushed properly
  218. X          on carrier loss. I hope I fixed this now. We'll see.
  219. X
  220. X     ------------------------------------------------------------
  221. X          
  222. X     release 2.01 Tue Nov 28, 1989
  223. X
  224. X     Did some cleanup in the source code.
  225. X
  226. X     I splitted the driver into two parts: The driver itself and
  227. X     the file `space.c'.
  228. X     `space.c' contains all data structures necessary to configure
  229. X     the driver and is compiled at kernel link time. Therefore, if you
  230. X     change your serial card configuration you simply change `space.c'
  231. X     directly in the link kit directory and relink the kernel. No
  232. X     driver recompilation or installation is necessary for this.
  233. X     But note that whenever you use `make install' your setup in
  234. X     the link kit directory is overwritten by the original `space.c'
  235. X     file. Therefore, you should copy your new `space.c' back to
  236. X     the source directory when you are finished with the configuration.
  237. X
  238. X     Renamed the package to `FAS Final Async Solution'. The following
  239. X     files have been renamed:
  240. X          asy.c          -> fas.c
  241. X          asy.h          -> fas.h
  242. X          asy_conf-xxxxx -> space-xxxxx
  243. X
  244. X     ISC 386/ix is supported now. There are separate makefiles
  245. X     for uPort and ISC to cope with the differences in link kit
  246. X     installation.
  247. X
  248. X     Bug Fixes:
  249. X
  250. X          `getty' still hung sometimes on a line with hardware
  251. X          handshake. Tried to fix it this time.
  252. X
  253. X     ------------------------------------------------------------
  254. X          
  255. X     release 2.02 Thu Nov 30, 1989
  256. X
  257. X     Abandoned the distinction between space-xxxxx files with
  258. X     and without hardware flow control because this is selected
  259. X     by the minor device number now.
  260. X
  261. X     Bug Fixes:
  262. X
  263. X          Set the high and low water marks for hardware input flow
  264. X          control to higher values than software flow control. This
  265. X          gives precedence to software flow control if both methods
  266. X          are used. These marks are self-adjusting and don't need to
  267. X          be changed if some flavor of UNIX has a different buffer
  268. X          size than the standard 256 characters. Before this change
  269. X          concurrent use of both flow controls could cause trouble
  270. X          with some high-speed modems. This is fixed now.
  271. X
  272. X          A flush read or write buffer request now also clears the
  273. X          receiver or transmitter FIFO, respectively. An ioctl
  274. X          call with a TCSETA* command clears the FIFOs, too.
  275. X
  276. X     ------------------------------------------------------------
  277. X          
  278. X     release 2.03 Fri Dec 01, 1989
  279. X
  280. X     Wrote an installation guide. The driver should be quite
  281. X     easy to install now.
  282. X
  283. X     Added tty node configuration files for ISC.
  284. X
  285. X     Hardware input flow control is bound now to the level of the
  286. X     receiver ring buffer instead of the UNIX input buffer. This
  287. X     has the advantage that buffer size and trigger levels are
  288. X     defined in the driver and therefore can be varied as needed.
  289. X
  290. X     New Features:
  291. X
  292. X          Added a boot time status message that shows the init
  293. X          state of each port. This tells you immediately what
  294. X          ports are found and initted by the driver. Useful to
  295. X          determine hardware configuration problems. Look at
  296. X          the description in the README file. Thanks to
  297. X          Kritt Gierlewsen (kritt@einoed.UUCP) for this proposal.
  298. X
  299. X     ------------------------------------------------------------
  300. X          
  301. X     release 2.04 Thu Dec 07, 1989
  302. X
  303. X     Did some cleanup in the source.
  304. X
  305. X     Removed the FIFO clear from the ioctl function. We don't want
  306. X     to do things there that aren't in the book.
  307. X
  308. X     An ioctl call that switches off the CLOCAL flag will create
  309. X     a SIGHUP signal if the carrier is actually missing at this
  310. X     time.
  311. X
  312. X     Every device is tested now quite thoroughly during initialization.
  313. X     If the test fails the corresponding device keeps unconfigured.
  314. X
  315. X     ------------------------------------------------------------
  316. X          
  317. X     release 2.05 Sat Jan 13, 1990
  318. X
  319. X     This is the first public release of the FAS driver.
  320. X
  321. X     Special thanks to the sysops of my test sites, Axel Fischer
  322. X     (fischer@utower.UUCP) and Kritt Gierlewsen (kritt@einoed.UUCP).
  323. X
  324. X     FAS is now an independant driver with its own driver name (`fas'),
  325. X     major device number, link kit directory and other things necessary
  326. X     for a driver. The original asy driver may or may not be linked
  327. X     with the kernel. You only need it if you want to access some
  328. X     serial devices via the virtual COM ports of the DOS emulator
  329. X     (DosMerge or VP/ix) because the FAS driver doesn't have this
  330. X     (really vendor dependant) feature.
  331. X
  332. X     The default prefix for tty device node names is `ttyF' now.
  333. X     This prevents mix-ups with the device names of the original
  334. X     asy driver.
  335. X
  336. X     Dropped the SYSV/AT support. I couldn't test the driver
  337. X     for several release generations on uPort SYSV/AT, and because
  338. X     there are not very much systems left with that flavor of UNIX
  339. X     it doesn't make sense to try to maintain compatibility with it.
  340. X     If someone really wants to use this driver on a 286 he has
  341. X     to port it himself.
  342. X
  343. X     Improved the transmitter FIFO fill procedure. Now it will try
  344. X     harder to fill the FIFO as much as possible to cut down on
  345. X     transmitter interrupts.
  346. X
  347. X     Software input flow control (XON/XOFF) is controlled by the driver now.
  348. X     It is bound to the level of the receiver ring buffer (as is hardware
  349. X     flow control). As usual, it can be switched on and off by the
  350. X     IXOFF flag in the termio(7) structure.
  351. X
  352. X     Changed and speeded up the ring buffer -> unix buffer processing.
  353. X
  354. X     For ISC, the getty lines for the inittab file are installed
  355. X     by the makefile now.
  356. X
  357. X     The conditional compilation of the function `init8250' (for
  358. X     DosMerge) is now controlled by a define in `fas.h'. The compiler
  359. X     switch `-DMERGE' is not used any more.
  360. X
  361. X     Improved the documentation.
  362. X
  363. X     The signals used for modem control and hardware flow control are
  364. X     fully configurable in the `space.c' file now. Look at `fas.h' for
  365. X     possible macros and combinations.
  366. X
  367. X     There are some new modes for hardware flow control, for instance
  368. X     HO_CTS_ON_DSR. This means that CTS is only looked at if DSR is on.
  369. X     If DSR is off output is possible regardless of CTS. The underlying
  370. X     assumption here is that we can expect proper handshake handling
  371. X     only from devices that are in the ready state (indicated by DSR).
  372. X     As a spin-off the problem with the hanging getty on lines with
  373. X     turned-off terminals (mentioned in earlier releases) should be
  374. X     gone if you use this new mode.
  375. X
  376. X     If the XCLUDE-Flag is availabe (SYSV 3.2 because of Xenix
  377. X     compatibility) exclusive open of a device is possible.
  378. X
  379. X     The default size of the input ring buffer is now 5000 bytes.
  380. X     This makes streaming input more likely even on loaded systems.
  381. X
  382. X     Bug Fixes:
  383. X
  384. X          The task state busy flag wasn't reset in some rare cases.
  385. X          This could cause processes to become immortal while waiting
  386. X          for the busy flag.
  387. X
  388. X          Under some special conditions an ioctl call with a TCSETA?
  389. X          command could corrupt the last character in the transmitter
  390. X          shift register. This is fixed now.
  391. X
  392. X          More fixing of the busy flag handling was necessary.
  393. X          Co-ordinating several delayed tasks controlling this flag
  394. X          is kind of tricky.
  395. X
  396. X          After a TCSETA* ioctl command we disable the transmitter
  397. X          for 2 sec (measured from the last transmitted character)
  398. X          if the character format and/or speed has changed. This
  399. X          gives the receiving side some time to do the same changes.
  400. X          This is kind of experimental. There may be applications that
  401. X          suffer from this delay. You may change the #define ADAPT_TIME
  402. X          in `fas.h' to a smaller value.
  403. X
  404. X     ------------------------------------------------------------
  405. X          
  406. X     release 2.06 Fri Mar 16, 1990
  407. X
  408. X     This should have been patch #3 for release 2.05, but there are
  409. X     so many changes now that I decided to make it a new release.
  410. X     Therefore, some of the changes are described in the 2.05 release
  411. X     notes above but were never released to the public.
  412. X
  413. X     New Features:
  414. X
  415. X          There is a transmitter ring buffer now to make the output
  416. X          less system load dependent. This really speeds things up
  417. X          because the transmitter FIFO gets filled with more characters
  418. X          at once. The buffer size depends on the actual baud rate to
  419. X          prevent long output buffer drains at low speeds.
  420. X
  421. X          There are also bigger input buffers to make FAS more competitive
  422. X          against "intelligent" cards.
  423. X
  424. X          Lots of speed improvements and many small changes.
  425. X
  426. X     Bug Fixes:
  427. X
  428. X          Fixed input/output buffer flush on carrier loss while close
  429. X          is waiting for the output to drain.
  430. X
  431. X     ------------------------------------------------------------
  432. X          
  433. X     release 2.07 Tue Sep 18, 1990
  434. X
  435. X     This is a major redesign of the previous release. I put most of the
  436. X     time consuming tasks in one function that is invoked asynchronously
  437. X     by timeout calls. Inside this function most of the code runs at
  438. X     a lower system priority level (spl5) than the interrupts. That
  439. X     means that during character processing tty interrupts are allowed.
  440. X     This is the main key to operation at 38400 bps on multiple ports
  441. X     at the same time which is possible now with this release.
  442. X
  443. X     New Features:
  444. X
  445. X          FAS supports the VP/ix DOS emulator!
  446. X          Now you can throw out the vendor's original driver even
  447. X          if you like to have a serial mouse or modem access in DOS.
  448. X          Read the paragraph about VP/ix in the README file.
  449. X
  450. X          The Intel i82510 port chip is supported. It has separate
  451. X          4-character FIFOs for input and output. Although the
  452. X          NS16550A is much better this chip is your second choice
  453. X          if you can't get your hands on the National chips.
  454. X          Thanks to Christian Seyb (cs@gold.UUCP) for sending me
  455. X          patches and the necessary documentation for the Intel
  456. X          chips.
  457. X
  458. X          There is an init sequence in `space.c'. You can put any
  459. X          number of address-data pairs in a null terminated array
  460. X          to program your serial card or other hardware before
  461. X          FAS makes the first access to the ports. AST 4-port cards,
  462. X          for instance, have an additional port that needs to be
  463. X          written to with a certain bit pattern to allow shared
  464. X          interrupts. If you need to read a port to achieve the
  465. X          setting or resetting of flags as a side effect, this
  466. X          is possible, too.
  467. X
  468. X          ESIX is officially supported now.
  469. X
  470. X          SCO UNIX is officially supported, too. FAS needs to be
  471. X          compiled with the command line flag `-DSCO'. The makefile
  472. X          for SCO takes care of that. Thanks to Walter Mecky
  473. X          (walter@mecky.systemware.de) and Frank Simon
  474. X          (terra@sol.north.de) for helping me in making the necessary
  475. X          changes for SCO UNIX.
  476. X
  477. X          SCO Xenix 386 is also officially supported. FAS needs to be
  478. X          compiled with the command line flag `-DXENIX'. The makefile
  479. X          for SCO Xenix takes care of that. Thanks to Andreas
  480. X          Steinmetzler (andreas@oil.UUCP) for doing the port.
  481. X
  482. X          If you have the RTSFLOW and CTSFLOW termio(7) flags,
  483. X          hardware handshake can be controlled by them.
  484. X          Note that enabling handware flow control via the
  485. X          minor device number overrides these flags. If you
  486. X          like to use them you need to create tty device nodes
  487. X          with minor device numbers in which the bit for hardware
  488. X          handshake is set to 0. Look at the description in the
  489. X          README file for more details.
  490. X          Note also that if you choose to use RTSFLOW and CTSFLOW
  491. X          all your programs that do initial access to tty devices
  492. X          (getty, uucico, cu, SLIP dialup program etc.) need to know
  493. X          about these flags or hardware handshake will not be used.
  494. X
  495. X          The `O_EXCL' flag for the open(2) call is honored now.
  496. X          This allowes exclusive access to an FAS device without
  497. X          suffering from race conditions which could occure with
  498. X          the termio(7) XCLUDE flag method.
  499. X
  500. X          The `fas_test_device' function returns a digit now that
  501. X          indicates at which phase the test exited due to an error.
  502. X          This error digit is displayed in the boot message. Thanks
  503. X          to Brian Beattie (beattie@visenix.UUCP) for sending me
  504. X          the necessary patches.
  505. X
  506. X     Bug Fixes:
  507. X
  508. X          Automatic input FIFO flush after unblocking the getty
  509. X          open by the carrier or the unblock signal. This makes sure
  510. X          that there is no chance that there are characters in the
  511. X          FIFO that were received before the open got unblocked.
  512. X
  513. X          The sdevice entry for the AST 4-port card had a wrong
  514. X          I/O address range (`s_fas-mux4'). This didn't affect FAS
  515. X          but is checked by the kernel config program.
  516. X
  517. X          The gcc (GNU cc) support was removed because gcc's object
  518. X          file wants to link in some "helpful" functions that aren't
  519. X          contained in the kernel. But anyway, FAS is tuned so carefully
  520. X          and depends on the optimization behaviour of the AT&T
  521. X          standard C compiler that gcc won't have any advantages.
  522. X
  523. X          I changed the method with which the `fas_test_device' function
  524. X          waits for certain events. The `delay' function was used
  525. X          for that purpose but it turned out that with some flavors
  526. X          of UNIX it is prohibited to use this function during the
  527. X          xxinit phase of the boot process. Now a simple timeout loop
  528. X          is used instead.
  529. X
  530. X          Removed the ADAPT_TIME mechanismn introduced in release 2.05.
  531. X
  532. X          The open() call now returns an `EBUSY' error number if the
  533. X          device is already open and can't be opened in the desired
  534. X          mode at this time.
  535. X
  536. X          The handling of the RING signal needed fixing. Unlike the other
  537. X          three modem status lines RING generates an interrupt only at
  538. X          the trailing edge.
  539. X
  540. X          No SIGHUP signal is sent any more if an ioctl call clears
  541. X          the CLOCAL termio(7) flag while there is no carrier present.
  542. X          SIGHUP is only sent if the actual DCD modem line drops.
  543. X
  544. X          The files *-mux4 were renamed to *-ast4 because this type of
  545. X          card was originally developed by AST (AST 4-port card).
  546. X
  547. X     ------------------------------------------------------------
  548. X          
  549. X     release 2.08 Sun Feb 03, 1991
  550. X
  551. X     New Features:
  552. X
  553. X          Bell Tech/Intel UNIX 3.2 is supported.
  554. X
  555. X          SCO Xenix 286 is also supported now. Thanks to Nickolay Saukh
  556. X          (nms@saukh.rd.jvd.su) for providing the patches.
  557. X
  558. X          The Bell Tech HUB-6 card can be used with FAS. Thanks to
  559. X          Keith Walker (kew@cims2.UUCP) for the patches.
  560. X
  561. X          For AT&T derived flavors of UNIX there is a line automatically
  562. X          added to the kernel description file that makes the adding
  563. X          and removing of FAS possible via the `kconfig' program. Thanks
  564. X          to John Adams (johna@grumpy.boston.ma.us) for this idea.
  565. X
  566. X          There is a mechanismn now that prevents excessive modem status
  567. X          interrupts caused by crosstalking between wires or by a loose
  568. X          cable.
  569. X
  570. X          You can disable the FIFOs in a UART by "oring" the macro
  571. X          `NO_FIFO' to the base port address of this device. This is
  572. X          useful for mouse devices where you need immediate response
  573. X          to the mouse movement.
  574. X
  575. X          The meaning of the bit mapped part of the minor device
  576. X          numbers has changed. Some rather useless functions were
  577. X          removed in favor of more control over the hardware handshake
  578. X          modes. Even systems where the SCO RTSFLOW/CTSFLOW termio(7)
  579. X          flags are not available can now use half duplex hardware
  580. X          flow control (selected via the minor device number).
  581. X
  582. X          The assignment of RS232C lines to certain FAS functions
  583. X          is even more flexible now. This allows to connect two
  584. X          UNIX systems (with FAS) via a null modem cable, running
  585. X          a getty at both ends. For more details, read the paragraph
  586. X          about CABLING in the README file.
  587. X
  588. X          A special handling of the NS16550A input FIFO was introduced.
  589. X          This causes multiple receiver interrupts (on the same IRQ
  590. X          line) to be synchronized so that only one interrupt is
  591. X          necessary to process all receiving ports. This reduces the
  592. X          interrupt handling overhead and therefore results in lower
  593. X          CPU load for concurrent serial input at high speeds.
  594. X
  595. X          The `fas_event' function processes all scheduled events
  596. X          for all units with one single call. Previously, every unit
  597. X          launched its own timeout() call if there was work to
  598. X          do. This could lead to up to 16 timeouts at the same time,
  599. X          resulting in some timeout handling overhead. This overhead
  600. X          is minimized now.
  601. X
  602. X     Bug Fixes:
  603. X
  604. X          There were two bugs that could cause a port to lock up,
  605. X          resulting in an immortal process.
  606. X
  607. X          Almost any kernel sleep is killable now (at least with one or
  608. X          two `kill -9'). Therefore, there should be no more immortal
  609. X          processes. Even killing a process that is hanging in a
  610. X          close-on-exit call is possible.
  611. X
  612. X          The meaning of the RTSFLOW/CTSFLOW termio(7) flags was converted
  613. X          to what SCO had in mind (half duplex flow control). This is for
  614. X          compatibility reasons. Full duplex RTS/CTS hardware flow control
  615. X          is still possible via the minor device number method. Thanks to
  616. X          Dmitry V. Volodin (dvv@hq.demos.su) for providing me with the
  617. X          necessary knowledge.
  618. X
  619. X          If a process is already sleeping in a getty open it will only
  620. X          unblock on DCD low->high. In particular, if in the meantime
  621. X          the device was open for dialout and DCD is still present if
  622. X          the getty open takes over again this won't unblock the getty
  623. X          open any more.
  624. X
  625. X          And there were, as usual, a number of other small bug fixes.
  626. X
  627. X     ------------------------------------------------------------
  628. X          
  629. X     release 2.09 Sun Jun 23, 1991
  630. X
  631. X     New Features:
  632. X
  633. X          AT&T UNIX 3.2 Version 2.1 is supported.
  634. X
  635. X          Support was added for SysVr4 UNIX 386 (with the tty compatibility
  636. X          drivers). This was mostly a problem of ANSI-fying certain parts
  637. X          of the FAS sources. For this operating system, there is no VP/ix
  638. X          support in FAS. This will change when FAS is converted into a
  639. X          STREAMS driver.
  640. X
  641. X          Killing a process hanging on an FAS port that had output
  642. X          flow stopped was usually done by issuing one or two `kill -9'
  643. X          commands. However, this method could hang the whole UNIX kernel.
  644. X          Therefore, another method to release hung processes is
  645. X          introduced in this release.
  646. X          If you open an FAS device with the O_TRUNC flag, the input
  647. X          and output buffers of that device get flushed. As a side
  648. X          effect, if you had previously tried to kill a hung process,
  649. X          and it continued to hang on an FAS device, you simply have
  650. X          to open that device with the O_TRUNC flag, and the hung
  651. X          process is released. All you have to do is to type
  652. X          echo '\c' > /dev/ttyname
  653. X          and the device buffers are flushed.
  654. X
  655. X          There is a new array called fas_overrun[], which is of
  656. X          type `uint', that contains three receiver overrun counters
  657. X          for NS16450, i82510 and NS16550A UART chips, in that order.
  658. X          If you have a tool that permits you to look at kernel
  659. X          variables during runtime, you can determine yourself
  660. X          whether the problems you may have might be caused by
  661. X          lost input characters. With every receiver overrun, the
  662. X          respective counter is incremented by one.
  663. X
  664. X     Bug Fixes:
  665. X
  666. X          The problem with the excessive modem status interrupts
  667. X          is fixed. Well, kind of. It is suppressed, at least.
  668. X          Crosstalk between the lines in a serial cable wastes
  669. X          only a minor amount of CPU time now. Therefore, it isn't
  670. X          necessary any more to shut down a port when this happens.
  671. X          However, if you use an operating mode (selected by the
  672. X          minor device number) that assigns certain functions to
  673. X          the input pins at the RS232C connector (DCD, DSR, CTS and
  674. X          RI), and these pins toggle because of crosstalk in the cable,
  675. X          problems may still occure. But at least it won't panic the
  676. X          kernel any more, nor will it consume lots of CPU time.
  677. X
  678. X          Additionally, in operating modes where FAS doesn't need to
  679. X          know anything about modem status lines, the modem status
  680. X          interrupt is actually disabled. For instance, when a minor
  681. X          device number of 0 + port# is used. On the other hand,
  682. X          switching the device to DOS mode always _enables_ the
  683. X          modem status interrupts.
  684. X
  685. X          A problem was fixed when a port was in the canonical (cooked)
  686. X          mode and FAS still tried to protect the CLIST input buffer
  687. X          from overflowing. This blocked the connected terminal until
  688. X          a break signal or a hangup. The input buffer protection
  689. X          should, of course, only happen in raw mode.
  690. X
  691. X          The TIMEOUT tty state flag isn't used any more by FAS.
  692. X          Because this flag is used by the line discipline as well,
  693. X          its usage in FAS could cause problems.
  694. X
  695. X          There was a bug in the handling of one pointer in the
  696. X          fas_test_device() function.
  697. X
  698. X          In fas_event(), looping for the same port several times until
  699. X          all events are serviced could cause temporary deadlocks. We
  700. X          now don't loop any more. If an event occures while in fas_event(),
  701. X          but the branch responsible for processing was already passed,
  702. X          this event has to wait until the next call of fas_event()
  703. X          (usually one or two kernel ticks later).
  704. X
  705. X          The AIOCINFO ioctl() command returned the minor device number.
  706. X          Now it returns the unit number.
  707. X
  708. X          SIGHUP will be sent only if the port is the controlling terminal
  709. X          of a process group.
  710. X
  711. X          There was a problem with the initialization macros for the
  712. X          fas_modem[] and fas_flow[] arrays. Under Xenix 286, some
  713. X          of these macros expanded to a value of zero because the
  714. X          size of type int is 16 bits, while it is 32 bits for all
  715. X          the 386 UNIX flavors. This resulted in dropped bits with
  716. X          some macros that use the `<<' operator.
  717. X
  718. X          An fasopen() call is checked immediately for permissions now,
  719. X          even if another process is currently hanging in fasclose().
  720. X          The fasopen() call, of course, can be completed only after
  721. X          the other process has returned from fasclose().
  722. SHAR_EOF
  723. true || echo 'restore of RELEASENOTES failed'
  724. rm -f _shar_wnt_.tmp
  725. fi
  726. # ============= config-ast4 ==============
  727. if test -f 'config-ast4' -a X"$1" != X"-c"; then
  728.     echo 'x - skipping config-ast4 (File already exists)'
  729.     rm -f _shar_wnt_.tmp
  730. else
  731. > _shar_wnt_.tmp
  732. echo 'x - extracting config-ast4 (Text)'
  733. sed 's/^X//' << 'SHAR_EOF' > 'config-ast4' &&
  734. X* its character device number 4
  735. Xcharacter(4)
  736. X
  737. X* its name
  738. Xprefix = fas
  739. X
  740. X* The interrupt vectors handled by this controller
  741. Xintvec = 4
  742. X
  743. X* its mask level
  744. Xintpri = SPLTTY
  745. X
  746. X* the functions it supports
  747. Xfunctions = init, open, close, read, write, ioctl, tty
  748. SHAR_EOF
  749. true || echo 'restore of config-ast4 failed'
  750. rm -f _shar_wnt_.tmp
  751. fi
  752. # ============= config-ast4c12 ==============
  753. if test -f 'config-ast4c12' -a X"$1" != X"-c"; then
  754.     echo 'x - skipping config-ast4c12 (File already exists)'
  755.     rm -f _shar_wnt_.tmp
  756. else
  757. > _shar_wnt_.tmp
  758. echo 'x - extracting config-ast4c12 (Text)'
  759. sed 's/^X//' << 'SHAR_EOF' > 'config-ast4c12' &&
  760. X* its character device number 4
  761. Xcharacter(4)
  762. X
  763. X* its name
  764. Xprefix = fas
  765. X
  766. X* The interrupt vectors handled by this controller
  767. Xintvec = 9,4,3
  768. X
  769. X* its mask level
  770. Xintpri = SPLTTY
  771. X
  772. X* the functions it supports
  773. Xfunctions = init, open, close, read, write, ioctl, tty
  774. SHAR_EOF
  775. true || echo 'restore of config-ast4c12 failed'
  776. rm -f _shar_wnt_.tmp
  777. fi
  778. # ============= config-c1-2 ==============
  779. if test -f 'config-c1-2' -a X"$1" != X"-c"; then
  780.     echo 'x - skipping config-c1-2 (File already exists)'
  781.     rm -f _shar_wnt_.tmp
  782. else
  783. > _shar_wnt_.tmp
  784. echo 'x - extracting config-c1-2 (Text)'
  785. sed 's/^X//' << 'SHAR_EOF' > 'config-c1-2' &&
  786. X* its character device number 4
  787. Xcharacter(4)
  788. X
  789. X* its name
  790. Xprefix = fas
  791. X
  792. X* The interrupt vectors handled by this controller
  793. Xintvec = 4,3
  794. X
  795. X* its mask level
  796. Xintpri = SPLTTY
  797. X
  798. X* the functions it supports
  799. Xfunctions = init, open, close, read, write, ioctl, tty
  800. SHAR_EOF
  801. true || echo 'restore of config-c1-2 failed'
  802. rm -f _shar_wnt_.tmp
  803. fi
  804. # ============= config-c1-3 ==============
  805. if test -f 'config-c1-3' -a X"$1" != X"-c"; then
  806.     echo 'x - skipping config-c1-3 (File already exists)'
  807.     rm -f _shar_wnt_.tmp
  808. else
  809. > _shar_wnt_.tmp
  810. echo 'x - extracting config-c1-3 (Text)'
  811. sed 's/^X//' << 'SHAR_EOF' > 'config-c1-3' &&
  812. X* its character device number 4
  813. Xcharacter(4)
  814. X
  815. X* its name
  816. Xprefix = fas
  817. X
  818. X* The interrupt vectors handled by this controller
  819. Xintvec = 4,3,9
  820. X
  821. X* its mask level
  822. Xintpri = SPLTTY
  823. X
  824. X* the functions it supports
  825. Xfunctions = init, open, close, read, write, ioctl, tty
  826. SHAR_EOF
  827. true || echo 'restore of config-c1-3 failed'
  828. rm -f _shar_wnt_.tmp
  829. fi
  830. # ============= config-hub6 ==============
  831. if test -f 'config-hub6' -a X"$1" != X"-c"; then
  832.     echo 'x - skipping config-hub6 (File already exists)'
  833.     rm -f _shar_wnt_.tmp
  834. else
  835. > _shar_wnt_.tmp
  836. echo 'x - extracting config-hub6 (Text)'
  837. sed 's/^X//' << 'SHAR_EOF' > 'config-hub6' &&
  838. X* its character device number 4
  839. Xcharacter(4)
  840. X
  841. X* its name
  842. Xprefix = fas
  843. X
  844. X* The interrupt vectors handled by this controller
  845. Xintvec = 3
  846. X
  847. X* its mask level
  848. Xintpri = SPLTTY
  849. X
  850. X* the functions it supports
  851. Xfunctions = init, open, close, read, write, ioctl, tty
  852. SHAR_EOF
  853. true || echo 'restore of config-hub6 failed'
  854. rm -f _shar_wnt_.tmp
  855. fi
  856. # ============= fas.c ==============
  857. if test -f 'fas.c' -a X"$1" != X"-c"; then
  858.     echo 'x - skipping fas.c (File already exists)'
  859.     rm -f _shar_wnt_.tmp
  860. else
  861. > _shar_wnt_.tmp
  862. echo 'x - extracting fas.c (Text)'
  863. sed 's/^X//' << 'SHAR_EOF' > 'fas.c' &&
  864. X/* FAS Final Async Solution driver for 286/386 versions of system V UNIX */
  865. X
  866. X/* FAS was developed by
  867. XUwe Doering             INET : gemini@geminix.in-berlin.de
  868. XBillstedter Pfad 17 b   UUCP : ...!unido!fub!geminix.in-berlin.de!gemini
  869. X1000 Berlin 20
  870. XGermany
  871. X*/
  872. X
  873. X#if !defined (M_I286)
  874. X#ident    "@(#)fas.c    2.09"
  875. X#endif
  876. X
  877. X/* Note: This source code was quite heavily optimized for speed. You
  878. X         may wonder that register variables aren't used everywhere.
  879. X         This is because there is an overhead in memory accesses
  880. X         when using register variables. As you may know data accesses
  881. X         usually need much more wait states on the memory bus than
  882. X         code accesses (because of page or cache misses). Therefore,
  883. X         saving some data accesses has higher priority than saving
  884. X         code accesses.
  885. X
  886. X         You may also note some not very elegant constructions that
  887. X         may be intentional because they are faster. If you want to
  888. X         make style improvements you should check the assembler output
  889. X         whether this wouldn't slow things down.
  890. X
  891. X         Decisions for speed optimization were based on assembler
  892. X         listings produced by the standard UNIX V [34].X/386 C compiler.
  893. X*/
  894. X
  895. X#if defined (XENIX)
  896. X#include "fas.h"
  897. X#else
  898. X#include <sys/fas.h>
  899. X#if !defined (NO_ASM)
  900. X#include <sys/inline.h>
  901. X#endif
  902. X#endif
  903. X
  904. X#if defined (SCO) || defined (XENIX)
  905. X#define asyputchar sioputchar
  906. X#define asygetchar siogetchar
  907. X#endif
  908. X
  909. X#if defined (XENIX) || defined (NO_ASM)
  910. X#define intr_disable()    old_level = SPLINT ()
  911. X#define intr_restore()    (void) splx (old_level)
  912. X#define REGVAR
  913. X#else
  914. X/* This is a terrible ugly kludge to speed up the `inb' and `outb'
  915. X   functions. I.e., originally, the `outb' inline function had an
  916. X   overhead of four data memory accesses for parameter passing. This
  917. X   parameter passing actually consumed more clock cycles than the
  918. X   assembler `outb' command itself. Although this solution can't
  919. X   prevent unnessessary register moves it limits them at least to
  920. X   register to register moves that are much faster. You need a
  921. X   line like the following in the declaration part of every
  922. X   function that uses `inb' or `outb' calls:
  923. X
  924. X    REGVAR;
  925. X
  926. X   This hack should work with every compiler that knows about the
  927. X   UNIX V [34].X/386 standard compiler's inline assembler directives.
  928. X*/
  929. X
  930. Xasm    void loadal (val)
  931. X{
  932. X%reg    val;
  933. X    movl    val,%eax
  934. X%mem    val;
  935. X    movb    val,%al
  936. X}
  937. X
  938. Xasm    void loaddx (val)
  939. X{
  940. X%reg    val;
  941. X    movl    val,%edx
  942. X%mem    val;
  943. X    movw    val,%dx
  944. X}
  945. X
  946. Xasm    int outbyte ()
  947. X{
  948. X    outb    (%dx)
  949. X}
  950. X
  951. Xasm    int inbyte ()
  952. X{
  953. X    xorl    %eax,%eax
  954. X    inb    (%dx)
  955. X}
  956. X
  957. X/* The port parameter of the `outb' macro must be one of the predefined
  958. X   port macros from `fas.h' or a simple uint variable (no indirection
  959. X   is allowed). Additionally, `fip' must be a register variable in the
  960. X   functions where `outb' is used. This prevents the destruction of the
  961. X   `eax' CPU register while loading the `edx' register with the port
  962. X   address. This is highly compiler implementation specific.
  963. X*/
  964. X#define outb(port,val) (regvar = (val), loadal (regvar), regvar = (port), loaddx (regvar), outbyte ())
  965. X
  966. X#define inb(port) (regvar = (port), loaddx (regvar), inbyte ())
  967. X
  968. X#define REGVAR register uint    regvar
  969. X
  970. X/* This function inserts the address optimization assembler pseudo-op
  971. X   wherever called.
  972. X*/
  973. X
  974. Xasm    void optim ()
  975. X{
  976. X    .optim
  977. X}
  978. X
  979. X/* This dummy function has nothing to do but to call optim so that
  980. X   the `.optim' assembler pseudo-op will be included in the assembler
  981. X   file. This must be the first of all functions.
  982. X*/
  983. X
  984. X#if defined (OPTIM)    /* Define for uPort, ISC doesn't know about */
  985. Xstatic void        /* `.optim', but has turned on optimization by */
  986. Xdummy ()        /* default, so we don't need it there anyway. */
  987. X{
  988. X    optim ();
  989. X}
  990. X#endif
  991. X#endif    /* XENIX || NO_ASM */
  992. X
  993. X/* functions provided by this driver */
  994. Xint        fasinit ();
  995. Xint        fasopen ();
  996. Xint        fasclose ();
  997. Xint        fasread ();
  998. Xint        faswrite ();
  999. Xint        fasioctl ();
  1000. Xint        fasintr ();
  1001. X#if defined (NEED_PUT_GETCHAR)
  1002. Xint        asyputchar ();
  1003. Xint        asygetchar ();
  1004. X#endif
  1005. X#if defined (NEED_INIT8250)
  1006. Xint        init8250 ();
  1007. X#endif
  1008. Xstatic int    fas_proc ();
  1009. Xstatic void    fas_param ();
  1010. Xstatic void    fas_fproc ();
  1011. Xstatic void    fas_mproc ();
  1012. Xstatic uint    fas_rproc ();
  1013. Xstatic void    fas_xproc ();
  1014. Xstatic void    fas_event ();
  1015. X#if defined (HAVE_VPIX)
  1016. Xstatic int    fas_vpix_sr ();
  1017. X#endif
  1018. Xstatic void    fas_rxfer ();
  1019. Xstatic void    fas_xxfer ();
  1020. Xstatic void    fas_ihlw_check ();
  1021. Xstatic void    fas_hdx_check ();
  1022. Xstatic void    fas_hangup ();
  1023. Xstatic void    fas_timeout ();
  1024. Xstatic void    fas_cmd ();
  1025. Xstatic void    fas_open_device ();
  1026. Xstatic void    fas_close_device ();
  1027. Xstatic uint    fas_make_ctl_val ();
  1028. Xstatic int    fas_test_device ();
  1029. X
  1030. X/* external functions used by this driver */
  1031. Xextern int    ttinit ();
  1032. Xextern int    ttiocom ();
  1033. Xextern int    ttyflush ();
  1034. Xextern int    SPLINT ();
  1035. Xextern int    SPLWRK ();
  1036. Xextern int    splx ();
  1037. Xextern int    sleep ();
  1038. Xextern int    wakeup ();
  1039. Xextern void    longjmp ();
  1040. X#if !defined (SVR4)
  1041. Xextern int    signal ();
  1042. X#endif
  1043. Xextern int    timeout ();
  1044. Xextern int    untimeout ();
  1045. X#if defined (SCO) || defined (XENIX)
  1046. Xextern int    printcfg ();
  1047. X#else
  1048. Xextern int    printf ();
  1049. X#endif
  1050. X#if defined (HAVE_VPIX)
  1051. Xextern int    fubyte ();
  1052. Xextern int    subyte ();
  1053. Xextern int    v86setint ();
  1054. X#endif
  1055. X#if defined (XENIX)
  1056. Xextern int    inb ();
  1057. Xextern int    outb ();
  1058. X#endif
  1059. X
  1060. X/* external data objects used by this driver */
  1061. Xextern int    tthiwat [];
  1062. X
  1063. X/* the following stuff is defined in space.c */
  1064. Xextern uint    fas_physical_units;
  1065. Xextern ulong    fas_port [];
  1066. Xextern uint    fas_vec [];
  1067. Xextern uint    fas_init_seq [];
  1068. Xextern uint    fas_mcb [];
  1069. Xextern ulong    fas_modem [];
  1070. Xextern ulong    fas_flow [];
  1071. Xextern uint    fas_ctl_port [];
  1072. Xextern uint    fas_ctl_val [];
  1073. Xextern uint    fas_int_ack_port [];
  1074. Xextern uint    fas_int_ack [];
  1075. Xextern struct fas_info    fas_info [];
  1076. Xextern struct tty    fas_tty [];
  1077. Xextern struct fas_info    *fas_info_ptr [];
  1078. Xextern struct tty    *fas_tty_ptr [];
  1079. X/* end of space.c references */
  1080. X
  1081. X/* fas_is_initted
  1082. X   Flag to indicate that we have been thru init.
  1083. X   This is realy only necessary for systems that use asyputchar
  1084. X   and asygetchar but it doesn't hurt to have it anyway.
  1085. X*/
  1086. Xstatic int    fas_is_initted = FALSE;
  1087. X
  1088. X/* event_scheduled
  1089. X   Flag to indicate that the event handler has been scheduled
  1090. X   via the timeout() function.
  1091. X*/
  1092. Xstatic int    event_scheduled = FALSE;
  1093. X
  1094. X/* array of pointers to the first fas_info structure for each
  1095. X   interrupt vector
  1096. X*/
  1097. Xstatic struct fas_info    *fas_first_int_user [NUM_INT_VECTORS];
  1098. X
  1099. X/* counters for receiver overruns, each UART type has its own counter
  1100. X   in the following order: NS16450, i82510, NS16550A
  1101. X*/
  1102. Xuint    fas_overrun [3];
  1103. X
  1104. X/* the values for the various baud rates */
  1105. Xstatic uint    fas_speeds [CBAUD + 1] =
  1106. X{    1,            BAUD_BASE/50,
  1107. X    BAUD_BASE/75,        BAUD_BASE/110,
  1108. X    (2*BAUD_BASE+134)/269,    BAUD_BASE/150,
  1109. X    BAUD_BASE/200,        BAUD_BASE/300,
  1110. X    BAUD_BASE/600,        BAUD_BASE/1200,
  1111. X    BAUD_BASE/1800,        BAUD_BASE/2400,
  1112. X    BAUD_BASE/4800,        BAUD_BASE/9600,
  1113. X    BAUD_BASE/19200,    BAUD_BASE/38400
  1114. X};
  1115. X
  1116. X/* time for one character to completely leave the transmitter shift register */
  1117. Xstatic uint    fas_ctimes [CBAUD + 1] =
  1118. X{    1,        HZ*15/50+2,
  1119. X    HZ*15/75+2,    HZ*15/110+2,
  1120. X    HZ*30/269+2,    HZ*15/150+2,
  1121. X    HZ*15/200+2,    HZ*15/300+2,
  1122. X    HZ*15/600+2,    HZ*15/1200+2,
  1123. X    HZ*15/1800+2,    HZ*15/2400+2,
  1124. X    HZ*15/4800+2,    HZ*15/9600+2,
  1125. X    HZ*15/19200+2,    HZ*15/38400+2
  1126. X};
  1127. X
  1128. X/* dynamically adapt xmit buffer size to baud rate to prevent long buffer
  1129. X   drains at low speeds
  1130. X   These values are checked against boundaries and will be modified if
  1131. X   necessary before use. Checking is done in fas_param (). Drain time
  1132. X   is about 5 seconds with continuous character flow.
  1133. X*/
  1134. Xstatic uint    fas_xbuf_size [CBAUD + 1] =
  1135. X{    1,        50/2,
  1136. X    75/2,        110/2,
  1137. X    269/4,        150/2,
  1138. X    200/2,        300/2,
  1139. X    600/2,        1200/2,
  1140. X    1800/2,        2400/2,
  1141. X    4800/2,        9600/2,
  1142. X    19200/2,    38400/2
  1143. X};
  1144. X
  1145. X/* lookup table for minor device number -> open mode flags translation */
  1146. Xstatic uint    fas_open_modes [16] =
  1147. X{
  1148. X    OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_CLOCAL,
  1149. X    OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_CLOCAL | OS_HWO_HANDSHAKE
  1150. X                            | OS_HWI_HANDSHAKE,
  1151. X    OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_CLOCAL | OS_HWO_HANDSHAKE,
  1152. X    OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_CLOCAL | OS_HWO_HANDSHAKE
  1153. X                            | OS_HDX_HANDSHAKE,
  1154. X    OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON,
  1155. X    OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_HWO_HANDSHAKE
  1156. X                        | OS_HWI_HANDSHAKE,
  1157. X    OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_HWO_HANDSHAKE,
  1158. X    OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_HWO_HANDSHAKE
  1159. X                        | OS_HDX_HANDSHAKE,
  1160. X    OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_NO_DIALOUT,
  1161. X    OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_NO_DIALOUT | OS_HWO_HANDSHAKE
  1162. X                            | OS_HWI_HANDSHAKE,
  1163. X    OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_NO_DIALOUT | OS_HWO_HANDSHAKE,
  1164. X    OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_NO_DIALOUT | OS_HWO_HANDSHAKE
  1165. X                            | OS_HDX_HANDSHAKE,
  1166. X    OS_OPEN_FOR_GETTY | OS_WAIT_OPEN,
  1167. X    OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_HWO_HANDSHAKE
  1168. X                        | OS_HWI_HANDSHAKE,
  1169. X    OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_HWO_HANDSHAKE,
  1170. X    OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_HWO_HANDSHAKE
  1171. X                        | OS_HDX_HANDSHAKE
  1172. X};
  1173. X
  1174. X/* The following defines are used to access multiplexed ports. */
  1175. X#define GET_PORT(port,num) \
  1176. X    ((fip->device_flags.i & DF_CTL_EVERY)\
  1177. X            ? (port)\
  1178. X            : (port) + (num))
  1179. X
  1180. X#define fas_first_ctl(fip,port) \
  1181. X    ((void) (((fip)->device_flags.i & DF_CTL_FIRST)\
  1182. X            ? outb (CTL_PORT, (port).p.ctl)\
  1183. X            : 0))
  1184. X
  1185. X#define fas_ctl(fip,port) \
  1186. X    ((void) (((fip)->device_flags.i & (DF_CTL_FIRST | DF_CTL_EVERY))\
  1187. X            ? outb (CTL_PORT, (port).p.ctl)\
  1188. X            : 0))
  1189. X
  1190. X#define fas_first_outb(fip,port,val) \
  1191. X    ((void) (((fip)->device_flags.i & (DF_CTL_FIRST | DF_CTL_EVERY))\
  1192. X            ? outb (CTL_PORT, (port).p.ctl)\
  1193. X            : 0),\
  1194. X        (void) outb ((port).addr, (val)))
  1195. X
  1196. X#define fas_outb(fip,port,val) \
  1197. X    ((void) (((fip)->device_flags.i & DF_CTL_EVERY)\
  1198. X            ? outb (CTL_PORT, (port).p.ctl)\
  1199. X            : 0),\
  1200. X        (void) outb ((port).addr, (val)))
  1201. X
  1202. X#define fas_first_inb(fip,port) \
  1203. X    ((void) (((fip)->device_flags.i & (DF_CTL_FIRST | DF_CTL_EVERY))\
  1204. X            ? outb (CTL_PORT, (port).p.ctl)\
  1205. X            : 0),\
  1206. X        inb ((port).addr))
  1207. X
  1208. X#define fas_inb(fip,port) \
  1209. X    ((void) (((fip)->device_flags.i & DF_CTL_EVERY)\
  1210. X            ? outb (CTL_PORT, (port).p.ctl)\
  1211. X            : 0),\
  1212. X        inb ((port).addr))
  1213. X
  1214. X/* The following defines are used to take apart the minor device numbers. */
  1215. X#define GET_UNIT(dev)        ((dev) & 0x0f)
  1216. X#define GET_OPEN_MODE(dev)    (fas_open_modes [((dev) >> 4) & 0x0f])
  1217. X
  1218. X/* lock device against concurrent use */
  1219. X#define get_device_lock(fip,prio) \
  1220. X{\
  1221. X    /* sleep while device is used by an other process */\
  1222. X    while ((fip)->device_flags.i & DF_DEVICE_LOCKED)\
  1223. X        (void) sleep ((caddr_t) &(fip)->device_flags.i, (prio));\
  1224. X    (fip)->device_flags.s |= DF_DEVICE_LOCKED;\
  1225. X}
  1226. X
  1227. X/* release device */
  1228. X#define release_device_lock(fip) \
  1229. X{\
  1230. X    (fip)->device_flags.s &= ~DF_DEVICE_LOCKED;\
  1231. X    /* wakeup the process that may wait for this device */\
  1232. X    (void) wakeup ((caddr_t) &(fip)->device_flags.i);\
  1233. X}
  1234. X
  1235. X/* schedule event */
  1236. X#define event_sched(fip,event) \
  1237. X{\
  1238. X    (fip)->event_flags.s |= (event);\
  1239. X    if (!event_scheduled)\
  1240. X    {\
  1241. X        event_scheduled = TRUE;\
  1242. X        (void) timeout (fas_event, (void *) NULL,\
  1243. X                (EVENT_TIME) * (HZ) / 1000);\
  1244. X    }\
  1245. X}
  1246. X
  1247. X/* fasinit
  1248. X   This routine checks for the presense of the devices in the fas_port
  1249. X   array and if the device is present tests and initializes it.
  1250. X   During the initialization if the device is determined to be an
  1251. X   NS16550A chip the DF_DEVICE_IS_NS16550A flag is set and the FIFOs will
  1252. X   be used. If the device is an i82510 chip the DF_DEVICE_IS_I82510 flag
  1253. X   is set and the device will be handled accordingly.
  1254. X*/
  1255. X
  1256. Xint
  1257. Xfasinit ()
  1258. X{
  1259. X    register struct fas_info    *fip;
  1260. X    register uint    unit;
  1261. X    uint    logical_units, port, *seq_ptr;
  1262. X    char    port_stat [MAX_UNITS + 1];
  1263. X    REGVAR;
  1264. X
  1265. X    if (fas_is_initted)
  1266. X        return (0);
  1267. X
  1268. X    fas_is_initted = TRUE;
  1269. X
  1270. X    /* execute the init sequence for the serial card */
  1271. X    for (seq_ptr = fas_init_seq; *seq_ptr; seq_ptr++)
  1272. X    {
  1273. X        port = *seq_ptr;
  1274. X        seq_ptr++;
  1275. X        if (*seq_ptr & READ_PORT)
  1276. X            (void) inb (port);
  1277. X        else
  1278. X            (void) outb (port, *seq_ptr);
  1279. X    }
  1280. X
  1281. X    /* setup the list of pointers to the tty structures */
  1282. X    for (unit = 0, logical_units = fas_physical_units * 2;
  1283. X        unit < logical_units; unit++)
  1284. X        fas_tty_ptr [unit] = &fas_tty [unit];
  1285. X
  1286. X    /* setup and initialize all serial ports */
  1287. X    for (unit = 0; unit < fas_physical_units; unit++)
  1288. X    {
  1289. X        fas_info_ptr [unit] = fip = &fas_info [unit];
  1290. X        port_stat [unit] = '-';
  1291. X        if (port = (uint) ((ushort) (fas_port [unit])))
  1292. X        {
  1293. X            /* check the int vector */
  1294. X            if (fas_vec [unit] >= NUM_INT_VECTORS)
  1295. X            {
  1296. X                port_stat [unit] = '>';
  1297. X                continue;
  1298. X            }
  1299. X
  1300. X            /* init all of its ports */
  1301. X            if (fas_ctl_port [unit])
  1302. X            {
  1303. X                fip->ctl_port = fas_ctl_port [unit];
  1304. X
  1305. X                if (fas_ctl_val [unit] & 0xff00)
  1306. X                    fip->device_flags.s |= DF_CTL_EVERY;
  1307. X                else
  1308. X                    fip->device_flags.s |= DF_CTL_FIRST;
  1309. X            }
  1310. X
  1311. X            fip->port_0.p.addr = GET_PORT (port, 0);
  1312. X            fip->port_1.p.addr = GET_PORT (port, 1);
  1313. X            fip->port_2.p.addr = GET_PORT (port, 2);
  1314. X            fip->port_3.p.addr = GET_PORT (port, 3);
  1315. X            fip->port_4.p.addr = GET_PORT (port, 4);
  1316. X            fip->port_5.p.addr = GET_PORT (port, 5);
  1317. X            fip->port_6.p.addr = GET_PORT (port, 6);
  1318. X            fip->port_0.p.ctl = fas_make_ctl_val (fip, unit, 0);
  1319. X            fip->port_1.p.ctl = fas_make_ctl_val (fip, unit, 1);
  1320. X            fip->port_2.p.ctl = fas_make_ctl_val (fip, unit, 2);
  1321. X            fip->port_3.p.ctl = fas_make_ctl_val (fip, unit, 3);
  1322. X            fip->port_4.p.ctl = fas_make_ctl_val (fip, unit, 4);
  1323. X            fip->port_5.p.ctl = fas_make_ctl_val (fip, unit, 5);
  1324. X            fip->port_6.p.ctl = fas_make_ctl_val (fip, unit, 6);
  1325. X            fip->vec = fas_vec [unit];
  1326. X            fip->modem.l = fas_modem [unit];
  1327. X            fip->flow.l = fas_flow [unit];
  1328. X
  1329. X            /* mask off invalid bits */
  1330. X            fip->modem.m.di &= MC_ANY_CONTROL;
  1331. X            fip->modem.m.eo &= MC_ANY_CONTROL;
  1332. X            fip->modem.m.ei &= MC_ANY_CONTROL;
  1333. X            fip->modem.m.ca &= MS_ANY_PRESENT;
  1334. X            fip->flow.m.ic &= MC_ANY_CONTROL;
  1335. X            fip->flow.m.oc &= MS_ANY_PRESENT;
  1336. X            fip->flow.m.oe &= MS_ANY_PRESENT;
  1337. X            fip->flow.m.hc &= MC_ANY_CONTROL;
  1338. X
  1339. X            fip->recv_ring_put_ptr = fip->recv_buffer;
  1340. X            fip->recv_ring_take_ptr = fip->recv_buffer;
  1341. X            fip->xmit_ring_put_ptr = fip->xmit_buffer;
  1342. X            fip->xmit_ring_take_ptr = fip->xmit_buffer;
  1343. X            fip->xmit_fifo_size = 1;
  1344. X
  1345. X            fip->ier = IE_NONE;    /* disable all ints */
  1346. X            fas_first_outb (fip, INT_ENABLE_PORT, fip->ier);
  1347. X
  1348. X            /* is there a serial chip ? */
  1349. X            if (fas_inb (fip, INT_ENABLE_PORT) != fip->ier)
  1350. X            {
  1351. X                port_stat [unit] = '?';
  1352. X                continue;    /* a hardware error */
  1353. X            }
  1354. X
  1355. X            /* test the chip thoroughly */
  1356. X            if ((port_stat [unit] = (fas_test_device (fip) + '0'))
  1357. X                != '0')
  1358. X            {
  1359. X                continue;    /* a hardware error */
  1360. X            }
  1361. X
  1362. X            fip->lcr = 0;
  1363. X            fas_outb (fip, LINE_CTL_PORT, fip->lcr);
  1364. X            fip->mcr = fas_mcb [unit] | fip->modem.m.di;
  1365. X            fas_outb (fip, MDM_CTL_PORT, fip->mcr);
  1366. X
  1367. X            port_stat [unit] = '*';
  1368. X
  1369. X            /* let's see if it's an NS16550A */
  1370. X            fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_INIT_CMD);
  1371. X            if (!(~fas_inb (fip, INT_ID_PORT) & II_NS_FIFO_ENABLED))
  1372. X            {
  1373. X                fip->device_flags.s |= DF_DEVICE_IS_NS16550A;
  1374. X                fip->xmit_fifo_size = OUTPUT_NS_FIFO_SIZE;
  1375. X                port_stat [unit] = 'F';
  1376. X                fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
  1377. X            }
  1378. X            else
  1379. X            {
  1380. X                fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
  1381. X                /* or is it an i82510 ? */
  1382. X                fas_outb (fip, I_BANK_PORT, I_BANK_2);
  1383. X                if (!(~fas_inb (fip, I_BANK_PORT) & I_BANK_2))
  1384. X                {
  1385. X                    fip->device_flags.s |= DF_DEVICE_IS_I82510;
  1386. X                    fip->xmit_fifo_size = OUTPUT_I_FIFO_SIZE;
  1387. X                    port_stat [unit] = 'f';
  1388. X                    fas_outb (fip, I_BANK_PORT, I_BANK_1);
  1389. X                    fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
  1390. X                    fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
  1391. X                }
  1392. X                fas_outb (fip, I_BANK_PORT, I_BANK_0);
  1393. X            }
  1394. X
  1395. X            /* disable FIFOs if requested in space.c */
  1396. X            if ((fas_port [unit] & NO_FIFO) && (fip->device_flags.i
  1397. X                        & (DF_DEVICE_IS_NS16550A
  1398. X                            | DF_DEVICE_IS_I82510)))
  1399. X            {
  1400. X                fip->device_flags.s &= ~(DF_DEVICE_IS_NS16550A
  1401. X                            | DF_DEVICE_IS_I82510);
  1402. X                fip->xmit_fifo_size = 1;
  1403. X                port_stat [unit] = '+';
  1404. X            }
  1405. X
  1406. X            /* clear potential interrupts */
  1407. X            (void) fas_inb (fip, MDM_STATUS_PORT);
  1408. X            (void) fas_inb (fip, RCV_DATA_PORT);
  1409. X            (void) fas_inb (fip, RCV_DATA_PORT);
  1410. X            (void) fas_inb (fip, LINE_STATUS_PORT);
  1411. X            (void) fas_inb (fip, INT_ID_PORT);
  1412. X            if (port = fas_int_ack_port [fip->vec])
  1413. X                (void) outb (port, fas_int_ack [fip->vec]);
  1414. X
  1415. X            /* show that it is present and configured */
  1416. X            fip->device_flags.s |= DF_DEVICE_CONFIGURED;
  1417. X        }
  1418. X    }
  1419. X
  1420. X#if defined (NEED_PUT_GETCHAR)
  1421. X    fip = &fas_info [0];
  1422. X    fip->mcr &= ~fip->modem.m.di;
  1423. X    fip->mcr |= INITIAL_MDM_CONTROL;
  1424. X    fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
  1425. X
  1426. X    fip->lcr = INITIAL_LINE_CONTROL;
  1427. X    fas_outb (fip, LINE_CTL_PORT, fip->lcr | LC_ENABLE_DIVISOR);
  1428. X    fas_outb (fip, DIVISOR_LSB_PORT, INITIAL_BAUD_RATE);
  1429. X    fas_outb (fip, DIVISOR_MSB_PORT, (INITIAL_BAUD_RATE) >> 8);
  1430. X    fas_outb (fip, LINE_CTL_PORT, fip->lcr);
  1431. X#endif
  1432. X
  1433. X#if defined (SCO) || defined (XENIX)
  1434. X    for (unit = 0; unit < fas_physical_units; unit++)
  1435. X        (void) printcfg ("fas", (uint) ((ushort) (fas_port [unit])), 7,
  1436. X                    fas_vec [unit], -1,
  1437. X                    "unit=%d type=%c release=2.09.0",
  1438. X                    unit, port_stat [unit]);
  1439. X#else
  1440. X    port_stat [unit] = '\0';
  1441. X    (void) printf ("\nFAS 2.09.0 async driver: Unit 0-%d init state is [%s]\n\n",
  1442. X            unit - 1,
  1443. X            port_stat);
  1444. X#endif
  1445. X    return (0);
  1446. X}
  1447. X
  1448. X/* Open a tty line. This function is called for every open, as opposed
  1449. X   to the fasclose function which is called only with the last close.
  1450. X*/
  1451. Xint
  1452. Xfasopen (dev, flag)
  1453. Xint    dev;
  1454. Xint    flag;
  1455. X{
  1456. X    register struct fas_info    *fip;
  1457. X    register struct tty        *ttyp;
  1458. X    register uint    open_mode;
  1459. X    uint    physical_unit;
  1460. X    int    have_lock;
  1461. X    int    old_level;
  1462. X
  1463. X    physical_unit = GET_UNIT (dev);
  1464. X
  1465. X    /* check for valid port number */
  1466. X    if (physical_unit >= fas_physical_units)
  1467. X    {
  1468. X        u.u_error = ENXIO;
  1469. X        return (-1);
  1470. X    }
  1471. X
  1472. X    fip = fas_info_ptr [physical_unit];
  1473. X
  1474. X    /* was the port present at init time ? */
  1475. X    if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))
  1476. X    {
  1477. X        u.u_error = ENXIO;
  1478. X        return (-1);
  1479. X    }
  1480. X
  1481. X    open_mode = GET_OPEN_MODE (dev);
  1482. X    have_lock = FALSE;
  1483. X    old_level = SPLINT ();
  1484. X
  1485. X    /* loop until we've got the device lock and, owning the lock, we've
  1486. X       checked whether the current open mode permits us to open the
  1487. X       device
  1488. X    */
  1489. X    for (;;)
  1490. X    {
  1491. X        /* If this is a getty open, the device is already open for
  1492. X           dialout and the FNDELAY flag is not set, wait until device
  1493. X           is closed.
  1494. X        */
  1495. X        while ((open_mode & OS_OPEN_FOR_GETTY)
  1496. X                    && (fip->o_state & OS_OPEN_FOR_DIALOUT)
  1497. X                    && !(flag & FNDELAY))
  1498. X        {
  1499. X            if (have_lock)
  1500. X            {
  1501. X                release_device_lock (fip);
  1502. X                have_lock = FALSE;
  1503. X            }
  1504. X            (void) sleep ((caddr_t) &fip->o_state, TTIPRI);
  1505. X        }
  1506. X        
  1507. X        /* If the device is already open and another open uses a
  1508. X           different open mode or if a getty open waits for carrier
  1509. X           and doesn't allow parallel dialout opens, return with
  1510. X           EBUSY error.
  1511. X        */
  1512. X        if ((fip->o_state & ((open_mode & OS_OPEN_FOR_GETTY)
  1513. X                    ? (OS_OPEN_STATES | OS_WAIT_OPEN)
  1514. X                    : (OS_OPEN_STATES | OS_NO_DIALOUT)))
  1515. X            && ((flag & FEXCL)
  1516. X                || ((open_mode ^ fip->o_state) & (u.u_uid
  1517. X                            ? OS_TEST_MASK
  1518. X                            : OS_SU_TEST_MASK))))
  1519. X        {
  1520. X            if (have_lock)
  1521. X                release_device_lock (fip);
  1522. X            (void) splx (old_level);
  1523. X            u.u_error = EBUSY;
  1524. X            return (-1);
  1525. X        }
  1526. X
  1527. X        /* If device is already open and the FTRUNC flag is set,
  1528. X           flush input and output buffers. This may be used to
  1529. X           release processes that got stuck in fasclose() during
  1530. X           an exit() call.
  1531. X        */
  1532. X        if ((fip->o_state & OS_OPEN_STATES) && (flag & FTRUNC))
  1533. X        {
  1534. X            flag &= ~FTRUNC;    /* flush only once */
  1535. X            (void) SPLWRK ();
  1536. X            (void) ttyflush (fip->tty, FREAD | FWRITE);
  1537. X            (void) SPLINT ();
  1538. X        }
  1539. X
  1540. X        /* if we don't have the device lock, yet, try to get it */
  1541. X        if (!have_lock)
  1542. X        {
  1543. X            if (fip->device_flags.i & DF_DEVICE_LOCKED)
  1544. X            {
  1545. X                get_device_lock (fip, TTIPRI);
  1546. X                have_lock = TRUE;
  1547. X                /* we had to sleep for some time to get the
  1548. X                   lock, therefore, re-check whether the
  1549. X                   current open mode still permits us to
  1550. X                   open the device
  1551. X                */
  1552. X                continue;
  1553. X            }
  1554. X            else
  1555. X                get_device_lock (fip, TTIPRI);
  1556. X        }
  1557. X
  1558. X        break;
  1559. X    }
  1560. X
  1561. X    /* disable subsequent opens */
  1562. X    if (flag & FEXCL)
  1563. X        open_mode |= OS_EXCLUSIVE_OPEN_1;
  1564. X
  1565. X    /* set up pointer to tty structure */
  1566. X    ttyp = (open_mode & OS_OPEN_FOR_GETTY)
  1567. X        ? fas_tty_ptr [physical_unit + fas_physical_units]
  1568. X        : fas_tty_ptr [physical_unit];
  1569. X
  1570. X    /* things to do on first open only */
  1571. X    if (!(fip->o_state & ((open_mode & OS_OPEN_FOR_GETTY)
  1572. X                ? (OS_OPEN_STATES | OS_WAIT_OPEN)
  1573. X                : OS_OPEN_STATES)))
  1574. X    {
  1575. X        /* init data structures */
  1576. X        fip->tty = ttyp;
  1577. X        (void) ttinit (ttyp);
  1578. X        ttyp->t_proc = fas_proc;
  1579. X        fip->po_state = fip->o_state;
  1580. X        fip->o_state = open_mode & ~OS_OPEN_STATES;
  1581. X#if defined (HAVE_VPIX)
  1582. X        /* initialize VP/ix related variables */
  1583. X        fip->v86_proc = (v86_t *) NULL;
  1584. X        fip->v86_intmask = 0;
  1585. X        fip->v86_ss.ss_start = CSTART;
  1586. X        fip->v86_ss.ss_stop = CSTOP;
  1587. X#endif
  1588. X        fas_open_device (fip);        /* open physical device */
  1589. X        fas_param (fip, HARD_INIT);    /* set up port registers */
  1590. X
  1591. X        /* allow pending tty interrupts */
  1592. X        (void) SPLWRK ();
  1593. X        (void) SPLINT ();
  1594. X    }
  1595. X
  1596. X    /* If getty open and the FNDELAY flag is not set,
  1597. X       block and wait for carrier if device not yet open.
  1598. X    */
  1599. X    if ((open_mode & OS_OPEN_FOR_GETTY) && !(flag & FNDELAY))
  1600. X    {
  1601. X        /* sleep while open for dialout or no carrier */
  1602. X        while ((fip->o_state & OS_OPEN_FOR_DIALOUT)
  1603. X            || !(ttyp->t_state & (ISOPEN | CARR_ON)))
  1604. X        {
  1605. X            ttyp->t_state |= WOPEN;
  1606. X            release_device_lock (fip);
  1607. X            (void) sleep ((caddr_t) &ttyp->t_canq, TTIPRI);
  1608. X            get_device_lock (fip, TTIPRI);
  1609. X        }
  1610. X        ttyp->t_state &= ~WOPEN;
  1611. X    }
  1612. X
  1613. X    /* wakeup processes that are still sleeping in getty open */
  1614. X    if (ttyp->t_state & WOPEN)
  1615. X        (void) wakeup ((caddr_t) &ttyp->t_canq);
  1616. X
  1617. X    /* we need to flush the receiver with the first open */
  1618. X    if (!(fip->o_state & OS_OPEN_STATES))
  1619. X        fas_cmd (fip, ttyp, T_RFLUSH);
  1620. X
  1621. X    (*linesw [ttyp->t_line].l_open) (ttyp);
  1622. X
  1623. X    /* set open type flags */
  1624. X    fip->o_state = open_mode;
  1625. X
  1626. X    release_device_lock (fip);
  1627. X    (void) splx (old_level);
  1628. X    return (0);
  1629. X}
  1630. X
  1631. X/* Close a tty line. This is only called if there is no other
  1632. X   concurrent open left. A blocked getty open is not counted as
  1633. X   a concurrent open because in this state it isn't really open.
  1634. X*/
  1635. Xint
  1636. Xfasclose (dev)
  1637. Xint    dev;
  1638. X{
  1639. X    register struct fas_info    *fip;
  1640. X    register struct tty        *ttyp;
  1641. X    uint    physical_unit;
  1642. X    uint    open_mode;
  1643. X    int    old_level;
  1644. X
  1645. X    physical_unit = GET_UNIT (dev);
  1646. X
  1647. X    fip = fas_info_ptr [physical_unit];
  1648. X
  1649. X    open_mode = GET_OPEN_MODE (dev);
  1650. X
  1651. X    /* set up pointer to tty structure */
  1652. X    ttyp = (open_mode & OS_OPEN_FOR_GETTY)
  1653. X        ? fas_tty_ptr [physical_unit + fas_physical_units]
  1654. X        : fas_tty_ptr [physical_unit];
  1655. X    
  1656. X    old_level = SPLINT ();
  1657. X    get_device_lock (fip, TTIPRI);
  1658. X
  1659. X    /* wait for output buffer drain only if device was open */
  1660. X    if (ttyp->t_state & ISOPEN)
  1661. X    {
  1662. X        /* wait for buffer drain and catch interrupts */
  1663. X        while (ttyp->t_outq.c_cc || (ttyp->t_state & (BUSY | TIMEOUT)))
  1664. X        {
  1665. X            ttyp->t_state |= TTIOW;
  1666. X            if (sleep ((caddr_t) &ttyp->t_oflag, TTOPRI | PCATCH))
  1667. X            {
  1668. X                /* caught signal */
  1669. X                ttyp->t_state &= ~TTIOW;
  1670. X                release_device_lock (fip);
  1671. X                (void) splx (old_level);
  1672. X                longjmp (u.u_qsav);
  1673. X            }
  1674. X        }
  1675. X        /* block transmitter and wait until it is
  1676. X           empty
  1677. X        */
  1678. X        fip->device_flags.s |= DF_XMIT_LOCKED;
  1679. X        while (fip->device_flags.i & (DF_XMIT_BUSY
  1680. X                    | DF_XMIT_BREAK
  1681. X                    | DF_GUARD_TIMEOUT))
  1682. X            (void) sleep ((caddr_t) &fip->device_flags.i,
  1683. X                            PZERO - 1);
  1684. X    }
  1685. X
  1686. X    (*linesw [ttyp->t_line].l_close) (ttyp);
  1687. X
  1688. X    /* allow pending tty interrupts */
  1689. X    (void) SPLWRK ();
  1690. X    (void) SPLINT ();
  1691. X
  1692. X    if (open_mode & OS_OPEN_FOR_GETTY)
  1693. X    {
  1694. X        /* not waiting any more */
  1695. X        ttyp->t_state &= ~WOPEN;
  1696. X        if (!(fip->o_state & OS_OPEN_FOR_DIALOUT))
  1697. X        {
  1698. X            fas_close_device (fip);
  1699. X            fip->o_state = OS_DEVICE_CLOSED;
  1700. X        }
  1701. X        else
  1702. X            fip->po_state = OS_DEVICE_CLOSED;
  1703. X    }
  1704. X    else
  1705. X    {
  1706. X        fas_close_device (fip);
  1707. X        fip->o_state = OS_DEVICE_CLOSED;
  1708. X        /* If there is a waiting getty open on
  1709. X           this port, reopen the physical device.
  1710. X        */
  1711. X        if (fip->po_state & OS_WAIT_OPEN)
  1712. X        {
  1713. X            /* get the getty version of the
  1714. X               tty structure
  1715. X            */
  1716. X            fip->tty = fas_tty_ptr [physical_unit
  1717. X                    + fas_physical_units];
  1718. X            fip->o_state = fip->po_state;
  1719. X            fip->po_state = OS_DEVICE_CLOSED;
  1720. X#if defined (HAVE_VPIX)
  1721. X            /* initialize VP/ix related variables */
  1722. X            fip->v86_proc = (v86_t *) NULL;
  1723. X            fip->v86_intmask = 0;
  1724. X            fip->v86_ss.ss_start = CSTART;
  1725. X            fip->v86_ss.ss_stop = CSTOP;
  1726. X#endif
  1727. X            if (!(fip->device_flags.i & DF_DO_HANGUP))
  1728. X            {
  1729. X                fas_open_device (fip);
  1730. X                /* set up port registers */
  1731. X                fas_param (fip, HARD_INIT);
  1732. X            }
  1733. X        }
  1734. X        (void) wakeup ((caddr_t) &fip->o_state);
  1735. X    }
  1736. X
  1737. X    if (!(fip->device_flags.i & DF_DO_HANGUP))
  1738. X        release_device_lock (fip);
  1739. X
  1740. X    (void) splx (old_level);
  1741. X    return (0);
  1742. X}
  1743. X
  1744. X/* read characters from the input buffer */
  1745. Xint
  1746. Xfasread (dev)
  1747. Xint    dev;
  1748. X{
  1749. X    register struct fas_info    *fip;
  1750. X    register struct tty    *ttyp;
  1751. X    int    old_level;
  1752. X
  1753. X    fip = fas_info_ptr [GET_UNIT (dev)];
  1754. X    ttyp = fip->tty;
  1755. X
  1756. X    (*linesw [ttyp->t_line].l_read) (ttyp);
  1757. X
  1758. X    old_level = SPLINT ();
  1759. X
  1760. X    /* schedule character transfer to UNIX buffer */
  1761. X    if (fip->recv_ring_cnt && (ttyp->t_line || (ttyp->t_lflag & ICANON)
  1762. X#if defined (HAVE_VPIX)
  1763. X        || ((((fip->iflag & DOSMODE)
  1764. X            ? MAX_VPIX_FILL - MIN_READ_CHUNK
  1765. X            : MAX_UNIX_FILL - MIN_READ_CHUNK)
  1766. X                >= ttyp->t_rawq.c_cc)
  1767. X#else
  1768. X        || (((MAX_UNIX_FILL - MIN_READ_CHUNK) >= ttyp->t_rawq.c_cc)
  1769. X#endif
  1770. X        && !(fip->flow_flags.i & FF_RXFER_STOPPED))))
  1771. X    {
  1772. X        event_sched (fip, EF_DO_RXFER);
  1773. X    }
  1774. X
  1775. X    (void) splx (old_level);
  1776. X    return (0);
  1777. SHAR_EOF
  1778. true || echo 'restore of fas.c failed'
  1779. fi
  1780. echo 'End of fas209 part 2'
  1781. echo 'File fas.c is continued in part 3'
  1782. echo 3 > _shar_seq_.tmp
  1783. exit 0
  1784. -- 
  1785. Uwe Doering  |  INET : gemini@geminix.in-berlin.de
  1786. Berlin       |----------------------------------------------------------------
  1787. Germany      |  UUCP : ...!unido!fub!geminix.in-berlin.de!gemini
  1788.