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