home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 October / PCO_1098.ISO / filesbbs / linux / patch-2_0_35.tgz / patch-2.0.35
Encoding:
Text File  |  1998-07-13  |  2.0 MB  |  68,257 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1. diff -u --recursive --new-file v2.0.34/linux/COPYING linux/COPYING
  2. --- v2.0.34/linux/COPYING    Wed Dec  1 04:44:15 1993
  3. +++ linux/COPYING    Mon Jul 13 13:47:25 1998
  4. @@ -3,7 +3,7 @@
  5.   services by normal system calls - this is merely considered normal use
  6.   of the kernel, and does *not* fall under the heading of "derived work".
  7.   Also note that the GPL below is copyrighted by the Free Software
  8. - Foundation, but the instance of code that it refers to (the linux
  9. + Foundation, but the instance of code that it refers to (the Linux
  10.   kernel) is copyrighted by me and others who actually wrote it.
  11.  
  12.              Linus Torvalds
  13. diff -u --recursive --new-file v2.0.34/linux/CREDITS linux/CREDITS
  14. --- v2.0.34/linux/CREDITS    Mon Jul 13 13:46:24 1998
  15. +++ linux/CREDITS    Mon Jul 13 13:47:25 1998
  16. @@ -1594,11 +1594,11 @@
  17.  S: Finland
  18.  
  19.  N: Roger E. Wolff
  20. -E: wolff@dutecai.et.tudelft.nl
  21. +E: R.E.Wolff@BitWizard.nl
  22.  D: Written kmalloc/kfree
  23.  D: Written Specialix IO8+ driver
  24. -S: Oosterstraat 23
  25. -S: 2611 TT Delft
  26. +S: Van Bronckhorststraat 12 
  27. +S: 2612 XV  Delft
  28.  S: The Netherlands
  29.  
  30.  N: Frank Xia
  31. diff -u --recursive --new-file v2.0.34/linux/Documentation/00-INDEX linux/Documentation/00-INDEX
  32. --- v2.0.34/linux/Documentation/00-INDEX    Thu Jun  6 04:57:43 1996
  33. +++ linux/Documentation/00-INDEX    Mon Jul 13 13:47:25 1998
  34. @@ -14,6 +14,8 @@
  35.      - how the boss likes the C code in the kernel to look.
  36.  Configure.help
  37.      - text file that is used for help when you run "make config"
  38. +IO-mapping.txt
  39. +    - how to access I/O mapped memory from within device drivers.
  40.  SMP.txt
  41.      - notes, and "To Fix" list for multi-processor Linux. (see smp.tex)
  42.  cdrom/
  43. @@ -38,10 +40,16 @@
  44.      - info on the in-kernel binary support for Java(tm)
  45.  locks.txt
  46.      - info on file locking implementations, flock() vs. fcntl(), etc.
  47. +logo.gif
  48. +    - GIF image of penguin as a linux logo (see logo.txt)
  49. +logo.txt
  50. +    - the who where and how of the penguin linux logo.
  51.  magic-number.txt
  52.      - list of magic numbers used to mark/protect kernel data structures.
  53.  mandatory.txt
  54.      - info on the linux implementation of Sys V mandatory file locking.
  55. +memory-tuning.txt
  56. +    - info on setting the /proc/sys/vm parameters to match your system.
  57.  modules.txt
  58.      - short guide on how to make kernel parts into loadable modules
  59.  networking/
  60. @@ -50,6 +58,8 @@
  61.      - short guide on setting up a diskless box with NFS root filesystem
  62.  oops-tracing.txt
  63.      - how to decode those nasty internal kernel error dump messages.
  64. +paride.txt
  65. +    - info on parallel port IDE devices (tapes, floppies, CD-ROMS, etc)
  66.  ramdisk.txt
  67.      - short guide on how to set up and use the RAM disk.
  68.  riscom8.txt
  69. @@ -60,10 +70,14 @@
  70.      - short blurb on using SCSI support as a module.
  71.  smp.tex
  72.      - TeX document describing implementation of Multiprocessor Linux
  73. +specialix.txt
  74. +    - info on hardware/driver for specialix IO8+ multiport serial card.
  75.  svga.txt
  76.      - short guide on selecting video modes at boot via VGA BIOS.
  77.  unicode.txt
  78.      - info on the Unicode character/font mapping used in Linux.
  79.  watchdog.txt
  80.      - how to auto-reboot Linux if it has "fallen and can't get up". ;-)
  81. +xterm-linux.xpm
  82. +    - XPM format image/icon of penguin on an xterm (see logo.txt)
  83.  
  84. diff -u --recursive --new-file v2.0.34/linux/Documentation/CodingStyle linux/Documentation/CodingStyle
  85. --- v2.0.34/linux/Documentation/CodingStyle    Wed Jan  3 21:43:40 1996
  86. +++ linux/Documentation/CodingStyle    Mon Jul 13 13:47:25 1998
  87. @@ -132,7 +132,7 @@
  88.  complexity and indentation level of that function.  So, if you have a
  89.  conceptually simple function that is just one long (but simple)
  90.  case-statement, where you have to do lots of small things for a lot of
  91. -different cases, it's ok to have a longer function. 
  92. +different cases, it's OK to have a longer function. 
  93.  
  94.  However, if you have a complex function, and you suspect that a
  95.  less-than-gifted first-year high-school student might not even
  96. @@ -169,7 +169,7 @@
  97.  
  98.          Chapter 6: You've made a mess of it
  99.  
  100. -That's ok, we all do.  You've probably been told by your long-time unix
  101. +That's OK, we all do.  You've probably been told by your long-time Unix
  102.  user helper that "GNU emacs" automatically formats the C sources for
  103.  you, and you've noticed that yes, it does do that, but the defaults it
  104.  uses are less than desirable (in fact, they are worse than random
  105. diff -u --recursive --new-file v2.0.34/linux/Documentation/Configure.help linux/Documentation/Configure.help
  106. --- v2.0.34/linux/Documentation/Configure.help    Mon Jul 13 13:46:24 1998
  107. +++ linux/Documentation/Configure.help    Mon Jul 13 13:47:25 1998
  108. @@ -320,6 +320,220 @@
  109.    Documentation/modules.txt.
  110.    It's pretty unlikely that you have one of these: say N.
  111.  
  112. +Parallel port IDE device support
  113. +CONFIG_PARIDE
  114. +  There are many external CD-ROM and disk devices that connect through
  115. +  your computer's parallel port. Most of them are actually IDE devices
  116. +  using a parallel port IDE adapter. This option enables the PARIDE
  117. +  subsystem which contains drivers for many of these external drives.
  118. +  Read linux/Documentation/paride.txt for more information.  If you 
  119. +  built PARIDE support into your kernel,  you may still build the 
  120. +  individual protocol modules and high-level drivers as loadable 
  121. +  modules. If you build this support as a module, it will be called 
  122. +  paride.o.  To use the PARIDE support, you must say Y or M here 
  123. +  and also to at least one high-level driver (e.g. "Parallel port 
  124. +  IDE disks", "Parallel port ATAPI CD-ROMs", "Parallel port ATAPI 
  125. +  disks" etc.) and to at least one protocol driver (e.g. "ATEN 
  126. +  EH-100 protocol", "MicroSolutions backpack protocol", "DataStor 
  127. +  Commuter protocol" etc.).
  128. +
  129. +Parallel port IDE disks
  130. +CONFIG_PARIDE_PD 
  131. +  This option enables the high-level driver for IDE-type disk devices 
  132. +  connected through a parallel port.  If you chose to build PARIDE 
  133. +  support into your kernel, you may answer Y here to build in the 
  134. +  parallel port IDE driver, otherwise you should answer M to build 
  135. +  it as a loadable module.  The module will be called pd.o.  You 
  136. +  must also have at least one parallel port protocol driver in your 
  137. +  system.  Among the devices supported by this driver are the SyQuest 
  138. +  EZ-135, EZ-230 and SparQ drives, the Avatar Shark and the backpack
  139. +  hard drives from MicroSolutions.
  140. +
  141. +Parallel port ATAPI CD-ROMs
  142. +CONFIG_PARIDE_PCD 
  143. +  This option enables the high-level driver for ATAPI CD-ROM devices
  144. +  connected through a parallel port. If you chose to build PARIDE
  145. +  support into your kernel, you may answer Y here to build in the
  146. +  parallel port ATAPI CD-ROM driver, otherwise you should answer M to
  147. +  build it as a loadable module. The module will be called pcd.o. You
  148. +  must also have at least one parallel port protocol driver in your
  149. +  system. Among the devices supported by this driver are the
  150. +  MicroSolutions backpack CD-ROM drives and the Freecom Power CD. If
  151. +  you have such a CD-ROM drive, you should also say Y to "ISO9660
  152. +  cdrom filesystem support" below, because that's the filesystem used
  153. +  on CDROMs.
  154. +
  155. +Parallel port ATAPI disks
  156. +CONFIG_PARIDE_PF 
  157. +  This option enables the high-level driver for ATAPI disk devices
  158. +  connected through a parallel port.  If you chose to build PARIDE
  159. +  support into your kernel, you may answer Y here to build in the
  160. +  parallel port ATAPI disk driver, otherwise you should answer M
  161. +  to build it as a loadable module.  The module will be called pf.o.
  162. +  You must also have at least one parallel port protocol driver in
  163. +  your system.  Among the devices supported by this driver are the
  164. +  MicroSolutions backpack PD/CD drive and the Imation Superdisk
  165. +  LS-120 drive.
  166. +
  167. +Parallel port ATAPI tapes
  168. +CONFIG_PARIDE_PT
  169. +  This option enables the high-level driver for ATAPI tape devices
  170. +  connected through a parallel port.  If you chose to build PARIDE
  171. +  support into your kernel, you may answer Y here to build in the
  172. +  parallel port ATAPI tape driver, otherwise you should answer M
  173. +  to build it as a loadable module.  The module will be called pt.o.
  174. +  You must also have at least one parallel port protocol driver in
  175. +  your system.  Among the devices supported by this driver is the
  176. +  parallel port version of the HP 5GB drive.
  177. +
  178. +Parallel port generic ATAPI devices
  179. +CONFIG_PARIDE_PG
  180. +  This option enables a special high-level driver for generic ATAPI
  181. +  devices connected through a parallel port. The driver allows user
  182. +  programs, such as cdrecord, to send ATAPI commands directly to a
  183. +  device. If you chose to build PARIDE support into your kernel, you 
  184. +  may answer Y here to build in the parallel port generic ATAPI driver, 
  185. +  otherwise you should answer M to build it as a loadable module.
  186. +  The module will be called pg.o.  You must also have at least one 
  187. +  parallel port protocol driver in your system.  This driver 
  188. +  implements an API loosely related to the generic SCSI driver.  
  189. +  See /usr/include/linux/pg.h for details, or visit 
  190. +  http://www.torque.net/parport/cdr.html for more information and
  191. +  the required patches to cdrecord.
  192. +
  193. +ATEN EH-100 protocol
  194. +CONFIG_PARIDE_ATEN 
  195. +  This option enables support for the ATEN EH-100 parallel port IDE
  196. +  protocol.  This protocol is used in some inexpensive low performance 
  197. +  parallel port kits made in Hong Kong. If you chose to build PARIDE 
  198. +  support into your kernel, you may answer Y here to build in the 
  199. +  protocol driver, otherwise you should answer M to build it as a 
  200. +  loadable module.  The module will be called aten.o.  You must also 
  201. +  have a high-level driver for the type of device that you want to 
  202. +  support.
  203. +
  204. +MicroSolutions backpack protocol
  205. +CONFIG_PARIDE_BPCK 
  206. +  This option enables support for the MicroSolutions backpack 
  207. +  parallel port IDE protocol.  If you chose to build PARIDE support
  208. +  into your kernel, you may answer Y here to build in the protocol
  209. +  driver, otherwise you should answer M to build it as a loadable
  210. +  module.  The module will be called bpck.o.  You must also have
  211. +  a high-level driver for the type of device that you want to support.
  212. +
  213. +DataStor Commuter protocol
  214. +CONFIG_PARIDE_COMM 
  215. +  This option enables support for the Commuter parallel port IDE 
  216. +  protocol from DataStor.  If you chose to build PARIDE support
  217. +  into your kernel, you may answer Y here to build in the protocol
  218. +  driver, otherwise you should answer M to build it as a loadable
  219. +  module.  The module will be called comm.o.  You must also have
  220. +  a high-level driver for the type of device that you want to support.
  221. +
  222. +DataStor EP-2000 protocol
  223. +CONFIG_PARIDE_DSTR 
  224. +  This option enables support for the EP-2000 parallel port IDE 
  225. +  protocol from DataStor.  If you chose to build PARIDE support
  226. +  into your kernel, you may answer Y here to build in the protocol
  227. +  driver, otherwise you should answer M to build it as a loadable
  228. +  module.  The module will be called dstr.o.  You must also have
  229. +  a high-level driver for the type of device that you want to support.
  230. +
  231. +Shuttle EPAT/EPEZ protocol
  232. +CONFIG_PARIDE_EPAT 
  233. +  This option enables support for the EPAT parallel port IDE 
  234. +  protocol.  EPAT is a parallel port IDE adapter manufactured by
  235. +  Shuttle Technology and widely used in devices from major vendors
  236. +  such as Hewlett-Packard, SyQuest, Imation and Avatar. If you 
  237. +  chose to build PARIDE support into your kernel, you may answer Y 
  238. +  here to build in the protocol driver, otherwise you should answer M 
  239. +  to build it as a loadable module.  The module will be called epat.o.  
  240. +  You must also have a high-level driver for the type of device that 
  241. +  you want to support.
  242. +
  243. +Shuttle EPIA protocol
  244. +CONFIG_PARIDE_EPIA 
  245. +  This option enables support for the (obsolete) EPIA parallel port 
  246. +  IDE protocol from Shuttle Technology.  This adapter can still be found
  247. +  in some no-name kits. If you chose to build PARIDE support into your 
  248. +  kernel, you may answer Y here to build in the protocol driver,
  249. +  otherwise you should answer M to build it as a loadable module.  
  250. +  The module will be called epia.o.  You must also have a high-level 
  251. +  driver for the type of device that you want to support.
  252. +
  253. +FIT TD-2000 protocol
  254. +CONFIG_PARIDE_FIT2
  255. +  This option enables support for the TD-2000 parallel port IDE protocol
  256. +  from Fidelity International Technology.  This is a simple (low speed) 
  257. +  adapter that is used in some portable hard drives.  If you chose to 
  258. +  build PARIDE support into your kernel, you may answer Y here to 
  259. +  build in the protocol driver, otherwise you should answer M to 
  260. +  build it as a loadable module.  The module will be called fit2.o.
  261. +  You must also have a high-level driver for the type of device 
  262. +  that you want to support.
  263. +
  264. +FIT TD-3000 protocol
  265. +CONFIG_PARIDE_FIT3
  266. +  This option enables support for the TD-3000 parallel port IDE protocol
  267. +  from Fidelity International Technology. This protocol is used in newer
  268. +  models of their portable disk, CD-ROM and PD/CD devices.   If you chose
  269. +  to build PARIDE support into your kernel, you may answer Y here to
  270. +  build in the protocol driver, otherwise you should answer M to
  271. +  build it as a loadable module.  The module will be called fit3.o.
  272. +  You must also have a high-level driver for the type of device
  273. +  that you want to support.
  274. +
  275. +FreeCom power protocol
  276. +CONFIG_PARIDE_FRPW 
  277. +  This option enables support for the Freecom power parallel port IDE 
  278. +  protocol.  If you chose to build PARIDE support into your kernel, you 
  279. +  may answer Y here to build in the protocol driver, otherwise you 
  280. +  should answer M to build it as a loadable module.  The module will be 
  281. +  called frpw.o.  You must also have a high-level driver for the type 
  282. +  of device that you want to support.
  283. +
  284. +KingByte KBIC-951A/971A protocols
  285. +CONFIG_PARIDE_KBIC 
  286. +  This option enables support for the KBIC-951A and KBIC-971A parallel 
  287. +  port IDE protocols from KingByte Information Corp.  KingByte's adapters
  288. +  appear in many no-name portable disk and CD-ROM products, especially 
  289. +  in Europe. If you chose to build PARIDE support into your kernel, you 
  290. +  may answer Y here to build in the protocol driver, otherwise you should 
  291. +  answer M to build it as a loadable module.  The module will be called 
  292. +  kbic.o.  You must also have a high-level driver for the type of device 
  293. +  that you want to support.
  294. +
  295. +KT PHd protocol
  296. +CONFIG_PARIDE_KTTI
  297. +  This option enables support for the "PHd" parallel port IDE protocol
  298. +  from KT Technology.  This is a simple (low speed) adapter that is
  299. +  used in some 2.5" portable hard drives.  If you chose to build PARIDE 
  300. +  support into your kernel, you may answer Y here to build in the 
  301. +  protocol driver, otherwise you should answer M to build it as a 
  302. +  loadable module.  The module will be called ktti.o.  You must also 
  303. +  have a high-level driver for the type of device that you want to
  304. +  support.
  305. +
  306. +OnSpec 90c20 protocol
  307. +CONFIG_PARIDE_ON20 
  308. +  This option enables support for the (obsolete) 90c20 parallel port 
  309. +  IDE protocol from OnSpec (often marketed under the ValuStore brand
  310. +  name).  If you chose to build PARIDE support into your kernel, you 
  311. +  may answer Y here to build in the protocol driver, otherwise you 
  312. +  should answer M to build it as a loadable module.  The module will 
  313. +  be called on20.o.  You must also have a high-level driver for the 
  314. +  type of device that you want to support.
  315. +
  316. +OnSpec 90c26 protocol
  317. +CONFIG_PARIDE_ON26 
  318. +  This option enables support for the 90c26 parallel port IDE protocol 
  319. +  from OnSpec Electronics (often marketed under the ValuStore brand
  320. +  name).  If you chose to build PARIDE support into your kernel, you 
  321. +  may answer Y here to build in the protocol driver, otherwise you 
  322. +  should answer M to build it as a loadable module.  The module will 
  323. +  be called on26.o.  You must also have a high-level driver for the 
  324. +  type of device that you want to support.
  325. +
  326.  Multiple devices driver support
  327.  CONFIG_BLK_DEV_MD
  328.    This driver lets you combine several harddisk partitions into one
  329. @@ -349,6 +563,31 @@
  330.    in and removed from the running kernel whenever you want), say M
  331.    here and read Documentation/modules.txt. If unsure, say Y.
  332.  
  333. +RAID-1 (mirroring) mode
  334. +CONFIG_MD_MIRRORING
  335. +  A RAID-1 set consists of several disk drives which are exact copies
  336. +  of each other. In the event of a mirror failture, the RAID driver
  337. +  will continue to use the operational mirrors in the set, providing
  338. +  an error free MD device to the higher levels of the kernel. In
  339. +  a set with N drives, the available space is the capacity of a single
  340. +  drive, and the set protects against a failture of (N - 1) drives.
  341. +  raidtools, a set of user-space tools which create and maintain
  342. +  RAID1/4/5 sets, is available at:
  343. +  http://luthien.nuclecu.unam.mx/~miguel/raid
  344. +
  345. +RAID-4/RAID-5 mode
  346. +CONFIG_MD_RAID5
  347. +  A RAID-5 set of N drives with a capacity of C MB per drive provides
  348. +  the capacity of C * (N - 1) drives, and protects against a failture
  349. +  of a single drive. For a given sector (row) number, (N - 1) drives
  350. +  contain data sectors, and one drive contains the parity protection.
  351. +  For a RAID-4 set, the parity blocks are present on a single drive,
  352. +  while a RAID-5 set distributes the parity accross the drives in one
  353. +  of the available parity distribution methods.
  354. +  raidtools, a set of user-space tools which create and maintain
  355. +  RAID1/4/5 sets, is available at:
  356. +  http://luthien.nuclecu.unam.mx/~miguel/raid
  357. +
  358.  Support for Deskstation RPC44
  359.  CONFIG_DESKSTATION_RPC44
  360.    This is a machine with a R4400 100 MHz CPU. To compile a Linux
  361. @@ -1013,7 +1252,7 @@
  362.  
  363.  PC/TCP compatibility mode
  364.  CONFIG_INET_PCTCP
  365. -  If you have been having difficulties telneting to your Linux machine
  366. +  If you have been having difficulties telnetting to your Linux machine
  367.    from a DOS system that uses (broken) PC/TCP networking software (all
  368.    versions up to OnNet 2.0) over your local ethernet try enabling this
  369.    option.  Everyone else says N.
  370. @@ -2045,18 +2284,112 @@
  371.    running kernel whenever you want), say M here and read
  372.    Documentation/modules.txt.
  373.  
  374. -BAYCOM ser12 and par96 kiss emulation driver for AX.25
  375. +BAYCOM ser12 and par96 driver for AX.25
  376.  CONFIG_BAYCOM
  377.    This is an experimental driver for Baycom style simple amateur radio
  378.    modems that connect to either a serial interface or a parallel
  379.    interface. The driver supports the ser12 and par96 designs. To
  380. -  configure the driver, use the setbaycom utility available from
  381. -  http://www.ife.ee.ethz.ch/~sailer/ham/ham.html#lnxbay. For
  382. -  information on the modems, see http://www.baycom.de and
  383. -  drivers/char/README.baycom.  If you want to compile this as a module
  384. -  ( = code which can be inserted in and removed from the running
  385. -  kernel whenever you want), say M here and read
  386. -  Documentation/modules.txt. This is recommended.
  387. +  configure the driver, use the sethdlc utility available
  388. +  in the standard ax25 utilities package. For information on the modems,
  389. +  see http://www.baycom.de and drivers/net/README.baycom.
  390. +  If you want to compile this as a module ( = code which can be
  391. +  inserted in and removed from the running kernel whenever you want),
  392. +  say M here and read Documentation/modules.txt. This is recommended.
  393. +
  394. +Sound card modem driver for AX.25
  395. +CONFIG_SOUNDMODEM
  396. +  This experimental driver allows a standard SoundBlaster or
  397. +  WindowsSoundSystem compatible sound card to be used as a packet radio
  398. +  modem (NOT as a telephone modem!), to send digital traffic over
  399. +  amateur radio. 
  400. +
  401. +  To configure the driver, use the sethdlc, smdiag and smmixer
  402. +  utilities available in the standard ax25 utilities package. For
  403. +  information on how to key the transmitter, see
  404. +  http://www.ife.ee.ethz.ch/~sailer/pcf/ptt_circ/ptt.html (to browse
  405. +  the WWW, you need to have access to a machine on the Internet that
  406. +  has a program like lynx or netscape) and
  407. +  Documentation/networking/soundmodem.txt. 
  408. +
  409. +  If you want to compile this driver as a module ( = code which can be
  410. +  inserted in and removed from the running kernel whenever you want),
  411. +  say M here and read Documentation/modules.txt. This is recommended.
  412. +  The module will be called soundmodem.o.
  413. +
  414. +Sound card modem support for SoundBlaster and compatible cards
  415. +CONFIG_SOUNDMODEM_SBC
  416. +  This option enables the soundmodem driver to use SoundBlaster and
  417. +  compatible cards. If you have a dual mode card (i.e. a WSS cards
  418. +  with a SoundBlaster emulation) you should say N here and Y to
  419. +  "Sound card modem support for WSS and Crystal cards", below, because
  420. +  this usually results in better performance. This option also supports
  421. +  SB16/32/64 in full duplex mode.
  422. +
  423. +Sound card modem support for WSS and Crystal cards
  424. +CONFIG_SOUNDMODEM_WSS
  425. +  This option enables the soundmodem driver to use WindowsSoundSystem
  426. +  compatible cards. These cards feature a codec chip from either
  427. +  Analog Devices (such as AD1848, AD1845, AD1812) or Crystal
  428. +  Semiconductors (such as CS4248, CS423x). This option also supports
  429. +  the WSS full duplex operation which currently works with Crystal
  430. +  CS423x chips. If you don't need full duplex operation, do not enable
  431. +  it to save performance.
  432. +
  433. +Sound card modem support for 1200 baud AFSK modulation
  434. +CONFIG_SOUNDMODEM_AFSK1200
  435. +  This option enables the soundmodem driver 1200 baud AFSK modem, 
  436. +  compatible to popular modems using TCM3105 or AM7911. The demodulator
  437. +  requires about 12% of the CPU power of a Pentium 75 CPU per channel.
  438. +
  439. +Sound card modem support for 2400 baud AFSK modulation (7.3728MHz crystal)
  440. +CONFIG_SOUNDMODEM_AFSK2400_7
  441. +  This option enables the soundmodem driver 2400 baud AFSK modem,
  442. +  compatible to TCM3105 modems (over-)clocked with a 7.3728MHz
  443. +  crystal.  Note that the availability of this driver does _not_ imply
  444. +  that I recommend building such links. It is only here since users
  445. +  especially in eastern Europe have asked me to do so. In fact this
  446. +  modulation scheme has many disadvantages, mainly its incompatibility
  447. +  with many transceiver designs and the fact that the TCM3105 (if
  448. +  used) is operated widely outside its specifications.
  449. +
  450. +Sound card modem support for 2400 baud AFSK modulation (8MHz crystal)
  451. +CONFIG_SOUNDMODEM_AFSK2400_8
  452. +  This option enables the soundmodem driver 2400 baud AFSK modem,
  453. +  compatible to TCM3105 modems (over-)clocked with an 8MHz crystal.
  454. +  Note that the availability of this driver does _not_ imply that I
  455. +  recommend building such links. It is only here since users
  456. +  especially in eastern Europe have asked me to do so. In fact this
  457. +  modulation scheme has many disadvantages, mainly its incompatibility
  458. +  with many transceiver designs and the fact that the TCM3105 (if
  459. +  used) is operated widely outside its specifications.
  460. +
  461. +Sound card modem support for 2666 baud AFSK modulation
  462. +CONFIG_SOUNDMODEM_AFSK2666
  463. +  This option enables the soundmodem driver 2666 baud AFSK modem.
  464. +  This modem is experimental, and not compatible to anything
  465. +  else I know of.
  466. +
  467. +Sound card modem support for 4800 baud 8PSK modulation
  468. +CONFIG_SOUNDMODEM_PSK4800
  469. +  This option enables the soundmodem driver 4800 baud 8PSK modem.
  470. +  This modem is experimental, and not compatible to anything
  471. +  else I know of.
  472. +
  473. +Sound card modem support for 4800 baud HAPN-1 modulation
  474. +CONFIG_SOUNDMODEM_HAPN4800
  475. +  This option enables the soundmodem driver 4800 baud HAPN-1
  476. +  compatible modem. This modulation seems to be widely used 'down
  477. +  under' and in the Netherlands. Here, nobody uses it, so I could not
  478. +  test if it works.  It is compatible to itself, however :-)
  479. +
  480. +Sound card modem support for 9600 baud FSK G3RUH modulation
  481. +CONFIG_SOUNDMODEM_FSK9600
  482. +  This option enables the soundmodem driver 9600 baud FSK modem,
  483. +  compatible to the G3RUH standard. The demodulator requires about 4%
  484. +  of the CPU power of a Pentium 75 CPU per channel. You can say Y to
  485. +  both 1200 baud AFSK and 9600 baud FSK if you want (but obviously you
  486. +  can only use one protocol at a time, depending on what the other end
  487. +  can understand).
  488.  
  489.  PLIP (parallel port) support
  490.  CONFIG_PLIP
  491. @@ -4324,10 +4657,10 @@
  492.  # LocalWords:  ipppd syncppp RFC MPP VJ downloaded icn NICCY Creatix shmem ufr
  493.  # LocalWords:  ibp md ARCnet ether encap NDIS arcether ODI Amigas AmiTCP NetBSD
  494.  # LocalWords:  initrd tue util DES funet des OnNet BIOSP smc Travan Iomega CMS
  495. -# LocalWords:  FC DC dc PPA IOMEGA's ppa RNFS FMV Fujitsu ARPD arpd loran layes
  496. +# LocalWords:  FC DC dc PPA ppa RNFS FMV Fujitsu ARPD arpd loran layes
  497.  # LocalWords:  FRAD indiana framerelay DLCI DCLIs Sangoma SDLA mrouted sync sec
  498.  # LocalWords:  Starmode Metricom MosquitoNet mosquitonet kbit nfsroot Digiboard
  499. -# LocalWords:  DIGI Xe Xeve digiboard UMISC touchscreens mtu ethernets HBAs MEX
  500. +# LocalWords:  DIGI Xe Xeve digiboard UMISC touchscreens mtu HBAs MEX
  501.  # LocalWords:  Shifflett netcom js jshiffle WIC DECchip ELCP EtherPower dst RTC
  502.  # LocalWords:  rtc SMP lp Digi Intl RightSwitch DGRS dgrs AFFS Amiga UFS SDL AP
  503.  # LocalWords:  Solaris RISCom riscom syncPPP PCBIT pcbit sparc anu au artoo ufs
  504. @@ -4336,7 +4669,7 @@
  505.  # LocalWords:  Bernd informatik rwth aachen uae affs multihosting bytecode java
  506.  # LocalWords:  applets applet JDK ncsa cabi SNI Alphatronix readme LANs scarab
  507.  # LocalWords:  winsock RNIS caltech OSPF honour Honouring Mbit Localtalk DEFRAG
  508. -# LocalWords:  localtalk download Packetwin Baycom baycom interwork ascii JNT
  509. +# LocalWords:  download Packetwin Baycom baycom interwork ascii JNT
  510.  # LocalWords:  Camtec proxying indyramp defragment defragmented UDP FAS FASXX
  511.  # LocalWords:  FastSCSI SIO FDC qlogicfas QLogic qlogicisp setbaycom ife ee LJ
  512.  # LocalWords:  ethz ch Travelmates ProAudioSpectrum ProAudio SoundMan SB SBPro
  513. diff -u --recursive --new-file v2.0.34/linux/Documentation/IO-mapping.txt linux/Documentation/IO-mapping.txt
  514. --- v2.0.34/linux/Documentation/IO-mapping.txt    Mon Sep 30 07:05:45 1996
  515. +++ linux/Documentation/IO-mapping.txt    Mon Jul 13 13:47:25 1998
  516. @@ -56,13 +56,13 @@
  517.  where all the addresses actually point to the same thing, it's just seen 
  518.  through different translations..
  519.  
  520. -Similarly, on the alpha, the normal translation is
  521. +Similarly, on the Alpha, the normal translation is
  522.  
  523.   physical address:    0
  524.   virtual address:    0xfffffc0000000000
  525.   bus address:        0x40000000
  526.  
  527. -(but there are also alpha's where the physical address and the bus address
  528. +(but there are also Alphas where the physical address and the bus address
  529.  are the same). 
  530.  
  531.  Anyway, the way to look up all these translations, you do
  532. @@ -169,7 +169,7 @@
  533.  
  534.  Ok, that just about covers the basics of accessing IO portably.  Questions?
  535.  Comments? You may think that all the above is overly complex, but one day you
  536. -might find yourself with a 500MHz alpha in front of you, and then you'll be
  537. +might find yourself with a 500 MHz Alpha in front of you, and then you'll be
  538.  happy that your driver works ;)
  539.  
  540.  Note that kernel versions 2.0.x (and earlier) mistakenly called the
  541. diff -u --recursive --new-file v2.0.34/linux/Documentation/SMP.txt linux/Documentation/SMP.txt
  542. --- v2.0.34/linux/Documentation/SMP.txt    Mon May  6 02:26:01 1996
  543. +++ linux/Documentation/SMP.txt    Mon Jul 13 13:47:25 1998
  544. @@ -19,7 +19,7 @@
  545.  o    Clean up warnings/volatiles.
  546.  o    Fix load_TR() for non contiguous processor ids
  547.  o    Iterate over the slave timer requests if one is lost (keep a count per cpu)
  548. -o    Distribute irq's (locking present just needs the 82489 to be asked
  549. +o    Distribute IRQs (locking present just needs the 82489 to be asked
  550.      nicely).
  551.  o    486 startup code.
  552.  o    How to handle mixed FPU/non FPU processors.
  553. diff -u --recursive --new-file v2.0.34/linux/Documentation/cdrom/sonycd535 linux/Documentation/cdrom/sonycd535
  554. --- v2.0.34/linux/Documentation/cdrom/sonycd535    Sat Jul  1 09:05:58 1995
  555. +++ linux/Documentation/cdrom/sonycd535    Mon Jul 13 13:47:25 1998
  556. @@ -1,7 +1,7 @@
  557.                README FOR LINUX SONY CDU-535/531 DRIVER
  558.                ========================================
  559.  
  560. -This is the the Sony CDU-535 (and 531) driver version 0.7 for Linux.
  561. +This is the Sony CDU-535 (and 531) driver version 0.7 for Linux.
  562.  I do not think I have the documentation to add features like DMA support
  563.  so if anyone else wants to pursue it or help me with it, please do.
  564.  (I need to see what was done for the CDU-31A driver -- perhaps I can
  565. diff -u --recursive --new-file v2.0.34/linux/Documentation/devices.txt linux/Documentation/devices.txt
  566. --- v2.0.34/linux/Documentation/devices.txt    Mon Jul 13 13:46:24 1998
  567. +++ linux/Documentation/devices.txt    Mon Jul 13 13:47:25 1998
  568. @@ -261,7 +261,7 @@
  569.                ...
  570.  
  571.          The metadisk driver is used to span a
  572. -        filesystem across multiple physical disks.
  573. +        file system across multiple physical disks.
  574.  
  575.   10 char    Non-serial mice, misc features
  576.            0 = /dev/logibm    Logitech bus mouse
  577. @@ -345,11 +345,11 @@
  578.           33 = /dev/patmgr1    Sequencer patch manager
  579.           34 = /dev/midi02    Third MIDI port
  580.           50 = /dev/midi03    Fourth MIDI port
  581. -    block    BIOS harddrive callback support
  582. -          0 = /dev/dos_hda    First BIOS harddrive whole disk
  583. -         64 = /dev/dos_hdb    Second BIOS harddrive whole disk
  584. -        128 = /dev/dos_hdc    Third BIOS harddrive whole disk
  585. -        192 = /dev/dos_hdd    Fourth BIOS harddrive whole disk
  586. +    block    BIOS hard drive callback support
  587. +          0 = /dev/dos_hda    First BIOS hard drive whole disk
  588. +         64 = /dev/dos_hdb    Second BIOS hard drive whole disk
  589. +        128 = /dev/dos_hdc    Third BIOS hard drive whole disk
  590. +        192 = /dev/dos_hdd    Fourth BIOS hard drive whole disk
  591.  
  592.          Partitions are handled in the same way as IDE disks
  593.          (see major number 3).
  594. @@ -854,7 +854,7 @@
  595.  /dev/cdwriter    CD-writer    symbolic    Current CD-writer device
  596.  /dev/scanner    scanner        symbolic    Current scanner device
  597.  /dev/modem    modem port    symbolic    Current dialout device
  598. -/dev/root    root device    symbolic    Current root filesystem
  599. +/dev/root    root device    symbolic    Current root file system
  600.  /dev/swap    swap device    symbolic    Current swap device
  601.  
  602.  /dev/modem should not be used for a modem which supports dialin as
  603. diff -u --recursive --new-file v2.0.34/linux/Documentation/filesystems/affs.txt linux/Documentation/filesystems/affs.txt
  604. --- v2.0.34/linux/Documentation/filesystems/affs.txt    Wed Jul 24 23:08:28 1996
  605. +++ linux/Documentation/filesystems/affs.txt    Mon Jul 13 13:47:25 1998
  606. @@ -121,7 +121,7 @@
  607.  Although the Amiga and Linux file systems resemble each other, there
  608.  are some, not always subtle, differences. One of them becomes apparent
  609.  with symbolic links. While Linux has a file system with exactly one
  610. -root directory, the Amiga has a seperate root directory for each
  611. +root directory, the Amiga has a separate root directory for each
  612.  file system (i. e. partition, floppy disk, ...). With the Amiga,
  613.  these entities are called "volumes". They have symbolic names which
  614.  can be used to access them. Thus, symbolic links can point to a
  615. diff -u --recursive --new-file v2.0.34/linux/Documentation/ide.txt linux/Documentation/ide.txt
  616. --- v2.0.34/linux/Documentation/ide.txt    Mon Aug  4 11:45:55 1997
  617. +++ linux/Documentation/ide.txt    Mon Jul 13 13:47:25 1998
  618. @@ -135,7 +135,7 @@
  619.  Note that the first parameter reserves 8 contiguous ioports, whereas the
  620.  second value denotes a single ioport. If in doubt, do a 'cat /proc/ioports'.
  621.  
  622. -In all probability the device uses these ports and irqs if it is attached
  623. +In all probability the device uses these ports and IRQs if it is attached
  624.  to the appropriate ide channel.  Pass the parameter for the correct ide
  625.  channel to the kernel, as explained above.
  626.  
  627. @@ -180,7 +180,7 @@
  628.  
  629.  Courtesy of Scott Snyder, the driver supports ATAPI cdrom drives
  630.  such as the NEC-260 and the new MITSUMI triple/quad speed drives.
  631. -Such drives will be identified at boot time, just like a harddisk.
  632. +Such drives will be identified at boot time, just like a hard disk.
  633.  
  634.  If for some reason your cdrom drive is *not* found at boot time, you can force
  635.  the probe to look harder by supplying a kernel command line parameter
  636. @@ -190,7 +190,7 @@
  637.  or
  638.      hdd=cdrom    /* hdd = "slave" on second interface */
  639.  
  640. -For example, a GW2000 system might have a harddrive on the primary
  641. +For example, a GW2000 system might have a hard drive on the primary
  642.  interface (/dev/hda) and an IDE cdrom drive on the secondary interface
  643.  (/dev/hdc).  To mount a CD in the cdrom drive, one would use something like:
  644.  
  645. @@ -258,6 +258,7 @@
  646.                  older/odd IDE drives.
  647.   "hdx=slow"        : insert a huge pause after each access to the data
  648.                  port. Should be used only as a last resort.
  649. + "hdx=ide-scsi"        : use the ide-scsi driver for hdx
  650.  
  651.   "idebus=xx"        : inform IDE driver of VESA/PCI bus speed in Mhz,
  652.                  where "xx" is between 20 and 66 inclusive,
  653. @@ -428,7 +429,7 @@
  654.  must reside within the first 1024 cylinders of the drive.  If your linux
  655.  root partition is *not* completely within the first 1024 cyls (quite common),
  656.  then you can use LILO to boot linux from files on your DOS partition
  657. -by doing the following after installing slackware (or whatever):
  658. +by doing the following after installing Slackware (or whatever):
  659.  
  660.      0. Boot from the "boot floppy" created during the installation
  661.          1. Mount your DOS partition as /dos (and stick it in /etc/fstab)
  662. diff -u --recursive --new-file v2.0.34/linux/Documentation/isdn/README linux/Documentation/isdn/README
  663. --- v2.0.34/linux/Documentation/isdn/README    Mon Aug  4 17:33:59 1997
  664. +++ linux/Documentation/isdn/README    Mon Jul 13 13:47:25 1998
  665. @@ -353,7 +353,7 @@
  666.     command "isdnctrl addphone <InterfaceName> in <caller-id>"
  667.     Euro-ISDN does not transmit the leading '0' of the caller-id for an
  668.     incoming call, therefore you should configure it accordingly.
  669. -   If the real number for the dialout e.g. is "09311234567" the the number
  670. +   If the real number for the dialout e.g. is "09311234567" the number
  671.     to configure here is "9311234567". The pattern-match function 
  672.     works similar to the shell mechanism.
  673.  
  674. @@ -374,7 +374,7 @@
  675.     Returns the EAZ of an interface.
  676.  
  677.     "isdnctrl delphone <InterfaceName> in|out <number>" 
  678. -   Deletes a number from one of the the access-lists of the interface.
  679. +   Deletes a number from one of the access-lists of the interface.
  680.  
  681.     "isdnctrl delif <InterfaceName>" 
  682.     Removes the interface (and possible slaves) from the kernel.
  683. diff -u --recursive --new-file v2.0.34/linux/Documentation/isdn/README.sc linux/Documentation/isdn/README.sc
  684. --- v2.0.34/linux/Documentation/isdn/README.sc    Mon Aug  4 17:33:59 1997
  685. +++ linux/Documentation/isdn/README.sc    Mon Jul 13 13:47:25 1998
  686. @@ -42,7 +42,7 @@
  687.  ---------------
  688.  
  689.  The revision 2 Linux driver for SpellCaster ISA ISDN adapters is built
  690. -upon ISDN4Linux available seperately or as included in Linux 2.0 and later.
  691. +upon ISDN4Linux available separately or as included in Linux 2.0 and later.
  692.  The driver will support a maximum of 4 adapters in any one system of any
  693.  type including DataCommute/BRI, DataCommute/PRI and TeleCommute/BRI for a
  694.  maximum of 92 channels for host. The driver is supplied as a module in
  695. @@ -81,7 +81,7 @@
  696.        the driver and at the same time doubled the number of I/O ports
  697.        probed increasing the likelyhood of finding an adapter.
  698.      - We now support all ISA adapter models with a single driver instead
  699. -      of seperate drivers for each model. The revision 2 driver supports
  700. +      of separate drivers for each model. The revision 2 driver supports
  701.        the DataCommute/BRI, DataCommute/PRI and TeleCommute/BRI in any
  702.        combination up to a maximum of four adapters per system.
  703.      - On board PPP protocol support has been removed in favour of the
  704. diff -u --recursive --new-file v2.0.34/linux/Documentation/memory-tuning.txt linux/Documentation/memory-tuning.txt
  705. --- v2.0.34/linux/Documentation/memory-tuning.txt    Mon Aug 18 20:16:47 1997
  706. +++ linux/Documentation/memory-tuning.txt    Mon Jul 13 13:47:25 1998
  707. @@ -21,8 +21,8 @@
  708.  
  709.  The values selected as boot defaults are the following:  For a
  710.  machine with n>=8 Megabytes of memory, set min_free_pages = n*2,
  711. -free_pages_low = n*3 and free_pages_high = n*4.  Machines with less
  712. -than 8 Megabytes or less as if they had 8 Megabytes.
  713. +free_pages_low = n*3 and free_pages_high = n*4.  Machines with
  714. +8 Megabytes or less behave as if they had 8 Megabytes.
  715.  
  716.  If "out of memory" errors sometimes occur, or if your machine does lots
  717.  of networking, increasing min_free_pages to 64 or more may be a good
  718. diff -u --recursive --new-file v2.0.34/linux/Documentation/networking/00-INDEX linux/Documentation/networking/00-INDEX
  719. --- v2.0.34/linux/Documentation/networking/00-INDEX    Tue Apr  8 08:47:45 1997
  720. +++ linux/Documentation/networking/00-INDEX    Mon Jul 13 13:47:26 1998
  721. @@ -12,8 +12,14 @@
  722.      - info on the using the arcnet driver itself.
  723.  ax25.txt
  724.      - info on using AX.25 and NET/ROM code for Linux
  725. +depca.txt
  726. +    - the Digital DEPCA/EtherWORKS DE1?? and DE2?? LANCE Ethernet driver
  727.  framerelay.txt
  728.      - info on using Frame Relay/Data Link Connection Identifier (DLCI).
  729. +ip_dynaddr.txt
  730. +    - info on using dynamic IP addressing for diald and IP masquerading.
  731. +ipx.txt
  732. +    - info on the two possible modes of kernel IPX network support.
  733.  masquerading.txt
  734.      - using IP masquerading, multiple machines using a single IP address.
  735.  ncsa-telnet
  736. @@ -22,10 +28,16 @@
  737.      - info and "insmod" parameters for all network driver modules.
  738.  ppp.txt
  739.      - info on what software you should use to run PPP.
  740. +so_bindtodevice.txt
  741. +    - info on binding a socket to a specific device/interface.
  742.  tcp.txt
  743.      - short blurb on how TCP output takes place.
  744. +tlan.FAQ
  745. +    - freq. asked questions on the TLAN (Compaq Netelligent) driver.
  746. +tlan.README
  747. +    - usage and supported hardware info for the Thunderlan driver.
  748.  tulip.txt
  749. -    - info on using DEC 21040/21041/21140 based PCI ethernet cards.
  750. +    - info on using DEC 21040/21041/21140 based PCI Ethernet cards.
  751.  vortex.txt
  752.      - info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) e'net cards.
  753.  z8530drv.txt
  754. diff -u --recursive --new-file v2.0.34/linux/Documentation/networking/arcnet-hardware.txt linux/Documentation/networking/arcnet-hardware.txt
  755. --- v2.0.34/linux/Documentation/networking/arcnet-hardware.txt    Mon May  6 02:26:01 1996
  756. +++ linux/Documentation/networking/arcnet-hardware.txt    Mon Jul 13 13:47:26 1998
  757. @@ -17,19 +17,19 @@
  758.  INTRODUCTION TO ARCNET
  759.  ----------------------
  760.  
  761. -ARCnet is a network type which works in a way similar to popular "ethernet"
  762. +ARCnet is a network type which works in a way similar to popular Ethernet
  763.  networks but which is also different in some very important ways.
  764.  
  765. -First of all, you can get ARCnet cards in at least two speeds: 2.5Mbps
  766. -(slower than ethernet) and 100Mbps (faster than normal ethernet).  In fact,
  767. +First of all, you can get ARCnet cards in at least two speeds: 2.5 Mbps
  768. +(slower than Ethernet) and 100 Mbps (faster than normal Ethernet).  In fact,
  769.  there are others as well, but these are less common.  The different hardware
  770.  types, as far as I'm aware, are not compatible and so you cannot wire a
  771. -100Mbps card to a 2.5Mbps card, and so on.  From what I hear, my driver does
  772. -work with 100Mbps cards, but I haven't been able to verify this myself,
  773. -since I only have the 2.5Mbps variety.  It is probably not going to saturate
  774. -your 100Mbps card.  Stop complaining :)
  775. +100 Mbps card to a 2.5 Mbps card, and so on.  From what I hear, my driver does
  776. +work with 100 Mbps cards, but I haven't been able to verify this myself,
  777. +since I only have the 2.5 Mbps variety.  It is probably not going to saturate
  778. +your 100 Mbps card.  Stop complaining :)
  779.  
  780. -You also cannot connect an ARCnet card to any kind of ethernet card and
  781. +You also cannot connect an ARCnet card to any kind of Ethernet card and
  782.  expect it to work.  
  783.  
  784.  There are two "types" of ARCnet - STAR topology and BUS topology.  This
  785. @@ -41,7 +41,7 @@
  786.  Once you get past these little stumbling blocks, ARCnet is actually quite a
  787.  well-designed standard.  It uses something called "modified token passing"
  788.  which makes it completely incompatible with so-called "Token Ring" cards,
  789. -but which makes transfers much more reliable than ethernet does.  In fact,
  790. +but which makes transfers much more reliable than Ethernet does.  In fact,
  791.  ARCnet will guarantee that a packet arrives safely at the destination, and
  792.  even if it can't possibly be delivered properly (ie. because of a cable
  793.  break, or because the destination computer does not exist) it will at least
  794. @@ -53,9 +53,9 @@
  795.  
  796.  In addition, all known ARCnet cards have an (almost) identical programming
  797.  interface.  This means that with one "arcnet" driver you can support any
  798. -card; whereas, with ethernet, each manufacturer uses what is sometimes a
  799. +card; whereas, with Ethernet, each manufacturer uses what is sometimes a
  800.  completely different programming interface, leading to a lot of different,
  801. -sometimes very similar, ethernet drivers.  Of course, always using the same
  802. +sometimes very similar, Ethernet drivers.  Of course, always using the same
  803.  programming interface also means that when high-performance hardware
  804.  facilities like PCI busmastering DMA appear, it's hard to take advantage of
  805.  them.  Let's not go into that.
  806. @@ -63,10 +63,10 @@
  807.  One thing that makes ARCnet cards difficult to program for, however, is the
  808.  limit on their packet sizes; standard ARCnet can only send packets that are
  809.  up to 508 bytes in length.  This is smaller than the internet "bare minimum"
  810. -of 576 bytes, let alone the ethernet MTU of 1500.  To compensate, an extra
  811. +of 576 bytes, let alone the Ethernet MTU of 1500.  To compensate, an extra
  812.  level of encapsulation is defined by RFC1201, which I call "packet
  813.  splitting," that allows "virtual packets" to grow as large as 64K each,
  814. -although they are generally kept down to the ethernet-style 1500 bytes.
  815. +although they are generally kept down to the Ethernet-style 1500 bytes.
  816.  
  817.  For more information on the advantages and disadvantages (mostly the
  818.  advantages) of ARCnet networks, you might try the "ARCnet Trade Association"
  819. @@ -319,7 +319,7 @@
  820.      - Avery's favourite: 0xD0000
  821.  
  822.    - the station address:  Every ARCnet card has its own "unique" network
  823. -    address from 0 to 255.  Unlike ethernet, you can set this address
  824. +    address from 0 to 255.  Unlike Ethernet, you can set this address
  825.      yourself with a jumper or switch (or on some cards, with special
  826.      software).  Since it's only 8 bits, you can only have 254 ARCnet cards
  827.      on a network.  DON'T use 0 or 255, since these are reserved (although
  828. @@ -1169,7 +1169,7 @@
  829.  
  830.  DIP Switches:
  831.  
  832. -    The dipswitches accessible on the accessible end of the card while
  833. +    The DIP switches accessible on the accessible end of the card while
  834.          it is installed, is used to set the arcnet address.  There are 8
  835.          switches.  Use an address from 1 to 254.
  836.  
  837. @@ -1184,7 +1184,7 @@
  838.      11111110    1
  839.      11111111    0    (Don't use this!)
  840.  
  841. -    There is another dipswitch array of 8 switches at the top of the
  842. +    There is another array of eight DIP switches at the top of the
  843.          card.  There are five labelled MS0-MS4 which seem to control the
  844.          memory address, and another three labelled IO0-IO2 which seem to
  845.          control the base I/O address of the card.
  846. diff -u --recursive --new-file v2.0.34/linux/Documentation/networking/arcnet.txt linux/Documentation/networking/arcnet.txt
  847. --- v2.0.34/linux/Documentation/networking/arcnet.txt    Wed Sep 11 07:57:12 1996
  848. +++ linux/Documentation/networking/arcnet.txt    Mon Jul 13 13:47:26 1998
  849. @@ -147,10 +147,10 @@
  850.  
  851.  Go read the NET-2-HOWTO and ETHERNET-HOWTO for Linux; they should be
  852.  available where you picked up this driver.  Think of your ARCnet as a
  853. -souped-up (or down, as the case may be) ethernet card.
  854. +souped-up (or down, as the case may be) Ethernet card.
  855.  
  856.  By the way, be sure to change all references from "eth0" to "arc0" in the
  857. -HOWTOs.  Remember that ARCnet isn't a "true" ethernet, and the device name
  858. +HOWTOs.  Remember that ARCnet isn't a "true" Ethernet, and the device name
  859.  is DIFFERENT.
  860.  
  861.  
  862. @@ -170,7 +170,7 @@
  863.  How do I get it to work with...?
  864.  --------------------------------
  865.  
  866. -NFS: Should be fine linux->linux, just pretend you're using ethernet cards. 
  867. +NFS: Should be fine Linux->Linux, just pretend you're using Ethernet cards. 
  868.          oak.oakland.edu:/simtel/msdos/nfs has some nice DOS clients.  There
  869.          is also a DOS-based NFS server called SOSS.  It doesn't multitask
  870.          quite the way Linux does (actually, it doesn't multitask AT ALL) but
  871. @@ -196,7 +196,7 @@
  872.  
  873.  LAN Manager and Windows for Workgroups: These programs use protocols that
  874.          are incompatible with the internet standard.  They try to pretend
  875. -        the cards are ethernet, and confuse everyone else on the network. 
  876. +        the cards are Ethernet, and confuse everyone else on the network. 
  877.          
  878.          However, v2.00 and higher of the Linux ARCnet driver supports this
  879.          protocol via the 'arc0e' device.  See the section on "Multiprotocol
  880. diff -u --recursive --new-file v2.0.34/linux/Documentation/networking/ax25.txt linux/Documentation/networking/ax25.txt
  881. --- v2.0.34/linux/Documentation/networking/ax25.txt    Wed Jul  5 03:06:27 1995
  882. +++ linux/Documentation/networking/ax25.txt    Mon Jul 13 13:47:26 1998
  883. @@ -1,50 +1,16 @@
  884. -This is version 029 of the new AX.25 and NET/ROM code for Linux. It
  885. -incorporates many enhancements since the last release, notably the rewriting
  886. -of the connected mode IP code and the IP over NET/ROM code. The opportunity
  887. -has been taken to add the G8BPQ NET/ROM extensions and to add BPQ Ethernet
  888. -support. The latter has been much eased by the use of the new variable
  889. -length header code by Alan Cox.
  890. +To use the amateur radio protocols within Linux you will need to get a
  891. +suitable copy of the AX.25 Utilities. More detailed information about these
  892. +and associated programs can be found on http://www.cs.nott.ac.uk/~jsn/.
  893. +
  894. +For more information about the AX.25, NET/ROM and ROSE protocol stacks, see
  895. +the AX25-HOWTO written by Terry Dawson <terry@perf.no.itg.telstra.com.au>
  896. +who is also the AX.25 Utilities maintainer.
  897. +
  898. +There is an active mailing list for discussing Linux amateur radio matters
  899. +called linux-hams. To subscribe to it, send a message to
  900. +Majordomo@vger.rutgers.edu with the words "subscribe linux-hams" in the body
  901. +of the message, the subject field is ignored.
  902.  
  903. -To use the BPQ Ethernet option, first up the ethernet interface in the usual
  904. -manner, the IP address of the interface is not that important but it will
  905. -be required for the ARP table. Next create an ARP entry in the ARP table of
  906. -type ax25 for the interface binding it to an AX.25 callsign, this callsign
  907. -will be the callsign of that interface. By default BPQ Ethernet uses a
  908. -multi-cast address, this implementation does not, instead the standard
  909. -ethernet broadcast address is used. Therefore the NET.CFG file for the
  910. -ODI driver should look similar to this:
  911. +Jonathan G4KLX
  912.  
  913. ------------------------------- cut here ------------------------------------
  914. -
  915. -LINK SUPPORT
  916. -
  917. -    MAX STACKS 1
  918. -    MAX BOARDS 1
  919. -
  920. -LINK DRIVER E2000            ; or other MLID to suit your card
  921. -
  922. -    INT 10                ;
  923. -    PORT 300            ; to suit your card
  924. -
  925. -    FRAME ETHERNET_II
  926. -
  927. -    PROTOCOL BPQ 8FF ETHERNET_II    ; required for BPQ - can change PID
  928. -
  929. -BPQPARMS                ; optional - only needed if you want
  930. -                    ; to override the default target addr
  931. -
  932. -    ETH_ADDR  FF:FF:FF:FF:FF:FF    ; Target address
  933. -
  934. ------------------------------ cut here -------------------------------------
  935. -
  936. -The above configuration assumes that only BPQ Ethernet is being used.
  937. -
  938. -It is not possible to run IP over AX.25 on the BPQ Ethernet port. To simply
  939. -route IP frames to (say) eth0 would create standard ethernet IP frames and
  940. -completely bypass the AX.25 code. However it is possible to use IP over
  941. -NET/ROM across a BPQ Ethernet link, the performance of such a system is
  942. -very acceptable indeed.
  943. -
  944. -Jonathan Naylor G4KLX
  945. -
  946. -g4klx@amsat.org
  947. +jsn@cs.nott.ac.uk
  948. diff -u --recursive --new-file v2.0.34/linux/Documentation/networking/baycom.txt linux/Documentation/networking/baycom.txt
  949. --- v2.0.34/linux/Documentation/networking/baycom.txt    Wed Dec 31 16:00:00 1969
  950. +++ linux/Documentation/networking/baycom.txt    Mon Jul 13 13:47:26 1998
  951. @@ -0,0 +1,131 @@
  952. +            LINUX DRIVER FOR BAYCOM MODEMS
  953. +
  954. +       Thomas M. Sailer, HB9JNX/AE4WA, <sailer@ife.ee.ethz.ch>
  955. +
  956. +This document describes the Linux Kernel Driver for simple Baycom style
  957. +amateur radio modems. The driver supports the following modems:
  958. +
  959. +ser12:  This is a very simple 1200 baud AFSK modem. The modem consists only
  960. +        of a modulator/demodulator chip, usually a TI TCM3105. The computer
  961. +        is responsible for regenerating the receiver bit clock, as well as
  962. +        for handling the HDLC protocol. The modem connects to a serial port,
  963. +        hence the name. Since the serial port is not used as an async serial
  964. +        port, the kernel driver for serial ports cannot be used, and this
  965. +        driver only supports standard serial hardware (8250, 16450, 16550)
  966. +
  967. +par96:  This is a modem for 9600 baud FSK compatible to the G3RUH standard.
  968. +        The modem does all the filtering and regenerates the receiver clock.
  969. +        Data is transferred from and to the PC via a shift register.
  970. +        The shift register is filled with 16 bits and an interrupt is signalled.
  971. +        The PC then empties the shift register in a burst. This modem connects
  972. +        to the parallel port, hence the name. The modem leaves the 
  973. +        implementation of the HDLC protocol and the scrambler polynomial to
  974. +        the PC.
  975. +
  976. +picpar: This is a redesign of the par96 modem by Henning Rech, DF9IC. The modem
  977. +        is protocol compatible to par96, but uses only three low power ICs
  978. +        and can therefore be fed from the parallel port and does not require
  979. +        an additional power supply. Furthermore, it incorporates a carrier
  980. +        detect circuitry.
  981. +
  982. +All of the above modems only support half duplex communications. However,
  983. +the driver supports the KISS (see below) fullduplex command. It then simply
  984. +starts to send as soon as there's a packet to transmit and does not care
  985. +about DCD, i.e. it starts to send even if there's someone else on the channel.
  986. +This command is required by some implementations of the DAMA channel 
  987. +access protocol.
  988. +
  989. +
  990. +The Interface of the driver
  991. +
  992. +Unlike previous drivers, the driver is no longer a character device,
  993. +but it is now a true kernel network interface. Installation is therefore
  994. +simple. Once installed, four interfaces named bc[0-3] are available.
  995. +sethdlc from the ax25 utilities may be used to set driver states etc.
  996. +Users of userland AX.25 stacks may use the net2kiss utility (also available
  997. +in the ax25 utilities package) to converts packets of a network interface
  998. +to a KISS stream on a pseudo tty. There's also a patch available from
  999. +me for WAMPES which allows attaching a kernel network interface directly.
  1000. +
  1001. +
  1002. +Configuring the driver
  1003. +
  1004. +Every time the driver is inserted into the kernel, it has to know which
  1005. +modems it should access at which ports. This can be done with the setbaycom
  1006. +utility. If you are only using one modem, you can also configure the
  1007. +driver from the insmod command line (or by means of an option line in
  1008. +/etc/conf.modules).
  1009. +
  1010. +Examples: (use either method, not both)
  1011. +  insmod baycom mode="ser12*" iobase=0x3f8 irq=4
  1012. +  sethdlc -i bc0 -p type "ser12*" io 0x3f8 irq 4
  1013. +
  1014. +Both lines configure the first port to drive a ser12 modem at the first
  1015. +serial port (COM1 under DOS). The star ('*') instructs the driver to use
  1016. +the software DCD algorithm (see below).
  1017. +
  1018. +  insmod baycom mode="par96*" iobase=0x378 irq=7
  1019. +  sethdlc -i bc0 -p type "par96*" io 0x378 irq 7
  1020. +
  1021. +Both lines configure the first port to drive a par96 or par97 modem at the
  1022. +first parallel port (LPT1 under DOS). options=1 instructs the driver to use
  1023. +the software DCD algorithm (see below).
  1024. +  
  1025. +  insmod baycom mode="par96" iobase=0x278 irq=5
  1026. +  sethdlc -i bc0 -p type "par96" io 0x278 irq 5
  1027. +
  1028. +Both lines configure the first port to drive a picpar modem at the
  1029. +second parallel port (LPT2 under DOS). The driver uses the hardware DCD
  1030. +signalled by the picpar modem (see below).
  1031. +  
  1032. +The channel access parameters can be set with sethdlc -a or kissparms.
  1033. +Note that both utilities interpret the values slightly different.
  1034. +
  1035. +
  1036. +
  1037. +Hardware DCD versus Software DCD
  1038. +
  1039. +To avoid collisions on the air, the driver must know when the channel is
  1040. +busy. This is the task of the DCD circuitry/software. The driver may either
  1041. +utilise a software DCD algorithm (a star after the mode string) or use a DCD
  1042. +signal from the hardware (no star).
  1043. +
  1044. +ser12:  if software DCD is utilised, the radio's squelch should always be
  1045. +        open. It is highly recommended to use the software DCD algorithm,
  1046. +        as it is much faster than most hardware squelch circuitry. The
  1047. +        disadvantage is a slightly higher load on the system.
  1048. +
  1049. +par96:  the software DCD algorithm for this type of modem is rather poor.
  1050. +        The modem simply does not provide enough information to implement
  1051. +        a reasonable DCD algorithm in software. Therefore, if your radio
  1052. +        feeds the DCD input of the par96 modem, the use of the hardware
  1053. +        DCD circuitry is recommended.
  1054. +
  1055. +picpar: the picpar modem features a builtin DCD hardware, which is highly
  1056. +        recommended.
  1057. +
  1058. +
  1059. +
  1060. +Compatibility with the rest of the Linux kernel
  1061. +
  1062. +The serial driver, the line printer (lp) driver and the baycom driver compete
  1063. +for the same hardware resources. Of course only one driver can access a given
  1064. +interface at a time. The serial driver grabs all interfaces it can find at
  1065. +startup time. Therefore the baycom driver subsequently won't be able to
  1066. +access a serial port. You might therefore find it necessary to release
  1067. +a port owned by the serial driver with 'setserial /dev/ttyS# uart none', where
  1068. +# is the number of the interface. The baycom driver does not reserve any
  1069. +port at startup, unless one is specified on the 'insmod' command line. Another
  1070. +method to solve the problem is to compile all three drivers as modules and
  1071. +leave it to kerneld to load the correct driver depending on the application.
  1072. +
  1073. +
  1074. +Further reading
  1075. +
  1076. +Please take a look at http://www.ife.ee.ethz.ch/~sailer/ham/linux/hdlc.html
  1077. +for further informations on the driver.
  1078. +
  1079. +
  1080. +vy 73s de
  1081. +Tom Sailer, sailer@ife.ee.ethz.ch
  1082. +Packet Radio: hb9jnx@hb9w.che.eu
  1083. diff -u --recursive --new-file v2.0.34/linux/Documentation/networking/soundmodem.txt linux/Documentation/networking/soundmodem.txt
  1084. --- v2.0.34/linux/Documentation/networking/soundmodem.txt    Wed Dec 31 16:00:00 1969
  1085. +++ linux/Documentation/networking/soundmodem.txt    Mon Jul 13 13:47:26 1998
  1086. @@ -0,0 +1,96 @@
  1087. +         LINUX DRIVER FOR SOUNDCARDS AS AX.25 MODEMS
  1088. +
  1089. +       Thomas M. Sailer, HB9JNX/AE4WA, <sailer@ife.ee.ethz.ch>
  1090. +
  1091. +This driver allows either SoundBlaster (sbc) or WindowsSoundSystem (wss)
  1092. +compatible soundcards to be used as either 1200 baud AFSK or 9600 baud FSK
  1093. +AX.25 packet radio modems. Only half duplex operation is supported by
  1094. +the SoundBlaster driver. Fullduplex is supported for WSS chipsets capable
  1095. +of addressing two DMA channels. The driver needs some processing power!
  1096. +A 486DX/2 66MHz is a minimum requirement, otherwise interactive performance
  1097. +of the computer may become sluggish.
  1098. +
  1099. +
  1100. +The Interface of the driver
  1101. +
  1102. +The driver provides a kernel network drivers named sm[0-3]. sethdlc 
  1103. +from the ax25 utilities may be used to set driver states etc. Users
  1104. +of userland AX.25 stacks may use the net2kiss utility (also available
  1105. +in the ax25 utilities package) to converts packets of a network interface
  1106. +to a KISS stream on a pseudo tty. There's also a patch available from
  1107. +me for WAMPES which allows attaching a kernel network interface directly.
  1108. +
  1109. +
  1110. +Configuring the driver
  1111. +
  1112. +Some sound cards need to be initialized before they operate in either
  1113. +SoundBlaster or WSS compatibility mode. The driver does _NOT_ do this;
  1114. +you may use the standard linux sound driver to initialize the soundcard;
  1115. +compile it as a module, and do
  1116. +  insmod sound
  1117. +  rmmod sound
  1118. +The soundcard should then be initialized correctly. isapnptools is another
  1119. +package that can configure PnP soundcards. If your soundcard contains
  1120. +a Crystal CS423x chip, you may also try the setcrystal utility in the
  1121. +ax25-utilities package.
  1122. +
  1123. +Every time the driver is inserted into the kernel, it has to know which
  1124. +modems it should access at which ports. This can be done with the sethdlc
  1125. +utility. If you are only using one modem, you can also configure the
  1126. +driver from the insmod command line (or by means of an option line in
  1127. +/etc/conf.modules).
  1128. +
  1129. +Examples: (use either method, not both)
  1130. +  insmod soundmodem mode="sbc:afsk1200" iobase=0x220 irq=5 dma=1
  1131. +  sethdlc -i sm0 -p hw sbc type afsk1200 io 0x220 irq 5 dma 1
  1132. +
  1133. +Both lines configure the first port to drive a soundblaster card
  1134. +in 1200 baud AFSK mode.
  1135. +
  1136. +The channel access parameters can be set with sethdlc -a or kissparms.
  1137. +Note that both utilities interpret the values slightly different.
  1138. +
  1139. +
  1140. +Input and output levels
  1141. +
  1142. +It is important that the input and output levels are adjusted properly.
  1143. +There are two utilities, available in the ax25 utilities distribution,
  1144. +to facilitate this: smmixer and smdiag. smdiag allows you to display
  1145. +the input signal in an oscilloscope like display or an eye diagram.
  1146. +smmixer allows you to adjust input/output levels. See the respective
  1147. +man pages. These two utilities have two counterparts: xfsmmixer and
  1148. +xfsmdiag. They both require the FORMS to compile, and provide a nicer
  1149. +user interface. Functionality is the same, though.
  1150. +
  1151. +
  1152. +Transmitter keying
  1153. +
  1154. +Since soundcards do not have a DC coupled output; PTT keying options include
  1155. +the following:
  1156. +* VOX circuitry
  1157. +* Serial port pin
  1158. +* Parallel port pin
  1159. +* MPU401 MIDI output via a retriggerable monoflop.
  1160. +Circuit schematics may be found at
  1161. +http://www.ife.ee.ethz.ch/~sailer/pcf/ptt_circ/ptt.html.
  1162. +
  1163. +
  1164. +Compatibility with the rest of the Linux kernel
  1165. +
  1166. +The sound driver and the soundcard modem driver compete for the same
  1167. +hardware resources. Of course only one driver can access a given
  1168. +interface at a time. Worse yet, the sound driver grabs the soundcard
  1169. +at startup time. Therefore the soundcard modem driver subsequently won't
  1170. +be able to access the soundcard. You might therefore find it necessary to
  1171. +unload the sound driver before using the soundcard modem driver.
  1172. +
  1173. +
  1174. +Further reading
  1175. +
  1176. +Please take a look at http://www.ife.ee.ethz.ch/~sailer/ham/linux/hdlc.html
  1177. +for further informations on the driver.
  1178. +
  1179. +
  1180. +vy 73s de
  1181. +Tom Sailer, sailer@ife.ee.ethz.ch
  1182. +Packet Radio: hb9jnx@hb9w.che.eu
  1183. diff -u --recursive --new-file v2.0.34/linux/Documentation/networking/tlan.README linux/Documentation/networking/tlan.README
  1184. --- v2.0.34/linux/Documentation/networking/tlan.README    Mon Jul 13 13:46:24 1998
  1185. +++ linux/Documentation/networking/tlan.README    Mon Jul 13 13:47:26 1998
  1186. @@ -1,6 +1,11 @@
  1187. -Caldera TLAN driver for Linux, version 0.42
  1188. +TLAN driver for Linux, version 0.43
  1189.  README
  1190.  
  1191. +Note: I (James) am not maintaining this driver anymore, as I no longer
  1192. +    have the equipment to do so.  So it is available to anyone who
  1193. +    wishes to take it over ;)  If someone needs to reach me about
  1194. +    it, my new email address is james@sovereign.org.
  1195. +
  1196.  
  1197.  I.  Supported Devices.
  1198.  
  1199. @@ -8,20 +13,32 @@
  1200.  
  1201.      Supported:
  1202.      Vendor ID    Device ID    Name
  1203. -    0e11    ae32        Compaq Netelligent 10/100 TX
  1204. -    0e11    ae34        Compaq Netelligent 10 T
  1205. +    0e11    ae32        Compaq Netelligent 10/100 TX PCI UTP
  1206. +    0e11    ae34        Compaq Netelligent 10 T PCI UTP
  1207.      0e11    ae35        Compaq Integrated NetFlex 3/P
  1208. -    0e11    ae43        Compaq ProLiant Integrated Netelligent 10/100 TX
  1209. -    0e11    ae40        Compaq Dual Port Netelligent 10/100 TX
  1210. -    0e11    b011        Compaq Deskpro 4000 5233MMX
  1211. +    0e11    ae40        Compaq Netelligent Dual 10/100 TX PCI UTP
  1212. +    0e11    ae43        Compaq Netelligent Integrated 10/100 TX UTP
  1213. +    0e11    b011        Compaq Netelligent 10/100 TX Embedded UTP
  1214. +    0e11    b012        Compaq Netelligent 10 T/2 PCI UTP/Coax
  1215. +    0e11    b030        Compaq Netelligent 10/100 TX UTP
  1216.      0e11    f130        Compaq NetFlex 3/P
  1217.      0e11    f150        Compaq NetFlex 3/P
  1218. +    108d    0012        Olicom OC-2325    
  1219. +    108d    0013        Olicom OC-2183
  1220.      108d    0014        Olicom OC-2326    
  1221.  
  1222. +
  1223.      Caveats:
  1224.      
  1225. -    I don't believe 100BaseTX daughterboards will work.  I am interested
  1226. -    in any reports.
  1227. +    I am not sure if 100BaseTX daughterboards (for those cards which
  1228. +    support such things) will work.  I haven't had any solid evidence
  1229. +    either way.
  1230. +
  1231. +    However, if a card supports 100BaseTx without requiring an add
  1232. +    on daughterboard, it should work with 100BaseTx.
  1233. +
  1234. +    The "Netelligent 10 T/2 PCI UTP/Coax" (b012) device is untested,
  1235. +    but I do not expect any problems.
  1236.      
  1237.  
  1238.  II.  Building the Driver.
  1239. @@ -77,6 +94,14 @@
  1240.         device that does not have an AUI/BNC connector will probably
  1241.         cause it to not function correctly.)
  1242.  
  1243. +    4. You can set duplex=1 to force half duplex, and duplex=2 to
  1244. +       force full duplex.
  1245. +
  1246. +    5. You can set speed=10 to force 10Mbs operation, and speed=100Mbs
  1247. +       to force 100Mbs operation. (I'm not sure what will happen
  1248. +       if a card which only supports 10Mbs is forced into 100Mbs
  1249. +       mode.)
  1250. +
  1251.      3. If the driver is built into the kernel, you can use the 3rd
  1252.         and 4th parameters to set aui and debug respectively.  For
  1253.         example:
  1254. @@ -90,6 +115,10 @@
  1255.  
  1256.          0x01 = aui
  1257.          0x02 = use SA_INTERRUPT flag when reserving the irq.
  1258. +        0x04 = use half duplex
  1259. +        0x08 = use full duplex
  1260. +        0x10 = use 10BaseT
  1261. +        0x20 = use 100BaseTx
  1262.  
  1263.  
  1264.  IV.  Things to try if you have problems.
  1265. @@ -98,33 +127,8 @@
  1266.      1. Make sure routing is correct.
  1267.      2. If you are using a 2.1.x kernel, try to duplicate the
  1268.         problem on a 2.0.x (preferably 2.0.29 or 2.0.30) kernel.
  1269. -    3. Set debug to 7, either in tlan.c or through insmod as in
  1270. -       section III.1 above.
  1271. -    4. Make sure klog is running so the kernel messages are
  1272. -       being recorded somewhere.
  1273. -    5. Run the following sequence of programs in order (you
  1274. -       may want to do this within an xterm, as background
  1275. -       traffic may cause a lot of TLAN RECEIVED: messages
  1276. -       on the console):
  1277. -
  1278. -       ifconfig eth0 your.ip.address netmask your.net.mask up
  1279. -       route add -net local.net.address eth0
  1280. -       ifconfig
  1281. -       ping some.computer.on.local.net
  1282. -       ifconfig eth0 down
  1283. -
  1284. -    6. Mail the log of what occurred to me.  Also include the
  1285. -       kernel version and what media/connector type (eg,
  1286. -       10 BaseT/RJ45, 100 BaseTX/RJ45, Thinnet/BNC, etc).
  1287. -
  1288.  
  1289.  
  1290. -Please e-mail me with any comments, successes, or failures.  Thanks.
  1291. -
  1292.  There is also a tlan mailing list which you can join by sending "subscribe tlan"
  1293. -in the body of an email to majordomo@vuser.vu.union.edu.  I will announce new
  1294. -releases of the TLAN driver there.
  1295. -
  1296. -James
  1297. -james.banks@caldera.com
  1298. +in the body of an email to majordomo@vuser.vu.union.edu.
  1299.  
  1300. diff -u --recursive --new-file v2.0.34/linux/Documentation/networking/tulip.txt linux/Documentation/networking/tulip.txt
  1301. --- v2.0.34/linux/Documentation/networking/tulip.txt    Mon Apr 22 01:27:41 1996
  1302. +++ linux/Documentation/networking/tulip.txt    Mon Jul 13 13:47:26 1998
  1303. @@ -1,7 +1,7 @@
  1304. -                Tulip ethernet card driver
  1305. +                Tulip Ethernet Card Driver
  1306.  
  1307.  The Tulip driver is developed by Donald Becker and changed by
  1308. -Takashi Manabe. This driver is designed to work with PCI ethernet
  1309. +Takashi Manabe. This driver is designed to work with PCI Ethernet
  1310.  cards which use the DECchip DC21x4x family. This driver hopefully
  1311.  works with all of 1.2.x and 1.3.x kernels, but I tested only
  1312.  with 1.2.13, 1.3.39, 1.3.49, 1.3.52, 1.3.57 and later.
  1313. diff -u --recursive --new-file v2.0.34/linux/Documentation/networking/z8530drv.txt linux/Documentation/networking/z8530drv.txt
  1314. --- v2.0.34/linux/Documentation/networking/z8530drv.txt    Tue Aug 12 14:47:03 1997
  1315. +++ linux/Documentation/networking/z8530drv.txt    Mon Jul 13 13:47:26 1998
  1316. @@ -238,7 +238,7 @@
  1317.  clock dpll        # clock source: 
  1318.              #     dpll     = normal halfduplex operation
  1319.              #     external = MODEM provides own Rx/Tx clock
  1320. -            #    divider  = use fullduplex divider if
  1321. +            #    divider  = use full duplex divider if
  1322.              #           installed (1)
  1323.  mode nrzi        # HDLC encoding mode
  1324.              #    nrzi = 1k2 MODEM, G3RUH 9k6 MODEM
  1325. @@ -463,7 +463,7 @@
  1326.       Example: sccparam /dev/scc3 speed 9600
  1327.  
  1328.  txdelay:
  1329. -     The delay (in units of 10ms) after keying of the 
  1330. +     The delay (in units of 10 ms) after keying of the 
  1331.       transmitter, until the first byte is sent. This is usually 
  1332.       called "TXDELAY" in a TNC.  When 0 is specified, the driver 
  1333.       will just wait until the CTS signal is asserted. This 
  1334. @@ -485,7 +485,7 @@
  1335.  
  1336.  slottime:
  1337.       This is the time between samples of the channel. It is 
  1338. -     expressed in units of 10ms.  About 200-300 ms (value 20-30) 
  1339. +     expressed in units of 10 ms.  About 200-300 ms (value 20-30) 
  1340.       seems to be a good value.
  1341.  
  1342.       Example: sccparam /dev/scc0 slot 20
  1343. @@ -497,7 +497,7 @@
  1344.       SCC before the transmitter is keyed down. The value depends 
  1345.       on the baudrate selected.  A few character times should be 
  1346.       sufficient, e.g. 40ms at 1200 baud. (value 4)
  1347. -     The value of this parameter is in 10ms units.
  1348. +     The value of this parameter is in 10 ms units.
  1349.  
  1350.       Example: sccparam /dev/scc2 4
  1351.  
  1352. @@ -520,9 +520,9 @@
  1353.  wait:
  1354.       The initial waittime before any transmit attempt, after the 
  1355.       frame has been queue for transmit.  This is the length of 
  1356. -     the first slot in CSMA mode.  In fullduplex modes it is
  1357. +     the first slot in CSMA mode.  In full duplex modes it is
  1358.       set to 0 for maximum performance.
  1359. -     The value of this parameter is in 10ms units. 
  1360. +     The value of this parameter is in 10 ms units. 
  1361.  
  1362.       Example: sccparam /dev/scc1 wait 4
  1363.  
  1364. @@ -547,7 +547,7 @@
  1365.       Example: sccparam /dev/scc3 min 10
  1366.  
  1367.  idle
  1368. -     This parameter specifies the maximum idle time in fullduplex 
  1369. +     This parameter specifies the maximum idle time in full duplex 
  1370.       2 mode, in seconds.  When no frames have been sent for this 
  1371.       time, the transmitter will be keyed down.  A value of 0 is
  1372.       has same result as the fullduplex mode 1. This parameter
  1373. diff -u --recursive --new-file v2.0.34/linux/Documentation/nfsroot.txt linux/Documentation/nfsroot.txt
  1374. --- v2.0.34/linux/Documentation/nfsroot.txt    Mon May  6 02:26:01 1996
  1375. +++ linux/Documentation/nfsroot.txt    Mon Jul 13 13:47:26 1998
  1376. @@ -109,7 +109,7 @@
  1377.          less a value has been received by BOOTP.
  1378.  
  1379.    <hostname>    Name of the client. If empty, the client IP address is
  1380. -        used in ASCII-notation, or the value received by BOOTP.
  1381. +        used in ASCII notation, or the value received by BOOTP.
  1382.  
  1383.    <device>    Name of network device to use. If this is empty, all
  1384.          devices are used for RARP requests, and the first one
  1385. diff -u --recursive --new-file v2.0.34/linux/Documentation/paride.txt linux/Documentation/paride.txt
  1386. --- v2.0.34/linux/Documentation/paride.txt    Wed Dec 31 16:00:00 1969
  1387. +++ linux/Documentation/paride.txt    Mon Jul 13 13:47:26 1998
  1388. @@ -0,0 +1,360 @@
  1389. +
  1390. +        Linux and parallel port IDE devices
  1391. +
  1392. +
  1393. +PARIDE-2.0.35   (c) 1997-8  Grant Guenther <grant@torque.net>
  1394. +
  1395. +*************************************************************************
  1396. +
  1397. +Special notes for the 2.0.35 version:
  1398. +
  1399. +(i)   This is the paride from 2.1.107 retrofitted to work with 2.0.34.
  1400. +     
  1401. +(ii)  PARPORT is _not_ supported.  If you obtain the PARPORT patches
  1402. +      for 2.0 and try to use them, it might work.  I have not tried
  1403. +      it.
  1404. +
  1405. +(iii) There is no guarantee of any ongoing support or future development
  1406. +      for this special retrofit.
  1407. +
  1408. +(iv)  I have not built or tested PARIDE with SMP support in 2.0.35,
  1409. +      use it at your own risk.
  1410. +
  1411. +*************************************************************************
  1412. +
  1413. +1. Introduction
  1414. +
  1415. +Owing to the simplicity and near universality of the parallel port interface
  1416. +to personal computers, many external devices such as portable hard-disk,
  1417. +CD-ROM, LS-120 and tape drives use the parallel port to connect to their
  1418. +host computer.  While some devices (notably scanners) use ad-hoc methods
  1419. +to pass commands and data through the parallel port interface, most 
  1420. +external devices are actually identical to an internal model, but with
  1421. +a parallel-port adapter chip added in.  Some of the original parallel port
  1422. +adapters were little more than mechanisms for multiplexing a SCSI bus.
  1423. +(The Iomega PPA-3 adapter used in the ZIP drives is an example of this
  1424. +approach).  Most current designs, however, take a different approach.
  1425. +The adapter chip reproduces a small ISA or IDE bus in the external device
  1426. +and the communication protocol provides operations for reading and writing
  1427. +device registers, as well as data block transfer functions.  Sometimes,
  1428. +the device being addressed via the parallel cable is a standard SCSI
  1429. +controller like an NCR 5380.  The "ditto" family of external tape
  1430. +drives use the ISA replicator to interface a floppy disk controller,
  1431. +which is then connected to a floppy-tape mechanism.  The vast majority
  1432. +of external parallel port devices, however, are now based on standard
  1433. +IDE type devices, which require no intermediate controller.  If one
  1434. +were to open up a parallel port CD-ROM drive, for instance, one would
  1435. +find a standard ATAPI CD-ROM drive, a power supply, and a single adapter
  1436. +that interconnected a standard PC parallel port cable and a standard
  1437. +IDE cable.  It is usually possible to exchange the CD-ROM device with
  1438. +any other device using the IDE interface. 
  1439. +
  1440. +The document describes the support in Linux for parallel port IDE
  1441. +devices.  It does not cover parallel port SCSI devices, "ditto" tape
  1442. +drives or scanners.  Many different devices are supported by the 
  1443. +parallel port IDE subsystem, including:
  1444. +
  1445. +    MicroSolutions backpack CD-ROM
  1446. +    MicroSolutions backpack PD/CD
  1447. +    MicroSolutions backpack hard-drives
  1448. +    MicroSolutions backpack 8000t tape drive
  1449. +    SyQuest EZ-135, EZ-230 & SparQ drives
  1450. +    Avatar Shark
  1451. +    Imation Superdisk LS-120
  1452. +    FreeCom Power CD
  1453. +    Hewlett-Packard 5GB tape drive
  1454. +    Hewlett-Packard 7100 and 7200 CD-RW drives
  1455. +
  1456. +as well as most of the clone and no-name products on the market.
  1457. +
  1458. +To support such a wide range of devices, PARIDE, the parallel port IDE
  1459. +subsystem, is actually structured in three parts.   There is a base
  1460. +paride module which provides a registry and some common methods for
  1461. +accessing the parallel ports.  The second component is a set of 
  1462. +high-level drivers for each of the different type of supported device: 
  1463. +
  1464. +    pd    IDE disk
  1465. +    pcd    ATAPI CD-ROM
  1466. +    pf    ATAPI disk
  1467. +    pt    ATAPI tape
  1468. +    pg    ATAPI generic
  1469. +
  1470. +(Currently, the pg driver is only used with CD-R drives).
  1471. +
  1472. +The high-level drivers function according to the relevant standards.
  1473. +The third component of PARIDE is a set of low-level protocol drivers
  1474. +for each of the parallel port IDE adapter chips.  Thanks to the interest
  1475. +and encouragement of Linux users from many parts of the world, 
  1476. +support is available for almost all known adapter protocols:
  1477. +
  1478. +        aten    ATEN EH-100                            (HK)
  1479. +        bpck    Microsolutions backpack                (US)
  1480. +        comm    DataStor (old-type) "commuter" adapter (TW)
  1481. +        dstr    DataStor EP-2000                       (TW)
  1482. +        epat    Shuttle EPAT                           (UK)
  1483. +        epia    Shuttle EPIA                           (UK)
  1484. +    fit2    FIT TD-2000                   (US)
  1485. +    fit3    FIT TD-3000                   (US)
  1486. +        frpw    Freecom Power                          (DE)
  1487. +        kbic    KingByte KBIC-951A and KBIC-971A       (TW)
  1488. +    ktti    KT Technology PHd adapter              (SG)
  1489. +        on20    OnSpec 90c20                           (US)
  1490. +        on26    OnSpec 90c26                           (US)
  1491. +
  1492. +
  1493. +2. Using the PARIDE subsystem
  1494. +
  1495. +While configuring the Linux kernel, you may choose either to build
  1496. +the PARIDE drivers into your kernel, or to build them as modules.
  1497. +
  1498. +In either case, you will need to select "Parallel port IDE device support"
  1499. +as well as at least one of the high-level drivers and at least one
  1500. +of the parallel port communication protocols.  If you do not know
  1501. +what kind of parallel port adapter is used in your drive, you could
  1502. +begin by checking the file names and any text files on your DOS 
  1503. +installation floppy.  Alternatively, you can look at the markings on
  1504. +the adapter chip itself.  That's usually sufficient to identify the
  1505. +correct device.  
  1506. +
  1507. +You can actually select all the protocol modules, and allow the PARIDE
  1508. +subsystem to try them all for you.
  1509. +
  1510. +For the "brand-name" products listed above, here are the protocol
  1511. +and high-level drivers that you would use:
  1512. +
  1513. +    Manufacturer        Model        Driver    Protocol
  1514. +    
  1515. +    MicroSolutions        CD-ROM        pcd    bpck
  1516. +    MicroSolutions        PD drive    pf    bpck
  1517. +    MicroSolutions        hard-drive    pd    bpck
  1518. +    MicroSolutions          8000t tape      pt      bpck
  1519. +    SyQuest            EZ, SparQ    pd    epat
  1520. +    Imation            Superdisk    pf    epat
  1521. +    Avatar            Shark        pd    epat
  1522. +    FreeCom            CD-ROM        pcd    frpw
  1523. +    Hewlett-Packard        5GB Tape    pt    epat
  1524. +    Hewlett-Packard        7100/7200    pg    epat
  1525. +
  1526. +2.1  Configuring built-in drivers
  1527. +
  1528. +We recommend that you get to know how the drivers work and how to
  1529. +configure them as loadable modules, before attempting to compile a
  1530. +kernel with the drivers built-in.
  1531. +
  1532. +If you built all of your PARIDE support directly into your kernel,
  1533. +and you have just a single parallel port IDE device, your kernel should
  1534. +locate it automatically for you.  If you have more than one device,
  1535. +you may need to give some command line options to your bootloader
  1536. +(eg: LILO), how to do that is beyond the scope of this document.
  1537. +
  1538. +The high-level drivers accept a number of command line parameters, all
  1539. +of which are documented in the source files in linux/drivers/block/paride.
  1540. +By default, each driver will automatically try all parallel ports it
  1541. +can find, and all protocol types that have been installed, until it finds
  1542. +a parallel port IDE adapter.  Once it finds one, the probe stops.  So,
  1543. +if you have more than one device, you will need to tell the drivers
  1544. +how to identify them.  This requires specifying the port address, the
  1545. +protocol identification number and, for some devices, the drive's
  1546. +chain ID.  While your system is booting, a number of messages are
  1547. +displayed on the console.  Like all such messages, they can be
  1548. +reviewed with the 'dmesg' command.  Among those messages will be
  1549. +some lines like:
  1550. +
  1551. +    paride: bpck registered as protocol 0
  1552. +    paride: epat registered as protocol 1
  1553. +
  1554. +The numbers will always be the same until you build a new kernel with
  1555. +different protocol selections.  You should note these numbers as you
  1556. +will need them to identify the devices.
  1557. +
  1558. +If you happen to be using a MicroSolutions backpack device, you will
  1559. +also need to know the unit ID number for each drive.  This is usually
  1560. +the last two digits of the drive's serial number (but read MicroSolutions'
  1561. +documentation about this).
  1562. +
  1563. +As an example, let's assume that you have a MicroSolutions PD/CD drive
  1564. +with unit ID number 36 connected to the parallel port at 0x378, a SyQuest 
  1565. +EZ-135 connected to the chained port on the PD/CD drive and also an 
  1566. +Imation Superdisk connected to port 0x278.  You could give the following 
  1567. +options on your boot command:
  1568. +
  1569. +    pd.drive0=0x378,1 pf.drive0=0x278,1 pf.drive1=0x378,0,36
  1570. +
  1571. +In the last option, pf.drive1 configures device /dev/pf1, the 0x378
  1572. +is the parallel port base address, the 0 is the protocol registration
  1573. +number and 36 is the chain ID.
  1574. +
  1575. +This (2.0.34) version of PARIDE does not support chained devices on the
  1576. +same parallel port.
  1577. +
  1578. +2.2  Loading and configuring PARIDE as modules
  1579. +
  1580. +It is much faster and simpler to get to understand the PARIDE drivers
  1581. +if you use them as loadable kernel modules.   
  1582. +
  1583. +Note:  using these drivers with the "kerneld" automatic module loading
  1584. +system is not recommended, and is not documented here.  
  1585. +
  1586. +To use PARIDE, you must begin by 
  1587. +
  1588. +    insmod paride
  1589. +
  1590. +this loads a base module which provides a registry for the protocols,
  1591. +among other tasks.
  1592. +
  1593. +Then, load as many of the protocol modules as you think you might need.
  1594. +As you load each module, it will register the protocols that it supports,
  1595. +and print a log message to your kernel log file and your console. For 
  1596. +example:
  1597. +
  1598. +    # insmod epat
  1599. +    paride: epat registered as protocol 0
  1600. +    # insmod kbic
  1601. +    paride: k951 registered as protocol 1
  1602. +        paride: k971 registered as protocol 2
  1603. +
  1604. +Finally, you can load high-level drivers for each kind of device that
  1605. +you have connected.  By default, each driver will autoprobe for a single 
  1606. +device, but you can support up to four similar devices by giving their
  1607. +individual co-ordinates when you load the driver.
  1608. +
  1609. +For example, if you had two no-name CD-ROM drives both using the
  1610. +KingByte KBIC-951A adapter, one on port 0x378 and the other on 0x3bc
  1611. +you could give the following command:
  1612. +
  1613. +    # insmod pcd drive0=0x378,1 drive1=0x3bc,1
  1614. +
  1615. +For most adapters, giving a port address and protocol number is sufficient,
  1616. +but check the source files in linux/drivers/block/paride for more 
  1617. +information.  (Hopefully someone will write some man pages one day !).
  1618. +
  1619. +As another example, here's what happens when PARPORT is installed, and
  1620. +a SyQuest EZ-135 is attached to port 0x378:
  1621. +
  1622. +    # insmod paride
  1623. +    paride: version 1.0 installed
  1624. +    # insmod epat
  1625. +    paride: epat registered as protocol 0
  1626. +    # insmod pd
  1627. +    pd: pd version 1.0, major 45, cluster 64, nice 0
  1628. +    pda: Sharing parport1 at 0x378
  1629. +    pda: epat 1.0, Shuttle EPAT chip c3 at 0x378, mode 5 (EPP-32), delay 1
  1630. +    pda: SyQuest EZ135A, 262144 blocks [128M], (512/16/32), removable media
  1631. +     pda: pda1
  1632. +
  1633. +Note that the last line is the output from the generic partition table
  1634. +scanner - in this case it reports that it has found a disk with one partition.
  1635. +
  1636. +2.3  Using a PARIDE device
  1637. +
  1638. +Once the drivers have been loaded, you can access PARIDE devices in the
  1639. +same way as their traditional counterparts.  You will probably need to
  1640. +create the device "special files".  Here is a simple script that you can
  1641. +cut to a file and execute:
  1642. +
  1643. +#!/bin/bash
  1644. +#
  1645. +# mkd -- a script to create the device special files for the PARIDE subsystem
  1646. +#
  1647. +function mkdev {
  1648. +  mknod $1 $2 $3 $4 ; chmod 0660 $1 ; chown root:disk $1
  1649. +}
  1650. +#
  1651. +function pd {
  1652. +  D=$( printf \\$( printf "x%03x" $[ $1 + 97 ] ) )
  1653. +  mkdev pd$D b 45 $[ $1 * 16 ]
  1654. +  for P in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  1655. +  do mkdev pd$D$P b 45 $[ $1 * 16 + $P ]
  1656. +  done
  1657. +}
  1658. +#
  1659. +cd /dev
  1660. +#
  1661. +for u in 0 1 2 3 ; do pd $u ; done
  1662. +for u in 0 1 2 3 ; do mkdev pcd$u b 46 $u ; done 
  1663. +for u in 0 1 2 3 ; do mkdev pf$u  b 47 $u ; done 
  1664. +for u in 0 1 2 3 ; do mkdev pt$u  c 96 $u ; done 
  1665. +for u in 0 1 2 3 ; do mkdev npt$u c 96 $[ $u + 128 ] ; done 
  1666. +for u in 0 1 2 3 ; do mkdev pg$u  c 97 $u ; done 
  1667. +#
  1668. +# end of mkd
  1669. +
  1670. +With the device files and drivers in place, you can access PARIDE devices
  1671. +like any other Linux device.   For example, to mount a CD-ROM in pcd0, use:
  1672. +
  1673. +    mount /dev/pcd0 /cdrom
  1674. +
  1675. +If you have a fresh Avatar Shark cartridge, and the drive is pda, you
  1676. +might do something like:
  1677. +
  1678. +    fdisk /dev/pda        -- make a new partition table with
  1679. +                   partition 1 of type 83
  1680. +
  1681. +    mke2fs /dev/pda1    -- to build the file system
  1682. +
  1683. +    mkdir /shark        -- make a place to mount the disk
  1684. +
  1685. +    mount /dev/pda1 /shark
  1686. +
  1687. +Devices like the Imation superdisk work in the same way, except that
  1688. +they do not have a partition table.  For example to make a 120MB
  1689. +floppy that you could share with a DOS system:
  1690. +
  1691. +    mkdosfs /dev/pf0
  1692. +    mount /dev/pf0 /mnt
  1693. +
  1694. +2.4  Using the pg driver
  1695. +
  1696. +The pg driver can be used in conjunction with the cdrecord program
  1697. +to create CD-ROMs.  For more information, and the required patches 
  1698. +to cdrecord, please visit http://www.torque.net/parport/cdr.html .
  1699. +
  1700. +3. Troubleshooting
  1701. +
  1702. +While a lot of testing has gone into these drivers to make them work
  1703. +as smoothly as possible, problems will arise.  If you do have problems,
  1704. +please check all the obvious things first:  does the drive work in
  1705. +DOS with the manufacturer's drivers ?  If that doesn't yield any useful
  1706. +clues, then please make sure that only one drive is hooked to your system,
  1707. +and that no other device driver is using your parallel port (check in 
  1708. +/proc/ioports).  Then, load the appropriate drivers (you can load several 
  1709. +protocol modules if you want) as in:
  1710. +
  1711. +    # insmod paride
  1712. +    # insmod epat
  1713. +    # insmod bpck
  1714. +    # insmod kbic
  1715. +    ...
  1716. +    # insmod pd verbose=1
  1717. +
  1718. +(using the correct driver for the type of device you have, of course).
  1719. +The verbose=1 parameter will cause the drivers to log a trace of their
  1720. +activity as they attempt to locate your drive.
  1721. +
  1722. +Use 'dmesg' to capture a log of all the PARIDE messages (any messages
  1723. +beginning with paride:, a protocol module's name or a driver's name) and
  1724. +include that with your bug report.  You can submit a bug report in one
  1725. +of two ways.  Either send it directly to the author of the PARIDE suite,
  1726. +by e-mail to grant@torque.net, or join the linux-parport mailing list
  1727. +and post your report there.
  1728. +
  1729. +You can join the linux-parport mailing list by sending a mail message
  1730. +to 
  1731. +        linux-parport-request@torque.net
  1732. +
  1733. +with the single word 
  1734. +
  1735. +        subscribe
  1736. +
  1737. +in the body of the mail message (not in the subject line).   Please be
  1738. +sure that your mail program is correctly set up when you do this,  as
  1739. +the list manager is a robot that will subscribe you using the reply
  1740. +address in your mail headers.  REMOVE any anti-spam gimmicks you may
  1741. +have in your mail headers, when sending mail to the list server.
  1742. +
  1743. +You might also find some useful information on the linux-parport
  1744. +web pages (although they are not always up to date) at
  1745. +
  1746. +    http://www.torque.net/parport/
  1747. +
  1748. +
  1749. diff -u --recursive --new-file v2.0.34/linux/Documentation/rtc.txt linux/Documentation/rtc.txt
  1750. --- v2.0.34/linux/Documentation/rtc.txt    Mon Jul 13 13:46:24 1998
  1751. +++ linux/Documentation/rtc.txt    Mon Jul 13 13:47:26 1998
  1752. @@ -158,7 +158,7 @@
  1753.  fflush(stderr);
  1754.  for (i=1; i<6; i++) {
  1755.      struct timeval tv = {5, 0};    /* 5 second timeout on select */
  1756. -    struct fd_set readfds;
  1757. +    fd_set readfds;
  1758.  
  1759.      FD_ZERO(&readfds);
  1760.      FD_SET(fd, &readfds);
  1761. diff -u --recursive --new-file v2.0.34/linux/Documentation/smp.tex linux/Documentation/smp.tex
  1762. --- v2.0.34/linux/Documentation/smp.tex    Thu Jun  6 04:57:43 1996
  1763. +++ linux/Documentation/smp.tex    Mon Jul 13 13:47:26 1998
  1764. @@ -24,8 +24,8 @@
  1765.  \hfill Alan Cox, 1995
  1766.  
  1767.  
  1768. -The author wishes to thank Caldera Inc ( http://www.caldera.com )
  1769. -whose donation of an ASUS dual pentium board made this project possible, 
  1770. +The author wishes to thank Caldera Inc. ( http://www.caldera.com )
  1771. +whose donation of an ASUS dual Pentium board made this project possible, 
  1772.  and Thomas Radke, whose initial work on multiprocessor Linux formed 
  1773.  the backbone of this project.
  1774.  
  1775. @@ -35,7 +35,7 @@
  1776.  specification places much of the onus for hard work on the chipset and 
  1777.  hardware rather than the operating system.
  1778.  
  1779. -The Intel pentium processors have a wide variety of inbuilt facilities for 
  1780. +The Intel Pentium processors have a wide variety of built-in facilities for 
  1781.  supporting multiprocessing, including hardware cache coherency, built in 
  1782.  interprocessor interrupt handling and a set of atomic test and set, 
  1783.  exchange and similar operations. The cache coherency in particular makes the 
  1784. @@ -176,7 +176,7 @@
  1785.  The memory management core of the existing Linux system functions 
  1786.  adequately within the multiprocessor framework providing the locking is 
  1787.  used. Certain processor specific areas do need changing, in particular 
  1788. -invalidate() must invalidate the TLB's of all processors before it returns.
  1789. +invalidate() must invalidate the TLBs of all processors before it returns.
  1790.  
  1791.  
  1792.  \subsubsection{Miscellaneous Functions}
  1793. @@ -210,7 +210,7 @@
  1794.  extensions to standard kernel facilities to cope with multiple processors.
  1795.  
  1796.  \subsubsection{Initialisation}    
  1797. -The intel MP architecture captures all the processors except for a single 
  1798. +The Intel MP architecture captures all the processors except for a single 
  1799.  processor known as the 'boot processor' in the BIOS at boot time. Thus a 
  1800.  single processor enters the kernel bootup code. The first processor 
  1801.  executes the bootstrap code, loads and uncompresses the kernel. Having 
  1802. @@ -266,8 +266,8 @@
  1803.  appropriately. From then on the real APIC logical identity register is 
  1804.  read.
  1805.  
  1806. -Message passing is accomplished using a pair of IPI's on interrupt 13 
  1807. -(unused by the 80486 FPU's in SMP mode) and interrupt 16. Two are used in 
  1808. +Message passing is accomplished using a pair of IPIs on interrupt 13 
  1809. +(unused by the 80486 FPUs in SMP mode) and interrupt 16. Two are used in 
  1810.  order to separate messages that cannot be processed until the receiver 
  1811.  obtains the kernel spinlock from messages that can be processed 
  1812.  immediately. In effect IRQ 13 is a fast IRQ handler that does not obtain 
  1813. diff -u --recursive --new-file v2.0.34/linux/MAINTAINERS linux/MAINTAINERS
  1814. --- v2.0.34/linux/MAINTAINERS    Mon Jul 13 13:46:24 1998
  1815. +++ linux/MAINTAINERS    Mon Jul 13 13:47:26 1998
  1816. @@ -389,6 +389,12 @@
  1817.  L:    linux-scsi@vger.rutgers.edu
  1818.  S:    Maintained
  1819.  
  1820. +GSCD CDROM DRIVER
  1821. +P:    Oliver Raupach
  1822. +M:    oliver@mm.gop.de
  1823. +L:    linux-kernel@vger.rutgers.edu
  1824. +S:    Maintained
  1825. +
  1826.  SBPCD CDROM DRIVER
  1827.  P:    Eberhard Moenkeberg
  1828.  M:    emoenke@gwdg.de
  1829. diff -u --recursive --new-file v2.0.34/linux/Makefile linux/Makefile
  1830. --- v2.0.34/linux/Makefile    Mon Jul 13 13:46:24 1998
  1831. +++ linux/Makefile    Mon Jul 13 13:47:26 1998
  1832. @@ -1,6 +1,6 @@
  1833.  VERSION = 2
  1834.  PATCHLEVEL = 0
  1835. -SUBLEVEL = 34
  1836. +SUBLEVEL = 35
  1837.  
  1838.  ARCH = i386
  1839.  
  1840. @@ -146,6 +146,10 @@
  1841.  DRIVERS := $(DRIVERS) drivers/sbus/sbus.a
  1842.  endif
  1843.  
  1844. +ifeq ($(CONFIG_PARIDE),y)
  1845. +DRIVERS := $(DRIVERS) drivers/block/paride/paride.a
  1846. +endif
  1847. +
  1848.  include arch/$(ARCH)/Makefile
  1849.  
  1850.  ifdef SMP
  1851. @@ -323,6 +327,10 @@
  1852.      rm -f include/linux/autoconf.h include/linux/version.h
  1853.      rm -f drivers/sound/local.h drivers/sound/.defines
  1854.      rm -f drivers/char/uni_hash.tbl drivers/char/conmakehash
  1855. +    rm -f drivers/net/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h
  1856. +    rm -f drivers/net/soundmodem/sm_tbl_{hapn4800,psk4800}.h
  1857. +    rm -f drivers/net/soundmodem/sm_tbl_{afsk2400_7,afsk2400_8}.h
  1858. +    rm -f drivers/net/soundmodem/gentbl
  1859.      rm -f .version .config* config.in config.old
  1860.      rm -f scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp
  1861.      rm -f scripts/lxdialog/*.o scripts/lxdialog/lxdialog
  1862. diff -u --recursive --new-file v2.0.34/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
  1863. --- v2.0.34/linux/arch/alpha/kernel/bios32.c    Mon Jul 13 13:46:25 1998
  1864. +++ linux/arch/alpha/kernel/bios32.c    Mon Jul 13 13:47:26 1998
  1865. @@ -345,13 +345,13 @@
  1866.               * Alpha implementation of the PCI interface:
  1867.               *
  1868.               * In sparse memory address space, the first
  1869. -             * octant (16MB) of every 128MB segment is
  1870. -             * aliased to the the very first 16MB of the
  1871. +             * octant (16 MB) of every 128 MB segment is
  1872. +             * aliased to the very first 16 MB of the
  1873.               * address space (i.e., it aliases the ISA
  1874.               * memory address space).  Thus, we try to
  1875.               * avoid allocating PCI devices in that range.
  1876.               * Can be allocated in 2nd-7th octant only.
  1877. -             * Devices that need more than 112MB of
  1878. +             * Devices that need more than 112 MB of
  1879.               * address space must be accessed through
  1880.               * dense memory space only!
  1881.               */
  1882. diff -u --recursive --new-file v2.0.34/linux/arch/alpha/math-emu/ieee-math.c linux/arch/alpha/math-emu/ieee-math.c
  1883. --- v2.0.34/linux/arch/alpha/math-emu/ieee-math.c    Mon Jul 13 13:46:25 1998
  1884. +++ linux/arch/alpha/math-emu/ieee-math.c    Mon Jul 13 13:47:26 1998
  1885. @@ -733,19 +733,23 @@
  1886.   *       FPCR_INV if invalid operation occurred, etc.
  1887.   */
  1888.  unsigned long
  1889. -ieee_CVTTQ (int f, unsigned long a, unsigned long *b)
  1890. +ieee_CVTTQ (int f, unsigned long a, unsigned long *pb)
  1891.  {
  1892.      unsigned int midway;
  1893. -    unsigned long ov, uv, res = 0;
  1894. +    unsigned long ov, uv, res, b;
  1895.      fpclass_t a_type;
  1896.      EXTENDED temp;
  1897.  
  1898. -    *b = 0;
  1899.      a_type = extend_ieee(a, &temp, DOUBLE);
  1900. +
  1901. +    b = 0x7fffffffffffffff;
  1902. +    res = FPCR_INV;
  1903.      if (a_type == NaN || a_type == INFTY)
  1904. -        return FPCR_INV;
  1905. +        goto out;
  1906. +
  1907. +    res = 0;
  1908.      if (a_type == QNaN)
  1909. -        return 0;
  1910. +        goto out;
  1911.  
  1912.      if (temp.e > 0) {
  1913.          ov = 0;
  1914. @@ -757,7 +761,7 @@
  1915.          if (ov || (temp.f[1] & 0xffc0000000000000))
  1916.              res |= FPCR_IOV | FPCR_INE;
  1917.      }
  1918. -    if (temp.e < 0) {
  1919. +    else if (temp.e < 0) {
  1920.          while (temp.e < 0) {
  1921.              ++temp.e;
  1922.              uv = temp.f[0] & 1;        /* save sticky bit */
  1923. @@ -765,7 +769,8 @@
  1924.              temp.f[0] |= uv;
  1925.          }
  1926.      }
  1927. -    *b = ((temp.f[1] << 9) | (temp.f[0] >> 55)) & 0x7fffffffffffffff;
  1928. +    b = (temp.f[1] << 9) | (temp.f[0] >> 55);
  1929. +
  1930.      /*
  1931.       * Notice: the fraction is only 52 bits long.  Thus, rounding
  1932.       * cannot possibly result in an integer overflow.
  1933. @@ -781,12 +786,12 @@
  1934.          break;
  1935.  
  1936.            case ROUND_PINF:
  1937. -        if ((temp.f[0] & 0x003fffffffffffff) != 0)
  1938. +        if ((temp.f[0] & 0x007fffffffffffff) != 0)
  1939.              ++b;
  1940.          break;
  1941.  
  1942.            case ROUND_NINF:
  1943. -        if ((temp.f[0] & 0x003fffffffffffff) != 0)
  1944. +        if ((temp.f[0] & 0x007fffffffffffff) != 0)
  1945.              --b;
  1946.          break;
  1947.  
  1948. @@ -794,12 +799,15 @@
  1949.          /* no action needed */
  1950.          break;
  1951.      }
  1952. -    if ((temp.f[0] & 0x003fffffffffffff) != 0)
  1953. +    if ((temp.f[0] & 0x007fffffffffffff) != 0)
  1954.          res |= FPCR_INE;
  1955.  
  1956.      if (temp.s) {
  1957. -        *b = -*b;
  1958. +        b = -b;
  1959.      }
  1960. +
  1961. +out:
  1962. +    *pb = b;
  1963.      return res;
  1964.  }
  1965.  
  1966. diff -u --recursive --new-file v2.0.34/linux/arch/i386/defconfig linux/arch/i386/defconfig
  1967. --- v2.0.34/linux/arch/i386/defconfig    Mon Sep 22 13:44:01 1997
  1968. +++ linux/arch/i386/defconfig    Mon Jul 13 13:47:26 1998
  1969. @@ -58,6 +58,7 @@
  1970.  # CONFIG_BLK_DEV_MD is not set
  1971.  # CONFIG_BLK_DEV_RAM is not set
  1972.  # CONFIG_BLK_DEV_XD is not set
  1973. +# CONFIG_PARIDE is not set
  1974.  # CONFIG_BLK_DEV_HD is not set
  1975.  
  1976.  #
  1977. @@ -110,9 +111,10 @@
  1978.  # CONFIG_EL1 is not set
  1979.  # CONFIG_EL2 is not set
  1980.  CONFIG_EL3=y
  1981. +# CONFIG_3C515 is not set
  1982.  # CONFIG_VORTEX is not set
  1983. -# CONFIG_LANCE is not set
  1984.  # CONFIG_NET_VENDOR_SMC is not set
  1985. +# CONFIG_NET_PCI is not set
  1986.  # CONFIG_NET_ISA is not set
  1987.  # CONFIG_NET_EISA is not set
  1988.  # CONFIG_NET_POCKET is not set
  1989. @@ -138,15 +140,42 @@
  1990.  # CONFIG_EXT_FS is not set
  1991.  CONFIG_EXT2_FS=y
  1992.  # CONFIG_XIA_FS is not set
  1993. +CONFIG_NLS=y
  1994. +CONFIG_ISO9660_FS=y
  1995.  CONFIG_FAT_FS=y
  1996.  CONFIG_MSDOS_FS=y
  1997. -# CONFIG_VFAT_FS is not set
  1998.  # CONFIG_UMSDOS_FS is not set
  1999. +# CONFIG_VFAT_FS is not set
  2000. +# CONFIG_NLS_CODEPAGE_437 is not set
  2001. +# CONFIG_NLS_CODEPAGE_737 is not set
  2002. +# CONFIG_NLS_CODEPAGE_775 is not set
  2003. +# CONFIG_NLS_CODEPAGE_850 is not set
  2004. +# CONFIG_NLS_CODEPAGE_852 is not set
  2005. +# CONFIG_NLS_CODEPAGE_855 is not set
  2006. +# CONFIG_NLS_CODEPAGE_857 is not set
  2007. +# CONFIG_NLS_CODEPAGE_860 is not set
  2008. +# CONFIG_NLS_CODEPAGE_861 is not set
  2009. +# CONFIG_NLS_CODEPAGE_862 is not set
  2010. +# CONFIG_NLS_CODEPAGE_863 is not set
  2011. +# CONFIG_NLS_CODEPAGE_864 is not set
  2012. +# CONFIG_NLS_CODEPAGE_865 is not set
  2013. +# CONFIG_NLS_CODEPAGE_866 is not set
  2014. +# CONFIG_NLS_CODEPAGE_869 is not set
  2015. +# CONFIG_NLS_CODEPAGE_874 is not set
  2016. +# CONFIG_NLS_ISO8859_1 is not set
  2017. +# CONFIG_NLS_ISO8859_2 is not set
  2018. +# CONFIG_NLS_ISO8859_3 is not set
  2019. +# CONFIG_NLS_ISO8859_4 is not set
  2020. +# CONFIG_NLS_ISO8859_5 is not set
  2021. +# CONFIG_NLS_ISO8859_6 is not set
  2022. +# CONFIG_NLS_ISO8859_7 is not set
  2023. +# CONFIG_NLS_ISO8859_8 is not set
  2024. +# CONFIG_NLS_ISO8859_9 is not set
  2025. +# CONFIG_NLS_KOI8_R is not set
  2026.  CONFIG_PROC_FS=y
  2027.  CONFIG_NFS_FS=y
  2028.  # CONFIG_ROOT_NFS is not set
  2029.  # CONFIG_SMB_FS is not set
  2030. -CONFIG_ISO9660_FS=y
  2031.  # CONFIG_HPFS_FS is not set
  2032.  # CONFIG_SYSV_FS is not set
  2033.  # CONFIG_UFS_FS is not set
  2034. diff -u --recursive --new-file v2.0.34/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
  2035. --- v2.0.34/linux/arch/i386/kernel/entry.S    Mon Jul 13 13:46:25 1998
  2036. +++ linux/arch/i386/kernel/entry.S    Mon Jul 13 13:47:27 1998
  2037. @@ -374,6 +374,7 @@
  2038.      jne signal_return
  2039.  2:    RESTORE_ALL
  2040.      ALIGN
  2041. +    .globl signal_return
  2042.  signal_return:
  2043.      movl %esp,%ecx
  2044.      pushl %ecx
  2045. diff -u --recursive --new-file v2.0.34/linux/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S
  2046. --- v2.0.34/linux/arch/i386/kernel/head.S    Mon Jul 13 13:46:25 1998
  2047. +++ linux/arch/i386/kernel/head.S    Mon Jul 13 13:47:27 1998
  2048. @@ -103,16 +103,17 @@
  2049.  checkCPUtype:
  2050.  #endif
  2051.  
  2052. -/* check if it is 486 or 386. */
  2053. +/* check Processor type: 386, 486, 6x86(L) or CPUID capable processor */
  2054.  /*
  2055.   * XXX - this does a lot of unnecessary setup.  Alignment checks don't
  2056.   * apply at our cpl of 0 and the stack ought to be aligned already, and
  2057.   * we don't need to preserve eflags.
  2058.   */
  2059. +
  2060.      movl $3, SYMBOL_NAME(x86)
  2061.      pushfl            # push EFLAGS
  2062.      popl %eax        # get EFLAGS
  2063. -    movl %eax,%ecx        # save original EFLAGS
  2064. +    movl %eax,%ecx        # save original EFLAGS in ecx
  2065.      xorl $0x40000,%eax    # flip AC bit in EFLAGS
  2066.      pushl %eax        # copy to EFLAGS
  2067.      popfl            # set EFLAGS
  2068. @@ -127,10 +128,11 @@
  2069.      pushl %eax
  2070.      popfl            # if we are on a straight 486DX, SX, or
  2071.      pushfl            # 487SX we can't change it
  2072. -    popl %eax
  2073. -    xorl %ecx,%eax
  2074. +    popl %eax        # Also if we are on a Cyrix 6x86(L)
  2075. +    xorl %ecx,%eax        # OTOH 6x86MXs and MIIs check OK
  2076.      andl $0x200000,%eax
  2077. -    je is486
  2078. +    je is486x
  2079. +
  2080.  isnew:    pushl %ecx        # restore original EFLAGS
  2081.      popfl
  2082.      incl SYMBOL_NAME(have_cpuid)    # we have CPUID
  2083. @@ -168,7 +170,72 @@
  2084.      andl $0x80000011,%eax    # Save PG,PE,ET
  2085.      orl $0x50022,%eax    # set AM, WP, NE and MP
  2086.      jmp 2f
  2087. -is486:    pushl %ecx        # restore original EFLAGS
  2088. +
  2089. +/* Now we test if we have a Cyrix 6x86(L). We didn't test before to avoid
  2090. + * clobbering the new BX chipset used with the Pentium II, which has a register
  2091. + * at the same addresses as those used to access the Cyrix special configuration
  2092. + * registers (CCRs).
  2093. + */
  2094. +    /*
  2095. +     * A Cyrix/IBM 6x86(L) preserves flags after dividing 5 by 2
  2096. +     * (and it _must_ be 5 divided by 2) while other CPUs change
  2097. +     * them in undefined ways. We need to know this since we may
  2098. +     * need to enable the CPUID instruction at least.
  2099. +     * We couldn't use this test before since the PPro and PII behave
  2100. +     * like Cyrix chips in this respect.
  2101. +     */
  2102. +is486x:    xor %ax,%ax
  2103. +    sahf
  2104. +    movb $5,%ax
  2105. +    movb $2,%bx
  2106. +    div %bl
  2107. +    lahf
  2108. +    cmpb $2,%ah
  2109. +    jne ncyrix
  2110. +    /*
  2111. +     * N.B. The pattern of accesses to 0x22 and 0x23 is *essential*
  2112. +     *      so do not try to "optimize" it! For the same reason we
  2113. +     *    do all this with interrupts off.
  2114. +     */
  2115. +#define setCx86(reg, val) \
  2116. +    movb reg,%ax;    \
  2117. +    outb %ax,$0x22;    \
  2118. +    movb val,%ax;    \
  2119. +    outb %ax,$0x23
  2120. +
  2121. +#define getCx86(reg) \
  2122. +    movb reg,%ax;    \
  2123. +    outb %ax,$0x22;    \
  2124. +    inb $0x23,%ax
  2125. +
  2126. +    cli
  2127. +    getCx86($0xc3)        # get CCR3
  2128. +    movb %ax,%cx        # Save old value
  2129. +    movb %ax,%bx
  2130. +    andb $0x0f,%bx        # Enable access to all config registers
  2131. +    orb $0x10,%bx        # by setting bit 4
  2132. +    setCx86($0xc3,%bx)
  2133. +
  2134. +    getCx86($0xe8)        # now we can get CCR4
  2135. +    orb $0x80,%ax        # and set bit 7 (CPUIDEN)
  2136. +    movb %ax,%bx        # to enable CPUID execution
  2137. +    setCx86($0xe8,%bx)
  2138. +
  2139. +        getCx86($0xfe)          # DIR0 : let's check this is a 6x86(L)
  2140. +        andb $0xf0,%ax        # should be 3xh
  2141. +    cmpb $0x30,%ax        # 
  2142. +    jne n6x86
  2143. +        getCx86($0xe9)          # CCR5 : we reset the SLOP bit
  2144. +        andb $0xfd,%ax        # so that udelay calculation
  2145. +        movb %ax,%bx        # is correct on 6x86(L) CPUs
  2146. +        setCx86($0xe9,%bx)
  2147. +    setCx86($0xc3,%cx)    # Restore old CCR3
  2148. +    sti
  2149. +    jmp isnew        # We enabled CPUID now
  2150. +
  2151. +n6x86:    setCx86($0xc3,%cx)    # Restore old CCR3
  2152. +    sti
  2153. +ncyrix:    pushl %ecx        # restore original EFLAGS
  2154.      popfl
  2155.      movl %cr0,%eax        # 486
  2156.      andl $0x80000011,%eax    # Save PG,PE,ET
  2157. diff -u --recursive --new-file v2.0.34/linux/arch/i386/kernel/ksyms.c linux/arch/i386/kernel/ksyms.c
  2158. --- v2.0.34/linux/arch/i386/kernel/ksyms.c    Tue Sep 16 14:40:50 1997
  2159. +++ linux/arch/i386/kernel/ksyms.c    Mon Jul 13 13:47:27 1998
  2160. @@ -5,6 +5,7 @@
  2161.  #include <linux/delay.h>
  2162.  
  2163.  #include <asm/semaphore.h>
  2164. +#include <asm/processor.h>
  2165.  
  2166.  extern void dump_thread(struct pt_regs *, struct user *);
  2167.  extern int dump_fpu(elf_fpregset_t *);
  2168. @@ -12,6 +13,7 @@
  2169.  static struct symbol_table arch_symbol_table = {
  2170.  #include <linux/symtab_begin.h>
  2171.      /* platform dependent support */
  2172. +    X(x86_capability),
  2173.      X(dump_thread),
  2174.      X(dump_fpu),
  2175.      XNOVERS(__do_delay),
  2176. diff -u --recursive --new-file v2.0.34/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c
  2177. --- v2.0.34/linux/arch/i386/kernel/ptrace.c    Mon Jul 13 13:46:25 1998
  2178. +++ linux/arch/i386/kernel/ptrace.c    Mon Jul 13 13:47:27 1998
  2179. @@ -323,41 +323,11 @@
  2180.  }
  2181.  #endif /* defined(CONFIG_MATH_EMULATION) */
  2182.  
  2183. -/* Put a word to the part of the user structure containing
  2184. - * floating point registers
  2185. +/*
  2186.   * Floating point support added to ptrace by Ramon Garcia,
  2187.   * ramon@juguete.quim.ucm.es
  2188.   */
  2189.  
  2190. -static int put_fpreg_word (struct task_struct *child,
  2191. -    unsigned long addr, long data)
  2192. -{
  2193. -    struct user *dummy = NULL;
  2194. -    if (addr < (long) (&dummy->i387.st_space))
  2195. -        return -EIO;
  2196. -    addr -= (long) (&dummy->i387.st_space);
  2197. -
  2198. -    if (!hard_math) {
  2199. -#ifdef CONFIG_MATH_EMULATION
  2200. -        write_emulator_word(child, addr, data);
  2201. -#else
  2202. -        return 0;
  2203. -#endif
  2204. -    }
  2205. -    else 
  2206. -#ifndef __SMP__
  2207. -        if (last_task_used_math == child) {
  2208. -            clts();
  2209. -            __asm__("fsave %0; fwait":"=m" (child->tss.i387));
  2210. -            last_task_used_math = current;
  2211. -            stts();
  2212. -        }
  2213. -#endif
  2214. -    *(long *)
  2215. -        ((char *) (child->tss.i387.hard.st_space) + addr) = data;
  2216. -    return 0;
  2217. -}
  2218. -
  2219.  #ifdef CONFIG_MATH_EMULATION
  2220.  
  2221.  static unsigned long get_emulator_word(struct task_struct *child,
  2222. @@ -386,35 +356,54 @@
  2223.  }
  2224.  
  2225.  #endif /* defined(CONFIG_MATH_EMULATION) */
  2226. -/* Get a word from the part of the user structure containing
  2227. - * floating point registers
  2228. - */
  2229. -static unsigned long get_fpreg_word(struct task_struct *child,
  2230. -    unsigned long addr)
  2231. +
  2232. +static int putreg(struct task_struct *child,
  2233. +    unsigned long regno, unsigned long value)
  2234.  {
  2235. -    struct user *dummy = NULL;
  2236. -    unsigned long tmp;
  2237. -    addr -= (long) (&dummy->i387.st_space);
  2238. -    if (!hard_math) {
  2239. -#ifdef CONFIG_MATH_EMULATION
  2240. -        tmp = get_emulator_word(child, addr);
  2241. -#else
  2242. -        tmp = 0;
  2243. -#endif /* !defined(CONFIG_MATH_EMULATION) */
  2244. -    } else {
  2245. -#ifndef __SMP__
  2246. -        if (last_task_used_math == child) {
  2247. -            clts();
  2248. -            __asm__("fsave %0; fwait":"=m" (child->tss.i387));
  2249. -            last_task_used_math = current;
  2250. -            stts();
  2251. -        }
  2252. -#endif
  2253. -        tmp = *(long *)
  2254. -            ((char *) (child->tss.i387.hard.st_space) +
  2255. -             addr);
  2256. +    switch (regno >> 2) {
  2257. +        case ORIG_EAX:
  2258. +            return -EIO;
  2259. +        case FS:
  2260. +        case GS:
  2261. +        case DS:
  2262. +        case ES:
  2263. +            if (value && (value & 3) != 3)
  2264. +                return -EIO;
  2265. +            value &= 0xffff;
  2266. +            break;
  2267. +        case SS:
  2268. +        case CS:
  2269. +            if ((value & 3) != 3)
  2270. +                return -EIO;
  2271. +            value &= 0xffff;
  2272. +            break;
  2273. +        case EFL:
  2274. +            value &= FLAG_MASK;
  2275. +            value |= get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~FLAG_MASK;
  2276.      }
  2277. -    return tmp;
  2278. +    put_stack_long(child, regno - sizeof(struct pt_regs), value);
  2279. +    return 0;
  2280. +}
  2281. +
  2282. +static unsigned long getreg(struct task_struct *child,
  2283. +    unsigned long regno)
  2284. +{
  2285. +    unsigned long retval = ~0UL;
  2286. +
  2287. +    switch (regno >> 2) {
  2288. +        case FS:
  2289. +        case GS:
  2290. +        case DS:
  2291. +        case ES:
  2292. +        case SS:
  2293. +        case CS:
  2294. +            retval = 0xffff;
  2295. +            /* fall through */
  2296. +        default:
  2297. +            regno = regno - sizeof(struct pt_regs);
  2298. +            retval &= get_stack_long(child, regno);
  2299. +    }
  2300. +    return retval;
  2301.  }
  2302.  
  2303.  asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
  2304. @@ -490,39 +479,23 @@
  2305.              unsigned long tmp;
  2306.              int res;
  2307.              
  2308. -              if ((addr & 3 && 
  2309. -                   (addr < (long) (&dummy->i387) ||
  2310. -                    addr > (long) (&dummy->i387.st_space[20]) )) ||
  2311. -                  addr < 0 || addr > sizeof(struct user) - 3)
  2312. +              if ((addr & 3) || addr < 0
  2313. +                || addr > sizeof(struct user) - 3)
  2314.                  return -EIO;
  2315.              
  2316.              res = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
  2317.              if (res)
  2318.                  return res;
  2319.              tmp = 0;  /* Default return condition */
  2320. -              if (addr >= (long) (&dummy->i387) &&
  2321. -                  addr < (long) (&dummy->i387.st_space[20]) ) {
  2322. -#ifndef CONFIG_MATH_EMULATION
  2323. -                if (!hard_math)
  2324. -                    return -EIO;
  2325. -#endif /* defined(CONFIG_MATH_EMULATION) */
  2326. -                tmp = get_fpreg_word(child, addr);
  2327. -              } 
  2328. -            if(addr < 17*sizeof(long)) {
  2329. -              addr = addr >> 2; /* temporary hack. */
  2330. -
  2331. -              tmp = get_stack_long(child, sizeof(long)*addr - MAGICNUMBER);
  2332. -              if (addr == DS || addr == ES ||
  2333. -                  addr == FS || addr == GS ||
  2334. -                  addr == CS || addr == SS)
  2335. -                tmp &= 0xffff;
  2336. -            };
  2337. -            if(addr >= (long) &dummy->u_debugreg[0] &&
  2338. -               addr <= (long) &dummy->u_debugreg[7]){
  2339. +            if(addr < 17*sizeof(long))
  2340. +                tmp = getreg(child, addr);
  2341. +            else if(addr >= (long) &dummy->u_debugreg[0]
  2342. +                && addr <= (long) &dummy->u_debugreg[7])
  2343. +            {
  2344.                  addr -= (long) &dummy->u_debugreg[0];
  2345.                  addr = addr >> 2;
  2346.                  tmp = child->debugreg[addr];
  2347. -            };
  2348. +            }
  2349.              put_fs_long(tmp,(unsigned long *) data);
  2350.              return 0;
  2351.          }
  2352. @@ -533,50 +506,18 @@
  2353.              return write_long(child,addr,data);
  2354.  
  2355.          case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
  2356. -            if ((addr & 3 &&
  2357. -                 (addr < (long) (&dummy->i387.st_space[0]) ||
  2358. -                  addr > (long) (&dummy->i387.st_space[20]) )) ||
  2359. -                addr < 0 || 
  2360. -                addr > sizeof(struct user) - 3)
  2361. -                return -EIO;
  2362. -                
  2363. -            if (addr >= (long) (&dummy->i387.st_space[0]) &&
  2364. -                addr < (long) (&dummy->i387.st_space[20]) ) {
  2365. -#ifndef CONFIG_MATH_EMULATION
  2366. -                if (!hard_math)
  2367. -                    return -EIO;
  2368. -#endif /* defined(CONFIG_MATH_EMULATION) */
  2369. -                return put_fpreg_word(child, addr, data);
  2370. -            }
  2371. -            addr = addr >> 2; /* temporary hack. */
  2372. -            
  2373. -            if (addr == ORIG_EAX)
  2374. +              if ((addr & 3) || addr < 0
  2375. +                || addr > sizeof(struct user) - 3)
  2376.                  return -EIO;
  2377. -            if (addr == DS || addr == ES ||
  2378. -                addr == FS || addr == GS ||
  2379. -                addr == CS || addr == SS) {
  2380. -                    data &= 0xffff;
  2381. -                    if (data && (data & 3) != 3)
  2382. -                    return -EIO;
  2383. -            }
  2384. -            if (addr == EFL) {   /* flags. */
  2385. -                data &= FLAG_MASK;
  2386. -                data |= get_stack_long(child, EFL*sizeof(long)-MAGICNUMBER)  & ~FLAG_MASK;
  2387. -            }
  2388. -          /* Do not allow the user to set the debug register for kernel
  2389. -             address space */
  2390. -          if(addr < 17){
  2391. -              if (put_stack_long(child, sizeof(long)*addr-MAGICNUMBER, data))
  2392. -                return -EIO;
  2393. -            return 0;
  2394. -            };
  2395. +
  2396. +            if(addr < 17*sizeof(long))
  2397. +                return putreg(child, addr, data);
  2398.  
  2399.            /* We need to be very careful here.  We implicitly
  2400.               want to modify a portion of the task_struct, and we
  2401.               have to be selective about what portions we allow someone
  2402.               to modify. */
  2403.  
  2404. -          addr = addr << 2;  /* Convert back again */
  2405.            if(addr >= (long) &dummy->u_debugreg[0] &&
  2406.               addr <= (long) &dummy->u_debugreg[7]){
  2407.  
  2408. @@ -665,6 +606,108 @@
  2409.              put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
  2410.              return 0;
  2411.          }
  2412. +
  2413. +        case PTRACE_GETREGS: { /* Get all gp regs from the child. */
  2414. +#ifdef CONFIG_MATH_EMULATION
  2415. +            if (!hard_math)
  2416. +                /* Not supported. */
  2417. +                return -EIO;
  2418. +#endif
  2419. +
  2420. +            if (verify_area(VERIFY_WRITE, (void *) data,
  2421. +                    17*sizeof(long)))
  2422. +              return -EIO;
  2423. +            for (i = 0; i < 17*sizeof(long);
  2424. +                 i += sizeof(long), data += sizeof(long))
  2425. +              put_fs_long (getreg(child, i), (unsigned long *) data);
  2426. +            return 0;
  2427. +          };
  2428. +
  2429. +        case PTRACE_SETREGS: { /* Set all gp regs in the child. */
  2430. +            unsigned long tmp;
  2431. +
  2432. +#ifdef CONFIG_MATH_EMULATION
  2433. +            if (!hard_math)
  2434. +                /* Not supported. */
  2435. +                return -EIO;
  2436. +#endif
  2437. +
  2438. +            if (verify_area(VERIFY_READ, (void *) data,
  2439. +                    17*sizeof(long)))
  2440. +              return -EIO;
  2441. +            for (i = 0; i < 17*sizeof(long);
  2442. +                 i += sizeof(long), data += sizeof(long))
  2443. +              {
  2444. +                tmp = get_fs_long ((unsigned long *) data);
  2445. +                putreg(child, i, tmp);
  2446. +              }
  2447. +            return 0;
  2448. +          };
  2449. +
  2450. +        case PTRACE_GETFPREGS: { /* Get the child FPU state. */
  2451. +            unsigned long *tmp;
  2452. +
  2453. +#ifdef CONFIG_MATH_EMULATION
  2454. +            if (!hard_math)
  2455. +                /* Not supported. */
  2456. +                return -EIO;
  2457. +#endif
  2458. +
  2459. +            if (verify_area(VERIFY_WRITE, (void *) data,
  2460. +                    sizeof(struct user_i387_struct)))
  2461. +              return -EIO;
  2462. +            if ( !child->used_math ) {
  2463. +              /* Simulate an empty FPU. */
  2464. +              child->tss.i387.hard.cwd = 0xffff037f;
  2465. +              child->tss.i387.hard.swd = 0xffff0000;
  2466. +              child->tss.i387.hard.twd = 0xffffffff;
  2467. +            }
  2468. +            if (last_task_used_math == child)
  2469. +              {
  2470. +                clts();
  2471. +                __asm__("fnsave %0; fwait":"=m" (child->tss.i387.hard));
  2472. +                last_task_used_math = NULL;
  2473. +                stts();
  2474. +              }
  2475. +            tmp = (unsigned long *) &child->tss.i387.hard;
  2476. +            for ( i = 0; i < sizeof(struct user_i387_struct); i += sizeof(long) )
  2477. +              {
  2478. +                put_fs_long (*tmp, (unsigned long *) data);
  2479. +                data += sizeof(long);
  2480. +                tmp++;
  2481. +              }
  2482. +
  2483. +            return 0;
  2484. +          };
  2485. +
  2486. +        case PTRACE_SETFPREGS: { /* Set the child FPU state. */
  2487. +            unsigned long *tmp;
  2488. +
  2489. +#ifdef CONFIG_MATH_EMULATION
  2490. +            if (!hard_math)
  2491. +                /* Not supported. */
  2492. +                return -EIO;
  2493. +#endif
  2494. +
  2495. +            if (verify_area(VERIFY_READ, (void *) data,
  2496. +                    sizeof(struct user_i387_struct)))
  2497. +              return -EIO;
  2498. +            child->used_math = 1;
  2499. +            if (last_task_used_math == child)
  2500. +              {
  2501. +                /* Discard the state of the FPU */
  2502. +                last_task_used_math = NULL;
  2503. +              }
  2504. +            tmp = (unsigned long *) &child->tss.i387.hard;
  2505. +            for ( i = 0; i < sizeof(struct user_i387_struct); i += sizeof(long) )
  2506. +              {
  2507. +                *tmp = get_fs_long ((unsigned long *) data);
  2508. +                data += sizeof(long);
  2509. +                tmp++;
  2510. +              }
  2511. +            child->flags &= ~PF_USEDFPU;
  2512. +            return 0;
  2513. +          };
  2514.  
  2515.          default:
  2516.              return -EIO;
  2517. diff -u --recursive --new-file v2.0.34/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
  2518. --- v2.0.34/linux/arch/i386/kernel/setup.c    Mon Jul 13 13:46:25 1998
  2519. +++ linux/arch/i386/kernel/setup.c    Mon Jul 13 13:47:27 1998
  2520. @@ -32,6 +32,7 @@
  2521.  #include <asm/segment.h>
  2522.  #include <asm/system.h>
  2523.  #include <asm/smp.h>
  2524. +#include <asm/io.h>
  2525.  
  2526.  /*
  2527.   * Tell us the machine setup..
  2528. @@ -49,7 +50,7 @@
  2529.  
  2530.  unsigned char Cx86_step = 0;
  2531.  static const char *Cx86_type[] = {
  2532. -    "unknown", "1.3", "1.4", "2.4", "2.5", "2.6", "2.7 or 3.7", "4.2"
  2533. +    "unknown", "1.3", "1.4", "1.5", "1.6", "2.4", "2.5", "2.6", "2.7 or 3.7", "4.2"
  2534.      };
  2535.  
  2536.  char ignore_irq13 = 0;        /* set if exception 16 works */
  2537. @@ -224,7 +225,9 @@
  2538.  static const char * i586model(unsigned int nr)
  2539.  {
  2540.      static const char *model[] = {
  2541. -        "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83"
  2542. +        "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83",
  2543. +        "Pentium MMX", NULL, NULL, "Mobile Pentium 75+",
  2544. +        "Mobile Pentium MMX"
  2545.      };
  2546.      if (nr < sizeof(model)/sizeof(char *))
  2547.          return model[nr];
  2548. @@ -235,7 +238,7 @@
  2549.  {
  2550.      unsigned char nr6x86 = 0;
  2551.      static const char *model[] = {
  2552. -        "unknown", "6x86", "6x86L", "6x86MX", "6x86MXi"
  2553. +        "unknown", "6x86", "6x86L", "6x86MX", "MII"
  2554.      };
  2555.      switch (x86) {
  2556.          case 5:
  2557. @@ -247,6 +250,10 @@
  2558.          default:
  2559.              nr6x86 = 0;
  2560.      }
  2561. +
  2562. +    /* We must get the stepping number by reading DIR1 */
  2563. +    outb(0xff, 0x22); x86_mask=inb(0x23);
  2564. +
  2565.      switch (x86_mask) {
  2566.          case 0x03:
  2567.              Cx86_step =  1;    /* 6x86MX Rev 1.3 */
  2568. @@ -254,20 +261,26 @@
  2569.          case 0x04:
  2570.              Cx86_step =  2;    /* 6x86MX Rev 1.4 */
  2571.              break;
  2572. +        case 0x05:
  2573. +            Cx86_step =  3;    /* 6x86MX Rev 1.5 */
  2574. +            break;
  2575. +        case 0x06:
  2576. +            Cx86_step =  4;    /* 6x86MX Rev 1.6 */
  2577. +            break;
  2578.          case 0x14:
  2579. -            Cx86_step =  3;    /* 6x86 Rev 2.4 */
  2580. +            Cx86_step =  5;    /* 6x86 Rev 2.4 */
  2581.              break;
  2582.          case 0x15:
  2583. -            Cx86_step =  4;    /* 6x86 Rev 2.5 */
  2584. +            Cx86_step =  6;    /* 6x86 Rev 2.5 */
  2585.              break;
  2586.          case 0x16:
  2587. -            Cx86_step =  5;    /* 6x86 Rev 2.6 */
  2588. +            Cx86_step =  7;    /* 6x86 Rev 2.6 */
  2589.              break;
  2590.          case 0x17:
  2591. -            Cx86_step =  6;    /* 6x86 Rev 2.7 or 3.7 */
  2592. +            Cx86_step =  8;    /* 6x86 Rev 2.7 or 3.7 */
  2593.              break;
  2594.          case 0x22:
  2595. -            Cx86_step =  7;    /* 6x86L Rev 4.2 */
  2596. +            Cx86_step =  9;    /* 6x86L Rev 4.2 */
  2597.              break;
  2598.          default:
  2599.              Cx86_step = 0;
  2600. @@ -285,12 +298,44 @@
  2601.      return NULL;
  2602.  }
  2603.  
  2604. +struct cpu_model_info {
  2605. +    int x86;
  2606. +    char *model_names[16];
  2607. +};
  2608. +
  2609. +static struct cpu_model_info amd_models[] = {
  2610. +    { 4,
  2611. +      { NULL, NULL, NULL, "DX/2", NULL, NULL, NULL, "DX/2-WB", "DX/4",
  2612. +        "DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT", "Am5x86-WB" }},
  2613. +    { 5,
  2614. +      { "K5/SSA5 (PR-75, PR-90, PR-100)", "K5 (PR-120, PR-133)",
  2615. +        "K5 (PR-166)", "K5 (PR-200)", NULL, NULL,
  2616. +        "K6 (166 - 266)", "K6 (166 - 300)", "K6-2 (200 - 450)",
  2617. +        "K6-3D-Plus (200 - 450)", NULL, NULL, NULL, NULL, NULL, NULL }},
  2618. +};
  2619. +
  2620. +static const char * AMDmodel(void)
  2621. +{
  2622. +    const char *p=NULL;
  2623. +    int i;
  2624. +    
  2625. +    if (x86_model < 16)
  2626. +        for (i=0; i<sizeof(amd_models)/sizeof(struct cpu_model_info); i++)
  2627. +            if (amd_models[i].x86 == x86) {
  2628. +                p = amd_models[i].model_names[(int)x86_model];
  2629. +                break;
  2630. +            }
  2631. +    return p;
  2632. +}
  2633. +
  2634.  static const char * getmodel(int x86, int model)
  2635.  {
  2636.          const char *p = NULL;
  2637.          static char nbuf[12];
  2638.      if (strncmp(x86_vendor_id, "Cyrix", 5) == 0)
  2639.          p = Cx86model();
  2640. +    else if(strcmp(x86_vendor_id, "AuthenticAMD")==0)
  2641. +        p = AMDmodel();
  2642.      else {
  2643.          switch (x86) {
  2644.              case 4:
  2645. diff -u --recursive --new-file v2.0.34/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
  2646. --- v2.0.34/linux/arch/i386/kernel/traps.c    Tue Mar 10 13:19:08 1998
  2647. +++ linux/arch/i386/kernel/traps.c    Mon Jul 13 13:47:27 1998
  2648. @@ -192,13 +192,36 @@
  2649.  DO_ERROR(17, SIGSEGV, "alignment check", alignment_check, current)
  2650.  DO_ERROR(18, SIGSEGV, "reserved", reserved, current)
  2651.  
  2652. +/* signal_return is directly after ret_from_sys_call in entry.S */
  2653. +asmlinkage void ret_from_sys_call(void)    __asm__("ret_from_sys_call");
  2654. +asmlinkage void signal_return(void)    __asm__("signal_return");
  2655. +
  2656.  asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
  2657.  {
  2658.      if (regs->eflags & VM_MASK) {
  2659.          handle_vm86_fault((struct vm86_regs *) regs, error_code);
  2660.          return;
  2661.      }
  2662. -    die_if_kernel("general protection",regs,error_code);
  2663. +
  2664. +    /* 
  2665. +     * HACK HACK HACK  :)  Fixing the segment invalid on syscall return
  2666. +     * barfage for 2.0 has been put into the too-hard basket but having
  2667. +     * a user producing endless GPFs is unacceptable as well. - Paul G.
  2668. +     */
  2669. +    if ((regs->cs & 3) != 3) {
  2670. +        if (regs->eip >= (unsigned long)ret_from_sys_call &&
  2671. +            regs->eip < (unsigned long)signal_return) {
  2672. +            static int moancount = 0;
  2673. +            if (moancount < 5) {
  2674. +                printk(KERN_INFO "Ignoring GPF attempt from program \"%s\" (pid %d).\n",
  2675. +                    current->comm, current->pid);
  2676. +                moancount++;
  2677. +            }
  2678. +            do_exit(SIGSEGV);
  2679. +        }
  2680. +        else 
  2681. +            die_if_kernel("general protection",regs,error_code);
  2682. +    }
  2683.      current->tss.error_code = error_code;
  2684.      current->tss.trap_no = 13;
  2685.      force_sig(SIGSEGV, current);    
  2686. diff -u --recursive --new-file v2.0.34/linux/arch/m68k/atari/stram.c linux/arch/m68k/atari/stram.c
  2687. --- v2.0.34/linux/arch/m68k/atari/stram.c    Wed Dec 27 12:44:28 1995
  2688. +++ linux/arch/m68k/atari/stram.c    Mon Jul 13 13:47:27 1998
  2689. @@ -153,7 +153,7 @@
  2690.  /* ++roman:
  2691.   * 
  2692.   * New version of ST-Ram buffer allocation. Instead of using the
  2693. - * 1 MB - 4 KB that remain when the the ST-Ram chunk starts at $1000
  2694. + * 1 MB - 4 KB that remain when the ST-Ram chunk starts at $1000
  2695.   * (1 MB granularity!), such buffers are reserved like this:
  2696.   *
  2697.   *  - If the kernel resides in ST-Ram anyway, we can take the buffer
  2698. diff -u --recursive --new-file v2.0.34/linux/arch/m68k/fpsp040/res_func.S linux/arch/m68k/fpsp040/res_func.S
  2699. --- v2.0.34/linux/arch/m68k/fpsp040/res_func.S    Fri Apr 26 02:12:35 1996
  2700. +++ linux/arch/m68k/fpsp040/res_func.S    Mon Jul 13 13:47:27 1998
  2701. @@ -1889,7 +1889,7 @@
  2702.  |
  2703.  | Input: a0  points to a normalized number in internal extended format
  2704.  |     d0  is the round precision (=1 for sgl; =2 for dbl)
  2705. -|     d1  is the the single precision or double precision
  2706. +|     d1  is the single precision or double precision
  2707.  |         denorm threshold
  2708.  |
  2709.  | Output: (In the format for dest_sgl or dest_dbl)
  2710. diff -u --recursive --new-file v2.0.34/linux/arch/m68k/fpsp040/slogn.S linux/arch/m68k/fpsp040/slogn.S
  2711. --- v2.0.34/linux/arch/m68k/fpsp040/slogn.S    Fri Apr 26 02:12:35 1996
  2712. +++ linux/arch/m68k/fpsp040/slogn.S    Mon Jul 13 13:47:27 1998
  2713. @@ -17,7 +17,7 @@
  2714.  |        result is provably monotonic in double precision.
  2715.  |
  2716.  |    Speed: The program slogn takes approximately 190 cycles for input 
  2717. -|        argument X such that |X-1| >= 1/16, which is the the usual 
  2718. +|        argument X such that |X-1| >= 1/16, which is the usual 
  2719.  |        situation. For those arguments, slognp1 takes approximately
  2720.  |         210 cycles. For the less common arguments, the program will
  2721.  |         run no worse than 10% slower.
  2722. diff -u --recursive --new-file v2.0.34/linux/arch/m68k/fpsp040/ssin.S linux/arch/m68k/fpsp040/ssin.S
  2723. --- v2.0.34/linux/arch/m68k/fpsp040/ssin.S    Fri Apr 26 02:12:35 1996
  2724. +++ linux/arch/m68k/fpsp040/ssin.S    Mon Jul 13 13:47:27 1998
  2725. @@ -21,7 +21,7 @@
  2726.  |        result is provably monotonic in double precision.
  2727.  |
  2728.  |    Speed: The programs sSIN and sCOS take approximately 150 cycles for
  2729. -|        input argument X such that |X| < 15Pi, which is the the usual
  2730. +|        input argument X such that |X| < 15Pi, which is the usual
  2731.  |        situation. The speed for sSINCOS is approximately 190 cycles.
  2732.  |
  2733.  |    Algorithm:
  2734. diff -u --recursive --new-file v2.0.34/linux/arch/m68k/fpsp040/stan.S linux/arch/m68k/fpsp040/stan.S
  2735. --- v2.0.34/linux/arch/m68k/fpsp040/stan.S    Fri Apr 26 02:12:35 1996
  2736. +++ linux/arch/m68k/fpsp040/stan.S    Mon Jul 13 13:47:27 1998
  2737. @@ -16,7 +16,7 @@
  2738.  |        result is provably monotonic in double precision.
  2739.  |
  2740.  |    Speed: The program sTAN takes approximately 170 cycles for
  2741. -|        input argument X such that |X| < 15Pi, which is the the usual
  2742. +|        input argument X such that |X| < 15Pi, which is the usual
  2743.  |        situation.
  2744.  |
  2745.  |    Algorithm:
  2746. diff -u --recursive --new-file v2.0.34/linux/arch/m68k/fpsp040/sto_res.S linux/arch/m68k/fpsp040/sto_res.S
  2747. --- v2.0.34/linux/arch/m68k/fpsp040/sto_res.S    Tue Apr 23 21:31:24 1996
  2748. +++ linux/arch/m68k/fpsp040/sto_res.S    Mon Jul 13 13:47:27 1998
  2749. @@ -3,7 +3,7 @@
  2750.  |
  2751.  |    Takes the result and puts it in where the user expects it.
  2752.  |    Library functions return result in fp0.    If fp0 is not the
  2753. -|    users destination register then fp0 is moved to the the
  2754. +|    user's destination register then fp0 is moved to the
  2755.  |    correct floating-point destination register.  fp0 and fp1
  2756.  |    are then restored to the original contents. 
  2757.  |
  2758. diff -u --recursive --new-file v2.0.34/linux/arch/m68k/mm/memory.c linux/arch/m68k/mm/memory.c
  2759. --- v2.0.34/linux/arch/m68k/mm/memory.c    Wed May 15 23:05:10 1996
  2760. +++ linux/arch/m68k/mm/memory.c    Mon Jul 13 13:47:27 1998
  2761. @@ -138,7 +138,7 @@
  2762.          return;
  2763.      } else {
  2764.          /*
  2765. -         * move this descriptor the the front of the list, since
  2766. +         * move this descriptor to the front of the list, since
  2767.           * it has one or more free tables.
  2768.           */
  2769.          save_flags(flags);
  2770. diff -u --recursive --new-file v2.0.34/linux/arch/sparc/config.in linux/arch/sparc/config.in
  2771. --- v2.0.34/linux/arch/sparc/config.in    Thu Apr 25 03:22:05 1996
  2772. +++ linux/arch/sparc/config.in    Mon Jul 13 13:47:27 1998
  2773. @@ -40,6 +40,8 @@
  2774.  if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
  2775.    tristate '   Linear (append) mode' CONFIG_MD_LINEAR
  2776.    tristate '   RAID-0 (striping) mode' CONFIG_MD_STRIPED
  2777. +  tristate '   RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
  2778. +  tristate '   RAID-4/RAID-5 mode' CONFIG_MD_RAID5
  2779.  fi
  2780.  
  2781.  tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
  2782. diff -u --recursive --new-file v2.0.34/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S
  2783. --- v2.0.34/linux/arch/sparc/kernel/head.S    Mon May  6 02:26:03 1996
  2784. +++ linux/arch/sparc/kernel/head.S    Mon Jul 13 13:47:27 1998
  2785. @@ -549,7 +549,7 @@
  2786.          bnz    srmmu_nviking            ! is in mbus mode
  2787.           nop
  2788.          
  2789. -        rd    %psr, %g3            ! DONT TOUCH %g3
  2790. +        rd    %psr, %g3            ! DO NOT TOUCH %g3
  2791.          andn    %g3, PSR_ET, %g2
  2792.          wr    %g2, 0x0, %psr
  2793.          WRITE_PAUSE
  2794. @@ -560,10 +560,10 @@
  2795.          set    AC_M_CTPR, %g4
  2796.          lda    [%g4] ASI_M_MMUREGS, %g4
  2797.          sll    %g4, 0x4, %g4            ! We use this below
  2798. -                            ! DONT TOUCH %g4
  2799. +                            ! DO NOT TOUCH %g4
  2800.  
  2801.          /* Set the AC bit in the Viking's MMU control reg. */
  2802. -        lda    [%g0] ASI_M_MMUREGS, %g5    ! DONT TOUCH %g5
  2803. +        lda    [%g0] ASI_M_MMUREGS, %g5    ! DO NOT TOUCH %g5
  2804.          set    0x8000, %g6            ! AC bit mask
  2805.          or    %g5, %g6, %g6            ! Or it in...
  2806.          sta    %g6, [%g0] ASI_M_MMUREGS    ! Close your eyes...
  2807. @@ -886,7 +886,7 @@
  2808.   * No, it doesn't work, have to play the save/readCWP/restore trick.
  2809.   */
  2810.  
  2811. -        wr    %g0, 0x0, %wim            ! so we dont get a trap
  2812. +        wr    %g0, 0x0, %wim            ! so we do not get a trap
  2813.          WRITE_PAUSE
  2814.  
  2815.          save
  2816. diff -u --recursive --new-file v2.0.34/linux/drivers/block/Config.in linux/drivers/block/Config.in
  2817. --- v2.0.34/linux/drivers/block/Config.in    Mon Aug  4 11:45:55 1997
  2818. +++ linux/drivers/block/Config.in    Mon Jul 13 13:47:27 1998
  2819. @@ -45,6 +45,8 @@
  2820.  if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
  2821.    tristate '   Linear (append) mode' CONFIG_MD_LINEAR
  2822.    tristate '   RAID-0 (striping) mode' CONFIG_MD_STRIPED
  2823. +  tristate '   RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
  2824. +  tristate '   RAID-4/RAID-5 mode' CONFIG_MD_RAID5
  2825.  fi
  2826.  tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
  2827.  if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
  2828. @@ -52,6 +54,10 @@
  2829.  fi
  2830.  tristate 'XT harddisk support' CONFIG_BLK_DEV_XD
  2831.  
  2832. +tristate 'Parallel port IDE device support' CONFIG_PARIDE 
  2833. +if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then
  2834. +  source drivers/block/paride/Config.in
  2835. +fi
  2836.  
  2837.  if [ "$CONFIG_BLK_DEV_HD_IDE" = "y" -o "$CONFIG_BLK_DEV_HD_ONLY" = "y" ]; then
  2838.    define_bool CONFIG_BLK_DEV_HD y
  2839. diff -u --recursive --new-file v2.0.34/linux/drivers/block/Makefile linux/drivers/block/Makefile
  2840. --- v2.0.34/linux/drivers/block/Makefile    Mon Aug  4 11:45:55 1997
  2841. +++ linux/drivers/block/Makefile    Mon Jul 13 13:47:27 1998
  2842. @@ -109,6 +109,15 @@
  2843.    endif
  2844.  endif
  2845.  
  2846. +ifeq ($(CONFIG_PARIDE),y)
  2847. +SUB_DIRS        += paride
  2848. +MOD_SUB_DIRS    += paride
  2849. +else
  2850. +  ifeq ($(CONFIG_PARIDE),m)
  2851. +  MOD_SUB_DIRS  += paride
  2852. +  endif
  2853. +endif
  2854. +
  2855.  ifeq ($(CONFIG_BLK_DEV_MD),y)
  2856.  LX_OBJS += md.o
  2857.  
  2858. @@ -128,25 +137,21 @@
  2859.    endif
  2860.  endif
  2861.  
  2862. -#ifeq ($(CONFIG_MD_RAID1),y)
  2863. -#L_OBJS += raid1.o
  2864. -#else
  2865. -#  ifeq ($(CONFIG_MD_SUPPORT_RAID1),y)
  2866. -#    ifeq ($(CONFIG_MD_RAID1),m)
  2867. -#    M_OBJS += raid1.o
  2868. -#    endif
  2869. -#  endif
  2870. -#endif
  2871. -#
  2872. -#ifeq ($(CONFIG_MD_RAID5),y)
  2873. -#L_OBJS += raid5.o
  2874. -#else
  2875. -#  ifeq ($(CONFIG_MD_SUPPORT_RAID5),y)
  2876. -#    ifeq ($(CONFIG_MD_RAID5),m)
  2877. -#    M_OBJS += raid5.o
  2878. -#    endif
  2879. -#  endif
  2880. -#endif
  2881. +ifeq ($(CONFIG_MD_MIRRORING),y)
  2882. +L_OBJS += raid1.o
  2883. +else
  2884. +  ifeq ($(CONFIG_MD_MIRRORING),m)
  2885. +  M_OBJS += raid1.o
  2886. +  endif
  2887. +endif
  2888. +
  2889. +ifeq ($(CONFIG_MD_RAID5),y)
  2890. +L_OBJS += raid5.o
  2891. +else
  2892. +  ifeq ($(CONFIG_MD_RAID5),m)
  2893. +  M_OBJS += raid5.o
  2894. +  endif
  2895. +endif
  2896.  
  2897.  endif
  2898.  
  2899. diff -u --recursive --new-file v2.0.34/linux/drivers/block/hd.c linux/drivers/block/hd.c
  2900. --- v2.0.34/linux/drivers/block/hd.c    Thu Feb 29 21:50:39 1996
  2901. +++ linux/drivers/block/hd.c    Mon Jul 13 13:47:27 1998
  2902. @@ -1064,7 +1064,7 @@
  2903.  #define DEVICE_BUSY busy[target]
  2904.  #define USAGE access_count[target]
  2905.  #define CAPACITY (bios_info[target].head*bios_info[target].sect*bios_info[target].cyl)
  2906. -/* We assume that the the bios parameters do not change, so the disk capacity
  2907. +/* We assume that the BIOS parameters do not change, so the disk capacity
  2908.     will not change */
  2909.  #undef MAYBE_REINIT
  2910.  #define GENDISK_STRUCT hd_gendisk
  2911. diff -u --recursive --new-file v2.0.34/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
  2912. --- v2.0.34/linux/drivers/block/ide-cd.c    Mon Jul 13 13:46:26 1998
  2913. +++ linux/drivers/block/ide-cd.c    Mon Jul 13 13:47:27 1998
  2914. @@ -2414,7 +2414,6 @@
  2915.      case CDROMREADMODE2: {
  2916.          struct cdrom_msf msf;
  2917.          int blocksize, format, stat, lba;
  2918. -        struct atapi_toc *toc;
  2919.          char *buf;
  2920.  
  2921.          if (cmd == CDROMREADMODE1) {
  2922. diff -u --recursive --new-file v2.0.34/linux/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c
  2923. --- v2.0.34/linux/drivers/block/ide-floppy.c    Mon Aug  4 11:45:55 1997
  2924. +++ linux/drivers/block/ide-floppy.c    Mon Jul 13 13:47:27 1998
  2925. @@ -1,5 +1,5 @@
  2926.  /*
  2927. - * linux/drivers/block/ide-floppy.c    Version 0.7 - ALPHA    Aug   4, 1997
  2928. + * linux/drivers/block/ide-floppy.c    Version 0.71 - ALPHA    May  21, 1998
  2929.   *
  2930.   * Copyright (C) 1996, 1997 Gadi Oxman <gadio@netvision.net.il>
  2931.   */
  2932. @@ -23,6 +23,11 @@
  2933.   *                       Fix potential null dereferencing with DEBUG_LOG.
  2934.   * Ver 0.6   Jul  3 97   Limit max sectors per read/write command to 64.
  2935.   * Ver 0.7   Aug  4 97   Increase irq timeout from 10 to 100 seconds.
  2936. + * Ver 0.71  May 21 98   Disallow opening a write protected media for writing
  2937. + *                       Limit max sectors only on IOMEGA ZIP 21.D
  2938. + *                       Issue START cmd only if TEST_UNIT_READY fails
  2939. + *                       Add CDROMEJECT ioctl
  2940. + *                       Clean up error messages a bit
  2941.   */
  2942.  
  2943.  #include <linux/config.h>
  2944. @@ -41,6 +46,7 @@
  2945.  #include <linux/hdreg.h>
  2946.  #include <linux/genhd.h>
  2947.  #include <linux/malloc.h>
  2948. +#include <linux/cdrom.h>
  2949.  
  2950.  #include <asm/byteorder.h>
  2951.  #include <asm/irq.h>
  2952. @@ -80,10 +86,7 @@
  2953.   */
  2954.  #define IDEFLOPPY_PC_STACK        (10 + IDEFLOPPY_MAX_PC_RETRIES)
  2955.  
  2956. -/*
  2957. - *    Some drives fail read/write requests with 64 or more sectors.
  2958. - */
  2959. -#define IDEFLOPPY_MAX_SECTORS        64
  2960. +#define IDEFLOPPY_MAX_SECTORS        256
  2961.  
  2962.  /*
  2963.   *    Some drives require a longer irq timeout.
  2964. @@ -203,6 +206,8 @@
  2965.      int blocks, block_size, bs_factor;            /* Current format */
  2966.      idefloppy_capacity_descriptor_t capacity;        /* Last format capacity */
  2967.      idefloppy_flexible_disk_page_t flexible_disk_page;    /* Copy of the flexible disk page */
  2968. +    int wp;
  2969. +    int max_sectors;
  2970.  
  2971.      unsigned int flags;            /* Status/Action flags */
  2972.  } idefloppy_floppy_t;
  2973. @@ -950,10 +955,16 @@
  2974.      pc->c[4] = start;
  2975.  }
  2976.  
  2977. +static void idefloppy_create_test_unit_ready_cmd (idefloppy_pc_t *pc)
  2978. +{
  2979. +    idefloppy_init_pc (pc);
  2980. +    pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD;
  2981. +}
  2982. +
  2983.  static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, unsigned long sector)
  2984.  {
  2985.      int block = sector / floppy->bs_factor;
  2986. -    int blocks = IDEFLOPPY_MIN(rq->nr_sectors / floppy->bs_factor, IDEFLOPPY_MAX_SECTORS);
  2987. +    int blocks = IDEFLOPPY_MIN(rq->nr_sectors, floppy->max_sectors) / floppy->bs_factor;
  2988.  
  2989.  #if IDEFLOPPY_DEBUG_LOG
  2990.      printk ("create_rw1%d_cmd: block == %d, blocks == %d\n",
  2991. @@ -1057,6 +1068,7 @@
  2992.          return 1;
  2993.      }
  2994.      header = (idefloppy_mode_parameter_header_t *) pc.buffer;
  2995. +    floppy->wp = header->wp;
  2996.      page = (idefloppy_flexible_disk_page_t *) (header + 1);
  2997.  
  2998.      page->transfer_rate = ntohs (page->transfer_rate);
  2999. @@ -1075,8 +1087,10 @@
  3000.      drive->bios_sect = page->sectors;
  3001.      lba_capacity = floppy->blocks * floppy->block_size;
  3002.      if (capacity != lba_capacity) {
  3003. -        printk (KERN_NOTICE "%s: The drive reports both %d and %d bytes as its capacity\n",
  3004. -            drive->name, capacity, lba_capacity);
  3005. +        if (!lba_capacity)
  3006. +            printk(KERN_NOTICE "%s: no media in the drive\n", drive->name);
  3007. +        else printk (KERN_NOTICE "%s: The drive reports both %d and %d bytes as its capacity\n",
  3008. +                 drive->name, capacity, lba_capacity);
  3009.          capacity = IDEFLOPPY_MIN(capacity, lba_capacity);
  3010.          floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0;
  3011.      }
  3012. @@ -1143,6 +1157,17 @@
  3013.  int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file,
  3014.              unsigned int cmd, unsigned long arg)
  3015.  {
  3016. +    idefloppy_pc_t pc;
  3017. +
  3018. +    if (cmd == CDROMEJECT) {
  3019. +        if (drive->usage > 1)
  3020. +            return -EBUSY;
  3021. +        idefloppy_create_prevent_cmd (&pc, 0);
  3022. +        (void) idefloppy_queue_pc_tail (drive, &pc);
  3023. +        idefloppy_create_start_stop_cmd (&pc, 2);
  3024. +        (void) idefloppy_queue_pc_tail (drive, &pc);
  3025. +        return 0;
  3026. +    }
  3027.      return -EIO;
  3028.  }
  3029.  
  3030. @@ -1160,13 +1185,21 @@
  3031.  
  3032.      MOD_INC_USE_COUNT;
  3033.      if (drive->usage == 1) {
  3034. -        idefloppy_create_start_stop_cmd (&pc, 1);
  3035. -        (void) idefloppy_queue_pc_tail (drive, &pc);
  3036. +        idefloppy_create_test_unit_ready_cmd(&pc);
  3037. +        if (idefloppy_queue_pc_tail(drive, &pc)) {
  3038. +            idefloppy_create_start_stop_cmd (&pc, 1);
  3039. +            (void) idefloppy_queue_pc_tail (drive, &pc);
  3040. +        }
  3041.          if (idefloppy_get_capacity (drive)) {
  3042.              drive->usage--;
  3043.              MOD_DEC_USE_COUNT;
  3044.              return -EIO;
  3045.          }
  3046. +        if (floppy->wp && (filp->f_mode & 2)) {
  3047. +            drive->usage--;
  3048. +            MOD_DEC_USE_COUNT;
  3049. +            return -EROFS;
  3050. +        }
  3051.          set_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
  3052.          idefloppy_create_prevent_cmd (&pc, 1);
  3053.          (void) idefloppy_queue_pc_tail (drive, &pc);
  3054. @@ -1328,46 +1361,6 @@
  3055.  }
  3056.  
  3057.  /*
  3058. - *    idefloppy_get_capabilities asks the floppy about its various
  3059. - *    parameters.
  3060. - */
  3061. -static void idefloppy_get_capabilities (ide_drive_t *drive)
  3062. -{
  3063. -    idefloppy_pc_t pc;
  3064. -    idefloppy_mode_parameter_header_t *header;
  3065. -    idefloppy_capabilities_page_t *capabilities;
  3066. -    
  3067. -    idefloppy_create_mode_sense_cmd (&pc, IDEFLOPPY_CAPABILITIES_PAGE, MODE_SENSE_CURRENT);
  3068. -    if (idefloppy_queue_pc_tail (drive,&pc)) {
  3069. -        printk (KERN_ERR "ide-floppy: Can't get drive capabilities\n");
  3070. -        return;
  3071. -    }
  3072. -    header = (idefloppy_mode_parameter_header_t *) pc.buffer;
  3073. -    capabilities = (idefloppy_capabilities_page_t *) (header + 1);
  3074. -
  3075. -    if (!capabilities->sflp)
  3076. -        printk (KERN_INFO "%s: Warning - system floppy device bit is not set\n", drive->name);
  3077. -
  3078. -#if IDEFLOPPY_DEBUG_INFO
  3079. -    printk (KERN_INFO "Dumping the results of the MODE SENSE packet command\n");
  3080. -    printk (KERN_INFO "Mode Parameter Header:\n");
  3081. -    printk (KERN_INFO "Mode Data Length - %d\n",header->mode_data_length);
  3082. -    printk (KERN_INFO "Medium Type - %d\n",header->medium_type);
  3083. -    printk (KERN_INFO "WP - %d\n",header->wp);
  3084. -
  3085. -    printk (KERN_INFO "Capabilities Page:\n");
  3086. -    printk (KERN_INFO "Page code - %d\n",capabilities->page_code);
  3087. -    printk (KERN_INFO "Page length - %d\n",capabilities->page_length);
  3088. -    printk (KERN_INFO "PS - %d\n",capabilities->ps);
  3089. -    printk (KERN_INFO "System Floppy Type device - %s\n",capabilities->sflp ? "Yes":"No");
  3090. -    printk (KERN_INFO "Supports Reporting progress of Format - %s\n",capabilities->srfp ? "Yes":"No");
  3091. -    printk (KERN_INFO "Non CD Optical device - %s\n",capabilities->ncd ? "Yes":"No");
  3092. -    printk (KERN_INFO "Multiple LUN support - %s\n",capabilities->sml ? "Yes":"No");
  3093. -    printk (KERN_INFO "Total LUN supported - %s\n",capabilities->tlun ? "Yes":"No");
  3094. -#endif /* IDEFLOPPY_DEBUG_INFO */
  3095. -}
  3096. -
  3097. -/*
  3098.   *    Driver initialization.
  3099.   */
  3100.  void idefloppy_setup (ide_drive_t *drive)
  3101. @@ -1382,7 +1375,10 @@
  3102.      floppy->pc = floppy->pc_stack;
  3103.      if (gcw.drq_type == 1)
  3104.          set_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags);
  3105. -
  3106. -    idefloppy_get_capabilities (drive);
  3107. +    if (strcmp(drive->id->model, "IOMEGA ZIP 100 ATAPI") == 0 &&
  3108. +        strcmp(drive->id->fw_rev, "21.D") == 0)
  3109. +        floppy->max_sectors = 64;
  3110. +    else
  3111. +        floppy->max_sectors = IDEFLOPPY_MAX_SECTORS;
  3112.      (void) idefloppy_get_capacity (drive);
  3113.  }
  3114. diff -u --recursive --new-file v2.0.34/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c
  3115. --- v2.0.34/linux/drivers/block/ide-tape.c    Wed Nov 13 23:34:52 1996
  3116. +++ linux/drivers/block/ide-tape.c    Mon Jul 13 13:47:28 1998
  3117. @@ -1,5 +1,5 @@
  3118.  /*
  3119. - * linux/drivers/block/ide-tape.c    Version 1.9 - ALPHA    Nov   5, 1996
  3120. + * linux/drivers/block/ide-tape.c    Version 1.91        May  21, 1998
  3121.   *
  3122.   * Copyright (C) 1995, 1996 Gadi Oxman <gadio@netvision.net.il>
  3123.   *
  3124. @@ -195,15 +195,8 @@
  3125.   *                       MTTELL was sometimes returning incorrect results.
  3126.   *                       Return the real block size in the MTIOCGET ioctl.
  3127.   *                       Some error recovery bug fixes.
  3128. - *
  3129. - * We are currently in an *alpha* stage. The driver is not complete and not
  3130. - * much tested. I would strongly suggest to:
  3131. - *
  3132. - *    1. Connect the tape to a separate interface and irq.
  3133. - *    2. Be truly prepared for a kernel crash and the resulting data loss.
  3134. - *    3. Don't rely too much on the resulting backups.
  3135. - *
  3136. - * Other than that, enjoy !
  3137. + * Ver 1.91  May 21 98   Add support for INTERRUPT DRQ devices.
  3138. + *                       Add "speed == 0" work-around for HP COLORADO 5GB
  3139.   *
  3140.   * Here are some words from the first releases of hd.c, which are quoted
  3141.   * in ide.c and apply here as well:
  3142. @@ -1157,11 +1150,6 @@
  3143.          printk ("ide-tape: The removable flag is not set\n");support=0;
  3144.      }
  3145.  
  3146. -    if (gcw.drq_type != 2) {
  3147. -        printk ("ide-tape: Sorry, DRQ types other than Accelerated DRQ\n");
  3148. -        printk ("ide-tape: are still not supported by the driver\n");support=0;
  3149. -    }
  3150. -
  3151.      if (gcw.packet_size != 0) {
  3152.          printk ("ide-tape: Packet size is not 12 bytes long\n");
  3153.          if (gcw.packet_size == 1)
  3154. @@ -1233,6 +1221,8 @@
  3155.  {
  3156.      idetape_tape_t *tape=&(drive->tape);
  3157.      unsigned int allocation_length;
  3158. +    struct idetape_id_gcw gcw;
  3159. +
  3160.  #if IDETAPE_ANTICIPATE_READ_WRITE_DSC
  3161.      ide_hwif_t *hwif = HWIF(drive);
  3162.      unsigned long t1, tmid, tn;
  3163. @@ -1260,7 +1250,10 @@
  3164.      tape->chrdev_direction=idetape_direction_none;
  3165.      tape->reset_issued=0;
  3166.      tape->pc=&(tape->pc_stack [0]);
  3167. -    
  3168. +
  3169. +    *((unsigned short *) &gcw) = drive->id->config;
  3170. +    tape->drq_interrupt = (gcw.drq_type == 1) ? 1 : 0;
  3171. +
  3172.  #if IDETAPE_PIPELINE
  3173.      tape->max_number_of_stages=IDETAPE_MIN_PIPELINE_STAGES;
  3174.  #else
  3175. @@ -1397,6 +1390,15 @@
  3176.      capabilities->speed=idetape_swap_short (capabilities->speed);
  3177.      capabilities->buffer_size=idetape_swap_short (capabilities->buffer_size);
  3178.  
  3179. +    if (!capabilities->speed) {
  3180. +        printk("ide-tape: %s: overriding capabilities->speed (assuming 650KB/sec)\n", drive->name);
  3181. +        capabilities->speed = 650;
  3182. +    }
  3183. +    if (!capabilities->max_speed) {
  3184. +        printk("ide-tape: %s: overriding capabilities->max_speed (assuming 650KB/sec)\n", drive->name);
  3185. +        capabilities->max_speed = 650;
  3186. +    }
  3187. +
  3188.      tape->capabilities=*capabilities;        /* Save us a copy */
  3189.      tape->tape_block_size=capabilities->blk512 ? 512:1024;
  3190.  
  3191. @@ -1441,6 +1443,26 @@
  3192.  #endif /* IDETAPE_DEBUG_LOG */
  3193.  }
  3194.  
  3195. +static void idetape_transfer_pc (ide_drive_t *drive)
  3196. +{
  3197. +    idetape_tape_t *tape=&(drive->tape);
  3198. +    idetape_packet_command_t *pc = tape->pc;
  3199. +    idetape_ireason_reg_t ireason;
  3200. +
  3201. +    if (ide_wait_stat (drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) {
  3202. +        printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
  3203. +        return;
  3204. +    }
  3205. +    ireason.all=IN_BYTE (IDE_IREASON_REG);
  3206. +    if (!ireason.b.cod || ireason.b.io) {
  3207. +        printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
  3208. +        ide_do_reset (drive);
  3209. +        return;
  3210. +    }
  3211. +    ide_set_handler (drive, &idetape_pc_intr, WAIT_CMD);    /* Set the interrupt routine */
  3212. +    ide_output_data (drive,pc->c,12/4);            /* Send the actual packet */
  3213. +}
  3214. +
  3215.  /*
  3216.   *    Packet Command Interface
  3217.   *
  3218. @@ -1489,7 +1511,6 @@
  3219.  {
  3220.      idetape_tape_t *tape;
  3221.      idetape_bcount_reg_t bcount;
  3222. -    idetape_ireason_reg_t ireason;
  3223.      int dma_ok=0;
  3224.  
  3225.      tape=&(drive->tape);
  3226. @@ -1562,37 +1583,21 @@
  3227.      OUT_BYTE (bcount.b.high,IDETAPE_BCOUNTH_REG);
  3228.      OUT_BYTE (bcount.b.low,IDETAPE_BCOUNTL_REG);
  3229.      OUT_BYTE (drive->select.all,IDETAPE_DRIVESEL_REG);
  3230. -    
  3231. -    ide_set_handler (drive,handler,WAIT_CMD);            /* Set the interrupt routine */
  3232. -    OUT_BYTE (WIN_PACKETCMD,IDETAPE_ATACOMMAND_REG);        /* Issue the packet command */
  3233. -    if (ide_wait_stat (drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) {     /* Wait for DRQ to be ready - Assuming Accelerated DRQ */    
  3234. -        /*
  3235. -         *    We currently only support tape drives which report
  3236. -         *    accelerated DRQ assertion. For this case, specs
  3237. -         *    allow up to 50us. We really shouldn't get here.
  3238. -         *
  3239. -         *    ??? Still needs to think what to do if we reach
  3240. -         *    here anyway.
  3241. -         */
  3242. -         
  3243. -        printk ("ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
  3244. -        return;
  3245. -    }
  3246. -    
  3247. -    ireason.all=IN_BYTE (IDETAPE_IREASON_REG);
  3248. -    if (!ireason.b.cod || ireason.b.io) {
  3249. -        printk ("ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
  3250. -        ide_do_reset (drive);
  3251. -        return;        
  3252. -    }
  3253. -        
  3254. -    ide_output_data (drive,pc->c,12/4);            /* Send the actual packet */
  3255. +
  3256.  #ifdef CONFIG_BLK_DEV_TRITON
  3257.      if ((pc->dma_in_progress=dma_ok)) {            /* Begin DMA, if necessary */
  3258.          pc->dma_error=0;
  3259.          (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
  3260.      }
  3261.  #endif /* CONFIG_BLK_DEV_TRITON */
  3262. +
  3263. +    if (tape->drq_interrupt) {
  3264. +        ide_set_handler (drive, &idetape_transfer_pc, WAIT_CMD);
  3265. +        OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);        /* Issue the packet command */
  3266. +    } else {
  3267. +        OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
  3268. +        idetape_transfer_pc (drive);
  3269. +    }
  3270.  }
  3271.  
  3272.  /*
  3273. diff -u --recursive --new-file v2.0.34/linux/drivers/block/ide-tape.h linux/drivers/block/ide-tape.h
  3274. --- v2.0.34/linux/drivers/block/ide-tape.h    Wed Nov  6 04:48:32 1996
  3275. +++ linux/drivers/block/ide-tape.h    Mon Jul 13 13:47:28 1998
  3276. @@ -511,6 +511,8 @@
  3277.      idetape_pipeline_stage_t *last_stage;    /* New requests will be added to the pipeline here */
  3278.      int error_in_pipeline_stage;        /* Set when an error was detected in one of the pipeline stages */    
  3279.      
  3280. +    int drq_interrupt;
  3281. +    
  3282.  } idetape_tape_t;
  3283.  
  3284.  /*
  3285. diff -u --recursive --new-file v2.0.34/linux/drivers/block/ide.c linux/drivers/block/ide.c
  3286. --- v2.0.34/linux/drivers/block/ide.c    Mon Jul 13 13:46:26 1998
  3287. +++ linux/drivers/block/ide.c    Mon Jul 13 13:47:28 1998
  3288. @@ -273,6 +273,10 @@
  3289.   *            add work-around for BMI drives
  3290.   *            remove "LBA" from boot messages
  3291.   * Version 5.53.1    add UDMA "CRC retry" support
  3292. + * Version 5.53.2    add Promise/33 auto-detection and DMA support
  3293. + *            fix MC_ERR handling
  3294. + *            fix mis-detection of NEC cdrom as floppy
  3295. + *            issue ATAPI reset and re-probe after "no response"
  3296.   *
  3297.   *  Some additional driver compile-time options are in ide.h
  3298.   *
  3299. @@ -1059,6 +1063,8 @@
  3300.                  rq->errors = ERROR_MAX;
  3301.              else if (err & TRK0_ERR)    /* help it find track zero */
  3302.                  rq->errors |= ERROR_RECAL;
  3303. +            else if (err & MC_ERR)
  3304. +                drive->special.b.mc = 1;
  3305.          }
  3306.          if ((stat & DRQ_STAT) && rq->cmd != WRITE)
  3307.              try_to_flush_leftover_data(drive);
  3308. @@ -2447,11 +2453,11 @@
  3309.              return;
  3310.          }
  3311.  #endif /* CONFIG_BLK_DEV_PROMISE */
  3312. -        switch (type) {
  3313. +        if (!drive->ide_scsi) switch (type) {
  3314.              case 0:
  3315.                  if (!strstr(id->model, "oppy") && !strstr(id->model, "poyp") && !strstr(id->model, "ZIP"))
  3316.                      printk("cdrom or floppy?, assuming ");
  3317. -                if (drive->media != ide_cdrom) {
  3318. +                if (drive->media != ide_cdrom && !strstr(id->model, "CD-ROM")) {
  3319.  #ifdef CONFIG_BLK_DEV_IDEFLOPPY
  3320.                      printk("FLOPPY drive\n");
  3321.                      drive->media = ide_floppy;
  3322. @@ -2728,6 +2734,7 @@
  3323.  {
  3324.      int rc;
  3325.      ide_hwif_t *hwif = HWIF(drive);
  3326. +    unsigned long timeout;
  3327.  #ifdef CONFIG_BLK_DEV_IDEATAPI
  3328.      if (drive->present) {    /* avoid waiting for inappropriate probes */
  3329.          if ((drive->media != ide_disk) && (cmd == WIN_IDENTIFY))
  3330. @@ -2752,6 +2759,17 @@
  3331.      {
  3332.          if ((rc = try_to_identify(drive,cmd)))   /* send cmd and wait */
  3333.              rc = try_to_identify(drive,cmd); /* failed: try again */
  3334. +        if (rc == 1 && cmd == WIN_PIDENTIFY && drive->autotune != 2) {
  3335. +            printk("%s: no response (status = 0x%02x), resetting drive\n", drive->name, GET_STAT());
  3336. +            delay_50ms();
  3337. +            OUT_BYTE (drive->select.all, IDE_SELECT_REG);
  3338. +            delay_50ms();
  3339. +            OUT_BYTE(WIN_SRST, IDE_COMMAND_REG);
  3340. +            timeout = jiffies;
  3341. +            while ((GET_STAT() & BUSY_STAT) && jiffies < timeout + WAIT_WORSTCASE)
  3342. +                delay_50ms();
  3343. +            rc = try_to_identify(drive, cmd);
  3344. +        }
  3345.          if (rc == 1)
  3346.              printk("%s: no response (status = 0x%02x)\n", drive->name, GET_STAT());
  3347.          (void) GET_STAT();        /* ensure drive irq is clear */
  3348. @@ -3085,7 +3103,7 @@
  3349.      if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
  3350.          const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom",
  3351.                  "serialize", "autotune", "noautotune",
  3352. -                "slow", NULL};
  3353. +                "slow", "ide-scsi", NULL};
  3354.          unit = s[2] - 'a';
  3355.          hw   = unit / MAX_DRIVES;
  3356.          unit = unit % MAX_DRIVES;
  3357. @@ -3118,6 +3136,9 @@
  3358.              case -8: /* "slow" */
  3359.                  drive->slow = 1;
  3360.                  goto done;
  3361. +            case -9: /* "ide-scsi" */
  3362. +                drive->ide_scsi = 1;
  3363. +                goto done;
  3364.              case 3: /* cyl,head,sect */
  3365.                  drive->media    = ide_disk;
  3366.                  drive->cyl    = drive->bios_cyl  = vals[0];
  3367. @@ -3514,6 +3535,43 @@
  3368.  }
  3369.  
  3370.  #endif /* defined(CONFIG_BLK_DEV_RZ1000) || defined(CONFIG_BLK_DEV_TRITON) */
  3371. +
  3372. +static void ide_probe_promise_20246(void)
  3373. +{
  3374. +    byte fn, bus;
  3375. +    unsigned short io[6], count = 0;
  3376. +    unsigned int reg, tmp, i;
  3377. +    ide_hwif_t *hwif;
  3378. +
  3379. +    memset(io, 0, 6 * sizeof(unsigned short));
  3380. +    if (pcibios_find_device(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, 0, &bus, &fn))
  3381. +        return;
  3382. +    printk("ide: Promise Technology IDE Ultra-DMA 33 on PCI bus %d function %d\n", bus, fn);
  3383. +    for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
  3384. +        pcibios_read_config_dword(bus, fn, reg, &tmp);
  3385. +        if (tmp & PCI_BASE_ADDRESS_SPACE_IO)
  3386. +            io[count++] = tmp & PCI_BASE_ADDRESS_IO_MASK;
  3387. +    }
  3388. +    for (i = 2; i < 4; i++) {
  3389. +        hwif = ide_hwifs + i;
  3390. +        if (hwif->chipset == ide_generic) {
  3391. +            printk("ide%d: overridden with command line parameter\n", i);
  3392. +            return;
  3393. +        }
  3394. +        tmp = (i - 2) * 2;
  3395. +        if (!io[tmp] || !io[tmp + 1]) {
  3396. +            printk("ide%d: invalid port address %x, %x -- aborting\n", i, io[tmp], io[tmp + 1]);
  3397. +            return;
  3398. +        }
  3399. +        hwif->io_base = io[tmp];
  3400. +        hwif->ctl_port = io[tmp + 1] + 2;
  3401. +        hwif->noprobe = 0;
  3402. +    }
  3403. +#ifdef CONFIG_BLK_DEV_TRITON
  3404. +    ide_init_promise (bus, fn, &ide_hwifs[2], &ide_hwifs[3], io[4]);
  3405. +#endif /* CONFIG_BLK_DEV_TRITON */
  3406. +}
  3407. +
  3408.  #endif /* CONFIG_PCI */
  3409.  
  3410.  /*
  3411. @@ -3545,6 +3603,7 @@
  3412.          ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, &ide_init_triton, 0);
  3413.          ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, &ide_init_triton, 0);
  3414.  #endif /* CONFIG_BLK_DEV_TRITON */
  3415. +        ide_probe_promise_20246();
  3416.      }
  3417.  #endif /* CONFIG_PCI */
  3418.  #ifdef CONFIG_BLK_DEV_CMD640
  3419. diff -u --recursive --new-file v2.0.34/linux/drivers/block/ide.h linux/drivers/block/ide.h
  3420. --- v2.0.34/linux/drivers/block/ide.h    Mon Jul 13 13:46:26 1998
  3421. +++ linux/drivers/block/ide.h    Mon Jul 13 13:47:28 1998
  3422. @@ -381,6 +381,7 @@
  3423.  #ifdef CONFIG_BLK_DEV_IDESCSI
  3424.      void *scsi;            /* for ide-scsi.c */
  3425.  #endif /* CONFIG_BLK_DEV_IDESCSI */
  3426. +    byte        ide_scsi;    /* use ide-scsi driver */
  3427.      } ide_drive_t;
  3428.  
  3429.  /*
  3430. @@ -428,7 +429,7 @@
  3431.  typedef enum {    ide_unknown,    ide_generic,    ide_triton,
  3432.          ide_cmd640,    ide_dtc2278,    ide_ali14xx,
  3433.          ide_qd6580,    ide_umc8672,    ide_ht6560b,
  3434. -        ide_promise }
  3435. +        ide_promise,    ide_promise_udma }
  3436.      hwif_chipset_t;
  3437.  
  3438.  typedef struct hwif_s {
  3439. @@ -742,4 +743,5 @@
  3440.  
  3441.  #ifdef CONFIG_BLK_DEV_TRITON
  3442.  void ide_init_triton (byte, byte);
  3443. +void ide_init_promise (byte bus, byte fn, ide_hwif_t *hwif0, ide_hwif_t *hwif1, unsigned short dma);
  3444.  #endif /* CONFIG_BLK_DEV_TRITON */
  3445. diff -u --recursive --new-file v2.0.34/linux/drivers/block/linear.c linux/drivers/block/linear.c
  3446. --- v2.0.34/linux/drivers/block/linear.c    Sun May 19 21:50:46 1996
  3447. +++ linux/drivers/block/linear.c    Mon Jul 13 13:47:28 1998
  3448. @@ -161,6 +161,7 @@
  3449.  
  3450.    sz+=sprintf (page+sz, "\n");
  3451.  #endif
  3452. +  sz+=sprintf (page+sz, " %dk rounding", 1<<FACTOR_SHIFT(FACTOR(mddev)));
  3453.    return sz;
  3454.  }
  3455.  
  3456. @@ -169,6 +170,8 @@
  3457.  {
  3458.    "linear",
  3459.    linear_map,
  3460. +  NULL,
  3461. +  NULL,
  3462.    linear_run,
  3463.    linear_stop,
  3464.    linear_status,
  3465. diff -u --recursive --new-file v2.0.34/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
  3466. --- v2.0.34/linux/drivers/block/ll_rw_blk.c    Wed Feb 26 11:10:15 1997
  3467. +++ linux/drivers/block/ll_rw_blk.c    Mon Jul 13 13:47:28 1998
  3468. @@ -280,7 +280,30 @@
  3469.      sti();
  3470.  }
  3471.  
  3472. -static void make_request(int major,int rw, struct buffer_head * bh)
  3473. +#define MAX_SECTORS 244
  3474. +
  3475. +static inline void attempt_merge (struct request *req)
  3476. +{
  3477. +    struct request *next = req->next;
  3478. +
  3479. +    if (!next)
  3480. +        return;
  3481. +    if (req->sector + req->nr_sectors != next->sector)
  3482. +        return;
  3483. +    if (next->sem || req->cmd != next->cmd || req->rq_dev != next->rq_dev || req->nr_sectors + next->nr_sectors >= MAX_SECTORS)
  3484. +        return;
  3485. +#if 0
  3486. +    printk ("%s: merge %ld, %ld + %ld == %ld\n", kdevname(req->rq_dev), req->sector, req->nr_sectors, next->nr_sectors, req->nr_sectors + next->nr_sectors);
  3487. +#endif    
  3488. +    req->bhtail->b_reqnext = next->bh;
  3489. +    req->bhtail = next->bhtail;
  3490. +    req->nr_sectors += next->nr_sectors;
  3491. +    next->rq_status = RQ_INACTIVE;
  3492. +    req->next = next->next;
  3493. +    wake_up (&wait_for_request);
  3494. +}
  3495. +
  3496. +void make_request(int major,int rw, struct buffer_head * bh)
  3497.  {
  3498.      unsigned int sector, count;
  3499.      struct request * req;
  3500. @@ -290,8 +313,12 @@
  3501.      sector = bh->b_rsector;
  3502.  
  3503.      /* Uhhuh.. Nasty dead-lock possible here.. */
  3504. -    if (buffer_locked(bh))
  3505. +    if (buffer_locked(bh)) {
  3506. +#if 0
  3507. +        printk("make_request(): buffer already locked\n");
  3508. +#endif
  3509.          return;
  3510. +    }
  3511.      /* Maybe the above fixes it, and maybe it doesn't boot. Life is interesting */
  3512.  
  3513.      lock_buffer(bh);
  3514. @@ -319,6 +346,9 @@
  3515.              rw = READ;    /* drop into READ */
  3516.          case READ:
  3517.              if (buffer_uptodate(bh)) {
  3518. +#if 0
  3519. +                printk ("make_request(): buffer uptodate for READ\n");
  3520. +#endif
  3521.                  unlock_buffer(bh); /* Hmmph! Already have it */
  3522.                  return;
  3523.              }
  3524. @@ -330,6 +360,9 @@
  3525.              rw = WRITE;    /* drop into WRITE */
  3526.          case WRITE:
  3527.              if (!buffer_dirty(bh)) {
  3528. +#if 0
  3529. +                printk ("make_request(): buffer clean for WRITE\n");
  3530. +#endif
  3531.                  unlock_buffer(bh); /* Hmmph! Nothing to write */
  3532.                  return;
  3533.              }
  3534. @@ -391,7 +424,7 @@
  3535.                  continue;
  3536.              if (req->cmd != rw)
  3537.                  continue;
  3538. -            if (req->nr_sectors >= 244)
  3539. +            if (req->nr_sectors >= MAX_SECTORS)
  3540.                  continue;
  3541.              if (req->rq_dev != bh->b_rdev)
  3542.                  continue;
  3543. @@ -399,6 +432,9 @@
  3544.              if (req->sector + req->nr_sectors == sector) {
  3545.                  req->bhtail->b_reqnext = bh;
  3546.                  req->bhtail = bh;
  3547. +                    req->nr_sectors += count;
  3548. +                /* Can we now merge this req with the next? */
  3549. +                attempt_merge(req);
  3550.              /* or to the beginning? */
  3551.              } else if (req->sector - count == sector) {
  3552.                      bh->b_reqnext = req->bh;
  3553. @@ -406,10 +442,10 @@
  3554.                      req->buffer = bh->b_data;
  3555.                      req->current_nr_sectors = count;
  3556.                      req->sector = sector;
  3557. +                    req->nr_sectors += count;
  3558.              } else
  3559.                  continue;
  3560.  
  3561. -                req->nr_sectors += count;
  3562.              mark_buffer_clean(bh);
  3563.                  sti();
  3564.                  return;
  3565. @@ -512,6 +548,12 @@
  3566.      for (i = 0; i < nr; i++) {
  3567.          if (bh[i]) {
  3568.              set_bit(BH_Req, &bh[i]->b_state);
  3569. +#ifdef CONFIG_BLK_DEV_MD
  3570. +            if (MAJOR(bh[i]->b_dev) == MD_MAJOR) {
  3571. +                md_make_request(MINOR (bh[i]->b_dev), rw, bh[i]);
  3572. +                continue;
  3573. +            }
  3574. +#endif
  3575.              make_request(MAJOR(bh[i]->b_rdev), rw, bh[i]);
  3576.          }
  3577.      }
  3578. @@ -645,6 +687,9 @@
  3579.  #endif
  3580.  #ifdef CONFIG_BLK_DEV_XD
  3581.      xd_init();
  3582. +#endif
  3583. +#ifdef CONFIG_PARIDE
  3584. +        { extern void paride_init(void); paride_init(); };
  3585.  #endif
  3586.  #ifdef CONFIG_BLK_DEV_FD
  3587.      floppy_init();
  3588. diff -u --recursive --new-file v2.0.34/linux/drivers/block/md.c linux/drivers/block/md.c
  3589. --- v2.0.34/linux/drivers/block/md.c    Mon Jul 13 13:46:26 1998
  3590. +++ linux/drivers/block/md.c    Mon Jul 13 13:47:28 1998
  3591. @@ -9,6 +9,9 @@
  3592.  
  3593.     kerneld support by Boris Tobotras <boris@xtalk.msk.su>
  3594.  
  3595. +   RAID-1/RAID-5 extensions by:
  3596. +        Ingo Molnar, Miguel de Icaza, Gadi Oxman
  3597. +   
  3598.     This program is free software; you can redistribute it and/or modify
  3599.     it under the terms of the GNU General Public License as published by
  3600.     the Free Software Foundation; either version 2, or (at your option)
  3601. @@ -31,18 +34,27 @@
  3602.  #include <linux/proc_fs.h>
  3603.  #include <linux/blkdev.h>
  3604.  #include <linux/genhd.h>
  3605. +#include <linux/smp_lock.h>
  3606.  #ifdef CONFIG_KERNELD
  3607.  #include <linux/kerneld.h>
  3608.  #endif
  3609.  #include <linux/errno.h>
  3610. +/*
  3611. + * For kernel_thread()
  3612. + */
  3613. +#define __KERNEL_SYSCALLS__
  3614. +#include <linux/unistd.h>
  3615.  
  3616.  #define MAJOR_NR MD_MAJOR
  3617.  #define MD_DRIVER
  3618.  
  3619.  #include <linux/blk.h>
  3620. +#include <asm/bitops.h>
  3621. +#include <asm/atomic.h>
  3622.  
  3623.  static struct hd_struct md_hd_struct[MAX_MD_DEV];
  3624.  static int md_blocksizes[MAX_MD_DEV];
  3625. +static struct md_thread md_threads[MAX_MD_THREADS];
  3626.  
  3627.  int md_size[MAX_MD_DEV]={0, };
  3628.  
  3629. @@ -91,8 +103,7 @@
  3630.  
  3631.    if (!hd)
  3632.    {
  3633. -    printk ("No gendisk entry for dev %s\n", kdevname(dev));
  3634. -    sprintf (name, "dev %s", kdevname(dev));
  3635. +    sprintf (name, "[dev %s]", kdevname(dev));
  3636.      return (name);
  3637.    }
  3638.  
  3639. @@ -117,23 +128,196 @@
  3640.    read_ahead[MD_MAJOR]=minra;
  3641.  }
  3642.  
  3643. +static int legacy_raid_sb (int minor, int pnum)
  3644. +{
  3645. +    int i, factor;
  3646. +
  3647. +    factor = 1 << FACTOR_SHIFT(FACTOR((md_dev+minor)));
  3648. +
  3649. +    /*****
  3650. +     * do size and offset calculations.
  3651. +     */
  3652. +    for (i=0; i<md_dev[minor].nb_dev; i++) {
  3653. +        md_dev[minor].devices[i].size &= ~(factor - 1);
  3654. +        md_size[minor] += md_dev[minor].devices[i].size;
  3655. +        md_dev[minor].devices[i].offset=i ? (md_dev[minor].devices[i-1].offset + 
  3656. +                            md_dev[minor].devices[i-1].size) : 0;
  3657. +    }
  3658. +    return 0;
  3659. +}
  3660. +
  3661. +static void free_sb (struct md_dev *mddev)
  3662. +{
  3663. +    int i;
  3664. +    struct real_dev *realdev;
  3665. +
  3666. +    if (mddev->sb) {
  3667. +        free_page((unsigned long) mddev->sb);
  3668. +        mddev->sb = NULL;
  3669. +    }
  3670. +    for (i = 0; i <mddev->nb_dev; i++) {
  3671. +        realdev = mddev->devices + i;
  3672. +        if (realdev->sb) {
  3673. +            free_page((unsigned long) realdev->sb);
  3674. +            realdev->sb = NULL;
  3675. +        }
  3676. +    }
  3677. +}
  3678. +
  3679. +static int analyze_sb (int minor, int pnum)
  3680. +{
  3681. +    int i;
  3682. +    struct md_dev *mddev = md_dev + minor;
  3683. +    struct buffer_head *bh;
  3684. +    kdev_t dev;
  3685. +    struct real_dev *realdev;
  3686. +    u32 sb_offset, device_size;
  3687. +    md_superblock_t *sb = NULL;
  3688. +
  3689. +    /*
  3690. +     * raid-0 and linear don't use a raid superblock
  3691. +     */
  3692. +    if (pnum == RAID0 >> PERSONALITY_SHIFT || pnum == LINEAR >> PERSONALITY_SHIFT)
  3693. +        return legacy_raid_sb(minor, pnum);
  3694. +    
  3695. +    /*
  3696. +     * Verify the raid superblock on each real device
  3697. +     */
  3698. +    for (i = 0; i < mddev->nb_dev; i++) {
  3699. +        realdev = mddev->devices + i;
  3700. +        dev = realdev->dev;
  3701. +        device_size = blk_size[MAJOR(dev)][MINOR(dev)];
  3702. +        realdev->sb_offset = sb_offset = MD_NEW_SIZE_BLOCKS(device_size);
  3703. +        set_blocksize(dev, MD_SB_BYTES);
  3704. +        bh = bread(dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
  3705. +        if (bh) {
  3706. +            sb = (md_superblock_t *) bh->b_data;
  3707. +            if (sb->md_magic != MD_SB_MAGIC) {
  3708. +                printk("md: %s: invalid raid superblock magic (%x) on block %u\n", kdevname(dev), sb->md_magic, sb_offset);
  3709. +                goto abort;
  3710. +            }
  3711. +            if (!mddev->sb) {
  3712. +                mddev->sb = (md_superblock_t *) __get_free_page(GFP_KERNEL);
  3713. +                if (!mddev->sb)
  3714. +                    goto abort;
  3715. +                memcpy(mddev->sb, sb, MD_SB_BYTES);
  3716. +            }
  3717. +            realdev->sb = (md_superblock_t *) __get_free_page(GFP_KERNEL);
  3718. +            if (!realdev->sb)
  3719. +                goto abort;
  3720. +            memcpy(realdev->sb, bh->b_data, MD_SB_BYTES);
  3721. +
  3722. +            if (memcmp(mddev->sb, sb, MD_SB_GENERIC_CONSTANT_WORDS * 4)) {
  3723. +                printk(KERN_ERR "md: superblock inconsistenty -- run ckraid\n");
  3724. +                goto abort;
  3725. +            }
  3726. +            /*
  3727. +             * Find the newest superblock version
  3728. +             */
  3729. +            if (sb->utime != mddev->sb->utime) {
  3730. +                printk(KERN_ERR "md: superblock update time inconsistenty -- using the most recent one\n");
  3731. +                if (sb->utime > mddev->sb->utime)
  3732. +                    memcpy(mddev->sb, sb, MD_SB_BYTES);
  3733. +            }
  3734. +            realdev->size = sb->size;
  3735. +        } else
  3736. +            printk(KERN_ERR "md: disabled device %s\n", kdevname(dev));
  3737. +    }
  3738. +    if (!mddev->sb) {
  3739. +        printk(KERN_ERR "md: couldn't access raid array %s\n", kdevname(MKDEV(MD_MAJOR, minor)));
  3740. +        goto abort;
  3741. +    }
  3742. +    sb = mddev->sb;
  3743. +
  3744. +    /*
  3745. +     * Check if we can support this raid array
  3746. +     */
  3747. +    if (sb->major_version != MD_MAJOR_VERSION || sb->minor_version > MD_MINOR_VERSION) {
  3748. +        printk("md: %s: unsupported raid array version %d.%d.%d\n", kdevname(MKDEV(MD_MAJOR, minor)),
  3749. +        sb->major_version, sb->minor_version, sb->patch_version);
  3750. +        goto abort;
  3751. +    }
  3752. +    if (sb->state != (1 << MD_SB_CLEAN)) {
  3753. +        printk(KERN_ERR "md: %s: raid array is not clean -- run ckraid\n", kdevname(MKDEV(MD_MAJOR, minor)));
  3754. +        goto abort;
  3755. +    }
  3756. +    switch (sb->level) {
  3757. +        case 1:
  3758. +            md_size[minor] = sb->size;
  3759. +            break;
  3760. +        case 4:
  3761. +        case 5:
  3762. +            md_size[minor] = sb->size * (sb->raid_disks - 1);
  3763. +            break;
  3764. +        default:
  3765. +            printk(KERN_ERR "md: %s: unsupported raid level %d\n", kdevname(MKDEV(MD_MAJOR, minor)), sb->level);
  3766. +            goto abort;
  3767. +    }
  3768. +    return 0;
  3769. +abort:
  3770. +    free_sb(mddev);
  3771. +    return 1;
  3772. +}
  3773. +
  3774. +int md_update_sb(int minor)
  3775. +{
  3776. +    struct md_dev *mddev = md_dev + minor;
  3777. +    struct buffer_head *bh;
  3778. +    md_superblock_t *sb = mddev->sb;
  3779. +    struct real_dev *realdev;
  3780. +    kdev_t dev;
  3781. +    int i;
  3782. +    u32 sb_offset;
  3783. +
  3784. +    sb->utime = CURRENT_TIME;
  3785. +    for (i = 0; i < mddev->nb_dev; i++) {
  3786. +        realdev = mddev->devices + i;
  3787. +        if (!realdev->sb)
  3788. +            continue;
  3789. +        dev = realdev->dev;
  3790. +        sb_offset = realdev->sb_offset;
  3791. +        set_blocksize(dev, MD_SB_BYTES);
  3792. +        printk("md: updating raid superblock on device %s, sb_offset == %u\n", kdevname(dev), sb_offset);
  3793. +        bh = getblk(dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
  3794. +        if (bh) {
  3795. +            sb = (md_superblock_t *) bh->b_data;
  3796. +            memcpy(sb, mddev->sb, MD_SB_BYTES);
  3797. +            memcpy(&sb->descriptor, sb->disks + realdev->sb->descriptor.number, MD_SB_DESCRIPTOR_WORDS * 4);
  3798. +            mark_buffer_uptodate(bh, 1);
  3799. +            mark_buffer_dirty(bh, 1);
  3800. +            ll_rw_block(WRITE, 1, &bh);
  3801. +            wait_on_buffer(bh);
  3802. +            bforget(bh);
  3803. +            fsync_dev(dev);
  3804. +            invalidate_buffers(dev);
  3805. +        } else
  3806. +            printk(KERN_ERR "md: getblk failed for device %s\n", kdevname(dev));
  3807. +    }
  3808. +    return 0;
  3809. +}
  3810.  
  3811.  static int do_md_run (int minor, int repart)
  3812.  {
  3813. -  int pnum, i, min, current_ra, err;
  3814. -  
  3815. +  int pnum, i, min, factor, current_ra, err;
  3816. +
  3817.    if (!md_dev[minor].nb_dev)
  3818.      return -EINVAL;
  3819.    
  3820.    if (md_dev[minor].pers)
  3821.      return -EBUSY;
  3822. -  
  3823. +
  3824.    md_dev[minor].repartition=repart;
  3825.    
  3826. -  if ((pnum=PERSONALITY(md_dev+minor) >> (PERSONALITY_SHIFT))
  3827. +  if ((pnum=PERSONALITY(&md_dev[minor]) >> (PERSONALITY_SHIFT))
  3828.        >= MAX_PERSONALITY)
  3829.      return -EINVAL;
  3830. -  
  3831. +
  3832. +  /* Only RAID-1 and RAID-5 can have MD devices as underlying devices */
  3833. +  if (pnum != (RAID1 >> PERSONALITY_SHIFT) && pnum != (RAID5 >> PERSONALITY_SHIFT)){
  3834. +      for (i = 0; i < md_dev [minor].nb_dev; i++)
  3835. +          if (MAJOR (md_dev [minor].devices [i].dev) == MD_MAJOR)
  3836. +              return -EINVAL;
  3837. +  }
  3838.    if (!pers[pnum])
  3839.    {
  3840.  #ifdef CONFIG_KERNELD
  3841. @@ -145,7 +329,7 @@
  3842.        return -EINVAL;
  3843.    }
  3844.    
  3845. -  min=1 << FACTOR_SHIFT(FACTOR((md_dev+minor)));
  3846. +  factor = min = 1 << FACTOR_SHIFT(FACTOR((md_dev+minor)));
  3847.    
  3848.    for (i=0; i<md_dev[minor].nb_dev; i++)
  3849.      if (md_dev[minor].devices[i].size<min)
  3850. @@ -154,26 +338,37 @@
  3851.            partition_name (md_dev[minor].devices[i].dev), min);
  3852.        return -EINVAL;
  3853.      }
  3854. +
  3855. +  for (i=0; i<md_dev[minor].nb_dev; i++) {
  3856. +    fsync_dev(md_dev[minor].devices[i].dev);
  3857. +    invalidate_buffers(md_dev[minor].devices[i].dev);
  3858. +  }
  3859.    
  3860.    /* Resize devices according to the factor. It is used to align
  3861.       partitions size on a given chunk size. */
  3862.    md_size[minor]=0;
  3863. -  
  3864. -  for (i=0; i<md_dev[minor].nb_dev; i++)
  3865. -  {
  3866. -    md_dev[minor].devices[i].size &= ~(min - 1);
  3867. -    md_size[minor] += md_dev[minor].devices[i].size;
  3868. -    md_dev[minor].devices[i].offset=i ? (md_dev[minor].devices[i-1].offset + md_dev[minor].devices[i-1].size) : 0;
  3869. -  }
  3870. +
  3871. +  /*
  3872. +   * Analyze the raid superblock
  3873. +   */ 
  3874. +  if (analyze_sb(minor, pnum))
  3875. +    return -EINVAL;
  3876.  
  3877.    md_dev[minor].pers=pers[pnum];
  3878.    
  3879.    if ((err=md_dev[minor].pers->run (minor, md_dev+minor)))
  3880.    {
  3881.      md_dev[minor].pers=NULL;
  3882. +    free_sb(md_dev + minor);
  3883.      return (err);
  3884.    }
  3885. -  
  3886. +
  3887. +  if (pnum != RAID0 >> PERSONALITY_SHIFT && pnum != LINEAR >> PERSONALITY_SHIFT)
  3888. +  {
  3889. +    md_dev[minor].sb->state &= ~(1 << MD_SB_CLEAN);
  3890. +    md_update_sb(minor);
  3891. +  }
  3892. +
  3893.    /* FIXME : We assume here we have blocks
  3894.       that are twice as large as sectors.
  3895.       THIS MAY NOT BE TRUE !!! */
  3896. @@ -191,7 +386,6 @@
  3897.    
  3898.    read_ahead[MD_MAJOR]=current_ra;
  3899.    
  3900. -  printk ("START_DEV md%x %s\n", minor, md_dev[minor].pers->name);
  3901.    return (0);
  3902.  }
  3903.  
  3904. @@ -211,38 +405,40 @@
  3905.      /*  The device won't exist anymore -> flush it now */
  3906.      fsync_dev (inode->i_rdev);
  3907.      invalidate_buffers (inode->i_rdev);
  3908. +    if (md_dev[minor].sb)
  3909. +    {
  3910. +      md_dev[minor].sb->state |= 1 << MD_SB_CLEAN;
  3911. +      md_update_sb(minor);
  3912. +    }
  3913.      md_dev[minor].pers->stop (minor, md_dev+minor);
  3914.    }
  3915.    
  3916.    /* Remove locks. */
  3917. +  if (md_dev[minor].sb)
  3918. +    free_sb(md_dev + minor);
  3919.    for (i=0; i<md_dev[minor].nb_dev; i++)
  3920.      clear_inode (md_dev[minor].devices[i].inode);
  3921. -  
  3922. +
  3923.    md_dev[minor].nb_dev=md_size[minor]=0;
  3924.    md_hd_struct[minor].nr_sects=0;
  3925.    md_dev[minor].pers=NULL;
  3926.    
  3927.    set_ra ();            /* calculate new read_ahead */
  3928.    
  3929. -  printk ("STOP_DEV md%x\n", minor);
  3930.    return (0);
  3931.  }
  3932.  
  3933.  
  3934.  static int do_md_add (int minor, kdev_t dev)
  3935.  {
  3936. -  struct gendisk *gen_real;
  3937.    int i;
  3938. -  
  3939. -  if (MAJOR(dev)==MD_MAJOR || md_dev[minor].nb_dev==MAX_REAL)
  3940. +
  3941. +  if (md_dev[minor].nb_dev==MAX_REAL)
  3942.      return -EINVAL;
  3943.    
  3944.    if (!fs_may_mount (dev) || md_dev[minor].pers)
  3945.      return -EBUSY;
  3946. -  
  3947. -  if (!(gen_real=find_gendisk (dev)))
  3948. -    return -ENOENT;
  3949. -  
  3950. +
  3951.    i=md_dev[minor].nb_dev++;
  3952.    md_dev[minor].devices[i].dev=dev;
  3953.    
  3954. @@ -258,7 +454,13 @@
  3955.    
  3956.    /* Sizes are now rounded at run time */
  3957.    
  3958. -  md_dev[minor].devices[i].size=gen_real->sizes[MINOR(dev)];
  3959. +/*  md_dev[minor].devices[i].size=gen_real->sizes[MINOR(dev)]; HACKHACK*/
  3960. +
  3961. +  if (blk_size[MAJOR(dev)][MINOR(dev)] == 0) {
  3962. +    printk("md_add(): zero device size, huh, bailing out.\n");
  3963. +  }
  3964. +
  3965. +  md_dev[minor].devices[i].size=blk_size[MAJOR(dev)][MINOR(dev)];
  3966.  
  3967.    printk ("REGISTER_DEV %s to md%x done\n", partition_name(dev), minor);
  3968.    return (0);
  3969. @@ -420,6 +622,27 @@
  3970.    return (md_dev[minor].pers->map(md_dev+minor, rdev, rsector, size));
  3971.  }
  3972.    
  3973. +int md_make_request (int minor, int rw, struct buffer_head * bh)
  3974. +{
  3975. +    if (md_dev [minor].pers->make_request) {
  3976. +        if (buffer_locked(bh))
  3977. +            return 0;
  3978. +        if (rw == WRITE || rw == WRITEA) {
  3979. +            if (!buffer_dirty(bh))
  3980. +                return 0;
  3981. +            set_bit(BH_Lock, &bh->b_state);
  3982. +        }
  3983. +        if (rw == READ || rw == READA) {
  3984. +            if (buffer_uptodate(bh))
  3985. +                return 0;
  3986. +            set_bit (BH_Lock, &bh->b_state);
  3987. +        }
  3988. +        return (md_dev[minor].pers->make_request(md_dev+minor, rw, bh));
  3989. +    } else {
  3990. +        make_request (MAJOR(bh->b_rdev), rw, bh);
  3991. +        return 0;
  3992. +    }
  3993. +}
  3994.  
  3995.  static void do_md_request (void)
  3996.  {
  3997. @@ -427,6 +650,40 @@
  3998.    return;
  3999.  }  
  4000.  
  4001. +/*
  4002. + * We run MAX_MD_THREADS from md_init() and arbitrate them in run time.
  4003. + * This is not so elegant, but how can we use kernel_thread() from within
  4004. + * loadable modules?
  4005. + */
  4006. +struct md_thread *md_register_thread (void (*run) (void *), void *data)
  4007. +{
  4008. +    int i;
  4009. +    for (i = 0; i < MAX_MD_THREADS; i++) {
  4010. +        if (md_threads[i].run == NULL) {
  4011. +            md_threads[i].run = run;
  4012. +            md_threads[i].data = data;
  4013. +            return md_threads + i;
  4014. +        }
  4015. +    }
  4016. +    return NULL;
  4017. +}
  4018. +
  4019. +
  4020. +void md_unregister_thread (struct md_thread *thread)
  4021. +{
  4022. +    thread->run = NULL;
  4023. +    thread->data = NULL;
  4024. +    thread->flags = 0;
  4025. +}
  4026. +
  4027. +void md_wakeup_thread(struct md_thread *thread)
  4028. +{
  4029. +    set_bit(THREAD_WAKEUP, &thread->flags);
  4030. +    wake_up(&thread->wqueue);
  4031. +}
  4032. +
  4033. +struct buffer_head *efind_buffer(kdev_t dev, int block, int size);
  4034. +
  4035.  static struct symbol_table md_symbol_table=
  4036.  {
  4037.  #include <linux/symtab_begin.h>
  4038. @@ -435,11 +692,18 @@
  4039.    X(register_md_personality),
  4040.    X(unregister_md_personality),
  4041.    X(partition_name),
  4042. +  X(md_dev),
  4043. +  X(md_error),
  4044. +  X(md_register_thread),
  4045. +  X(md_unregister_thread),
  4046. +  X(md_update_sb),
  4047. +  X(md_map),
  4048. +  X(md_wakeup_thread),
  4049. +  X(efind_buffer),
  4050.  
  4051.  #include <linux/symtab_end.h>
  4052.  };
  4053.  
  4054. -
  4055.  static void md_geninit (struct gendisk *gdisk)
  4056.  {
  4057.    int i;
  4058. @@ -463,6 +727,17 @@
  4059.            });
  4060.  }
  4061.  
  4062. +int md_error (kdev_t mddev, kdev_t rdev)
  4063. +{
  4064. +    unsigned int minor = MINOR (mddev);
  4065. +    if (MAJOR(mddev) != MD_MAJOR || minor > MAX_MD_DEV)
  4066. +    panic ("md_error gets unknown device\n");
  4067. +    if (!md_dev [minor].pers)
  4068. +    panic ("md_error gets an error for an unknown device\n");
  4069. +    if (md_dev [minor].pers->error_handler)
  4070. +    return (md_dev [minor].pers->error_handler (md_dev+minor, rdev));
  4071. +    return 0;
  4072. +}
  4073.  
  4074.  int get_md_status (char *page)
  4075.  {
  4076. @@ -495,9 +770,13 @@
  4077.             partition_name(md_dev[i].devices[j].dev));
  4078.        size+=md_dev[i].devices[j].size;
  4079.      }
  4080. -    
  4081. -    if (md_dev[i].nb_dev)
  4082. -      sz+=sprintf (page+sz, " %d blocks", size);
  4083. +
  4084. +    if (md_dev[i].nb_dev) {
  4085. +      if (md_dev[i].pers)
  4086. +        sz+=sprintf (page+sz, " %d blocks", md_size[i]);
  4087. +      else
  4088. +        sz+=sprintf (page+sz, " %d blocks", size);
  4089. +    }
  4090.  
  4091.      if (!md_dev[i].pers)
  4092.      {
  4093. @@ -508,11 +787,8 @@
  4094.      if (md_dev[i].pers->max_invalid_dev)
  4095.        sz+=sprintf (page+sz, " maxfault=%ld", MAX_FAULT(md_dev+i));
  4096.  
  4097. -    sz+=sprintf (page+sz, " %dk %s\n", 1<<FACTOR_SHIFT(FACTOR(md_dev+i)),
  4098. -         md_dev[i].pers == pers[LINEAR>>PERSONALITY_SHIFT] ?
  4099. -         "rounding" : "chunks");
  4100. -
  4101.      sz+=md_dev[i].pers->status (page+sz, i, md_dev+i);
  4102. +    sz+=sprintf (page+sz, "\n");
  4103.    }
  4104.  
  4105.    return (sz);
  4106. @@ -545,6 +821,32 @@
  4107.    return 0;
  4108.  } 
  4109.  
  4110. +int md_thread(void * arg)
  4111. +{
  4112. +    struct md_thread *thread = arg;
  4113. +
  4114. +    current->session = 1;
  4115. +    current->pgrp = 1;
  4116. +    sprintf(current->comm, "md_thread");
  4117. +
  4118. +#ifdef __SMP__
  4119. +    lock_kernel();
  4120. +    syscall_count++;
  4121. +#endif
  4122. +    for (;;) {
  4123. +        sti();
  4124. +        clear_bit(THREAD_WAKEUP, &thread->flags);
  4125. +        if (thread->run) {
  4126. +            thread->run(thread->data);
  4127. +            run_task_queue(&tq_disk);
  4128. +        }
  4129. +        current->signal = 0;
  4130. +        cli();
  4131. +        if (!test_bit(THREAD_WAKEUP, &thread->flags))
  4132. +            interruptible_sleep_on(&thread->wqueue);
  4133. +    }
  4134. +}
  4135. +
  4136.  void linear_init (void);
  4137.  void raid0_init (void);
  4138.  void raid1_init (void);
  4139. @@ -552,7 +854,11 @@
  4140.  
  4141.  int md_init (void)
  4142.  {
  4143. -  printk ("md driver %s MAX_MD_DEV=%d, MAX_REAL=%d\n", MD_VERSION, MAX_MD_DEV, MAX_REAL);
  4144. +  int i;
  4145. +
  4146. +  printk ("md driver %d.%d.%d MAX_MD_DEV=%d, MAX_REAL=%d\n",
  4147. +    MD_MAJOR_VERSION, MD_MINOR_VERSION, MD_PATCHLEVEL_VERSION,
  4148. +    MAX_MD_DEV, MAX_REAL);
  4149.  
  4150.    if (register_blkdev (MD_MAJOR, "md", &md_fops))
  4151.    {
  4152. @@ -560,9 +866,17 @@
  4153.      return (-1);
  4154.    }
  4155.  
  4156. +  for (i = 0; i < MAX_MD_THREADS; i++) {
  4157. +    md_threads[i].run = NULL;
  4158. +    init_waitqueue(&md_threads[i].wqueue);
  4159. +    md_threads[i].flags = 0;
  4160. +    kernel_thread (md_thread, md_threads + i, 0);
  4161. +  }
  4162. +
  4163.    blk_dev[MD_MAJOR].request_fn=DEVICE_REQUEST;
  4164.    blk_dev[MD_MAJOR].current_request=NULL;
  4165.    read_ahead[MD_MAJOR]=INT_MAX;
  4166. +  memset(md_dev, 0, MAX_MD_DEV * sizeof (struct md_dev));
  4167.    md_gendisk.next=gendisk_head;
  4168.  
  4169.    gendisk_head=&md_gendisk;
  4170. @@ -572,6 +886,12 @@
  4171.  #endif
  4172.  #ifdef CONFIG_MD_STRIPED
  4173.    raid0_init ();
  4174. +#endif
  4175. +#ifdef CONFIG_MD_MIRRORING
  4176. +  raid1_init ();
  4177. +#endif
  4178. +#ifdef CONFIG_MD_RAID5
  4179. +  raid5_init ();
  4180.  #endif
  4181.    
  4182.    return (0);
  4183. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/Config.in linux/drivers/block/paride/Config.in
  4184. --- v2.0.34/linux/drivers/block/paride/Config.in    Wed Dec 31 16:00:00 1969
  4185. +++ linux/drivers/block/paride/Config.in    Mon Jul 13 13:47:28 1998
  4186. @@ -0,0 +1,24 @@
  4187. +#
  4188. +# PARIDE configuration
  4189. +#
  4190. +comment 'Parallel IDE high-level drivers'
  4191. +dep_tristate '  Parallel port IDE disks' CONFIG_PARIDE_PD $CONFIG_PARIDE
  4192. +dep_tristate '  Parallel port ATAPI CD-ROMs' CONFIG_PARIDE_PCD $CONFIG_PARIDE
  4193. +dep_tristate '  Parallel port ATAPI disks' CONFIG_PARIDE_PF $CONFIG_PARIDE
  4194. +dep_tristate '  Parallel port ATAPI tapes' CONFIG_PARIDE_PT $CONFIG_PARIDE
  4195. +dep_tristate '  Parallel port generic ATAPI devices' CONFIG_PARIDE_PG $CONFIG_PARIDE
  4196. +comment 'Parallel IDE protocol modules'
  4197. +dep_tristate '    ATEN EH-100 protocol' CONFIG_PARIDE_ATEN $CONFIG_PARIDE
  4198. +dep_tristate '    MicroSolutions backpack protocol' CONFIG_PARIDE_BPCK $CONFIG_PARIDE
  4199. +dep_tristate '    DataStor Commuter protocol' CONFIG_PARIDE_COMM $CONFIG_PARIDE
  4200. +dep_tristate '    DataStor EP-2000 protocol' CONFIG_PARIDE_DSTR $CONFIG_PARIDE
  4201. +dep_tristate '    FIT TD-2000 protocol' CONFIG_PARIDE_FIT2 $CONFIG_PARIDE
  4202. +dep_tristate '    FIT TD-3000 protocol' CONFIG_PARIDE_FIT3 $CONFIG_PARIDE
  4203. +dep_tristate '    Shuttle EPAT/EPEZ protocol' CONFIG_PARIDE_EPAT $CONFIG_PARIDE
  4204. +dep_tristate '    Shuttle EPIA protocol' CONFIG_PARIDE_EPIA $CONFIG_PARIDE
  4205. +dep_tristate '    FreeCom power protocol' CONFIG_PARIDE_FRPW $CONFIG_PARIDE
  4206. +dep_tristate '    KingByte KBIC-951A/971A protocols' CONFIG_PARIDE_KBIC $CONFIG_PARIDE
  4207. +dep_tristate '    KT PHd protocol' CONFIG_PARIDE_KTTI $CONFIG_PARIDE
  4208. +dep_tristate '    OnSpec 90c20 protocol' CONFIG_PARIDE_ON20 $CONFIG_PARIDE
  4209. +dep_tristate '    OnSpec 90c26 protocol' CONFIG_PARIDE_ON26 $CONFIG_PARIDE
  4210. +#
  4211. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/Makefile linux/drivers/block/paride/Makefile
  4212. --- v2.0.34/linux/drivers/block/paride/Makefile    Wed Dec 31 16:00:00 1969
  4213. +++ linux/drivers/block/paride/Makefile    Mon Jul 13 13:47:28 1998
  4214. @@ -0,0 +1,174 @@
  4215. +#
  4216. +# Makefile for PARIDE
  4217. +#
  4218. +# Note! Dependencies are done automagically by 'make dep', which also
  4219. +# removes any old dependencies. DON'T put your own dependencies here
  4220. +# unless it's something special (ie not a .c file).
  4221. +#
  4222. +# Note 2! The CFLAGS definitions are now inherited from the
  4223. +# parent makes..
  4224. +
  4225. +SUB_DIRS     := 
  4226. +MOD_SUB_DIRS := $(SUB_DIRS)
  4227. +ALL_SUB_DIRS := $(SUB_DIRS)
  4228. +
  4229. +L_TARGET := paride.a
  4230. +MX_OBJS  :=
  4231. +LX_OBJS  := 
  4232. +MI_OBJS  :=
  4233. +MIX_OBJS :=
  4234. +
  4235. +ifeq ($(CONFIG_PARIDE),y)
  4236. +  LX_OBJS += paride.o
  4237. +else
  4238. +  ifeq ($(CONFIG_PARIDE),m)
  4239. +    MX_OBJS += paride.o
  4240. +  endif
  4241. +endif
  4242. +
  4243. +ifeq ($(CONFIG_PARIDE_PD),y)
  4244. +  LX_OBJS += pd.o
  4245. +else
  4246. +  ifeq ($(CONFIG_PARIDE_PD),m)
  4247. +    MX_OBJS += pd.o
  4248. +  endif
  4249. +endif
  4250. +
  4251. +ifeq ($(CONFIG_PARIDE_PCD),y)
  4252. +  LX_OBJS += pcd.o
  4253. +else
  4254. +  ifeq ($(CONFIG_PARIDE_PCD),m)
  4255. +    MX_OBJS += pcd.o
  4256. +  endif
  4257. +endif
  4258. +
  4259. +ifeq ($(CONFIG_PARIDE_PF),y)
  4260. +  LX_OBJS += pf.o
  4261. +else
  4262. +  ifeq ($(CONFIG_PARIDE_PF),m)
  4263. +    MX_OBJS += pf.o
  4264. +  endif
  4265. +endif
  4266. +
  4267. +ifeq ($(CONFIG_PARIDE_PT),y)
  4268. +  LX_OBJS += pt.o
  4269. +else
  4270. +  ifeq ($(CONFIG_PARIDE_PT),m)
  4271. +    MX_OBJS += pt.o
  4272. +  endif
  4273. +endif
  4274. +
  4275. +ifeq ($(CONFIG_PARIDE_PG),y)
  4276. +  LX_OBJS += pg.o
  4277. +else
  4278. +  ifeq ($(CONFIG_PARIDE_PG),m)
  4279. +    MX_OBJS += pg.o
  4280. +  endif
  4281. +endif
  4282. +
  4283. +ifeq ($(CONFIG_PARIDE_ATEN),y)
  4284. +  LX_OBJS += aten.o
  4285. +else
  4286. +  ifeq ($(CONFIG_PARIDE_ATEN),m)
  4287. +    MX_OBJS += aten.o
  4288. +  endif
  4289. +endif
  4290. +
  4291. +ifeq ($(CONFIG_PARIDE_BPCK),y)
  4292. +  LX_OBJS += bpck.o
  4293. +else
  4294. +  ifeq ($(CONFIG_PARIDE_BPCK),m)
  4295. +    MX_OBJS += bpck.o
  4296. +  endif
  4297. +endif
  4298. +
  4299. +ifeq ($(CONFIG_PARIDE_COMM),y)
  4300. +  LX_OBJS += comm.o
  4301. +else
  4302. +  ifeq ($(CONFIG_PARIDE_COMM),m)
  4303. +    MX_OBJS += comm.o
  4304. +  endif
  4305. +endif
  4306. +
  4307. +ifeq ($(CONFIG_PARIDE_DSTR),y)
  4308. +  LX_OBJS += dstr.o
  4309. +else
  4310. +  ifeq ($(CONFIG_PARIDE_DSTR),m)
  4311. +    MX_OBJS += dstr.o
  4312. +  endif
  4313. +endif
  4314. +
  4315. +ifeq ($(CONFIG_PARIDE_KBIC),y)
  4316. +  LX_OBJS += kbic.o
  4317. +else
  4318. +  ifeq ($(CONFIG_PARIDE_KBIC),m)
  4319. +    MX_OBJS += kbic.o
  4320. +  endif
  4321. +endif
  4322. +
  4323. +ifeq ($(CONFIG_PARIDE_EPAT),y)
  4324. +  LX_OBJS += epat.o
  4325. +else
  4326. +  ifeq ($(CONFIG_PARIDE_EPAT),m)
  4327. +    MX_OBJS += epat.o
  4328. +  endif
  4329. +endif
  4330. +
  4331. +ifeq ($(CONFIG_PARIDE_EPIA),y)
  4332. +  LX_OBJS += epia.o
  4333. +else
  4334. +  ifeq ($(CONFIG_PARIDE_EPIA),m)
  4335. +    MX_OBJS += epia.o
  4336. +  endif
  4337. +endif
  4338. +
  4339. +ifeq ($(CONFIG_PARIDE_FIT2),y)
  4340. +  LX_OBJS += fit2.o
  4341. +else
  4342. +  ifeq ($(CONFIG_PARIDE_FIT2),m)
  4343. +    MX_OBJS += fit2.o
  4344. +  endif
  4345. +endif
  4346. +
  4347. +ifeq ($(CONFIG_PARIDE_FIT3),y)
  4348. +  LX_OBJS += fit3.o
  4349. +else
  4350. +  ifeq ($(CONFIG_PARIDE_FIT3),m)
  4351. +    MX_OBJS += fit3.o
  4352. +  endif
  4353. +endif
  4354. +
  4355. +ifeq ($(CONFIG_PARIDE_FRPW),y)
  4356. +  LX_OBJS += frpw.o
  4357. +else
  4358. +  ifeq ($(CONFIG_PARIDE_FRPW),m)
  4359. +    MX_OBJS += frpw.o
  4360. +  endif
  4361. +endif
  4362. +
  4363. +ifeq ($(CONFIG_PARIDE_ON20),y)
  4364. +  LX_OBJS += on20.o
  4365. +else
  4366. +  ifeq ($(CONFIG_PARIDE_ON20),m)
  4367. +    MX_OBJS += on20.o
  4368. +  endif
  4369. +endif
  4370. +
  4371. +ifeq ($(CONFIG_PARIDE_ON26),y)
  4372. +  LX_OBJS += on26.o
  4373. +else
  4374. +  ifeq ($(CONFIG_PARIDE_ON26),m)
  4375. +    MX_OBJS += on26.o
  4376. +  endif
  4377. +endif
  4378. +
  4379. +ifeq ($(CONFIG_PARIDE_KTTI),y)
  4380. +  LX_OBJS += ktti.o
  4381. +else
  4382. +  ifeq ($(CONFIG_PARIDE_KTTI),m)
  4383. +    MX_OBJS += ktti.o
  4384. +  endif
  4385. +endif
  4386. +
  4387. +include $(TOPDIR)/Rules.make
  4388. +
  4389. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/aten.c linux/drivers/block/paride/aten.c
  4390. --- v2.0.34/linux/drivers/block/paride/aten.c    Wed Dec 31 16:00:00 1969
  4391. +++ linux/drivers/block/paride/aten.c    Mon Jul 13 13:47:28 1998
  4392. @@ -0,0 +1,172 @@
  4393. +/* 
  4394. +        aten.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
  4395. +                            Under the terms of the GNU public license.
  4396. +
  4397. +    aten.c is a low-level protocol driver for the ATEN EH-100
  4398. +    parallel port adapter.  The EH-100 supports 4-bit and 8-bit
  4399. +        modes only.  There is also an EH-132 which supports EPP mode
  4400. +        transfers.  The EH-132 is not yet supported.
  4401. +
  4402. +*/
  4403. +
  4404. +/* Changes:
  4405. +
  4406. +    1.01    GRG 1998.05.05    init_proto, release_proto
  4407. +
  4408. +*/
  4409. +
  4410. +#define ATEN_VERSION      "1.01"
  4411. +
  4412. +#include <linux/module.h>
  4413. +#include <linux/delay.h>
  4414. +#include <linux/kernel.h>
  4415. +#include <linux/types.h>
  4416. +#include <asm/io.h>
  4417. +
  4418. +#include "paride.h"
  4419. +
  4420. +#define j44(a,b)                ((((a>>4)&0x0f)|(b&0xf0))^0x88)
  4421. +
  4422. +/* cont = 0 - access the IDE register file 
  4423. +   cont = 1 - access the IDE command set 
  4424. +*/
  4425. +
  4426. +static int  cont_map[2] = { 0x08, 0x20 };
  4427. +
  4428. +static void  aten_write_regr( PIA *pi, int cont, int regr, int val)
  4429. +
  4430. +{    int r;
  4431. +
  4432. +    r = regr + cont_map[cont] + 0x80;
  4433. +
  4434. +    w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc);
  4435. +}
  4436. +
  4437. +static int aten_read_regr( PIA *pi, int cont, int regr )
  4438. +
  4439. +{    int  a, b, r;
  4440. +
  4441. +        r = regr + cont_map[cont] + 0x40;
  4442. +
  4443. +    switch (pi->mode) {
  4444. +
  4445. +        case 0: w0(r); w2(0xe); w2(6); 
  4446. +        w2(7); w2(6); w2(0);
  4447. +        a = r1(); w0(0x10); b = r1(); w2(0xc);
  4448. +        return j44(a,b);
  4449. +
  4450. +        case 1: r |= 0x10;
  4451. +        w0(r); w2(0xe); w2(6); w0(0xff); 
  4452. +        w2(0x27); w2(0x26); w2(0x20);
  4453. +        a = r0();
  4454. +        w2(0x26); w2(0xc);
  4455. +        return a;
  4456. +    }
  4457. +    return -1;
  4458. +}
  4459. +
  4460. +static void aten_read_block( PIA *pi, char * buf, int count )
  4461. +
  4462. +{    int  k, a, b, c, d;
  4463. +
  4464. +    switch (pi->mode) {
  4465. +
  4466. +    case 0:    w0(0x48); w2(0xe); w2(6);
  4467. +        for (k=0;k<count/2;k++) {
  4468. +            w2(7); w2(6); w2(2);
  4469. +            a = r1(); w0(0x58); b = r1();
  4470. +            w2(0); d = r1(); w0(0x48); c = r1();
  4471. +            buf[2*k] = j44(c,d);
  4472. +            buf[2*k+1] = j44(a,b);
  4473. +        }
  4474. +        w2(0xc);
  4475. +        break;
  4476. +
  4477. +    case 1: w0(0x58); w2(0xe); w2(6);
  4478. +        for (k=0;k<count/2;k++) {
  4479. +            w2(0x27); w2(0x26); w2(0x22);
  4480. +            a = r0(); w2(0x20); b = r0();
  4481. +            buf[2*k] = b; buf[2*k+1] = a;
  4482. +        }
  4483. +        w2(0x26); w2(0xc);
  4484. +        break;
  4485. +    }
  4486. +}
  4487. +
  4488. +static void aten_write_block( PIA *pi, char * buf, int count )
  4489. +
  4490. +{    int k;
  4491. +
  4492. +    w0(0x88); w2(0xe); w2(6);
  4493. +    for (k=0;k<count/2;k++) {
  4494. +        w0(buf[2*k+1]); w2(0xe); w2(6);
  4495. +        w0(buf[2*k]); w2(7); w2(6);
  4496. +    }
  4497. +    w2(0xc);
  4498. +}
  4499. +
  4500. +static void aten_connect ( PIA *pi  )
  4501. +
  4502. +{       pi->saved_r0 = r0();
  4503. +        pi->saved_r2 = r2();
  4504. +    w2(0xc);    
  4505. +}
  4506. +
  4507. +static void aten_disconnect ( PIA *pi )
  4508. +
  4509. +{       w0(pi->saved_r0);
  4510. +        w2(pi->saved_r2);
  4511. +} 
  4512. +
  4513. +static void aten_log_adapter( PIA *pi, char * scratch, int verbose )
  4514. +
  4515. +{       char    *mode_string[2] = {"4-bit","8-bit"};
  4516. +
  4517. +        printk("%s: aten %s, ATEN EH-100 at 0x%x, ",
  4518. +                pi->device,ATEN_VERSION,pi->port);
  4519. +        printk("mode %d (%s), delay %d\n",pi->mode,
  4520. +        mode_string[pi->mode],pi->delay);
  4521. +
  4522. +}
  4523. +
  4524. +static void aten_init_proto( PIA *pi )
  4525. +
  4526. +{       MOD_INC_USE_COUNT;
  4527. +}
  4528. +
  4529. +static void aten_release_proto( PIA *pi )
  4530. +
  4531. +{       MOD_DEC_USE_COUNT;
  4532. +}
  4533. +
  4534. +struct pi_protocol aten = {"aten",0,2,2,1,1,
  4535. +                           aten_write_regr,
  4536. +                           aten_read_regr,
  4537. +                           aten_write_block,
  4538. +                           aten_read_block,
  4539. +                           aten_connect,
  4540. +                           aten_disconnect,
  4541. +                           0,
  4542. +                           0,
  4543. +                           0,
  4544. +                           aten_log_adapter,
  4545. +                           aten_init_proto,
  4546. +                           aten_release_proto
  4547. +                          };
  4548. +
  4549. +
  4550. +#ifdef MODULE
  4551. +
  4552. +int     init_module(void)
  4553. +
  4554. +{       return pi_register( &aten ) - 1;
  4555. +}
  4556. +
  4557. +void    cleanup_module(void)
  4558. +
  4559. +{       pi_unregister( &aten );
  4560. +}
  4561. +
  4562. +#endif
  4563. +
  4564. +/* end of aten.c */
  4565. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/bpck.c linux/drivers/block/paride/bpck.c
  4566. --- v2.0.34/linux/drivers/block/paride/bpck.c    Wed Dec 31 16:00:00 1969
  4567. +++ linux/drivers/block/paride/bpck.c    Mon Jul 13 13:47:28 1998
  4568. @@ -0,0 +1,482 @@
  4569. +/* 
  4570. +    bpck.c    (c) 1996-8  Grant R. Guenther <grant@torque.net>
  4571. +                    Under the terms of the GNU public license.
  4572. +
  4573. +    bpck.c is a low-level protocol driver for the MicroSolutions 
  4574. +    "backpack" parallel port IDE adapter.  
  4575. +
  4576. +*/
  4577. +
  4578. +/* Changes:
  4579. +
  4580. +    1.01    GRG 1998.05.05 init_proto, release_proto, pi->delay 
  4581. +
  4582. +*/
  4583. +
  4584. +#define    BPCK_VERSION    "1.01" 
  4585. +
  4586. +#include <linux/module.h>
  4587. +#include <linux/delay.h>
  4588. +#include <linux/kernel.h>
  4589. +#include <linux/types.h>
  4590. +#include <asm/io.h>
  4591. +
  4592. +#include "paride.h"
  4593. +
  4594. +#undef r2
  4595. +#undef w2
  4596. +
  4597. +#define PC            pi->private
  4598. +#define r2()            (PC=(in_p(2) & 0xff))
  4599. +#define w2(byte)          {out_p(2,byte); PC = byte;}
  4600. +#define t2(pat)           {PC ^= pat; out_p(2,PC);}
  4601. +#define e2()            {PC &= 0xfe; out_p(2,PC);}
  4602. +#define o2()            {PC |= 1; out_p(2,PC);}
  4603. +
  4604. +#define j44(l,h)     (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
  4605. +
  4606. +/* cont = 0 - access the IDE register file 
  4607. +   cont = 1 - access the IDE command set 
  4608. +   cont = 2 - use internal bpck register addressing
  4609. +*/
  4610. +
  4611. +static int  cont_map[3] = { 0x40, 0x48, 0 };
  4612. +
  4613. +static int bpck_read_regr( PIA *pi, int cont, int regr )
  4614. +
  4615. +{       int r, l, h;
  4616. +
  4617. +    r = regr + cont_map[cont];
  4618. +
  4619. +    switch (pi->mode) {
  4620. +
  4621. +    case 0: w0(r & 0xf); w0(r); t2(2); t2(4);
  4622. +            l = r1();
  4623. +            t2(4);
  4624. +            h = r1();
  4625. +            return j44(l,h);
  4626. +
  4627. +    case 1: w0(r & 0xf); w0(r); t2(2);
  4628. +            e2(); t2(0x20);
  4629. +        t2(4); h = r0();
  4630. +            t2(1); t2(0x20);
  4631. +            return h;
  4632. +
  4633. +    case 2:
  4634. +    case 3:
  4635. +    case 4: w0(r); w2(9); w2(0); w2(0x20);
  4636. +        h = r4();
  4637. +        w2(0);
  4638. +        return h;
  4639. +
  4640. +    }
  4641. +    return -1;
  4642. +}    
  4643. +
  4644. +static void bpck_write_regr( PIA *pi, int cont, int regr, int val )
  4645. +
  4646. +{    int    r;
  4647. +
  4648. +        r = regr + cont_map[cont];
  4649. +
  4650. +    switch (pi->mode) {
  4651. +
  4652. +    case 0:
  4653. +    case 1: w0(r);
  4654. +        t2(2);
  4655. +        w0(val);
  4656. +        o2(); t2(4); t2(1);
  4657. +        break;
  4658. +
  4659. +    case 2:
  4660. +    case 3:
  4661. +    case 4: w0(r); w2(9); w2(0);
  4662. +        w0(val); w2(1); w2(3); w2(0);
  4663. +        break;
  4664. +
  4665. +    }
  4666. +}
  4667. +
  4668. +/* These macros access the bpck registers in native addressing */
  4669. +
  4670. +#define WR(r,v)        bpck_write_regr(pi,2,r,v)
  4671. +#define RR(r)        (bpck_read_regr(pi,2,r))
  4672. +
  4673. +static void bpck_write_block( PIA *pi, char * buf, int count )
  4674. +
  4675. +{    int i;
  4676. +
  4677. +    switch (pi->mode) {
  4678. +
  4679. +    case 0: WR(4,0x40);
  4680. +        w0(0x40); t2(2); t2(1);
  4681. +        for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
  4682. +        WR(4,0);
  4683. +        break;
  4684. +
  4685. +    case 1: WR(4,0x50);
  4686. +                w0(0x40); t2(2); t2(1);
  4687. +                for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
  4688. +                WR(4,0x10);
  4689. +        break;
  4690. +
  4691. +    case 2: WR(4,0x48);
  4692. +        w0(0x40); w2(9); w2(0); w2(1);
  4693. +        for (i=0;i<count;i++) w4(buf[i]);
  4694. +        w2(0);
  4695. +        WR(4,8);
  4696. +        break;
  4697. +
  4698. +        case 3: WR(4,0x48);
  4699. +                w0(0x40); w2(9); w2(0); w2(1);
  4700. +                for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]);
  4701. +                w2(0);
  4702. +                WR(4,8);
  4703. +                break;
  4704. +        case 4: WR(4,0x48);
  4705. +                w0(0x40); w2(9); w2(0); w2(1);
  4706. +                for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]);
  4707. +                w2(0);
  4708. +                WR(4,8);
  4709. +                break;
  4710. +     }
  4711. +}
  4712. +
  4713. +static void bpck_read_block( PIA *pi, char * buf, int count )
  4714. +
  4715. +{    int i, l, h;
  4716. +
  4717. +    switch (pi->mode) {
  4718. +
  4719. +          case 0: WR(4,0x40);
  4720. +        w0(0x40); t2(2);
  4721. +        for (i=0;i<count;i++) {
  4722. +            t2(4); l = r1();
  4723. +            t2(4); h = r1();
  4724. +            buf[i] = j44(l,h);
  4725. +        }
  4726. +        WR(4,0);
  4727. +        break;
  4728. +
  4729. +    case 1: WR(4,0x50);
  4730. +        w0(0x40); t2(2); t2(0x20);
  4731. +                  for(i=0;i<count;i++) { t2(4); buf[i] = r0(); }
  4732. +            t2(1); t2(0x20);
  4733. +            WR(4,0x10);
  4734. +        break;
  4735. +
  4736. +    case 2: WR(4,0x48);
  4737. +        w0(0x40); w2(9); w2(0); w2(0x20);
  4738. +        for (i=0;i<count;i++) buf[i] = r4();
  4739. +        w2(0);
  4740. +        WR(4,8);
  4741. +        break;
  4742. +
  4743. +        case 3: WR(4,0x48);
  4744. +                w0(0x40); w2(9); w2(0); w2(0x20);
  4745. +                for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
  4746. +                w2(0);
  4747. +                WR(4,8);
  4748. +                break;
  4749. +
  4750. +        case 4: WR(4,0x48);
  4751. +                w0(0x40); w2(9); w2(0); w2(0x20);
  4752. +                for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
  4753. +                w2(0);
  4754. +                WR(4,8);
  4755. +                break;
  4756. +
  4757. +    }
  4758. +}
  4759. +
  4760. +static int bpck_probe_unit ( PIA *pi )
  4761. +
  4762. +{    int o1, o0, f7, id;
  4763. +    int t, s;
  4764. +
  4765. +    id = pi->unit;
  4766. +    s = 0;
  4767. +    w2(4); w2(0xe); r2(); t2(2); 
  4768. +    o1 = r1()&0xf8;
  4769. +    o0 = r0();
  4770. +    w0(255-id); w2(4); w0(id);
  4771. +    t2(8); t2(8); t2(8);
  4772. +    t2(2); t = r1()&0xf8;
  4773. +    f7 = ((id % 8) == 7);
  4774. +    if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; }
  4775. +    if ((t == o1) && ((!f7) || (s == o1)))  {
  4776. +        w2(0x4c); w0(o0);
  4777. +        return 0;    
  4778. +    }
  4779. +    t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
  4780. +    return 1;
  4781. +}
  4782. +    
  4783. +static void bpck_connect ( PIA *pi  )
  4784. +
  4785. +{       pi->saved_r0 = r0();
  4786. +    w0(0xff-pi->unit); w2(4); w0(pi->unit);
  4787. +    t2(8); t2(8); t2(8); 
  4788. +    t2(2); t2(2);
  4789. +    
  4790. +    switch (pi->mode) {
  4791. +
  4792. +    case 0: t2(8); WR(4,0);
  4793. +        break;
  4794. +
  4795. +    case 1: t2(8); WR(4,0x10);
  4796. +        break;
  4797. +
  4798. +    case 2:
  4799. +        case 3:
  4800. +    case 4: w2(0); WR(4,8);
  4801. +        break;
  4802. +
  4803. +    }
  4804. +
  4805. +    WR(5,8);
  4806. +
  4807. +    if (pi->devtype == PI_PCD) {
  4808. +        WR(0x46,0x10);        /* fiddle with ESS logic ??? */
  4809. +        WR(0x4c,0x38);
  4810. +        WR(0x4d,0x88);
  4811. +        WR(0x46,0xa0);
  4812. +        WR(0x41,0);
  4813. +        WR(0x4e,8);
  4814. +        }
  4815. +}
  4816. +
  4817. +static void bpck_disconnect ( PIA *pi )
  4818. +
  4819. +{    w0(0); 
  4820. +    if (pi->mode >= 2) { w2(9); w2(0); } else t2(2);
  4821. +    w2(0x4c); w0(pi->saved_r0);
  4822. +} 
  4823. +
  4824. +static void bpck_force_spp ( PIA *pi )
  4825. +
  4826. +/* This fakes the EPP protocol to turn off EPP ... */
  4827. +
  4828. +{       pi->saved_r0 = r0();
  4829. +        w0(0xff-pi->unit); w2(4); w0(pi->unit);
  4830. +        t2(8); t2(8); t2(8); 
  4831. +        t2(2); t2(2);
  4832. +
  4833. +        w2(0); 
  4834. +        w0(4); w2(9); w2(0); 
  4835. +        w0(0); w2(1); w2(3); w2(0);     
  4836. +        w0(0); w2(9); w2(0);
  4837. +        w2(0x4c); w0(pi->saved_r0);
  4838. +}
  4839. +
  4840. +#define TEST_LEN  16
  4841. +
  4842. +static int bpck_test_proto( PIA *pi, char * scratch, int verbose )
  4843. +
  4844. +{    int i, e, l, h, om;
  4845. +    char buf[TEST_LEN];
  4846. +
  4847. +    bpck_force_spp(pi);
  4848. +
  4849. +    switch (pi->mode) {
  4850. +
  4851. +    case 0: bpck_connect(pi);
  4852. +        WR(0x13,0x7f);
  4853. +        w0(0x13); t2(2);
  4854. +        for(i=0;i<TEST_LEN;i++) {
  4855. +                    t2(4); l = r1();
  4856. +                    t2(4); h = r1();
  4857. +                    buf[i] = j44(l,h);
  4858. +        }
  4859. +        bpck_disconnect(pi);
  4860. +        break;
  4861. +
  4862. +        case 1: bpck_connect(pi);
  4863. +        WR(0x13,0x7f);
  4864. +                w0(0x13); t2(2); t2(0x20);
  4865. +                for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); }
  4866. +                t2(1); t2(0x20);
  4867. +        bpck_disconnect(pi);
  4868. +        break;
  4869. +
  4870. +    case 2:
  4871. +    case 3:
  4872. +    case 4: om = pi->mode;
  4873. +        pi->mode = 0;
  4874. +        bpck_connect(pi);
  4875. +        WR(7,3);
  4876. +        WR(4,8);
  4877. +        bpck_disconnect(pi);
  4878. +
  4879. +        pi->mode = om;
  4880. +        bpck_connect(pi);
  4881. +        w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
  4882. +
  4883. +        switch (pi->mode) {
  4884. +          case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4();
  4885. +              break;
  4886. +          case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w();
  4887. +                          break;
  4888. +          case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l();
  4889. +                          break;
  4890. +        }
  4891. +
  4892. +        w2(0);
  4893. +        WR(7,0);
  4894. +        bpck_disconnect(pi);
  4895. +
  4896. +        break;
  4897. +
  4898. +    }
  4899. +
  4900. +    if (verbose) {
  4901. +        printk("%s: bpck: 0x%x unit %d mode %d: ",
  4902. +           pi->device,pi->port,pi->unit,pi->mode);
  4903. +        for (i=0;i<TEST_LEN;i++) printk("%3d",buf[i]);
  4904. +        printk("\n");
  4905. +    }
  4906. +
  4907. +    e = 0;
  4908. +    for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++;
  4909. +    return e;
  4910. +}
  4911. +
  4912. +static void bpck_read_eeprom ( PIA *pi, char * buf )
  4913. +
  4914. +{       int i,j,k,n,p,v,f, om, od;
  4915. +
  4916. +    bpck_force_spp(pi);
  4917. +
  4918. +    om = pi->mode;  od = pi->delay;
  4919. +    pi->mode = 0; pi->delay = 6;
  4920. +
  4921. +    bpck_connect(pi);
  4922. +    
  4923. +    n = 0;
  4924. +    WR(4,0);
  4925. +    for (i=0;i<64;i++) {
  4926. +        WR(6,8);  
  4927. +        WR(6,0xc);
  4928. +        p = 0x100;
  4929. +        for (k=0;k<9;k++) {
  4930. +        f = (((i + 0x180) & p) != 0) * 2;
  4931. +        WR(6,f+0xc); 
  4932. +        WR(6,f+0xd); 
  4933. +        WR(6,f+0xc);
  4934. +        p = (p >> 1);
  4935. +        }
  4936. +        for (j=0;j<2;j++) {
  4937. +        v = 0;
  4938. +        for (k=0;k<8;k++) {
  4939. +            WR(6,0xc); 
  4940. +            WR(6,0xd); 
  4941. +            WR(6,0xc); 
  4942. +            f = RR(0);
  4943. +            v = 2*v + (f == 0x84);
  4944. +        }
  4945. +        buf[2*i+1-j] = v;
  4946. +        }
  4947. +    }
  4948. +    WR(6,8);
  4949. +    WR(6,0);
  4950. +    WR(5,8);
  4951. +
  4952. +    bpck_disconnect(pi);
  4953. +
  4954. +        if (om >= 2) {
  4955. +                bpck_connect(pi);
  4956. +                WR(7,3);
  4957. +                WR(4,8);
  4958. +                bpck_disconnect(pi);
  4959. +        }
  4960. +
  4961. +    pi->mode = om; pi->delay = od;
  4962. +}
  4963. +
  4964. +static int bpck_test_port ( PIA *pi )     /* check for 8-bit port */
  4965. +
  4966. +{    int    i, r, m;
  4967. +
  4968. +    w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
  4969. +    m = -1;
  4970. +    if (r == i) m = 2;
  4971. +    if (r == (255-i)) m = 0;
  4972. +
  4973. +    w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
  4974. +    if (r != (255-i)) m = -1;
  4975. +    
  4976. +    if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); }
  4977. +    if (m == 2) { w2(0x26); w2(0xc); }
  4978. +
  4979. +    if (m == -1) return 0;
  4980. +    return 5;
  4981. +}
  4982. +
  4983. +static void bpck_log_adapter( PIA *pi, char * scratch, int verbose )
  4984. +
  4985. +{    char    *mode_string[5] = { "4-bit","8-bit","EPP-8",
  4986. +                    "EPP-16","EPP-32" };
  4987. +
  4988. +#ifdef DUMP_EEPROM
  4989. +    int i;
  4990. +#endif
  4991. +
  4992. +    bpck_read_eeprom(pi,scratch);
  4993. +
  4994. +#ifdef DUMP_EEPROM
  4995. +    if (verbose) {
  4996. +       for(i=0;i<128;i++)
  4997. +        if ((scratch[i] < ' ') || (scratch[i] > '~'))
  4998. +            scratch[i] = '.';
  4999. +       printk("%s: bpck EEPROM: %64.64s\n",pi->device,scratch);
  5000. +       printk("%s:              %64.64s\n",pi->device,&scratch[64]);
  5001. +    }
  5002. +#endif
  5003. +
  5004. +    printk("%s: bpck %s, backpack %8.8s unit %d",
  5005. +        pi->device,BPCK_VERSION,&scratch[110],pi->unit);
  5006. +    printk(" at 0x%x, mode %d (%s), delay %d\n",pi->port,
  5007. +        pi->mode,mode_string[pi->mode],pi->delay);
  5008. +}
  5009. +
  5010. +static void bpck_init_proto( PIA *pi)
  5011. +
  5012. +{    MOD_INC_USE_COUNT;
  5013. +}
  5014. +
  5015. +static void bpck_release_proto( PIA *pi)
  5016. +
  5017. +{       MOD_DEC_USE_COUNT;
  5018. +}
  5019. +
  5020. +struct pi_protocol bpck = { "bpck",0,5,2,1,256,
  5021. +              bpck_write_regr,
  5022. +              bpck_read_regr,
  5023. +              bpck_write_block,
  5024. +              bpck_read_block,
  5025. +              bpck_connect,
  5026. +              bpck_disconnect,
  5027. +              bpck_test_port,
  5028. +              bpck_probe_unit,
  5029. +                  bpck_test_proto,
  5030. +              bpck_log_adapter,
  5031. +              bpck_init_proto,
  5032. +              bpck_release_proto
  5033. +            };
  5034. +
  5035. +#ifdef MODULE
  5036. +
  5037. +int    init_module(void)
  5038. +
  5039. +{    return pi_register(&bpck) - 1;
  5040. +}
  5041. +
  5042. +void    cleanup_module(void)
  5043. +
  5044. +{    pi_unregister(&bpck);
  5045. +}
  5046. +
  5047. +#endif
  5048. +
  5049. +/* end of bpck.c */
  5050. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/comm.c linux/drivers/block/paride/comm.c
  5051. --- v2.0.34/linux/drivers/block/paride/comm.c    Wed Dec 31 16:00:00 1969
  5052. +++ linux/drivers/block/paride/comm.c    Mon Jul 13 13:47:28 1998
  5053. @@ -0,0 +1,228 @@
  5054. +/* 
  5055. +        comm.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  5056. +                              Under the terms of the GNU public license.
  5057. +
  5058. +    comm.c is a low-level protocol driver for some older models
  5059. +    of the DataStor "Commuter" parallel to IDE adapter.  Some of
  5060. +    the parallel port devices marketed by Arista currently
  5061. +    use this adapter.
  5062. +*/
  5063. +
  5064. +/* Changes:
  5065. +
  5066. +    1.01    GRG 1998.05.05  init_proto, release_proto
  5067. +
  5068. +*/
  5069. +
  5070. +#define COMM_VERSION      "1.01"
  5071. +
  5072. +#include <linux/module.h>
  5073. +#include <linux/delay.h>
  5074. +#include <linux/kernel.h>
  5075. +#include <linux/types.h>
  5076. +#include <asm/io.h>
  5077. +
  5078. +#include "paride.h"
  5079. +
  5080. +/* mode codes:  0  nybble reads, 8-bit writes
  5081. +                1  8-bit reads and writes
  5082. +                2  8-bit EPP mode
  5083. +*/
  5084. +
  5085. +#define j44(a,b)    (((a>>3)&0x0f)|((b<<1)&0xf0))
  5086. +
  5087. +#define P1    w2(5);w2(0xd);w2(0xd);w2(5);w2(4);
  5088. +#define P2    w2(5);w2(7);w2(7);w2(5);w2(4);
  5089. +
  5090. +/* cont = 0 - access the IDE register file 
  5091. +   cont = 1 - access the IDE command set 
  5092. +*/
  5093. +
  5094. +static int  cont_map[2] = { 0x08, 0x10 };
  5095. +
  5096. +static int comm_read_regr( PIA *pi, int cont, int regr )
  5097. +
  5098. +{       int     l, h, r;
  5099. +
  5100. +        r = regr + cont_map[cont];
  5101. +
  5102. +        switch (pi->mode)  {
  5103. +
  5104. +        case 0: w0(r); P1; w0(0);
  5105. +            w2(6); l = r1(); w0(0x80); h = r1(); w2(4);
  5106. +                return j44(l,h);
  5107. +
  5108. +        case 1: w0(r+0x20); P1; 
  5109. +            w0(0); w2(0x26); h = r0(); w2(4);
  5110. +                return h;
  5111. +
  5112. +    case 2:
  5113. +    case 3:
  5114. +        case 4: w3(r+0x20); r1(); 
  5115. +            w2(0x24); h = r4(); w2(4);
  5116. +                return h;
  5117. +
  5118. +        }
  5119. +        return -1;
  5120. +}       
  5121. +
  5122. +static void comm_write_regr( PIA *pi, int cont, int regr, int val )
  5123. +
  5124. +{       int  r;
  5125. +
  5126. +        r = regr + cont_map[cont];
  5127. +
  5128. +        switch (pi->mode)  {
  5129. +
  5130. +        case 0:
  5131. +        case 1: w0(r); P1; w0(val); P2;
  5132. +        break;
  5133. +
  5134. +    case 2:
  5135. +    case 3:
  5136. +        case 4: w3(r); r1(); w4(val); 
  5137. +                break;
  5138. +        }
  5139. +}
  5140. +
  5141. +static void comm_connect ( PIA *pi  )
  5142. +
  5143. +{       pi->saved_r0 = r0();
  5144. +        pi->saved_r2 = r2();
  5145. +        w2(4); w0(0xff); w2(6);
  5146. +        w2(4); w0(0xaa); w2(6);
  5147. +        w2(4); w0(0x00); w2(6);
  5148. +        w2(4); w0(0x87); w2(6);
  5149. +        w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
  5150. +}
  5151. +
  5152. +static void comm_disconnect ( PIA *pi )
  5153. +
  5154. +{       w2(0); w2(0); w2(0); w2(4); 
  5155. +    w0(pi->saved_r0);
  5156. +        w2(pi->saved_r2);
  5157. +} 
  5158. +
  5159. +static void comm_read_block( PIA *pi, char * buf, int count )
  5160. +
  5161. +{       int     i, l, h;
  5162. +
  5163. +        switch (pi->mode) {
  5164. +        
  5165. +        case 0: w0(0x48); P1;
  5166. +                for(i=0;i<count;i++) {
  5167. +                        w0(0); w2(6); l = r1();
  5168. +                        w0(0x80); h = r1(); w2(4);
  5169. +                        buf[i] = j44(l,h);
  5170. +                }
  5171. +                break;
  5172. +
  5173. +        case 1: w0(0x68); P1; w0(0);
  5174. +                for(i=0;i<count;i++) {
  5175. +                        w2(0x26); buf[i] = r0(); w2(0x24);
  5176. +                }
  5177. +        w2(4);
  5178. +        break;
  5179. +        
  5180. +    case 2: w3(0x68); r1(); w2(0x24);
  5181. +        for (i=0;i<count;i++) buf[i] = r4();
  5182. +        w2(4);
  5183. +        break;
  5184. +
  5185. +        case 3: w3(0x68); r1(); w2(0x24);
  5186. +                for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
  5187. +                w2(4);
  5188. +                break;
  5189. +
  5190. +        case 4: w3(0x68); r1(); w2(0x24);
  5191. +                for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
  5192. +                w2(4);
  5193. +                break;
  5194. +        
  5195. +    }
  5196. +}
  5197. +
  5198. +/* NB: Watch out for the byte swapped writes ! */
  5199. +
  5200. +static void comm_write_block( PIA *pi, char * buf, int count )
  5201. +
  5202. +{       int    k;
  5203. +
  5204. +        switch (pi->mode) {
  5205. +
  5206. +        case 0:
  5207. +        case 1: w0(0x68); P1;
  5208. +            for (k=0;k<count;k++) {
  5209. +                        w2(5); w0(buf[k^1]); w2(7);
  5210. +                }
  5211. +                w2(5); w2(4);
  5212. +                break;
  5213. +
  5214. +        case 2: w3(0x48); r1();
  5215. +                for (k=0;k<count;k++) w4(buf[k^1]);
  5216. +                break;
  5217. +
  5218. +        case 3: w3(0x48); r1();
  5219. +                for (k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
  5220. +                break;
  5221. +
  5222. +        case 4: w3(0x48); r1();
  5223. +                for (k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
  5224. +                break;
  5225. +
  5226. +
  5227. +        }
  5228. +}
  5229. +
  5230. +static void comm_log_adapter( PIA *pi, char * scratch, int verbose )
  5231. +
  5232. +{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
  5233. +
  5234. +        printk("%s: comm %s, DataStor Commuter at 0x%x, ",
  5235. +                pi->device,COMM_VERSION,pi->port);
  5236. +        printk("mode %d (%s), delay %d\n",pi->mode,
  5237. +        mode_string[pi->mode],pi->delay);
  5238. +
  5239. +}
  5240. +
  5241. +static void comm_init_proto(PIA *pi)
  5242. +
  5243. +{       MOD_INC_USE_COUNT;
  5244. +}
  5245. +
  5246. +static void comm_release_proto(PIA *pi)
  5247. +
  5248. +{       MOD_DEC_USE_COUNT;
  5249. +}
  5250. +
  5251. +struct pi_protocol comm = {"comm",0,5,2,1,1,
  5252. +                           comm_write_regr,
  5253. +                           comm_read_regr,
  5254. +                           comm_write_block,
  5255. +                           comm_read_block,
  5256. +                           comm_connect,
  5257. +                           comm_disconnect,
  5258. +                           0,
  5259. +                           0,
  5260. +                           0,
  5261. +                           comm_log_adapter,
  5262. +                           comm_init_proto,
  5263. +                           comm_release_proto
  5264. +                          };
  5265. +
  5266. +
  5267. +#ifdef MODULE
  5268. +
  5269. +int     init_module(void)
  5270. +
  5271. +{       return pi_register( &comm ) - 1;
  5272. +}
  5273. +
  5274. +void    cleanup_module(void)
  5275. +
  5276. +{       pi_unregister( &comm );
  5277. +}
  5278. +
  5279. +#endif
  5280. +
  5281. +/* end of comm.c */
  5282. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/dstr.c linux/drivers/block/paride/dstr.c
  5283. --- v2.0.34/linux/drivers/block/paride/dstr.c    Wed Dec 31 16:00:00 1969
  5284. +++ linux/drivers/block/paride/dstr.c    Mon Jul 13 13:47:28 1998
  5285. @@ -0,0 +1,243 @@
  5286. +/* 
  5287. +        dstr.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  5288. +                              Under the terms of the GNU public license.
  5289. +
  5290. +        dstr.c is a low-level protocol driver for the 
  5291. +        DataStor EP2000 parallel to IDE adapter chip.
  5292. +
  5293. +*/
  5294. +
  5295. +/* Changes:
  5296. +
  5297. +        1.01    GRG 1998.05.06 init_proto, release_proto
  5298. +
  5299. +*/
  5300. +
  5301. +#define DSTR_VERSION      "1.01"
  5302. +
  5303. +#include <linux/module.h>
  5304. +#include <linux/delay.h>
  5305. +#include <linux/kernel.h>
  5306. +#include <linux/types.h>
  5307. +#include <asm/io.h>
  5308. +
  5309. +#include "paride.h"
  5310. +
  5311. +/* mode codes:  0  nybble reads, 8-bit writes
  5312. +                1  8-bit reads and writes
  5313. +                2  8-bit EPP mode
  5314. +        3  EPP-16
  5315. +        4  EPP-32
  5316. +*/
  5317. +
  5318. +#define j44(a,b)  (((a>>3)&0x07)|((~a>>4)&0x08)|((b<<1)&0x70)|((~b)&0x80))
  5319. +
  5320. +#define P1    w2(5);w2(0xd);w2(5);w2(4);
  5321. +#define P2    w2(5);w2(7);w2(5);w2(4);
  5322. +#define P3      w2(6);w2(4);w2(6);w2(4);
  5323. +
  5324. +/* cont = 0 - access the IDE register file 
  5325. +   cont = 1 - access the IDE command set 
  5326. +*/
  5327. +
  5328. +static int  cont_map[2] = { 0x20, 0x40 };
  5329. +
  5330. +static int dstr_read_regr( PIA *pi, int cont, int regr )
  5331. +
  5332. +{       int     a, b, r;
  5333. +
  5334. +        r = regr + cont_map[cont];
  5335. +
  5336. +    w0(0x81); P1;
  5337. +    if (pi->mode) { w0(0x11); } else { w0(1); }
  5338. +    P2; w0(r); P1;
  5339. +
  5340. +        switch (pi->mode)  {
  5341. +
  5342. +        case 0: w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4);
  5343. +                return j44(a,b);
  5344. +
  5345. +        case 1: w0(0); w2(0x26); a = r0(); w2(4);
  5346. +                return a;
  5347. +
  5348. +    case 2:
  5349. +    case 3:
  5350. +        case 4: w2(0x24); a = r4(); w2(4);
  5351. +                return a;
  5352. +
  5353. +        }
  5354. +        return -1;
  5355. +}       
  5356. +
  5357. +static void dstr_write_regr(  PIA *pi, int cont, int regr, int val )
  5358. +
  5359. +{       int  r;
  5360. +
  5361. +        r = regr + cont_map[cont];
  5362. +
  5363. +    w0(0x81); P1; 
  5364. +    if (pi->mode >= 2) { w0(0x11); } else { w0(1); }
  5365. +    P2; w0(r); P1;
  5366. +    
  5367. +        switch (pi->mode)  {
  5368. +
  5369. +        case 0:
  5370. +        case 1: w0(val); w2(5); w2(7); w2(5); w2(4);
  5371. +        break;
  5372. +
  5373. +    case 2:
  5374. +    case 3:
  5375. +        case 4: w4(val); 
  5376. +                break;
  5377. +        }
  5378. +}
  5379. +
  5380. +#define  CCP(x)  w0(0xff);w2(0xc);w2(4);\
  5381. +         w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);w0(0x78);\
  5382. +         w0(x);w2(5);w2(4);
  5383. +
  5384. +static void dstr_connect ( PIA *pi  )
  5385. +
  5386. +{       pi->saved_r0 = r0();
  5387. +        pi->saved_r2 = r2();
  5388. +        w2(4); CCP(0xe0); w0(0xff);
  5389. +}
  5390. +
  5391. +static void dstr_disconnect ( PIA *pi )
  5392. +
  5393. +{       CCP(0x30);
  5394. +        w0(pi->saved_r0);
  5395. +        w2(pi->saved_r2);
  5396. +} 
  5397. +
  5398. +static void dstr_read_block( PIA *pi, char * buf, int count )
  5399. +
  5400. +{       int     k, a, b;
  5401. +
  5402. +        w0(0x81); P1;
  5403. +        if (pi->mode) { w0(0x19); } else { w0(9); }
  5404. +    P2; w0(0x82); P1; P3; w0(0x20); P1;
  5405. +
  5406. +        switch (pi->mode) {
  5407. +
  5408. +        case 0: for (k=0;k<count;k++) {
  5409. +                        w2(6); a = r1(); w2(4);
  5410. +                        w2(6); b = r1(); w2(4);
  5411. +                        buf[k] = j44(a,b);
  5412. +                } 
  5413. +                break;
  5414. +
  5415. +        case 1: w0(0);
  5416. +                for (k=0;k<count;k++) {
  5417. +                        w2(0x26); buf[k] = r0(); w2(0x24);
  5418. +                }
  5419. +                w2(4);
  5420. +                break;
  5421. +
  5422. +        case 2: w2(0x24); 
  5423. +                for (k=0;k<count;k++) buf[k] = r4();
  5424. +                w2(4);
  5425. +                break;
  5426. +
  5427. +        case 3: w2(0x24); 
  5428. +                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
  5429. +                w2(4);
  5430. +                break;
  5431. +
  5432. +        case 4: w2(0x24); 
  5433. +                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
  5434. +                w2(4);
  5435. +                break;
  5436. +
  5437. +        }
  5438. +}
  5439. +
  5440. +static void dstr_write_block( PIA *pi, char * buf, int count )
  5441. +
  5442. +{       int    k;
  5443. +
  5444. +        w0(0x81); P1;
  5445. +        if (pi->mode) { w0(0x19); } else { w0(9); }
  5446. +        P2; w0(0x82); P1; P3; w0(0x20); P1;
  5447. +
  5448. +        switch (pi->mode) {
  5449. +
  5450. +        case 0:
  5451. +        case 1: for (k=0;k<count;k++) {
  5452. +                        w2(5); w0(buf[k]); w2(7);
  5453. +                }
  5454. +                w2(5); w2(4);
  5455. +                break;
  5456. +
  5457. +        case 2: w2(0xc5);
  5458. +                for (k=0;k<count;k++) w4(buf[k]);
  5459. +        w2(0xc4);
  5460. +                break;
  5461. +
  5462. +        case 3: w2(0xc5);
  5463. +                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
  5464. +                w2(0xc4);
  5465. +                break;
  5466. +
  5467. +        case 4: w2(0xc5);
  5468. +                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
  5469. +                w2(0xc4);
  5470. +                break;
  5471. +
  5472. +        }
  5473. +}
  5474. +
  5475. +
  5476. +static void dstr_log_adapter( PIA *pi, char * scratch, int verbose )
  5477. +
  5478. +{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8",
  5479. +                   "EPP-16","EPP-32"};
  5480. +
  5481. +        printk("%s: dstr %s, DataStor EP2000 at 0x%x, ",
  5482. +                pi->device,DSTR_VERSION,pi->port);
  5483. +        printk("mode %d (%s), delay %d\n",pi->mode,
  5484. +        mode_string[pi->mode],pi->delay);
  5485. +
  5486. +}
  5487. +
  5488. +static void dstr_init_proto( PIA *pi)
  5489. +
  5490. +{       MOD_INC_USE_COUNT;
  5491. +}
  5492. +
  5493. +static void dstr_release_proto( PIA *pi)
  5494. +
  5495. +{       MOD_DEC_USE_COUNT;
  5496. +}
  5497. +
  5498. +struct pi_protocol dstr = {"dstr",0,5,2,1,1,
  5499. +                           dstr_write_regr,
  5500. +                           dstr_read_regr,
  5501. +                           dstr_write_block,
  5502. +                           dstr_read_block,
  5503. +                           dstr_connect,
  5504. +                           dstr_disconnect,
  5505. +                           0,
  5506. +                           0,
  5507. +                           0,
  5508. +                           dstr_log_adapter,
  5509. +                           dstr_init_proto,
  5510. +                           dstr_release_proto
  5511. +                          };
  5512. +
  5513. +
  5514. +#ifdef MODULE
  5515. +
  5516. +int     init_module(void)
  5517. +
  5518. +{       return pi_register( &dstr ) - 1;
  5519. +}
  5520. +
  5521. +void    cleanup_module(void)
  5522. +
  5523. +{       pi_unregister( &dstr );
  5524. +}
  5525. +
  5526. +#endif
  5527. +
  5528. +/* end of dstr.c */
  5529. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/epat.c linux/drivers/block/paride/epat.c
  5530. --- v2.0.34/linux/drivers/block/paride/epat.c    Wed Dec 31 16:00:00 1969
  5531. +++ linux/drivers/block/paride/epat.c    Mon Jul 13 13:47:28 1998
  5532. @@ -0,0 +1,321 @@
  5533. +/* 
  5534. +        epat.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
  5535. +                            Under the terms of the GNU public license.
  5536. +
  5537. +    This is the low level protocol driver for the EPAT parallel
  5538. +        to IDE adapter from Shuttle Technologies.  This adapter is
  5539. +        used in many popular parallel port disk products such as the
  5540. +        SyQuest EZ drives, the Avatar Shark and the Imation SuperDisk.
  5541. +    
  5542. +*/
  5543. +
  5544. +/* Changes:
  5545. +
  5546. +        1.01    GRG 1998.05.06 init_proto, release_proto
  5547. +
  5548. +*/
  5549. +
  5550. +#define EPAT_VERSION      "1.01"
  5551. +
  5552. +#include <linux/module.h>
  5553. +#include <linux/delay.h>
  5554. +#include <linux/kernel.h>
  5555. +#include <linux/types.h>
  5556. +#include <asm/io.h>
  5557. +
  5558. +#include "paride.h"
  5559. +
  5560. +#define j44(a,b)        (((a>>4)&0x0f)+(b&0xf0))
  5561. +#define j53(a,b)        (((a>>3)&0x1f)+((b<<4)&0xe0))
  5562. +
  5563. +/* cont =  0   IDE register file
  5564. +   cont =  1   IDE control registers
  5565. +   cont =  2   internal EPAT registers
  5566. +*/
  5567. +
  5568. +static int cont_map[3] = { 0x18, 0x10, 0 };
  5569. +
  5570. +static void epat_write_regr( PIA *pi, int cont, int regr, int val)
  5571. +
  5572. +{    int r;
  5573. +
  5574. +    r = regr + cont_map[cont];
  5575. +
  5576. +    switch (pi->mode) {
  5577. +
  5578. +    case 0:
  5579. +    case 1:
  5580. +    case 2:    w0(0x60+r); w2(1); w0(val); w2(4);
  5581. +        break;
  5582. +
  5583. +    case 3:
  5584. +    case 4:
  5585. +    case 5: w3(0x40+r); w4(val);
  5586. +        break;
  5587. +
  5588. +    }
  5589. +}
  5590. +
  5591. +static int epat_read_regr( PIA *pi, int cont, int regr )
  5592. +
  5593. +{    int  a, b, r;
  5594. +
  5595. +    r = regr + cont_map[cont];
  5596. +
  5597. +    switch (pi->mode) {
  5598. +
  5599. +    case 0:    w0(r); w2(1); w2(3); 
  5600. +        a = r1(); w2(4); b = r1();
  5601. +        return j44(a,b);
  5602. +
  5603. +    case 1: w0(0x40+r); w2(1); w2(4);
  5604. +        a = r1(); b = r2(); w0(0xff);
  5605. +        return j53(a,b);
  5606. +
  5607. +    case 2: w0(0x20+r); w2(1); w2(0x25);
  5608. +        a = r0(); w2(4);
  5609. +        return a;
  5610. +
  5611. +    case 3:
  5612. +    case 4:
  5613. +    case 5: w3(r); w2(0x24); a = r4(); w2(4);
  5614. +        return a;
  5615. +
  5616. +    }
  5617. +    return -1;    /* never gets here */
  5618. +}
  5619. +
  5620. +static void epat_read_block( PIA *pi, char * buf, int count )
  5621. +
  5622. +{    int  k, ph, a, b;
  5623. +
  5624. +    switch (pi->mode) {
  5625. +
  5626. +    case 0:    w0(7); w2(1); w2(3); w0(0xff);
  5627. +        ph = 0;
  5628. +        for(k=0;k<count;k++) {
  5629. +            if (k == count-1) w0(0xfd);
  5630. +            w2(6+ph); a = r1();
  5631. +            if (a & 8) b = a; 
  5632. +              else { w2(4+ph); b = r1(); }
  5633. +            buf[k] = j44(a,b);
  5634. +            ph =  1 - ph;
  5635. +        }
  5636. +        w0(0); w2(4);
  5637. +        break;
  5638. +
  5639. +    case 1: w0(0x47); w2(1); w2(5); w0(0xff);
  5640. +        ph = 0;
  5641. +        for(k=0;k<count;k++) {
  5642. +            if (k == count-1) w0(0xfd); 
  5643. +            w2(4+ph);
  5644. +            a = r1(); b = r2();
  5645. +            buf[k] = j53(a,b);
  5646. +            ph = 1 - ph;
  5647. +        }
  5648. +        w0(0); w2(4);
  5649. +        break;
  5650. +
  5651. +    case 2: w0(0x27); w2(1); w2(0x25); w0(0);
  5652. +        ph = 0;
  5653. +        for(k=0;k<count-1;k++) {
  5654. +            w2(0x24+ph);
  5655. +            buf[k] = r0();
  5656. +            ph = 1 - ph;
  5657. +        }
  5658. +        w2(0x26); w2(0x27); buf[count-1] = r0(); 
  5659. +        w2(0x25); w2(4);
  5660. +        break;
  5661. +
  5662. +    case 3: w3(0x80); w2(0x24);
  5663. +        for(k=0;k<count-1;k++) buf[k] = r4();
  5664. +        w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
  5665. +        w2(4);
  5666. +        break;
  5667. +
  5668. +    case 4: w3(0x80); w2(0x24);
  5669. +        for(k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
  5670. +        buf[count-2] = r4();
  5671. +        w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
  5672. +        w2(4);
  5673. +        break;
  5674. +
  5675. +    case 5: w3(0x80); w2(0x24);
  5676. +        for(k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
  5677. +        for(k=count-4;k<count-1;k++) buf[k] = r4();
  5678. +        w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
  5679. +        w2(4);
  5680. +        break;
  5681. +
  5682. +    }
  5683. +}
  5684. +
  5685. +static void epat_write_block( PIA *pi, char * buf, int count )   
  5686. +
  5687. +{    int ph, k;
  5688. +
  5689. +    switch (pi->mode) {
  5690. +
  5691. +    case 0:
  5692. +    case 1:
  5693. +    case 2: w0(0x67); w2(1); w2(5);
  5694. +        ph = 0;
  5695. +        for(k=0;k<count;k++) {
  5696. +              w0(buf[k]);
  5697. +            w2(4+ph);
  5698. +            ph = 1 - ph;
  5699. +        }
  5700. +        w2(7); w2(4);
  5701. +        break;
  5702. +
  5703. +    case 3: w3(0xc0); 
  5704. +        for(k=0;k<count;k++) w4(buf[k]);
  5705. +        w2(4);
  5706. +        break;
  5707. +
  5708. +    case 4: w3(0xc0); 
  5709. +        for(k=0;k<(count/2);k++) w4w(((u16 *)buf)[k]);
  5710. +        w2(4);
  5711. +        break;
  5712. +
  5713. +    case 5: w3(0xc0); 
  5714. +        for(k=0;k<(count/4);k++) w4l(((u32 *)buf)[k]);
  5715. +        w2(4);
  5716. +        break;
  5717. +
  5718. +    }
  5719. +}
  5720. +
  5721. +/* these macros access the EPAT registers in native addressing */
  5722. +
  5723. +#define    WR(r,v)        epat_write_regr(pi,2,r,v)
  5724. +#define    RR(r)        (epat_read_regr(pi,2,r))
  5725. +
  5726. +/* and these access the IDE task file */
  5727. +
  5728. +#define WRi(r,v)         epat_write_regr(pi,0,r,v)
  5729. +#define RRi(r)           (epat_read_regr(pi,0,r))
  5730. +
  5731. +/* FIXME:  the CCP stuff should be fixed to handle multiple EPATs on a chain */
  5732. +
  5733. +#define CCP(x)     w2(4);w0(0x22);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
  5734. +                w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
  5735. +
  5736. +static void epat_connect ( PIA *pi )
  5737. +
  5738. +{       pi->saved_r0 = r0();
  5739. +        pi->saved_r2 = r2();
  5740. +    CCP(0); CCP(0xe0);
  5741. +    w0(0); w2(1); w2(4);
  5742. +    if (pi->mode >= 3) {
  5743. +        w0(0); w2(1); w2(4); w2(0xc);
  5744. +        w0(0x40); w2(6); w2(7); w2(4); w2(0xc); w2(4);
  5745. +    }
  5746. +    WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
  5747. +}
  5748. +
  5749. +static void epat_disconnect ( PIA *pi )
  5750. +
  5751. +{       CCP(0x30);
  5752. +        w0(pi->saved_r0);
  5753. +        w2(pi->saved_r2);
  5754. +} 
  5755. +
  5756. +static int epat_test_proto( PIA *pi, char * scratch, int verbose )
  5757. +
  5758. +{       int     k, j, f, cc;
  5759. +    int    e[2] = {0,0};
  5760. +
  5761. +        epat_connect(pi);
  5762. +    cc = RR(0xd);
  5763. +    epat_disconnect(pi);
  5764. +
  5765. +    epat_connect(pi);
  5766. +    for (j=0;j<2;j++) {
  5767. +          WRi(6,0xa0+j*0x10);
  5768. +            for (k=0;k<256;k++) {
  5769. +                WRi(2,k^0xaa);
  5770. +                WRi(3,k^0x55);
  5771. +                if (RRi(2) != (k^0xaa)) e[j]++;
  5772. +                }
  5773. +        }
  5774. +        epat_disconnect(pi);
  5775. +
  5776. +        f = 0;
  5777. +        epat_connect(pi);
  5778. +        WR(0x13,1); WR(0x13,0); WR(0xa,0x11);
  5779. +        epat_read_block(pi,scratch,512);
  5780. +    
  5781. +        for (k=0;k<256;k++) {
  5782. +            if ((scratch[2*k] & 0xff) != k) f++;
  5783. +            if ((scratch[2*k+1] & 0xff) != (0xff-k)) f++;
  5784. +        }
  5785. +        epat_disconnect(pi);
  5786. +
  5787. +        if (verbose)  {
  5788. +            printk("%s: epat: port 0x%x, mode %d, ccr %x, test=(%d,%d,%d)\n",
  5789. +           pi->device,pi->port,pi->mode,cc,e[0],e[1],f);
  5790. +    }
  5791. +    
  5792. +        return (e[0] && e[1]) || f;
  5793. +}
  5794. +
  5795. +static void epat_log_adapter( PIA *pi, char * scratch, int verbose )
  5796. +
  5797. +{    int    ver;
  5798. +        char    *mode_string[6] = 
  5799. +           {"4-bit","5/3","8-bit","EPP-8","EPP-16","EPP-32"};
  5800. +
  5801. +    epat_connect(pi);
  5802. +    WR(0xa,0x38);        /* read the version code */
  5803. +        ver = RR(0xb);
  5804. +        epat_disconnect(pi);
  5805. +
  5806. +    printk("%s: epat %s, Shuttle EPAT chip %x at 0x%x, ",
  5807. +        pi->device,EPAT_VERSION,ver,pi->port);
  5808. +    printk("mode %d (%s), delay %d\n",pi->mode,
  5809. +        mode_string[pi->mode],pi->delay);
  5810. +
  5811. +}
  5812. +
  5813. +static void epat_init_proto( PIA *pi)
  5814. +
  5815. +{      MOD_INC_USE_COUNT;
  5816. +}
  5817. +
  5818. +static void epat_release_proto( PIA *pi)
  5819. +
  5820. +{    MOD_DEC_USE_COUNT;
  5821. +}
  5822. +
  5823. +struct pi_protocol epat = {"epat",0,6,3,1,1,
  5824. +               epat_write_regr,
  5825. +               epat_read_regr,
  5826. +               epat_write_block,
  5827. +               epat_read_block,
  5828. +               epat_connect,
  5829. +               epat_disconnect,
  5830. +               0,
  5831. +               0,
  5832. +               epat_test_proto,
  5833. +               epat_log_adapter,
  5834. +               epat_init_proto,
  5835. +               epat_release_proto
  5836. +              };
  5837. +
  5838. +
  5839. +#ifdef MODULE
  5840. +
  5841. +int    init_module(void)
  5842. +
  5843. +{    return pi_register( &epat) - 1;
  5844. +}
  5845. +
  5846. +void    cleanup_module(void)
  5847. +
  5848. +{    pi_unregister( &epat);
  5849. +}
  5850. +
  5851. +#endif
  5852. +
  5853. +/* end of epat.c */
  5854. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/epia.c linux/drivers/block/paride/epia.c
  5855. --- v2.0.34/linux/drivers/block/paride/epia.c    Wed Dec 31 16:00:00 1969
  5856. +++ linux/drivers/block/paride/epia.c    Mon Jul 13 13:47:28 1998
  5857. @@ -0,0 +1,326 @@
  5858. +/* 
  5859. +        epia.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  5860. +                              Under the terms of the GNU public license.
  5861. +
  5862. +        epia.c is a low-level protocol driver for Shuttle Technologies 
  5863. +    EPIA parallel to IDE adapter chip.  This device is now obsolete
  5864. +    and has been replaced with the EPAT chip, which is supported
  5865. +    by epat.c, however, some devices based on EPIA are still
  5866. +    available.
  5867. +
  5868. +*/
  5869. +
  5870. +/* Changes:
  5871. +
  5872. +        1.01    GRG 1998.05.06 init_proto, release_proto
  5873. +    1.02    GRG 1998.06.17 support older versions of EPIA
  5874. +
  5875. +*/
  5876. +
  5877. +#define EPIA_VERSION      "1.02"
  5878. +
  5879. +#include <linux/module.h>
  5880. +#include <linux/delay.h>
  5881. +#include <linux/kernel.h>
  5882. +#include <linux/types.h>
  5883. +#include <asm/io.h>
  5884. +
  5885. +#include "paride.h"
  5886. +
  5887. +/* mode codes:  0  nybble reads on port 1, 8-bit writes
  5888. +                1  5/3 reads on ports 1 & 2, 8-bit writes
  5889. +                2  8-bit reads and writes
  5890. +                3  8-bit EPP mode
  5891. +        4  16-bit EPP
  5892. +        5  32-bit EPP
  5893. +*/
  5894. +
  5895. +#define j44(a,b)                (((a>>4)&0x0f)+(b&0xf0))
  5896. +#define j53(a,b)                (((a>>3)&0x1f)+((b<<4)&0xe0))
  5897. +
  5898. +/* cont =  0   IDE register file
  5899. +   cont =  1   IDE control registers
  5900. +*/
  5901. +
  5902. +static int cont_map[2] = { 0, 0x80 };
  5903. +
  5904. +static int epia_read_regr( PIA *pi, int cont, int regr )
  5905. +
  5906. +{       int     a, b, r;
  5907. +
  5908. +    regr += cont_map[cont];
  5909. +
  5910. +        switch (pi->mode)  {
  5911. +
  5912. +        case 0: r = regr^0x39;
  5913. +                w0(r); w2(1); w2(3); w0(r);
  5914. +                a = r1(); w2(1); b = r1(); w2(4);
  5915. +                return j44(a,b);
  5916. +
  5917. +        case 1: r = regr^0x31;
  5918. +                w0(r); w2(1); w0(r&0x37); 
  5919. +                w2(3); w2(5); w0(r|0xf0);
  5920. +                a = r1(); b = r2(); w2(4);
  5921. +                return j53(a,b);
  5922. +
  5923. +        case 2: r = regr^0x29;
  5924. +                w0(r); w2(1); w2(0X21); w2(0x23); 
  5925. +                a = r0(); w2(4);
  5926. +                return a;
  5927. +
  5928. +    case 3:
  5929. +    case 4:
  5930. +        case 5: w3(regr); w2(0x24); a = r4(); w2(4);
  5931. +                return a;
  5932. +
  5933. +        }
  5934. +        return -1;
  5935. +}       
  5936. +
  5937. +static void epia_write_regr( PIA *pi, int cont, int regr, int val)
  5938. +
  5939. +{       int  r;
  5940. +
  5941. +    regr += cont_map[cont];
  5942. +
  5943. +        switch (pi->mode)  {
  5944. +
  5945. +        case 0:
  5946. +        case 1:
  5947. +        case 2: r = regr^0x19;
  5948. +                w0(r); w2(1); w0(val); w2(3); w2(4);
  5949. +                break;
  5950. +
  5951. +    case 3:
  5952. +    case 4:
  5953. +        case 5: r = regr^0x40;
  5954. +                w3(r); w4(val); w2(4);
  5955. +                break;
  5956. +        }
  5957. +}
  5958. +
  5959. +#define WR(r,v)         epia_write_regr(pi,0,r,v)
  5960. +#define RR(r)           (epia_read_regr(pi,0,r))
  5961. +
  5962. +/* The use of register 0x84 is entirely unclear - it seems to control
  5963. +   some EPP counters ...  currently we know about 3 different block
  5964. +   sizes:  the standard 512 byte reads and writes, 12 byte writes and 
  5965. +   2048 byte reads (the last two being used in the CDrom drivers.
  5966. +*/
  5967. +
  5968. +static void epia_connect ( PIA *pi  )
  5969. +
  5970. +{       pi->saved_r0 = r0();
  5971. +        pi->saved_r2 = r2();
  5972. +
  5973. +        w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
  5974. +        w2(1); w2(4);
  5975. +        if (pi->mode >= 3) { 
  5976. +                w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
  5977. +                w2(0x24); w2(0x26); w2(4);
  5978. +        }
  5979. +        WR(0x86,8);  
  5980. +}
  5981. +
  5982. +static void epia_disconnect ( PIA *pi )
  5983. +
  5984. +{       /* WR(0x84,0x10); */
  5985. +        w0(pi->saved_r0);
  5986. +        w2(1); w2(4);
  5987. +        w0(pi->saved_r0);
  5988. +        w2(pi->saved_r2);
  5989. +} 
  5990. +
  5991. +static void epia_read_block( PIA *pi, char * buf, int count )
  5992. +
  5993. +{       int     k, ph, a, b;
  5994. +
  5995. +        switch (pi->mode) {
  5996. +
  5997. +        case 0: w0(0x81); w2(1); w2(3); w0(0xc1);
  5998. +                ph = 1;
  5999. +                for (k=0;k<count;k++) {
  6000. +                        w2(2+ph); a = r1();
  6001. +                        w2(4+ph); b = r1();
  6002. +                        buf[k] = j44(a,b);
  6003. +                        ph = 1 - ph;
  6004. +                } 
  6005. +                w0(0); w2(4);
  6006. +                break;
  6007. +
  6008. +        case 1: w0(0x91); w2(1); w0(0x10); w2(3); 
  6009. +                w0(0x51); w2(5); w0(0xd1); 
  6010. +                ph = 1;
  6011. +                for (k=0;k<count;k++) {
  6012. +                        w2(4+ph);
  6013. +                        a = r1(); b = r2();
  6014. +                        buf[k] = j53(a,b);
  6015. +                        ph = 1 - ph;
  6016. +                }
  6017. +                w0(0); w2(4);
  6018. +                break;
  6019. +
  6020. +        case 2: w0(0x89); w2(1); w2(0x23); w2(0x21); 
  6021. +                ph = 1;
  6022. +                for (k=0;k<count;k++) {
  6023. +                        w2(0x24+ph);
  6024. +                        buf[k] = r0();
  6025. +                        ph = 1 - ph;
  6026. +                }
  6027. +                w2(6); w2(4);
  6028. +                break;
  6029. +
  6030. +        case 3: if (count > 512) WR(0x84,3);
  6031. +        w3(0); w2(0x24);
  6032. +                for (k=0;k<count;k++) buf[k] = r4();
  6033. +                w2(4); WR(0x84,0);
  6034. +                break;
  6035. +
  6036. +        case 4: if (count > 512) WR(0x84,3);
  6037. +        w3(0); w2(0x24);
  6038. +        for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
  6039. +                w2(4); WR(0x84,0);
  6040. +                break;
  6041. +
  6042. +        case 5: if (count > 512) WR(0x84,3);
  6043. +        w3(0); w2(0x24);
  6044. +                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
  6045. +                w2(4); WR(0x84,0);
  6046. +                break;
  6047. +
  6048. +        }
  6049. +}
  6050. +
  6051. +static void epia_write_block( PIA *pi, char * buf, int count )
  6052. +
  6053. +{       int     ph, k, last, d;
  6054. +
  6055. +        switch (pi->mode) {
  6056. +
  6057. +        case 0:
  6058. +        case 1:
  6059. +        case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
  6060. +                ph = 0;  last = 0x8000;
  6061. +                for (k=0;k<count;k++) {
  6062. +                        d = buf[k];
  6063. +                        if (d != last) { last = d; w0(d); }
  6064. +                        w2(4+ph);
  6065. +                        ph = 1 - ph;
  6066. +                }
  6067. +                w2(7); w2(4);
  6068. +                break;
  6069. +
  6070. +        case 3: if (count < 512) WR(0x84,1);
  6071. +        w3(0x40);
  6072. +                for (k=0;k<count;k++) w4(buf[k]);
  6073. +        if (count < 512) WR(0x84,0);
  6074. +                break;
  6075. +
  6076. +        case 4: if (count < 512) WR(0x84,1);
  6077. +        w3(0x40);
  6078. +                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
  6079. +        if (count < 512) WR(0x84,0);
  6080. +                break;
  6081. +
  6082. +        case 5: if (count < 512) WR(0x84,1);
  6083. +        w3(0x40);
  6084. +                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
  6085. +        if (count < 512) WR(0x84,0);
  6086. +                break;
  6087. +
  6088. +        }
  6089. +
  6090. +}
  6091. +
  6092. +static int epia_test_proto( PIA *pi, char * scratch, int verbose )
  6093. +
  6094. +{       int     j, k, f;
  6095. +    int    e[2] = {0,0};
  6096. +
  6097. +        epia_connect(pi);
  6098. +        for (j=0;j<2;j++) {
  6099. +            WR(6,0xa0+j*0x10);
  6100. +            for (k=0;k<256;k++) {
  6101. +                WR(2,k^0xaa);
  6102. +                WR(3,k^0x55);
  6103. +                if (RR(2) != (k^0xaa)) e[j]++;
  6104. +            }
  6105. +        WR(2,1); WR(3,1);
  6106. +        }
  6107. +        epia_disconnect(pi);
  6108. +
  6109. +        f = 0;
  6110. +        epia_connect(pi);
  6111. +        WR(0x84,8);
  6112. +        epia_read_block(pi,scratch,512);
  6113. +        for (k=0;k<256;k++) {
  6114. +            if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
  6115. +            if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
  6116. +        }
  6117. +        WR(0x84,0);
  6118. +        epia_disconnect(pi);
  6119. +
  6120. +        if (verbose)  {
  6121. +            printk("%s: epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
  6122. +                   pi->device,pi->port,pi->mode,e[0],e[1],f);
  6123. +        }
  6124. +        
  6125. +        return (e[0] && e[1]) || f;
  6126. +
  6127. +}
  6128. +
  6129. +
  6130. +static void epia_log_adapter( PIA *pi, char * scratch, int verbose )
  6131. +
  6132. +{       char    *mode_string[6] = {"4-bit","5/3","8-bit",
  6133. +                   "EPP-8","EPP-16","EPP-32"};
  6134. +
  6135. +        printk("%s: epia %s, Shuttle EPIA at 0x%x, ",
  6136. +                pi->device,EPIA_VERSION,pi->port);
  6137. +        printk("mode %d (%s), delay %d\n",pi->mode,
  6138. +        mode_string[pi->mode],pi->delay);
  6139. +
  6140. +}
  6141. +
  6142. +static void epia_init_proto( PIA *pi)
  6143. +
  6144. +{       MOD_INC_USE_COUNT;
  6145. +}
  6146. +
  6147. +static void epia_release_proto( PIA *pi)
  6148. +
  6149. +{       MOD_DEC_USE_COUNT;
  6150. +}
  6151. +
  6152. +struct pi_protocol epia = {"epia",0,6,3,1,1,
  6153. +                           epia_write_regr,
  6154. +                           epia_read_regr,
  6155. +                           epia_write_block,
  6156. +                           epia_read_block,
  6157. +                           epia_connect,
  6158. +                           epia_disconnect,
  6159. +                           0,
  6160. +                           0,
  6161. +                           epia_test_proto,
  6162. +                           epia_log_adapter,
  6163. +                           epia_init_proto,
  6164. +                           epia_release_proto
  6165. +                          };
  6166. +
  6167. +
  6168. +#ifdef MODULE
  6169. +
  6170. +int     init_module(void)
  6171. +
  6172. +{       return pi_register( &epia ) - 1;
  6173. +}
  6174. +
  6175. +void    cleanup_module(void)
  6176. +
  6177. +{       pi_unregister( &epia );
  6178. +}
  6179. +
  6180. +#endif
  6181. +
  6182. +/* end of epia.c */
  6183. +
  6184. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/fit2.c linux/drivers/block/paride/fit2.c
  6185. --- v2.0.34/linux/drivers/block/paride/fit2.c    Wed Dec 31 16:00:00 1969
  6186. +++ linux/drivers/block/paride/fit2.c    Mon Jul 13 13:47:28 1998
  6187. @@ -0,0 +1,161 @@
  6188. +/* 
  6189. +        fit2.c        (c) 1998  Grant R. Guenther <grant@torque.net>
  6190. +                          Under the terms of the GNU public license.
  6191. +
  6192. +    fit2.c is a low-level protocol driver for the older version
  6193. +        of the Fidelity International Technology parallel port adapter.  
  6194. +    This adapter is used in their TransDisk 2000 and older TransDisk
  6195. +    3000 portable hard-drives.  As far as I can tell, this device
  6196. +    supports 4-bit mode _only_.  
  6197. +
  6198. +    Newer models of the FIT products use an enhanced protocol.
  6199. +    The "fit3" protocol module should support current drives.
  6200. +
  6201. +*/
  6202. +
  6203. +#define FIT2_VERSION      "1.0"
  6204. +
  6205. +#include <linux/module.h>
  6206. +#include <linux/delay.h>
  6207. +#include <linux/kernel.h>
  6208. +#include <linux/types.h>
  6209. +#include <asm/io.h>
  6210. +
  6211. +#include "paride.h"
  6212. +
  6213. +#define j44(a,b)                (((a>>4)&0x0f)|(b&0xf0))
  6214. +
  6215. +/* cont = 0 - access the IDE register file 
  6216. +   cont = 1 - access the IDE command set 
  6217. +
  6218. +NB:  The FIT adapter does not appear to use the control registers.
  6219. +So, we map ALT_STATUS to STATUS and NO-OP writes to the device
  6220. +control register - this means that IDE reset will not work on these
  6221. +devices.
  6222. +
  6223. +*/
  6224. +
  6225. +static void  fit2_write_regr( PIA *pi, int cont, int regr, int val)
  6226. +
  6227. +{    if (cont == 1) return;
  6228. +    w2(0xc); w0(regr); w2(4); w0(val); w2(5); w0(0); w2(4);
  6229. +}
  6230. +
  6231. +static int fit2_read_regr( PIA *pi, int cont, int regr )
  6232. +
  6233. +{    int  a, b, r;
  6234. +
  6235. +    if (cont) {
  6236. +      if (regr != 6) return 0xff;
  6237. +      r = 7;
  6238. +    } else r = regr + 0x10;
  6239. +
  6240. +    w2(0xc); w0(r); w2(4); w2(5); 
  6241. +             w0(0); a = r1();
  6242. +             w0(1); b = r1();
  6243. +    w2(4);
  6244. +
  6245. +    return j44(a,b);
  6246. +
  6247. +}
  6248. +
  6249. +static void fit2_read_block( PIA *pi, char * buf, int count )
  6250. +
  6251. +{    int  k, a, b, c, d;
  6252. +
  6253. +    w2(0xc); w0(0x10);
  6254. +
  6255. +    for (k=0;k<count/4;k++) {
  6256. +
  6257. +        w2(4); w2(5);
  6258. +        w0(0); a = r1(); w0(1); b = r1();
  6259. +        w0(3); c = r1(); w0(2); d = r1(); 
  6260. +        buf[4*k+0] = j44(a,b);
  6261. +        buf[4*k+1] = j44(d,c);
  6262. +
  6263. +                w2(4); w2(5);
  6264. +                       a = r1(); w0(3); b = r1();
  6265. +                w0(1); c = r1(); w0(0); d = r1(); 
  6266. +                buf[4*k+2] = j44(d,c);
  6267. +                buf[4*k+3] = j44(a,b);
  6268. +
  6269. +    }
  6270. +
  6271. +    w2(4);
  6272. +
  6273. +}
  6274. +
  6275. +static void fit2_write_block( PIA *pi, char * buf, int count )
  6276. +
  6277. +{    int k;
  6278. +
  6279. +
  6280. +    w2(0xc); w0(0); 
  6281. +    for (k=0;k<count/2;k++) {
  6282. +        w2(4); w0(buf[2*k]); 
  6283. +        w2(5); w0(buf[2*k+1]);
  6284. +    }
  6285. +    w2(4);
  6286. +}
  6287. +
  6288. +static void fit2_connect ( PIA *pi  )
  6289. +
  6290. +{       pi->saved_r0 = r0();
  6291. +        pi->saved_r2 = r2();
  6292. +    w2(0xcc); 
  6293. +}
  6294. +
  6295. +static void fit2_disconnect ( PIA *pi )
  6296. +
  6297. +{       w0(pi->saved_r0);
  6298. +        w2(pi->saved_r2);
  6299. +} 
  6300. +
  6301. +static void fit2_log_adapter( PIA *pi, char * scratch, int verbose )
  6302. +
  6303. +{       printk("%s: fit2 %s, FIT 2000 adapter at 0x%x, delay %d\n",
  6304. +                pi->device,FIT2_VERSION,pi->port,pi->delay);
  6305. +
  6306. +}
  6307. +
  6308. +static void fit2_init_proto( PIA *pi)
  6309. +
  6310. +{       MOD_INC_USE_COUNT;
  6311. +}
  6312. +
  6313. +static void fit2_release_proto( PIA *pi)
  6314. +
  6315. +{       MOD_DEC_USE_COUNT;
  6316. +}
  6317. +
  6318. +struct pi_protocol fit2 = {"fit2",0,1,2,1,1,
  6319. +                           fit2_write_regr,
  6320. +                           fit2_read_regr,
  6321. +                           fit2_write_block,
  6322. +                           fit2_read_block,
  6323. +                           fit2_connect,
  6324. +                           fit2_disconnect,
  6325. +                           0,
  6326. +                           0,
  6327. +                           0,
  6328. +                           fit2_log_adapter,
  6329. +                           fit2_init_proto,
  6330. +                           fit2_release_proto
  6331. +                          };
  6332. +
  6333. +
  6334. +#ifdef MODULE
  6335. +
  6336. +int     init_module(void)
  6337. +
  6338. +{       return pi_register( &fit2 ) - 1;
  6339. +}
  6340. +
  6341. +void    cleanup_module(void)
  6342. +
  6343. +{       pi_unregister( &fit2 );
  6344. +}
  6345. +
  6346. +#endif
  6347. +
  6348. +/* end of fit2.c */
  6349. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/fit3.c linux/drivers/block/paride/fit3.c
  6350. --- v2.0.34/linux/drivers/block/paride/fit3.c    Wed Dec 31 16:00:00 1969
  6351. +++ linux/drivers/block/paride/fit3.c    Mon Jul 13 13:47:28 1998
  6352. @@ -0,0 +1,221 @@
  6353. +/* 
  6354. +        fit3.c        (c) 1998  Grant R. Guenther <grant@torque.net>
  6355. +                          Under the terms of the GNU public license.
  6356. +
  6357. +    fit3.c is a low-level protocol driver for newer models 
  6358. +        of the Fidelity International Technology parallel port adapter.  
  6359. +    This adapter is used in their TransDisk 3000 portable 
  6360. +    hard-drives, as well as CD-ROM, PD-CD and other devices.
  6361. +
  6362. +    The TD-2000 and certain older devices use a different protocol.
  6363. +    Try the fit2 protocol module with them.
  6364. +
  6365. +        NB:  The FIT adapters do not appear to support the control 
  6366. +    registers.  So, we map ALT_STATUS to STATUS and NO-OP writes 
  6367. +    to the device control register - this means that IDE reset 
  6368. +    will not work on these devices.
  6369. +
  6370. +*/
  6371. +
  6372. +#define FIT3_VERSION      "1.0"
  6373. +
  6374. +#include <linux/module.h>
  6375. +#include <linux/delay.h>
  6376. +#include <linux/kernel.h>
  6377. +#include <linux/types.h>
  6378. +#include <asm/io.h>
  6379. +
  6380. +#include "paride.h"
  6381. +
  6382. +#define j44(a,b)                (((a>>3)&0x0f)|((b<<1)&0xf0))
  6383. +
  6384. +#define w7(byte)                {out_p(7,byte);}
  6385. +#define r7()                    (in_p(7) & 0xff)
  6386. +
  6387. +/* cont = 0 - access the IDE register file 
  6388. +   cont = 1 - access the IDE command set 
  6389. +
  6390. +*/
  6391. +
  6392. +static void  fit3_write_regr( PIA *pi, int cont, int regr, int val)
  6393. +
  6394. +{    if (cont == 1) return;
  6395. +
  6396. +    switch (pi->mode) {
  6397. +
  6398. +    case 0:
  6399. +    case 1: w2(0xc); w0(regr); w2(0x8); w2(0xc); 
  6400. +        w0(val); w2(0xd); 
  6401. +        w0(0);   w2(0xc);
  6402. +        break;
  6403. +
  6404. +    case 2: w2(0xc); w0(regr); w2(0x8); w2(0xc);
  6405. +        w4(val); w4(0);
  6406. +        w2(0xc);
  6407. +        break;
  6408. +
  6409. +    }
  6410. +}
  6411. +
  6412. +static int fit3_read_regr( PIA *pi, int cont, int regr )
  6413. +
  6414. +{    int  a, b;
  6415. +
  6416. +    if (cont) {
  6417. +      if (regr != 6) return 0xff;
  6418. +      regr = 7;
  6419. +    } 
  6420. +
  6421. +    switch (pi->mode) {
  6422. +
  6423. +    case 0: w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
  6424. +        w2(0xd); a = r1();
  6425. +        w2(0xf); b = r1(); 
  6426. +        w2(0xc);
  6427. +        return j44(a,b);
  6428. +
  6429. +    case 1: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
  6430. +        w2(0xec); w2(0xee); w2(0xef); a = r0(); 
  6431. +        w2(0xc);
  6432. +        return a;
  6433. +
  6434. +    case 2: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc); 
  6435. +        w2(0xec); 
  6436. +        a = r4(); b = r4(); 
  6437. +        w2(0xc);
  6438. +        return a;
  6439. +
  6440. +    }
  6441. +    return -1; 
  6442. +
  6443. +}
  6444. +
  6445. +static void fit3_read_block( PIA *pi, char * buf, int count )
  6446. +
  6447. +{    int  k, a, b, c, d;
  6448. +
  6449. +    switch (pi->mode) {
  6450. +
  6451. +    case 0: w2(0xc); w0(0x10); w2(0x8); w2(0xc);
  6452. +        for (k=0;k<count/2;k++) {
  6453. +            w2(0xd); a = r1();
  6454. +            w2(0xf); b = r1();
  6455. +            w2(0xc); c = r1();
  6456. +            w2(0xe); d = r1();
  6457. +            buf[2*k  ] = j44(a,b);
  6458. +            buf[2*k+1] = j44(c,d);
  6459. +        }
  6460. +        w2(0xc);
  6461. +        break;
  6462. +
  6463. +    case 1: w2(0xc); w0(0x90); w2(0x8); w2(0xc); 
  6464. +        w2(0xec); w2(0xee);
  6465. +        for (k=0;k<count/2;k++) {
  6466. +            w2(0xef); a = r0();
  6467. +            w2(0xee); b = r0();
  6468. +                    buf[2*k  ] = a;
  6469. +                    buf[2*k+1] = b;
  6470. +        }
  6471. +        w2(0xec); 
  6472. +        w2(0xc);
  6473. +        break;
  6474. +
  6475. +    case 2: w2(0xc); w0(0x90); w2(0x8); w2(0xc); 
  6476. +                w2(0xec);
  6477. +        for (k=0;k<count;k++) buf[k] = r4();
  6478. +                w2(0xc);
  6479. +        break;
  6480. +
  6481. +    }
  6482. +}
  6483. +
  6484. +static void fit3_write_block( PIA *pi, char * buf, int count )
  6485. +
  6486. +{    int k;
  6487. +
  6488. +        switch (pi->mode) {
  6489. +
  6490. +    case 0:
  6491. +        case 1: w2(0xc); w0(0); w2(0x8); w2(0xc);
  6492. +                for (k=0;k<count/2;k++) {
  6493. +             w0(buf[2*k  ]); w2(0xd);
  6494. +             w0(buf[2*k+1]); w2(0xc);
  6495. +        }
  6496. +        break;
  6497. +
  6498. +        case 2: w2(0xc); w0(0); w2(0x8); w2(0xc); 
  6499. +                for (k=0;k<count;k++) w4(buf[k]);
  6500. +                w2(0xc);
  6501. +        break;
  6502. +    }
  6503. +}
  6504. +
  6505. +static void fit3_connect ( PIA *pi  )
  6506. +
  6507. +{       pi->saved_r0 = r0();
  6508. +        pi->saved_r2 = r2();
  6509. +    w2(0xc); w0(0); w2(0xa);
  6510. +    if (pi->mode == 2) { 
  6511. +        w2(0xc); w0(0x9); w2(0x8); w2(0xc); 
  6512. +        }
  6513. +}
  6514. +
  6515. +static void fit3_disconnect ( PIA *pi )
  6516. +
  6517. +{       w2(0xc); w0(0xa); w2(0x8); w2(0xc);
  6518. +    w0(pi->saved_r0);
  6519. +        w2(pi->saved_r2);
  6520. +} 
  6521. +
  6522. +static void fit3_log_adapter( PIA *pi, char * scratch, int verbose )
  6523. +
  6524. +{       char    *mode_string[3] = {"4-bit","8-bit","EPP"};
  6525. +
  6526. +    printk("%s: fit3 %s, FIT 3000 adapter at 0x%x, "
  6527. +           "mode %d (%s), delay %d\n",
  6528. +                pi->device,FIT3_VERSION,pi->port,
  6529. +        pi->mode,mode_string[pi->mode],pi->delay);
  6530. +
  6531. +}
  6532. +
  6533. +static void fit3_init_proto(PIA *pi)
  6534. +
  6535. +{       MOD_INC_USE_COUNT;
  6536. +}
  6537. +
  6538. +static void fit3_release_proto(PIA *pi)
  6539. +
  6540. +{       MOD_DEC_USE_COUNT;
  6541. +}
  6542. +
  6543. +struct pi_protocol fit3 = {"fit3",0,3,2,1,1,
  6544. +                           fit3_write_regr,
  6545. +                           fit3_read_regr,
  6546. +                           fit3_write_block,
  6547. +                           fit3_read_block,
  6548. +                           fit3_connect,
  6549. +                           fit3_disconnect,
  6550. +                           0,
  6551. +                           0,
  6552. +                           0,
  6553. +                           fit3_log_adapter,
  6554. +                           fit3_init_proto,
  6555. +                           fit3_release_proto
  6556. +                          };
  6557. +
  6558. +
  6559. +#ifdef MODULE
  6560. +
  6561. +int     init_module(void)
  6562. +
  6563. +{       return pi_register( &fit3 ) - 1;
  6564. +}
  6565. +
  6566. +void    cleanup_module(void)
  6567. +
  6568. +{       pi_unregister( &fit3 );
  6569. +}
  6570. +
  6571. +#endif
  6572. +
  6573. +/* end of fit3.c */
  6574. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/frpw.c linux/drivers/block/paride/frpw.c
  6575. --- v2.0.34/linux/drivers/block/paride/frpw.c    Wed Dec 31 16:00:00 1969
  6576. +++ linux/drivers/block/paride/frpw.c    Mon Jul 13 13:47:28 1998
  6577. @@ -0,0 +1,310 @@
  6578. +/* 
  6579. +    frpw.c    (c) 1996-8  Grant R. Guenther <grant@torque.net>
  6580. +                    Under the terms of the GNU public license
  6581. +
  6582. +    frpw.c is a low-level protocol driver for the Freecom "Power"
  6583. +    parallel port IDE adapter.
  6584. +    
  6585. +*/
  6586. +
  6587. +/* Changes:
  6588. +
  6589. +        1.01    GRG 1998.05.06 init_proto, release_proto
  6590. +                   fix chip detect
  6591. +                   added EPP-16 and EPP-32
  6592. +
  6593. +*/
  6594. +
  6595. +#define    FRPW_VERSION    "1.01" 
  6596. +
  6597. +#include <linux/module.h>
  6598. +#include <linux/delay.h>
  6599. +#include <linux/kernel.h>
  6600. +#include <linux/types.h>
  6601. +#include <asm/io.h>
  6602. +
  6603. +#include "paride.h"
  6604. +
  6605. +#define cec4        w2(0xc);w2(0xe);w2(0xe);w2(0xc);w2(4);w2(4);w2(4);
  6606. +#define j44(l,h)    (((l>>4)&0x0f)|(h&0xf0))
  6607. +
  6608. +/* cont = 0 - access the IDE register file 
  6609. +   cont = 1 - access the IDE command set 
  6610. +*/
  6611. +
  6612. +static int  cont_map[2] = { 0x08, 0x10 };
  6613. +
  6614. +static int frpw_read_regr( PIA *pi, int cont, int regr )
  6615. +
  6616. +{    int    h,l,r;
  6617. +
  6618. +    r = regr + cont_map[cont];
  6619. +
  6620. +    w2(4);
  6621. +    w0(r); cec4;
  6622. +    w2(6); l = r1();
  6623. +    w2(4); h = r1();
  6624. +    w2(4); 
  6625. +
  6626. +    return j44(l,h);
  6627. +
  6628. +}
  6629. +
  6630. +static void frpw_write_regr( PIA *pi, int cont, int regr, int val)
  6631. +
  6632. +{    int r;
  6633. +
  6634. +        r = regr + cont_map[cont];
  6635. +
  6636. +    w2(4); w0(r); cec4; 
  6637. +    w0(val);
  6638. +    w2(5);w2(7);w2(5);w2(4);
  6639. +}
  6640. +
  6641. +static void frpw_read_block_int( PIA *pi, char * buf, int count, int regr )
  6642. +
  6643. +{       int     h, l, k, ph;
  6644. +
  6645. +        switch(pi->mode) {
  6646. +
  6647. +        case 0: w2(4); w0(regr); cec4;
  6648. +                for (k=0;k<count;k++) {
  6649. +                        w2(6); l = r1();
  6650. +                        w2(4); h = r1();
  6651. +                        buf[k] = j44(l,h);
  6652. +                }
  6653. +                w2(4);
  6654. +                break;
  6655. +
  6656. +        case 1: ph = 2;
  6657. +                w2(4); w0(regr + 0xc0); cec4;
  6658. +                w0(0xff);
  6659. +                for (k=0;k<count;k++) {
  6660. +                        w2(0xa4 + ph); 
  6661. +                        buf[k] = r0();
  6662. +                        ph = 2 - ph;
  6663. +                } 
  6664. +                w2(0xac); w2(0xa4); w2(4);
  6665. +                break;
  6666. +
  6667. +        case 2: w2(4); w0(regr + 0x80); cec4;
  6668. +                for (k=0;k<count;k++) buf[k] = r4();
  6669. +                w2(0xac); w2(0xa4);
  6670. +                w2(4);
  6671. +                break;
  6672. +
  6673. +    case 3: w2(4); w0(regr + 0x80); cec4;
  6674. +        for (k=0;k<count-2;k++) buf[k] = r4();
  6675. +        w2(0xac); w2(0xa4);
  6676. +        buf[count-2] = r4();
  6677. +        buf[count-1] = r4();
  6678. +        w2(4);
  6679. +        break;
  6680. +
  6681. +    case 4: w2(4); w0(regr + 0x80); cec4;
  6682. +                for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
  6683. +                w2(0xac); w2(0xa4);
  6684. +                buf[count-2] = r4();
  6685. +                buf[count-1] = r4();
  6686. +                w2(4);
  6687. +                break;
  6688. +
  6689. +    case 5: w2(4); w0(regr + 0x80); cec4;
  6690. +                for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
  6691. +                buf[count-4] = r4();
  6692. +                buf[count-3] = r4();
  6693. +                w2(0xac); w2(0xa4);
  6694. +                buf[count-2] = r4();
  6695. +                buf[count-1] = r4();
  6696. +                w2(4);
  6697. +                break;
  6698. +
  6699. +        }
  6700. +}
  6701. +
  6702. +static void frpw_read_block( PIA *pi, char * buf, int count)
  6703. +
  6704. +{    frpw_read_block_int(pi,buf,count,0x08);
  6705. +}
  6706. +
  6707. +static void frpw_write_block( PIA *pi, char * buf, int count )
  6708. +{    int    k;
  6709. +
  6710. +    switch(pi->mode) {
  6711. +
  6712. +    case 0:
  6713. +    case 1:
  6714. +    case 2: w2(4); w0(8); cec4; w2(5);
  6715. +            for (k=0;k<count;k++) {
  6716. +            w0(buf[k]);
  6717. +            w2(7);w2(5);
  6718. +        }
  6719. +        w2(4);
  6720. +        break;
  6721. +
  6722. +    case 3: w2(4); w0(0xc8); cec4; w2(5);
  6723. +        for (k=0;k<count;k++) w4(buf[k]);
  6724. +        w2(4);
  6725. +        break;
  6726. +
  6727. +        case 4: w2(4); w0(0xc8); cec4; w2(5);
  6728. +                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
  6729. +                w2(4);
  6730. +                break;
  6731. +
  6732. +        case 5: w2(4); w0(0xc8); cec4; w2(5);
  6733. +                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
  6734. +                w2(4);
  6735. +                break;
  6736. +    }
  6737. +}
  6738. +
  6739. +static void frpw_connect ( PIA *pi  )
  6740. +
  6741. +{       pi->saved_r0 = r0();
  6742. +        pi->saved_r2 = r2();
  6743. +    w2(4);
  6744. +}
  6745. +
  6746. +static void frpw_disconnect ( PIA *pi )
  6747. +
  6748. +{       w2(4); w0(0x20); cec4;
  6749. +    w0(pi->saved_r0);
  6750. +        w2(pi->saved_r2);
  6751. +} 
  6752. +
  6753. +/* Stub logic to see if PNP string is available - used to distinguish
  6754. +   between the Xilinx and ASIC implementations of the Freecom adapter.
  6755. +*/
  6756. +
  6757. +static int frpw_test_pnp ( PIA *pi )
  6758. +
  6759. +/*  returns chip_type:   0 = Xilinx, 1 = ASIC   */
  6760. +
  6761. +{    int olddelay, a, b;
  6762. +
  6763. +    olddelay = pi->delay;
  6764. +    pi->delay = 10;
  6765. +
  6766. +    pi->saved_r0 = r0();
  6767. +        pi->saved_r2 = r2();
  6768. +    
  6769. +    w2(4); w0(4); w2(6); w2(7);
  6770. +    a = r1() & 0xff; w2(4); b = r1() & 0xff;
  6771. +    w2(0xc); w2(0xe); w2(4);
  6772. +
  6773. +    pi->delay = olddelay;
  6774. +        w0(pi->saved_r0);
  6775. +        w2(pi->saved_r2);
  6776. +
  6777. +    return ((~a&0x40) && (b&0x40));
  6778. +} 
  6779. +
  6780. +/* We use the pi->private to remember the result of the PNP test.
  6781. +   To make this work, private = port*2 + chip.  Yes, I know it's
  6782. +   a hack :-(
  6783. +*/
  6784. +
  6785. +static int frpw_test_proto( PIA *pi, char * scratch, int verbose )
  6786. +
  6787. +{       int     j, k, r;
  6788. +    int    e[2] = {0,0};
  6789. +
  6790. +    if ((pi->private>>1) != pi->port)
  6791. +       pi->private = frpw_test_pnp(pi) + 2*pi->port;
  6792. +
  6793. +    if (((pi->private%2) == 0) && (pi->mode > 2)) {
  6794. +       if (verbose) 
  6795. +        printk("%s: frpw: Xilinx does not support mode %d\n",
  6796. +            pi->device, pi->mode);
  6797. +       return 1;
  6798. +    }
  6799. +
  6800. +    if (((pi->private%2) == 1) && (pi->mode == 2)) {
  6801. +       if (verbose)
  6802. +        printk("%s: frpw: ASIC does not support mode 2\n",
  6803. +            pi->device);
  6804. +       return 1;
  6805. +    }
  6806. +
  6807. +    frpw_connect(pi);
  6808. +    for (j=0;j<2;j++) {
  6809. +                frpw_write_regr(pi,0,6,0xa0+j*0x10);
  6810. +                for (k=0;k<256;k++) {
  6811. +                        frpw_write_regr(pi,0,2,k^0xaa);
  6812. +                        frpw_write_regr(pi,0,3,k^0x55);
  6813. +                        if (frpw_read_regr(pi,0,2) != (k^0xaa)) e[j]++;
  6814. +                        }
  6815. +                }
  6816. +    frpw_disconnect(pi);
  6817. +
  6818. +    frpw_connect(pi);
  6819. +        frpw_read_block_int(pi,scratch,512,0x10);
  6820. +        r = 0;
  6821. +        for (k=0;k<128;k++) if (scratch[k] != k) r++;
  6822. +    frpw_disconnect(pi);
  6823. +
  6824. +        if (verbose)  {
  6825. +            printk("%s: frpw: port 0x%x, chip %d, mode %d, test=(%d,%d,%d)\n",
  6826. +                   pi->device,pi->port,(pi->private%2),pi->mode,e[0],e[1],r);
  6827. +        }
  6828. +
  6829. +        return (r || (e[0] && e[1]));
  6830. +}
  6831. +
  6832. +
  6833. +static void frpw_log_adapter( PIA *pi, char * scratch, int verbose )
  6834. +
  6835. +{       char    *mode_string[6] = {"4-bit","8-bit","EPP",
  6836. +                   "EPP-8","EPP-16","EPP-32"};
  6837. +
  6838. +        printk("%s: frpw %s, Freecom (%s) adapter at 0x%x, ", pi->device,
  6839. +        FRPW_VERSION,((pi->private%2) == 0)?"Xilinx":"ASIC",pi->port);
  6840. +        printk("mode %d (%s), delay %d\n",pi->mode,
  6841. +        mode_string[pi->mode],pi->delay);
  6842. +
  6843. +}
  6844. +
  6845. +static void frpw_init_proto( PIA *pi)
  6846. +
  6847. +{       MOD_INC_USE_COUNT;
  6848. +    pi->private = 0;
  6849. +}
  6850. +
  6851. +static void frpw_release_proto( PIA *pi)
  6852. +
  6853. +{       MOD_DEC_USE_COUNT;
  6854. +}
  6855. +
  6856. +struct pi_protocol frpw = {"frpw",0,6,2,2,1,
  6857. +                           frpw_write_regr,
  6858. +                           frpw_read_regr,
  6859. +                           frpw_write_block,
  6860. +                           frpw_read_block,
  6861. +                           frpw_connect,
  6862. +                           frpw_disconnect,
  6863. +                           0,
  6864. +                           0,
  6865. +                           frpw_test_proto,
  6866. +                           frpw_log_adapter,
  6867. +                           frpw_init_proto,
  6868. +                           frpw_release_proto
  6869. +                          };
  6870. +
  6871. +
  6872. +#ifdef MODULE
  6873. +
  6874. +int     init_module(void)
  6875. +
  6876. +{       return pi_register( &frpw ) - 1;
  6877. +}
  6878. +
  6879. +void    cleanup_module(void)
  6880. +
  6881. +{       pi_unregister( &frpw );
  6882. +}
  6883. +
  6884. +#endif
  6885. +
  6886. +/* end of frpw.c */
  6887. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/kbic.c linux/drivers/block/paride/kbic.c
  6888. --- v2.0.34/linux/drivers/block/paride/kbic.c    Wed Dec 31 16:00:00 1969
  6889. +++ linux/drivers/block/paride/kbic.c    Mon Jul 13 13:47:28 1998
  6890. @@ -0,0 +1,311 @@
  6891. +/*
  6892. +        kbic.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  6893. +                              Under the terms of the GNU public license.
  6894. +
  6895. +        This is a low-level driver for the KBIC-951A and KBIC-971A
  6896. +        parallel to IDE adapter chips from KingByte Information Systems.
  6897. +
  6898. +    The chips are almost identical, however, the wakeup code 
  6899. +    required for the 971A interferes with the correct operation of
  6900. +        the 951A, so this driver registers itself twice, once for
  6901. +    each chip.
  6902. +
  6903. +*/
  6904. +
  6905. +/* Changes:
  6906. +
  6907. +        1.01    GRG 1998.05.06 init_proto, release_proto
  6908. +
  6909. +*/
  6910. +
  6911. +#define KBIC_VERSION      "1.01"
  6912. +
  6913. +#include <linux/module.h>
  6914. +#include <linux/delay.h>
  6915. +#include <linux/kernel.h>
  6916. +#include <linux/types.h>
  6917. +#include <asm/io.h>
  6918. +
  6919. +#include "paride.h"
  6920. +
  6921. +#define r12w()            (delay_p,inw(pi->port+1)&0xffff) 
  6922. +
  6923. +#define j44(a,b)                ((((a>>4)&0x0f)|(b&0xf0))^0x88)
  6924. +#define j53(w)                  (((w>>3)&0x1f)|((w>>4)&0xe0))
  6925. +
  6926. +
  6927. +/* cont = 0 - access the IDE register file 
  6928. +   cont = 1 - access the IDE command set 
  6929. +*/
  6930. +
  6931. +static int  cont_map[2] = { 0x80, 0x40 };
  6932. +
  6933. +static int kbic_read_regr( PIA *pi, int cont, int regr )
  6934. +
  6935. +{       int     a, b, s;
  6936. +
  6937. +        s = cont_map[cont];
  6938. +
  6939. +    switch (pi->mode) {
  6940. +
  6941. +    case 0: w0(regr|0x18|s); w2(4); w2(6); w2(4); w2(1); w0(8);
  6942. +            a = r1(); w0(0x28); b = r1(); w2(4);
  6943. +        return j44(a,b);
  6944. +
  6945. +    case 1: w0(regr|0x38|s); w2(4); w2(6); w2(4); w2(5); w0(8);
  6946. +        a = r12w(); w2(4);
  6947. +        return j53(a);
  6948. +
  6949. +    case 2: w0(regr|0x08|s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);
  6950. +        a = r0(); w2(4);
  6951. +               return a;
  6952. +
  6953. +    case 3:
  6954. +    case 4:
  6955. +    case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
  6956. +        a = r4(); b = r4(); w2(4); w2(0); w2(4);
  6957. +        return a;
  6958. +
  6959. +    }
  6960. +    return -1;
  6961. +}       
  6962. +
  6963. +static void  kbic_write_regr( PIA *pi, int cont, int regr, int val)
  6964. +
  6965. +{       int  s;
  6966. +
  6967. +        s = cont_map[cont];
  6968. +
  6969. +        switch (pi->mode) {
  6970. +
  6971. +    case 0: 
  6972. +        case 1:
  6973. +    case 2:    w0(regr|0x10|s); w2(4); w2(6); w2(4); 
  6974. +        w0(val); w2(5); w2(4);
  6975. +        break;
  6976. +
  6977. +    case 3:
  6978. +    case 4:
  6979. +    case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
  6980. +        w4(val); w4(val);
  6981. +        w2(4); w2(0); w2(4);
  6982. +                break;
  6983. +
  6984. +    }
  6985. +}
  6986. +
  6987. +static void k951_connect ( PIA *pi  )
  6988. +
  6989. +{     pi->saved_r0 = r0();
  6990. +        pi->saved_r2 = r2();
  6991. +        w2(4); 
  6992. +}
  6993. +
  6994. +static void k951_disconnect ( PIA *pi )
  6995. +
  6996. +{          w0(pi->saved_r0);
  6997. +        w2(pi->saved_r2);
  6998. +}
  6999. +
  7000. +#define    CCP(x)    w2(0xc4);w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);\
  7001. +        w0(0x78);w0(x);w2(0xc5);w2(0xc4);w0(0xff);
  7002. +
  7003. +static void k971_connect ( PIA *pi  )
  7004. +
  7005. +{     pi->saved_r0 = r0();
  7006. +        pi->saved_r2 = r2();
  7007. +    CCP(0x20);
  7008. +        w2(4); 
  7009. +}
  7010. +
  7011. +static void k971_disconnect ( PIA *pi )
  7012. +
  7013. +{       CCP(0x30);
  7014. +    w0(pi->saved_r0);
  7015. +        w2(pi->saved_r2);
  7016. +}
  7017. +
  7018. +/* counts must be congruent to 0 MOD 4, but all known applications
  7019. +   have this property.
  7020. +*/
  7021. +
  7022. +static void kbic_read_block( PIA *pi, char * buf, int count )
  7023. +
  7024. +{       int     k, a, b;
  7025. +
  7026. +        switch (pi->mode) {
  7027. +
  7028. +        case 0: w0(0x98); w2(4); w2(6); w2(4);
  7029. +                for (k=0;k<count/2;k++) {
  7030. +            w2(1); w0(8);    a = r1();
  7031. +                   w0(0x28); b = r1();
  7032. +            buf[2*k]   = j44(a,b);
  7033. +            w2(5);           b = r1();
  7034. +                   w0(8);    a = r1();
  7035. +            buf[2*k+1] = j44(a,b);
  7036. +            w2(4);
  7037. +                } 
  7038. +                break;
  7039. +
  7040. +        case 1: w0(0xb8); w2(4); w2(6); w2(4); 
  7041. +                for (k=0;k<count/4;k++) {
  7042. +                        w0(0xb8); 
  7043. +            w2(4); w2(5); 
  7044. +                        w0(8);    buf[4*k]   = j53(r12w());
  7045. +            w0(0xb8); buf[4*k+1] = j53(r12w());
  7046. +            w2(4); w2(5);
  7047. +                      buf[4*k+3] = j53(r12w());
  7048. +            w0(8);    buf[4*k+2] = j53(r12w());
  7049. +                }
  7050. +                w2(4);
  7051. +                break;
  7052. +
  7053. +        case 2: w0(0x88); w2(4); w2(6); w2(4);
  7054. +                for (k=0;k<count/2;k++) {
  7055. +                        w2(0xa0); w2(0xa1); buf[2*k] = r0();
  7056. +                        w2(0xa5); buf[2*k+1] = r0();
  7057. +                }
  7058. +                w2(4);
  7059. +                break;
  7060. +
  7061. +        case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
  7062. +                for (k=0;k<count;k++) buf[k] = r4();
  7063. +                w2(4); w2(0); w2(4);
  7064. +                break;
  7065. +
  7066. +    case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
  7067. +                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
  7068. +                w2(4); w2(0); w2(4);
  7069. +                break;
  7070. +
  7071. +        case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
  7072. +                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
  7073. +                w2(4); w2(0); w2(4);
  7074. +                break;
  7075. +
  7076. +
  7077. +        }
  7078. +}
  7079. +
  7080. +static void kbic_write_block( PIA *pi, char * buf, int count )
  7081. +
  7082. +{       int     k;
  7083. +
  7084. +        switch (pi->mode) {
  7085. +
  7086. +        case 0:
  7087. +        case 1:
  7088. +        case 2: w0(0x90); w2(4); w2(6); w2(4); 
  7089. +        for(k=0;k<count/2;k++) {
  7090. +            w0(buf[2*k+1]); w2(0); w2(4); 
  7091. +            w0(buf[2*k]);   w2(5); w2(4); 
  7092. +        }
  7093. +        break;
  7094. +
  7095. +        case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
  7096. +        for(k=0;k<count/2;k++) {
  7097. +            w4(buf[2*k+1]); 
  7098. +                        w4(buf[2*k]);
  7099. +                }
  7100. +        w2(4); w2(0); w2(4);
  7101. +        break;
  7102. +
  7103. +    case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
  7104. +                for(k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
  7105. +                w2(4); w2(0); w2(4);
  7106. +                break;
  7107. +
  7108. +        case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
  7109. +                for(k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
  7110. +                w2(4); w2(0); w2(4);
  7111. +                break;
  7112. +
  7113. +        }
  7114. +
  7115. +}
  7116. +
  7117. +static void kbic_log_adapter( PIA *pi, char * scratch, 
  7118. +                  int verbose, char * chip )
  7119. +
  7120. +{       char    *mode_string[6] = {"4-bit","5/3","8-bit",
  7121. +                   "EPP-8","EPP_16","EPP-32"};
  7122. +
  7123. +        printk("%s: kbic %s, KingByte %s at 0x%x, ",
  7124. +                pi->device,KBIC_VERSION,chip,pi->port);
  7125. +        printk("mode %d (%s), delay %d\n",pi->mode,
  7126. +        mode_string[pi->mode],pi->delay);
  7127. +
  7128. +}
  7129. +
  7130. +static void k951_log_adapter( PIA *pi, char * scratch, int verbose )
  7131. +
  7132. +{    kbic_log_adapter(pi,scratch,verbose,"KBIC-951A");
  7133. +}
  7134. +
  7135. +static void k971_log_adapter( PIA *pi, char * scratch, int verbose )
  7136. +
  7137. +{       kbic_log_adapter(pi,scratch,verbose,"KBIC-971A");
  7138. +}
  7139. +
  7140. +static void kbic_init_proto( PIA *pi)
  7141. +
  7142. +{       MOD_INC_USE_COUNT;
  7143. +}
  7144. +
  7145. +static void kbic_release_proto( PIA *pi)
  7146. +
  7147. +{       MOD_DEC_USE_COUNT;
  7148. +}
  7149. +
  7150. +struct pi_protocol k951 = {"k951",0,6,3,1,1,
  7151. +                           kbic_write_regr,
  7152. +                           kbic_read_regr,
  7153. +                           kbic_write_block,
  7154. +                           kbic_read_block,
  7155. +                           k951_connect,
  7156. +                           k951_disconnect,
  7157. +                           0,
  7158. +                           0,
  7159. +                           0,
  7160. +                           k951_log_adapter,
  7161. +                           kbic_init_proto,
  7162. +                           kbic_release_proto
  7163. +                };
  7164. +
  7165. +
  7166. +struct pi_protocol k971 = {"k971",0,6,3,1,1,
  7167. +                           kbic_write_regr,
  7168. +                           kbic_read_regr,
  7169. +                           kbic_write_block,
  7170. +                           kbic_read_block,
  7171. +                           k971_connect,
  7172. +                           k971_disconnect,
  7173. +                           0,
  7174. +                           0,
  7175. +                           0,
  7176. +                           k971_log_adapter,
  7177. +                           kbic_init_proto,
  7178. +                           kbic_release_proto
  7179. +                          };
  7180. +
  7181. +#ifdef MODULE
  7182. +
  7183. +int     init_module(void)
  7184. +
  7185. +{       int s5,s7;
  7186. +
  7187. +    s5 = pi_register(&k951);
  7188. +    s7 = pi_register(&k971);
  7189. +
  7190. +    return (s5 || s7) - 1;
  7191. +}
  7192. +
  7193. +void    cleanup_module(void)
  7194. +
  7195. +{       pi_unregister( &k951 );
  7196. +    pi_unregister( &k971 );
  7197. +}
  7198. +
  7199. +#endif
  7200. +
  7201. +/* end of kbic.c */
  7202. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/ktti.c linux/drivers/block/paride/ktti.c
  7203. --- v2.0.34/linux/drivers/block/paride/ktti.c    Wed Dec 31 16:00:00 1969
  7204. +++ linux/drivers/block/paride/ktti.c    Mon Jul 13 13:47:28 1998
  7205. @@ -0,0 +1,138 @@
  7206. +/* 
  7207. +        ktti.c        (c) 1998  Grant R. Guenther <grant@torque.net>
  7208. +                          Under the terms of the GNU public license.
  7209. +
  7210. +    ktti.c is a low-level protocol driver for the KT Technology
  7211. +    parallel port adapter.  This adapter is used in the "PHd" 
  7212. +        portable hard-drives.  As far as I can tell, this device
  7213. +    supports 4-bit mode _only_.  
  7214. +
  7215. +*/
  7216. +
  7217. +#define KTTI_VERSION      "1.0"
  7218. +
  7219. +#include <linux/module.h>
  7220. +#include <linux/delay.h>
  7221. +#include <linux/kernel.h>
  7222. +#include <linux/types.h>
  7223. +#include <asm/io.h>
  7224. +
  7225. +#include "paride.h"
  7226. +
  7227. +#define j44(a,b)                (((a>>4)&0x0f)|(b&0xf0))
  7228. +
  7229. +/* cont = 0 - access the IDE register file 
  7230. +   cont = 1 - access the IDE command set 
  7231. +*/
  7232. +
  7233. +static int  cont_map[2] = { 0x10, 0x08 };
  7234. +
  7235. +static void  ktti_write_regr( PIA *pi, int cont, int regr, int val)
  7236. +
  7237. +{    int r;
  7238. +
  7239. +    r = regr + cont_map[cont];
  7240. +
  7241. +    w0(r); w2(0xb); w2(0xa); w2(3); w2(6); 
  7242. +    w0(val); w2(3); w0(0); w2(6); w2(0xb);
  7243. +}
  7244. +
  7245. +static int ktti_read_regr( PIA *pi, int cont, int regr )
  7246. +
  7247. +{    int  a, b, r;
  7248. +
  7249. +        r = regr + cont_map[cont];
  7250. +
  7251. +        w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9); 
  7252. +    a = r1(); w2(0xc);  b = r1(); w2(9); w2(0xc); w2(9);
  7253. +    return j44(a,b);
  7254. +
  7255. +}
  7256. +
  7257. +static void ktti_read_block( PIA *pi, char * buf, int count )
  7258. +
  7259. +{    int  k, a, b;
  7260. +
  7261. +    for (k=0;k<count/2;k++) {
  7262. +        w0(0x10); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9);
  7263. +        a = r1(); w2(0xc); b = r1(); w2(9);
  7264. +        buf[2*k] = j44(a,b);
  7265. +        a = r1(); w2(0xc); b = r1(); w2(9);
  7266. +        buf[2*k+1] = j44(a,b);
  7267. +    }
  7268. +}
  7269. +
  7270. +static void ktti_write_block( PIA *pi, char * buf, int count )
  7271. +
  7272. +{    int k;
  7273. +
  7274. +    for (k=0;k<count/2;k++) {
  7275. +        w0(0x10); w2(0xb); w2(0xa); w2(3); w2(6);
  7276. +        w0(buf[2*k]); w2(3);
  7277. +        w0(buf[2*k+1]); w2(6);
  7278. +        w2(0xb);
  7279. +    }
  7280. +}
  7281. +
  7282. +static void ktti_connect ( PIA *pi  )
  7283. +
  7284. +{       pi->saved_r0 = r0();
  7285. +        pi->saved_r2 = r2();
  7286. +    w2(0xb); w2(0xa); w0(0); w2(3); w2(6);    
  7287. +}
  7288. +
  7289. +static void ktti_disconnect ( PIA *pi )
  7290. +
  7291. +{       w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4);
  7292. +    w0(pi->saved_r0);
  7293. +        w2(pi->saved_r2);
  7294. +} 
  7295. +
  7296. +static void ktti_log_adapter( PIA *pi, char * scratch, int verbose )
  7297. +
  7298. +{       printk("%s: ktti %s, KT adapter at 0x%x, delay %d\n",
  7299. +                pi->device,KTTI_VERSION,pi->port,pi->delay);
  7300. +
  7301. +}
  7302. +
  7303. +static void ktti_init_proto( PIA *pi)
  7304. +
  7305. +{       MOD_INC_USE_COUNT;
  7306. +}
  7307. +
  7308. +static void ktti_release_proto( PIA *pi)
  7309. +
  7310. +{       MOD_DEC_USE_COUNT;
  7311. +}
  7312. +
  7313. +struct pi_protocol ktti = {"ktti",0,1,2,1,1,
  7314. +                           ktti_write_regr,
  7315. +                           ktti_read_regr,
  7316. +                           ktti_write_block,
  7317. +                           ktti_read_block,
  7318. +                           ktti_connect,
  7319. +                           ktti_disconnect,
  7320. +                           0,
  7321. +                           0,
  7322. +                           0,
  7323. +                           ktti_log_adapter,
  7324. +                           ktti_init_proto,
  7325. +                           ktti_release_proto
  7326. +                          };
  7327. +
  7328. +
  7329. +#ifdef MODULE
  7330. +
  7331. +int     init_module(void)
  7332. +
  7333. +{       return pi_register( &ktti ) - 1;
  7334. +}
  7335. +
  7336. +void    cleanup_module(void)
  7337. +
  7338. +{       pi_unregister( &ktti );
  7339. +}
  7340. +
  7341. +#endif
  7342. +
  7343. +/* end of ktti.c */
  7344. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/mkd linux/drivers/block/paride/mkd
  7345. --- v2.0.34/linux/drivers/block/paride/mkd    Wed Dec 31 16:00:00 1969
  7346. +++ linux/drivers/block/paride/mkd    Mon Jul 13 13:47:28 1998
  7347. @@ -0,0 +1,30 @@
  7348. +#!/bin/bash
  7349. +#
  7350. +# mkd -- a script to create the device special files for the PARIDE subsystem
  7351. +#
  7352. +#  block devices:      pd (45), pcd (46), pf (47)
  7353. +#  character devices:    pt (96), pg (97)
  7354. +#
  7355. +function mkdev {
  7356. +  mknod $1 $2 $3 $4 ; chmod 0660 $1 ; chown root:disk $1
  7357. +}
  7358. +#
  7359. +function pd {
  7360. +  D=$( printf \\$( printf "x%03x" $[ $1 + 97 ] ) )
  7361. +  mkdev pd$D b 45 $[ $1 * 16 ]
  7362. +  for P in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  7363. +  do mkdev pd$D$P b 45 $[ $1 * 16 + $P ]
  7364. +  done
  7365. +}
  7366. +#
  7367. +cd /dev
  7368. +#
  7369. +for u in 0 1 2 3 ; do pd $u ; done
  7370. +for u in 0 1 2 3 ; do mkdev pcd$u b 46 $u ; done 
  7371. +for u in 0 1 2 3 ; do mkdev pf$u  b 47 $u ; done 
  7372. +for u in 0 1 2 3 ; do mkdev pt$u  c 96 $u ; done 
  7373. +for u in 0 1 2 3 ; do mkdev npt$u c 96 $[ $u + 128 ] ; done 
  7374. +for u in 0 1 2 3 ; do mkdev pg$u  c 97 $u ; done
  7375. +#
  7376. +# end of mkd
  7377. +
  7378. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/on20.c linux/drivers/block/paride/on20.c
  7379. --- v2.0.34/linux/drivers/block/paride/on20.c    Wed Dec 31 16:00:00 1969
  7380. +++ linux/drivers/block/paride/on20.c    Mon Jul 13 13:47:28 1998
  7381. @@ -0,0 +1,163 @@
  7382. +/* 
  7383. +    on20.c    (c) 1996-8  Grant R. Guenther <grant@torque.net>
  7384. +                    Under the terms of the GNU public license.
  7385. +
  7386. +        on20.c is a low-level protocol driver for the
  7387. +        Onspec 90c20 parallel to IDE adapter. 
  7388. +*/
  7389. +
  7390. +/* Changes:
  7391. +
  7392. +        1.01    GRG 1998.05.06 init_proto, release_proto
  7393. +
  7394. +*/
  7395. +
  7396. +#define    ON20_VERSION    "1.01"
  7397. +
  7398. +#include <linux/module.h>
  7399. +#include <linux/delay.h>
  7400. +#include <linux/kernel.h>
  7401. +#include <linux/types.h>
  7402. +#include <asm/io.h>
  7403. +
  7404. +#include "paride.h"
  7405. +
  7406. +#define op(f)    w2(4);w0(f);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
  7407. +#define vl(v)    w2(4);w0(v);w2(5);w2(7);w2(5);w2(4);
  7408. +
  7409. +#define j44(a,b)  (((a>>4)&0x0f)|(b&0xf0))
  7410. +
  7411. +/* cont = 0 - access the IDE register file 
  7412. +   cont = 1 - access the IDE command set 
  7413. +*/
  7414. +
  7415. +static int on20_read_regr( PIA *pi, int cont, int regr )
  7416. +
  7417. +{    int h,l, r ;
  7418. +
  7419. +        r = (regr<<2) + 1 + cont;
  7420. +
  7421. +        op(1); vl(r); op(0);
  7422. +
  7423. +    switch (pi->mode)  {
  7424. +
  7425. +        case 0:  w2(4); w2(6); l = r1();
  7426. +                 w2(4); w2(6); h = r1();
  7427. +                 w2(4); w2(6); w2(4); w2(6); w2(4);
  7428. +         return j44(l,h);
  7429. +
  7430. +    case 1:  w2(4); w2(0x26); r = r0(); 
  7431. +                 w2(4); w2(0x26); w2(4);
  7432. +         return r;
  7433. +
  7434. +    }
  7435. +    return -1;
  7436. +}    
  7437. +
  7438. +static void on20_write_regr( PIA *pi, int cont, int regr, int val )
  7439. +
  7440. +{    int r;
  7441. +
  7442. +    r = (regr<<2) + 1 + cont;
  7443. +
  7444. +    op(1); vl(r); 
  7445. +    op(0); vl(val); 
  7446. +    op(0); vl(val);
  7447. +}
  7448. +
  7449. +static void on20_connect ( PIA *pi)
  7450. +
  7451. +{    pi->saved_r0 = r0();
  7452. +        pi->saved_r2 = r2();
  7453. +
  7454. +    w2(4);w0(0);w2(0xc);w2(4);w2(6);w2(4);w2(6);w2(4); 
  7455. +    if (pi->mode) { op(2); vl(8); op(2); vl(9); }
  7456. +           else   { op(2); vl(0); op(2); vl(8); }
  7457. +}
  7458. +
  7459. +static void on20_disconnect ( PIA *pi )
  7460. +
  7461. +{    w2(4);w0(7);w2(4);w2(0xc);w2(4);
  7462. +        w0(pi->saved_r0);
  7463. +        w2(pi->saved_r2);
  7464. +} 
  7465. +
  7466. +static void on20_read_block( PIA *pi, char * buf, int count )
  7467. +
  7468. +{    int     k, l, h; 
  7469. +
  7470. +    op(1); vl(1); op(0);
  7471. +
  7472. +    for (k=0;k<count;k++) 
  7473. +        if (pi->mode) {
  7474. +        w2(4); w2(0x26); buf[k] = r0();
  7475. +        } else {
  7476. +        w2(6); l = r1(); w2(4);
  7477. +        w2(6); h = r1(); w2(4);
  7478. +        buf[k] = j44(l,h);
  7479. +        }
  7480. +    w2(4);
  7481. +}
  7482. +
  7483. +static void on20_write_block(  PIA *pi, char * buf, int count )
  7484. +
  7485. +{    int    k;
  7486. +
  7487. +    op(1); vl(1); op(0);
  7488. +
  7489. +    for (k=0;k<count;k++) { w2(5); w0(buf[k]); w2(7); }
  7490. +    w2(4);
  7491. +}
  7492. +
  7493. +static void on20_log_adapter( PIA *pi, char * scratch, int verbose )
  7494. +
  7495. +{       char    *mode_string[2] = {"4-bit","8-bit"};
  7496. +
  7497. +        printk("%s: on20 %s, OnSpec 90c20 at 0x%x, ",
  7498. +                pi->device,ON20_VERSION,pi->port);
  7499. +        printk("mode %d (%s), delay %d\n",pi->mode,
  7500. +        mode_string[pi->mode],pi->delay);
  7501. +
  7502. +}
  7503. +
  7504. +static void on20_init_proto( PIA *pi)
  7505. +
  7506. +{       MOD_INC_USE_COUNT;
  7507. +}
  7508. +
  7509. +static void on20_release_proto( PIA *pi)
  7510. +
  7511. +{       MOD_DEC_USE_COUNT;
  7512. +}
  7513. +
  7514. +struct pi_protocol on20 = {"on20",0,2,2,1,1,
  7515. +                           on20_write_regr,
  7516. +                           on20_read_regr,
  7517. +                           on20_write_block,
  7518. +                           on20_read_block,
  7519. +                           on20_connect,
  7520. +                           on20_disconnect,
  7521. +                           0,
  7522. +                           0,
  7523. +                           0,
  7524. +                           on20_log_adapter,
  7525. +                           on20_init_proto,
  7526. +                           on20_release_proto
  7527. +                          };
  7528. +
  7529. +
  7530. +#ifdef MODULE
  7531. +
  7532. +int     init_module(void)
  7533. +
  7534. +{       return pi_register( &on20 ) - 1;
  7535. +}
  7536. +
  7537. +void    cleanup_module(void)
  7538. +
  7539. +{       pi_unregister( &on20 );
  7540. +}
  7541. +
  7542. +#endif
  7543. +
  7544. +/* end of on20.c */
  7545. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/on26.c linux/drivers/block/paride/on26.c
  7546. --- v2.0.34/linux/drivers/block/paride/on26.c    Wed Dec 31 16:00:00 1969
  7547. +++ linux/drivers/block/paride/on26.c    Mon Jul 13 13:47:28 1998
  7548. @@ -0,0 +1,267 @@
  7549. +/* 
  7550. +        on26.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  7551. +                              Under the terms of the GNU public license.
  7552. +
  7553. +        on26.c is a low-level protocol driver for the 
  7554. +        OnSpec 90c26 parallel to IDE adapter chip.
  7555. +
  7556. +*/
  7557. +
  7558. +/* Changes:
  7559. +
  7560. +        1.01    GRG 1998.05.06 init_proto, release_proto
  7561. +
  7562. +*/
  7563. +
  7564. +#define ON26_VERSION      "1.01"
  7565. +
  7566. +#include <linux/module.h>
  7567. +#include <linux/delay.h>
  7568. +#include <linux/kernel.h>
  7569. +#include <linux/types.h>
  7570. +#include <asm/io.h>
  7571. +
  7572. +#include "paride.h"
  7573. +
  7574. +/* mode codes:  0  nybble reads, 8-bit writes
  7575. +                1  8-bit reads and writes
  7576. +                2  8-bit EPP mode
  7577. +        3  EPP-16
  7578. +        4  EPP-32
  7579. +*/
  7580. +
  7581. +#define j44(a,b)  (((a>>4)&0x0f)|(b&0xf0))
  7582. +
  7583. +#define P1    w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
  7584. +#define P2    w2(5);w2(7);w2(5);w2(4);
  7585. +
  7586. +/* cont = 0 - access the IDE register file 
  7587. +   cont = 1 - access the IDE command set 
  7588. +*/
  7589. +
  7590. +static int on26_read_regr( PIA *pi, int cont, int regr )
  7591. +
  7592. +{       int     a, b, r;
  7593. +
  7594. +    r = (regr<<2) + 1 + cont;
  7595. +
  7596. +        switch (pi->mode)  {
  7597. +
  7598. +        case 0: w0(1); P1; w0(r); P2; w0(0); P1; 
  7599. +        w2(6); a = r1(); w2(4);
  7600. +        w2(6); b = r1(); w2(4);
  7601. +        w2(6); w2(4); w2(6); w2(4);
  7602. +                return j44(a,b);
  7603. +
  7604. +        case 1: w0(1); P1; w0(r); P2; w0(0); P1;
  7605. +        w2(0x26); a = r0(); w2(4); w2(0x26); w2(4);
  7606. +                return a;
  7607. +
  7608. +    case 2:
  7609. +    case 3:
  7610. +        case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
  7611. +        w3(0); w3(0); w2(0x24); a = r4(); w2(4);
  7612. +        w2(0x24); r4(); w2(4);
  7613. +                return a;
  7614. +
  7615. +        }
  7616. +        return -1;
  7617. +}       
  7618. +
  7619. +static void on26_write_regr( PIA *pi, int cont, int regr, int val )
  7620. +
  7621. +{       int  r;
  7622. +
  7623. +        r = (regr<<2) + 1 + cont;
  7624. +
  7625. +        switch (pi->mode)  {
  7626. +
  7627. +        case 0:
  7628. +        case 1: w0(1); P1; w0(r); P2; w0(0); P1;
  7629. +        w0(val); P2; w0(val); P2;
  7630. +        break;
  7631. +
  7632. +    case 2:
  7633. +    case 3:
  7634. +        case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
  7635. +        w3(0); w3(0); 
  7636. +        w2(5); w4(val); w2(4);
  7637. +        w2(5); w4(val); w2(4);
  7638. +                break;
  7639. +        }
  7640. +}
  7641. +
  7642. +#define  CCP(x)  w0(0xff);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
  7643. +         w0(0x87);w0(0x78);w0(x);w2(4);
  7644. +
  7645. +static void on26_connect ( PIA *pi )
  7646. +
  7647. +{       int    x;
  7648. +
  7649. +    pi->saved_r0 = r0();
  7650. +        pi->saved_r2 = r2();
  7651. +
  7652. +        CCP(0x20);
  7653. +    w2(0xcd); w2(0xcc); w0(0xff);
  7654. +    x = 8; if (pi->mode) x = 9;
  7655. +
  7656. +    w0(2); P1; w0(8); P2;
  7657. +    w0(2); P1; w0(x); P2;
  7658. +}
  7659. +
  7660. +static void on26_disconnect ( PIA *pi )
  7661. +
  7662. +{       if (pi->mode >= 2) { w3(4); w3(4); w3(4); w3(4); }
  7663. +                  else { w0(4); P1; w0(4); P1; }
  7664. +    CCP(0x30);
  7665. +        w2(0xcd); w2(0xcc); w0(0xff);
  7666. +        w0(pi->saved_r0);
  7667. +        w2(pi->saved_r2);
  7668. +} 
  7669. +
  7670. +static void on26_read_block( PIA *pi, char * buf, int count )
  7671. +
  7672. +{       int     k, a, b;
  7673. +
  7674. +        switch (pi->mode) {
  7675. +
  7676. +        case 0: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1;
  7677. +        udelay(10);
  7678. +        for (k=0;k<count;k++) {
  7679. +                        w2(6); a = r1();
  7680. +                        w2(4); b = r1();
  7681. +                        buf[k] = j44(a,b);
  7682. +                }
  7683. +        w0(2); P1; w0(8); P2; 
  7684. +                break;
  7685. +
  7686. +        case 1: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1;
  7687. +        udelay(10);
  7688. +                for (k=0;k<count/2;k++) {
  7689. +                        w2(0x26); buf[2*k] = r0(); 
  7690. +            w2(0x24); buf[2*k+1] = r0();
  7691. +                }
  7692. +                w0(2); P1; w0(9); P2;
  7693. +                break;
  7694. +
  7695. +        case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
  7696. +        w3(0); w3(0); w2(0x24);
  7697. +        udelay(10);
  7698. +                for (k=0;k<count;k++) buf[k] = r4();
  7699. +                w2(4);
  7700. +                break;
  7701. +
  7702. +        case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
  7703. +                w3(0); w3(0); w2(0x24);
  7704. +                udelay(10);
  7705. +                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
  7706. +                w2(4);
  7707. +                break;
  7708. +
  7709. +        case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
  7710. +                w3(0); w3(0); w2(0x24);
  7711. +                udelay(10);
  7712. +                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
  7713. +                w2(4);
  7714. +                break;
  7715. +
  7716. +        }
  7717. +}
  7718. +
  7719. +static void on26_write_block( PIA *pi, char * buf, int count )
  7720. +
  7721. +{       int    k;
  7722. +
  7723. +        switch (pi->mode) {
  7724. +
  7725. +        case 0: 
  7726. +        case 1: w0(1); P1; w0(1); P2; 
  7727. +        w0(2); P1; w0(0x18+pi->mode); P2; w0(0); P1;
  7728. +        udelay(10);
  7729. +        for (k=0;k<count/2;k++) {
  7730. +                        w2(5); w0(buf[2*k]); 
  7731. +            w2(7); w0(buf[2*k+1]);
  7732. +                }
  7733. +                w2(5); w2(4);
  7734. +        w0(2); P1; w0(8+pi->mode); P2;
  7735. +                break;
  7736. +
  7737. +        case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
  7738. +        w3(0); w3(0); w2(0xc5);
  7739. +        udelay(10);
  7740. +                for (k=0;k<count;k++) w4(buf[k]);
  7741. +        w2(0xc4);
  7742. +                break;
  7743. +
  7744. +        case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
  7745. +                w3(0); w3(0); w2(0xc5);
  7746. +                udelay(10);
  7747. +                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
  7748. +                w2(0xc4);
  7749. +                break;
  7750. +
  7751. +        case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
  7752. +                w3(0); w3(0); w2(0xc5);
  7753. +                udelay(10);
  7754. +                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
  7755. +                w2(0xc4);
  7756. +                break;
  7757. +
  7758. +        }
  7759. +
  7760. +}
  7761. +
  7762. +static void on26_log_adapter( PIA *pi, char * scratch, int verbose )
  7763. +
  7764. +{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8",
  7765. +                   "EPP-16","EPP-32"};
  7766. +
  7767. +        printk("%s: on26 %s, OnSpec 90c26 at 0x%x, ",
  7768. +                pi->device,ON26_VERSION,pi->port);
  7769. +        printk("mode %d (%s), delay %d\n",pi->mode,
  7770. +        mode_string[pi->mode],pi->delay);
  7771. +
  7772. +}
  7773. +
  7774. +static void on26_init_proto( PIA *pi)
  7775. +
  7776. +{       MOD_INC_USE_COUNT;
  7777. +}
  7778. +
  7779. +static void on26_release_proto( PIA *pi)
  7780. +
  7781. +{       MOD_DEC_USE_COUNT;
  7782. +}
  7783. +
  7784. +struct pi_protocol on26 = {"on26",0,5,2,1,1,
  7785. +                           on26_write_regr,
  7786. +                           on26_read_regr,
  7787. +                           on26_write_block,
  7788. +                           on26_read_block,
  7789. +                           on26_connect,
  7790. +                           on26_disconnect,
  7791. +                           0,
  7792. +                           0,
  7793. +                           0,
  7794. +                           on26_log_adapter,
  7795. +                           on26_init_proto,
  7796. +                           on26_release_proto
  7797. +                          };
  7798. +
  7799. +
  7800. +#ifdef MODULE
  7801. +
  7802. +int     init_module(void)
  7803. +
  7804. +{       return pi_register( &on26 ) - 1;
  7805. +}
  7806. +
  7807. +void    cleanup_module(void)
  7808. +
  7809. +{       pi_unregister( &on26 );
  7810. +}
  7811. +
  7812. +#endif
  7813. +
  7814. +/* end of on26.c */
  7815. +
  7816. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/paride.c linux/drivers/block/paride/paride.c
  7817. --- v2.0.34/linux/drivers/block/paride/paride.c    Wed Dec 31 16:00:00 1969
  7818. +++ linux/drivers/block/paride/paride.c    Mon Jul 13 13:47:28 1998
  7819. @@ -0,0 +1,514 @@
  7820. +/* 
  7821. +        paride.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
  7822. +                              Under the terms of the GNU public license.
  7823. +
  7824. +    This is the base module for the family of device drivers
  7825. +        that support parallel port IDE devices.  
  7826. +
  7827. +*/
  7828. +
  7829. +/* Changes:
  7830. +
  7831. +    1.01    GRG 1998.05.03    Use spinlocks
  7832. +    1.02    GRG 1998.05.05  init_proto, release_proto, ktti
  7833. +
  7834. +*/
  7835. +
  7836. +#define PI_VERSION      "1.02"
  7837. +
  7838. +#include <linux/module.h>
  7839. +#include <linux/config.h>
  7840. +#include <linux/types.h>
  7841. +#include <linux/kernel.h>
  7842. +#include <linux/ioport.h>
  7843. +#include <linux/string.h>
  7844. +#include "spinlock.h"
  7845. +
  7846. +#ifdef CONFIG_PARPORT_MODULE
  7847. +#define CONFIG_PARPORT
  7848. +#endif
  7849. +
  7850. +#ifdef CONFIG_PARPORT
  7851. +#include <linux/parport.h>
  7852. +#endif
  7853. +
  7854. +#include "paride.h"
  7855. +
  7856. +#define MAX_PROTOS    32
  7857. +
  7858. +static struct pi_protocol    *protocols[MAX_PROTOS];
  7859. +
  7860. +/* spinlock_t    pi_spinlock = SPIN_LOCK_UNLOCKED; */
  7861. +
  7862. +void pi_write_regr( PIA *pi, int cont, int regr, int val)
  7863. +
  7864. +{    pi->proto->write_regr(pi,cont,regr,val);
  7865. +}
  7866. +
  7867. +int pi_read_regr( PIA *pi, int cont, int regr)
  7868. +
  7869. +{    return pi->proto->read_regr(pi,cont,regr);
  7870. +}
  7871. +
  7872. +void pi_write_block( PIA *pi, char * buf, int count)
  7873. +
  7874. +{    pi->proto->write_block(pi,buf,count);
  7875. +}
  7876. +
  7877. +void pi_read_block( PIA *pi, char * buf, int count)
  7878. +
  7879. +{       pi->proto->read_block(pi,buf,count);
  7880. +}
  7881. +
  7882. +#ifdef CONFIG_PARPORT
  7883. +
  7884. +static void pi_wake_up( void *p)
  7885. +
  7886. +{       PIA  *pi = (PIA *) p;
  7887. +    long flags;
  7888. +    void (*cont)(void) = NULL;
  7889. +
  7890. +    spin_lock_irqsave(&pi_spinlock,flags);
  7891. +
  7892. +    if (pi->claim_cont && !parport_claim(pi->pardev)) {
  7893. +        cont = pi->claim_cont;
  7894. +        pi->claim_cont = NULL;
  7895. +        pi->claimed = 1;
  7896. +    }
  7897. +
  7898. +    spin_unlock_irqrestore(&pi_spinlock,flags);    
  7899. +
  7900. +    wake_up(&(pi->parq));
  7901. +
  7902. +    if (cont) cont();
  7903. +}
  7904. +
  7905. +#endif
  7906. +
  7907. +void pi_do_claimed( PIA *pi, void(*cont)(void))
  7908. +
  7909. +#ifdef CONFIG_PARPORT
  7910. +
  7911. +{    long flags;
  7912. +
  7913. +    spin_lock_irqsave(&pi_spinlock,flags); 
  7914. +
  7915. +    if (!pi->pardev || !parport_claim(pi->pardev)) {
  7916. +        pi->claimed = 1;
  7917. +        spin_unlock_irqrestore(&pi_spinlock,flags);
  7918. +        cont();
  7919. +    } else {
  7920. +        pi->claim_cont = cont;
  7921. +        spin_unlock_irqrestore(&pi_spinlock,flags);    
  7922. +    }
  7923. +}
  7924. +
  7925. +#else
  7926. +
  7927. +{    cont();
  7928. +}
  7929. +
  7930. +#endif
  7931. +
  7932. +static void pi_claim( PIA *pi)
  7933. +
  7934. +{    if (pi->claimed) return;
  7935. +    pi->claimed = 1;
  7936. +#ifdef CONFIG_PARPORT
  7937. +        if (pi->pardev)
  7938. +          while (parport_claim((struct pardevice *)(pi->pardev)))
  7939. +            sleep_on(&(pi->parq));
  7940. +#endif
  7941. +}
  7942. +
  7943. +static void pi_unclaim( PIA *pi)
  7944. +
  7945. +{    pi->claimed = 0;
  7946. +#ifdef CONFIG_PARPORT
  7947. +        if (pi->pardev) parport_release((struct pardevice *)(pi->pardev));
  7948. +#endif 
  7949. +}
  7950. +
  7951. +void pi_connect( PIA *pi)
  7952. +
  7953. +{    pi_claim(pi);
  7954. +    pi->proto->connect(pi);
  7955. +}
  7956. +
  7957. +void pi_disconnect( PIA *pi)
  7958. +
  7959. +{    pi->proto->disconnect(pi);
  7960. +    pi_unclaim(pi);
  7961. +}
  7962. +
  7963. +static void pi_unregister_parport( PIA *pi)
  7964. +
  7965. +{
  7966. +#ifdef CONFIG_PARPORT
  7967. +        if (pi->pardev) {
  7968. +           parport_unregister_device((struct pardevice *)(pi->pardev));
  7969. +       pi->pardev = NULL;
  7970. +    }
  7971. +#endif
  7972. +}
  7973. +
  7974. +void pi_release( PIA *pi)
  7975. +
  7976. +{    pi_unregister_parport(pi);
  7977. +    if ((!pi->pardev)&&(pi->reserved)) 
  7978. +        release_region(pi->port,pi->reserved);
  7979. +    pi->proto->release_proto(pi);
  7980. +}
  7981. +
  7982. +#define WR(r,v)         pi_write_regr(pi,0,r,v)
  7983. +#define RR(r)           (pi_read_regr(pi,0,r))
  7984. +
  7985. +static int pi_test_proto( PIA *pi, char * scratch, int verbose )
  7986. +
  7987. +{       int     j, k;
  7988. +        int     e[2] = {0,0};
  7989. +
  7990. +    if (pi->proto->test_proto) {
  7991. +        pi_claim(pi);
  7992. +        j = pi->proto->test_proto(pi,scratch,verbose);
  7993. +        pi_unclaim(pi);
  7994. +        return j;
  7995. +    }
  7996. +
  7997. +        pi_connect(pi);
  7998. +
  7999. +        for (j=0;j<2;j++) {
  8000. +                WR(6,0xa0+j*0x10);
  8001. +                for (k=0;k<256;k++) {
  8002. +                        WR(2,k^0xaa);
  8003. +                        WR(3,k^0x55);
  8004. +                        if (RR(2) != (k^0xaa)) e[j]++;
  8005. +                        }
  8006. +                }
  8007. +
  8008. +        pi_disconnect(pi);
  8009. +
  8010. +        if (verbose)
  8011. +                printk("%s: %s: port 0x%x, mode  %d, test=(%d,%d)\n",
  8012. +                        pi->device,pi->proto->name,pi->port,
  8013. +            pi->mode,e[0],e[1]);
  8014. +
  8015. +        return (e[0] && e[1]);  /* not here if both > 0 */
  8016. +}
  8017. +
  8018. +int  pi_register( PIP *pr)
  8019. +
  8020. +{    int k;
  8021. +
  8022. +    for (k=0;k<MAX_PROTOS;k++) 
  8023. +       if (protocols[k] && !strcmp(pr->name,protocols[k]->name)) {
  8024. +        printk("paride: %s protocol already registered\n",pr->name);
  8025. +        return 0;
  8026. +       }
  8027. +    k = 0;
  8028. +    while((k<MAX_PROTOS) && (protocols[k])) k++;
  8029. +    if (k == MAX_PROTOS) {
  8030. +        printk("paride: protocol table full\n");
  8031. +        return 0;
  8032. +    }
  8033. +    MOD_INC_USE_COUNT;
  8034. +    protocols[k] = pr;
  8035. +    pr->index = k;
  8036. +    printk("paride: %s registered as protocol %d\n",pr->name,k);
  8037. +    return 1;
  8038. +}    
  8039. +
  8040. +void pi_unregister( PIP *pr)
  8041. +
  8042. +{    if (!pr) return;
  8043. +    if (protocols[pr->index] != pr) {
  8044. +        printk("paride: %s not registered\n",pr->name);
  8045. +        return;
  8046. +    } 
  8047. +    protocols[pr->index] = 0;
  8048. +    MOD_DEC_USE_COUNT;
  8049. +}
  8050. +
  8051. +static void pi_register_parport( PIA *pi, int verbose)
  8052. +
  8053. +{
  8054. +#ifdef CONFIG_PARPORT
  8055. +
  8056. +    struct parport    *pp;
  8057. +
  8058. +    pp = parport_enumerate();
  8059. +
  8060. +    while((pp)&&(pp->base != pi->port)) pp = pp->next;
  8061. +
  8062. +    if (!pp) return;
  8063. +
  8064. +    pi->pardev = (void *) parport_register_device(
  8065. +          pp,pi->device,NULL,pi_wake_up,NULL,0,(void *)pi);
  8066. +
  8067. +    pi->parq = NULL;
  8068. +
  8069. +    if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port,pp->name);
  8070. +    
  8071. +    pi->parname = pp->name;
  8072. +
  8073. +#endif
  8074. +}
  8075. +
  8076. +static int pi_probe_mode( PIA *pi, int max, char * scratch, int verbose)
  8077. +
  8078. +{    int    best, range;
  8079. +
  8080. +    if (pi->mode != -1) {
  8081. +        if (pi->mode >= max) return 0;
  8082. +        range = 3;
  8083. +        if (pi->mode >= pi->proto->epp_first) range = 8;
  8084. +        if ((range == 8) && (pi->port % 8)) return 0;
  8085. +        if ((!pi->pardev) && check_region(pi->port,range)) return 0;
  8086. +        pi->reserved = range;
  8087. +        return (!pi_test_proto(pi,scratch,verbose));
  8088. +    }
  8089. +    best = -1;
  8090. +    for(pi->mode=0;pi->mode<max;pi->mode++) {
  8091. +        range = 3;
  8092. +        if (pi->mode >= pi->proto->epp_first) range = 8;
  8093. +        if ((range == 8) && (pi->port % 8)) break;
  8094. +        if ((!pi->pardev) && check_region(pi->port,range)) break;
  8095. +        pi->reserved = range;
  8096. +        if (!pi_test_proto(pi,scratch,verbose)) best = pi->mode;
  8097. +    }
  8098. +    pi->mode = best;
  8099. +    return (best > -1);
  8100. +}
  8101. +
  8102. +static int pi_probe_unit( PIA *pi, int unit, char * scratch, int verbose)
  8103. +
  8104. +{    int max,s,e;
  8105. +
  8106. +    s = unit; e = s+1;
  8107. +
  8108. +    if (s == -1) { 
  8109. +        s = 0; 
  8110. +        e = pi->proto->max_units; 
  8111. +    }
  8112. +
  8113. +    pi_register_parport(pi,verbose);
  8114. +
  8115. +    if ((!pi->pardev) && check_region(pi->port,3)) return 0;
  8116. +
  8117. +    if (pi->proto->test_port) {
  8118. +        pi_claim(pi);
  8119. +        max = pi->proto->test_port(pi);
  8120. +        pi_unclaim(pi);
  8121. +    }
  8122. +    else max = pi->proto->max_mode;
  8123. +
  8124. +    if (pi->proto->probe_unit) {
  8125. +       pi_claim(pi);
  8126. +       for (pi->unit=s;pi->unit<e;pi->unit++)
  8127. +          if (pi->proto->probe_unit(pi)) {
  8128. +         pi_unclaim(pi);
  8129. +         if (pi_probe_mode(pi,max,scratch,verbose)) return 1;
  8130. +             pi_unregister_parport(pi); 
  8131. +         return 0;
  8132. +             }
  8133. +       pi_unclaim(pi);
  8134. +       pi_unregister_parport(pi); 
  8135. +       return 0;
  8136. +       }
  8137. +
  8138. +    if (!pi_probe_mode(pi,max,scratch,verbose)) {
  8139. +       pi_unregister_parport(pi); 
  8140. +       return 0;
  8141. +    }
  8142. +    return 1;
  8143. +        
  8144. +}
  8145. +
  8146. +int pi_init(PIA *pi, int autoprobe, int port, int mode, 
  8147. +        int unit, int protocol, int delay, char * scratch, 
  8148. +        int devtype, int verbose, char *device )
  8149. +
  8150. +{    int p,k,s,e;
  8151. +    int lpts[7] = {0x3bc,0x378,0x278,0x268,0x27c,0x26c,0};
  8152. +
  8153. +    s = protocol; e = s+1;
  8154. +
  8155. +    if (autoprobe) {
  8156. +        s = 0; 
  8157. +        e = MAX_PROTOS;
  8158. +    } else if ((s < 0) || (s >= MAX_PROTOS) || (port <= 0) ||
  8159. +            (!protocols[s]) || (unit < 0) || 
  8160. +            (unit >= protocols[s]->max_units)) {
  8161. +            printk("%s: Invalid parameters\n",device);
  8162. +            return 0;
  8163. +                }
  8164. +
  8165. +    for (p=s;p<e;p++) {
  8166. +      if (protocols[p]) {
  8167. +        pi->proto = protocols[p];
  8168. +        pi->private = 0;
  8169. +        pi->proto->init_proto(pi);
  8170. +        if (delay == -1) pi->delay = pi->proto->default_delay;
  8171. +          else pi->delay = delay;
  8172. +        pi->devtype = devtype;
  8173. +        pi->device = device;
  8174. +
  8175. +        pi->parname = NULL;
  8176. +        pi->pardev = NULL;
  8177. +        pi->parq = NULL;
  8178. +        pi->claimed = 0;
  8179. +        pi->claim_cont = NULL;
  8180. +            
  8181. +        pi->mode = mode;
  8182. +        if (port != -1) {
  8183. +            pi->port = port;
  8184. +            if (pi_probe_unit(pi,unit,scratch,verbose)) break;
  8185. +            pi->port = 0;
  8186. +        } else { 
  8187. +            k = 0;
  8188. +            while ((pi->port = lpts[k++]))
  8189. +               if (pi_probe_unit(pi,unit,scratch,verbose)) break;
  8190. +                  if (pi->port) break;
  8191. +        }
  8192. +        pi->proto->release_proto(pi);
  8193. +      }
  8194. +    }
  8195. +
  8196. +    if (!pi->port) {
  8197. +        if (autoprobe) printk("%s: Autoprobe failed\n",device);
  8198. +        else printk("%s: Adapter not found\n",device);
  8199. +        return 0;
  8200. +    }
  8201. +
  8202. +    if (!pi->pardev)
  8203. +       request_region(pi->port,pi->reserved,pi->device);
  8204. +
  8205. +    if (pi->parname)
  8206. +       printk("%s: Sharing %s at 0x%x\n",pi->device,
  8207. +            pi->parname,pi->port);
  8208. +
  8209. +    pi->proto->log_adapter(pi,scratch,verbose);
  8210. +
  8211. +    return 1;
  8212. +}
  8213. +
  8214. +#ifdef MODULE
  8215. +
  8216. +int    init_module(void)
  8217. +
  8218. +{    int k;
  8219. +
  8220. +    for (k=0;k<MAX_PROTOS;k++) protocols[k] = 0;
  8221. +    printk("paride: version %s installed\n",PI_VERSION);
  8222. +    return 0;
  8223. +}
  8224. +
  8225. +void    cleanup_module(void)
  8226. +
  8227. +{
  8228. +}
  8229. +
  8230. +#else
  8231. +
  8232. +void    paride_init( void )
  8233. +
  8234. +{
  8235. +
  8236. +#ifdef CONFIG_PARIDE_ATEN
  8237. +    { extern struct pi_protocol aten;
  8238. +      pi_register(&aten);
  8239. +    };
  8240. +#endif
  8241. +#ifdef CONFIG_PARIDE_BPCK
  8242. +        { extern struct pi_protocol bpck;
  8243. +          pi_register(&bpck);
  8244. +        };
  8245. +#endif
  8246. +#ifdef CONFIG_PARIDE_COMM
  8247. +        { extern struct pi_protocol comm;
  8248. +          pi_register(&comm);
  8249. +        };
  8250. +#endif
  8251. +#ifdef CONFIG_PARIDE_DSTR
  8252. +        { extern struct pi_protocol dstr;
  8253. +          pi_register(&dstr);
  8254. +        };
  8255. +#endif
  8256. +#ifdef CONFIG_PARIDE_EPAT
  8257. +        { extern struct pi_protocol epat;
  8258. +          pi_register(&epat);
  8259. +        };
  8260. +#endif
  8261. +#ifdef CONFIG_PARIDE_EPIA
  8262. +        { extern struct pi_protocol epia;
  8263. +          pi_register(&epia);
  8264. +        };
  8265. +#endif
  8266. +#ifdef CONFIG_PARIDE_FRPW
  8267. +        { extern struct pi_protocol frpw;
  8268. +          pi_register(&frpw);
  8269. +        };
  8270. +#endif
  8271. +#ifdef CONFIG_PARIDE_FIT2
  8272. +        { extern struct pi_protocol fit2;
  8273. +          pi_register(&fit2);
  8274. +        };
  8275. +#endif
  8276. +#ifdef CONFIG_PARIDE_FIT3
  8277. +        { extern struct pi_protocol fit3;
  8278. +          pi_register(&fit3);
  8279. +        };
  8280. +#endif
  8281. +#ifdef CONFIG_PARIDE_KBIC
  8282. +        { extern struct pi_protocol k951;
  8283. +          extern struct pi_protocol k971;
  8284. +          pi_register(&k951);
  8285. +          pi_register(&k971);
  8286. +        };
  8287. +#endif
  8288. +#ifdef CONFIG_PARIDE_KTTI
  8289. +        { extern struct pi_protocol ktti;
  8290. +          pi_register(&ktti);
  8291. +        };
  8292. +#endif
  8293. +#ifdef CONFIG_PARIDE_ON20
  8294. +        { extern struct pi_protocol on20;
  8295. +          pi_register(&on20);
  8296. +        };
  8297. +#endif
  8298. +#ifdef CONFIG_PARIDE_ON26
  8299. +        { extern struct pi_protocol on26;
  8300. +          pi_register(&on26);
  8301. +        };
  8302. +#endif
  8303. +
  8304. +#ifdef CONFIG_PARIDE_PD
  8305. +    { extern int pd_init(void);
  8306. +      pd_init();
  8307. +    };
  8308. +#endif
  8309. +#ifdef CONFIG_PARIDE_PCD
  8310. +        { extern int pcd_init(void);
  8311. +          pcd_init();
  8312. +        };
  8313. +#endif
  8314. +#ifdef CONFIG_PARIDE_PF
  8315. +        { extern int pf_init(void);
  8316. +          pf_init();
  8317. +        };
  8318. +#endif
  8319. +#ifdef CONFIG_PARIDE_PT
  8320. +        { extern int pt_init(void);
  8321. +          pt_init();
  8322. +        };
  8323. +#endif
  8324. +#ifdef CONFIG_PARIDE_PG
  8325. +        { extern int pg_init(void);
  8326. +          pg_init();
  8327. +        };
  8328. +#endif
  8329. +}
  8330. +
  8331. +#endif
  8332. +
  8333. +/* end of paride.c */
  8334. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/paride.h linux/drivers/block/paride/paride.h
  8335. --- v2.0.34/linux/drivers/block/paride/paride.h    Wed Dec 31 16:00:00 1969
  8336. +++ linux/drivers/block/paride/paride.h    Mon Jul 13 13:47:28 1998
  8337. @@ -0,0 +1,164 @@
  8338. +/* 
  8339. +    paride.h    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  8340. +                               Under the terms of the GPL.
  8341. +
  8342. +   This file defines the interface between the high-level parallel
  8343. +   IDE device drivers (pd, pf, pcd, pt) and the adapter chips.
  8344. +
  8345. +*/
  8346. +
  8347. +/* Changes:
  8348. +
  8349. +    1.01    GRG 1998.05.05    init_proto, release_proto
  8350. +*/
  8351. +
  8352. +#define PARIDE_H_VERSION     "1.01"
  8353. +
  8354. +/* Some adapters need to know what kind of device they are in
  8355. +
  8356. +   Values for devtype:
  8357. +*/
  8358. +
  8359. +#define    PI_PD    0    /* IDE disk */
  8360. +#define PI_PCD    1    /* ATAPI CDrom */
  8361. +#define PI_PF   2    /* ATAPI disk */
  8362. +#define PI_PT    3    /* ATAPI tape */
  8363. +#define PI_PG   4       /* ATAPI generic */
  8364. +
  8365. +/* The paride module contains no state, instead the drivers allocate
  8366. +   a pi_adapter data structure and pass it to paride in every operation.
  8367. +
  8368. +*/
  8369. +
  8370. +struct pi_adapter  {
  8371. +
  8372. +    struct pi_protocol *proto;   /* adapter protocol */
  8373. +    int    port;             /* base address of parallel port */
  8374. +    int    mode;             /* transfer mode in use */
  8375. +    int     delay;             /* adapter delay setting */
  8376. +    int    devtype;         /* device type: PI_PD etc. */
  8377. +    char    *device;         /* name of driver */
  8378. +    int     unit;             /* unit number for chained adapters */
  8379. +    int    saved_r0;         /* saved port state */
  8380. +    int    saved_r2;         /* saved port state */
  8381. +    int    reserved;         /* number of ports reserved */
  8382. +    int    private;         /* for protocol module */
  8383. +
  8384. +    struct wait_queue *parq;     /* semaphore for parport sharing */
  8385. +    void    *pardev;         /* pointer to pardevice */
  8386. +    char    *parname;         /* parport name */
  8387. +    int    claimed;         /* parport has already been claimed */
  8388. +    void (*claim_cont)(void);    /* continuation for parport wait */
  8389. +};
  8390. +
  8391. +typedef struct pi_adapter PIA;
  8392. +
  8393. +/* functions exported by paride to the high level drivers */
  8394. +
  8395. +extern int pi_init(PIA *pi, 
  8396. +    int autoprobe,        /* 1 to autoprobe */
  8397. +    int port,         /* base port address */
  8398. +    int mode,         /* -1 for autoprobe */
  8399. +    int unit,        /* unit number, if supported */
  8400. +    int protocol,         /* protocol to use */
  8401. +    int delay,         /* -1 to use adapter specific default */
  8402. +    char * scratch,     /* address of 512 byte buffer */
  8403. +    int devtype,        /* device type: PI_PD, PI_PCD, etc ... */
  8404. +    int verbose,        /* log verbose data while probing */
  8405. +    char *device        /* name of the driver */
  8406. +    );            /* returns 0 on failure, 1 on success */
  8407. +
  8408. +extern void pi_release(PIA *pi);
  8409. +
  8410. +/* registers are addressed as (cont,regr)
  8411. +
  8412. +           cont: 0 for command register file, 1 for control register(s)
  8413. +    regr: 0-7 for register number.
  8414. +
  8415. +*/
  8416. +
  8417. +extern void pi_write_regr(PIA *pi, int cont, int regr, int val);
  8418. +
  8419. +extern int pi_read_regr(PIA *pi, int cont, int regr);
  8420. +
  8421. +extern void pi_write_block(PIA *pi, char * buf, int count);
  8422. +
  8423. +extern void pi_read_block(PIA *pi, char * buf, int count);
  8424. +
  8425. +extern void pi_connect(PIA *pi);
  8426. +
  8427. +extern void pi_disconnect(PIA *pi);
  8428. +
  8429. +extern void pi_do_claimed(PIA *pi, void (*cont)(void));
  8430. +
  8431. +/* macros and functions exported to the protocol modules */
  8432. +
  8433. +#define delay_p            (pi->delay?udelay(pi->delay):0)
  8434. +#define out_p(offs,byte)    outb(byte,pi->port+offs); delay_p;
  8435. +#define in_p(offs)        (delay_p,inb(pi->port+offs))
  8436. +
  8437. +#define w0(byte)                {out_p(0,byte);}
  8438. +#define r0()                    (in_p(0) & 0xff)
  8439. +#define w1(byte)                {out_p(1,byte);}
  8440. +#define r1()                    (in_p(1) & 0xff)
  8441. +#define w2(byte)                {out_p(2,byte);}
  8442. +#define r2()                    (in_p(2) & 0xff)
  8443. +#define w3(byte)                {out_p(3,byte);}
  8444. +#define w4(byte)                {out_p(4,byte);}
  8445. +#define r4()                    (in_p(4) & 0xff)
  8446. +#define w4w(data)             {outw(data,pi->port+4); delay_p;}
  8447. +#define w4l(data)             {outl(data,pi->port+4); delay_p;}
  8448. +#define r4w()                 (delay_p,inw(pi->port+4)&0xffff)
  8449. +#define r4l()                 (delay_p,inl(pi->port+4)&0xffffffff)
  8450. +
  8451. +static inline u16 pi_swab16( char *b, int k)
  8452. +
  8453. +{     union { u16 u; char t[2]; } r;
  8454. +
  8455. +    r.t[0]=b[2*k+1]; r.t[1]=b[2*k];
  8456. +        return r.u;
  8457. +}
  8458. +
  8459. +static inline u32 pi_swab32( char *b, int k)
  8460. +
  8461. +{     union { u32 u; char f[4]; } r;
  8462. +
  8463. +    r.f[0]=b[4*k+1]; r.f[1]=b[4*k];
  8464. +    r.f[2]=b[4*k+3]; r.f[3]=b[4*k+2];
  8465. +        return r.u;
  8466. +}
  8467. +
  8468. +struct pi_protocol {
  8469. +
  8470. +    char    name[8];    /* name for this protocol */
  8471. +    int    index;        /* index into protocol table */
  8472. +
  8473. +    int    max_mode;    /* max mode number */
  8474. +    int    epp_first;    /* modes >= this use 8 ports */
  8475. +    
  8476. +    int    default_delay;  /* delay parameter if not specified */
  8477. +    int    max_units;    /* max chained units probed for */
  8478. +
  8479. +    void (*write_regr)(PIA *,int,int,int);
  8480. +    int  (*read_regr)(PIA *,int,int);
  8481. +    void (*write_block)(PIA *,char *,int);
  8482. +    void (*read_block)(PIA *,char *,int);
  8483. +
  8484. +    void (*connect)(PIA *);
  8485. +    void (*disconnect)(PIA *);
  8486. +    
  8487. +    int  (*test_port)(PIA *);
  8488. +    int  (*probe_unit)(PIA *);
  8489. +    int  (*test_proto)(PIA *,char *,int);
  8490. +    void (*log_adapter)(PIA *,char *,int);
  8491. +    
  8492. +    void (*init_proto)(PIA *);
  8493. +    void (*release_proto)(PIA *);
  8494. +};
  8495. +
  8496. +typedef struct pi_protocol PIP;
  8497. +
  8498. +extern int pi_register( PIP * );
  8499. +extern void pi_unregister ( PIP * );
  8500. +
  8501. +/* end of paride.h */
  8502. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/pcd.c linux/drivers/block/paride/pcd.c
  8503. --- v2.0.34/linux/drivers/block/paride/pcd.c    Wed Dec 31 16:00:00 1969
  8504. +++ linux/drivers/block/paride/pcd.c    Mon Jul 13 13:47:28 1998
  8505. @@ -0,0 +1,807 @@
  8506. +/* 
  8507. +    pcd.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  8508. +                    Under the terms of the GNU public license.
  8509. +
  8510. +
  8511. +    Special 2.0.34 version
  8512. +
  8513. +
  8514. +    This is high-level driver for parallel port ATAPI CDrom
  8515. +        drives based on chips supported by the paride module.
  8516. +
  8517. +        By default, the driver will autoprobe for a single parallel
  8518. +        port ATAPI CDrom drive, but if their individual parameters are
  8519. +        specified, the driver can handle up to 4 drives.
  8520. +
  8521. +        The behaviour of the pcd driver can be altered by setting
  8522. +        some parameters from the insmod command line.  The following
  8523. +        parameters are adjustable:
  8524. +
  8525. +            drive0      These four arguments can be arrays of       
  8526. +            drive1      1-6 integers as follows:
  8527. +            drive2
  8528. +            drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
  8529. +
  8530. +                        Where,
  8531. +
  8532. +                <prt>   is the base of the parallel port address for
  8533. +                        the corresponding drive.  (required)
  8534. +
  8535. +                <pro>   is the protocol number for the adapter that
  8536. +                        supports this drive.  These numbers are
  8537. +                        logged by 'paride' when the protocol modules
  8538. +                        are initialised.  (0 if not given)
  8539. +
  8540. +                <uni>   for those adapters that support chained
  8541. +                        devices, this is the unit selector for the
  8542. +                        chain of devices on the given port.  It should
  8543. +                        be zero for devices that don't support chaining.
  8544. +                        (0 if not given)
  8545. +
  8546. +                <mod>   this can be -1 to choose the best mode, or one
  8547. +                        of the mode numbers supported by the adapter.
  8548. +                        (-1 if not given)
  8549. +
  8550. +        <slv>   ATAPI CDroms can be jumpered to master or slave.
  8551. +            Set this to 0 to choose the master drive, 1 to
  8552. +                        choose the slave, -1 (the default) to choose the
  8553. +            first drive found.
  8554. +
  8555. +                <dly>   some parallel ports require the driver to 
  8556. +                        go more slowly.  -1 sets a default value that
  8557. +                        should work with the chosen protocol.  Otherwise,
  8558. +                        set this to a small integer, the larger it is
  8559. +                        the slower the port i/o.  In some cases, setting
  8560. +                        this to zero will speed up the device. (default -1)
  8561. +                        
  8562. +            major       You may use this parameter to overide the
  8563. +                        default major number (46) that this driver
  8564. +                        will use.  Be sure to change the device
  8565. +                        name as well.
  8566. +
  8567. +            name        This parameter is a character string that
  8568. +                        contains the name the kernel will use for this
  8569. +                        device (in /proc output, for instance).
  8570. +                        (default "pcd")
  8571. +
  8572. +            verbose     This parameter controls the amount of logging
  8573. +                        that is done while the driver probes for
  8574. +                        devices.  Set it to 0 for a quiet load, or 1 to
  8575. +                        see all the progress messages.  (default 0)
  8576. +
  8577. +            nice        This parameter controls the driver's use of
  8578. +                        idle CPU time, at the expense of some speed.
  8579. +    If this driver is built into the kernel, you can use kernel
  8580. +        the following command line parameters, with the same values
  8581. +        as the corresponding module parameters listed above:
  8582. +
  8583. +        pcd.drive0
  8584. +        pcd.drive1
  8585. +        pcd.drive2
  8586. +        pcd.drive3
  8587. +        pcd.nice
  8588. +
  8589. +        In addition, you can use the parameter pcd.disable to disable
  8590. +        the driver entirely.
  8591. +
  8592. +*/
  8593. +
  8594. +/* Changes:
  8595. +
  8596. +    1.01    GRG 1997.01.24    Added test unit ready support
  8597. +    1.02    GRG 1998.05.06  Changes to pcd_completion, ready_wait,
  8598. +                and loosen interpretation of ATAPI
  8599. +                    standard for clearing error status.
  8600. +                Use spinlocks. Eliminate sti().
  8601. +    1.03    GRG 1998.06.16  Eliminated an Ugh
  8602. +
  8603. +*/
  8604. +
  8605. +#define    PCD_VERSION    "1.03s"
  8606. +#define PCD_MAJOR    46
  8607. +#define PCD_NAME    "pcd"
  8608. +#define PCD_UNITS    4
  8609. +
  8610. +/* Here are things one can override from the insmod command.
  8611. +   Most are autoprobed by paride unless set here.  Verbose is off
  8612. +   by default.
  8613. +
  8614. +*/
  8615. +
  8616. +static int      verbose = 0;
  8617. +static int      major = PCD_MAJOR;
  8618. +static char     *name = PCD_NAME;
  8619. +static int      nice = 0;
  8620. +static int      disable = 0;
  8621. +
  8622. +static int drive0[6] = {0,0,0,-1,-1,-1};
  8623. +static int drive1[6] = {0,0,0,-1,-1,-1};
  8624. +static int drive2[6] = {0,0,0,-1,-1,-1};
  8625. +static int drive3[6] = {0,0,0,-1,-1,-1};
  8626. +
  8627. +static int (*drives[4])[6] = {&drive0,&drive1,&drive2,&drive3};
  8628. +static int pcd_drive_count;
  8629. +
  8630. +#define D_PRT   0
  8631. +#define D_PRO   1
  8632. +#define D_UNI   2
  8633. +#define D_MOD   3
  8634. +#define D_SLV   4
  8635. +#define D_DLY   5
  8636. +
  8637. +#define DU              (*drives[unit])
  8638. +
  8639. +/* end of parameters */
  8640. +
  8641. +#include <linux/module.h>
  8642. +#include <linux/errno.h>
  8643. +#include <linux/fs.h>
  8644. +#include <linux/kernel.h>
  8645. +#include <linux/delay.h>
  8646. +#include <linux/cdrom.h>
  8647. +
  8648. +#include <asm/segment.h>
  8649. +#include "spinlock.h"
  8650. +
  8651. +#ifndef MODULE
  8652. +
  8653. +#include "setup.h"
  8654. +
  8655. +static STT pcd_stt[6] = {{"drive0",6,drive0},
  8656. +                         {"drive1",6,drive1},
  8657. +                         {"drive2",6,drive2},
  8658. +                         {"drive3",6,drive3},
  8659. +             {"disable",1,&disable},
  8660. +                         {"nice",1,&nice}};
  8661. +
  8662. +void pcd_setup( char *str, int *ints)
  8663. +
  8664. +{       generic_setup(pcd_stt,6,str);
  8665. +}
  8666. +
  8667. +#endif
  8668. +
  8669. +#include "paride.h"
  8670. +
  8671. +/* set up defines for blk.h,  why don't all drivers do it this way ? */
  8672. +
  8673. +#define MAJOR_NR    major
  8674. +#define DEVICE_NAME "PCD"
  8675. +#define DEVICE_REQUEST do_pcd_request
  8676. +#define DEVICE_NR(device) (MINOR(device))
  8677. +#define DEVICE_ON(device)
  8678. +#define DEVICE_OFF(device)
  8679. +
  8680. +#include <linux/blk.h>
  8681. +
  8682. +#include "pseudo.h"
  8683. +
  8684. +#define PCD_RETRIES         5
  8685. +#define PCD_TMO           800        /* timeout in jiffies */
  8686. +#define PCD_DELAY           50          /* spin delay in uS */
  8687. +#define PCD_READY_TMO        20
  8688. +
  8689. +#define PCD_SPIN        (10000/PCD_DELAY)*PCD_TMO
  8690. +
  8691. +#define IDE_ERR        0x01
  8692. +#define IDE_DRQ         0x08
  8693. +#define IDE_READY       0x40
  8694. +#define IDE_BUSY        0x80
  8695. +
  8696. +int pcd_init(void);
  8697. +void cleanup_module( void );
  8698. +
  8699. +static int     pcd_open(struct inode *inode, struct file *file);
  8700. +static void     do_pcd_request(void);
  8701. +static void     do_pcd_read(void);
  8702. +static int     pcd_ioctl(struct inode *inode,struct file *file,
  8703. +                         unsigned int cmd, unsigned long arg);
  8704. +
  8705. +static void pcd_release (struct inode *inode, struct file *file);
  8706. +
  8707. +static int     pcd_detect(void);
  8708. +static void     pcd_lock(int unit);
  8709. +static void     pcd_unlock(int unit);
  8710. +static void     pcd_eject(int unit);
  8711. +static int      pcd_check_media(int unit);
  8712. +static void     do_pcd_read_drq(void);
  8713. +
  8714. +static int pcd_blocksizes[PCD_UNITS];
  8715. +
  8716. +#define PCD_NAMELEN    8
  8717. +
  8718. +struct pcd_unit {
  8719. +    struct pi_adapter pia;    /* interface to paride layer */
  8720. +    struct pi_adapter *pi;
  8721. +    int drive;        /* master/slave */
  8722. +    int last_sense;        /* result of last request sense */
  8723. +    int access;        /* count of active opens */
  8724. +    int present;        /* does this unit exist ? */
  8725. +    char name[PCD_NAMELEN];    /* pcd0, pcd1, etc */
  8726. +    };
  8727. +
  8728. +struct pcd_unit pcd[PCD_UNITS];
  8729. +
  8730. +/*  'unit' must be defined in all functions - either as a local or a param */
  8731. +
  8732. +#define PCD pcd[unit]
  8733. +#define PI PCD.pi
  8734. +
  8735. +static char pcd_scratch[64];
  8736. +static char pcd_buffer[2048];           /* raw block buffer */
  8737. +static int pcd_bufblk = -1;             /* block in buffer, in CD units,
  8738. +                                           -1 for nothing there. See also
  8739. +                       pd_unit.
  8740. +                     */
  8741. +
  8742. +/* the variables below are used mainly in the I/O request engine, which
  8743. +   processes only one request at a time.
  8744. +*/
  8745. +
  8746. +static int pcd_unit = -1;        /* unit of current request & bufblk */
  8747. +static int pcd_retries;            /* retries on current request */
  8748. +static int pcd_busy = 0;        /* request being processed ? */
  8749. +static int pcd_sector;            /* address of next requested sector */
  8750. +static int pcd_count;            /* number of blocks still to do */
  8751. +static char * pcd_buf;            /* buffer for request in progress */
  8752. +
  8753. +/* kernel glue structures */
  8754. +
  8755. +static struct file_operations pcd_fops = {
  8756. +    NULL,            /* lseek - default */
  8757. +    block_read,        /* read - general block-dev read */
  8758. +    block_write,        /* write - general block-dev write */
  8759. +    NULL,            /* readdir - bad */
  8760. +    NULL,            /* select */
  8761. +    pcd_ioctl,        /* ioctl */
  8762. +    NULL,            /* mmap */
  8763. +    pcd_open,        /* open */
  8764. +    pcd_release,        /* release */
  8765. +    block_fsync,        /* fsync */
  8766. +    NULL,            /* fasync */
  8767. +    NULL,                   /* media change ? */
  8768. +    NULL            /* revalidate new media */
  8769. +};
  8770. +
  8771. +static void pcd_init_units( void )
  8772. +
  8773. +{       int     unit, j;
  8774. +
  8775. +        pcd_drive_count = 0;
  8776. +        for (unit=0;unit<PCD_UNITS;unit++) {
  8777. +                PCD.pi = & PCD.pia;
  8778. +                PCD.access = 0;
  8779. +                PCD.present = 0;
  8780. +        PCD.last_sense = 0;
  8781. +                j = 0;
  8782. +                while ((j < PCD_NAMELEN-2) && (PCD.name[j]=name[j])) j++;
  8783. +                PCD.name[j++] = '0' + unit;
  8784. +                PCD.name[j] = 0;
  8785. +                PCD.drive = DU[D_SLV];
  8786. +                if (DU[D_PRT]) pcd_drive_count++;
  8787. +        }
  8788. +}
  8789. +
  8790. +int pcd_init (void)    /* preliminary initialisation */
  8791. +
  8792. +{       int     i;
  8793. +
  8794. +    if (disable) return -1;
  8795. +
  8796. +    pcd_init_units();
  8797. +
  8798. +    if (pcd_detect()) return -1;
  8799. +
  8800. +    if (register_blkdev(MAJOR_NR,name,&pcd_fops)) {
  8801. +        printk("pcd: unable to get major number %d\n",MAJOR_NR);
  8802. +        return -1;
  8803. +    }
  8804. +    blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
  8805. +    read_ahead[MAJOR_NR] = 8;    /* 8 sector (4kB) read ahead */
  8806. +
  8807. +    for (i=0;i<PCD_UNITS;i++) pcd_blocksizes[i] = 1024;
  8808. +        blksize_size[MAJOR_NR] = pcd_blocksizes;
  8809. +
  8810. +    return 0;
  8811. +}
  8812. +
  8813. +static int pcd_open (struct inode *inode, struct file *file)
  8814. +
  8815. +{    int unit = DEVICE_NR(inode->i_rdev);
  8816. +
  8817. +    if  ((unit >= PCD_UNITS) || (!PCD.present)) return -ENODEV;
  8818. +
  8819. +    if (file->f_mode & 2) return -EROFS;  /* wants to write ? */
  8820. +
  8821. +    MOD_INC_USE_COUNT;
  8822. +
  8823. +    if (pcd_check_media(unit)) {
  8824. +        MOD_DEC_USE_COUNT;
  8825. +        return -ENXIO;
  8826. +    }
  8827. +
  8828. +    pcd_lock(unit);
  8829. +
  8830. +    PCD.access++;
  8831. +    return 0;
  8832. +}
  8833. +
  8834. +static void do_pcd_request (void)
  8835. +
  8836. +{       int unit;
  8837. +
  8838. +    if (pcd_busy) return;
  8839. +        while (1) {
  8840. +        if ((!CURRENT) || (CURRENT->rq_status == RQ_INACTIVE)) return;
  8841. +        INIT_REQUEST;
  8842. +        if (CURRENT->cmd == READ) {
  8843. +        unit = MINOR(CURRENT->rq_dev);
  8844. +        if (unit != pcd_unit) {
  8845. +            pcd_bufblk = -1;
  8846. +            pcd_unit = unit;
  8847. +        }
  8848. +            pcd_sector = CURRENT->sector;
  8849. +            pcd_count = CURRENT->nr_sectors;
  8850. +            pcd_buf = CURRENT->buffer;
  8851. +        pcd_busy = 1;
  8852. +            ps_set_intr(do_pcd_read,0,0,nice); 
  8853. +        return;
  8854. +        } 
  8855. +        else end_request(0);
  8856. +    }
  8857. +}
  8858. +
  8859. +static int pcd_ioctl(struct inode *inode,struct file *file,
  8860. +            unsigned int cmd, unsigned long arg)
  8861. +
  8862. +/* we currently support only the EJECT ioctl. */
  8863. +
  8864. +{    int unit = DEVICE_NR(inode->i_rdev);
  8865. +    if  ((unit >= PCD_UNITS) || (!PCD.present)) return -ENODEV;
  8866. +
  8867. +    switch (cmd) {
  8868. +            case CDROMEJECT: if (PCD.access == 1) {
  8869. +                pcd_eject(unit);
  8870. +                return 0;
  8871. +                 }
  8872. +        default:
  8873. +            return -EINVAL;
  8874. +    }
  8875. +}
  8876. +
  8877. +static void pcd_release (struct inode *inode, struct file *file)
  8878. +
  8879. +{    kdev_t    devp;
  8880. +    int     unit;
  8881. +
  8882. +    devp = inode->i_rdev;
  8883. +    unit = DEVICE_NR(devp);
  8884. +
  8885. +    if  ((unit >= PCD_UNITS) || (PCD.access <= 0)) 
  8886. +            return;
  8887. +       
  8888. +    PCD.access--;
  8889. +
  8890. +    if (!PCD.access) { 
  8891. +        fsync_dev(devp);
  8892. +
  8893. +                invalidate_inodes(devp);
  8894. +
  8895. +            invalidate_buffers(devp);
  8896. +            pcd_unlock(unit);
  8897. +
  8898. +    }
  8899. +
  8900. +    MOD_DEC_USE_COUNT;
  8901. +
  8902. +}
  8903. +
  8904. +#ifdef MODULE
  8905. +
  8906. +/* Glue for modules ... */
  8907. +
  8908. +int    init_module(void)
  8909. +
  8910. +{    int    err;
  8911. +
  8912. +    err = pcd_init();
  8913. +
  8914. +    return err;
  8915. +}
  8916. +
  8917. +void    cleanup_module(void)
  8918. +
  8919. +{    int unit;
  8920. +
  8921. +    unregister_blkdev(MAJOR_NR,name);
  8922. +    
  8923. +        for (unit=0;unit<PCD_UNITS;unit++) 
  8924. +           if (PCD.present) pi_release(PI);
  8925. +}
  8926. +
  8927. +#endif
  8928. +
  8929. +#define WR(c,r,v)       pi_write_regr(PI,c,r,v)
  8930. +#define RR(c,r)         (pi_read_regr(PI,c,r))
  8931. +
  8932. +static int pcd_wait( int unit, int go, int stop, char * fun, char * msg )
  8933. +
  8934. +{    int j, r, e, s, p;
  8935. +
  8936. +    j = 0;
  8937. +    while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PCD_SPIN))
  8938. +        udelay(PCD_DELAY);
  8939. +
  8940. +    if ((r&(IDE_ERR&stop))||(j>=PCD_SPIN)) {
  8941. +       s = RR(0,7);
  8942. +       e = RR(0,1);
  8943. +       p = RR(0,2);
  8944. +              if (j >= PCD_SPIN) e |= 0x100;
  8945. +           if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
  8946. +               " loop=%d phase=%d\n",
  8947. +                PCD.name,fun,msg,r,s,e,j,p);
  8948. +       return (s<<8)+r;
  8949. +    }
  8950. +    return 0;
  8951. +}
  8952. +
  8953. +static int pcd_command( int unit, char * cmd, int dlen, char * fun )
  8954. +
  8955. +{    pi_connect(PI);
  8956. +
  8957. +        WR(0,6,0xa0 + 0x10*PCD.drive);
  8958. +
  8959. +    if (pcd_wait(unit,IDE_BUSY|IDE_DRQ,0,fun,"before command")) {
  8960. +        pi_disconnect(PI);
  8961. +        return -1;
  8962. +    }
  8963. +
  8964. +        WR(0,4,dlen % 256);
  8965. +        WR(0,5,dlen / 256);
  8966. +        WR(0,7,0xa0);          /* ATAPI packet command */
  8967. +
  8968. +        if (pcd_wait(unit,IDE_BUSY,IDE_DRQ,fun,"command DRQ")) {
  8969. +        pi_disconnect(PI);
  8970. +        return -1;
  8971. +    }
  8972. +
  8973. +        if (RR(0,2) != 1) {
  8974. +           printk("%s: %s: command phase error\n",PCD.name,fun);
  8975. +       pi_disconnect(PI);
  8976. +           return -1;
  8977. +        }
  8978. +
  8979. +    pi_write_block(PI,cmd,12);
  8980. +
  8981. +    return 0;
  8982. +}
  8983. +
  8984. +static int pcd_completion( int unit, char * buf,  char * fun )
  8985. +
  8986. +{    int r, s, n;
  8987. +
  8988. +    r = pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,fun,"completion");
  8989. +
  8990. +    if ((RR(0,2)&2) && (RR(0,7)&IDE_DRQ)) { 
  8991. +            n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
  8992. +            pi_read_block(PI,buf,n);
  8993. +    }
  8994. +
  8995. +    s = pcd_wait(unit,IDE_BUSY,IDE_READY|IDE_ERR,fun,"data done");
  8996. +
  8997. +    pi_disconnect(PI); 
  8998. +
  8999. +    return (r?r:s);
  9000. +}
  9001. +
  9002. +static void pcd_req_sense( int unit, int quiet )
  9003. +
  9004. +{    char    rs_cmd[12] = { 0x03,0,0,0,16,0,0,0,0,0,0,0 };
  9005. +    char    buf[16];
  9006. +    int     r;
  9007. +
  9008. +    r = pcd_command(unit,rs_cmd,16,"Request sense");
  9009. +    udelay(1000);
  9010. +    if (!r) pcd_completion(unit,buf,"Request sense");
  9011. +
  9012. +    PCD.last_sense = -1;
  9013. +    if (!r) {
  9014. +            if (!quiet) printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
  9015. +                           PCD.name,buf[2]&0xf,buf[12],buf[13]);
  9016. +        PCD.last_sense = (buf[2]&0xf) | ((buf[12]&0xff)<<8)
  9017. +                                          | ((buf[13]&0xff)<<16) ;
  9018. +        } 
  9019. +}
  9020. +
  9021. +static int pcd_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
  9022. +
  9023. +{    int r;
  9024. +
  9025. +    r = pcd_command(unit,cmd,dlen,fun);
  9026. +    udelay(1000);
  9027. +    if (!r) r = pcd_completion(unit,buf,fun);
  9028. +    if (r) pcd_req_sense(unit,!fun);
  9029. +    
  9030. +    return r;
  9031. +}
  9032. +
  9033. +#define DBMSG(msg)    NULL
  9034. +
  9035. +static void pcd_lock(int unit)
  9036. +
  9037. +{    char    lo_cmd[12] = { 0x1e,0,0,0,1,0,0,0,0,0,0,0 };
  9038. +    char    cl_cmd[12] = { 0x1b,0,0,0,3,0,0,0,0,0,0,0 };
  9039. +
  9040. +    pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd1")); 
  9041. +    pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd2"));
  9042. +    pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd3"));
  9043. +    pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd4"));
  9044. +    pcd_atapi(unit,cl_cmd,0,pcd_scratch,"close door");
  9045. +
  9046. +        pcd_atapi(unit,lo_cmd,0,pcd_scratch,DBMSG("ld"));
  9047. +        pcd_atapi(unit,lo_cmd,0,pcd_scratch,"lock door");
  9048. +}
  9049. +
  9050. +static void pcd_unlock( int unit )
  9051. +
  9052. +{    char    un_cmd[12] = { 0x1e,0,0,0,0,0,0,0,0,0,0,0 };
  9053. +
  9054. +    pcd_atapi(unit,un_cmd,0,pcd_scratch,"unlock door");
  9055. +}
  9056. +
  9057. +static void pcd_eject( int unit)
  9058. +
  9059. +{    char    ej_cmd[12] = { 0x1b,0,0,0,2,0,0,0,0,0,0,0 };
  9060. +
  9061. +    pcd_unlock(unit);
  9062. +    pcd_atapi(unit,ej_cmd,0,pcd_scratch,"eject");
  9063. +}
  9064. +
  9065. +#define PCD_RESET_TMO    30        /* in tenths of a second */
  9066. +
  9067. +static void pcd_sleep( int cs )
  9068. +
  9069. +{       current->state = TASK_INTERRUPTIBLE;
  9070. +        current->timeout = jiffies + cs;
  9071. +        schedule();
  9072. +}
  9073. +
  9074. +static int pcd_reset( int unit )
  9075. +
  9076. +/* the ATAPI standard actually specifies the contents of all 7 registers
  9077. +   after a reset, but the specification is ambiguous concerning the last
  9078. +   two bytes, and different drives interpret the standard differently.
  9079. +*/
  9080. +
  9081. +{    int    i, k, flg;
  9082. +    int    expect[5] = {1,1,1,0x14,0xeb};
  9083. +
  9084. +    pi_connect(PI);
  9085. +    WR(0,6,0xa0 + 0x10*PCD.drive);
  9086. +    WR(0,7,8);
  9087. +
  9088. +    pcd_sleep(2);          /* delay a bit*/
  9089. +
  9090. +    k = 0;
  9091. +    while ((k++ < PCD_RESET_TMO) && (RR(1,6)&IDE_BUSY))
  9092. +        pcd_sleep(10);
  9093. +
  9094. +    flg = 1;
  9095. +    for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
  9096. +
  9097. +    if (verbose) {
  9098. +        printk("%s: Reset (%d) signature = ",PCD.name,k);
  9099. +        for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
  9100. +        if (!flg) printk(" (incorrect)");
  9101. +        printk("\n");
  9102. +    }
  9103. +    
  9104. +    pi_disconnect(PI);
  9105. +    return flg-1;    
  9106. +}
  9107. +
  9108. +static int pcd_ready_wait( int unit, int tmo )
  9109. +
  9110. +{       char    tr_cmd[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
  9111. +        int     k, p;
  9112. +
  9113. +        k = 0;
  9114. +        while (k < tmo) {
  9115. +          PCD.last_sense = 0;
  9116. +          pcd_atapi(unit,tr_cmd,0,NULL,DBMSG("test unit ready"));
  9117. +          p = PCD.last_sense;
  9118. +          if (!p) return 0;
  9119. +      if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
  9120. +          k++;
  9121. +          pcd_sleep(100);
  9122. +        }
  9123. +        return 0x000020;        /* timeout */
  9124. +}
  9125. +
  9126. +static int pcd_check_media( int unit )
  9127. +
  9128. +{    char    rc_cmd[12] = { 0x25,0,0,0,0,0,0,0,0,0,0,0};
  9129. +
  9130. +    pcd_ready_wait(unit,PCD_READY_TMO);
  9131. +    return (pcd_atapi(unit,rc_cmd,8,pcd_scratch,DBMSG("check media")));
  9132. +}
  9133. +
  9134. +static int pcd_identify( int unit, char * id )
  9135. +
  9136. +{    int k, s;
  9137. +    char   id_cmd[12] = {0x12,0,0,0,36,0,0,0,0,0,0,0};
  9138. +
  9139. +    pcd_bufblk = -1;
  9140. +
  9141. +        s = pcd_atapi(unit,id_cmd,36,pcd_buffer,"identify");
  9142. +
  9143. +    if (s) return -1;
  9144. +    if ((pcd_buffer[0] & 0x1f) != 5) {
  9145. +      if (verbose) printk("%s: %s is not a CDrom\n",
  9146. +            PCD.name,PCD.drive?"Slave":"Master");
  9147. +      return -1;
  9148. +    }
  9149. +    for (k=0;k<16;k++) id[k] = pcd_buffer[16+k]; id[16] = 0;
  9150. +    k = 16; while ((k >= 0) && (id[k] <= 0x20)) { id[k] = 0; k--; }
  9151. +
  9152. +    printk("%s: %s: %s\n",PCD.name,PCD.drive?"Slave":"Master",id);
  9153. +
  9154. +    return 0;
  9155. +}
  9156. +
  9157. +static int pcd_probe( int unit, int ms, char * id )
  9158. +
  9159. +/*    returns  0, with id set if drive is detected
  9160. +            -1, if drive detection failed
  9161. +*/
  9162. +
  9163. +{    if (ms == -1) {
  9164. +            for (PCD.drive=0;PCD.drive<=1;PCD.drive++)
  9165. +           if (!pcd_reset(unit) && !pcd_identify(unit,id)) 
  9166. +          return 0;
  9167. +    } else {
  9168. +        PCD.drive = ms;
  9169. +            if (!pcd_reset(unit) && !pcd_identify(unit,id)) 
  9170. +        return 0;
  9171. +    }
  9172. +    return -1;
  9173. +}
  9174. +
  9175. +static int pcd_detect( void )
  9176. +
  9177. +{    char    id[18];
  9178. +    int    k, unit;
  9179. +
  9180. +    printk("%s: %s version %s, major %d, nice %d\n",
  9181. +        name,name,PCD_VERSION,major,nice);
  9182. +
  9183. +    k = 0;
  9184. +    if (pcd_drive_count == 0) {  /* nothing spec'd - so autoprobe for 1 */
  9185. +        unit = 0;
  9186. +        if (pi_init(PI,1,-1,-1,-1,-1,-1,pcd_buffer,
  9187. +                     PI_PCD,verbose,PCD.name)) {
  9188. +        if (!pcd_probe(unit,-1,id)) {
  9189. +            PCD.present = 1;
  9190. +            k++;
  9191. +        } else pi_release(PI);
  9192. +        }
  9193. +
  9194. +    } else for (unit=0;unit<PCD_UNITS;unit++) if (DU[D_PRT])
  9195. +        if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
  9196. +                        DU[D_PRO],DU[D_DLY],pcd_buffer,PI_PCD,verbose,
  9197. +                        PCD.name)) {
  9198. +        if (!pcd_probe(unit,DU[D_SLV],id)) {
  9199. +                        PCD.present = 1;
  9200. +                        k++;
  9201. +                } else pi_release(PI);
  9202. +            }
  9203. +
  9204. +    if (k) return 0;
  9205. +    
  9206. +    printk("%s: No CDrom drive found\n",name);
  9207. +    return -1;
  9208. +}
  9209. +
  9210. +/* I/O request processing */
  9211. +
  9212. +static int pcd_ready( void )
  9213. +
  9214. +{    int    unit = pcd_unit;
  9215. +
  9216. +    return (((RR(1,6)&(IDE_BUSY|IDE_DRQ))==IDE_DRQ)) ;
  9217. +}
  9218. +
  9219. +static void pcd_transfer( void )
  9220. +
  9221. +{    int    k, o;
  9222. +
  9223. +    while (pcd_count && (pcd_sector/4 == pcd_bufblk)) {
  9224. +        o = (pcd_sector % 4) * 512;
  9225. +        for(k=0;k<512;k++) pcd_buf[k] = pcd_buffer[o+k];
  9226. +        pcd_count--;
  9227. +        pcd_buf += 512;
  9228. +        pcd_sector++;
  9229. +    }
  9230. +}
  9231. +
  9232. +static void pcd_start( void )
  9233. +
  9234. +{    int    unit = pcd_unit;
  9235. +    int    b, i;
  9236. +    char    rd_cmd[12] = {0xa8,0,0,0,0,0,0,0,0,1,0,0};
  9237. +    long    saved_flags;
  9238. +
  9239. +    pcd_bufblk = pcd_sector / 4;
  9240. +        b = pcd_bufblk;
  9241. +    for(i=0;i<4;i++) { 
  9242. +       rd_cmd[5-i] = b & 0xff;
  9243. +       b = b >> 8;
  9244. +    }
  9245. +
  9246. +    if (pcd_command(unit,rd_cmd,2048,"read block")) {
  9247. +        pcd_bufblk = -1; 
  9248. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  9249. +        pcd_busy = 0;
  9250. +        end_request(0);
  9251. +        do_pcd_request();
  9252. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  9253. +        return;
  9254. +    }
  9255. +
  9256. +    udelay(1000);
  9257. +
  9258. +    ps_set_intr(do_pcd_read_drq,pcd_ready,PCD_TMO,nice);
  9259. +
  9260. +}
  9261. +
  9262. +static void do_pcd_read( void )
  9263. +
  9264. +
  9265. +{    int    unit = pcd_unit;
  9266. +    long    saved_flags;
  9267. +
  9268. +    pcd_busy = 1;
  9269. +    pcd_retries = 0;
  9270. +    pcd_transfer();
  9271. +    if (!pcd_count) {
  9272. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  9273. +        end_request(1);
  9274. +        pcd_busy = 0;
  9275. +        do_pcd_request();
  9276. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  9277. +        return;
  9278. +    }
  9279. +
  9280. +    pi_do_claimed(PI,pcd_start);
  9281. +}
  9282. +
  9283. +static void do_pcd_read_drq( void )
  9284. +
  9285. +{    int    unit = pcd_unit;
  9286. +    long    saved_flags;
  9287. +
  9288. +    if (pcd_completion(unit,pcd_buffer,"read block")) {
  9289. +                if (pcd_retries < PCD_RETRIES) {
  9290. +                        udelay(1000);
  9291. +                        pcd_retries++;
  9292. +            pi_do_claimed(PI,pcd_start);
  9293. +                        return;
  9294. +                        }
  9295. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  9296. +        pcd_busy = 0;
  9297. +        pcd_bufblk = -1;
  9298. +        end_request(0);
  9299. +        do_pcd_request();
  9300. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  9301. +        return;
  9302. +    }
  9303. +
  9304. +    do_pcd_read();
  9305. +    spin_lock_irqsave(&io_request_lock,saved_flags);
  9306. +    do_pcd_request();
  9307. +    spin_unlock_irqrestore(&io_request_lock,saved_flags); 
  9308. +}
  9309. +    
  9310. +/* end of pcd.c */
  9311. +
  9312. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/pd.c linux/drivers/block/paride/pd.c
  9313. --- v2.0.34/linux/drivers/block/paride/pd.c    Wed Dec 31 16:00:00 1969
  9314. +++ linux/drivers/block/paride/pd.c    Mon Jul 13 13:47:28 1998
  9315. @@ -0,0 +1,1107 @@
  9316. +/* 
  9317. +        pd.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  9318. +                            Under the terms of the GNU public license.
  9319. +
  9320. +
  9321. +    Special 2.0.34 version.
  9322. +
  9323. +
  9324. +
  9325. +        This is the high-level driver for parallel port IDE hard
  9326. +        drives based on chips supported by the paride module.
  9327. +
  9328. +    By default, the driver will autoprobe for a single parallel
  9329. +    port IDE drive, but if their individual parameters are
  9330. +        specified, the driver can handle up to 4 drives.
  9331. +
  9332. +        The behaviour of the pd driver can be altered by setting
  9333. +        some parameters from the insmod command line.  The following
  9334. +        parameters are adjustable:
  9335. +        drive0      These four arguments can be arrays of        
  9336. +        drive1    1-8 integers as follows:
  9337. +        drive2
  9338. +        drive3    <prt>,<pro>,<uni>,<mod>,<geo>,<sby>,<dly>,<slv>
  9339. +
  9340. +            Where,
  9341. +
  9342. +        <prt>    is the base of the parallel port address for
  9343. +            the corresponding drive.  (required)
  9344. +
  9345. +        <pro>   is the protocol number for the adapter that
  9346. +            supports this drive.  These numbers are
  9347. +                        logged by 'paride' when the protocol modules
  9348. +            are initialised.  (0 if not given)
  9349. +
  9350. +        <uni>   for those adapters that support chained
  9351. +            devices, this is the unit selector for the
  9352. +                chain of devices on the given port.  It should
  9353. +            be zero for devices that don't support chaining.
  9354. +            (0 if not given)
  9355. +
  9356. +        <mod>   this can be -1 to choose the best mode, or one
  9357. +                of the mode numbers supported by the adapter.
  9358. +            (-1 if not given)
  9359. +
  9360. +        <geo>   this defaults to 0 to indicate that the driver
  9361. +            should use the CHS geometry provided by the drive
  9362. +            itself.  If set to 1, the driver will provide
  9363. +            a logical geometry with 64 heads and 32 sectors
  9364. +            per track, to be consistent with most SCSI
  9365. +                drivers.  (0 if not given)
  9366. +
  9367. +        <sby>   set this to zero to disable the power saving
  9368. +            standby mode, if needed.  (1 if not given)
  9369. +
  9370. +        <dly>   some parallel ports require the driver to 
  9371. +            go more slowly.  -1 sets a default value that
  9372. +            should work with the chosen protocol.  Otherwise,
  9373. +            set this to a small integer, the larger it is
  9374. +            the slower the port i/o.  In some cases, setting
  9375. +            this to zero will speed up the device. (default -1)
  9376. +
  9377. +        <slv>   IDE disks can be jumpered to master or slave.
  9378. +                        Set this to 0 to choose the master drive, 1 to
  9379. +                        choose the slave, -1 (the default) to choose the
  9380. +                        first drive found.
  9381. +            
  9382. +
  9383. +            major       You may use this parameter to overide the
  9384. +                        default major number (45) that this driver
  9385. +                        will use.  Be sure to change the device
  9386. +                        name as well.
  9387. +
  9388. +            name        This parameter is a character string that
  9389. +                        contains the name the kernel will use for this
  9390. +                        device (in /proc output, for instance).
  9391. +            (default "pd")
  9392. +
  9393. +        cluster    The driver will attempt to aggregate requests
  9394. +            for adjacent blocks into larger multi-block
  9395. +            clusters.  The maximum cluster size (in 512
  9396. +            byte sectors) is set with this parameter.
  9397. +            (default 64)
  9398. +
  9399. +        verbose    This parameter controls the amount of logging
  9400. +            that is done while the driver probes for
  9401. +            devices.  Set it to 0 for a quiet load, or to 1
  9402. +            see all the progress messages.  (default 0)
  9403. +
  9404. +            nice        This parameter controls the driver's use of
  9405. +                        idle CPU time, at the expense of some speed.
  9406. +
  9407. +        If this driver is built into the kernel, you can use kernel
  9408. +        the following command line parameters, with the same values
  9409. +        as the corresponding module parameters listed above:
  9410. +
  9411. +            pd.drive0
  9412. +            pd.drive1
  9413. +            pd.drive2
  9414. +            pd.drive3
  9415. +            pd.cluster
  9416. +            pd.nice
  9417. +
  9418. +        In addition, you can use the parameter pd.disable to disable
  9419. +        the driver entirely.
  9420. +*/
  9421. +
  9422. +/* Changes:
  9423. +
  9424. +    1.01    GRG 1997.01.24    Restored pd_reset()
  9425. +                Added eject ioctl
  9426. +    1.02    GRG 1998.05.06  SMP spinlock changes, 
  9427. +                Added slave support
  9428. +    1.03    GRG 1998.06.16  Eliminate an Ugh.
  9429. +
  9430. +*/
  9431. +
  9432. +#define PD_VERSION      "1.03s"
  9433. +#define PD_MAJOR    45
  9434. +#define PD_NAME        "pd"
  9435. +#define PD_UNITS    4
  9436. +
  9437. +/* Here are things one can override from the insmod command.
  9438. +   Most are autoprobed by paride unless set here.  Verbose is off
  9439. +   by default.
  9440. +
  9441. +*/
  9442. +
  9443. +static int    verbose = 0;
  9444. +static int    major = PD_MAJOR;
  9445. +static char    *name = PD_NAME;
  9446. +static int    cluster = 64;    
  9447. +static int      nice = 0;
  9448. +static int      disable = 0;
  9449. +
  9450. +static int drive0[8] = {0,0,0,-1,0,1,-1,-1};
  9451. +static int drive1[8] = {0,0,0,-1,0,1,-1,-1};
  9452. +static int drive2[8] = {0,0,0,-1,0,1,-1,-1};
  9453. +static int drive3[8] = {0,0,0,-1,0,1,-1,-1};
  9454. +
  9455. +static int (*drives[4])[8] = {&drive0,&drive1,&drive2,&drive3};
  9456. +static int pd_drive_count;
  9457. +
  9458. +#define D_PRT    0
  9459. +#define D_PRO   1
  9460. +#define D_UNI    2
  9461. +#define D_MOD    3
  9462. +#define D_GEO    4
  9463. +#define D_SBY    5
  9464. +#define D_DLY    6
  9465. +#define D_SLV   7
  9466. +
  9467. +#define    DU        (*drives[unit])
  9468. +
  9469. +/* end of parameters */
  9470. +
  9471. +#include <linux/module.h>
  9472. +#include <linux/errno.h>
  9473. +#include <linux/fs.h>
  9474. +#include <linux/kernel.h>
  9475. +#include <linux/delay.h>
  9476. +#include <linux/genhd.h>
  9477. +#include <linux/hdreg.h>
  9478. +#include <linux/cdrom.h>    /* for the eject ioctl */
  9479. +
  9480. +#include "spinlock.h"
  9481. +#include <asm/segment.h>
  9482. +
  9483. +#ifndef MODULE
  9484. +
  9485. +#include "setup.h"
  9486. +
  9487. +static STT pd_stt[7] = {{"drive0",8,drive0},
  9488. +                {"drive1",8,drive1},
  9489. +                {"drive2",8,drive2},
  9490. +                {"drive3",8,drive3},
  9491. +            {"disable",1,&disable},
  9492. +                {"cluster",1,&cluster},
  9493. +                {"nice",1,&nice}};
  9494. +
  9495. +void pd_setup( char *str, int *ints)
  9496. +
  9497. +{    generic_setup(pd_stt,7,str);
  9498. +}
  9499. +
  9500. +#endif
  9501. +
  9502. +#include "paride.h"
  9503. +
  9504. +#define PD_BITS    4
  9505. +
  9506. +/* set up defines for blk.h,  why don't all drivers do it this way ? */
  9507. +
  9508. +#define MAJOR_NR   major
  9509. +#define DEVICE_NAME "PD"
  9510. +#define DEVICE_REQUEST do_pd_request
  9511. +#define DEVICE_NR(device) (MINOR(device)>>PD_BITS)
  9512. +#define DEVICE_ON(device)
  9513. +#define DEVICE_OFF(device)
  9514. +
  9515. +#include <linux/blk.h>
  9516. +
  9517. +#include "pseudo.h"
  9518. +
  9519. +#define PD_PARTNS      (1<<PD_BITS)
  9520. +#define PD_DEVS        PD_PARTNS*PD_UNITS
  9521. +
  9522. +/* numbers for "SCSI" geometry */
  9523. +
  9524. +#define PD_LOG_HEADS    64
  9525. +#define PD_LOG_SECTS    32
  9526. +
  9527. +#define PD_ID_OFF       54
  9528. +#define PD_ID_LEN       14
  9529. +
  9530. +#define PD_MAX_RETRIES  5
  9531. +#define PD_TMO          800             /* interrupt timeout in jiffies */
  9532. +#define PD_SPIN_DEL     50              /* spin delay in micro-seconds  */
  9533. +
  9534. +#define PD_SPIN         (10000/PD_SPIN_DEL)*PD_TMO  
  9535. +
  9536. +#define STAT_ERR        0x00001
  9537. +#define STAT_INDEX      0x00002
  9538. +#define STAT_ECC        0x00004
  9539. +#define STAT_DRQ        0x00008
  9540. +#define STAT_SEEK       0x00010
  9541. +#define STAT_WRERR      0x00020
  9542. +#define STAT_READY      0x00040
  9543. +#define STAT_BUSY       0x00080
  9544. +
  9545. +#define ERR_AMNF        0x00100
  9546. +#define ERR_TK0NF       0x00200
  9547. +#define ERR_ABRT        0x00400
  9548. +#define ERR_MCR         0x00800
  9549. +#define ERR_IDNF        0x01000
  9550. +#define ERR_MC          0x02000
  9551. +#define ERR_UNC         0x04000
  9552. +#define ERR_TMO         0x10000
  9553. +
  9554. +#define IDE_READ            0x20
  9555. +#define IDE_WRITE           0x30
  9556. +#define IDE_READ_VRFY        0x40
  9557. +#define IDE_INIT_DEV_PARMS    0x91
  9558. +#define IDE_STANDBY         0x96
  9559. +#define IDE_ACKCHANGE       0xdb
  9560. +#define IDE_DOORLOCK        0xde
  9561. +#define IDE_DOORUNLOCK      0xdf
  9562. +#define IDE_IDENTIFY        0xec
  9563. +#define IDE_EJECT        0xed
  9564. +
  9565. +int pd_init(void);
  9566. +void pd_setup(char * str, int * ints);
  9567. +#ifdef MODULE
  9568. +void cleanup_module( void );
  9569. +#endif
  9570. +static void pd_geninit(struct gendisk *ignored);
  9571. +static int pd_open(struct inode *inode, struct file *file);
  9572. +static void do_pd_request(void);
  9573. +static int pd_ioctl(struct inode *inode,struct file *file,
  9574. +                    unsigned int cmd, unsigned long arg);
  9575. +static void pd_release (struct inode *inode, struct file *file);
  9576. +static int pd_revalidate(kdev_t dev);
  9577. +static int pd_detect(void);
  9578. +static void do_pd_read(void);
  9579. +static void do_pd_read_start(void);
  9580. +static void do_pd_write(void);
  9581. +static void do_pd_write_start(void);
  9582. +static void do_pd_read_drq( void );
  9583. +static void do_pd_write_done( void );
  9584. +
  9585. +static int pd_identify (int unit);
  9586. +static void pd_media_check(int unit);
  9587. +static void pd_doorlock(int unit, int func);
  9588. +static int pd_check_media(kdev_t dev);
  9589. +static void pd_eject( int unit);
  9590. +
  9591. +static struct hd_struct pd_hd[PD_DEVS];
  9592. +static int pd_sizes[PD_DEVS];
  9593. +static int pd_blocksizes[PD_DEVS];
  9594. +
  9595. +#define PD_NAMELEN    8
  9596. +
  9597. +struct pd_unit {
  9598. +    struct pi_adapter pia;        /* interface to paride layer */
  9599. +    struct pi_adapter *pi;
  9600. +    int access;                   /* count of active opens ... */
  9601. +    int capacity;                 /* Size of this volume in sectors */
  9602. +    int heads;                    /* physical geometry */
  9603. +    int sectors;
  9604. +    int cylinders;
  9605. +    int drive;            /* master=0 slave=1 */
  9606. +    int changed;            /* Have we seen a disk change ? */
  9607. +    int removable;            /* removable media device  ?  */
  9608. +    int standby;
  9609. +    int alt_geom;
  9610. +    int present;
  9611. +    char name[PD_NAMELEN];        /* pda, pdb, etc ... */
  9612. +    };
  9613. +
  9614. +struct pd_unit pd[PD_UNITS];
  9615. +
  9616. +/*  'unit' must be defined in all functions - either as a local or a param */
  9617. +
  9618. +#define PD pd[unit]
  9619. +#define PI PD.pi
  9620. +
  9621. +static int pd_valid = 1;        /* serialise partition checks */
  9622. +static char pd_scratch[512];            /* scratch block buffer */
  9623. +
  9624. +/* the variables below are used mainly in the I/O request engine, which
  9625. +   processes only one request at a time.
  9626. +*/
  9627. +
  9628. +static int pd_retries = 0;              /* i/o error retry count */
  9629. +static int pd_busy = 0;                 /* request being processed ? */
  9630. +static int pd_block;                    /* address of next requested block */
  9631. +static int pd_count;                    /* number of blocks still to do */
  9632. +static int pd_run;            /* sectors in current cluster */
  9633. +static int pd_cmd;            /* current command READ/WRITE */
  9634. +static int pd_unit;            /* unit of current request */
  9635. +static int pd_dev;            /* minor of current request */
  9636. +static int pd_poffs;            /* partition offset of current minor */
  9637. +static char * pd_buf;                   /* buffer for request in progress */
  9638. +
  9639. +static struct wait_queue *pd_wait_open = NULL;
  9640. +
  9641. +static char *pd_errs[17] = { "ERR","INDEX","ECC","DRQ","SEEK","WRERR",
  9642. +                             "READY","BUSY","AMNF","TK0NF","ABRT","MCR",
  9643. +                             "IDNF","MC","UNC","???","TMO"};
  9644. +
  9645. +/* kernel glue structures */
  9646. +
  9647. +static struct gendisk pd_gendisk = {
  9648. +        PD_MAJOR,       /* Major number */
  9649. +        PD_NAME,        /* Major name */
  9650. +        PD_BITS,        /* Bits to shift to get real from partition */
  9651. +        PD_PARTNS,      /* Number of partitions per real */
  9652. +        PD_UNITS,       /* maximum number of real */
  9653. +        pd_geninit,     /* init function */
  9654. +        pd_hd,          /* hd struct */
  9655. +        pd_sizes,       /* block sizes */
  9656. +        0,              /* number */
  9657. +        NULL,           /* internal */
  9658. +        NULL            /* next */
  9659. +};
  9660. +
  9661. +static struct file_operations pd_fops = {
  9662. +        NULL,                   /* lseek - default */
  9663. +        block_read,             /* read - general block-dev read */
  9664. +        block_write,            /* write - general block-dev write */
  9665. +        NULL,                   /* readdir - bad */
  9666. +        NULL,                   /* select */
  9667. +        pd_ioctl,               /* ioctl */
  9668. +        NULL,                   /* mmap */
  9669. +        pd_open,                /* open */
  9670. +        pd_release,             /* release */
  9671. +        block_fsync,            /* fsync */
  9672. +        NULL,                   /* fasync */
  9673. +        pd_check_media,         /* media change ? */
  9674. +        pd_revalidate           /* revalidate new media */
  9675. +};
  9676. +
  9677. +void pd_init_units( void )
  9678. +
  9679. +{    int    unit, j;
  9680. +
  9681. +    pd_drive_count = 0;
  9682. +    for (unit=0;unit<PD_UNITS;unit++) {
  9683. +        PD.pi = & PD.pia;
  9684. +        PD.access = 0;
  9685. +        PD.changed = 1;
  9686. +        PD.capacity = 0;
  9687. +        PD.drive = DU[D_SLV];
  9688. +        PD.present = 0;
  9689. +        j = 0;
  9690. +        while ((j < PD_NAMELEN-2) && (PD.name[j]=name[j])) j++;
  9691. +        PD.name[j++] = 'a' + unit;
  9692. +        PD.name[j] = 0;
  9693. +        PD.alt_geom = DU[D_GEO];
  9694. +        PD.standby = DU[D_SBY];
  9695. +        if (DU[D_PRT]) pd_drive_count++;
  9696. +    }
  9697. +}
  9698. +
  9699. +int pd_init (void)
  9700. +
  9701. +{       int i;
  9702. +
  9703. +    if (disable) return -1;
  9704. +
  9705. +        if (register_blkdev(MAJOR_NR,name,&pd_fops)) {
  9706. +                printk("%s: unable to get major number %d\n",
  9707. +                        name,major);
  9708. +                return -1;
  9709. +        }
  9710. +        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
  9711. +        read_ahead[MAJOR_NR] = 8;       /* 8 sector (4kB) read ahead */
  9712. +        
  9713. +    pd_gendisk.major = major;
  9714. +    pd_gendisk.major_name = name;
  9715. +    pd_gendisk.next = gendisk_head;
  9716. +        gendisk_head = &pd_gendisk;
  9717. +
  9718. +        for(i=0;i<PD_DEVS;i++) pd_blocksizes[i] = 1024;
  9719. +        blksize_size[MAJOR_NR] = pd_blocksizes;
  9720. +
  9721. +        printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
  9722. +                name,name,PD_VERSION,major,cluster,nice);
  9723. +    
  9724. +        return 0;
  9725. +}
  9726. +
  9727. +static void pd_geninit (struct gendisk *ignored)
  9728. +
  9729. +{    pd_init_units();
  9730. +    pd_gendisk.nr_real = pd_detect();
  9731. +
  9732. +#ifdef MODULE
  9733. +        if (!pd_gendisk.nr_real) cleanup_module();
  9734. +#endif
  9735. +
  9736. +}
  9737. +
  9738. +static int pd_open (struct inode *inode, struct file *file)
  9739. +
  9740. +{       int unit = DEVICE_NR(inode->i_rdev);
  9741. +
  9742. +        if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;
  9743. +
  9744. +        MOD_INC_USE_COUNT;
  9745. +
  9746. +        while (!pd_valid) sleep_on(&pd_wait_open);
  9747. +
  9748. +        PD.access++;
  9749. +
  9750. +        if (PD.removable) {
  9751. +        pd_media_check(unit);
  9752. +        pd_doorlock(unit,IDE_DOORLOCK);
  9753. +    }
  9754. +        return 0;
  9755. +}
  9756. +
  9757. +static int pd_ioctl(struct inode *inode,struct file *file,
  9758. +                    unsigned int cmd, unsigned long arg)
  9759. +
  9760. +{       struct hd_geometry *geo = (struct hd_geometry *) arg;
  9761. +        int dev, err, unit;
  9762. +
  9763. +        if ((!inode) || (!inode->i_rdev)) return -EINVAL;
  9764. +        dev = MINOR(inode->i_rdev);
  9765. +    unit = DEVICE_NR(inode->i_rdev);
  9766. +        if (dev >= PD_DEVS) return -EINVAL;
  9767. +    if (!PD.present) return -ENODEV;
  9768. +
  9769. +        switch (cmd) {
  9770. +        case CDROMEJECT:
  9771. +        if (PD.access == 1) pd_eject(unit);
  9772. +        return 0;
  9773. +            case HDIO_GETGEO:
  9774. +                if (!geo) return -EINVAL;
  9775. +                err = verify_area(VERIFY_WRITE,geo,sizeof(*geo));
  9776. +                if (err) return err;
  9777. +
  9778. +        if (PD.alt_geom) {
  9779. +                    put_user(PD.capacity/(PD_LOG_HEADS*PD_LOG_SECTS), 
  9780. +                    (short *) &geo->cylinders);
  9781. +                    put_user(PD_LOG_HEADS, (char *) &geo->heads);
  9782. +                    put_user(PD_LOG_SECTS, (char *) &geo->sectors);
  9783. +        } else {
  9784. +                    put_user(PD.cylinders, (short *) &geo->cylinders);
  9785. +                    put_user(PD.heads, (char *) &geo->heads);
  9786. +                    put_user(PD.sectors, (char *) &geo->sectors);
  9787. +        }
  9788. +                put_user(pd_hd[dev].start_sect,(long *)&geo->start);
  9789. +                return 0;
  9790. +            case BLKRASET:
  9791. +                if(!suser()) return -EACCES;
  9792. +                if(!(inode->i_rdev)) return -EINVAL;
  9793. +                if(arg > 0xff) return -EINVAL;
  9794. +                read_ahead[MAJOR(inode->i_rdev)] = arg;
  9795. +                return 0;
  9796. +            case BLKRAGET:
  9797. +                if (!arg) return -EINVAL;
  9798. +                err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));
  9799. +                if (err) return (err);
  9800. +                put_user(read_ahead[MAJOR(inode->i_rdev)],(long *) arg);
  9801. +                return (0);
  9802. +            case BLKGETSIZE:
  9803. +                if (!arg) return -EINVAL;
  9804. +                err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));
  9805. +                if (err) return (err);
  9806. +                put_user(pd_hd[dev].nr_sects,(long *) arg);
  9807. +                return (0);
  9808. +            case BLKFLSBUF:
  9809. +                if(!suser())  return -EACCES;
  9810. +                if(!(inode->i_rdev)) return -EINVAL;
  9811. +                fsync_dev(inode->i_rdev);
  9812. +                invalidate_buffers(inode->i_rdev);
  9813. +                return 0;
  9814. +            case BLKRRPART:
  9815. +        if (!suser()) return -EACCES;
  9816. +                return pd_revalidate(inode->i_rdev);
  9817. +            RO_IOCTLS(inode->i_rdev,arg);
  9818. +            default:
  9819. +                return -EINVAL;
  9820. +        }
  9821. +}
  9822. +
  9823. +static void pd_release (struct inode *inode, struct file *file)
  9824. +
  9825. +{       kdev_t devp;
  9826. +    int    unit;
  9827. +
  9828. +        devp = inode->i_rdev;
  9829. +    unit = DEVICE_NR(devp);
  9830. +
  9831. +    if ((unit >= PD_UNITS) || (PD.access <= 0)) 
  9832. +        return;
  9833. +
  9834. +    PD.access--;
  9835. +
  9836. +        if (!PD.access)  {
  9837. +                fsync_dev(devp);
  9838. +
  9839. +        invalidate_inodes(devp);
  9840. +
  9841. +                invalidate_buffers(devp);
  9842. +        if (PD.removable) pd_doorlock(unit,IDE_DOORUNLOCK);
  9843. +    }
  9844. +
  9845. +        MOD_DEC_USE_COUNT;
  9846. +
  9847. +}
  9848. +
  9849. +static int pd_check_media( kdev_t dev)
  9850. +
  9851. +{       int r, unit;
  9852. +
  9853. +    unit = DEVICE_NR(dev);
  9854. +    if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;
  9855. +        if (!PD.removable) return 0;
  9856. +    pd_media_check(unit);
  9857. +    r = PD.changed;
  9858. +    PD.changed = 0;
  9859. +    return r;
  9860. +}
  9861. +
  9862. +static int pd_revalidate(kdev_t dev)
  9863. +
  9864. +{       int p, unit, minor;
  9865. +        long flags;
  9866. +        kdev_t devp;
  9867. +
  9868. +        unit = DEVICE_NR(dev);
  9869. +        if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;
  9870. +
  9871. +        save_flags(flags);
  9872. +        cli(); 
  9873. +        if (PD.access > 1) {
  9874. +                restore_flags(flags);
  9875. +                return -EBUSY;
  9876. +        }
  9877. +        pd_valid = 0;
  9878. +        restore_flags(flags);   
  9879. +
  9880. +        for (p=(PD_PARTNS-1);p>=0;p--) {
  9881. +        minor = p + unit*PD_PARTNS;
  9882. +                devp = MKDEV(MAJOR_NR, minor);
  9883. +                fsync_dev(devp);
  9884. +
  9885. +                invalidate_inodes(devp);
  9886. +
  9887. +                invalidate_buffers(devp);
  9888. +                pd_hd[minor].start_sect = 0;
  9889. +                pd_hd[minor].nr_sects = 0;
  9890. +        }
  9891. +
  9892. +    pd_identify(unit);
  9893. +        resetup_one_dev(&pd_gendisk,unit);
  9894. +
  9895. +        pd_valid = 1;
  9896. +        wake_up(&pd_wait_open);
  9897. +
  9898. +        return 0;
  9899. +}
  9900. +
  9901. +#ifdef MODULE
  9902. +
  9903. +/* Glue for modules ... */
  9904. +
  9905. +void    cleanup_module(void);
  9906. +
  9907. +int     init_module(void)
  9908. +
  9909. +{       int     err, unit;
  9910. +
  9911. +        err = pd_init();
  9912. +        if (err) return err;
  9913. +
  9914. +    pd_geninit(&pd_gendisk);
  9915. +
  9916. +        if (!pd_gendisk.nr_real)  return -1;
  9917. +
  9918. +        pd_valid = 0;
  9919. +    for (unit=0;unit<PD_UNITS;unit++) 
  9920. +          if (PD.present) resetup_one_dev(&pd_gendisk,unit);
  9921. +        pd_valid = 1;
  9922. +
  9923. +        return 0;
  9924. +}
  9925. +
  9926. +void    cleanup_module(void)
  9927. +
  9928. +{       struct gendisk **gdp;
  9929. +    int unit;
  9930. +
  9931. +        unregister_blkdev(MAJOR_NR,name);
  9932. +
  9933. +        for(gdp=&gendisk_head;*gdp;gdp=&((*gdp)->next))
  9934. +                if (*gdp == &pd_gendisk) break;
  9935. +        if (*gdp) *gdp = (*gdp)->next;
  9936. +
  9937. +    for (unit=0;unit<PD_UNITS;unit++) 
  9938. +       if (PD.present) pi_release(PI);
  9939. +}
  9940. +
  9941. +#endif
  9942. +
  9943. +#define    WR(c,r,v)    pi_write_regr(PI,c,r,v)
  9944. +#define    RR(c,r)        (pi_read_regr(PI,c,r))
  9945. +
  9946. +#define DRIVE        (0xa0+0x10*PD.drive)
  9947. +
  9948. +/*  ide command interface */
  9949. +
  9950. +static void pd_print_error( int unit, char * msg, int status )
  9951. +
  9952. +{       int     i;
  9953. +
  9954. +    printk("%s: %s: status = 0x%x =",PD.name,msg,status);
  9955. +        for(i=0;i<18;i++) if (status & (1<<i)) printk(" %s",pd_errs[i]);
  9956. +    printk("\n");
  9957. +}
  9958. +
  9959. +static void pd_reset( int unit )    /* called only for MASTER drive */
  9960. +
  9961. +{       pi_connect(PI);
  9962. +    WR(1,6,4);
  9963. +        udelay(50);
  9964. +        WR(1,6,0);
  9965. +    pi_disconnect(PI);
  9966. +    udelay(250);
  9967. +}
  9968. +
  9969. +#define DBMSG(msg)    NULL
  9970. +
  9971. +static int pd_wait_for( int unit, int w, char * msg )    /* polled wait */
  9972. +
  9973. +{       int     k, r, e;
  9974. +
  9975. +        k=0;
  9976. +        while(k < PD_SPIN) { 
  9977. +            r = RR(1,6);
  9978. +            k++;
  9979. +            if (((r & w) == w) && !(r & STAT_BUSY)) break;
  9980. +            udelay(PD_SPIN_DEL);
  9981. +        }
  9982. +        e = (RR(0,1)<<8) + RR(0,7);
  9983. +        if (k >= PD_SPIN)  e |= ERR_TMO;
  9984. +        if ((e & (STAT_ERR|ERR_TMO)) && (msg != NULL)) 
  9985. +        pd_print_error(unit,msg,e);
  9986. +        return e;
  9987. +}
  9988. +
  9989. +static void pd_send_command( int unit, int n, int s, int h, 
  9990. +                 int c0, int c1, int func )
  9991. +
  9992. +{
  9993. +        WR(0,6,DRIVE+h);
  9994. +        WR(0,1,0);                /* the IDE task file */
  9995. +        WR(0,2,n);
  9996. +        WR(0,3,s);
  9997. +        WR(0,4,c0);
  9998. +        WR(0,5,c1);
  9999. +        WR(0,7,func);
  10000. +
  10001. +        udelay(1);
  10002. +}
  10003. +
  10004. +static void pd_ide_command( int unit, int func, int block, int count )
  10005. +
  10006. +/* Don't use this call if the capacity is zero. */
  10007. +
  10008. +{       int c1, c0, h, s;
  10009. +
  10010. +        s  = ( block % PD.sectors) + 1;
  10011. +        h  = ( block / PD.sectors) % PD.heads;
  10012. +        c0 = ( block / (PD.sectors*PD.heads)) % 256;
  10013. +        c1 = ( block / (PD.sectors*PD.heads*256));
  10014. +
  10015. +        pd_send_command(unit,count,s,h,c0,c1,func);
  10016. +}
  10017. +
  10018. +/* According to the ATA standard, the default CHS geometry should be
  10019. +   available following a reset.  Some Western Digital drives come up
  10020. +   in a mode where only LBA addresses are accepted until the device
  10021. +   parameters are initialised.
  10022. +*/
  10023. +
  10024. +static void pd_init_dev_parms( int unit )
  10025. +{       pi_connect(PI);
  10026. +        pd_wait_for(unit,0,DBMSG("before init_dev_parms"));
  10027. +        pd_send_command(unit,PD.sectors,0,PD.heads-1,0,0,IDE_INIT_DEV_PARMS);
  10028. +        udelay(300);
  10029. +        pd_wait_for(unit,0,"Initialise device parameters");
  10030. +        pi_disconnect(PI);
  10031. +}
  10032. +
  10033. +static void pd_doorlock( int unit, int func )
  10034. +
  10035. +{       pi_connect(PI);
  10036. +        if (pd_wait_for(unit,STAT_READY,"Lock") & STAT_ERR) {
  10037. +                pi_disconnect(PI);
  10038. +                return;
  10039. +        }
  10040. +        pd_send_command(unit,1,0,0,0,0,func);
  10041. +        pd_wait_for(unit,STAT_READY,"Lock done");
  10042. +        pi_disconnect(PI);
  10043. +}
  10044. +
  10045. +static void pd_eject( int unit )
  10046. +
  10047. +{    pi_connect(PI);
  10048. +        pd_wait_for(unit,0,DBMSG("before unlock on eject"));
  10049. +        pd_send_command(unit,1,0,0,0,0,IDE_DOORUNLOCK);
  10050. +        pd_wait_for(unit,0,DBMSG("after unlock on eject"));
  10051. +        pd_wait_for(unit,0,DBMSG("before eject"));
  10052. +        pd_send_command(unit,0,0,0,0,0,IDE_EJECT);
  10053. +        pd_wait_for(unit,0,DBMSG("after eject"));
  10054. +        pi_disconnect(PI);
  10055. +}
  10056. +
  10057. +static void pd_media_check( int unit )
  10058. +
  10059. +{       int     r;
  10060. +
  10061. +        pi_connect(PI);
  10062. +        r = pd_wait_for(unit,STAT_READY,DBMSG("before media_check"));
  10063. +        if (!(r & STAT_ERR)) {
  10064. +                pd_send_command(unit,1,1,0,0,0,IDE_READ_VRFY);  
  10065. +                r = pd_wait_for(unit,STAT_READY,DBMSG("RDY after READ_VRFY"));
  10066. +        } else PD.changed = 1;   /* say changed if other error */
  10067. +        if (r & ERR_MC) {
  10068. +                PD.changed = 1;
  10069. +                pd_send_command(unit,1,0,0,0,0,IDE_ACKCHANGE);
  10070. +                pd_wait_for(unit,STAT_READY,DBMSG("RDY after ACKCHANGE"));
  10071. +        pd_send_command(unit,1,1,0,0,0,IDE_READ_VRFY);
  10072. +                r = pd_wait_for(unit,STAT_READY,DBMSG("RDY after VRFY"));
  10073. +        }
  10074. +        pi_disconnect(PI);
  10075. +
  10076. +}
  10077. +
  10078. +static void pd_standby_off( int unit )
  10079. +
  10080. +{       pi_connect(PI);
  10081. +        pd_wait_for(unit,0,DBMSG("before STANDBY"));
  10082. +        pd_send_command(unit,0,0,0,0,0,IDE_STANDBY);
  10083. +        pd_wait_for(unit,0,DBMSG("after STANDBY"));
  10084. +        pi_disconnect(PI);
  10085. +}
  10086. +
  10087. +#define  word_val(n) ((pd_scratch[2*n]&0xff)+256*(pd_scratch[2*n+1]&0xff))
  10088. +
  10089. +static int pd_identify( int unit )
  10090. +
  10091. +{       int    j;
  10092. +    char id[PD_ID_LEN+1];
  10093. +
  10094. +/* WARNING:  here there may be dragons.  reset() applies to both drives,
  10095. +   but we call it only on probing the MASTER. This should allow most
  10096. +   common configurations to work, but be warned that a reset can clear
  10097. +   settings on the SLAVE drive.
  10098. +*/ 
  10099. +
  10100. +    if (PD.drive == 0) pd_reset(unit);
  10101. +
  10102. +        pi_connect(PI);
  10103. +    WR(0,6,DRIVE);
  10104. +        pd_wait_for(unit,0,DBMSG("before IDENT"));  
  10105. +        pd_send_command(unit,1,0,0,0,0,IDE_IDENTIFY);
  10106. +
  10107. +        if (pd_wait_for(unit,STAT_DRQ,DBMSG("IDENT DRQ")) & STAT_ERR) {
  10108. +                pi_disconnect(PI);
  10109. +                return 0;
  10110. +        }
  10111. +        pi_read_block(PI,pd_scratch,512);
  10112. +        pi_disconnect(PI);
  10113. +        PD.sectors = word_val(6);
  10114. +        PD.heads = word_val(3);
  10115. +        PD.cylinders  = word_val(1);
  10116. +        PD.capacity = PD.sectors*PD.heads*PD.cylinders;
  10117. +
  10118. +        for(j=0;j<PD_ID_LEN;j++) id[j^1] = pd_scratch[j+PD_ID_OFF];
  10119. +        j = PD_ID_LEN-1;
  10120. +        while ((j >= 0) && (id[j] <= 0x20)) j--;
  10121. +        j++; id[j] = 0;
  10122. +
  10123. +        PD.removable = (word_val(0) & 0x80);
  10124. +        printk("%s: %s, %s, %d blocks [%dM], (%d/%d/%d), %s media\n",
  10125. +                    PD.name,id,
  10126. +            PD.drive?"slave":"master",
  10127. +            PD.capacity,PD.capacity/2048,
  10128. +                    PD.cylinders,PD.heads,PD.sectors,
  10129. +                    PD.removable?"removable":"fixed");
  10130. +
  10131. +        if (PD.capacity) pd_init_dev_parms(unit);
  10132. +        if (!PD.standby) pd_standby_off(unit);
  10133. +
  10134. +    pd_hd[unit<<PD_BITS].nr_sects = PD.capacity;
  10135. +    pd_hd[unit<<PD_BITS].start_sect = 0;
  10136. +    
  10137. +        return 1;
  10138. +}
  10139. +
  10140. +static int pd_probe_drive( int unit )
  10141. +
  10142. +{    if (PD.drive == -1) {
  10143. +      for (PD.drive=0;PD.drive<=1;PD.drive++)
  10144. +         if (pd_identify(unit)) return 1;
  10145. +      return 0;
  10146. +      }
  10147. +    else return pd_identify(unit);
  10148. +}
  10149. +
  10150. +static int pd_detect( void )
  10151. +
  10152. +{       int    k, unit;
  10153. +
  10154. +    k = 0;
  10155. +    if (pd_drive_count == 0) {  /* nothing spec'd - so autoprobe for 1 */
  10156. +        unit = 0;
  10157. +        if (pi_init(PI,1,-1,-1,-1,-1,-1,pd_scratch,
  10158. +                 PI_PD,verbose,PD.name)) {
  10159. +        if (pd_probe_drive(unit)) {
  10160. +            PD.present = 1;
  10161. +            k = 1;
  10162. +        } else pi_release(PI);
  10163. +        }
  10164. +
  10165. +       } else for (unit=0;unit<PD_UNITS;unit++) if (DU[D_PRT])
  10166. +        if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
  10167. +            DU[D_PRO],DU[D_DLY],pd_scratch,
  10168. +            PI_PD,verbose,PD.name)) {
  10169. +                if (pd_probe_drive(unit)) {
  10170. +                        PD.present = 1;
  10171. +                        k = unit+1;
  10172. +                } else pi_release(PI);
  10173. +            }
  10174. +
  10175. +/* We lie about the number of drives found, as the generic partition
  10176. +   scanner assumes that the drives are numbered sequentially from 0.
  10177. +   This can result in some bogus error messages if non-sequential
  10178. +   drive numbers are used.
  10179. +*/
  10180. +    
  10181. +    if (k) return k; 
  10182. +
  10183. +        printk("%s: no valid drive found\n",name);
  10184. +        return 0;
  10185. +}
  10186. +
  10187. +/* The i/o request engine */
  10188. +
  10189. +static int pd_ready( void )
  10190. +
  10191. +{     int unit = pd_unit;
  10192. +
  10193. +    return (!(RR(1,6) & STAT_BUSY)) ;
  10194. +}
  10195. +
  10196. +static void do_pd_request (void)
  10197. +
  10198. +{       struct buffer_head * bh;
  10199. +    struct request * req;
  10200. +    int    unit;
  10201. +
  10202. +        if (pd_busy) return;
  10203. +repeat:
  10204. +        if ((!CURRENT) || (CURRENT->rq_status == RQ_INACTIVE)) return;
  10205. +        INIT_REQUEST;
  10206. +
  10207. +        pd_dev = MINOR(CURRENT->rq_dev);
  10208. +    pd_unit = unit = DEVICE_NR(CURRENT->rq_dev);
  10209. +        pd_block = CURRENT->sector;
  10210. +        pd_count = CURRENT->nr_sectors;
  10211. +
  10212. +    bh = CURRENT->bh;
  10213. +    req = CURRENT;
  10214. +    if (bh->b_reqnext)
  10215. +        printk("%s: OUCH: b_reqnext != NULL\n",PD.name);
  10216. +
  10217. +        if ((pd_dev >= PD_DEVS) || 
  10218. +        ((pd_block+pd_count) > pd_hd[pd_dev].nr_sects)) {
  10219. +                end_request(0);
  10220. +                goto repeat;
  10221. +        }
  10222. +
  10223. +    pd_cmd = CURRENT->cmd;
  10224. +    pd_run = pd_count;
  10225. +        while ((pd_run <= cluster) &&
  10226. +           (req = req->next) && 
  10227. +           (pd_block+pd_run == req->sector) &&
  10228. +           (pd_cmd == req->cmd) &&
  10229. +           (pd_dev == MINOR(req->rq_dev)))
  10230. +            pd_run += req->nr_sectors;
  10231. +
  10232. +    pd_poffs = pd_hd[pd_dev].start_sect;
  10233. +        pd_block += pd_poffs;
  10234. +        pd_buf = CURRENT->buffer;
  10235. +        pd_retries = 0;
  10236. +
  10237. +    pd_busy = 1;
  10238. +        if (pd_cmd == READ) pi_do_claimed(PI,do_pd_read);
  10239. +        else if (pd_cmd == WRITE) pi_do_claimed(PI,do_pd_write);
  10240. +        else {  pd_busy = 0;
  10241. +        end_request(0);
  10242. +                goto repeat;
  10243. +        }
  10244. +}
  10245. +
  10246. +static void pd_next_buf( int unit )
  10247. +
  10248. +{    long    saved_flags;
  10249. +
  10250. +    spin_lock_irqsave(&io_request_lock,saved_flags);
  10251. +    end_request(1);
  10252. +    if (!pd_run) {  spin_unlock_irqrestore(&io_request_lock,saved_flags);
  10253. +            return; 
  10254. +    }
  10255. +    
  10256. +/* paranoia */
  10257. +
  10258. +    if ((!CURRENT) ||
  10259. +        (CURRENT->cmd != pd_cmd) ||
  10260. +        (MINOR(CURRENT->rq_dev) != pd_dev) ||
  10261. +        (CURRENT->rq_status == RQ_INACTIVE) ||
  10262. +        (CURRENT->sector+pd_poffs != pd_block)) 
  10263. +        printk("%s: OUCH: request list changed unexpectedly\n",
  10264. +            PD.name);
  10265. +
  10266. +    pd_count = CURRENT->nr_sectors;
  10267. +    pd_buf = CURRENT->buffer;
  10268. +    spin_unlock_irqrestore(&io_request_lock,saved_flags);
  10269. +}
  10270. +
  10271. +static void do_pd_read( void )
  10272. +
  10273. +{    ps_set_intr(do_pd_read_start,0,0,nice);
  10274. +}
  10275. +
  10276. +static void do_pd_read_start( void )
  10277. +{       int    unit = pd_unit;
  10278. +    long    saved_flags;
  10279. +
  10280. +    pd_busy = 1;
  10281. +
  10282. +        pi_connect(PI);
  10283. +        if (pd_wait_for(unit,STAT_READY,"do_pd_read") & STAT_ERR) {
  10284. +                pi_disconnect(PI);
  10285. +                if (pd_retries < PD_MAX_RETRIES) {
  10286. +                        pd_retries++;
  10287. +                        pi_do_claimed(PI,do_pd_read_start);
  10288. +            return;
  10289. +                }
  10290. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  10291. +                end_request(0);
  10292. +                pd_busy = 0;
  10293. +                do_pd_request();
  10294. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  10295. +                return;
  10296. +        }
  10297. +        pd_ide_command(unit,IDE_READ,pd_block,pd_run);
  10298. +        ps_set_intr(do_pd_read_drq,pd_ready,PD_TMO,nice);
  10299. +}
  10300. +
  10301. +static void do_pd_read_drq( void )
  10302. +
  10303. +{       int    unit = pd_unit;
  10304. +    long    saved_flags;
  10305. +
  10306. +    while (1) {
  10307. +            if (pd_wait_for(unit,STAT_DRQ,"do_pd_read_drq") & STAT_ERR) {
  10308. +                pi_disconnect(PI);
  10309. +                if (pd_retries < PD_MAX_RETRIES) {
  10310. +                        pd_retries++;
  10311. +                        pi_do_claimed(PI,do_pd_read_start);
  10312. +                        return;
  10313. +                }
  10314. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  10315. +                end_request(0);
  10316. +                pd_busy = 0;
  10317. +                do_pd_request();
  10318. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  10319. +                return;
  10320. +            }
  10321. +            pi_read_block(PI,pd_buf,512);
  10322. +            pd_count--; pd_run--;
  10323. +            pd_buf += 512;
  10324. +        pd_block++;
  10325. +        if (!pd_run) break;
  10326. +        if (!pd_count) pd_next_buf(unit);
  10327. +        }
  10328. +        pi_disconnect(PI);
  10329. +    spin_lock_irqsave(&io_request_lock,saved_flags);
  10330. +        end_request(1);
  10331. +        pd_busy = 0;
  10332. +        do_pd_request();
  10333. +    spin_unlock_irqrestore(&io_request_lock,saved_flags);
  10334. +}
  10335. +
  10336. +static void do_pd_write( void )
  10337. +
  10338. +{     ps_set_intr(do_pd_write_start,0,0,nice);
  10339. +}
  10340. +
  10341. +static void do_pd_write_start( void )
  10342. +
  10343. +{       int     unit = pd_unit;
  10344. +    long    saved_flags;
  10345. +
  10346. +    pd_busy = 1;
  10347. +
  10348. +        pi_connect(PI);
  10349. +        if (pd_wait_for(unit,STAT_READY,"do_pd_write") & STAT_ERR) {
  10350. +                pi_disconnect(PI);
  10351. +                if (pd_retries < PD_MAX_RETRIES) {
  10352. +                        pd_retries++;
  10353. +            pi_do_claimed(PI,do_pd_write_start);
  10354. +                        return;
  10355. +                }
  10356. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  10357. +                end_request(0);
  10358. +                pd_busy = 0;
  10359. +                do_pd_request();
  10360. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  10361. +                return;
  10362. +        }
  10363. +        pd_ide_command(unit,IDE_WRITE,pd_block,pd_run);
  10364. +    while (1) {
  10365. +            if (pd_wait_for(unit,STAT_DRQ,"do_pd_write_drq") & STAT_ERR) {
  10366. +                pi_disconnect(PI);
  10367. +                if (pd_retries < PD_MAX_RETRIES) {
  10368. +                        pd_retries++;
  10369. +                        pi_do_claimed(PI,do_pd_write_start);
  10370. +                        return;
  10371. +                }
  10372. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  10373. +                end_request(0);
  10374. +                pd_busy = 0;
  10375. +                do_pd_request();
  10376. +                spin_unlock_irqrestore(&io_request_lock,saved_flags);
  10377. +        return;
  10378. +            }
  10379. +            pi_write_block(PI,pd_buf,512);
  10380. +        pd_count--; pd_run--;
  10381. +        pd_buf += 512;
  10382. +        pd_block++;
  10383. +        if (!pd_run) break;
  10384. +        if (!pd_count) pd_next_buf(unit);
  10385. +    }
  10386. +        ps_set_intr(do_pd_write_done,pd_ready,PD_TMO,nice);
  10387. +}
  10388. +
  10389. +static void do_pd_write_done( void )
  10390. +
  10391. +{       int    unit = pd_unit;
  10392. +    long    saved_flags;
  10393. +
  10394. +        if (pd_wait_for(unit,STAT_READY,"do_pd_write_done") & STAT_ERR) {
  10395. +                pi_disconnect(PI);
  10396. +                if (pd_retries < PD_MAX_RETRIES) {
  10397. +                        pd_retries++;
  10398. +                        pi_do_claimed(PI,do_pd_write_start);
  10399. +                        return;
  10400. +                }
  10401. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  10402. +                end_request(0);
  10403. +                pd_busy = 0;
  10404. +                do_pd_request();
  10405. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  10406. +                return;
  10407. +        }
  10408. +        pi_disconnect(PI);
  10409. +    spin_lock_irqsave(&io_request_lock,saved_flags);
  10410. +        end_request(1);
  10411. +        pd_busy = 0;
  10412. +        do_pd_request();
  10413. +    spin_unlock_irqrestore(&io_request_lock,saved_flags);
  10414. +}
  10415. +
  10416. +/* end of pd.c */
  10417. +
  10418. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/pf.c linux/drivers/block/paride/pf.c
  10419. --- v2.0.34/linux/drivers/block/paride/pf.c    Wed Dec 31 16:00:00 1969
  10420. +++ linux/drivers/block/paride/pf.c    Mon Jul 13 13:47:28 1998
  10421. @@ -0,0 +1,1080 @@
  10422. +/* 
  10423. +        pf.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  10424. +                            Under the terms of the GNU public license.
  10425. +
  10426. +
  10427. +    Special 2.0.34 version
  10428. +
  10429. +
  10430. +        This is the high-level driver for parallel port ATAPI disk
  10431. +        drives based on chips supported by the paride module.
  10432. +
  10433. +        By default, the driver will autoprobe for a single parallel
  10434. +        port ATAPI disk drive, but if their individual parameters are
  10435. +        specified, the driver can handle up to 4 drives.
  10436. +
  10437. +        The behaviour of the pf driver can be altered by setting
  10438. +        some parameters from the insmod command line.  The following
  10439. +        parameters are adjustable:
  10440. +
  10441. +            drive0      These four arguments can be arrays of       
  10442. +            drive1      1-7 integers as follows:
  10443. +            drive2
  10444. +            drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<lun>,<dly>
  10445. +
  10446. +                        Where,
  10447. +
  10448. +                <prt>   is the base of the parallel port address for
  10449. +                        the corresponding drive.  (required)
  10450. +
  10451. +                <pro>   is the protocol number for the adapter that
  10452. +                        supports this drive.  These numbers are
  10453. +                        logged by 'paride' when the protocol modules
  10454. +                        are initialised.  (0 if not given)
  10455. +
  10456. +                <uni>   for those adapters that support chained
  10457. +                        devices, this is the unit selector for the
  10458. +                        chain of devices on the given port.  It should
  10459. +                        be zero for devices that don't support chaining.
  10460. +                        (0 if not given)
  10461. +
  10462. +                <mod>   this can be -1 to choose the best mode, or one
  10463. +                        of the mode numbers supported by the adapter.
  10464. +                        (-1 if not given)
  10465. +
  10466. +                <slv>   ATAPI CDroms can be jumpered to master or slave.
  10467. +                        Set this to 0 to choose the master drive, 1 to
  10468. +                        choose the slave, -1 (the default) to choose the
  10469. +                        first drive found.
  10470. +
  10471. +        <lun>   Some ATAPI devices support multiple LUNs.
  10472. +                        One example is the ATAPI PD/CD drive from
  10473. +                        Matshita/Panasonic.  This device has a 
  10474. +                        CD drive on LUN 0 and a PD drive on LUN 1.
  10475. +                        By default, the driver will search for the
  10476. +                        first LUN with a supported device.  Set 
  10477. +                        this parameter to force it to use a specific
  10478. +                        LUN.  (default -1)
  10479. +
  10480. +                <dly>   some parallel ports require the driver to 
  10481. +                        go more slowly.  -1 sets a default value that
  10482. +                        should work with the chosen protocol.  Otherwise,
  10483. +                        set this to a small integer, the larger it is
  10484. +                        the slower the port i/o.  In some cases, setting
  10485. +                        this to zero will speed up the device. (default -1)
  10486. +
  10487. +        major    You may use this parameter to overide the
  10488. +            default major number (47) that this driver
  10489. +            will use.  Be sure to change the device
  10490. +            name as well.
  10491. +
  10492. +        name    This parameter is a character string that
  10493. +            contains the name the kernel will use for this
  10494. +            device (in /proc output, for instance).
  10495. +            (default "pf").
  10496. +
  10497. +            cluster     The driver will attempt to aggregate requests
  10498. +                        for adjacent blocks into larger multi-block
  10499. +                        clusters.  The maximum cluster size (in 512
  10500. +                        byte sectors) is set with this parameter.
  10501. +                        (default 64)
  10502. +
  10503. +            verbose     This parameter controls the amount of logging
  10504. +                        that is done while the driver probes for
  10505. +                        devices.  Set it to 0 for a quiet load, or 1 to
  10506. +                        see all the progress messages.  (default 0)
  10507. +
  10508. +        nice        This parameter controls the driver's use of
  10509. +            idle CPU time, at the expense of some speed.
  10510. +
  10511. +        If this driver is built into the kernel, you can use the
  10512. +        following command line parameters, with the same values
  10513. +        as the corresponding module parameters listed above:
  10514. +
  10515. +            pf.drive0
  10516. +            pf.drive1
  10517. +            pf.drive2
  10518. +            pf.drive3
  10519. +        pf.cluster
  10520. +            pf.nice
  10521. +
  10522. +        In addition, you can use the parameter pf.disable to disable
  10523. +        the driver entirely.
  10524. +
  10525. +*/
  10526. +
  10527. +/* Changes:
  10528. +
  10529. +    1.01    GRG 1998.05.03  Changes for SMP.  Eliminate sti().
  10530. +                Fix for drives that don't clear STAT_ERR
  10531. +                    until after next CDB delivered.
  10532. +                Small change in pf_completion to round
  10533. +                up transfer size.
  10534. +    1.02    GRG 1998.06.16  Eliminated an Ugh
  10535. +
  10536. +*/
  10537. +
  10538. +#define PF_VERSION      "1.02s"
  10539. +#define PF_MAJOR    47
  10540. +#define PF_NAME        "pf"
  10541. +#define PF_UNITS    4
  10542. +
  10543. +/* Here are things one can override from the insmod command.
  10544. +   Most are autoprobed by paride unless set here.  Verbose is off
  10545. +   by default.
  10546. +
  10547. +*/
  10548. +
  10549. +static int    verbose = 0;
  10550. +static int    major = PF_MAJOR;
  10551. +static char    *name = PF_NAME;
  10552. +static int      cluster = 64;
  10553. +static int      nice = 0;
  10554. +static int      disable = 0;
  10555. +
  10556. +static int drive0[7] = {0,0,0,-1,-1,-1,-1};
  10557. +static int drive1[7] = {0,0,0,-1,-1,-1,-1};
  10558. +static int drive2[7] = {0,0,0,-1,-1,-1,-1};
  10559. +static int drive3[7] = {0,0,0,-1,-1,-1,-1};
  10560. +
  10561. +static int (*drives[4])[7] = {&drive0,&drive1,&drive2,&drive3};
  10562. +static int pf_drive_count;
  10563. +
  10564. +#define D_PRT   0
  10565. +#define D_PRO   1
  10566. +#define D_UNI   2
  10567. +#define D_MOD   3
  10568. +#define D_SLV   4
  10569. +#define D_LUN   5
  10570. +#define D_DLY   6
  10571. +
  10572. +#define DU              (*drives[unit])
  10573. +
  10574. +/* end of parameters */
  10575. +
  10576. +
  10577. +#include <linux/module.h>
  10578. +#include <linux/errno.h>
  10579. +#include <linux/fs.h>
  10580. +#include <linux/kernel.h>
  10581. +#include <linux/delay.h>
  10582. +#include <linux/genhd.h>
  10583. +#include <linux/hdreg.h>
  10584. +#include <linux/cdrom.h>
  10585. +#include "spinlock.h"
  10586. +
  10587. +#include <asm/segment.h>
  10588. +
  10589. +#ifndef MODULE
  10590. +
  10591. +#include "setup.h"
  10592. +
  10593. +static STT pf_stt[7] = {{"drive0",7,drive0},
  10594. +                        {"drive1",7,drive1},
  10595. +                        {"drive2",7,drive2},
  10596. +                        {"drive3",7,drive3},
  10597. +            {"disable",1,&disable},
  10598. +                        {"cluster",1,&cluster},
  10599. +                        {"nice",1,&nice}};
  10600. +
  10601. +void pf_setup( char *str, int *ints)
  10602. +
  10603. +{       generic_setup(pf_stt,7,str);
  10604. +}
  10605. +
  10606. +#endif
  10607. +
  10608. +#include "paride.h"
  10609. +
  10610. +/* set up defines for blk.h,  why don't all drivers do it this way ? */
  10611. +
  10612. +#define MAJOR_NR   major
  10613. +#define DEVICE_NAME "PF"
  10614. +#define DEVICE_REQUEST do_pf_request
  10615. +#define DEVICE_NR(device) MINOR(device)
  10616. +#define DEVICE_ON(device)
  10617. +#define DEVICE_OFF(device)
  10618. +
  10619. +#include <linux/blk.h>
  10620. +
  10621. +#include "pseudo.h"
  10622. +
  10623. +/* constants for faking geometry numbers */
  10624. +
  10625. +#define PF_FD_MAX    8192        /* use FD geometry under this size */
  10626. +#define PF_FD_HDS    2
  10627. +#define PF_FD_SPT    18
  10628. +#define PF_HD_HDS    64
  10629. +#define PF_HD_SPT    32
  10630. +
  10631. +#define PF_MAX_RETRIES  5
  10632. +#define PF_TMO          800             /* interrupt timeout in jiffies */
  10633. +#define PF_SPIN_DEL     50              /* spin delay in micro-seconds  */
  10634. +
  10635. +#define PF_SPIN         (10000/PF_SPIN_DEL)*PF_TMO  
  10636. +
  10637. +#define STAT_ERR        0x00001
  10638. +#define STAT_INDEX      0x00002
  10639. +#define STAT_ECC        0x00004
  10640. +#define STAT_DRQ        0x00008
  10641. +#define STAT_SEEK       0x00010
  10642. +#define STAT_WRERR      0x00020
  10643. +#define STAT_READY      0x00040
  10644. +#define STAT_BUSY       0x00080
  10645. +
  10646. +#define ATAPI_REQ_SENSE        0x03
  10647. +#define ATAPI_LOCK        0x1e
  10648. +#define ATAPI_DOOR        0x1b
  10649. +#define ATAPI_MODE_SENSE    0x5a
  10650. +#define ATAPI_CAPACITY        0x25
  10651. +#define ATAPI_IDENTIFY        0x12
  10652. +#define ATAPI_READ_10        0x28
  10653. +#define ATAPI_WRITE_10        0x2a
  10654. +
  10655. +int pf_init(void);
  10656. +#ifdef MODULE
  10657. +void cleanup_module( void );
  10658. +#endif
  10659. +static int pf_open(struct inode *inode, struct file *file);
  10660. +static void do_pf_request(void);
  10661. +static int pf_ioctl(struct inode *inode,struct file *file,
  10662. +                    unsigned int cmd, unsigned long arg);
  10663. +
  10664. +static void pf_release (struct inode *inode, struct file *file);
  10665. +
  10666. +static int pf_detect(void);
  10667. +static void do_pf_read(void);
  10668. +static void do_pf_read_start(void);
  10669. +static void do_pf_write(void);
  10670. +static void do_pf_write_start(void);
  10671. +static void do_pf_read_drq( void );
  10672. +static void do_pf_write_done( void );
  10673. +
  10674. +static int pf_identify (int unit);
  10675. +static void pf_lock(int unit, int func);
  10676. +static void pf_eject(int unit);
  10677. +static int pf_check_media(kdev_t dev);
  10678. +
  10679. +static int pf_blocksizes[PF_UNITS];
  10680. +
  10681. +#define PF_NM           0
  10682. +#define PF_RO           1
  10683. +#define PF_RW           2
  10684. +
  10685. +#define PF_NAMELEN      8
  10686. +
  10687. +struct pf_unit {
  10688. +    struct pi_adapter pia;    /* interface to paride layer */
  10689. +    struct pi_adapter *pi;
  10690. +    int removable;          /* removable media device  ?  */
  10691. +    int media_status;      /* media present ?  WP ? */
  10692. +    int drive;          /* drive */
  10693. +    int lun;
  10694. +    int access;               /* count of active opens ... */
  10695. +    int capacity;             /* Size of this volume in sectors */
  10696. +    int present;          /* device present ? */
  10697. +    char name[PF_NAMELEN];      /* pf0, pf1, ... */
  10698. +    };
  10699. +
  10700. +struct pf_unit pf[PF_UNITS];
  10701. +
  10702. +/*  'unit' must be defined in all functions - either as a local or a param */
  10703. +
  10704. +#define PF pf[unit]
  10705. +#define PI PF.pi
  10706. +
  10707. +static char pf_scratch[512];            /* scratch block buffer */
  10708. +
  10709. +/* the variables below are used mainly in the I/O request engine, which
  10710. +   processes only one request at a time.
  10711. +*/
  10712. +
  10713. +static int pf_retries = 0;              /* i/o error retry count */
  10714. +static int pf_busy = 0;                 /* request being processed ? */
  10715. +static int pf_block;                    /* address of next requested block */
  10716. +static int pf_count;                    /* number of blocks still to do */
  10717. +static int pf_run;            /* sectors in current cluster */
  10718. +static int pf_cmd;            /* current command READ/WRITE */
  10719. +static int pf_unit;            /* unit of current request */
  10720. +static int pf_mask;            /* stopper for pseudo-int */
  10721. +static char * pf_buf;                   /* buffer for request in progress */
  10722. +
  10723. +/* kernel glue structures */
  10724. +
  10725. +static struct file_operations pf_fops = {
  10726. +        NULL,                   /* lseek - default */
  10727. +        block_read,             /* read - general block-dev read */
  10728. +        block_write,            /* write - general block-dev write */
  10729. +        NULL,                   /* readdir - bad */
  10730. +        NULL,                   /* select */
  10731. +        pf_ioctl,               /* ioctl */
  10732. +        NULL,                   /* mmap */
  10733. +        pf_open,                /* open */
  10734. +        pf_release,             /* release */
  10735. +        block_fsync,            /* fsync */
  10736. +        NULL,                   /* fasync */
  10737. +        pf_check_media,         /* media change ? */
  10738. +        NULL                    /* revalidate new media */
  10739. +};
  10740. +
  10741. +void pf_init_units( void )
  10742. +
  10743. +{       int     unit, j;
  10744. +
  10745. +        pf_drive_count = 0;
  10746. +        for (unit=0;unit<PF_UNITS;unit++) {
  10747. +                PF.pi = & PF.pia;
  10748. +                PF.access = 0;
  10749. +                PF.media_status = PF_NM;
  10750. +                PF.capacity = 0;
  10751. +                PF.present = 0;
  10752. +        PF.drive = DU[D_SLV];
  10753. +        PF.lun = DU[D_LUN];
  10754. +                j = 0;
  10755. +                while ((j < PF_NAMELEN-2) && (PF.name[j]=name[j])) j++;
  10756. +                PF.name[j++] = '0' + unit;
  10757. +                PF.name[j] = 0;
  10758. +                if (DU[D_PRT]) pf_drive_count++;
  10759. +        }
  10760. +} 
  10761. +
  10762. +int pf_init (void)      /* preliminary initialisation */
  10763. +
  10764. +{       int i;
  10765. +
  10766. +    if (disable) return -1;
  10767. +
  10768. +    pf_init_units();
  10769. +
  10770. +    if (pf_detect()) return -1;
  10771. +    pf_busy = 0;
  10772. +
  10773. +        if (register_blkdev(MAJOR_NR,name,&pf_fops)) {
  10774. +                printk("pf_init: unable to get major number %d\n",
  10775. +                        major);
  10776. +                return -1;
  10777. +        }
  10778. +        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
  10779. +        read_ahead[MAJOR_NR] = 8;       /* 8 sector (4kB) read ahead */
  10780. +        
  10781. +    for (i=0;i<PF_UNITS;i++) pf_blocksizes[i] = 1024;
  10782. +    blksize_size[MAJOR_NR] = pf_blocksizes;
  10783. +
  10784. +        return 0;
  10785. +}
  10786. +
  10787. +static int pf_open (struct inode *inode, struct file *file)
  10788. +
  10789. +{       int    unit = DEVICE_NR(inode->i_rdev);
  10790. +
  10791. +        if ((unit >= PF_UNITS) || (!PF.present)) return -ENODEV;
  10792. +
  10793. +        MOD_INC_USE_COUNT;
  10794. +
  10795. +    pf_identify(unit);
  10796. +
  10797. +    if (PF.media_status == PF_NM) {
  10798. +        MOD_DEC_USE_COUNT;
  10799. +        return -ENODEV;
  10800. +        }
  10801. +
  10802. +    if ((PF.media_status == PF_RO) && (file ->f_mode & 2)) {
  10803. +        MOD_DEC_USE_COUNT;
  10804. +        return -EROFS;
  10805. +        }
  10806. +
  10807. +        PF.access++;
  10808. +        if (PF.removable) pf_lock(unit,1);
  10809. +
  10810. +        return 0;
  10811. +}
  10812. +
  10813. +static int pf_ioctl(struct inode *inode,struct file *file,
  10814. +                    unsigned int cmd, unsigned long arg)
  10815. +
  10816. +{       int err, unit;
  10817. +    struct hd_geometry *geo = (struct hd_geometry *) arg;
  10818. +
  10819. +        if ((!inode) || (!inode->i_rdev)) return -EINVAL;
  10820. +        unit = DEVICE_NR(inode->i_rdev);
  10821. +        if (unit >= PF_UNITS) return -EINVAL;
  10822. +        if (!PF.present) return -ENODEV;
  10823. +
  10824. +        switch (cmd) {
  10825. +        case CDROMEJECT: 
  10826. +        if (PF.access == 1) {
  10827. +            pf_eject(unit);
  10828. +            return 0;
  10829. +            }
  10830. +        case HDIO_GETGEO:
  10831. +                if (!geo) return -EINVAL;
  10832. +                err = verify_area(VERIFY_WRITE,geo,sizeof(*geo));
  10833. +                if (err) return err;
  10834. +                if (PF.capacity < PF_FD_MAX) {
  10835. +                    put_user(PF.capacity/(PF_FD_HDS*PF_FD_SPT),
  10836. +                                (short *) &geo->cylinders);
  10837. +                    put_user(PF_FD_HDS, (char *) &geo->heads);
  10838. +                    put_user(PF_FD_SPT, (char *) &geo->sectors);
  10839. +                } else {
  10840. +                    put_user(PF.capacity/(PF_HD_HDS*PF_HD_SPT), 
  10841. +                (short *) &geo->cylinders);
  10842. +                    put_user(PF_HD_HDS, (char *) &geo->heads);
  10843. +                    put_user(PF_HD_SPT, (char *) &geo->sectors);
  10844. +                }
  10845. +                put_user(0,(long *)&geo->start);
  10846. +                return 0;
  10847. +            case BLKRASET:
  10848. +                if(!suser()) return -EACCES;
  10849. +                if(!(inode->i_rdev)) return -EINVAL;
  10850. +                if(arg > 0xff) return -EINVAL;
  10851. +                read_ahead[MAJOR(inode->i_rdev)] = arg;
  10852. +                return 0;
  10853. +            case BLKRAGET:
  10854. +                if (!arg) return -EINVAL;
  10855. +                err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));
  10856. +                if (err) return (err);
  10857. +                put_user(read_ahead[MAJOR(inode->i_rdev)],(long *) arg);
  10858. +                return (0);
  10859. +            case BLKGETSIZE:
  10860. +                if (!arg) return -EINVAL;
  10861. +                err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));
  10862. +                if (err) return (err);
  10863. +                put_user(PF.capacity,(long *) arg);
  10864. +                return (0);
  10865. +            case BLKFLSBUF:
  10866. +                if(!suser())  return -EACCES;
  10867. +                if(!(inode->i_rdev)) return -EINVAL;
  10868. +                fsync_dev(inode->i_rdev);
  10869. +                invalidate_buffers(inode->i_rdev);
  10870. +                return 0;
  10871. +            RO_IOCTLS(inode->i_rdev,arg);
  10872. +            default:
  10873. +                return -EINVAL;
  10874. +        }
  10875. +}
  10876. +
  10877. +
  10878. +static void pf_release (struct inode *inode, struct file *file)
  10879. +
  10880. +{       kdev_t devp;
  10881. +    int    unit;
  10882. +
  10883. +        devp = inode->i_rdev;
  10884. +        unit = DEVICE_NR(devp);
  10885. +
  10886. +        if ((unit >= PF_UNITS) || (PF.access <= 0)) 
  10887. +                return;
  10888. +
  10889. +    PF.access--;
  10890. +
  10891. +    if (!PF.access) {
  10892. +                fsync_dev(devp);
  10893. +
  10894. +        invalidate_inodes(devp);
  10895. +
  10896. +                invalidate_buffers(devp);
  10897. +        if (PF.removable) pf_lock(unit,0);
  10898. +        }
  10899. +
  10900. +        MOD_DEC_USE_COUNT;
  10901. +
  10902. +}
  10903. +
  10904. +static int pf_check_media( kdev_t dev)
  10905. +
  10906. +{       return 1;
  10907. +}
  10908. +
  10909. +#ifdef MODULE
  10910. +
  10911. +/* Glue for modules ... */
  10912. +
  10913. +void    cleanup_module(void);
  10914. +
  10915. +int     init_module(void)
  10916. +
  10917. +{       int     err;
  10918. +
  10919. +        err = pf_init();
  10920. +
  10921. +        return err;
  10922. +}
  10923. +
  10924. +void    cleanup_module(void)
  10925. +
  10926. +{       int unit;
  10927. +
  10928. +        unregister_blkdev(MAJOR_NR,name);
  10929. +
  10930. +    for (unit=0;unit<PF_UNITS;unit++)
  10931. +      if (PF.present) pi_release(PI);
  10932. +}
  10933. +
  10934. +#endif
  10935. +
  10936. +#define    WR(c,r,v)    pi_write_regr(PI,c,r,v)
  10937. +#define    RR(c,r)        (pi_read_regr(PI,c,r))
  10938. +
  10939. +#define LUN             (0x20*PF.lun)
  10940. +#define DRIVE           (0xa0+0x10*PF.drive)
  10941. +
  10942. +static int pf_wait( int unit, int go, int stop, char * fun, char * msg )
  10943. +
  10944. +{       int j, r, e, s, p;
  10945. +
  10946. +        j = 0;
  10947. +        while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PF_SPIN))
  10948. +                udelay(PF_SPIN_DEL);
  10949. +
  10950. +        if ((r&(STAT_ERR&stop))||(j>=PF_SPIN)) {
  10951. +           s = RR(0,7);
  10952. +           e = RR(0,1);
  10953. +           p = RR(0,2);
  10954. +           if (j >= PF_SPIN) e |= 0x100;
  10955. +           if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
  10956. +                           " loop=%d phase=%d\n",
  10957. +                            PF.name,fun,msg,r,s,e,j,p);
  10958. +           return (e<<8)+s;
  10959. +        }
  10960. +        return 0;
  10961. +}
  10962. +
  10963. +static int pf_command( int unit, char * cmd, int dlen, char * fun )
  10964. +
  10965. +{       pi_connect(PI);
  10966. +
  10967. +        WR(0,6,DRIVE);
  10968. +
  10969. +        if (pf_wait(unit,STAT_BUSY|STAT_DRQ,0,fun,"before command")) {
  10970. +                pi_disconnect(PI);
  10971. +                return -1;
  10972. +        }
  10973. +
  10974. +        WR(0,4,dlen % 256);
  10975. +        WR(0,5,dlen / 256);
  10976. +        WR(0,7,0xa0);          /* ATAPI packet command */
  10977. +
  10978. +        if (pf_wait(unit,STAT_BUSY,STAT_DRQ,fun,"command DRQ")) {
  10979. +                pi_disconnect(PI);
  10980. +                return -1;
  10981. +        }
  10982. +
  10983. +        if (RR(0,2) != 1) {
  10984. +           printk("%s: %s: command phase error\n",PF.name,fun);
  10985. +           pi_disconnect(PI);
  10986. +           return -1;
  10987. +        }
  10988. +
  10989. +        pi_write_block(PI,cmd,12);
  10990. +
  10991. +        return 0;
  10992. +}
  10993. +
  10994. +static int pf_completion( int unit, char * buf, char * fun )
  10995. +
  10996. +{       int r, s, n;
  10997. +
  10998. +        r = pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
  10999. +            fun,"completion");
  11000. +
  11001. +        if ((RR(0,2)&2) && (RR(0,7)&STAT_DRQ)) { 
  11002. +                n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
  11003. +                pi_read_block(PI,buf,n);
  11004. +        }
  11005. +
  11006. +        s = pf_wait(unit,STAT_BUSY,STAT_READY|STAT_ERR,fun,"data done");
  11007. +
  11008. +        pi_disconnect(PI); 
  11009. +
  11010. +        return (r?r:s);
  11011. +}
  11012. +
  11013. +static void pf_req_sense( int unit, int quiet )
  11014. +
  11015. +{       char    rs_cmd[12] = { ATAPI_REQ_SENSE,LUN,0,0,16,0,0,0,0,0,0,0 };
  11016. +        char    buf[16];
  11017. +        int     r;
  11018. +
  11019. +        r = pf_command(unit,rs_cmd,16,"Request sense");
  11020. +        udelay(1000);
  11021. +        if (!r) pf_completion(unit,buf,"Request sense");
  11022. +
  11023. +        if ((!r)&&(!quiet)) 
  11024. +                printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
  11025. +                       PF.name,buf[2]&0xf,buf[12],buf[13]);
  11026. +}
  11027. +
  11028. +static int pf_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
  11029. +
  11030. +{       int r;
  11031. +
  11032. +        r = pf_command(unit,cmd,dlen,fun);
  11033. +        udelay(1000);
  11034. +        if (!r) r = pf_completion(unit,buf,fun);
  11035. +        if (r) pf_req_sense(unit,!fun);
  11036. +        
  11037. +        return r;
  11038. +}
  11039. +
  11040. +#define DBMSG(msg)      NULL
  11041. +
  11042. +static void pf_lock(int unit, int func)
  11043. +
  11044. +{    char    lo_cmd[12] = { ATAPI_LOCK,LUN,0,0,func,0,0,0,0,0,0,0 };
  11045. +
  11046. +        pf_atapi(unit,lo_cmd,0,pf_scratch,func?"unlock":"lock");
  11047. +}
  11048. +
  11049. +
  11050. +static void pf_eject( int unit )
  11051. +
  11052. +{    char    ej_cmd[12] = { ATAPI_DOOR,LUN,0,0,2,0,0,0,0,0,0,0 };
  11053. +
  11054. +    pf_lock(unit,0);
  11055. +    pf_atapi(unit,ej_cmd,0,pf_scratch,"eject");
  11056. +}
  11057. +
  11058. +#define PF_RESET_TMO   30              /* in tenths of a second */
  11059. +
  11060. +static void pf_sleep( int cs )
  11061. +
  11062. +{       current->state = TASK_INTERRUPTIBLE;
  11063. +        current->timeout = jiffies + cs;
  11064. +        schedule();
  11065. +}
  11066. +
  11067. +
  11068. +static int pf_reset( int unit )
  11069. +
  11070. +/* the ATAPI standard actually specifies the contents of all 7 registers
  11071. +   after a reset, but the specification is ambiguous concerning the last
  11072. +   two bytes, and different drives interpret the standard differently.
  11073. +*/
  11074. +
  11075. +{    int    i, k, flg;
  11076. +    int    expect[5] = {1,1,1,0x14,0xeb};
  11077. +
  11078. +    pi_connect(PI);
  11079. +    WR(0,6,DRIVE);
  11080. +    WR(0,7,8);
  11081. +
  11082. +    pf_sleep(2);
  11083. +
  11084. +        k = 0;
  11085. +        while ((k++ < PF_RESET_TMO) && (RR(1,6)&STAT_BUSY))
  11086. +                pf_sleep(10);
  11087. +
  11088. +    flg = 1;
  11089. +    for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
  11090. +
  11091. +    if (verbose) {
  11092. +        printk("%s: Reset (%d) signature = ",PF.name,k);
  11093. +        for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
  11094. +        if (!flg) printk(" (incorrect)");
  11095. +        printk("\n");
  11096. +    }
  11097. +    
  11098. +    pi_disconnect(PI);
  11099. +    return flg-1;    
  11100. +}
  11101. +
  11102. +static void pf_mode_sense( int unit )
  11103. +
  11104. +{       char    ms_cmd[12] = { ATAPI_MODE_SENSE,LUN,0,0,0,0,0,0,8,0,0,0};
  11105. +    char    buf[8];
  11106. +
  11107. +        pf_atapi(unit,ms_cmd,8,buf,DBMSG("mode sense"));
  11108. +    PF.media_status = PF_RW;
  11109. +    if (buf[3] & 0x80) PF.media_status = PF_RO;
  11110. +}
  11111. +
  11112. +static void xs( char *buf, char *targ, int offs, int len )
  11113. +
  11114. +{    int    j,k,l;
  11115. +
  11116. +    j=0; l=0;
  11117. +    for (k=0;k<len;k++) 
  11118. +       if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
  11119. +        l=targ[j++]=buf[k+offs];
  11120. +    if (l==0x20) j--; targ[j]=0;
  11121. +}
  11122. +
  11123. +static int xl( char *buf, int offs )
  11124. +
  11125. +{    int    v,k;
  11126. +
  11127. +    v=0; 
  11128. +    for(k=0;k<4;k++) v=v*256+(buf[k+offs]&0xff);
  11129. +    return v;
  11130. +}
  11131. +
  11132. +static void pf_get_capacity( int unit )
  11133. +
  11134. +{    char    rc_cmd[12] = { ATAPI_CAPACITY,LUN,0,0,0,0,0,0,0,0,0,0};
  11135. +    char    buf[8];
  11136. +        int     bs;
  11137. +
  11138. +    if (pf_atapi(unit,rc_cmd,8,buf,DBMSG("get capacity"))) {
  11139. +        PF.media_status = PF_NM;
  11140. +        return;
  11141. +    }
  11142. +    PF.capacity = xl(buf,0) + 1;  
  11143. +    bs = xl(buf,4);
  11144. +    if (bs != 512) {
  11145. +        PF.capacity = 0;
  11146. +        if (verbose) printk("%s: Drive %d, LUN %d,"
  11147. +                           " unsupported block size %d\n",
  11148. +                        PF.name,PF.drive,PF.lun,bs);
  11149. +        }
  11150. +}
  11151. +
  11152. +static int pf_identify( int unit )
  11153. +
  11154. +{    int     dt, s;
  11155. +    char    *ms[2] = {"master","slave"};
  11156. +    char    mf[10], id[18];
  11157. +    char    id_cmd[12] = { ATAPI_IDENTIFY,LUN,0,0,36,0,0,0,0,0,0,0};
  11158. +    char    buf[36];
  11159. +
  11160. +        s = pf_atapi(unit,id_cmd,36,buf,"identify");
  11161. +    if (s) return -1;
  11162. +
  11163. +    dt = buf[0] & 0x1f;
  11164. +    if ((dt != 0) && (dt != 7)) {
  11165. +          if (verbose) 
  11166. +           printk("%s: Drive %d, LUN %d, unsupported type %d\n",
  11167. +                PF.name,PF.drive,PF.lun,dt);
  11168. +          return -1;
  11169. +           }
  11170. +
  11171. +    xs(buf,mf,8,8);
  11172. +    xs(buf,id,16,16);
  11173. +
  11174. +    PF.removable = (buf[1] & 0x80);
  11175. +
  11176. +    pf_mode_sense(unit);
  11177. +    pf_mode_sense(unit);
  11178. +    pf_mode_sense(unit);
  11179. +
  11180. +    pf_get_capacity(unit);
  11181. +
  11182. +        printk("%s: %s %s, %s LUN %d, type %d",
  11183. +        PF.name,mf,id,ms[PF.drive],PF.lun,dt);
  11184. +        if (PF.removable) printk(", removable");
  11185. +        if (PF.media_status == PF_NM) 
  11186. +                printk(", no media\n");
  11187. +        else {  if (PF.media_status == PF_RO) printk(", RO");
  11188. +                printk(", %d blocks\n",PF.capacity);
  11189. +        }
  11190. +
  11191. +    return 0;
  11192. +}
  11193. +
  11194. +static int pf_probe( int unit )
  11195. +
  11196. +/*    returns  0, with id set if drive is detected
  11197. +            -1, if drive detection failed
  11198. +*/
  11199. +
  11200. +{    if (PF.drive == -1) {
  11201. +       for (PF.drive=0;PF.drive<=1;PF.drive++)
  11202. +        if (!pf_reset(unit)) {
  11203. +           if (PF.lun != -1) return pf_identify(unit);
  11204. +           else for (PF.lun=0;PF.lun<8;PF.lun++) 
  11205. +                           if (!pf_identify(unit)) return 0;
  11206. +        }
  11207. +    } else {
  11208. +       if (pf_reset(unit)) return -1;
  11209. +       if (PF.lun != -1) return pf_identify(unit);
  11210. +       for (PF.lun=0;PF.lun<8;PF.lun++) 
  11211. +          if (!pf_identify(unit)) return 0;
  11212. +    }
  11213. +        return -1; 
  11214. +}
  11215. +
  11216. +static int pf_detect( void )
  11217. +
  11218. +{    int    k, unit;
  11219. +
  11220. +    printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
  11221. +        name,name,PF_VERSION,major,cluster,nice);
  11222. +
  11223. +    k = 0;
  11224. +    if (pf_drive_count == 0) {
  11225. +        unit = 0;
  11226. +        if (pi_init(PI,1,-1,-1,-1,-1,-1,pf_scratch,
  11227. +                        PI_PF,verbose,PF.name)) {
  11228. +            if (!pf_probe(unit)) {
  11229. +            PF.present = 1;
  11230. +            k++;
  11231. +            } else pi_release(PI);
  11232. +        }
  11233. +
  11234. +    } else for (unit=0;unit<PF_UNITS;unit++) if (DU[D_PRT])
  11235. +        if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
  11236. +            DU[D_PRO],DU[D_DLY],pf_scratch,PI_PF,verbose,
  11237. +            PF.name)) { 
  11238. +                if (!pf_probe(unit)) {
  11239. +                        PF.present = 1;
  11240. +                        k++;
  11241. +                } else pi_release(PI);
  11242. +            }
  11243. +
  11244. +    if (k) return 0;
  11245. +
  11246. +    printk("%s: No ATAPI disk detected\n",name);
  11247. +    return -1;
  11248. +}
  11249. +
  11250. +/* The i/o request engine */
  11251. +
  11252. +static int pf_start( int unit, int cmd, int b, int c )
  11253. +
  11254. +{    int    i;
  11255. +    char    io_cmd[12] = {cmd,LUN,0,0,0,0,0,0,0,0,0,0};
  11256. +
  11257. +    for(i=0;i<4;i++) { 
  11258. +       io_cmd[5-i] = b & 0xff;
  11259. +       b = b >> 8;
  11260. +    }
  11261. +    
  11262. +    io_cmd[8] = c & 0xff;
  11263. +    io_cmd[7] = (c >> 8) & 0xff;
  11264. +
  11265. +    i = pf_command(unit,io_cmd,c*512,"start i/o");
  11266. +
  11267. +        udelay(1000);
  11268. +
  11269. +    return i;    
  11270. +}
  11271. +
  11272. +static int pf_ready( void )
  11273. +
  11274. +{    int    unit = pf_unit;
  11275. +
  11276. +    return (((RR(1,6)&(STAT_BUSY|pf_mask)) == pf_mask));
  11277. +}
  11278. +
  11279. +static void do_pf_request (void)
  11280. +
  11281. +{       struct buffer_head * bh;
  11282. +    struct request * req;
  11283. +    int unit;
  11284. +
  11285. +        if (pf_busy) return;
  11286. +repeat:
  11287. +        if ((!CURRENT) || (CURRENT->rq_status == RQ_INACTIVE)) return;
  11288. +        INIT_REQUEST;
  11289. +
  11290. +        pf_unit = unit = DEVICE_NR(CURRENT->rq_dev);
  11291. +        pf_block = CURRENT->sector;
  11292. +        pf_count = CURRENT->nr_sectors;
  11293. +
  11294. +    bh = CURRENT->bh;
  11295. +    req = CURRENT;
  11296. +    if (bh->b_reqnext)
  11297. +        printk("%s: OUCH: b_reqnext != NULL\n",PF.name);
  11298. +
  11299. +        if ((pf_unit >= PF_UNITS) || (pf_block+pf_count > PF.capacity)) {
  11300. +                end_request(0);
  11301. +                goto repeat;
  11302. +        }
  11303. +
  11304. +    pf_cmd = CURRENT->cmd;
  11305. +    pf_run = pf_count;
  11306. +        while ((pf_run <= cluster) &&
  11307. +           (req = req->next) && 
  11308. +           (pf_block+pf_run == req->sector) &&
  11309. +           (pf_cmd == req->cmd) &&
  11310. +           (pf_unit == DEVICE_NR(req->rq_dev)))
  11311. +            pf_run += req->nr_sectors;
  11312. +
  11313. +        pf_buf = CURRENT->buffer;
  11314. +        pf_retries = 0;
  11315. +
  11316. +    pf_busy = 1;
  11317. +        if (pf_cmd == READ) pi_do_claimed(PI,do_pf_read);
  11318. +        else if (pf_cmd == WRITE) pi_do_claimed(PI,do_pf_write);
  11319. +        else {  pf_busy = 0;
  11320. +        end_request(0);
  11321. +                goto repeat;
  11322. +        }
  11323. +}
  11324. +
  11325. +static void pf_next_buf( int unit )
  11326. +
  11327. +{    long    saved_flags;
  11328. +
  11329. +    spin_lock_irqsave(&io_request_lock,saved_flags);
  11330. +    end_request(1);
  11331. +    if (!pf_run) { spin_unlock_irqrestore(&io_request_lock,saved_flags);
  11332. +               return; 
  11333. +    }
  11334. +    
  11335. +/* paranoia */
  11336. +
  11337. +    if ((!CURRENT) ||
  11338. +        (CURRENT->cmd != pf_cmd) ||
  11339. +        (DEVICE_NR(CURRENT->rq_dev) != pf_unit) ||
  11340. +        (CURRENT->rq_status == RQ_INACTIVE) ||
  11341. +        (CURRENT->sector != pf_block)) 
  11342. +        printk("%s: OUCH: request list changed unexpectedly\n",
  11343. +            PF.name);
  11344. +
  11345. +    pf_count = CURRENT->nr_sectors;
  11346. +    pf_buf = CURRENT->buffer;
  11347. +    spin_unlock_irqrestore(&io_request_lock,saved_flags);
  11348. +}
  11349. +
  11350. +static void do_pf_read( void )
  11351. +
  11352. +/* detach from the calling context - in case the spinlock is held */
  11353. +
  11354. +{    ps_set_intr(do_pf_read_start,0,0,nice);
  11355. +}
  11356. +
  11357. +static void do_pf_read_start( void )
  11358. +
  11359. +{       int    unit = pf_unit;
  11360. +    long    saved_flags;
  11361. +
  11362. +    pf_busy = 1;
  11363. +
  11364. +    if (pf_start(unit,ATAPI_READ_10,pf_block,pf_run)) {
  11365. +                pi_disconnect(PI);
  11366. +                if (pf_retries < PF_MAX_RETRIES) {
  11367. +                        pf_retries++;
  11368. +                        pi_do_claimed(PI,do_pf_read_start);
  11369. +            return;
  11370. +                }
  11371. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  11372. +                end_request(0);
  11373. +                pf_busy = 0;
  11374. +                do_pf_request();
  11375. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  11376. +                return;
  11377. +        }
  11378. +    pf_mask = STAT_DRQ;
  11379. +        ps_set_intr(do_pf_read_drq,pf_ready,PF_TMO,nice);
  11380. +}
  11381. +
  11382. +static void do_pf_read_drq( void )
  11383. +
  11384. +{       int    unit = pf_unit;
  11385. +    long    saved_flags;
  11386. +    
  11387. +    while (1) {
  11388. +            if (pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR,
  11389. +            "read block","completion") & STAT_ERR) {
  11390. +                pi_disconnect(PI);
  11391. +                if (pf_retries < PF_MAX_RETRIES) {
  11392. +            pf_req_sense(unit,0);
  11393. +                        pf_retries++;
  11394. +                        pi_do_claimed(PI,do_pf_read_start);
  11395. +                        return;
  11396. +                }
  11397. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  11398. +                end_request(0);
  11399. +                pf_busy = 0;
  11400. +                do_pf_request();
  11401. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  11402. +                return;
  11403. +            }
  11404. +            pi_read_block(PI,pf_buf,512);
  11405. +            pf_count--; pf_run--;
  11406. +            pf_buf += 512;
  11407. +        pf_block++;
  11408. +        if (!pf_run) break;
  11409. +        if (!pf_count) pf_next_buf(unit);
  11410. +        }
  11411. +        pi_disconnect(PI);
  11412. +    spin_lock_irqsave(&io_request_lock,saved_flags); 
  11413. +        end_request(1);
  11414. +        pf_busy = 0;
  11415. +        do_pf_request();
  11416. +    spin_unlock_irqrestore(&io_request_lock,saved_flags);
  11417. +}
  11418. +
  11419. +static void do_pf_write( void )
  11420. +
  11421. +{    ps_set_intr(do_pf_write_start,0,0,nice);
  11422. +}
  11423. +
  11424. +static void do_pf_write_start( void )
  11425. +
  11426. +{       int    unit = pf_unit;
  11427. +    long    saved_flags;
  11428. +
  11429. +    pf_busy = 1;
  11430. +
  11431. +    if (pf_start(unit,ATAPI_WRITE_10,pf_block,pf_run)) {
  11432. +                pi_disconnect(PI);
  11433. +                if (pf_retries < PF_MAX_RETRIES) {
  11434. +                        pf_retries++;
  11435. +                        pi_do_claimed(PI,do_pf_write_start);
  11436. +            return;
  11437. +                }
  11438. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  11439. +                end_request(0);
  11440. +                pf_busy = 0;
  11441. +                do_pf_request();
  11442. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  11443. +                return;
  11444. +        }
  11445. +
  11446. +    while (1) {
  11447. +            if (pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR,
  11448. +            "write block","data wait") & STAT_ERR) {
  11449. +                pi_disconnect(PI);
  11450. +                if (pf_retries < PF_MAX_RETRIES) {
  11451. +                        pf_retries++;
  11452. +                        pi_do_claimed(PI,do_pf_write_start);
  11453. +                        return;
  11454. +                }
  11455. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  11456. +                end_request(0);
  11457. +                pf_busy = 0;
  11458. +                do_pf_request();
  11459. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  11460. +                return;
  11461. +            }
  11462. +            pi_write_block(PI,pf_buf,512);
  11463. +        pf_count--; pf_run--;
  11464. +        pf_buf += 512;
  11465. +        pf_block++;
  11466. +        if (!pf_run) break;
  11467. +        if (!pf_count) pf_next_buf(unit);
  11468. +    }
  11469. +    pf_mask = 0;
  11470. +        ps_set_intr(do_pf_write_done,pf_ready,PF_TMO,nice);
  11471. +}
  11472. +
  11473. +static void do_pf_write_done( void )
  11474. +
  11475. +{       int    unit = pf_unit;
  11476. +    long    saved_flags;
  11477. +
  11478. +        if (pf_wait(unit,STAT_BUSY,0,"write block","done") & STAT_ERR) {
  11479. +                pi_disconnect(PI);
  11480. +                if (pf_retries < PF_MAX_RETRIES) {
  11481. +                        pf_retries++;
  11482. +            pi_do_claimed(PI,do_pf_write_start);
  11483. +                        return;
  11484. +                }
  11485. +        spin_lock_irqsave(&io_request_lock,saved_flags);
  11486. +                end_request(0);
  11487. +                pf_busy = 0;
  11488. +                do_pf_request();
  11489. +        spin_unlock_irqrestore(&io_request_lock,saved_flags);
  11490. +                return;
  11491. +        }
  11492. +        pi_disconnect(PI);
  11493. +    spin_lock_irqsave(&io_request_lock,saved_flags);
  11494. +        end_request(1);
  11495. +        pf_busy = 0;
  11496. +        do_pf_request();
  11497. +    spin_unlock_irqrestore(&io_request_lock,saved_flags);
  11498. +}
  11499. +
  11500. +/* end of pf.c */
  11501. +
  11502. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/pg.c linux/drivers/block/paride/pg.c
  11503. --- v2.0.34/linux/drivers/block/paride/pg.c    Wed Dec 31 16:00:00 1969
  11504. +++ linux/drivers/block/paride/pg.c    Mon Jul 13 13:47:28 1998
  11505. @@ -0,0 +1,682 @@
  11506. +/* 
  11507. +        pg.c    (c) 1998  Grant R. Guenther <grant@torque.net>
  11508. +                          Under the terms of the GNU public license.
  11509. +
  11510. +
  11511. +    Special 2.0.35 version
  11512. +
  11513. +
  11514. +    The pg driver provides a simple character device interface for
  11515. +        sending ATAPI commands to a device.  With the exception of the
  11516. +    ATAPI reset operation, all operations are performed by a pair
  11517. +        of read and write operations to the appropriate /dev/pgN device.
  11518. +    A write operation delivers a command and any outbound data in
  11519. +        a single buffer.  Normally, the write will succeed unless the
  11520. +        device is offline or malfunctioning, or there is already another
  11521. +    command pending.  If the write succeeds, it should be followed
  11522. +        immediately by a read operation, to obtain any returned data and
  11523. +        status information.  A read will fail if there is no operation
  11524. +        in progress.
  11525. +
  11526. +    As a special case, the device can be reset with a write operation,
  11527. +        and in this case, no following read is expected, or permitted.
  11528. +
  11529. +    There are no ioctl() operations.  Any single operation
  11530. +    may transfer at most PG_MAX_DATA bytes.  Note that the driver must
  11531. +        copy the data through an internal buffer.  In keeping with all
  11532. +    current ATAPI devices, command packets are assumed to be exactly
  11533. +    12 bytes in length.
  11534. +
  11535. +    To permit future changes to this interface, the headers in the
  11536. +    read and write buffers contain a single character "magic" flag.
  11537. +        Currently this flag must be the character "P".
  11538. +
  11539. +        By default, the driver will autoprobe for a single parallel
  11540. +        port ATAPI device, but if their individual parameters are
  11541. +        specified, the driver can handle up to 4 devices.
  11542. +
  11543. +    To use this device, you must have the following device 
  11544. +    special files defined:
  11545. +
  11546. +        /dev/pg0 b 97 0
  11547. +        /dev/pg1 b 97 1
  11548. +        /dev/pg2 b 97 2
  11549. +        /dev/pg3 b 97 3
  11550. +
  11551. +    (You'll need to change the 97 to something else if you use
  11552. +    the 'major' parameter to install the driver on a different
  11553. +        major number.)
  11554. +
  11555. +        The behaviour of the pg driver can be altered by setting
  11556. +        some parameters from the insmod command line.  The following
  11557. +        parameters are adjustable:
  11558. +
  11559. +            drive0      These four arguments can be arrays of       
  11560. +            drive1      1-6 integers as follows:
  11561. +            drive2
  11562. +            drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
  11563. +
  11564. +                        Where,
  11565. +
  11566. +                <prt>   is the base of the parallel port address for
  11567. +                        the corresponding drive.  (required)
  11568. +
  11569. +                <pro>   is the protocol number for the adapter that
  11570. +                        supports this drive.  These numbers are
  11571. +                        logged by 'paride' when the protocol modules
  11572. +                        are initialised.  (0 if not given)
  11573. +
  11574. +                <uni>   for those adapters that support chained
  11575. +                        devices, this is the unit selector for the
  11576. +                        chain of devices on the given port.  It should
  11577. +                        be zero for devices that don't support chaining.
  11578. +                        (0 if not given)
  11579. +
  11580. +                <mod>   this can be -1 to choose the best mode, or one
  11581. +                        of the mode numbers supported by the adapter.
  11582. +                        (-1 if not given)
  11583. +
  11584. +                <slv>   ATAPI devices can be jumpered to master or slave.
  11585. +                        Set this to 0 to choose the master drive, 1 to
  11586. +                        choose the slave, -1 (the default) to choose the
  11587. +                        first drive found.
  11588. +
  11589. +                <dly>   some parallel ports require the driver to 
  11590. +                        go more slowly.  -1 sets a default value that
  11591. +                        should work with the chosen protocol.  Otherwise,
  11592. +                        set this to a small integer, the larger it is
  11593. +                        the slower the port i/o.  In some cases, setting
  11594. +                        this to zero will speed up the device. (default -1)
  11595. +
  11596. +        major    You may use this parameter to overide the
  11597. +            default major number (97) that this driver
  11598. +            will use.  Be sure to change the device
  11599. +            name as well.
  11600. +
  11601. +        name    This parameter is a character string that
  11602. +            contains the name the kernel will use for this
  11603. +            device (in /proc output, for instance).
  11604. +            (default "pg").
  11605. +
  11606. +            verbose     This parameter controls the amount of logging
  11607. +                        that is done by the driver.  Set it to 0 for 
  11608. +            quiet operation, to 1 to enable progress
  11609. +            messages while the driver probes for devices,
  11610. +            or to 2 for full debug logging.  (default 0)
  11611. +
  11612. +        If this driver is built into the kernel, you can use 
  11613. +        the following command line parameters, with the same values
  11614. +        as the corresponding module parameters listed above:
  11615. +
  11616. +            pg.drive0
  11617. +            pg.drive1
  11618. +            pg.drive2
  11619. +            pg.drive3
  11620. +
  11621. +        In addition, you can use the parameter pg.disable to disable
  11622. +        the driver entirely.
  11623. +
  11624. +*/
  11625. +
  11626. +/* Changes:
  11627. +
  11628. +    1.01    GRG 1998.06.16    Bug fixes
  11629. +*/
  11630. +
  11631. +#define PG_VERSION      "1.01s"
  11632. +#define PG_MAJOR    97
  11633. +#define PG_NAME        "pg"
  11634. +#define PG_UNITS    4
  11635. +
  11636. +#ifndef PI_PG
  11637. +#define PI_PG    4
  11638. +#endif
  11639. +
  11640. +/* Here are things one can override from the insmod command.
  11641. +   Most are autoprobed by paride unless set here.  Verbose is 0
  11642. +   by default.
  11643. +
  11644. +*/
  11645. +
  11646. +static int    verbose = 0;
  11647. +static int    major = PG_MAJOR;
  11648. +static char    *name = PG_NAME;
  11649. +static int      disable = 0;
  11650. +
  11651. +static int drive0[6] = {0,0,0,-1,-1,-1};
  11652. +static int drive1[6] = {0,0,0,-1,-1,-1};
  11653. +static int drive2[6] = {0,0,0,-1,-1,-1};
  11654. +static int drive3[6] = {0,0,0,-1,-1,-1};
  11655. +
  11656. +static int (*drives[4])[6] = {&drive0,&drive1,&drive2,&drive3};
  11657. +static int pg_drive_count;
  11658. +
  11659. +#define D_PRT   0
  11660. +#define D_PRO   1
  11661. +#define D_UNI   2
  11662. +#define D_MOD   3
  11663. +#define D_SLV   4
  11664. +#define D_DLY   5
  11665. +
  11666. +#define DU              (*drives[unit])
  11667. +
  11668. +/* end of parameters */
  11669. +
  11670. +
  11671. +#include <linux/module.h>
  11672. +#include <linux/errno.h>
  11673. +#include <linux/fs.h>
  11674. +#include <linux/kernel.h>
  11675. +#include <linux/delay.h>
  11676. +#include <linux/malloc.h>
  11677. +#include <linux/mtio.h>
  11678. +#include <linux/pg.h>
  11679. +
  11680. +#include <asm/segment.h>
  11681. +
  11682. +#ifndef MODULE
  11683. +
  11684. +#include "setup.h"
  11685. +
  11686. +static STT pg_stt[5] = {{"drive0",6,drive0},
  11687. +                        {"drive1",6,drive1},
  11688. +                        {"drive2",6,drive2},
  11689. +                        {"drive3",6,drive3},
  11690. +            {"disable",1,&disable}};
  11691. +
  11692. +void pg_setup( char *str, int *ints)
  11693. +
  11694. +{       generic_setup(pg_stt,5,str);
  11695. +}
  11696. +
  11697. +#endif
  11698. +
  11699. +#include "paride.h"
  11700. +
  11701. +#define PG_SPIN_DEL     50              /* spin delay in micro-seconds  */
  11702. +#define PG_SPIN         200
  11703. +#define PG_TMO        HZ
  11704. +#define PG_CMD_TMO    3*HZ
  11705. +#define PG_RESET_TMO    10*HZ
  11706. +
  11707. +#define STAT_ERR        0x01
  11708. +#define STAT_INDEX      0x02
  11709. +#define STAT_ECC        0x04
  11710. +#define STAT_DRQ        0x08
  11711. +#define STAT_SEEK       0x10
  11712. +#define STAT_WRERR      0x20
  11713. +#define STAT_READY      0x40
  11714. +#define STAT_BUSY       0x80
  11715. +
  11716. +#define ATAPI_IDENTIFY        0x12
  11717. +
  11718. +int pg_init(void);
  11719. +#ifdef MODULE
  11720. +void cleanup_module( void );
  11721. +#endif
  11722. +
  11723. +static int pg_open(struct inode *inode, struct file *file);
  11724. +static void pg_release (struct inode *inode, struct file *file);
  11725. +static int pg_read(struct inode *inode, struct file *filp, char *buf, int count);
  11726. +static int pg_write(struct inode *inode, struct file *filp, 
  11727. +            const char *buf, int count);
  11728. +static int pg_detect(void);
  11729. +
  11730. +static int pg_identify (int unit, int log);
  11731. +
  11732. +#define PG_NAMELEN      8
  11733. +
  11734. +struct pg_unit {
  11735. +    struct pi_adapter pia;    /* interface to paride layer */
  11736. +    struct pi_adapter *pi;
  11737. +    int busy;              /* write done, read expected */
  11738. +    int start;          /* jiffies at command start */
  11739. +    int dlen;          /* transfer size requested */
  11740. +    int timeout;          /* timeout requested */
  11741. +    int status;          /* last sense key */
  11742. +    int drive;          /* drive */
  11743. +    int access;               /* count of active opens ... */
  11744. +    int present;          /* device present ? */
  11745. +    char *bufptr;
  11746. +    char name[PG_NAMELEN];      /* pg0, pg1, ... */
  11747. +    };
  11748. +
  11749. +struct pg_unit pg[PG_UNITS];
  11750. +
  11751. +/*  'unit' must be defined in all functions - either as a local or a param */
  11752. +
  11753. +#define PG pg[unit]
  11754. +#define PI PG.pi
  11755. +
  11756. +static char pg_scratch[512];            /* scratch block buffer */
  11757. +
  11758. +/* kernel glue structures */
  11759. +
  11760. +static struct file_operations pg_fops = {
  11761. +        NULL,                   /* lseek - default */
  11762. +        pg_read,                /* read */
  11763. +        pg_write,               /* write */
  11764. +        NULL,                   /* readdir - bad */
  11765. +        NULL,                   /* select */
  11766. +        NULL,                   /* ioctl */
  11767. +        NULL,                   /* mmap */
  11768. +        pg_open,                /* open */
  11769. +        pg_release,             /* release */
  11770. +        NULL,                   /* fsync */
  11771. +        NULL,                   /* fasync */
  11772. +        NULL,                   /* media change ? */
  11773. +        NULL                    /* revalidate new media */
  11774. +};
  11775. +
  11776. +void pg_init_units( void )
  11777. +
  11778. +{       int     unit, j;
  11779. +
  11780. +        pg_drive_count = 0;
  11781. +        for (unit=0;unit<PG_UNITS;unit++) {
  11782. +                PG.pi = & PG.pia;
  11783. +                PG.access = 0;
  11784. +                PG.busy = 0;
  11785. +                PG.present = 0;
  11786. +        PG.bufptr = NULL;
  11787. +        PG.drive = DU[D_SLV];
  11788. +                j = 0;
  11789. +                while ((j < PG_NAMELEN-2) && (PG.name[j]=name[j])) j++;
  11790. +                PG.name[j++] = '0' + unit;
  11791. +                PG.name[j] = 0;
  11792. +                if (DU[D_PRT]) pg_drive_count++;
  11793. +        }
  11794. +} 
  11795. +
  11796. +int pg_init (void)      /* preliminary initialisation */
  11797. +
  11798. +{       int unit;
  11799. +
  11800. +    if (disable) return -1;
  11801. +
  11802. +    pg_init_units();
  11803. +
  11804. +    if (pg_detect()) return -1;
  11805. +
  11806. +        if (register_chrdev(major,name,&pg_fops)) {
  11807. +                printk("pg_init: unable to get major number %d\n",
  11808. +                        major);
  11809. +            for (unit=0;unit<PG_UNITS;unit++)
  11810. +              if (PG.present) pi_release(PI);
  11811. +                return -1;
  11812. +        }
  11813. +
  11814. +        return 0;
  11815. +}
  11816. +
  11817. +#ifdef MODULE
  11818. +
  11819. +/* Glue for modules ... */
  11820. +
  11821. +void    cleanup_module(void);
  11822. +
  11823. +int     init_module(void)
  11824. +
  11825. +{       int     err;
  11826. +
  11827. +        err = pg_init();
  11828. +
  11829. +        return err;
  11830. +}
  11831. +
  11832. +void    cleanup_module(void)
  11833. +
  11834. +{       int unit;
  11835. +
  11836. +        unregister_chrdev(major,name);
  11837. +
  11838. +    for (unit=0;unit<PG_UNITS;unit++)
  11839. +      if (PG.present) pi_release(PI);
  11840. +}
  11841. +
  11842. +#endif
  11843. +
  11844. +#define    WR(c,r,v)    pi_write_regr(PI,c,r,v)
  11845. +#define    RR(c,r)        (pi_read_regr(PI,c,r))
  11846. +
  11847. +#define DRIVE           (0xa0+0x10*PG.drive)
  11848. +
  11849. +static void pg_sleep( int cs )
  11850. +
  11851. +{       current->state = TASK_INTERRUPTIBLE;
  11852. +        current->timeout = jiffies + cs;
  11853. +        schedule();
  11854. +}
  11855. +
  11856. +static int pg_wait( int unit, int go, int stop, int tmo, char * msg )
  11857. +
  11858. +{       int j, r, e, s, p;
  11859. +
  11860. +    PG.status = 0;
  11861. +
  11862. +        j = 0;
  11863. +        while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(jiffies<tmo)) {
  11864. +                if (j++ < PG_SPIN) udelay(PG_SPIN_DEL);
  11865. +        else pg_sleep(1);
  11866. +    }
  11867. +
  11868. +        if ((r&(STAT_ERR&stop))||(jiffies>=tmo)) {
  11869. +           s = RR(0,7);
  11870. +           e = RR(0,1);
  11871. +           p = RR(0,2);
  11872. +           if (verbose > 1)
  11873. +         printk("%s: %s: stat=0x%x err=0x%x phase=%d%s\n",
  11874. +                   PG.name,msg,s,e,p,(jiffies>=tmo)?" timeout":"");
  11875. +
  11876. +
  11877. +           if (jiffies>=tmo) e |= 0x100;
  11878. +       PG.status = (e >> 4) & 0xff;
  11879. +           return -1;
  11880. +        }
  11881. +        return 0;
  11882. +}
  11883. +
  11884. +static int pg_command( int unit, char * cmd, int dlen, int tmo )
  11885. +
  11886. +{       int k;
  11887. +
  11888. +    pi_connect(PI);
  11889. +
  11890. +        WR(0,6,DRIVE);
  11891. +
  11892. +        if (pg_wait(unit,STAT_BUSY|STAT_DRQ,0,tmo,"before command")) {
  11893. +                pi_disconnect(PI);
  11894. +                return -1;
  11895. +        }
  11896. +
  11897. +        WR(0,4,dlen % 256);
  11898. +        WR(0,5,dlen / 256);
  11899. +        WR(0,7,0xa0);          /* ATAPI packet command */
  11900. +
  11901. +        if (pg_wait(unit,STAT_BUSY,STAT_DRQ,tmo,"command DRQ")) {
  11902. +                pi_disconnect(PI);
  11903. +                return -1;
  11904. +        }
  11905. +
  11906. +        if (RR(0,2) != 1) {
  11907. +           printk("%s: command phase error\n",PG.name);
  11908. +           pi_disconnect(PI);
  11909. +           return -1;
  11910. +        }
  11911. +
  11912. +        pi_write_block(PI,cmd,12);
  11913. +
  11914. +    if (verbose > 1) {
  11915. +        printk("%s: Command sent, dlen=%d packet= ", PG.name,dlen);
  11916. +        for (k=0;k<12;k++) printk("%02x ",cmd[k]&0xff);
  11917. +        printk("\n");
  11918. +    }
  11919. +        return 0;
  11920. +}
  11921. +
  11922. +static int pg_completion( int unit, char * buf, int tmo)
  11923. +
  11924. +{       int r, d, n, p;
  11925. +
  11926. +        r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
  11927. +                        tmo,"completion");
  11928. +
  11929. +        PG.dlen = 0;
  11930. +
  11931. +        while (RR(0,7)&STAT_DRQ) {
  11932. +           d = (RR(0,4)+256*RR(0,5));
  11933. +           n = ((d+3)&0xfffc);
  11934. +           p = RR(0,2)&3;
  11935. +           if (p == 0) pi_write_block(PI,buf,n);
  11936. +           if (p == 2) pi_read_block(PI,buf,n);
  11937. +           if (verbose > 1) printk("%s: %s %d bytes\n",PG.name,
  11938. +                                    p?"Read":"Write",n);
  11939. +           PG.dlen += (1-p)*d;
  11940. +           buf += d;
  11941. +           r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
  11942. +                        tmo,"completion");
  11943. +        }
  11944. +
  11945. +        pi_disconnect(PI);
  11946. +
  11947. +        return r;
  11948. +}
  11949. +
  11950. +static int pg_reset( int unit )
  11951. +
  11952. +{    int    i, k, flg;
  11953. +    int    expect[5] = {1,1,1,0x14,0xeb};
  11954. +
  11955. +    pi_connect(PI);
  11956. +    WR(0,6,DRIVE);
  11957. +    WR(0,7,8);
  11958. +
  11959. +    pg_sleep(2);
  11960. +
  11961. +        k = 0;
  11962. +        while ((k++ < PG_RESET_TMO) && (RR(1,6)&STAT_BUSY))
  11963. +                pg_sleep(1);
  11964. +
  11965. +    flg = 1;
  11966. +    for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
  11967. +
  11968. +    if (verbose) {
  11969. +        printk("%s: Reset (%d) signature = ",PG.name,k);
  11970. +        for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
  11971. +        if (!flg) printk(" (incorrect)");
  11972. +        printk("\n");
  11973. +    }
  11974. +    
  11975. +    pi_disconnect(PI);
  11976. +    return flg-1;    
  11977. +}
  11978. +
  11979. +static void xs( char *buf, char *targ, int offs, int len )
  11980. +
  11981. +{    int    j,k,l;
  11982. +
  11983. +    j=0; l=0;
  11984. +    for (k=0;k<len;k++) 
  11985. +       if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
  11986. +        l=targ[j++]=buf[k+offs];
  11987. +    if (l==0x20) j--; targ[j]=0;
  11988. +}
  11989. +
  11990. +static int pg_identify( int unit, int log )
  11991. +
  11992. +{    int     s;
  11993. +    char    *ms[2] = {"master","slave"};
  11994. +    char    mf[10], id[18];
  11995. +    char    id_cmd[12] = { ATAPI_IDENTIFY,0,0,0,36,0,0,0,0,0,0,0};
  11996. +    char    buf[36];
  11997. +
  11998. +        s = pg_command(unit,id_cmd,36,jiffies+PG_TMO);
  11999. +    if (s) return -1;
  12000. +    s = pg_completion(unit,buf,jiffies+PG_TMO);
  12001. +    if (s) return -1;
  12002. +
  12003. +    if (log) {
  12004. +        xs(buf,mf,8,8);
  12005. +        xs(buf,id,16,16);
  12006. +            printk("%s: %s %s, %s\n",PG.name,mf,id,ms[PG.drive]);
  12007. +    }
  12008. +
  12009. +    return 0;
  12010. +}
  12011. +
  12012. +static int pg_probe( int unit )
  12013. +
  12014. +/*    returns  0, with id set if drive is detected
  12015. +            -1, if drive detection failed
  12016. +*/
  12017. +
  12018. +{    if (PG.drive == -1) {
  12019. +       for (PG.drive=0;PG.drive<=1;PG.drive++)
  12020. +        if (!pg_reset(unit)) return pg_identify(unit,1);
  12021. +    } else {
  12022. +       if (!pg_reset(unit)) return pg_identify(unit,1);
  12023. +    }
  12024. +        return -1; 
  12025. +}
  12026. +
  12027. +static int pg_detect( void )
  12028. +
  12029. +{    int    k, unit;
  12030. +
  12031. +    printk("%s: %s version %s, major %d\n",
  12032. +        name,name,PG_VERSION,major);
  12033. +
  12034. +    k = 0;
  12035. +    if (pg_drive_count == 0) {
  12036. +        unit = 0;
  12037. +        if (pi_init(PI,1,-1,-1,-1,-1,-1,pg_scratch,
  12038. +                        PI_PG,verbose,PG.name)) {
  12039. +            if (!pg_probe(unit)) {
  12040. +            PG.present = 1;
  12041. +            k++;
  12042. +            } else pi_release(PI);
  12043. +        }
  12044. +
  12045. +    } else for (unit=0;unit<PG_UNITS;unit++) if (DU[D_PRT])
  12046. +        if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
  12047. +            DU[D_PRO],DU[D_DLY],pg_scratch,PI_PG,verbose,
  12048. +            PG.name)) { 
  12049. +                if (!pg_probe(unit)) {
  12050. +                        PG.present = 1;
  12051. +                        k++;
  12052. +                } else pi_release(PI);
  12053. +            }
  12054. +
  12055. +    if (k) return 0;
  12056. +
  12057. +    printk("%s: No ATAPI device detected\n",name);
  12058. +    return -1;
  12059. +}
  12060. +
  12061. +#define DEVICE_NR(dev)    (MINOR(dev) % 128)
  12062. +
  12063. +static int pg_open (struct inode *inode, struct file *file)
  12064. +
  12065. +{       int    unit = DEVICE_NR(inode->i_rdev);
  12066. +
  12067. +        if ((unit >= PG_UNITS) || (!PG.present)) return -ENODEV;
  12068. +
  12069. +        PG.access++;
  12070. +
  12071. +    if (PG.access > 1) {
  12072. +        PG.access--;
  12073. +        return -EBUSY;
  12074. +    }
  12075. +
  12076. +        MOD_INC_USE_COUNT;
  12077. +
  12078. +    if (PG.busy) {
  12079. +        pg_reset(unit);
  12080. +        PG.busy = 0;
  12081. +    }
  12082. +
  12083. +    pg_identify(unit,(verbose>1));
  12084. +
  12085. +
  12086. +    PG.bufptr = kmalloc(PG_MAX_DATA,GFP_KERNEL);
  12087. +    if (PG.bufptr == NULL) {
  12088. +        PG.access--;
  12089. +        MOD_DEC_USE_COUNT;
  12090. +        printk("%s: buffer allocation failed\n",PG.name);
  12091. +        return -ENOMEM;
  12092. +    }
  12093. +
  12094. +        return 0;
  12095. +}
  12096. +
  12097. +static void pg_release (struct inode *inode, struct file *file)
  12098. +{
  12099. +        int    unit = DEVICE_NR(inode->i_rdev);
  12100. +
  12101. +        if ((unit >= PG_UNITS) || (PG.access <= 0)) 
  12102. +                return;
  12103. +
  12104. +    PG.access--;
  12105. +
  12106. +    kfree(PG.bufptr);
  12107. +    PG.bufptr = NULL;
  12108. +
  12109. +        MOD_DEC_USE_COUNT;
  12110. +
  12111. +}
  12112. +
  12113. +static int pg_write(struct inode *inode, struct file *filp, 
  12114. +        const char *buf, int count)
  12115. +
  12116. +{       int                     unit = DEVICE_NR(inode->i_rdev);
  12117. +        struct pg_write_hdr     hdr;
  12118. +        int                     hs = sizeof(hdr);
  12119. +
  12120. +    if (PG.busy) return -EBUSY;
  12121. +    if (count < hs) return -EINVAL;
  12122. +    
  12123. +    memcpy_fromfs((char *)&hdr,buf,hs);
  12124. +
  12125. +    if (hdr.magic != PG_MAGIC) return -EINVAL;
  12126. +    if (hdr.dlen > PG_MAX_DATA) return -EINVAL;
  12127. +    if ((count - hs) > PG_MAX_DATA) return -EINVAL;
  12128. +
  12129. +    if (hdr.func == PG_RESET) {
  12130. +        if (count != hs) return -EINVAL;
  12131. +        if (pg_reset(unit)) return -EIO;
  12132. +        return count;
  12133. +    }
  12134. +
  12135. +    if (hdr.func != PG_COMMAND) return -EINVAL;
  12136. +
  12137. +    PG.start = jiffies;
  12138. +    PG.timeout = hdr.timeout*HZ + HZ/2 + jiffies;
  12139. +
  12140. +    if (pg_command(unit,hdr.packet,hdr.dlen,jiffies+PG_CMD_TMO)) {
  12141. +        if (PG.status & 0x10) return -ETIME;
  12142. +        return -EIO;
  12143. +    }
  12144. +
  12145. +    PG.busy = 1;
  12146. +
  12147. +    memcpy_fromfs(PG.bufptr,buf+hs,count-hs);
  12148. +
  12149. +    return count;
  12150. +}
  12151. +
  12152. +static int pg_read(struct inode *inode, struct file *filp, char *buf, int count)
  12153. +
  12154. +{      int            unit = DEVICE_NR(inode->i_rdev); 
  12155. +    struct pg_read_hdr     hdr;
  12156. +    int            hs = sizeof(hdr);
  12157. +    int            copy;
  12158. +
  12159. +    if (!PG.busy) return -EINVAL;
  12160. +    if (count < hs) return -EINVAL;
  12161. +
  12162. +    PG.busy = 0;
  12163. +
  12164. +    if (pg_completion(unit,PG.bufptr,PG.timeout))
  12165. +      if (PG.status & 0x10) return -ETIME;
  12166. +
  12167. +    hdr.magic = PG_MAGIC;
  12168. +    hdr.dlen = PG.dlen;
  12169. +    copy = 0;
  12170. +
  12171. +    if (hdr.dlen < 0) {
  12172. +            hdr.dlen = -1 * hdr.dlen;
  12173. +        copy = hdr.dlen;
  12174. +        if (copy > (count - hs)) copy = count - hs;
  12175. +    }
  12176. +
  12177. +    hdr.duration = (jiffies - PG.start + HZ/2) / HZ;
  12178. +    hdr.scsi = PG.status & 0x0f;
  12179. +
  12180. +    memcpy_tofs(buf,(char *)&hdr,hs);
  12181. +    if (copy > 0) memcpy_tofs(buf+hs,PG.bufptr,copy);
  12182. +    
  12183. +    return copy+hs;
  12184. +}
  12185. +
  12186. +/* end of pg.c */
  12187. +
  12188. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/pseudo.h linux/drivers/block/paride/pseudo.h
  12189. --- v2.0.34/linux/drivers/block/paride/pseudo.h    Wed Dec 31 16:00:00 1969
  12190. +++ linux/drivers/block/paride/pseudo.h    Mon Jul 13 13:47:28 1998
  12191. @@ -0,0 +1,145 @@
  12192. +/* 
  12193. +        pseudo.h    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  12194. +                                Under the terms of the GNU public license.
  12195. +
  12196. +    This is the "pseudo-interrupt" logic for parallel port drivers.
  12197. +
  12198. +        This module is #included into each driver.  It makes one
  12199. +        function available:
  12200. +
  12201. +        ps_set_intr( void (*continuation)(void),
  12202. +                 int  (*ready)(void),
  12203. +                 int timeout,
  12204. +                 int nice )
  12205. +
  12206. +    Which will arrange for ready() to be evaluated frequently and
  12207. +    when either it returns true, or timeout jiffies have passed,
  12208. +    continuation() will be invoked.
  12209. +
  12210. +    If nice is true, the test will done approximately once a
  12211. +    jiffy.  If nice is 0, the test will also be done whenever
  12212. +    the scheduler runs (by adding it to a task queue).
  12213. +
  12214. +*/
  12215. +
  12216. +/* Changes:
  12217. +
  12218. +    1.01    1998.05.03    Switched from cli()/sti() to spinlocks
  12219. +
  12220. +*/
  12221. +    
  12222. +#define PS_VERSION    "1.01"
  12223. +
  12224. +#include <linux/sched.h>
  12225. +#include <linux/timer.h>
  12226. +#include <linux/tqueue.h>
  12227. +
  12228. +static void ps_timer_int( unsigned long data);
  12229. +static void ps_tq_int( void *data);
  12230. +
  12231. +static int ps_use_tq = 1;
  12232. +static void (* ps_continuation)(void);
  12233. +static int (* ps_ready)(void);
  12234. +static int ps_then;
  12235. +static int ps_timeout;
  12236. +static int ps_timer_active = 0;
  12237. +static int ps_tq_active = 0;
  12238. +
  12239. +/* static spinlock_t ps_spinlock = SPIN_LOCK_UNLOCKED; */
  12240. +
  12241. +static struct timer_list ps_timer = {0,0,0,0,ps_timer_int};
  12242. +static struct tq_struct ps_tq = {0,0,ps_tq_int,NULL};
  12243. +
  12244. +static void ps_set_intr( void (*continuation)(void), 
  12245. +             int (*ready)(void),
  12246. +             int timeout, int nice )
  12247. +
  12248. +{       long    flags;
  12249. +
  12250. +    spin_lock_irqsave(&ps_spinlock,flags);
  12251. +
  12252. +    ps_continuation = continuation;
  12253. +    ps_ready = ready;
  12254. +        ps_then = jiffies;
  12255. +    ps_timeout = jiffies + timeout;
  12256. +    ps_use_tq = !nice;
  12257. +
  12258. +        if (ps_use_tq && !ps_tq_active) {
  12259. +#ifdef HAVE_DISABLE_HLT
  12260. +                disable_hlt();
  12261. +#endif
  12262. +        ps_tq_active = 1;
  12263. +                queue_task(&ps_tq,&tq_scheduler);
  12264. +    }
  12265. +
  12266. +        if (!ps_timer_active) {
  12267. +        ps_timer_active = 1;
  12268. +                ps_timer.expires = jiffies;
  12269. +                add_timer(&ps_timer);
  12270. +        }
  12271. +
  12272. +    spin_unlock_irqrestore(&ps_spinlock,flags);
  12273. +}
  12274. +
  12275. +static void ps_tq_int( void *data )
  12276. +
  12277. +{       void (*con)(void);
  12278. +    long flags;
  12279. +
  12280. +    spin_lock_irqsave(&ps_spinlock,flags);
  12281. +
  12282. +        con = ps_continuation;
  12283. +
  12284. +#ifdef HAVE_DISABLE_HLT
  12285. +        enable_hlt();
  12286. +#endif
  12287. +
  12288. +        ps_tq_active = 0;
  12289. +
  12290. +        if (!con) {
  12291. +        spin_unlock_irqrestore(&ps_spinlock,flags);
  12292. +        return;
  12293. +    }
  12294. +        if (!ps_ready || ps_ready() || (jiffies >= ps_timeout)) {
  12295. +                ps_continuation = NULL;
  12296. +            spin_unlock_irqrestore(&ps_spinlock,flags);
  12297. +                con();
  12298. +                return;
  12299. +                }
  12300. +
  12301. +#ifdef HAVE_DISABLE_HLT
  12302. +        disable_hlt();
  12303. +#endif
  12304. +
  12305. +        ps_tq_active = 1;
  12306. +    queue_task(&ps_tq,&tq_scheduler);
  12307. +        spin_unlock_irqrestore(&ps_spinlock,flags);
  12308. +}
  12309. +
  12310. +static void ps_timer_int( unsigned long data)
  12311. +
  12312. +{       void (*con)(void);
  12313. +    long    flags;
  12314. +
  12315. +    spin_lock_irqsave(&ps_spinlock,flags);
  12316. +
  12317. +    con = ps_continuation;
  12318. +    ps_timer_active = 0;
  12319. +    if (!con) {
  12320. +            spin_unlock_irqrestore(&ps_spinlock,flags);
  12321. +        return;
  12322. +    }
  12323. +        if (!ps_ready || ps_ready() || (jiffies >= ps_timeout)) {
  12324. +                ps_continuation = NULL;
  12325. +            spin_unlock_irqrestore(&ps_spinlock,flags);
  12326. +                con();
  12327. +        return;
  12328. +        }
  12329. +    ps_timer_active = 1;
  12330. +        ps_timer.expires = jiffies;
  12331. +        add_timer(&ps_timer);
  12332. +        spin_unlock_irqrestore(&ps_spinlock,flags);
  12333. +}
  12334. +
  12335. +/* end of pseudo.h */
  12336. +
  12337. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/pt.c linux/drivers/block/paride/pt.c
  12338. --- v2.0.34/linux/drivers/block/paride/pt.c    Wed Dec 31 16:00:00 1969
  12339. +++ linux/drivers/block/paride/pt.c    Mon Jul 13 13:47:28 1998
  12340. @@ -0,0 +1,940 @@
  12341. +/* 
  12342. +        pt.c    (c) 1998  Grant R. Guenther <grant@torque.net>
  12343. +                          Under the terms of the GNU public license.
  12344. +
  12345. +    Special 2.0.35 version
  12346. +
  12347. +        This is the high-level driver for parallel port ATAPI tape
  12348. +        drives based on chips supported by the paride module.
  12349. +
  12350. +    The driver implements both rewinding and non-rewinding
  12351. +    devices, filemarks, and the rewind ioctl.  It allocates
  12352. +    a small internal "bounce buffer" for each open device, but
  12353. +        otherwise expects buffering and blocking to be done at the
  12354. +        user level.  As with most block-structured tapes, short
  12355. +    writes are padded to full tape blocks, so reading back a file
  12356. +        may return more data than was actually written.
  12357. +
  12358. +        By default, the driver will autoprobe for a single parallel
  12359. +        port ATAPI tape drive, but if their individual parameters are
  12360. +        specified, the driver can handle up to 4 drives.
  12361. +
  12362. +    The rewinding devices are named /dev/pt0, /dev/pt1, ...
  12363. +    while the non-rewinding devices are /dev/npt0, /dev/npt1, etc.
  12364. +
  12365. +        The behaviour of the pt driver can be altered by setting
  12366. +        some parameters from the insmod command line.  The following
  12367. +        parameters are adjustable:
  12368. +
  12369. +            drive0      These four arguments can be arrays of       
  12370. +            drive1      1-6 integers as follows:
  12371. +            drive2
  12372. +            drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
  12373. +
  12374. +                        Where,
  12375. +
  12376. +                <prt>   is the base of the parallel port address for
  12377. +                        the corresponding drive.  (required)
  12378. +
  12379. +                <pro>   is the protocol number for the adapter that
  12380. +                        supports this drive.  These numbers are
  12381. +                        logged by 'paride' when the protocol modules
  12382. +                        are initialised.  (0 if not given)
  12383. +
  12384. +                <uni>   for those adapters that support chained
  12385. +                        devices, this is the unit selector for the
  12386. +                        chain of devices on the given port.  It should
  12387. +                        be zero for devices that don't support chaining.
  12388. +                        (0 if not given)
  12389. +
  12390. +                <mod>   this can be -1 to choose the best mode, or one
  12391. +                        of the mode numbers supported by the adapter.
  12392. +                        (-1 if not given)
  12393. +
  12394. +                <slv>   ATAPI devices can be jumpered to master or slave.
  12395. +                        Set this to 0 to choose the master drive, 1 to
  12396. +                        choose the slave, -1 (the default) to choose the
  12397. +                        first drive found.
  12398. +
  12399. +                <dly>   some parallel ports require the driver to 
  12400. +                        go more slowly.  -1 sets a default value that
  12401. +                        should work with the chosen protocol.  Otherwise,
  12402. +                        set this to a small integer, the larger it is
  12403. +                        the slower the port i/o.  In some cases, setting
  12404. +                        this to zero will speed up the device. (default -1)
  12405. +
  12406. +        major    You may use this parameter to overide the
  12407. +            default major number (96) that this driver
  12408. +            will use.  Be sure to change the device
  12409. +            name as well.
  12410. +
  12411. +        name    This parameter is a character string that
  12412. +            contains the name the kernel will use for this
  12413. +            device (in /proc output, for instance).
  12414. +            (default "pt").
  12415. +
  12416. +            verbose     This parameter controls the amount of logging
  12417. +                        that is done while the driver probes for
  12418. +                        devices.  Set it to 0 for a quiet load, or 1 to
  12419. +                        see all the progress messages.  (default 0)
  12420. +
  12421. +        If this driver is built into the kernel, you can use 
  12422. +        the following command line parameters, with the same values
  12423. +        as the corresponding module parameters listed above:
  12424. +
  12425. +            pt.drive0
  12426. +            pt.drive1
  12427. +            pt.drive2
  12428. +            pt.drive3
  12429. +
  12430. +        In addition, you can use the parameter pt.disable to disable
  12431. +        the driver entirely.
  12432. +
  12433. +*/
  12434. +
  12435. +/*   Changes:
  12436. +
  12437. +    1.01    GRG 1998.05.06    Round up transfer size, fix ready_wait,
  12438. +                    loosed interpretation of ATAPI standard
  12439. +                for clearing error status.
  12440. +                Eliminate sti();
  12441. +    1.02    GRG 1998.06.16  Eliminate an Ugh.
  12442. +
  12443. +*/
  12444. +
  12445. +#define PT_VERSION      "1.02s"
  12446. +#define PT_MAJOR    96
  12447. +#define PT_NAME        "pt"
  12448. +#define PT_UNITS    4
  12449. +
  12450. +/* Here are things one can override from the insmod command.
  12451. +   Most are autoprobed by paride unless set here.  Verbose is on
  12452. +   by default.
  12453. +
  12454. +*/
  12455. +
  12456. +static int    verbose = 0;
  12457. +static int    major = PT_MAJOR;
  12458. +static char    *name = PT_NAME;
  12459. +static int      disable = 0;
  12460. +
  12461. +static int drive0[6] = {0,0,0,-1,-1,-1};
  12462. +static int drive1[6] = {0,0,0,-1,-1,-1};
  12463. +static int drive2[6] = {0,0,0,-1,-1,-1};
  12464. +static int drive3[6] = {0,0,0,-1,-1,-1};
  12465. +
  12466. +static int (*drives[4])[6] = {&drive0,&drive1,&drive2,&drive3};
  12467. +static int pt_drive_count;
  12468. +
  12469. +#define D_PRT   0
  12470. +#define D_PRO   1
  12471. +#define D_UNI   2
  12472. +#define D_MOD   3
  12473. +#define D_SLV   4
  12474. +#define D_DLY   5
  12475. +
  12476. +#define DU              (*drives[unit])
  12477. +
  12478. +/* end of parameters */
  12479. +
  12480. +
  12481. +#include <linux/module.h>
  12482. +#include <linux/errno.h>
  12483. +#include <linux/fs.h>
  12484. +#include <linux/kernel.h>
  12485. +#include <linux/delay.h>
  12486. +#include <linux/malloc.h>
  12487. +#include <linux/mtio.h>
  12488. +
  12489. +#include <asm/segment.h>
  12490. +
  12491. +#ifndef MODULE
  12492. +
  12493. +#include "setup.h"
  12494. +
  12495. +static STT pt_stt[5] = {{"drive0",6,drive0},
  12496. +                        {"drive1",6,drive1},
  12497. +                        {"drive2",6,drive2},
  12498. +                        {"drive3",6,drive3},
  12499. +            {"disable",1,&disable}};
  12500. +
  12501. +void pt_setup( char *str, int *ints)
  12502. +
  12503. +{       generic_setup(pt_stt,5,str);
  12504. +}
  12505. +
  12506. +#endif
  12507. +
  12508. +#include "paride.h"
  12509. +
  12510. +#define PT_MAX_RETRIES  5
  12511. +#define PT_TMO          800             /* interrupt timeout in jiffies */
  12512. +#define PT_SPIN_DEL     50              /* spin delay in micro-seconds  */
  12513. +#define PT_RESET_TMO    30        /* 3 seconds */
  12514. +#define PT_READY_TMO    60        /* 60 seconds */
  12515. +#define PT_REWIND_TMO    1200        /* 20 minutes */
  12516. +
  12517. +#define PT_SPIN         (10000/PT_SPIN_DEL)*PT_TMO  
  12518. +
  12519. +#define STAT_ERR        0x00001
  12520. +#define STAT_INDEX      0x00002
  12521. +#define STAT_ECC        0x00004
  12522. +#define STAT_DRQ        0x00008
  12523. +#define STAT_SEEK       0x00010
  12524. +#define STAT_WRERR      0x00020
  12525. +#define STAT_READY      0x00040
  12526. +#define STAT_BUSY       0x00080
  12527. +#define STAT_SENSE    0x1f000
  12528. +
  12529. +#define ATAPI_TEST_READY    0x00
  12530. +#define ATAPI_REWIND        0x01
  12531. +#define ATAPI_REQ_SENSE        0x03
  12532. +#define ATAPI_READ_6        0x08
  12533. +#define ATAPI_WRITE_6        0x0a
  12534. +#define ATAPI_WFM        0x10
  12535. +#define ATAPI_IDENTIFY        0x12
  12536. +#define ATAPI_MODE_SENSE    0x1a
  12537. +#define ATAPI_LOG_SENSE        0x4d
  12538. +
  12539. +int pt_init(void);
  12540. +#ifdef MODULE
  12541. +void cleanup_module( void );
  12542. +#endif
  12543. +
  12544. +static int pt_open(struct inode *inode, struct file *file);
  12545. +static int pt_ioctl(struct inode *inode,struct file *file,
  12546. +                    unsigned int cmd, unsigned long arg);
  12547. +static void pt_release (struct inode *inode, struct file *file);
  12548. +static int pt_read(struct inode *inode, struct file *filp, char *buf, int count);
  12549. +static int pt_write(struct inode *inode, struct file *filp, 
  12550. +        const char *buf, int count);
  12551. +static int pt_detect(void);
  12552. +
  12553. +static int pt_identify (int unit);
  12554. +
  12555. +/* bits in PT.flags */
  12556. +
  12557. +#define PT_MEDIA    1
  12558. +#define PT_WRITE_OK    2
  12559. +#define PT_REWIND    4
  12560. +#define PT_WRITING      8
  12561. +#define PT_READING     16
  12562. +#define PT_EOF           32
  12563. +
  12564. +#define PT_NAMELEN      8
  12565. +#define PT_BUFSIZE  16384
  12566. +
  12567. +struct pt_unit {
  12568. +    struct pi_adapter pia;    /* interface to paride layer */
  12569. +    struct pi_adapter *pi;
  12570. +    int flags;              /* various state flags */
  12571. +    int last_sense;          /* result of last request sense */
  12572. +    int drive;          /* drive */
  12573. +    int access;               /* count of active opens ... */
  12574. +    int bs;              /* block size */
  12575. +    int capacity;             /* Size of tape in KB */
  12576. +    int present;          /* device present ? */
  12577. +    char *bufptr;
  12578. +    char name[PT_NAMELEN];      /* pf0, pf1, ... */
  12579. +    };
  12580. +
  12581. +struct pt_unit pt[PT_UNITS];
  12582. +
  12583. +/*  'unit' must be defined in all functions - either as a local or a param */
  12584. +
  12585. +#define PT pt[unit]
  12586. +#define PI PT.pi
  12587. +
  12588. +static char pt_scratch[512];            /* scratch block buffer */
  12589. +
  12590. +/* kernel glue structures */
  12591. +
  12592. +static struct file_operations pt_fops = {
  12593. +        NULL,                   /* lseek - default */
  12594. +        pt_read,                /* read */
  12595. +        pt_write,               /* write */
  12596. +        NULL,                   /* readdir - bad */
  12597. +        NULL,                   /* select */
  12598. +        pt_ioctl,               /* ioctl */
  12599. +        NULL,                   /* mmap */
  12600. +        pt_open,                /* open */
  12601. +        pt_release,             /* release */
  12602. +        NULL,                   /* fsync */
  12603. +        NULL,                   /* fasync */
  12604. +        NULL,                   /* media change ? */
  12605. +        NULL                    /* revalidate new media */
  12606. +};
  12607. +
  12608. +void pt_init_units( void )
  12609. +
  12610. +{       int     unit, j;
  12611. +
  12612. +        pt_drive_count = 0;
  12613. +        for (unit=0;unit<PT_UNITS;unit++) {
  12614. +                PT.pi = & PT.pia;
  12615. +                PT.access = 0;
  12616. +                PT.flags = 0;
  12617. +        PT.last_sense = 0;
  12618. +                PT.present = 0;
  12619. +        PT.bufptr = NULL;
  12620. +        PT.drive = DU[D_SLV];
  12621. +                j = 0;
  12622. +                while ((j < PT_NAMELEN-2) && (PT.name[j]=name[j])) j++;
  12623. +                PT.name[j++] = '0' + unit;
  12624. +                PT.name[j] = 0;
  12625. +                if (DU[D_PRT]) pt_drive_count++;
  12626. +        }
  12627. +} 
  12628. +
  12629. +int pt_init (void)      /* preliminary initialisation */
  12630. +
  12631. +{       int unit;
  12632. +
  12633. +    if (disable) return -1;
  12634. +
  12635. +    pt_init_units();
  12636. +
  12637. +    if (pt_detect()) return -1;
  12638. +
  12639. +        if (register_chrdev(major,name,&pt_fops)) {
  12640. +                printk("pt_init: unable to get major number %d\n",
  12641. +                        major);
  12642. +            for (unit=0;unit<PT_UNITS;unit++)
  12643. +              if (PT.present) pi_release(PI);
  12644. +                return -1;
  12645. +        }
  12646. +
  12647. +        return 0;
  12648. +}
  12649. +
  12650. +#ifdef MODULE
  12651. +
  12652. +/* Glue for modules ... */
  12653. +
  12654. +void    cleanup_module(void);
  12655. +
  12656. +int     init_module(void)
  12657. +
  12658. +{       int     err;
  12659. +
  12660. +        err = pt_init();
  12661. +
  12662. +        return err;
  12663. +}
  12664. +
  12665. +void    cleanup_module(void)
  12666. +
  12667. +{       int unit;
  12668. +
  12669. +        unregister_chrdev(major,name);
  12670. +
  12671. +    for (unit=0;unit<PT_UNITS;unit++)
  12672. +      if (PT.present) pi_release(PI);
  12673. +}
  12674. +
  12675. +#endif
  12676. +
  12677. +#define    WR(c,r,v)    pi_write_regr(PI,c,r,v)
  12678. +#define    RR(c,r)        (pi_read_regr(PI,c,r))
  12679. +
  12680. +#define DRIVE           (0xa0+0x10*PT.drive)
  12681. +
  12682. +static int pt_wait( int unit, int go, int stop, char * fun, char * msg )
  12683. +
  12684. +{       int j, r, e, s, p;
  12685. +
  12686. +        j = 0;
  12687. +        while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PT_SPIN))
  12688. +                udelay(PT_SPIN_DEL);
  12689. +
  12690. +        if ((r&(STAT_ERR&stop))||(j>=PT_SPIN)) {
  12691. +           s = RR(0,7);
  12692. +           e = RR(0,1);
  12693. +           p = RR(0,2);
  12694. +           if (j >= PT_SPIN) e |= 0x100;
  12695. +           if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
  12696. +                           " loop=%d phase=%d\n",
  12697. +                            PT.name,fun,msg,r,s,e,j,p);
  12698. +           return (e<<8)+s;
  12699. +        }
  12700. +        return 0;
  12701. +}
  12702. +
  12703. +static int pt_command( int unit, char * cmd, int dlen, char * fun )
  12704. +
  12705. +{       pi_connect(PI);
  12706. +
  12707. +        WR(0,6,DRIVE);
  12708. +
  12709. +        if (pt_wait(unit,STAT_BUSY|STAT_DRQ,0,fun,"before command")) {
  12710. +                pi_disconnect(PI);
  12711. +                return -1;
  12712. +        }
  12713. +
  12714. +        WR(0,4,dlen % 256);
  12715. +        WR(0,5,dlen / 256);
  12716. +        WR(0,7,0xa0);          /* ATAPI packet command */
  12717. +
  12718. +        if (pt_wait(unit,STAT_BUSY,STAT_DRQ,fun,"command DRQ")) {
  12719. +                pi_disconnect(PI);
  12720. +                return -1;
  12721. +        }
  12722. +
  12723. +        if (RR(0,2) != 1) {
  12724. +           printk("%s: %s: command phase error\n",PT.name,fun);
  12725. +           pi_disconnect(PI);
  12726. +           return -1;
  12727. +        }
  12728. +
  12729. +        pi_write_block(PI,cmd,12);
  12730. +
  12731. +        return 0;
  12732. +}
  12733. +
  12734. +static int pt_completion( int unit, char * buf, char * fun )
  12735. +
  12736. +{       int r, s, n, p;
  12737. +
  12738. +        r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
  12739. +            fun,"completion");
  12740. +
  12741. +        if (RR(0,7)&STAT_DRQ) { 
  12742. +           n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
  12743. +       p = RR(0,2)&3;
  12744. +       if (p == 0) pi_write_block(PI,buf,n);
  12745. +       if (p == 2) pi_read_block(PI,buf,n);
  12746. +        }
  12747. +
  12748. +        s = pt_wait(unit,STAT_BUSY,STAT_READY|STAT_ERR,fun,"data done");
  12749. +
  12750. +        pi_disconnect(PI); 
  12751. +
  12752. +        return (r?r:s);
  12753. +}
  12754. +
  12755. +static void pt_req_sense( int unit, int quiet )
  12756. +
  12757. +{       char    rs_cmd[12] = { ATAPI_REQ_SENSE,0,0,0,16,0,0,0,0,0,0,0 };
  12758. +        char    buf[16];
  12759. +        int     r;
  12760. +
  12761. +        r = pt_command(unit,rs_cmd,16,"Request sense");
  12762. +        udelay(1000);
  12763. +        if (!r) pt_completion(unit,buf,"Request sense");
  12764. +
  12765. +    PT.last_sense = -1;
  12766. +        if (!r) {
  12767. +        if (!quiet) printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
  12768. +                                    PT.name,buf[2]&0xf,buf[12],buf[13]);
  12769. +        PT.last_sense = (buf[2]&0xf) | ((buf[12]&0xff)<<8)
  12770. +                     | ((buf[13]&0xff)<<16) ;
  12771. +    } 
  12772. +}
  12773. +
  12774. +static int pt_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
  12775. +
  12776. +{       int r;
  12777. +
  12778. +        r = pt_command(unit,cmd,dlen,fun);
  12779. +        udelay(1000);
  12780. +        if (!r) r = pt_completion(unit,buf,fun);
  12781. +        if (r) pt_req_sense(unit,!fun);
  12782. +        
  12783. +        return r;
  12784. +}
  12785. +
  12786. +static void pt_sleep( int cs )
  12787. +
  12788. +{       current->state = TASK_INTERRUPTIBLE;
  12789. +        current->timeout = jiffies + cs;
  12790. +        schedule();
  12791. +}
  12792. +
  12793. +static int pt_poll_dsc( int unit, int pause, int tmo, char *msg )
  12794. +
  12795. +{    int    k, e, s;
  12796. +
  12797. +    k = 0;
  12798. +    while (k < tmo) {
  12799. +        pt_sleep(pause);
  12800. +        k++;
  12801. +        pi_connect(PI);
  12802. +        WR(0,6,DRIVE);
  12803. +        s = RR(0,7);
  12804. +        e = RR(0,1);
  12805. +        pi_disconnect(PI);
  12806. +        if (s & (STAT_ERR|STAT_SEEK)) break;
  12807. +    }
  12808. +    if ((k >= tmo) || (s & STAT_ERR)) {
  12809. +       if (k >= tmo) printk("%s: %s DSC timeout\n",PT.name,msg);
  12810. +         else printk("%s: %s stat=0x%x err=0x%x\n",PT.name,msg,s,e);
  12811. +       pt_req_sense(unit,0);
  12812. +       return 0;
  12813. +    }
  12814. +    return 1;
  12815. +}
  12816. +
  12817. +static void pt_media_access_cmd( int unit, int tmo, char *cmd, char *fun)
  12818. +
  12819. +{    if (pt_command(unit,cmd,0,fun)) {
  12820. +        pt_req_sense(unit,0);
  12821. +        return;
  12822. +    }
  12823. +    pi_disconnect(PI);
  12824. +    pt_poll_dsc(unit,100,tmo,fun);
  12825. +}
  12826. +
  12827. +static void pt_rewind( int unit )
  12828. +
  12829. +{    char    rw_cmd[12] = {ATAPI_REWIND,0,0,0,0,0,0,0,0,0,0,0};
  12830. +
  12831. +    pt_media_access_cmd(unit,PT_REWIND_TMO,rw_cmd,"rewind");
  12832. +}
  12833. +
  12834. +static void pt_write_fm( int unit )
  12835. +
  12836. +{    char    wm_cmd[12] = {ATAPI_WFM,0,0,0,1,0,0,0,0,0,0,0};
  12837. +
  12838. +        pt_media_access_cmd(unit,PT_TMO,wm_cmd,"write filemark");
  12839. +}
  12840. +
  12841. +#define DBMSG(msg)      NULL
  12842. +
  12843. +static int pt_reset( int unit )
  12844. +
  12845. +{    int    i, k, flg;
  12846. +    int    expect[5] = {1,1,1,0x14,0xeb};
  12847. +
  12848. +    pi_connect(PI);
  12849. +    WR(0,6,DRIVE);
  12850. +    WR(0,7,8);
  12851. +
  12852. +    pt_sleep(2);
  12853. +
  12854. +        k = 0;
  12855. +        while ((k++ < PT_RESET_TMO) && (RR(1,6)&STAT_BUSY))
  12856. +                pt_sleep(10);
  12857. +
  12858. +    flg = 1;
  12859. +    for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
  12860. +
  12861. +    if (verbose) {
  12862. +        printk("%s: Reset (%d) signature = ",PT.name,k);
  12863. +        for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
  12864. +        if (!flg) printk(" (incorrect)");
  12865. +        printk("\n");
  12866. +    }
  12867. +    
  12868. +    pi_disconnect(PI);
  12869. +    return flg-1;    
  12870. +}
  12871. +
  12872. +static int pt_ready_wait( int unit, int tmo )
  12873. +
  12874. +{    char    tr_cmd[12] = {ATAPI_TEST_READY,0,0,0,0,0,0,0,0,0,0,0};
  12875. +    int    k, p;
  12876. +
  12877. +    k = 0;
  12878. +    while (k < tmo) {
  12879. +      PT.last_sense = 0;
  12880. +      pt_atapi(unit,tr_cmd,0,NULL,DBMSG("test unit ready"));
  12881. +      p = PT.last_sense;
  12882. +      if (!p) return 0;
  12883. +      if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
  12884. +      k++;
  12885. +          pt_sleep(100);
  12886. +    }
  12887. +    return 0x000020;    /* timeout */
  12888. +}
  12889. +
  12890. +static void xs( char *buf, char *targ, int offs, int len )
  12891. +
  12892. +{    int    j,k,l;
  12893. +
  12894. +    j=0; l=0;
  12895. +    for (k=0;k<len;k++) 
  12896. +       if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
  12897. +        l=targ[j++]=buf[k+offs];
  12898. +    if (l==0x20) j--; targ[j]=0;
  12899. +}
  12900. +
  12901. +static int xn( char *buf, int offs, int size )
  12902. +
  12903. +{    int    v,k;
  12904. +
  12905. +    v=0; 
  12906. +    for(k=0;k<size;k++) v=v*256+(buf[k+offs]&0xff);
  12907. +    return v;
  12908. +}
  12909. +
  12910. +static int pt_identify( int unit )
  12911. +
  12912. +{    int     dt, s;
  12913. +    char    *ms[2] = {"master","slave"};
  12914. +    char    mf[10], id[18];
  12915. +    char    id_cmd[12] = { ATAPI_IDENTIFY,0,0,0,36,0,0,0,0,0,0,0};
  12916. +        char    ms_cmd[12] = { ATAPI_MODE_SENSE,0,0x2a,0,128,0,0,0,0,0,0,0};
  12917. +    char    ls_cmd[12] = { ATAPI_LOG_SENSE,0,0x71,0,0,0,0,0,128,0,0,0};
  12918. +    char    buf[36];
  12919. +
  12920. +        s = pt_atapi(unit,id_cmd,36,buf,"identify");
  12921. +    if (s) return -1;
  12922. +
  12923. +    dt = buf[0] & 0x1f;
  12924. +    if (dt != 1) {
  12925. +          if (verbose) 
  12926. +           printk("%s: Drive %d, unsupported type %d\n",
  12927. +                PT.name,PT.drive,dt);
  12928. +          return -1;
  12929. +           }
  12930. +
  12931. +    xs(buf,mf,8,8);
  12932. +    xs(buf,id,16,16);
  12933. +
  12934. +    PT.flags = 0;
  12935. +    PT.capacity = 0;
  12936. +    PT.bs = 0;
  12937. +
  12938. +    if (!pt_ready_wait(unit,PT_READY_TMO)) PT.flags |= PT_MEDIA;
  12939. +
  12940. +        if (!pt_atapi(unit,ms_cmd,36,buf,"mode sense")) {
  12941. +          if (!(buf[2] & 0x80)) PT.flags |= PT_WRITE_OK;
  12942. +      PT.bs = xn(buf,10,2);
  12943. +    }
  12944. +
  12945. +        if (!pt_atapi(unit,ls_cmd,36,buf,"log sense")) 
  12946. +        PT.capacity = xn(buf,24,4);
  12947. +
  12948. +        printk("%s: %s %s, %s",
  12949. +        PT.name,mf,id,ms[PT.drive]);
  12950. +        if (!(PT.flags & PT_MEDIA)) 
  12951. +                printk(", no media\n");
  12952. +        else {  if (!(PT.flags & PT_WRITE_OK)) printk(", RO");
  12953. +                printk(", blocksize %d, %d MB\n",
  12954. +               PT.bs,PT.capacity/1024);
  12955. +        }
  12956. +
  12957. +    return 0;
  12958. +}
  12959. +
  12960. +static int pt_probe( int unit )
  12961. +
  12962. +/*    returns  0, with id set if drive is detected
  12963. +            -1, if drive detection failed
  12964. +*/
  12965. +
  12966. +{    if (PT.drive == -1) {
  12967. +       for (PT.drive=0;PT.drive<=1;PT.drive++)
  12968. +        if (!pt_reset(unit)) return pt_identify(unit);
  12969. +    } else {
  12970. +       if (!pt_reset(unit)) return pt_identify(unit);
  12971. +    }
  12972. +        return -1; 
  12973. +}
  12974. +
  12975. +static int pt_detect( void )
  12976. +
  12977. +{    int    k, unit;
  12978. +
  12979. +    printk("%s: %s version %s, major %d\n",
  12980. +        name,name,PT_VERSION,major);
  12981. +
  12982. +    k = 0;
  12983. +    if (pt_drive_count == 0) {
  12984. +        unit = 0;
  12985. +        if (pi_init(PI,1,-1,-1,-1,-1,-1,pt_scratch,
  12986. +                        PI_PT,verbose,PT.name)) {
  12987. +            if (!pt_probe(unit)) {
  12988. +            PT.present = 1;
  12989. +            k++;
  12990. +            } else pi_release(PI);
  12991. +        }
  12992. +
  12993. +    } else for (unit=0;unit<PT_UNITS;unit++) if (DU[D_PRT])
  12994. +        if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
  12995. +            DU[D_PRO],DU[D_DLY],pt_scratch,PI_PT,verbose,
  12996. +            PT.name)) { 
  12997. +                if (!pt_probe(unit)) {
  12998. +                        PT.present = 1;
  12999. +                        k++;
  13000. +                } else pi_release(PI);
  13001. +            }
  13002. +
  13003. +    if (k) return 0;
  13004. +
  13005. +    printk("%s: No ATAPI tape drive detected\n",name);
  13006. +    return -1;
  13007. +}
  13008. +
  13009. +#define DEVICE_NR(dev)    (MINOR(dev) % 128)
  13010. +
  13011. +static int pt_open (struct inode *inode, struct file *file)
  13012. +
  13013. +{       int    unit = DEVICE_NR(inode->i_rdev);
  13014. +
  13015. +        if ((unit >= PT_UNITS) || (!PT.present)) return -ENODEV;
  13016. +
  13017. +        PT.access++;
  13018. +
  13019. +    if (PT.access > 1) {
  13020. +        PT.access--;
  13021. +        return -EBUSY;
  13022. +    }
  13023. +
  13024. +        MOD_INC_USE_COUNT;
  13025. +
  13026. +    pt_identify(unit);
  13027. +
  13028. +    if (!PT.flags & PT_MEDIA) {
  13029. +        PT.access--;
  13030. +        MOD_DEC_USE_COUNT;
  13031. +        return -ENODEV;
  13032. +        }
  13033. +
  13034. +    if ((!PT.flags & PT_WRITE_OK) && (file ->f_mode & 2)) {
  13035. +        PT.access--;
  13036. +        MOD_DEC_USE_COUNT;
  13037. +        return -EROFS;
  13038. +        }
  13039. +
  13040. +    if (!(MINOR(inode->i_rdev) & 128))
  13041. +        PT.flags |= PT_REWIND;
  13042. +
  13043. +    PT.bufptr = kmalloc(PT_BUFSIZE,GFP_KERNEL);
  13044. +    if (PT.bufptr == NULL) {
  13045. +        PT.access--;
  13046. +        MOD_DEC_USE_COUNT;
  13047. +        printk("%s: buffer allocation failed\n",PT.name);
  13048. +        return -ENOMEM;
  13049. +    }
  13050. +
  13051. +        return 0;
  13052. +}
  13053. +
  13054. +static int pt_ioctl(struct inode *inode,struct file *file,
  13055. +                    unsigned int cmd, unsigned long arg)
  13056. +{
  13057. +    int unit;
  13058. +    struct mtop mtop;
  13059. +
  13060. +        if (!inode || !inode->i_rdev)
  13061. +        return -EINVAL;
  13062. +        unit = DEVICE_NR(inode->i_rdev);
  13063. +        if (unit >= PT_UNITS)
  13064. +        return -EINVAL;
  13065. +        if (!PT.present)
  13066. +        return -ENODEV;
  13067. +
  13068. +        switch (cmd) {
  13069. +        case MTIOCTOP:    
  13070. +        memcpy_fromfs((char *)&mtop, (char *)arg, 
  13071. +                       sizeof(struct mtop));
  13072. +
  13073. +        switch (mtop.mt_op) {
  13074. +
  13075. +            case MTREW: 
  13076. +            pt_rewind(unit);
  13077. +            return 0;
  13078. +
  13079. +            default:    
  13080. +            printk("%s: Unimplemented mt_op %d\n",PT.name,
  13081. +                    mtop.mt_op);
  13082. +            return -EINVAL;
  13083. +        }
  13084. +
  13085. +            default:
  13086. +        printk("%s: Unimplemented ioctl 0x%x\n",PT.name,cmd);
  13087. +                return -EINVAL;
  13088. +
  13089. +        }
  13090. +}
  13091. +
  13092. +
  13093. +static void pt_release (struct inode *inode, struct file *file)
  13094. +{
  13095. +        int    unit = DEVICE_NR(inode->i_rdev);
  13096. +
  13097. +        if ((unit >= PT_UNITS) || (PT.access <= 0)) 
  13098. +                return;
  13099. +
  13100. +    if (PT.flags & PT_WRITING) pt_write_fm(unit);
  13101. +
  13102. +    if (PT.flags & PT_REWIND) pt_rewind(unit);    
  13103. +
  13104. +    PT.access--;
  13105. +
  13106. +    kfree(PT.bufptr);
  13107. +    PT.bufptr = NULL;
  13108. +
  13109. +        MOD_DEC_USE_COUNT;
  13110. +
  13111. +}
  13112. +
  13113. +static int pt_read(struct inode *inode, struct file *filp, char *buf, int count)
  13114. +
  13115. +{    int    unit = DEVICE_NR(inode->i_rdev);
  13116. +    char    rd_cmd[12] = {ATAPI_READ_6,1,0,0,0,0,0,0,0,0,0,0};
  13117. +    int    k, n, r, p, s, t, b;
  13118. +
  13119. +    if (!(PT.flags & (PT_READING|PT_WRITING))) {
  13120. +        PT.flags |= PT_READING;
  13121. +        if (pt_atapi(unit,rd_cmd,0,NULL,"start read-ahead"))
  13122. +            return -EIO;
  13123. +    } else if (PT.flags & PT_WRITING) return -EIO;
  13124. +
  13125. +    if (PT.flags & PT_EOF) return 0;
  13126. +
  13127. +    t = 0;
  13128. +
  13129. +    while (count > 0) {
  13130. +
  13131. +        if (!pt_poll_dsc(unit,1,PT_TMO,"read")) return -EIO;
  13132. +
  13133. +        n = count;
  13134. +        if (n > 32768) n = 32768;   /* max per command */
  13135. +        b = (n-1+PT.bs)/PT.bs;
  13136. +        n = b*PT.bs;        /* rounded up to even block */
  13137. +
  13138. +        rd_cmd[4] = b;
  13139. +
  13140. +        r = pt_command(unit,rd_cmd,n,"read");
  13141. +
  13142. +        udelay(1000);
  13143. +
  13144. +        if (r) {
  13145. +            pt_req_sense(unit,0);
  13146. +            return -EIO;
  13147. +        }
  13148. +
  13149. +        while (1) {
  13150. +
  13151. +            r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR|STAT_READY,
  13152. +                                           DBMSG("read DRQ"),"");
  13153. +
  13154. +            if (r & STAT_SENSE) {
  13155. +                pi_disconnect(PI);
  13156. +            pt_req_sense(unit,0);
  13157. +            return -EIO;
  13158. +            }
  13159. +
  13160. +            if (r) PT.flags |= PT_EOF; 
  13161. +
  13162. +            s = RR(0,7);
  13163. +
  13164. +            if (!(s & STAT_DRQ)) break;
  13165. +
  13166. +            n = (RR(0,4)+256*RR(0,5));
  13167. +            p = (RR(0,2)&3);
  13168. +            if (p != 2) {
  13169. +            pi_disconnect(PI);
  13170. +            printk("%s: Phase error on read: %d\n",PT.name,p);
  13171. +            return -EIO;
  13172. +            }
  13173. +
  13174. +            while (n > 0) {
  13175. +            k = n;
  13176. +            if (k > PT_BUFSIZE) k = PT_BUFSIZE; 
  13177. +            pi_read_block(PI,PT.bufptr,k);
  13178. +            n -= k;
  13179. +            b = k;
  13180. +            if (b > count) b = count;
  13181. +            memcpy_tofs(buf+t,PT.bufptr,b);
  13182. +            t += b;
  13183. +            count -= b;
  13184. +            }
  13185. +
  13186. +        }
  13187. +        pi_disconnect(PI);
  13188. +        if (PT.flags & PT_EOF) break;
  13189. +    }
  13190. +
  13191. +    return t;
  13192. +
  13193. +}
  13194. +
  13195. +static int pt_write(struct inode *inode, struct file *filp, 
  13196. +            const char *buf, int count)
  13197. +
  13198. +{    int unit = DEVICE_NR(inode->i_rdev);
  13199. +        char    wr_cmd[12] = {ATAPI_WRITE_6,1,0,0,0,0,0,0,0,0,0,0};
  13200. +        int     k, n, r, p, s, t, b;
  13201. +
  13202. +    if (!(PT.flags & PT_WRITE_OK)) return -EROFS;
  13203. +
  13204. +        if (!(PT.flags & (PT_READING|PT_WRITING))) {
  13205. +            PT.flags |= PT_WRITING;
  13206. +            if (pt_atapi(unit,wr_cmd,0,NULL,"start buffer-available mode"))
  13207. +                        return -EIO;
  13208. +        } else if (PT.flags&PT_READING) return -EIO;
  13209. +
  13210. +    if (PT.flags & PT_EOF) return -ENOSPC;
  13211. +
  13212. +    t = 0;
  13213. +
  13214. +    while (count > 0) {
  13215. +
  13216. +        if (!pt_poll_dsc(unit,1,PT_TMO,"write")) return -EIO;
  13217. +
  13218. +            n = count;
  13219. +            if (n > 32768) n = 32768;    /* max per command */
  13220. +            b = (n-1+PT.bs)/PT.bs;
  13221. +            n = b*PT.bs;                /* rounded up to even block */
  13222. +
  13223. +            wr_cmd[4] = b;
  13224. +
  13225. +            r = pt_command(unit,wr_cmd,n,"write");
  13226. +
  13227. +            udelay(1000);
  13228. +
  13229. +            if (r) {            /* error delivering command only */
  13230. +                pt_req_sense(unit,0);
  13231. +                return -EIO;
  13232. +            }
  13233. +
  13234. +        while (1) {
  13235. +
  13236. +                r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR|STAT_READY,
  13237. +                                    DBMSG("write DRQ"),NULL);
  13238. +
  13239. +                if (r & STAT_SENSE) {
  13240. +                    pi_disconnect(PI);
  13241. +                    pt_req_sense(unit,0);
  13242. +                    return -EIO;
  13243. +                }
  13244. +
  13245. +                if (r) PT.flags |= PT_EOF;
  13246. +
  13247. +            s = RR(0,7);
  13248. +
  13249. +            if (!(s & STAT_DRQ)) break;
  13250. +
  13251. +                n = (RR(0,4)+256*RR(0,5));
  13252. +                p = (RR(0,2)&3);
  13253. +                if (p != 0) {
  13254. +                    pi_disconnect(PI);
  13255. +                    printk("%s: Phase error on write: %d \n",PT.name,p);
  13256. +                    return -EIO;
  13257. +                }
  13258. +
  13259. +                while (n > 0) {
  13260. +            k = n;
  13261. +            if (k > PT_BUFSIZE) k = PT_BUFSIZE;
  13262. +            b = k;
  13263. +            if (b > count) b = count;
  13264. +            memcpy_fromfs(PT.bufptr,buf+t,b);
  13265. +                    pi_write_block(PI,PT.bufptr,k);
  13266. +            t += b;
  13267. +            count -= b;
  13268. +            n -= k;
  13269. +                }
  13270. +
  13271. +        }
  13272. +        pi_disconnect(PI);
  13273. +        if (PT.flags & PT_EOF) break;
  13274. +    }
  13275. +
  13276. +    return t;
  13277. +}
  13278. +
  13279. +/* end of pt.c */
  13280. +
  13281. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/setup.h linux/drivers/block/paride/setup.h
  13282. --- v2.0.34/linux/drivers/block/paride/setup.h    Wed Dec 31 16:00:00 1969
  13283. +++ linux/drivers/block/paride/setup.h    Mon Jul 13 13:47:28 1998
  13284. @@ -0,0 +1,69 @@
  13285. +/*
  13286. +    setup.h       (c) 1997-8   Grant R. Guenther <grant@torque.net>
  13287. +                        Under the terms of the GNU public license.
  13288. +
  13289. +        This is a table driven setup function for kernel modules
  13290. +        using the module.variable=val,... command line notation.
  13291. +
  13292. +*/
  13293. +
  13294. +/* Changes:
  13295. +
  13296. +    1.01    GRG 1998.05.05    Allow negative and defaulted values
  13297. +
  13298. +*/
  13299. +
  13300. +#include <linux/ctype.h>
  13301. +#include <linux/string.h>
  13302. +
  13303. +struct setup_tab_t {
  13304. +
  13305. +    char    *tag;    /* variable name */
  13306. +    int    size;    /* number of elements in array */
  13307. +    int    *iv;    /* pointer to variable */
  13308. +};
  13309. +
  13310. +typedef struct setup_tab_t STT;
  13311. +
  13312. +/*  t       is a table that describes the variables that can be set
  13313. +      by gen_setup
  13314. +    n      is the number of entries in the table
  13315. +    ss      is a string of the form:
  13316. +
  13317. +        <tag>=[<val>,...]<val>
  13318. +*/
  13319. +
  13320. +static void generic_setup( STT t[], int n, char *ss )
  13321. +
  13322. +{    int    j,k, sgn;
  13323. +
  13324. +    k = 0;
  13325. +    for (j=0;j<n;j++) {
  13326. +        k = strlen(t[j].tag);
  13327. +        if (strncmp(ss,t[j].tag,k) == 0) break;
  13328. +    }
  13329. +    if (j == n) return;
  13330. +
  13331. +    if (ss[k] == 0) {
  13332. +        t[j].iv[0] = 1;
  13333. +        return;
  13334. +    }
  13335. +
  13336. +    if (ss[k] != '=') return;
  13337. +    ss += (k+1);
  13338. +
  13339. +    k = 0;
  13340. +    while (ss && (k < t[j].size)) {
  13341. +        if (!*ss) break;
  13342. +        sgn = 1;
  13343. +        if (*ss == '-') { ss++; sgn = -1; }
  13344. +        if (!*ss) break;
  13345. +        if (isdigit(*ss))
  13346. +          t[j].iv[k] = sgn * simple_strtoul(ss,NULL,0);
  13347. +        k++; 
  13348. +        if ((ss = strchr(ss,',')) != NULL) ss++;
  13349. +    }
  13350. +}
  13351. +
  13352. +/* end of setup.h */
  13353. +
  13354. diff -u --recursive --new-file v2.0.34/linux/drivers/block/paride/spinlock.h linux/drivers/block/paride/spinlock.h
  13355. --- v2.0.34/linux/drivers/block/paride/spinlock.h    Wed Dec 31 16:00:00 1969
  13356. +++ linux/drivers/block/paride/spinlock.h    Mon Jul 13 13:47:28 1998
  13357. @@ -0,0 +1,6 @@
  13358. +/* spinlock.h -- dummy version for PARIDE-2.0.34 */
  13359. +
  13360. +#define spin_lock_irqsave(a,b)         { save_flags(b); cli(); }
  13361. +#define spin_unlock_irqrestore(a,b)     restore_flags(b);
  13362. +
  13363. +
  13364. diff -u --recursive --new-file v2.0.34/linux/drivers/block/raid0.c linux/drivers/block/raid0.c
  13365. --- v2.0.34/linux/drivers/block/raid0.c    Mon Jul 13 13:46:26 1998
  13366. +++ linux/drivers/block/raid0.c    Mon Jul 13 13:47:28 1998
  13367. @@ -243,6 +243,7 @@
  13368.           data->strip_zone[j].size);
  13369.    }
  13370.  #endif
  13371. +  sz+=sprintf (page+sz, " %dk chunks", 1<<FACTOR_SHIFT(FACTOR(mddev)));
  13372.    return sz;
  13373.  }
  13374.  
  13375. @@ -251,11 +252,14 @@
  13376.  {
  13377.    "raid0",
  13378.    raid0_map,
  13379. +  NULL,                /* no special make_request */
  13380. +  NULL,                /* no special end_request */
  13381.    raid0_run,
  13382.    raid0_stop,
  13383.    raid0_status,
  13384.    NULL,                /* no ioctls */
  13385. -  0
  13386. +  0,
  13387. +  NULL,                /* no error_handler */
  13388.  };
  13389.  
  13390.  
  13391. diff -u --recursive --new-file v2.0.34/linux/drivers/block/raid1.c linux/drivers/block/raid1.c
  13392. --- v2.0.34/linux/drivers/block/raid1.c    Wed Dec 31 16:00:00 1969
  13393. +++ linux/drivers/block/raid1.c    Mon Jul 13 13:47:28 1998
  13394. @@ -0,0 +1,766 @@
  13395. +/************************************************************************
  13396. + * raid1.c : Multiple Devices driver for Linux
  13397. + *           Copyright (C) 1996 Ingo Molnar, Miguel de Icaza, Gadi Oxman
  13398. + *
  13399. + * RAID-1 management functions.
  13400. + *
  13401. + * This program is free software; you can redistribute it and/or modify
  13402. + * it under the terms of the GNU General Public License as published by
  13403. + * the Free Software Foundation; either version 2, or (at your option)
  13404. + * any later version.
  13405. + *
  13406. + * You should have received a copy of the GNU General Public License
  13407. + * (for example /usr/src/linux/COPYING); if not, write to the Free
  13408. + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  13409. + */
  13410. +
  13411. +#include <linux/module.h>
  13412. +#include <linux/locks.h>
  13413. +#include <linux/malloc.h>
  13414. +#include <linux/md.h>
  13415. +#include <linux/raid1.h>
  13416. +#include <asm/bitops.h>
  13417. +#include <asm/atomic.h>
  13418. +
  13419. +#define MAJOR_NR MD_MAJOR
  13420. +#define MD_DRIVER
  13421. +#define MD_PERSONALITY
  13422. +
  13423. +/*
  13424. + * The following can be used to debug the driver
  13425. + */
  13426. +/*#define RAID1_DEBUG*/
  13427. +#ifdef RAID1_DEBUG
  13428. +#define PRINTK(x)   do { printk x; } while (0);
  13429. +#else
  13430. +#define PRINTK(x)   do { ; } while (0);
  13431. +#endif
  13432. +
  13433. +
  13434. +static struct md_personality raid1_personality;
  13435. +static struct md_thread *raid1_thread = NULL;
  13436. +struct buffer_head *raid1_retry_list = NULL;
  13437. +
  13438. +static int __raid1_map (struct md_dev *mddev, kdev_t *rdev,
  13439. +                unsigned long *rsector, unsigned long size)
  13440. +{
  13441. +    struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
  13442. +    int i, n = raid_conf->raid_disks;
  13443. +
  13444. +    /*
  13445. +     * Later we do read balancing on the read side 
  13446. +     * now we use the first available disk.
  13447. +     */
  13448. +
  13449. +    PRINTK(("raid1_map().\n"));
  13450. +
  13451. +    for (i=0; i<n; i++) {
  13452. +        if (raid_conf->mirrors[i].operational) {
  13453. +            *rdev = raid_conf->mirrors[i].dev;
  13454. +            return (0);
  13455. +        }
  13456. +    }
  13457. +
  13458. +    printk (KERN_ERR "raid1_map(): huh, no more operational devices?\n");
  13459. +    return (-1);
  13460. +}
  13461. +
  13462. +static int raid1_map (struct md_dev *mddev, kdev_t *rdev,
  13463. +              unsigned long *rsector, unsigned long size)
  13464. +{
  13465. +    return 0;
  13466. +}
  13467. +
  13468. +void raid1_reschedule_retry (struct buffer_head *bh)
  13469. +{
  13470. +    struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->private_bh);
  13471. +
  13472. +    PRINTK(("raid1_reschedule_retry().\n"));
  13473. +
  13474. +    r1_bh->next_retry = raid1_retry_list;
  13475. +    raid1_retry_list = bh;
  13476. +    md_wakeup_thread(raid1_thread);
  13477. +}
  13478. +
  13479. +/*
  13480. + * raid1_end_buffer_io() is called when we have finished servicing a mirrored
  13481. + * operation and are ready to return a success/failture code to the buffer
  13482. + * cache layer.
  13483. + */
  13484. +static inline void raid1_end_buffer_io (struct buffer_head *bh, int uptodate)
  13485. +{
  13486. +    /*
  13487. +     * kfree() can sleep and we try to keep this bh operation atomic.
  13488. +     */
  13489. +    struct raid1_bh * tmp = (struct raid1_bh *) bh->private_bh;
  13490. +
  13491. +    clear_bit (BH_MD, &bh->b_state);
  13492. +    bh->private_bh = NULL;
  13493. +    bh->personality = NULL;
  13494. +    mark_buffer_uptodate(bh, uptodate);
  13495. +    unlock_buffer(bh);
  13496. +    kfree(tmp);
  13497. +}
  13498. +
  13499. +void raid1_end_request (struct buffer_head *bh, int uptodate)
  13500. +{
  13501. +    struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->private_bh);
  13502. +    unsigned long flags;
  13503. +
  13504. +    save_flags(flags);
  13505. +    cli();
  13506. +    PRINTK(("raid1_end_request().\n"));
  13507. +
  13508. +    /*
  13509. +     * this branch is our 'one mirror IO has finished' event handler:
  13510. +     */
  13511. +    if (!uptodate)
  13512. +        md_error (bh->b_dev, bh->b_rdev);
  13513. +    else {
  13514. +        /*
  13515. +         * Set BH_Uptodate in our master buffer_head, so that
  13516. +         * we will return a good error code for to the higher
  13517. +         * levels even if IO on some other mirrored buffer fails.
  13518. +         *
  13519. +         * The 'master' represents the complex operation to 
  13520. +         * user-side. So if something waits for IO, then it will
  13521. +         * wait for the 'master' buffer_head.
  13522. +         */
  13523. +        set_bit (BH_Uptodate, &r1_bh->state);
  13524. +    }
  13525. +
  13526. +    /*
  13527. +     * We split up the read and write side, imho they are 
  13528. +     * conceptually different.
  13529. +     */
  13530. +
  13531. +    if ( (r1_bh->cmd == READ) || (r1_bh->cmd == READA) ) {
  13532. +
  13533. +        PRINTK(("raid1_end_request(), read branch.\n"));
  13534. +
  13535. +        /*
  13536. +         * we have only one buffer_head on the read side
  13537. +         */
  13538. +        if (uptodate) {
  13539. +            PRINTK(("raid1_end_request(), read branch, uptodate.\n"));
  13540. +            raid1_end_buffer_io (bh, uptodate);
  13541. +            restore_flags(flags);
  13542. +            return;
  13543. +        }
  13544. +        /*
  13545. +         * oops, read error:
  13546. +         */
  13547. +        printk(KERN_ERR "raid1: %s: rescheduling block %lu\n", 
  13548. +                 kdevname(bh->b_dev), bh->b_blocknr);
  13549. +        raid1_reschedule_retry (bh);
  13550. +        restore_flags(flags);
  13551. +        return;
  13552. +    }
  13553. +
  13554. +    /*
  13555. +     * WRITE or WRITEA.
  13556. +     */
  13557. +    PRINTK(("raid1_end_request(), write branch.\n"));
  13558. +
  13559. +    /*
  13560. +     * lets see if all mirrored write operations have finished 
  13561. +     * already [we have irqs off, so we can decrease]:
  13562. +     */
  13563. +
  13564. +    if (!--r1_bh->remaining) {
  13565. +        struct md_dev *mddev = r1_bh->mddev;
  13566. +        struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
  13567. +        int i, n = raid_conf->raid_disks;
  13568. +
  13569. +        PRINTK(("raid1_end_request(), remaining == 0.\n"));
  13570. +
  13571. +        /*
  13572. +         * kfree() can sleep? really? if yes then we are
  13573. +         * doomed here ...
  13574. +         */
  13575. +        for ( i=0; i<n; i++) {
  13576. +            if (r1_bh->mirror_bh[i]) kfree(r1_bh->mirror_bh[i]);
  13577. +        }
  13578. +
  13579. +        /*
  13580. +         * the 'master' bh is the one that is used in page IO,
  13581. +         * perhaps someone is waiting on it. Lets erase all
  13582. +         * signs of mirroring, and lets finish the bh operation:
  13583. +         *
  13584. +         * In particular, the "uptodate" value which we return
  13585. +         * to the higher level represents the entire mirror set.
  13586. +         *
  13587. +         * yes, and this is why i want to use the 'master' bh as
  13588. +         * a 'representative'. Thats why i think it's not clean to
  13589. +         * use the master bh for real IO. We mix concepts, which
  13590. +         * isnt too good.
  13591. +         *
  13592. +         * a buffer_head is basically a user-side file buffer.
  13593. +         * Normally it has direct relationship with the physical
  13594. +         * device, but as in this case, we have an abstract mapping
  13595. +         * between the file buffer and the physical layout. So i've
  13596. +         * reverted all changes that do this mixing.
  13597. +         *
  13598. +         * we 'waste' about 76 bytes for the one more buffer_head,
  13599. +         * but note that we will do the mirror bh allocation at once
  13600. +         * in the future, so this isnt really a valid point, i think.
  13601. +         *
  13602. +         * Also i dont like the current way of mixing the user-side buffer
  13603. +         * concept with the 'real' physical layout like raid0.c does
  13604. +         * now: it increases the size of buffer_head even for nonstriped
  13605. +         * devices, etc.
  13606. +         *
  13607. +         * IMHO, in the future, we should have a lightweight buffer_head
  13608. +         * structure, which holds almost no physical device information.
  13609. +         
  13610. +         * Abstract relationship between buffers:
  13611. +         * ===================================== 
  13612. +         * 
  13613. +         *           [user] 
  13614. +         *              |
  13615. +         *              |
  13616. +         *    ['master' buffer_head] + [private_buffer_head]
  13617. +         *                                      |
  13618. +         *                                      |
  13619. +         *                                      |
  13620. +         *                        [additional 'sub'-buffer_heads]
  13621. +         *                           |          |           | 
  13622. +         *                         [dev1]     [dev2]      [dev3]
  13623. +         * 
  13624. +         * In this scheme it's not clean to use the 'master' as one of
  13625. +         * the 'sub' buffer_heads. If you think about it, currently we can 
  13626. +         * do this only because raid0 introduced it's own private_buffer_head
  13627. +         * structure in buffer_head: rdev,rsector. And raid0 has a 1:1
  13628. +         * relationship to the physical device. But this is really just a
  13629. +         * special case. Once we have our megafast bh pools running, we could
  13630. +         * clean up raid0.c too :))
  13631. +         *
  13632. +         * Not that it isnt clean, it is lethal if in the future we insert our 
  13633. +         * sub buffer_heads into the global block cache. The master request
  13634. +         * should be an IO operation label for the complex operation, nothing
  13635. +         * more.
  13636. +         *
  13637. +         * So we have almost no performance arguments, and alot of cleanness
  13638. +         * arguments.
  13639. +         *
  13640. +         * Comments? Gonna change it back to your way again if you can convince
  13641. +         * me :)) --mingo
  13642. +         *
  13643. +         */
  13644. +        raid1_end_buffer_io ( r1_bh->master_bh, 
  13645. +                test_bit (BH_Uptodate, &r1_bh->state));
  13646. +    }
  13647. +    else PRINTK(("raid1_end_request(), remaining == %u.\n", r1_bh->remaining));
  13648. +    restore_flags(flags);
  13649. +}
  13650. +
  13651. +/* This routine checks if the undelying device is an md device and in that
  13652. + * case it maps the blocks before putting the request on the queue
  13653. + */
  13654. +static inline void
  13655. +map_and_make_request (int rw, struct buffer_head *bh)
  13656. +{
  13657. +    if (MAJOR (bh->b_rdev) == MD_MAJOR){
  13658. +        md_map (MINOR (bh->b_rdev), &bh->b_rdev, &bh->b_rsector, bh->b_size >> 9);
  13659. +    }
  13660. +    make_request (MAJOR (bh->b_rdev), rw, bh);
  13661. +}
  13662. +    
  13663. +static int
  13664. +raid1_make_request (struct md_dev *mddev, int rw, struct buffer_head * bh)
  13665. +{
  13666. +
  13667. +    struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
  13668. +    struct buffer_head *mirror_bh[MD_SB_DISKS];
  13669. +    struct raid1_bh * r1_bh;
  13670. +    int n = raid_conf->raid_disks, i, sum_bhs = 0, switch_disks = 0, sectors;
  13671. +    struct mirror_info *mirror;
  13672. +
  13673. +    PRINTK(("raid1_make_request().\n"));
  13674. +
  13675. +/*
  13676. + * We put allocations at the beginning, to avoid sleeping while doing
  13677. + * atomic operations of buffer heads. This might or might not make much
  13678. + * difference, but lets rather be careful.
  13679. + *
  13680. + * but this has two side effects (probably non harmless):
  13681. + *
  13682. + *    1.    The buffer will not be locked while we sleep.
  13683. + *    2.    The rest of the kernel will see BH_Req without
  13684. + *        BH_Lock.
  13685. + */
  13686. +    while (!( /* FIXME: now we are rather fault tolerant than nice */
  13687. +    r1_bh = kmalloc (sizeof (struct raid1_bh), GFP_KERNEL)
  13688. +    ) )
  13689. +        printk ("raid1_make_request(#1): out of memory\n");
  13690. +    memset (r1_bh, 0, sizeof (struct raid1_bh));
  13691. +/*
  13692. + * make_request() can abort the operation when READA or WRITEA are being
  13693. + * used and no empty request is available.
  13694. + *
  13695. + * Currently, just replace the command with READ/WRITE.
  13696. + */
  13697. +    if (rw == READA) rw = READ;
  13698. +    if (rw == WRITEA) rw = WRITE;
  13699. +
  13700. +    if (rw == WRITE || rw == WRITEA)
  13701. +        mark_buffer_clean(bh);        /* Too early ? */
  13702. +
  13703. +/*
  13704. + * i think the read and write branch should be separated completely, since we want
  13705. + * to do read balancing on the read side for example. Comments? :) --mingo
  13706. + */
  13707. +
  13708. +    r1_bh->master_bh=bh;
  13709. +    r1_bh->mddev=mddev;
  13710. +    r1_bh->cmd = rw;
  13711. +
  13712. +    set_bit (BH_MD,    &bh->b_state);
  13713. +    bh->personality  = &raid1_personality;
  13714. +    bh->private_bh   = (void*)(r1_bh);
  13715. +
  13716. +    if (rw==READ || rw==READA) {
  13717. +        int last_used = raid_conf->last_used;
  13718. +        PRINTK(("raid1_make_request(), read branch.\n"));
  13719. +        mirror = raid_conf->mirrors + last_used;
  13720. +        bh->b_rdev = mirror->dev;
  13721. +        sectors = bh->b_size >> 9;
  13722. +        if (bh->b_blocknr * sectors == raid_conf->next_sect) {
  13723. +            raid_conf->sect_count += sectors;
  13724. +            if (raid_conf->sect_count >= mirror->sect_limit)
  13725. +                switch_disks = 1;
  13726. +        } else
  13727. +            switch_disks = 1;
  13728. +        raid_conf->next_sect = (bh->b_blocknr + 1) * sectors;
  13729. +        if (switch_disks) {
  13730. +            PRINTK(("read-balancing: switching %d -> %d (%d sectors)\n", last_used, mirror->next, raid_conf->sect_count));
  13731. +            raid_conf->sect_count = 0;
  13732. +            raid_conf->last_used = mirror->next;
  13733. +        }
  13734. +        PRINTK (("raid1 read queue: %d %d\n", MAJOR (bh->b_rdev), MINOR (bh->b_rdev)));
  13735. +
  13736. +        clear_bit (BH_Lock, &bh->b_state);
  13737. +        map_and_make_request (rw, bh);
  13738. +        return 0;
  13739. +    }
  13740. +
  13741. +    /*
  13742. +     * WRITE or WRITEA.
  13743. +     */
  13744. +/*
  13745. + * btw, we have no more master disk. 'slave' is gone too :) [i hate that word :))]
  13746. + *
  13747. + * We are now using the master bh for a real IO. It seems important that:
  13748. + *
  13749. + * 1.    lock_buffer() will be called when we start to handle the request,
  13750. + *    before we do anything (done by ll_rw_blk.c).
  13751. + *
  13752. + * 2.    It seems that Linus took great care to set mark_buffer_clean()
  13753. + *    atomically with cli() in effect just when the buffer was placed
  13754. + *    into the queue. To be compatible with this behavior, it would be
  13755. + *    best to lock the buffer *first*, but mark it clean *last*, and to
  13756. + *    do this by passing through the exact logic in ll_rw_blk.c.
  13757. + *
  13758. + * Note: i've reverted this #3 thing, see the big comment in this file.
  13759. + *
  13760. + * 3.    We are now called from within make_request(), so the real bh
  13761. + *    will be automatically handled last when we return, so we only need
  13762. + *    to add the rest of the buffers (but remember to include the
  13763. + *    master bh in the remaining count).
  13764. + */
  13765. +    PRINTK(("raid1_make_request(n=%d), write branch.\n",n));
  13766. +
  13767. +    for (i = 0; i < n; i++) {
  13768. +
  13769. +        if (!raid_conf->mirrors [i].operational) {
  13770. +            /*
  13771. +             * the r1_bh->mirror_bh[i] pointer remains NULL
  13772. +             */
  13773. +            mirror_bh[i] = NULL;
  13774. +            continue;
  13775. +        }
  13776. +
  13777. +    /*
  13778. +     * We should use a private pool (size depending on NR_REQUEST),
  13779. +     * to avoid writes filling up the memory with bhs
  13780. +     *
  13781. +     * Such pools are much faster than kmalloc anyways (so we waste almost 
  13782. +     * nothing by not using the master bh when writing and win alot of cleanness)
  13783. +     *
  13784. +     * but for now we are cool enough. --mingo
  13785. +     *
  13786. +     * It's safe to sleep here, buffer heads cannot be used in a shared
  13787. +     * manner in the write branch. Look how we lock the buffer at the beginning
  13788. +     * of this function to grok the difference ;)
  13789. +     */
  13790. +        while (!( /* FIXME: now we are rather fault tolerant than nice */
  13791. +        mirror_bh[i] = kmalloc (sizeof (struct buffer_head), GFP_KERNEL)
  13792. +        ) )
  13793. +            printk ("raid1_make_request(#2): out of memory\n");
  13794. +        memset (mirror_bh[i], 0, sizeof (struct buffer_head));
  13795. +
  13796. +    /*
  13797. +     * prepare mirrored bh (fields ordered for max mem throughput):
  13798. +     */
  13799. +        mirror_bh [i]->b_blocknr    = bh->b_blocknr;
  13800. +        mirror_bh [i]->b_dev        = bh->b_dev;
  13801. +        mirror_bh [i]->b_rdev         = raid_conf->mirrors [i].dev;
  13802. +        mirror_bh [i]->b_rsector    = bh->b_rsector;
  13803. +        mirror_bh [i]->b_state      =   (1<<BH_MD)      | (1<<BH_Req) | 
  13804. +                        (1<<BH_Touched) | (1<<BH_Dirty);
  13805. +        mirror_bh [i]->b_count      = 1;
  13806. +        mirror_bh [i]->b_size       = bh->b_size;
  13807. +        mirror_bh [i]->b_data       = bh->b_data;
  13808. +        mirror_bh [i]->b_list       = BUF_LOCKED;
  13809. +        mirror_bh [i]->personality  = &raid1_personality;
  13810. +        mirror_bh [i]->private_bh   = (void*)(r1_bh);
  13811. +
  13812. +        r1_bh->mirror_bh[i] = mirror_bh[i];
  13813. +        sum_bhs++;
  13814. +    }
  13815. +
  13816. +    r1_bh->remaining = sum_bhs;
  13817. +
  13818. +    PRINTK(("raid1_make_request(), write branch, sum_bhs=%d.\n",sum_bhs));
  13819. +
  13820. +    /*
  13821. +     * We have to be a bit careful about the semaphore above, thats why we
  13822. +     * start the requests separately. Since kmalloc() could fail, sleep and
  13823. +     * make_request() can sleep too, this is the safer solution. Imagine,
  13824. +     * end_request decreasing the semaphore before we could have set it up ...
  13825. +     * We could play tricks with the semaphore (presetting it and correcting
  13826. +     * at the end if sum_bhs is not 'n' but we have to do end_request by hand
  13827. +     * if all requests finish until we had a chance to set up the semaphore
  13828. +     * correctly ... lots of races).
  13829. +     */
  13830. +    for (i = 0; i < n; i++)
  13831. +        if (mirror_bh [i] != NULL)
  13832. +            map_and_make_request (rw, mirror_bh [i]);
  13833. +
  13834. +    return (0);
  13835. +}
  13836. +               
  13837. +static int raid1_status (char *page, int minor, struct md_dev *mddev)
  13838. +{
  13839. +    struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
  13840. +    int sz = 0, i;
  13841. +    
  13842. +    sz += sprintf (page+sz, " [%d/%d] [", raid_conf->raid_disks, raid_conf->working_disks);
  13843. +    for (i = 0; i < raid_conf->raid_disks; i++)
  13844. +        sz += sprintf (page+sz, "%s", raid_conf->mirrors [i].operational ? "U" : "_");
  13845. +    sz += sprintf (page+sz, "]");
  13846. +    return sz;
  13847. +}
  13848. +
  13849. +static void raid1_fix_links (struct raid1_data *raid_conf, int failed_index)
  13850. +{
  13851. +    int disks = raid_conf->raid_disks;
  13852. +    int j;
  13853. +
  13854. +    for (j = 0; j < disks; j++)
  13855. +        if (raid_conf->mirrors [j].next == failed_index)
  13856. +            raid_conf->mirrors [j].next = raid_conf->mirrors [failed_index].next;
  13857. +}
  13858. +
  13859. +static int raid1_error (struct md_dev *mddev, kdev_t dev)
  13860. +{
  13861. +    struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
  13862. +    struct mirror_info *mirror;
  13863. +    md_superblock_t *sb = mddev->sb;
  13864. +    int disks = raid_conf->raid_disks;
  13865. +    int i;
  13866. +
  13867. +    PRINTK(("raid1_error called\n"));
  13868. +
  13869. +    if (raid_conf->working_disks == 1) {
  13870. +        /*
  13871. +         * Uh oh, we can do nothing if this is our last disk, but
  13872. +         * first check if this is a queued request for a device
  13873. +         * which has just failed.
  13874. +         */
  13875. +        for (i = 0, mirror = raid_conf->mirrors; i < disks; i++, mirror++)
  13876. +            if (mirror->dev == dev && !mirror->operational)
  13877. +                return 0;
  13878. +        printk (KERN_ALERT "RAID1: only one disk left and IO error.\n");
  13879. +        return 0;
  13880. +    }
  13881. +
  13882. +    /* Mark disk as unusable */
  13883. +    for (i = 0, mirror = raid_conf->mirrors; i < disks; i++, mirror++) {
  13884. +        if (mirror->dev == dev && mirror->operational){
  13885. +            mirror->operational = 0;
  13886. +            raid1_fix_links (raid_conf, i);
  13887. +            sb->disks[mirror->number].state |= (1 << MD_FAULTY_DEVICE);
  13888. +            sb->disks[mirror->number].state &= ~(1 << MD_SYNC_DEVICE);
  13889. +            sb->disks[mirror->number].state &= ~(1 << MD_ACTIVE_DEVICE);
  13890. +            sb->active_disks--;
  13891. +            sb->working_disks--;
  13892. +            sb->failed_disks++;
  13893. +            mddev->sb_dirty = 1;
  13894. +            md_wakeup_thread(raid1_thread);
  13895. +            raid_conf->working_disks--;
  13896. +            printk (KERN_ALERT
  13897. +                "RAID1: Disk failure on %s, disabling device."
  13898. +                "Operation continuing on %d devices\n",
  13899. +                kdevname (dev), raid_conf->working_disks);
  13900. +        }
  13901. +    }
  13902. +
  13903. +    return 0;
  13904. +}
  13905. +
  13906. +/*
  13907. + * This is a kernel thread which:
  13908. + *
  13909. + *    1.    Retries failed read operations on working mirrors.
  13910. + *    2.    Updates the raid superblock when problems are encountered.
  13911. + */
  13912. +void raid1d (void *data)
  13913. +{
  13914. +    struct buffer_head *bh;
  13915. +    kdev_t dev;
  13916. +    unsigned long flags;
  13917. +    struct raid1_bh * r1_bh;
  13918. +    struct md_dev *mddev;
  13919. +
  13920. +    PRINTK(("raid1d() active\n"));
  13921. +    save_flags(flags);
  13922. +    cli();
  13923. +    while (raid1_retry_list) {
  13924. +        bh = raid1_retry_list;
  13925. +        r1_bh = (struct raid1_bh *)(bh->private_bh);
  13926. +        raid1_retry_list = r1_bh->next_retry;
  13927. +        restore_flags(flags);
  13928. +
  13929. +        mddev = md_dev + MINOR(bh->b_dev);
  13930. +        if (mddev->sb_dirty) {
  13931. +            mddev->sb_dirty = 0;
  13932. +            md_update_sb(MINOR(bh->b_dev));
  13933. +        }
  13934. +        dev = bh->b_rdev;
  13935. +        __raid1_map (md_dev + MINOR(bh->b_dev), &bh->b_rdev, &bh->b_rsector, bh->b_size >> 9);
  13936. +        if (bh->b_rdev == dev) {
  13937. +            printk (KERN_ALERT 
  13938. +                    "raid1: %s: unrecoverable I/O read error for block %lu\n",
  13939. +                        kdevname(bh->b_dev), bh->b_blocknr);
  13940. +            raid1_end_buffer_io (bh, 0);
  13941. +        } else {
  13942. +            printk (KERN_ERR "raid1: %s: redirecting sector %lu to another mirror\n", 
  13943. +                      kdevname(bh->b_dev), bh->b_blocknr);
  13944. +            clear_bit (BH_Lock, &bh->b_state);
  13945. +            map_and_make_request (r1_bh->cmd, bh);
  13946. +        }
  13947. +        cli();
  13948. +    }
  13949. +    restore_flags(flags);
  13950. +    
  13951. +}
  13952. +
  13953. +/*
  13954. + * This will catch the scenario in which one of the mirrors was
  13955. + * mounted as a normal device rather than as a part of a raid set.
  13956. + */
  13957. +static int check_consistenty (struct md_dev *mddev)
  13958. +{
  13959. +    struct raid1_data *raid_conf = mddev->private;
  13960. +    kdev_t dev;
  13961. +    struct buffer_head *bh = NULL;
  13962. +    int i, rc = 0;
  13963. +    char *buffer = NULL;
  13964. +
  13965. +    for (i = 0; i < raid_conf->raid_disks; i++) {
  13966. +        if (!raid_conf->mirrors[i].operational)
  13967. +            continue;
  13968. +        dev = raid_conf->mirrors[i].dev;
  13969. +        set_blocksize(dev, 4096);
  13970. +        if ((bh = bread(dev, 0, 4096)) == NULL)
  13971. +            break;
  13972. +        if (!buffer) {
  13973. +            buffer = (char *) __get_free_page(GFP_KERNEL);
  13974. +            if (!buffer)
  13975. +                break;
  13976. +            memcpy(buffer, bh->b_data, 4096);
  13977. +        } else if (memcmp(buffer, bh->b_data, 4096)) {
  13978. +            rc = 1;
  13979. +            break;
  13980. +        }
  13981. +        bforget(bh);
  13982. +        fsync_dev(dev);
  13983. +        invalidate_buffers(dev);
  13984. +        bh = NULL;
  13985. +    }
  13986. +    if (buffer)
  13987. +        free_page((unsigned long) buffer);
  13988. +    if (bh) {
  13989. +        dev = bh->b_dev;
  13990. +        bforget(bh);
  13991. +        fsync_dev(dev);
  13992. +        invalidate_buffers(dev);
  13993. +    }
  13994. +    return rc;
  13995. +}
  13996. +
  13997. +static int raid1_run (int minor, struct md_dev *mddev)
  13998. +{
  13999. +    struct raid1_data *raid_conf;
  14000. +    int i, j, raid_disk;
  14001. +    md_superblock_t *sb = mddev->sb;
  14002. +    md_descriptor_t *descriptor;
  14003. +    struct real_dev *realdev;
  14004. +
  14005. +    MOD_INC_USE_COUNT;
  14006. +
  14007. +    if (sb->level != 1) {
  14008. +        printk("raid1: %s: raid level not set to mirroring (%d)\n", kdevname(MKDEV(MD_MAJOR, minor)), sb->level);
  14009. +        MOD_DEC_USE_COUNT;
  14010. +        return -EIO;
  14011. +    }
  14012. +    /****
  14013. +     * copy the now verified devices into our private RAID1 bookkeeping area:
  14014. +     *
  14015. +     * [whatever we allocate in raid1_run(), should be freed in raid1_stop()]
  14016. +     */
  14017. +
  14018. +    while (!( /* FIXME: now we are rather fault tolerant than nice */
  14019. +    mddev->private = kmalloc (sizeof (struct raid1_data), GFP_KERNEL)
  14020. +    ) )
  14021. +        printk ("raid1_run(): out of memory\n");
  14022. +    raid_conf = mddev->private;
  14023. +    memset(raid_conf, 0, sizeof(*raid_conf));
  14024. +
  14025. +    PRINTK(("raid1_run(%d) called.\n", minor));
  14026. +
  14027. +      for (i = 0; i < mddev->nb_dev; i++) {
  14028. +          realdev = &mddev->devices[i];
  14029. +        if (!realdev->sb) {
  14030. +            printk(KERN_ERR "raid1: disabled mirror %s (couldn't access raid superblock)\n", kdevname(realdev->dev));
  14031. +            continue;
  14032. +        }
  14033. +
  14034. +        /*
  14035. +         * This is important -- we are using the descriptor on
  14036. +         * the disk only to get a pointer to the descriptor on
  14037. +         * the main superblock, which might be more recent.
  14038. +         */
  14039. +        descriptor = &sb->disks[realdev->sb->descriptor.number];
  14040. +        if (descriptor->state & (1 << MD_FAULTY_DEVICE)) {
  14041. +            printk(KERN_ERR "raid1: disabled mirror %s (errors detected)\n", kdevname(realdev->dev));
  14042. +            continue;
  14043. +        }
  14044. +        if (descriptor->state & (1 << MD_ACTIVE_DEVICE)) {
  14045. +            if (!(descriptor->state & (1 << MD_SYNC_DEVICE))) {
  14046. +                printk(KERN_ERR "raid1: disabled mirror %s (not in sync)\n", kdevname(realdev->dev));
  14047. +                continue;
  14048. +            }
  14049. +            raid_disk = descriptor->raid_disk;
  14050. +            if (descriptor->number > sb->nr_disks || raid_disk > sb->raid_disks) {
  14051. +                printk(KERN_ERR "raid1: disabled mirror %s (inconsistent descriptor)\n", kdevname(realdev->dev));
  14052. +                continue;
  14053. +            }
  14054. +            if (raid_conf->mirrors[raid_disk].operational) {
  14055. +                printk(KERN_ERR "raid1: disabled mirror %s (mirror %d already operational)\n", kdevname(realdev->dev), raid_disk);
  14056. +                continue;
  14057. +            }
  14058. +            printk(KERN_INFO "raid1: device %s operational as mirror %d\n", kdevname(realdev->dev), raid_disk);
  14059. +            raid_conf->mirrors[raid_disk].number = descriptor->number;
  14060. +            raid_conf->mirrors[raid_disk].raid_disk = raid_disk;
  14061. +            raid_conf->mirrors[raid_disk].dev = mddev->devices [i].dev;
  14062. +            raid_conf->mirrors[raid_disk].operational = 1;
  14063. +            raid_conf->mirrors[raid_disk].sect_limit = 128;
  14064. +            raid_conf->working_disks++;
  14065. +        }
  14066. +    }
  14067. +    if (!raid_conf->working_disks) {
  14068. +        printk(KERN_ERR "raid1: no operational mirrors for %s\n", kdevname(MKDEV(MD_MAJOR, minor)));
  14069. +        kfree(raid_conf);
  14070. +        mddev->private = NULL;
  14071. +        MOD_DEC_USE_COUNT;
  14072. +        return -EIO;
  14073. +    }
  14074. +
  14075. +    raid_conf->raid_disks = sb->raid_disks;
  14076. +    raid_conf->mddev = mddev;
  14077. +
  14078. +    for (j = 0; !raid_conf->mirrors[j].operational; j++);
  14079. +    raid_conf->last_used = j;
  14080. +    for (i = raid_conf->raid_disks - 1; i >= 0; i--) {
  14081. +        if (raid_conf->mirrors[i].operational) {
  14082. +            PRINTK(("raid_conf->mirrors[%d].next == %d\n", i, j));
  14083. +            raid_conf->mirrors[i].next = j;
  14084. +            j = i;
  14085. +        }
  14086. +    }
  14087. +
  14088. +    if (check_consistenty(mddev)) {
  14089. +        printk(KERN_ERR "raid1: detected mirror differences -- run ckraid\n");
  14090. +        sb->state |= 1 << MD_SB_ERRORS;
  14091. +        kfree(raid_conf);
  14092. +        mddev->private = NULL;
  14093. +        MOD_DEC_USE_COUNT;
  14094. +        return -EIO;
  14095. +    }
  14096. +
  14097. +    /*
  14098. +     * Regenerate the "device is in sync with the raid set" bit for
  14099. +     * each device.
  14100. +     */
  14101. +    for (i = 0; i < sb->nr_disks ; i++) {
  14102. +        sb->disks[i].state &= ~(1 << MD_SYNC_DEVICE);
  14103. +        for (j = 0; j < sb->raid_disks; j++) {
  14104. +            if (!raid_conf->mirrors[j].operational)
  14105. +                continue;
  14106. +            if (sb->disks[i].number == raid_conf->mirrors[j].number)
  14107. +                sb->disks[i].state |= 1 << MD_SYNC_DEVICE;
  14108. +        }
  14109. +    }
  14110. +    sb->active_disks = raid_conf->working_disks;
  14111. +
  14112. +    printk("raid1: raid set %s active with %d out of %d mirrors\n", kdevname(MKDEV(MD_MAJOR, minor)), sb->active_disks, sb->raid_disks);
  14113. +    /* Ok, everything is just fine now */
  14114. +    return (0);
  14115. +}
  14116. +
  14117. +static int raid1_stop (int minor, struct md_dev *mddev)
  14118. +{
  14119. +    struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
  14120. +
  14121. +    kfree (raid_conf);
  14122. +    mddev->private = NULL;
  14123. +    MOD_DEC_USE_COUNT;
  14124. +    return 0;
  14125. +}
  14126. +
  14127. +static struct md_personality raid1_personality=
  14128. +{
  14129. +    "raid1",
  14130. +    raid1_map,
  14131. +    raid1_make_request,
  14132. +    raid1_end_request,
  14133. +    raid1_run,
  14134. +    raid1_stop,
  14135. +    raid1_status,
  14136. +    NULL,            /* no ioctls */
  14137. +    0,
  14138. +    raid1_error
  14139. +};
  14140. +
  14141. +int raid1_init (void)
  14142. +{
  14143. +    if ((raid1_thread = md_register_thread(raid1d, NULL)) == NULL)
  14144. +        return -EBUSY;
  14145. +    return register_md_personality (RAID1, &raid1_personality);
  14146. +}
  14147. +
  14148. +#ifdef MODULE
  14149. +int init_module (void)
  14150. +{
  14151. +    return raid1_init();
  14152. +}
  14153. +
  14154. +void cleanup_module (void)
  14155. +{
  14156. +    md_unregister_thread (raid1_thread);
  14157. +    unregister_md_personality (RAID1);
  14158. +}
  14159. +#endif
  14160. diff -u --recursive --new-file v2.0.34/linux/drivers/block/raid5.c linux/drivers/block/raid5.c
  14161. --- v2.0.34/linux/drivers/block/raid5.c    Wed Dec 31 16:00:00 1969
  14162. +++ linux/drivers/block/raid5.c    Mon Jul 13 13:47:28 1998
  14163. @@ -0,0 +1,1504 @@
  14164. +/*****************************************************************************
  14165. + * raid5.c : Multiple Devices driver for Linux
  14166. + *           Copyright (C) 1996, 1997 Ingo Molnar, Miguel de Icaza, Gadi Oxman
  14167. + *
  14168. + * RAID-5 management functions.
  14169. + *
  14170. + * This program is free software; you can redistribute it and/or modify
  14171. + * it under the terms of the GNU General Public License as published by
  14172. + * the Free Software Foundation; either version 2, or (at your option)
  14173. + * any later version.
  14174. + *
  14175. + * You should have received a copy of the GNU General Public License
  14176. + * (for example /usr/src/linux/COPYING); if not, write to the Free
  14177. + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14178. + */
  14179. +
  14180. +#include <linux/module.h>
  14181. +#include <linux/locks.h>
  14182. +#include <linux/malloc.h>
  14183. +#include <linux/md.h>
  14184. +#include <linux/raid5.h>
  14185. +#include <asm/bitops.h>
  14186. +#include <asm/atomic.h>
  14187. +
  14188. +struct buffer_head *efind_buffer(kdev_t dev, int block, int size);
  14189. +
  14190. +#define MAJOR_NR MD_MAJOR
  14191. +#define MD_DRIVER
  14192. +#define MD_PERSONALITY
  14193. +
  14194. +static struct md_personality raid5_personality;
  14195. +
  14196. +struct stripe_head {
  14197. +    struct stripe_head    *hash_next, **hash_pprev; /* hash pointers */
  14198. +    struct stripe_head    *handle_next;        /* completed during hash scan pointers */
  14199. +    struct raid5_data    *raid_conf;
  14200. +    struct buffer_head    *bh_old[MD_SB_DISKS];    /* disk image */
  14201. +    struct buffer_head    *bh_new[MD_SB_DISKS];    /* buffers of the MD device (present in buffer cache) */
  14202. +    struct buffer_head    *bh_copy[MD_SB_DISKS];    /* copy on write of bh_new (bh_new can change from under us) */
  14203. +    int            cmd_new[MD_SB_DISKS];    /* READ/WRITE for new */
  14204. +    int            new[MD_SB_DISKS];    /* buffer added since the last handle_stripe() */
  14205. +    unsigned long        sector;            /* sector of this row */
  14206. +    int            size;            /* buffers size */
  14207. +    int            pd_idx;            /* parity disk index */
  14208. +    int            nr_pending;        /* nr of pending cmds */
  14209. +    __u32            state;            /* state flags */
  14210. +    int            cmd;            /* stripe cmd */
  14211. +    int            count;            /* nr of waiters */
  14212. +    int            write_method;        /* reconstruct-write / read-modify-write */
  14213. +    int            phase;            /* PHASE_BEGIN, ..., PHASE_COMPLETE */
  14214. +    struct wait_queue    *wait;            /* processes waiting for this stripe */
  14215. +};
  14216. +
  14217. +/*
  14218. + * Phase
  14219. + */
  14220. +#define PHASE_BEGIN        0
  14221. +#define PHASE_READ_OLD        1
  14222. +#define PHASE_WRITE        2
  14223. +#define PHASE_READ        3
  14224. +#define PHASE_COMPLETE        4
  14225. +
  14226. +/*
  14227. + * Write method
  14228. + */
  14229. +#define METHOD_NONE        0
  14230. +#define RECONSTRUCT_WRITE    1
  14231. +#define READ_MODIFY_WRITE    2
  14232. +
  14233. +/*
  14234. + * Stripe state
  14235. + */
  14236. +#define STRIPE_LOCKED        0
  14237. +#define STRIPE_ERROR        1
  14238. +
  14239. +/*
  14240. + * Stripe commands
  14241. + */
  14242. +#define STRIPE_NONE        0
  14243. +#define    STRIPE_WRITE        1
  14244. +#define STRIPE_READ        2
  14245. +
  14246. +/*
  14247. + * Stripe cache
  14248. + */
  14249. +#define RAID5_STRIPE_POOL_SIZE    128
  14250. +#define HASH_PAGES        1
  14251. +#define HASH_PAGES_ORDER    0
  14252. +#define NR_HASH            (HASH_PAGES * PAGE_SIZE / sizeof(struct stripe_head *))
  14253. +#define HASH_MASK        (NR_HASH - 1)
  14254. +#define stripe_hash(sect, size)    (stripe_hashtbl[((sect) / (size >> 9)) & HASH_MASK])
  14255. +
  14256. +int nr_stripes = 0, nr_locked_stripes = 0, nr_pending_stripes = 0;
  14257. +struct stripe_head **stripe_hashtbl;
  14258. +static struct wait_queue *raid5_wait_for_stripe = NULL;
  14259. +struct stripe_head *stripe_handle_list = NULL, *stripe_handle_tail = NULL;
  14260. +
  14261. +/*
  14262. + * Free buffers pool
  14263. + */  
  14264. +#define RAID5_POOL_SIZE    3000
  14265. +static int nr_free_buffers = 0, nr_used_buffers = 0, max_nr_used_buffers = 0;
  14266. +static struct buffer_head *raid5_buffer_list = NULL;
  14267. +static struct wait_queue *raid5_wait_for_bh = NULL;
  14268. +
  14269. +/*
  14270. + * The following can be used to debug the driver
  14271. + */
  14272. +#define RAID5_DEBUG    0
  14273. +
  14274. +#if RAID5_DEBUG
  14275. +#define PRINTK(x)   do { printk x; } while (0);
  14276. +static int nr_pending = 0, free_1024 = 0, free_4096 = 0, used_1024 = 0, used_4096 = 0;
  14277. +#else
  14278. +#define PRINTK(x)   do { ; } while (0)
  14279. +#endif
  14280. +
  14281. +static inline int stripe_locked(struct stripe_head *sh)
  14282. +{
  14283. +    return test_bit(STRIPE_LOCKED, &sh->state);
  14284. +}
  14285. +
  14286. +static inline int stripe_error(struct stripe_head *sh)
  14287. +{
  14288. +    return test_bit(STRIPE_ERROR, &sh->state);
  14289. +}
  14290. +
  14291. +/*
  14292. + * Stripes are locked whenever new buffers can't be added to them.
  14293. + */
  14294. +static inline void lock_stripe(struct stripe_head *sh)
  14295. +{
  14296. +    if (!set_bit(STRIPE_LOCKED, &sh->state)) {
  14297. +        PRINTK(("locking stripe %lu\n", sh->sector));
  14298. +        nr_locked_stripes++;
  14299. +    }
  14300. +}
  14301. +
  14302. +static inline void unlock_stripe(struct stripe_head *sh)
  14303. +{
  14304. +    if (clear_bit(STRIPE_LOCKED, &sh->state)) {
  14305. +        PRINTK(("unlocking stripe %lu\n", sh->sector));
  14306. +        nr_locked_stripes--;
  14307. +        wake_up(&sh->wait);
  14308. +    }
  14309. +}
  14310. +
  14311. +static inline void finish_stripe(struct stripe_head *sh)
  14312. +{
  14313. +    unlock_stripe(sh);
  14314. +    sh->cmd = STRIPE_NONE;
  14315. +    sh->phase = PHASE_COMPLETE;
  14316. +    nr_pending_stripes--;
  14317. +    wake_up(&raid5_wait_for_stripe);
  14318. +}
  14319. +
  14320. +static void unplug_devices(struct stripe_head *sh)
  14321. +{
  14322. +    struct raid5_data *raid_conf = sh->raid_conf;
  14323. +    int i;
  14324. +
  14325. +    for (i = 0; i < raid_conf->raid_disks; i++)
  14326. +        unplug_device(blk_dev + MAJOR(raid_conf->disks[i].dev));
  14327. +}
  14328. +
  14329. +static void raid5d (void *data);
  14330. +
  14331. +void __wait_on_stripe(struct stripe_head *sh)
  14332. +{
  14333. +    struct wait_queue wait = { current, NULL };
  14334. +
  14335. +    PRINTK(("wait_on_stripe %lu\n", sh->sector));
  14336. +    sh->count++;
  14337. +    add_wait_queue(&sh->wait, &wait);
  14338. +repeat:
  14339. +    current->state = TASK_UNINTERRUPTIBLE;
  14340. +    if (stripe_locked(sh)) {
  14341. +        schedule();
  14342. +        goto repeat;
  14343. +    }
  14344. +    PRINTK(("wait_on_stripe %lu done\n", sh->sector));
  14345. +    remove_wait_queue(&sh->wait, &wait);
  14346. +    sh->count--;
  14347. +    current->state = TASK_RUNNING;
  14348. +}
  14349. +
  14350. +static inline void wait_on_stripe(struct stripe_head *sh)
  14351. +{
  14352. +    if (stripe_locked(sh))
  14353. +        __wait_on_stripe(sh);
  14354. +}
  14355. +
  14356. +static inline void remove_hash(struct stripe_head *sh)
  14357. +{
  14358. +    PRINTK(("remove_hash(), stripe %lu\n", sh->sector));
  14359. +
  14360. +    if (sh->hash_pprev) {
  14361. +        if (sh->hash_next)
  14362. +            sh->hash_next->hash_pprev = sh->hash_pprev;
  14363. +        *sh->hash_pprev = sh->hash_next;
  14364. +        sh->hash_pprev = NULL;
  14365. +        nr_stripes--;
  14366. +    }
  14367. +}
  14368. +
  14369. +static inline void insert_hash(struct stripe_head *sh)
  14370. +{
  14371. +    struct stripe_head **shp = &stripe_hash(sh->sector, sh->size);
  14372. +
  14373. +    PRINTK(("insert_hash(), stripe %lu, nr_stripes %d\n", sh->sector, nr_stripes));
  14374. +
  14375. +    if ((sh->hash_next = *shp) != NULL)
  14376. +        (*shp)->hash_pprev = &sh->hash_next;
  14377. +    *shp = sh;
  14378. +    sh->hash_pprev = shp;
  14379. +    nr_stripes++;
  14380. +}
  14381. +
  14382. +static void add_bh (struct buffer_head *bh)
  14383. +{
  14384. +    unsigned long flags;
  14385. +
  14386. +    save_flags(flags);
  14387. +    cli();
  14388. +    bh->b_next = raid5_buffer_list;
  14389. +    raid5_buffer_list = bh;
  14390. +    nr_free_buffers++;
  14391. +#if RAID5_DEBUG
  14392. +    if (bh->b_size == 1024)
  14393. +        free_1024++;
  14394. +    if (bh->b_size == 4096)
  14395. +        free_4096++;
  14396. +#endif
  14397. +    restore_flags(flags);
  14398. +}
  14399. +
  14400. +static void raid5_kfree_bh (struct buffer_head *bh)
  14401. +{
  14402. +    unsigned long flags;
  14403. +
  14404. +    save_flags(flags);
  14405. +    cli();
  14406. +    nr_used_buffers--;
  14407. +#if RAID5_DEBUG
  14408. +    if (bh->b_size == 1024)
  14409. +        used_1024--;
  14410. +    if (bh->b_size == 4096)
  14411. +        used_4096--;
  14412. +#endif
  14413. +    if (nr_free_buffers < RAID5_POOL_SIZE) {
  14414. +#if 0 /* This can magically catch races :-) */
  14415. +        char *b_data = ((volatile struct buffer_head *) bh)->b_data;
  14416. +        int b_size = ((volatile struct buffer_head *) bh)->b_size;
  14417. +        memset (bh, 0, sizeof (struct buffer_head));
  14418. +        ((volatile struct buffer_head *) bh)->b_data = b_data;
  14419. +        ((volatile struct buffer_head *) bh)->b_size = b_size;
  14420. +#endif
  14421. +        add_bh (bh);
  14422. +        wake_up (&raid5_wait_for_bh);
  14423. +    } else {
  14424. +        if (bh->b_size == PAGE_SIZE)
  14425. +            free_page ((unsigned long) bh->b_data);
  14426. +        else
  14427. +            kfree (bh->b_data);
  14428. +#if 0
  14429. +        memset (bh, 0, sizeof (struct buffer_head));
  14430. +#endif
  14431. +        kfree (bh);
  14432. +    }
  14433. +#if RAID5_DEBUG
  14434. +    printk ("kfree_bh: nr_free == %d, nr_used == %d, max_nr_used == %d\n", nr_free_buffers, nr_used_buffers, max_nr_used_buffers);
  14435. +#endif
  14436. +    restore_flags(flags);
  14437. +}
  14438. +
  14439. +static void raid5_kfree_old_bh(struct stripe_head *sh, int i)
  14440. +{
  14441. +    if (!sh->bh_old[i]) {
  14442. +        printk("raid5_kfree_old_bh: bug: sector %lu, index %d not present\n", sh->sector, i);
  14443. +        return;
  14444. +    }
  14445. +    raid5_kfree_bh(sh->bh_old[i]);
  14446. +    sh->bh_old[i] = NULL;
  14447. +}
  14448. +
  14449. +static void raid5_update_old_bh(struct stripe_head *sh, int i)
  14450. +{
  14451. +    PRINTK(("stripe %lu, idx %d, updating cache copy\n", sh->sector, i));
  14452. +    if (!sh->bh_copy[i]) {
  14453. +        printk("raid5_update_old_bh: bug: sector %lu, index %d not present\n", sh->sector, i);
  14454. +        return;
  14455. +    }
  14456. +    if (sh->bh_old[i])
  14457. +        raid5_kfree_old_bh(sh, i);
  14458. +    sh->bh_old[i] = sh->bh_copy[i];
  14459. +    sh->bh_copy[i] = NULL;
  14460. +}
  14461. +
  14462. +static void kfree_stripe(struct stripe_head *sh)
  14463. +{
  14464. +    struct raid5_data *raid_conf = sh->raid_conf;
  14465. +    int disks = raid_conf->raid_disks, j;
  14466. +
  14467. +    PRINTK(("kfree_stripe called, stripe %lu\n", sh->sector));
  14468. +    if (sh->phase != PHASE_COMPLETE || stripe_locked(sh) || sh->count) {
  14469. +        printk("raid5: kfree_stripe(), sector %lu, phase %d, locked %d, count %d\n", sh->sector, sh->phase, stripe_locked(sh), sh->count);
  14470. +        return;
  14471. +    }
  14472. +    for (j = 0; j < disks; j++) {
  14473. +        if (sh->bh_old[j])
  14474. +            raid5_kfree_old_bh(sh, j);
  14475. +        if (sh->bh_new[j] || sh->bh_copy[j])
  14476. +            printk("raid5: bug: sector %lu, new %p, copy %p\n", sh->sector, sh->bh_new[j], sh->bh_copy[j]);
  14477. +    }
  14478. +    remove_hash(sh);
  14479. +    kfree(sh);
  14480. +}
  14481. +
  14482. +static int shrink_stripe_cache(int nr)
  14483. +{
  14484. +    struct stripe_head *sh;
  14485. +    int i, count = 0;
  14486. +    static int clock = 0;
  14487. +
  14488. +    PRINTK(("shrink_stripe_cache called, %d/%d, clock %d\n", nr, nr_stripes, clock));
  14489. +    for (i = 0; i < NR_HASH; i++) {
  14490. +repeat:
  14491. +        sh = stripe_hashtbl[(i + clock) & HASH_MASK];
  14492. +        for (; sh; sh = sh->hash_next) {
  14493. +            if (sh->phase != PHASE_COMPLETE)
  14494. +                continue;
  14495. +            if (stripe_locked(sh))
  14496. +                continue;
  14497. +            if (sh->count)
  14498. +                continue;
  14499. +            kfree_stripe(sh);
  14500. +            if (++count == nr) {
  14501. +                PRINTK(("shrink completed, nr_stripes %d\n", nr_stripes));
  14502. +                clock = (i + clock) & HASH_MASK;
  14503. +                return nr;
  14504. +            }
  14505. +            goto repeat;
  14506. +        }
  14507. +    }
  14508. +    PRINTK(("shrink completed, nr_stripes %d\n", nr_stripes));
  14509. +    return count;
  14510. +}
  14511. +
  14512. +static struct stripe_head *find_stripe(struct raid5_data *raid_conf, unsigned long sector, int size)
  14513. +{
  14514. +    struct stripe_head *sh;
  14515. +
  14516. +    if (raid_conf->buffer_size != size) {
  14517. +        PRINTK(("switching size, %d --> %d\n", raid_conf->buffer_size, size));
  14518. +        shrink_stripe_cache(RAID5_STRIPE_POOL_SIZE);
  14519. +        raid_conf->buffer_size = size;
  14520. +    }
  14521. +
  14522. +    PRINTK(("find_stripe, sector %lu\n", sector));
  14523. +    for (sh = stripe_hash(sector, size); sh; sh = sh->hash_next)
  14524. +        if (sh->sector == sector && sh->raid_conf == raid_conf) {
  14525. +            if (sh->size == size) {
  14526. +                PRINTK(("found stripe %lu\n", sector));
  14527. +                return sh;
  14528. +            } else {
  14529. +                PRINTK(("switching size for %lu, %d --> %d\n", sector, sh->size, size));
  14530. +                kfree_stripe(sh);
  14531. +                break;
  14532. +            }
  14533. +        }
  14534. +    PRINTK(("stripe %lu not in cache\n", sector));
  14535. +    return NULL;
  14536. +}
  14537. +
  14538. +static struct stripe_head *kmalloc_stripe(struct raid5_data *raid_conf, unsigned long sector, int size)
  14539. +{
  14540. +    struct stripe_head *sh = NULL, *tmp;
  14541. +
  14542. +    PRINTK(("kmalloc_stripe called\n"));
  14543. +
  14544. +    while (nr_stripes > RAID5_STRIPE_POOL_SIZE) {
  14545. +        shrink_stripe_cache(RAID5_STRIPE_POOL_SIZE / 8);
  14546. +        if (nr_stripes <= RAID5_STRIPE_POOL_SIZE)
  14547. +            break;
  14548. +        md_wakeup_thread(raid_conf->thread);
  14549. +        PRINTK(("waiting for some stripes to complete\n"));
  14550. +        sleep_on(&raid5_wait_for_stripe);
  14551. +    }
  14552. +    md_wakeup_thread(raid_conf->thread);
  14553. +    sh = kmalloc(sizeof(*sh), GFP_KERNEL);
  14554. +
  14555. +    /*
  14556. +     * The above might have slept, so perhaps another process
  14557. +     * already created the stripe for us..
  14558. +     */
  14559. +    if ((tmp = find_stripe(raid_conf, sector, size)) != NULL) { 
  14560. +        kfree(sh);
  14561. +        wait_on_stripe(tmp);
  14562. +        return tmp;
  14563. +    }
  14564. +    if (sh) {
  14565. +        memset(sh, 0, sizeof(*sh));
  14566. +        sh->phase = PHASE_COMPLETE;
  14567. +        sh->cmd = STRIPE_NONE;
  14568. +        sh->raid_conf = raid_conf;
  14569. +        sh->sector = sector;
  14570. +        sh->size = size;
  14571. +        insert_hash(sh);
  14572. +    }
  14573. +    return sh;
  14574. +}
  14575. +
  14576. +static struct stripe_head *get_stripe(struct raid5_data *raid_conf, unsigned long sector, int size)
  14577. +{
  14578. +    struct stripe_head *sh;
  14579. +
  14580. +    PRINTK(("get_stripe, sector %lu\n", sector));
  14581. +    sh = find_stripe(raid_conf, sector, size);
  14582. +    if (sh)
  14583. +        wait_on_stripe(sh);
  14584. +    else
  14585. +        sh = kmalloc_stripe(raid_conf, sector, size);
  14586. +    return sh;
  14587. +}
  14588. +
  14589. +static struct buffer_head *remove_bh (int b_size)
  14590. +{
  14591. +    struct buffer_head *bh, *bhp = NULL;
  14592. +    unsigned long flags;
  14593. +
  14594. +    save_flags(flags);
  14595. +    cli();
  14596. +    if ((bh = raid5_buffer_list) == NULL)
  14597. +        return NULL;
  14598. +    do {
  14599. +        if (bh->b_size == b_size || b_size == -1)
  14600. +            break;
  14601. +        bhp = bh;
  14602. +        bh = bh->b_next;
  14603. +    } while (bh);
  14604. +    if (!bh)
  14605. +        return NULL;
  14606. +    if (bhp)
  14607. +        bhp->b_next = bh->b_next;
  14608. +    else
  14609. +        raid5_buffer_list = bh->b_next;
  14610. +#if RAID5_DEBUG
  14611. +    if (bh->b_size == 1024)
  14612. +        free_1024--;
  14613. +    if (bh->b_size == 4096)
  14614. +        free_4096--;
  14615. +#endif
  14616. +    nr_free_buffers--;
  14617. +    if (!nr_free_buffers && raid5_buffer_list)
  14618. +        printk ("raid5: bug: buffer_list != NULL, nr_free_buffers == 0\n");
  14619. +    restore_flags(flags);
  14620. +    return bh;
  14621. +}
  14622. +
  14623. +
  14624. +static void shrink_buffers (int num)
  14625. +{
  14626. +    struct buffer_head *bh;
  14627. +
  14628. +    while (num--) {
  14629. +        if ((bh = remove_bh(-1)) == NULL)
  14630. +            return;
  14631. +        if (bh->b_size == PAGE_SIZE)
  14632. +            free_page ((unsigned long) bh->b_data);
  14633. +        else
  14634. +            kfree (bh->b_data);
  14635. +        kfree (bh);
  14636. +    }
  14637. +}
  14638. +
  14639. +static void grow_buffers (int num, int b_size, int priority)
  14640. +{
  14641. +    struct buffer_head *bh;
  14642. +
  14643. +    while (num--) {
  14644. +        bh = kmalloc (sizeof (struct buffer_head), priority);
  14645. +        if (!bh)
  14646. +            break;
  14647. +        memset (bh, 0, sizeof (struct buffer_head));
  14648. +        if (b_size == PAGE_SIZE)
  14649. +            bh->b_data = (char *) __get_free_page (priority);
  14650. +        else
  14651. +            bh->b_data = kmalloc (b_size, priority);
  14652. +        if (!bh->b_data) {
  14653. +            kfree (bh);
  14654. +            break;
  14655. +        }
  14656. +        bh->b_size = b_size;
  14657. +        add_bh (bh);
  14658. +    }
  14659. +}
  14660. +
  14661. +static struct buffer_head *raid5_kmalloc_bh (struct stripe_head *sh, int b_size)
  14662. +{
  14663. +    struct buffer_head *bh;
  14664. +    struct raid5_data *raid_conf = sh->raid_conf;
  14665. +    unsigned long flags;
  14666. +
  14667. +    bh = remove_bh(b_size);
  14668. +    if (!bh && nr_free_buffers > RAID5_POOL_SIZE / 10)
  14669. +        shrink_buffers (RAID5_POOL_SIZE / 10);
  14670. +    if (!bh && nr_used_buffers < RAID5_POOL_SIZE) {
  14671. +#if 0
  14672. +        grow_buffers (200, b_size, GFP_BUFFER);
  14673. +#else
  14674. +        grow_buffers (200, b_size, GFP_KERNEL);
  14675. +#endif
  14676. +        bh = remove_bh(b_size);
  14677. +    }
  14678. +    if (bh == NULL && nr_used_buffers > RAID5_POOL_SIZE / 2) {
  14679. +        shrink_stripe_cache(RAID5_STRIPE_POOL_SIZE / 2);
  14680. +        bh = remove_bh(b_size);
  14681. +    }
  14682. +
  14683. +    while (bh == NULL && nr_used_buffers > 3 * RAID5_POOL_SIZE / 4) {
  14684. +        md_wakeup_thread(raid_conf->thread);
  14685. +        run_task_queue (&tq_disk);
  14686. +        unplug_devices(sh);
  14687. +        PRINTK(("waiting for bh\n"));
  14688. +        sleep_on (&raid5_wait_for_bh);
  14689. +        bh = remove_bh(b_size);
  14690. +    }
  14691. +    if (bh == NULL) {
  14692. +        grow_buffers (200, b_size, GFP_KERNEL);
  14693. +        bh = remove_bh(b_size);
  14694. +    }
  14695. +    if (bh) {
  14696. +        save_flags(flags);
  14697. +        cli();
  14698. +        nr_used_buffers++;
  14699. +        if (nr_used_buffers > max_nr_used_buffers)
  14700. +            max_nr_used_buffers = nr_used_buffers;
  14701. +#if RAID5_DEBUG
  14702. +        if (bh->b_size == 1024)
  14703. +            used_1024++;
  14704. +        if (bh->b_size == 4096)
  14705. +            used_4096++;
  14706. +        printk ("kmalloc_bh: free, used, pending, max = %d, %d, %d, %d\n", nr_free_buffers, nr_used_buffers, nr_pending, max_nr_used_buffers);
  14707. +        printk ("kmalloc_bh: free1, used1, free4, used4 = %d, %d, %d, %d\n", free_1024, used_1024, free_4096, used_4096);
  14708. +#endif
  14709. +        restore_flags(flags);
  14710. +    }
  14711. +    return bh;
  14712. +}
  14713. +
  14714. +static inline void raid5_end_buffer_io (struct stripe_head *sh, int i, int uptodate)
  14715. +{
  14716. +    struct buffer_head *bh = sh->bh_new[i];
  14717. +
  14718. +    sh->bh_new[i] = NULL;
  14719. +    clear_bit (BH_MD, &bh->b_state);
  14720. +    bh->private_bh = NULL;
  14721. +    bh->personality = NULL;
  14722. +    mark_buffer_uptodate(bh, uptodate);
  14723. +    unlock_buffer(bh);
  14724. +    if (!uptodate)
  14725. +        printk(KERN_ALERT "raid5: %s: unrecoverable I/O error for "
  14726. +               "block %lu\n", kdevname(bh->b_dev), bh->b_blocknr);
  14727. +}
  14728. +
  14729. +static inline void raid5_mark_buffer_uptodate (struct buffer_head *bh, int uptodate)
  14730. +{
  14731. +    if (uptodate)
  14732. +        set_bit(BH_Uptodate, &bh->b_state);
  14733. +    else
  14734. +        clear_bit(BH_Uptodate, &bh->b_state);
  14735. +}
  14736. +
  14737. +static void raid5_end_request (struct buffer_head * bh, int uptodate)
  14738. +{
  14739. +    struct stripe_head *sh = bh->private_bh;
  14740. +    struct raid5_data *raid_conf = sh->raid_conf;
  14741. +    int disks = raid_conf->raid_disks, i;
  14742. +    unsigned long flags;
  14743. +
  14744. +    PRINTK(("end_request %lu, nr_pending %d\n", sh->sector, sh->nr_pending));
  14745. +    save_flags(flags);
  14746. +    cli();
  14747. +    raid5_mark_buffer_uptodate(bh, uptodate);
  14748. +    --sh->nr_pending;
  14749. +    if (!sh->nr_pending) {
  14750. +        md_wakeup_thread(raid_conf->thread);
  14751. +        atomic_inc(&raid_conf->nr_handle);
  14752. +        if (!stripe_handle_tail)
  14753. +            stripe_handle_list = sh;
  14754. +        else
  14755. +            stripe_handle_tail->handle_next = sh;
  14756. +        sh->handle_next = NULL;
  14757. +        stripe_handle_tail = sh;
  14758. +    }
  14759. +    if (!uptodate)
  14760. +        md_error(bh->b_dev, bh->b_rdev);
  14761. +    if (raid_conf->failed_disks) {
  14762. +        for (i = 0; i < disks; i++) {
  14763. +            if (raid_conf->disks[i].operational)
  14764. +                continue;
  14765. +            if (bh != sh->bh_old[i] && bh != sh->bh_new[i] && bh != sh->bh_copy[i])
  14766. +                continue;
  14767. +            set_bit(STRIPE_ERROR, &sh->state);
  14768. +        }
  14769. +    }
  14770. +    restore_flags(flags);
  14771. +}
  14772. +
  14773. +static int raid5_map (struct md_dev *mddev, kdev_t *rdev,
  14774. +              unsigned long *rsector, unsigned long size)
  14775. +{
  14776. +    /* No complex mapping used: the core of the work is done in the
  14777. +     * request routine
  14778. +     */
  14779. +    return 0;
  14780. +}
  14781. +
  14782. +static void raid5_build_block (struct stripe_head *sh, struct buffer_head *bh, int i)
  14783. +{
  14784. +    struct raid5_data *raid_conf = sh->raid_conf;
  14785. +    struct md_dev *mddev = raid_conf->mddev;
  14786. +    int minor = (int) (mddev - md_dev);
  14787. +    char *b_data;
  14788. +
  14789. +    b_data = ((volatile struct buffer_head *) bh)->b_data;
  14790. +    memset (bh, 0, sizeof (struct buffer_head));
  14791. +    ((volatile struct buffer_head *) bh)->b_data = b_data;
  14792. +
  14793. +    bh->personality    = &raid5_personality;
  14794. +    bh->private_bh  = (void *) sh;
  14795. +
  14796. +    bh->b_rdev    = raid_conf->disks[i].dev;
  14797. +    bh->b_dev    = MKDEV(MD_MAJOR, minor);
  14798. +    bh->b_rsector   = sh->sector;
  14799. +    bh->b_blocknr   = sh->sector / (sh->size >> 9);
  14800. +
  14801. +    bh->b_state    = (1 << BH_MD) | (1 << BH_Req);
  14802. +    bh->b_count    = 1;
  14803. +    bh->b_size    = sh->size;
  14804. +    bh->b_list    = BUF_LOCKED;
  14805. +}
  14806. +
  14807. +static int raid5_error (struct md_dev *mddev, kdev_t dev)
  14808. +{
  14809. +    struct raid5_data *raid_conf = (struct raid5_data *) mddev->private;
  14810. +    md_superblock_t *sb = mddev->sb;
  14811. +    struct disk_info *disk;
  14812. +    int i;
  14813. +
  14814. +    PRINTK(("raid5_error called\n"));
  14815. +    for (i = 0, disk = raid_conf->disks; i < raid_conf->raid_disks; i++, disk++)
  14816. +        if (disk->dev == dev && disk->operational) {
  14817. +            disk->operational = 0;
  14818. +            sb->disks[disk->number].state |= (1 << MD_FAULTY_DEVICE);
  14819. +            sb->disks[disk->number].state &= ~(1 << MD_SYNC_DEVICE);
  14820. +            sb->disks[disk->number].state &= ~(1 << MD_ACTIVE_DEVICE);
  14821. +            sb->active_disks--;
  14822. +            sb->working_disks--;
  14823. +            sb->failed_disks++;
  14824. +            mddev->sb_dirty = 1;
  14825. +            raid_conf->working_disks--;
  14826. +            raid_conf->failed_disks++;
  14827. +            md_wakeup_thread(raid_conf->thread);
  14828. +            printk (KERN_ALERT
  14829. +                "RAID5: Disk failure on %s, disabling device."
  14830. +                "Operation continuing on %d devices\n",
  14831. +                kdevname (dev), raid_conf->working_disks);
  14832. +        }
  14833. +    return 0;
  14834. +}    
  14835. +
  14836. +/*
  14837. + * Input: a 'big' sector number, 
  14838. + * Output: index of the data and parity disk, and the sector # in them.
  14839. + */
  14840. +static inline unsigned long 
  14841. +raid5_compute_sector (int r_sector, unsigned int raid_disks, unsigned int data_disks,
  14842. +            unsigned int * dd_idx, unsigned int * pd_idx, 
  14843. +            struct raid5_data *raid_conf)
  14844. +{
  14845. +    unsigned int  stripe;
  14846. +    int chunk_number, chunk_offset;
  14847. +    unsigned long new_sector;
  14848. +    int sectors_per_chunk = raid_conf->chunk_size >> 9;
  14849. +
  14850. +    /* First compute the information on this sector */
  14851. +
  14852. +    /*
  14853. +     * Compute the chunk number and the sector offset inside the chunk
  14854. +     */
  14855. +    chunk_number = r_sector / sectors_per_chunk;
  14856. +    chunk_offset = r_sector % sectors_per_chunk;
  14857. +
  14858. +    /*
  14859. +     * Compute the stripe number
  14860. +     */
  14861. +    stripe = chunk_number / data_disks;
  14862. +
  14863. +    /*
  14864. +     * Compute the data disk and parity disk indexes inside the stripe
  14865. +     */
  14866. +    *dd_idx = chunk_number % data_disks;
  14867. +
  14868. +    /*
  14869. +     * Select the parity disk based on the user selected algorithm.
  14870. +     */
  14871. +    if (raid_conf->level == 4)
  14872. +        *pd_idx = data_disks;
  14873. +    else switch (raid_conf->algorithm) {
  14874. +        case ALGORITHM_LEFT_ASYMMETRIC:
  14875. +            *pd_idx = data_disks - stripe % raid_disks;
  14876. +            if (*dd_idx >= *pd_idx)
  14877. +                (*dd_idx)++;
  14878. +            break;
  14879. +        case ALGORITHM_RIGHT_ASYMMETRIC:
  14880. +            *pd_idx = stripe % raid_disks;
  14881. +            if (*dd_idx >= *pd_idx)
  14882. +                (*dd_idx)++;
  14883. +            break;
  14884. +        case ALGORITHM_LEFT_SYMMETRIC:
  14885. +            *pd_idx = data_disks - stripe % raid_disks;
  14886. +            *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
  14887. +            break;
  14888. +        case ALGORITHM_RIGHT_SYMMETRIC:
  14889. +            *pd_idx = stripe % raid_disks;
  14890. +            *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
  14891. +            break;
  14892. +        default:
  14893. +            printk ("raid5: unsupported algorithm %d\n", raid_conf->algorithm);
  14894. +    }
  14895. +
  14896. +    /*
  14897. +     * Finally, compute the new sector number
  14898. +     */
  14899. +    new_sector = stripe * sectors_per_chunk + chunk_offset;
  14900. +
  14901. +#if 0
  14902. +    if (    *dd_idx > data_disks || *pd_idx > data_disks || 
  14903. +        chunk_offset + bh->b_size / 512 > sectors_per_chunk    )
  14904. +
  14905. +        printk ("raid5: bug: dd_idx == %d, pd_idx == %d, chunk_offset == %d\n", 
  14906. +                *dd_idx, *pd_idx, chunk_offset);
  14907. +#endif
  14908. +
  14909. +    return new_sector;
  14910. +}
  14911. +
  14912. +static unsigned long compute_blocknr(struct stripe_head *sh, int i)
  14913. +{
  14914. +    struct raid5_data *raid_conf = sh->raid_conf;
  14915. +    int raid_disks = raid_conf->raid_disks, data_disks = raid_disks - 1;
  14916. +    unsigned long new_sector = sh->sector, check;
  14917. +    int sectors_per_chunk = raid_conf->chunk_size >> 9;
  14918. +    unsigned long stripe = new_sector / sectors_per_chunk;
  14919. +    int chunk_offset = new_sector % sectors_per_chunk;
  14920. +    int chunk_number, dummy1, dummy2, dd_idx = i;
  14921. +    unsigned long r_sector, blocknr;
  14922. +
  14923. +    switch (raid_conf->algorithm) {
  14924. +        case ALGORITHM_LEFT_ASYMMETRIC:
  14925. +        case ALGORITHM_RIGHT_ASYMMETRIC:
  14926. +            if (i > sh->pd_idx)
  14927. +                i--;
  14928. +            break;
  14929. +        case ALGORITHM_LEFT_SYMMETRIC:
  14930. +        case ALGORITHM_RIGHT_SYMMETRIC:
  14931. +            if (i < sh->pd_idx)
  14932. +                i += raid_disks;
  14933. +            i -= (sh->pd_idx + 1);
  14934. +            break;
  14935. +        default:
  14936. +            printk ("raid5: unsupported algorithm %d\n", raid_conf->algorithm);
  14937. +    }
  14938. +
  14939. +    chunk_number = stripe * data_disks + i;
  14940. +    r_sector = chunk_number * sectors_per_chunk + chunk_offset;
  14941. +    blocknr = r_sector / (sh->size >> 9);
  14942. +
  14943. +    check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, raid_conf);
  14944. +    if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
  14945. +        printk("compute_blocknr: map not correct\n");
  14946. +        return 0;
  14947. +    }
  14948. +    return blocknr;
  14949. +}
  14950. +
  14951. +static void xor_block(struct buffer_head *dest, struct buffer_head *source)
  14952. +{
  14953. +    int lines = dest->b_size / (sizeof (int)) / 8, i;
  14954. +    int *destp = (int *) dest->b_data, *sourcep = (int *) source->b_data;
  14955. +
  14956. +    for (i = lines; i > 0; i--) {
  14957. +        *(destp + 0) ^= *(sourcep + 0);
  14958. +        *(destp + 1) ^= *(sourcep + 1);
  14959. +        *(destp + 2) ^= *(sourcep + 2);
  14960. +        *(destp + 3) ^= *(sourcep + 3);
  14961. +        *(destp + 4) ^= *(sourcep + 4);
  14962. +        *(destp + 5) ^= *(sourcep + 5);
  14963. +        *(destp + 6) ^= *(sourcep + 6);
  14964. +        *(destp + 7) ^= *(sourcep + 7);
  14965. +        destp += 8;
  14966. +        sourcep += 8;
  14967. +    }
  14968. +}
  14969. +
  14970. +static void compute_block(struct stripe_head *sh, int dd_idx)
  14971. +{
  14972. +    struct raid5_data *raid_conf = sh->raid_conf;
  14973. +    int i, disks = raid_conf->raid_disks;
  14974. +
  14975. +    PRINTK(("compute_block, stripe %lu, idx %d\n", sh->sector, dd_idx));
  14976. +
  14977. +    if (sh->bh_old[dd_idx] == NULL)
  14978. +        sh->bh_old[dd_idx] = raid5_kmalloc_bh(sh, sh->size);
  14979. +    raid5_build_block(sh, sh->bh_old[dd_idx], dd_idx);
  14980. +
  14981. +    memset(sh->bh_old[dd_idx]->b_data, 0, sh->size);
  14982. +    for (i = 0; i < disks; i++) {
  14983. +        if (i == dd_idx)
  14984. +            continue;
  14985. +        if (sh->bh_old[i]) {
  14986. +            xor_block(sh->bh_old[dd_idx], sh->bh_old[i]);
  14987. +            continue;
  14988. +        } else
  14989. +            printk("compute_block() %d, stripe %lu, %d not present\n", dd_idx, sh->sector, i);
  14990. +    }
  14991. +    raid5_mark_buffer_uptodate(sh->bh_old[dd_idx], 1);
  14992. +}
  14993. +
  14994. +static void compute_parity(struct stripe_head *sh, int method)
  14995. +{
  14996. +    struct raid5_data *raid_conf = sh->raid_conf;
  14997. +    int i, pd_idx = sh->pd_idx, disks = raid_conf->raid_disks;
  14998. +
  14999. +    PRINTK(("compute_parity, stripe %lu, method %d\n", sh->sector, method));
  15000. +    for (i = 0; i < disks; i++) {
  15001. +        if (i == pd_idx || !sh->bh_new[i])
  15002. +            continue;
  15003. +        if (!sh->bh_copy[i])
  15004. +            sh->bh_copy[i] = raid5_kmalloc_bh(sh, sh->size);
  15005. +        raid5_build_block(sh, sh->bh_copy[i], i);
  15006. +        mark_buffer_clean(sh->bh_new[i]);
  15007. +        memcpy(sh->bh_copy[i]->b_data, sh->bh_new[i]->b_data, sh->size);
  15008. +    }
  15009. +    if (sh->bh_copy[pd_idx] == NULL)
  15010. +        sh->bh_copy[pd_idx] = raid5_kmalloc_bh(sh, sh->size);
  15011. +    raid5_build_block(sh, sh->bh_copy[pd_idx], sh->pd_idx);
  15012. +
  15013. +    if (method == RECONSTRUCT_WRITE) {
  15014. +        memset(sh->bh_copy[pd_idx]->b_data, 0, sh->size);
  15015. +        for (i = 0; i < disks; i++) {
  15016. +            if (i == sh->pd_idx)
  15017. +                continue;
  15018. +            if (sh->bh_new[i]) {
  15019. +                xor_block(sh->bh_copy[pd_idx], sh->bh_copy[i]);
  15020. +                continue;
  15021. +            }
  15022. +            if (sh->bh_old[i]) {
  15023. +                xor_block(sh->bh_copy[pd_idx], sh->bh_old[i]);
  15024. +                continue;
  15025. +            }
  15026. +        }
  15027. +    } else if (method == READ_MODIFY_WRITE) {
  15028. +        memcpy(sh->bh_copy[pd_idx]->b_data, sh->bh_old[pd_idx]->b_data, sh->size);
  15029. +        for (i = 0; i < disks; i++) {
  15030. +            if (i == sh->pd_idx)
  15031. +                continue;
  15032. +            if (sh->bh_new[i] && sh->bh_old[i]) {
  15033. +                xor_block(sh->bh_copy[pd_idx], sh->bh_copy[i]);
  15034. +                xor_block(sh->bh_copy[pd_idx], sh->bh_old[i]);
  15035. +                continue;
  15036. +            }
  15037. +        }
  15038. +    }
  15039. +    raid5_mark_buffer_uptodate(sh->bh_copy[pd_idx], 1);
  15040. +}
  15041. +
  15042. +static void add_stripe_bh (struct stripe_head *sh, struct buffer_head *bh, int dd_idx, int rw)
  15043. +{
  15044. +    struct raid5_data *raid_conf = sh->raid_conf;
  15045. +
  15046. +    if (sh->bh_new[dd_idx])
  15047. +        printk("raid5: bug: stripe->bh_new[%d], sector %lu exists\n", dd_idx, sh->sector);
  15048. +
  15049. +    set_bit(BH_MD, &bh->b_state);
  15050. +    set_bit(BH_Lock, &bh->b_state);
  15051. +    bh->personality  = &raid5_personality;
  15052. +    bh->private_bh   = (void *) sh;
  15053. +    bh->b_rdev    = raid_conf->disks[dd_idx].dev;
  15054. +    bh->b_rsector = sh->sector;
  15055. +
  15056. +    if (sh->phase == PHASE_COMPLETE && sh->cmd == STRIPE_NONE) {
  15057. +        sh->phase = PHASE_BEGIN;
  15058. +        sh->cmd = (rw == READ) ? STRIPE_READ : STRIPE_WRITE;
  15059. +        nr_pending_stripes++;
  15060. +        atomic_inc(&raid_conf->nr_handle);
  15061. +    }
  15062. +    sh->bh_new[dd_idx] = bh;
  15063. +    sh->cmd_new[dd_idx] = rw;
  15064. +    sh->new[dd_idx] = 1;
  15065. +}
  15066. +
  15067. +static void complete_stripe(struct stripe_head *sh)
  15068. +{
  15069. +    struct raid5_data *raid_conf = sh->raid_conf;
  15070. +    int disks = raid_conf->raid_disks;
  15071. +    int i, new = 0;
  15072. +    
  15073. +    PRINTK(("complete_stripe %lu\n", sh->sector));
  15074. +    for (i = 0; i < disks; i++) {
  15075. +        if (sh->cmd == STRIPE_WRITE && i == sh->pd_idx)
  15076. +            raid5_update_old_bh(sh, i);
  15077. +        if (sh->bh_new[i]) {
  15078. +            if (!sh->new[i]) {
  15079. +#if 0
  15080. +                if (sh->cmd == STRIPE_WRITE) {
  15081. +                    if (memcmp(sh->bh_new[i]->b_data, sh->bh_copy[i]->b_data, sh->size)) {
  15082. +                        printk("copy differs, %s, sector %lu ",
  15083. +                            test_bit(BH_Dirty, &sh->bh_new[i]->b_state) ? "dirty" : "clean",
  15084. +                            sh->sector);
  15085. +                    } else if (test_bit(BH_Dirty, &sh->bh_new[i]->b_state))
  15086. +                        printk("sector %lu dirty\n", sh->sector);
  15087. +                }
  15088. +#endif
  15089. +                if (sh->cmd == STRIPE_WRITE)
  15090. +                    raid5_update_old_bh(sh, i);
  15091. +                raid5_end_buffer_io(sh, i, 1);
  15092. +                continue;
  15093. +            } else
  15094. +                new++;
  15095. +        }
  15096. +        if (new && sh->cmd == STRIPE_WRITE)
  15097. +            printk("raid5: bug, completed STRIPE_WRITE with new == %d\n", new);
  15098. +    }
  15099. +    if (!new)
  15100. +        finish_stripe(sh);
  15101. +    else {
  15102. +        PRINTK(("stripe %lu, new == %d\n", sh->sector, new));
  15103. +        sh->phase = PHASE_BEGIN;
  15104. +    }
  15105. +}
  15106. +
  15107. +/*
  15108. + * handle_stripe() is our main logic routine. Note that:
  15109. + *
  15110. + * 1.    lock_stripe() should be used whenever we can't accept additonal
  15111. + *    buffers, either during short sleeping in handle_stripe() or
  15112. + *    during io operations.
  15113. + *
  15114. + * 2.    We should be careful to set sh->nr_pending whenever we sleep,
  15115. + *    to prevent re-entry of handle_stripe() for the same sh.
  15116. + *
  15117. + * 3.    raid_conf->failed_disks and disk->operational can be changed
  15118. + *    from an interrupt. This complicates things a bit, but it allows
  15119. + *    us to stop issuing requests for a failed drive as soon as possible.
  15120. + */
  15121. +static void handle_stripe(struct stripe_head *sh)
  15122. +{
  15123. +    struct raid5_data *raid_conf = sh->raid_conf;
  15124. +    struct md_dev *mddev = raid_conf->mddev;
  15125. +    int minor = (int) (mddev - md_dev);
  15126. +    struct buffer_head *bh;
  15127. +    int disks = raid_conf->raid_disks;
  15128. +    int i, nr = 0, nr_read = 0, nr_write = 0;
  15129. +    int nr_cache = 0, nr_cache_other = 0, nr_cache_overwrite = 0, parity = 0;
  15130. +    int nr_failed_other = 0, nr_failed_overwrite = 0, parity_failed = 0;
  15131. +    int reading = 0, nr_writing = 0;
  15132. +    int method1 = INT_MAX, method2 = INT_MAX;
  15133. +    int block;
  15134. +    unsigned long flags;
  15135. +    int operational[MD_SB_DISKS], failed_disks = raid_conf->failed_disks;
  15136. +
  15137. +    PRINTK(("handle_stripe(), stripe %lu\n", sh->sector));
  15138. +    if (sh->nr_pending) {
  15139. +        printk("handle_stripe(), stripe %lu, io still pending\n", sh->sector);
  15140. +        return;
  15141. +    }
  15142. +    if (sh->phase == PHASE_COMPLETE) {
  15143. +        printk("handle_stripe(), stripe %lu, already complete\n", sh->sector);
  15144. +        return;
  15145. +    }
  15146. +
  15147. +    atomic_dec(&raid_conf->nr_handle);
  15148. +
  15149. +    if (clear_bit(STRIPE_ERROR, &sh->state)) {
  15150. +        printk("raid5: restarting stripe %lu\n", sh->sector);
  15151. +        sh->phase = PHASE_BEGIN;
  15152. +    }
  15153. +
  15154. +    if ((sh->cmd == STRIPE_WRITE && sh->phase == PHASE_WRITE) ||
  15155. +        (sh->cmd == STRIPE_READ && sh->phase == PHASE_READ)) {
  15156. +        /*
  15157. +         * Completed
  15158. +         */
  15159. +        complete_stripe(sh);
  15160. +        if (sh->phase == PHASE_COMPLETE)
  15161. +            return;
  15162. +    }
  15163. +
  15164. +    save_flags(flags);
  15165. +    cli();
  15166. +    for (i = 0; i < disks; i++)
  15167. +        operational[i] = raid_conf->disks[i].operational;
  15168. +    failed_disks = raid_conf->failed_disks;
  15169. +    restore_flags(flags);
  15170. +
  15171. +    if (failed_disks > 1) {
  15172. +        for (i = 0; i < disks; i++) {
  15173. +            if (sh->bh_new[i]) {
  15174. +                raid5_end_buffer_io(sh, i, 0);
  15175. +                continue;
  15176. +            }
  15177. +        }
  15178. +        finish_stripe(sh);
  15179. +        return;
  15180. +    }
  15181. +
  15182. +    for (i = 0; i < disks; i++) {
  15183. +        if (sh->bh_old[i])
  15184. +            nr_cache++;
  15185. +        if (i == sh->pd_idx) {
  15186. +            if (sh->bh_old[i])
  15187. +                parity = 1;
  15188. +            else if(!operational[i])
  15189. +                parity_failed = 1;
  15190. +            continue;
  15191. +        }
  15192. +        if (!sh->bh_new[i]) {
  15193. +            if (sh->bh_old[i])
  15194. +                nr_cache_other++;
  15195. +            else if (!operational[i])
  15196. +                nr_failed_other++;
  15197. +            continue;
  15198. +        }
  15199. +        sh->new[i] = 0;
  15200. +        nr++;
  15201. +        if (sh->cmd_new[i] == READ)
  15202. +            nr_read++;
  15203. +        if (sh->cmd_new[i] == WRITE)
  15204. +            nr_write++;
  15205. +        if (sh->bh_old[i])
  15206. +            nr_cache_overwrite++;
  15207. +        else if (!operational[i])
  15208. +            nr_failed_overwrite++;
  15209. +    }
  15210. +
  15211. +    if (nr_write && nr_read)
  15212. +        printk("raid5: bug, nr_write == %d, nr_read == %d, sh->cmd == %d\n", nr_write, nr_read, sh->cmd);
  15213. +
  15214. +    if (nr_write) {
  15215. +        /*
  15216. +         * Attempt to add entries :-)
  15217. +         */
  15218. +        if (nr_write != disks - 1) {
  15219. +            for (i = 0; i < disks; i++) {
  15220. +                if (i == sh->pd_idx)
  15221. +                    continue;
  15222. +                if (sh->bh_new[i])
  15223. +                    continue;
  15224. +                block = (int) compute_blocknr(sh, i);
  15225. +                bh = efind_buffer(MKDEV(MD_MAJOR, minor), block, sh->size);
  15226. +                if (bh && bh->b_count == 0 && buffer_dirty(bh) && !buffer_locked(bh)) {
  15227. +                    PRINTK(("Whee.. sector %lu, index %d (%d) found in the buffer cache!\n", sh->sector, i, block));
  15228. +                    add_stripe_bh(sh, bh, i, WRITE);
  15229. +                    sh->new[i] = 0;
  15230. +                    nr++; nr_write++;
  15231. +                    if (sh->bh_old[i]) {
  15232. +                        nr_cache_overwrite++;
  15233. +                        nr_cache_other--;
  15234. +                    } else if (!operational[i]) {
  15235. +                        nr_failed_overwrite++;
  15236. +                        nr_failed_other--;
  15237. +                    }
  15238. +                }
  15239. +            }
  15240. +        }
  15241. +        PRINTK(("handle_stripe() -- begin writing, stripe %lu\n", sh->sector));
  15242. +        /*
  15243. +         * Writing, need to update parity buffer.
  15244. +         *
  15245. +         * Compute the number of I/O requests in the "reconstruct
  15246. +         * write" and "read modify write" methods.
  15247. +         */
  15248. +        if (!nr_failed_other)
  15249. +            method1 = (disks - 1) - (nr_write + nr_cache_other);
  15250. +        if (!nr_failed_overwrite && !parity_failed)
  15251. +            method2 = nr_write - nr_cache_overwrite + (1 - parity);
  15252. +
  15253. +        if (method1 == INT_MAX && method2 == INT_MAX)
  15254. +            printk("raid5: bug: method1 == method2 == INT_MAX\n");
  15255. +        PRINTK(("handle_stripe(), sector %lu, nr_write %d, method1 %d, method2 %d\n", sh->sector, nr_write, method1, method2));
  15256. +
  15257. +        if (!method1 || !method2) {
  15258. +            lock_stripe(sh);
  15259. +            sh->nr_pending++;
  15260. +            sh->phase = PHASE_WRITE;
  15261. +            compute_parity(sh, method1 <= method2 ? RECONSTRUCT_WRITE : READ_MODIFY_WRITE);
  15262. +            for (i = 0; i < disks; i++) {
  15263. +                if (!operational[i])
  15264. +                    continue;
  15265. +                if (i == sh->pd_idx || sh->bh_new[i])
  15266. +                    nr_writing++;
  15267. +            }
  15268. +
  15269. +            sh->nr_pending = nr_writing;
  15270. +            PRINTK(("handle_stripe() %lu, writing back %d\n", sh->sector, sh->nr_pending));
  15271. +
  15272. +            for (i = 0; i < disks; i++) {
  15273. +                if (!operational[i])
  15274. +                    continue;
  15275. +                bh = sh->bh_copy[i];
  15276. +                if (i != sh->pd_idx && ((bh == NULL) ^ (sh->bh_new[i] == NULL)))
  15277. +                    printk("raid5: bug: bh == %p, bh_new[%d] == %p\n", bh, i, sh->bh_new[i]);
  15278. +                if (i == sh->pd_idx && !bh)
  15279. +                    printk("raid5: bug: bh == NULL, i == pd_idx == %d\n", i);
  15280. +                if (bh) {
  15281. +                    bh->b_state |= (1<<BH_Dirty);
  15282. +                    PRINTK(("making request for buffer %d\n", i));
  15283. +                    clear_bit(BH_Lock, &bh->b_state);
  15284. +                    make_request(MAJOR(raid_conf->disks[i].dev), WRITE, bh);
  15285. +                }
  15286. +            }
  15287. +            return;
  15288. +        }
  15289. +
  15290. +        lock_stripe(sh);
  15291. +        sh->nr_pending++;
  15292. +        if (method1 < method2) {
  15293. +            sh->write_method = RECONSTRUCT_WRITE;
  15294. +            for (i = 0; i < disks; i++) {
  15295. +                if (i == sh->pd_idx)
  15296. +                    continue;
  15297. +                if (sh->bh_new[i] || sh->bh_old[i])
  15298. +                    continue;
  15299. +                sh->bh_old[i] = raid5_kmalloc_bh(sh, sh->size);
  15300. +                raid5_build_block(sh, sh->bh_old[i], i);
  15301. +                reading++;
  15302. +            }
  15303. +        } else {
  15304. +            sh->write_method = READ_MODIFY_WRITE;
  15305. +            for (i = 0; i < disks; i++) {
  15306. +                if (sh->bh_old[i])
  15307. +                    continue;
  15308. +                if (!sh->bh_new[i] && i != sh->pd_idx)
  15309. +                    continue;
  15310. +                sh->bh_old[i] = raid5_kmalloc_bh(sh, sh->size);
  15311. +                raid5_build_block(sh, sh->bh_old[i], i);
  15312. +                reading++;
  15313. +            }
  15314. +        }
  15315. +        sh->phase = PHASE_READ_OLD;
  15316. +        sh->nr_pending = reading;
  15317. +        PRINTK(("handle_stripe() %lu, reading %d old buffers\n", sh->sector, sh->nr_pending));
  15318. +        for (i = 0; i < disks; i++) {
  15319. +            if (!sh->bh_old[i])
  15320. +                continue;
  15321. +            if (buffer_uptodate(sh->bh_old[i]))
  15322. +                continue;
  15323. +             clear_bit(BH_Lock, &sh->bh_old[i]->b_state);
  15324. +            make_request(MAJOR(raid_conf->disks[i].dev), READ, sh->bh_old[i]);
  15325. +        }
  15326. +    } else {
  15327. +        /*
  15328. +         * Reading
  15329. +         */
  15330. +        method1 = nr_read - nr_cache_overwrite;
  15331. +        lock_stripe(sh);
  15332. +        sh->nr_pending++;
  15333. +
  15334. +        PRINTK(("handle_stripe(), sector %lu, nr_read %d, nr_cache %d, method1 %d\n", sh->sector, nr_read, nr_cache, method1));
  15335. +        if (!method1 || (method1 == 1 && nr_cache == disks - 1)) {
  15336. +            PRINTK(("read %lu completed from cache\n", sh->sector));
  15337. +            for (i = 0; i < disks; i++) {
  15338. +                if (!sh->bh_new[i])
  15339. +                    continue;
  15340. +                if (!sh->bh_old[i])
  15341. +                    compute_block(sh, i);
  15342. +                memcpy(sh->bh_new[i]->b_data, sh->bh_old[i]->b_data, sh->size);
  15343. +            }
  15344. +            sh->nr_pending--;
  15345. +            complete_stripe(sh);
  15346. +            return;
  15347. +        }
  15348. +        if (nr_failed_overwrite) {
  15349. +            sh->phase = PHASE_READ_OLD;
  15350. +            sh->nr_pending = (disks - 1) - nr_cache;
  15351. +            PRINTK(("handle_stripe() %lu, phase READ_OLD, pending %d\n", sh->sector, sh->nr_pending));
  15352. +            for (i = 0; i < disks; i++) {
  15353. +                if (sh->bh_old[i])
  15354. +                    continue;
  15355. +                if (!operational[i])
  15356. +                    continue;
  15357. +                sh->bh_old[i] = raid5_kmalloc_bh(sh, sh->size);
  15358. +                raid5_build_block(sh, sh->bh_old[i], i);
  15359. +                 clear_bit(BH_Lock, &sh->bh_old[i]->b_state);
  15360. +                make_request(MAJOR(raid_conf->disks[i].dev), READ, sh->bh_old[i]);
  15361. +            }
  15362. +        } else {
  15363. +            sh->phase = PHASE_READ;
  15364. +            sh->nr_pending = nr_read - nr_cache_overwrite;
  15365. +            PRINTK(("handle_stripe() %lu, phase READ, pending %d\n", sh->sector, sh->nr_pending));
  15366. +            for (i = 0; i < disks; i++) {
  15367. +                if (!sh->bh_new[i])
  15368. +                    continue;
  15369. +                if (sh->bh_old[i]) {
  15370. +                    memcpy(sh->bh_new[i]->b_data, sh->bh_old[i]->b_data, sh->size);
  15371. +                    continue;
  15372. +                }
  15373. +                clear_bit(BH_Lock, &sh->bh_new[i]->b_state);
  15374. +                make_request(MAJOR(raid_conf->disks[i].dev), READ, sh->bh_new[i]);
  15375. +            }
  15376. +        }
  15377. +    }
  15378. +}
  15379. +
  15380. +static int raid5_make_request (struct md_dev *mddev, int rw, struct buffer_head * bh)
  15381. +{
  15382. +    struct raid5_data *raid_conf = (struct raid5_data *) mddev->private;
  15383. +    const unsigned int raid_disks = raid_conf->raid_disks;
  15384. +    const unsigned int data_disks = raid_disks - 1;
  15385. +    unsigned int  dd_idx, pd_idx;
  15386. +    unsigned long new_sector;
  15387. +
  15388. +    struct stripe_head *sh;
  15389. +
  15390. +    if (rw == READA) rw = READ;
  15391. +    if (rw == WRITEA) rw = WRITE;
  15392. +
  15393. +    new_sector = raid5_compute_sector(bh->b_rsector, raid_disks, data_disks,
  15394. +                        &dd_idx, &pd_idx, raid_conf);
  15395. +
  15396. +    PRINTK(("raid5_make_request, sector %lu\n", new_sector));
  15397. +    sh = get_stripe(raid_conf, new_sector, bh->b_size);
  15398. +    if ((rw == READ && sh->cmd == STRIPE_WRITE) || (rw == WRITE && sh->cmd == STRIPE_READ)) {
  15399. +        printk("raid5: lock contention, rw == %d, sh->cmd == %d\n", rw, sh->cmd);
  15400. +        lock_stripe(sh);
  15401. +        if (!sh->nr_pending)
  15402. +            handle_stripe(sh);
  15403. +        wait_on_stripe(sh);
  15404. +    }
  15405. +    sh->pd_idx = pd_idx;
  15406. +    if (sh->phase != PHASE_COMPLETE && sh->phase != PHASE_BEGIN)
  15407. +        PRINTK(("stripe %lu catching the bus!\n", sh->sector));
  15408. +    add_stripe_bh(sh, bh, dd_idx, rw);
  15409. +
  15410. +    md_wakeup_thread(raid_conf->thread);
  15411. +    return 0;
  15412. +}
  15413. +
  15414. +/*
  15415. + * This is our raid5 kernel thread.
  15416. + *
  15417. + * We scan the hash table for stripes which can be handled now.
  15418. + * During the scan, completed stripes are saved for us by the interrupt
  15419. + * handler, so that they will not have to wait for our next wakeup.
  15420. + */
  15421. +static void raid5d (void *data)
  15422. +{
  15423. +    struct stripe_head *sh;
  15424. +    struct raid5_data *raid_conf = data;
  15425. +    struct md_dev *mddev = raid_conf->mddev;
  15426. +    int i, handled = 0, unplug = 0;
  15427. +    unsigned long flags;
  15428. +
  15429. +    PRINTK(("+++ raid5d active\n"));
  15430. +
  15431. +    if (mddev->sb_dirty) {
  15432. +        mddev->sb_dirty = 0;
  15433. +        md_update_sb((int) (mddev - md_dev));
  15434. +    }
  15435. +    save_flags(flags);
  15436. +    cli();
  15437. +    stripe_handle_list = stripe_handle_tail = NULL;
  15438. +    restore_flags(flags);
  15439. +
  15440. +    for (i = 0; i < NR_HASH; i++) {
  15441. +repeat:
  15442. +        sh = stripe_hashtbl[i];
  15443. +        for (; sh; sh = sh->hash_next) {
  15444. +            if (sh->raid_conf != raid_conf)
  15445. +                continue;
  15446. +            if (sh->phase == PHASE_COMPLETE)
  15447. +                continue;
  15448. +            if (sh->nr_pending)
  15449. +                continue;
  15450. +            if (sh->sector == raid_conf->next_sector) {
  15451. +                raid_conf->sector_count += (sh->size >> 9);
  15452. +                if (raid_conf->sector_count >= 128)
  15453. +                    unplug = 1;
  15454. +            } else
  15455. +                unplug = 1;
  15456. +            if (unplug) {
  15457. +                PRINTK(("unplugging devices, sector == %lu, count == %d\n", sh->sector, raid_conf->sector_count));
  15458. +                unplug_devices(sh);
  15459. +                unplug = 0;
  15460. +                raid_conf->sector_count = 0;
  15461. +            }
  15462. +            raid_conf->next_sector = sh->sector + (sh->size >> 9);
  15463. +            handled++;
  15464. +            handle_stripe(sh);
  15465. +            goto repeat;
  15466. +        }
  15467. +    }
  15468. +    if (raid_conf) {
  15469. +        PRINTK(("%d stripes handled, nr_handle %d\n", handled, raid_conf->nr_handle));
  15470. +        save_flags(flags);
  15471. +        cli();
  15472. +        if (!raid_conf->nr_handle)
  15473. +            clear_bit(THREAD_WAKEUP, &raid_conf->thread->flags);
  15474. +    }
  15475. +    PRINTK(("--- raid5d inactive\n"));
  15476. +}
  15477. +
  15478. +static int raid5_run (int minor, struct md_dev *mddev)
  15479. +{
  15480. +    struct raid5_data *raid_conf;
  15481. +    int i, j, raid_disk;
  15482. +    md_superblock_t *sb = mddev->sb;
  15483. +    md_descriptor_t *descriptor;
  15484. +    struct real_dev *realdev;
  15485. +
  15486. +    MOD_INC_USE_COUNT;
  15487. +
  15488. +    if (sb->level != 5 && sb->level != 4) {
  15489. +        printk("raid5: %s: raid level not set to 4/5 (%d)\n", kdevname(MKDEV(MD_MAJOR, minor)), sb->level);
  15490. +        MOD_DEC_USE_COUNT;
  15491. +        return -EIO;
  15492. +    }
  15493. +
  15494. +    mddev->private = kmalloc (sizeof (struct raid5_data), GFP_KERNEL);
  15495. +    raid_conf = mddev->private;
  15496. +    memset (raid_conf, 0, sizeof (*raid_conf));
  15497. +    raid_conf->mddev = mddev;
  15498. +
  15499. +    PRINTK(("raid5_run(%d) called.\n", minor));
  15500. +
  15501. +      for (i = 0; i < mddev->nb_dev; i++) {
  15502. +          realdev = &mddev->devices[i];
  15503. +        if (!realdev->sb) {
  15504. +            printk(KERN_ERR "raid5: disabled device %s (couldn't access raid superblock)\n", kdevname(realdev->dev));
  15505. +            continue;
  15506. +        }
  15507. +
  15508. +        /*
  15509. +         * This is important -- we are using the descriptor on
  15510. +         * the disk only to get a pointer to the descriptor on
  15511. +         * the main superblock, which might be more recent.
  15512. +         */
  15513. +        descriptor = &sb->disks[realdev->sb->descriptor.number];
  15514. +        if (descriptor->state & (1 << MD_FAULTY_DEVICE)) {
  15515. +            printk(KERN_ERR "raid5: disabled device %s (errors detected)\n", kdevname(realdev->dev));
  15516. +            continue;
  15517. +        }
  15518. +        if (descriptor->state & (1 << MD_ACTIVE_DEVICE)) {
  15519. +            if (!(descriptor->state & (1 << MD_SYNC_DEVICE))) {
  15520. +                printk(KERN_ERR "raid5: disabled device %s (not in sync)\n", kdevname(realdev->dev));
  15521. +                continue;
  15522. +            }
  15523. +            raid_disk = descriptor->raid_disk;
  15524. +            if (descriptor->number > sb->nr_disks || raid_disk > sb->raid_disks) {
  15525. +                printk(KERN_ERR "raid5: disabled device %s (inconsistent descriptor)\n", kdevname(realdev->dev));
  15526. +                continue;
  15527. +            }
  15528. +            if (raid_conf->disks[raid_disk].operational) {
  15529. +                printk(KERN_ERR "raid5: disabled device %s (device %d already operational)\n", kdevname(realdev->dev), raid_disk);
  15530. +                continue;
  15531. +            }
  15532. +            printk(KERN_INFO "raid5: device %s operational as raid disk %d\n", kdevname(realdev->dev), raid_disk);
  15533. +    
  15534. +            raid_conf->disks[raid_disk].number = descriptor->number;
  15535. +            raid_conf->disks[raid_disk].raid_disk = raid_disk;
  15536. +            raid_conf->disks[raid_disk].dev = mddev->devices[i].dev;
  15537. +            raid_conf->disks[raid_disk].operational = 1;
  15538. +
  15539. +            raid_conf->working_disks++;
  15540. +        }
  15541. +    }
  15542. +    raid_conf->raid_disks = sb->raid_disks;
  15543. +    raid_conf->failed_disks = raid_conf->raid_disks - raid_conf->working_disks;
  15544. +    raid_conf->mddev = mddev;
  15545. +    raid_conf->chunk_size = sb->chunk_size;
  15546. +    raid_conf->level = sb->level;
  15547. +    raid_conf->algorithm = sb->parity_algorithm;
  15548. +
  15549. +    if (!raid_conf->chunk_size || raid_conf->chunk_size % 4) {
  15550. +        printk(KERN_ERR "raid5: invalid chunk size %d for %s\n", raid_conf->chunk_size, kdevname(MKDEV(MD_MAJOR, minor)));
  15551. +        goto abort;
  15552. +    }
  15553. +    if (raid_conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) {
  15554. +        printk(KERN_ERR "raid5: unsupported parity algorithm %d for %s\n", raid_conf->algorithm, kdevname(MKDEV(MD_MAJOR, minor)));
  15555. +        goto abort;
  15556. +    }
  15557. +    if (raid_conf->failed_disks > 1) {
  15558. +        printk(KERN_ERR "raid5: not enough operational devices for %s (%d/%d failed)\n", kdevname(MKDEV(MD_MAJOR, minor)), raid_conf->failed_disks, raid_conf->raid_disks);
  15559. +        goto abort;
  15560. +    }
  15561. +
  15562. +#if 0
  15563. +    if (check_consistenty(mddev)) {
  15564. +        printk(KERN_ERR "raid5: detected raid-5 xor inconsistenty -- run ckraid\n");
  15565. +        sb->state |= 1 << MD_SB_ERRORS;
  15566. +        goto abort;
  15567. +    }
  15568. +#endif
  15569. +
  15570. +    if ((raid_conf->thread = md_register_thread(raid5d, raid_conf)) == NULL) {
  15571. +        printk(KERN_ERR "raid5: couldn't allocate thread for %s\n", kdevname(MKDEV(MD_MAJOR, minor)));
  15572. +        goto abort;
  15573. +    }
  15574. +
  15575. +    /*
  15576. +     * Regenerate the "device is in sync with the raid set" bit for
  15577. +     * each device.
  15578. +     */
  15579. +    for (i = 0; i < sb->nr_disks ; i++) {
  15580. +        sb->disks[i].state &= ~(1 << MD_SYNC_DEVICE);
  15581. +        for (j = 0; j < sb->raid_disks; j++) {
  15582. +            if (!raid_conf->disks[j].operational)
  15583. +                continue;
  15584. +            if (sb->disks[i].number == raid_conf->disks[j].number)
  15585. +                sb->disks[i].state |= 1 << MD_SYNC_DEVICE;
  15586. +        }
  15587. +    }
  15588. +    sb->active_disks = raid_conf->working_disks;
  15589. +
  15590. +    if (sb->active_disks == sb->raid_disks)
  15591. +        printk("raid5: raid level %d set %s active with %d out of %d devices, algorithm %d\n", raid_conf->level, kdevname(MKDEV(MD_MAJOR, minor)), sb->active_disks, sb->raid_disks, raid_conf->algorithm);
  15592. +    else
  15593. +        printk(KERN_ALERT "raid5: raid level %d set %s active with %d out of %d devices, algorithm %d\n", raid_conf->level, kdevname(MKDEV(MD_MAJOR, minor)), sb->active_disks, sb->raid_disks, raid_conf->algorithm);
  15594. +
  15595. +    /* Ok, everything is just fine now */
  15596. +    return (0);
  15597. +abort:
  15598. +    if (raid_conf)
  15599. +        kfree(raid_conf);
  15600. +    mddev->private = NULL;
  15601. +    printk(KERN_ALERT "raid5: failed to run raid set %s\n", kdevname(MKDEV(MD_MAJOR, minor)));
  15602. +    MOD_DEC_USE_COUNT;
  15603. +    return -EIO;
  15604. +}
  15605. +
  15606. +static int raid5_stop (int minor, struct md_dev *mddev)
  15607. +{
  15608. +    struct raid5_data *raid_conf = (struct raid5_data *) mddev->private;
  15609. +
  15610. +    md_unregister_thread(raid_conf->thread);
  15611. +    kfree (raid_conf);
  15612. +    shrink_stripe_cache(RAID5_STRIPE_POOL_SIZE);
  15613. +    shrink_buffers(RAID5_POOL_SIZE);
  15614. +    MOD_DEC_USE_COUNT;
  15615. +    return 0;
  15616. +}
  15617. +
  15618. +static int raid5_status (char *page, int minor, struct md_dev *mddev)
  15619. +{
  15620. +    struct raid5_data *raid_conf = (struct raid5_data *) mddev->private;
  15621. +    md_superblock_t *sb = mddev->sb;
  15622. +    int sz = 0, i;
  15623. +
  15624. +    sz += sprintf (page+sz, " level %d, %dk chunk, algorithm %d", sb->level, sb->chunk_size >> 10, sb->parity_algorithm);
  15625. +    sz += sprintf (page+sz, " [%d/%d] [", raid_conf->raid_disks, raid_conf->working_disks);
  15626. +    for (i = 0; i < raid_conf->raid_disks; i++)
  15627. +        sz += sprintf (page+sz, "%s", raid_conf->disks[i].operational ? "U" : "_");
  15628. +    sz += sprintf (page+sz, "]");
  15629. +    return sz;
  15630. +}
  15631. +
  15632. +static struct md_personality raid5_personality=
  15633. +{
  15634. +    "raid5",
  15635. +    raid5_map,
  15636. +    raid5_make_request,
  15637. +    raid5_end_request,
  15638. +    raid5_run,
  15639. +    raid5_stop,
  15640. +    raid5_status,
  15641. +    NULL,            /* no ioctls */
  15642. +    0,
  15643. +    raid5_error
  15644. +};
  15645. +
  15646. +int raid5_init (void)
  15647. +{
  15648. +    if ((stripe_hashtbl = (struct stripe_head **) __get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER, 0)) == NULL)
  15649. +        return -ENOMEM;
  15650. +    memset(stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE);
  15651. +    return register_md_personality (RAID5, &raid5_personality);
  15652. +}
  15653. +
  15654. +#ifdef MODULE
  15655. +int init_module (void)
  15656. +{
  15657. +    return raid5_init();
  15658. +}
  15659. +
  15660. +void cleanup_module (void)
  15661. +{
  15662. +    free_pages((unsigned long) stripe_hashtbl, HASH_PAGES_ORDER);
  15663. +    shrink_stripe_cache(RAID5_STRIPE_POOL_SIZE);
  15664. +    shrink_buffers(RAID5_POOL_SIZE);
  15665. +    unregister_md_personality (RAID5);
  15666. +}
  15667. +#endif
  15668. diff -u --recursive --new-file v2.0.34/linux/drivers/block/rd.c linux/drivers/block/rd.c
  15669. --- v2.0.34/linux/drivers/block/rd.c    Mon Jul 13 13:46:26 1998
  15670. +++ linux/drivers/block/rd.c    Mon Jul 13 13:47:28 1998
  15671. @@ -582,7 +582,7 @@
  15672.  static unsigned insize = 0;  /* valid bytes in inbuf */
  15673.  static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
  15674.  static unsigned outcnt = 0;  /* bytes in output buffer */
  15675. -static exit_code = 0;
  15676. +static int exit_code = 0;
  15677.  static long bytes_out = 0;
  15678.  static struct file *crd_infp, *crd_outfp;
  15679.  
  15680. diff -u --recursive --new-file v2.0.34/linux/drivers/block/triton.c linux/drivers/block/triton.c
  15681. --- v2.0.34/linux/drivers/block/triton.c    Mon Jul 13 13:46:26 1998
  15682. +++ linux/drivers/block/triton.c    Mon Jul 13 13:47:28 1998
  15683. @@ -374,7 +374,7 @@
  15684.               * safely use __get_free_page() here instead
  15685.               * of __get_dma_pages() -- no ISA limitations.
  15686.               */
  15687. -            dmatable = __get_free_page(GFP_KERNEL);
  15688. +            dmatable = __get_free_pages(GFP_KERNEL, 1, 0);
  15689.          }
  15690.          if (dmatable) {
  15691.              hwif->dmatable = (unsigned long *) dmatable;
  15692. @@ -503,3 +503,25 @@
  15693.  quit: if (rc) printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));
  15694.  }
  15695.  
  15696. +void ide_init_promise (byte bus, byte fn, ide_hwif_t *hwif0, ide_hwif_t *hwif1, unsigned short dma)
  15697. +{
  15698. +    int rc;
  15699. +    unsigned short pcicmd;
  15700. +    unsigned int bmiba = 0;
  15701. +
  15702. +    printk("ide: Enabling DMA for Promise Technology IDE Ultra-DMA 33 on PCI bus %d function %d, port 0x%04x\n", bus, fn, dma);
  15703. +    if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)) || (pcicmd & 1) == 0 || (pcicmd & 4) == 0)
  15704. +        goto abort;
  15705. +    if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))
  15706. +        goto abort;
  15707. +    bmiba &= 0xfff0;    /* extract port base address */
  15708. +    if (bmiba != dma || !bmiba)
  15709. +        goto abort;
  15710. +    hwif0->chipset = ide_promise_udma;
  15711. +    hwif1->chipset = ide_promise_udma;
  15712. +    init_triton_dma(hwif0, bmiba);
  15713. +    init_triton_dma(hwif1, bmiba + 0x08);
  15714. +    return;
  15715. +abort:
  15716. +    printk(KERN_WARNING "ide: Promise/33 not configured correctly (BIOS)\n");
  15717. +}
  15718. diff -u --recursive --new-file v2.0.34/linux/drivers/cdrom/cm206.c linux/drivers/cdrom/cm206.c
  15719. --- v2.0.34/linux/drivers/cdrom/cm206.c    Sat Aug 17 11:19:26 1996
  15720. +++ linux/drivers/cdrom/cm206.c    Mon Jul 13 13:47:28 1998
  15721. @@ -739,7 +739,7 @@
  15722.    uch * q = cd->q;
  15723.    uch ct;            /* current track */
  15724.    int binary=0;
  15725. -  const skip = 3*60*75;
  15726. +  const int skip = 3*60*75;
  15727.  
  15728.    for (i=track; i>0; i--) if (cd->toc[i].track) {
  15729.      min = fsm2lba(cd->toc[i].fsm);
  15730. diff -u --recursive --new-file v2.0.34/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c
  15731. --- v2.0.34/linux/drivers/cdrom/mcd.c    Wed Nov 13 23:30:59 1996
  15732. +++ linux/drivers/cdrom/mcd.c    Mon Jul 13 13:47:28 1998
  15733. @@ -311,7 +311,10 @@
  15734.      {
  15735.          i = updateToc();
  15736.          if (i < 0)
  15737. -            return i;    /* error reading TOC */
  15738. +            /* Hermann.Lauer@IWR.Uni-Heidelberg.De:
  15739. +             We _can_ open the door even without a CD */
  15740. +            if (cmd != CDROMEJECT)
  15741. +                return i;    /* error reading TOC */
  15742.      }
  15743.  
  15744.      switch (cmd)
  15745. diff -u --recursive --new-file v2.0.34/linux/drivers/cdrom/sonycd535.c linux/drivers/cdrom/sonycd535.c
  15746. --- v2.0.34/linux/drivers/cdrom/sonycd535.c    Mon Apr  1 21:43:06 1996
  15747. +++ linux/drivers/cdrom/sonycd535.c    Mon Jul 13 13:47:28 1998
  15748. @@ -4,7 +4,7 @@
  15749.   * This is a modified version of the CDU-31A device driver (see below).
  15750.   * Changes were made using documentation for the CDU-531 (which Sony
  15751.   * assures me is very similar to the 535) and partial disassembly of the
  15752. - * DOS driver.  I used Minyard's driver and replaced the the CDU-31A
  15753. + * DOS driver.  I used Minyard's driver and replaced the CDU-31A
  15754.   * commands with the CDU-531 commands.  This was complicated by a different
  15755.   * interface protocol with the drive.  The driver is still polled.
  15756.   *
  15757. @@ -31,6 +31,10 @@
  15758.   *  More changes to support CDU-510/515 series
  15759.   *      (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
  15760.   *
  15761. + * 1997-11-18
  15762. + *  Blocksize awareness
  15763. + *      Dong Liu <qian!dliu@arrow.njit.edu>
  15764. + *
  15765.   * Things to do:
  15766.   *  - handle errors and status better, put everything into a single word
  15767.   *  - use interrupts (code mostly there, but a big hole still missing)
  15768. @@ -589,11 +593,13 @@
  15769.   *    The routine returns number of bytes read in if successful, otherwise
  15770.   *  it returns one of the standard error returns.
  15771.   ***************************************************************************/
  15772. +
  15773. +static int sonycd535_block_size = 2048;
  15774. +
  15775.  static int
  15776.  seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
  15777.                         Byte **buff, int buf_size)
  15778.  {
  15779. -    const int block_size = 2048;
  15780.      Byte cmd_buff[7];
  15781.      int  i;
  15782.      int  read_status;
  15783. @@ -601,7 +607,7 @@
  15784.      Byte *data_buff;
  15785.      int  sector_count = 0;
  15786.  
  15787. -    if (buf_size < ((long)block_size) * n_blocks)
  15788. +    if (buf_size < sonycd535_block_size * n_blocks)
  15789.          return NO_ROOM;
  15790.  
  15791.      set_drive_mode(SONY535_CDROM_DRIVE_MODE, status);
  15792. @@ -626,7 +632,7 @@
  15793.              if ((read_status & SONY535_DATA_NOT_READY_BIT) == 0) {
  15794.                  /* data is ready, read it */
  15795.                  data_buff = buff[sector_count++];
  15796. -                for (i = 0; i < block_size; i++)
  15797. +                for (i = 0; i < sonycd535_block_size; i++)
  15798.                      *data_buff++ = inb(data_reg);    /* unrolling this loop does not seem to help */
  15799.                  break;            /* exit the timeout loop */
  15800.              }
  15801. @@ -639,7 +645,7 @@
  15802.      /* read all the data, now read the status */
  15803.      if ((i = read_exec_status(status)) != 0)
  15804.          return i;
  15805. -    return block_size * sector_count;
  15806. +    return sonycd535_block_size * sector_count;
  15807.  }    /* seek_and_read_N_blocks() */
  15808.  
  15809.  /****************************************************************************
  15810. @@ -1594,6 +1600,7 @@
  15811.                      return -EIO;
  15812.                  }
  15813.                  blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
  15814. +                blksize_size[MAJOR_NR] = &sonycd535_block_size;
  15815.                  read_ahead[MAJOR_NR] = 8;    /* 8 sector (4kB) read-ahead */
  15816.  
  15817.                  sony_toc = (struct s535_sony_toc *)
  15818. diff -u --recursive --new-file v2.0.34/linux/drivers/char/ChangeLog linux/drivers/char/ChangeLog
  15819. --- v2.0.34/linux/drivers/char/ChangeLog    Thu Jun  6 12:23:08 1996
  15820. +++ linux/drivers/char/ChangeLog    Mon Jul 13 13:47:28 1998
  15821. @@ -253,7 +253,7 @@
  15822.  Fri Feb 17 09:34:09 1995  Theodore Y. Ts'o  (tytso@rt-11)
  15823.  
  15824.      * serial.c (rs_interrupt_single, rs_interrupt, rs_interrupt_multi): 
  15825. -        Change the the number of passes made from 64 to be 256,
  15826. +        Change the number of passes made from 64 to be 256,
  15827.          configurable with the #define RS_ISR_PASS_LIMIT.
  15828.  
  15829.      * serial.c (rs_init, set_serial_info, get_serial_info, rs_close):
  15830. diff -u --recursive --new-file v2.0.34/linux/drivers/char/Makefile linux/drivers/char/Makefile
  15831. --- v2.0.34/linux/drivers/char/Makefile    Mon Jul 13 13:46:26 1998
  15832. +++ linux/drivers/char/Makefile    Mon Jul 13 13:47:28 1998
  15833. @@ -217,14 +217,6 @@
  15834.    endif
  15835.  endif  
  15836.  
  15837. -ifeq ($(CONFIG_BAYCOM),y)
  15838. -L_OBJS += baycom.o
  15839. -else
  15840. -  ifeq ($(CONFIG_BAYCOM),m)
  15841. -  M_OBJS += baycom.o
  15842. -  endif
  15843. -endif  
  15844. -
  15845.  ifdef CONFIG_TGA_CONSOLE
  15846.  L_OBJS += tga.o
  15847.    ifdef CONFIG_VGA_CONSOLE
  15848. diff -u --recursive --new-file v2.0.34/linux/drivers/char/README.stallion linux/drivers/char/README.stallion
  15849. --- v2.0.34/linux/drivers/char/README.stallion    Wed Apr 24 02:48:04 1996
  15850. +++ linux/drivers/char/README.stallion    Mon Jul 13 13:47:29 1998
  15851. @@ -1,52 +1,183 @@
  15852.  
  15853. -Stallion Multiport Serial Drivers
  15854. ----------------------------------
  15855. +Stallion Multiport Serial Driver Readme
  15856. +---------------------------------------
  15857. +
  15858. +Copyright (C) 1994-1998,  Stallion Technologies (support@stallion.com).
  15859. +
  15860. +Version:   5.4.4
  15861. +Date:      20MAR98
  15862.  
  15863. -Version: 1.1.3
  15864. -Date:    23APR96
  15865. -Author:  Greg Ungerer (gerg@stallion.oz.au)
  15866.  
  15867.  
  15868.  1. INTRODUCTION
  15869.  
  15870. -There are two drivers that work with the different families of Stallion
  15871. -multiport serial boards. One is for the Stallion smart boards - that is
  15872. -EasyIO and EasyConnection 8/32, the other for the true Stallion intelligent
  15873. -multiport boards - EasyConnection 8/64, ONboard, Brumby and Stallion.
  15874. -
  15875. -If you are using any of the Stallion intelligent multiport boards (Brumby,
  15876. -ONboard, Stallion, EasyConnection 8/64) with Linux you will need to get the
  15877. -driver utility package. This package is available at most of the Linux
  15878. -archive sites (and on CD's that contain these archives). The file will be
  15879. -called stallion-X.X.X.tar.gz where X.X.X will be the version number. In
  15880. -particular this package contains the board embedded executable images that
  15881. -are required for these boards. It also contains the downloader program.
  15882. -These boards cannot be used without this.
  15883. -
  15884. -The following ftp sites (and their mirrors) definitely have the stallion
  15885. -driver utility package: ftp.stallion.com, tsx-11.mit.edu, sunsite.unc.edu.
  15886. -
  15887. -ftp.stallion.com:/drivers/ata5/Linux/stallion-1.1.2.tar.gz
  15888. -tsx-11.mit.edu:/pub/linux/BETA/serial/stallion/stallion-1.1.2.tar.gz
  15889. -sunsite.unc.edu:/pub/Linux/kernel/patches/serial/stallion-1.1.2.tar.gz
  15890. -
  15891. -If you are using the EasyIO or EasyConnection 8/32 boards then you don't
  15892. -need this package. Although it does have a handy script to create the
  15893. -/dev device nodes for these boards, and a serial stats display program.
  15894. -
  15895. -If you require DIP switch settings, EISA/MCA configuration files, or any
  15896. -other information related to Stallion boards then have a look at Stallion's
  15897. -web pages at http://www.stallion.com.
  15898. +This is a Linux driver for some of the Stallion Technologies range of
  15899. +multiport serial boards. There are really two drivers in this package.
  15900. +One is for the Stallion smart boards, the other for the true Stallion
  15901. +intelligent multiport boards.
  15902. +
  15903. +The drivers included in this package are intended as a replacement for
  15904. +those shipped with Linux kernel versions in the 2.0.X series. For later
  15905. +versions of the kernel (2.1.0 and above) use the driver source supplied
  15906. +with the kernel. The drivers in this package specifically add support
  15907. +for the most recent releases of Stallion hardware - which are not supported
  15908. +in the Stallion drivers supplied in the 2.0.X kernels. The drivers in this
  15909. +package do not support kernel versions earlier than 2.0.0.
  15910. +
  15911. +The other utilities supplied in this package can be used with Stallion
  15912. +drivers on any version of the kernel.
  15913. +
  15914. +If you have any trouble getting Stallion boards to work in Linux systems,
  15915. +please contact Stallion Technologies support department via email or phone.
  15916. +Contact information for Stallion Technologies offices is included in the
  15917. +file "Offices" contained in this distribution.
  15918. +
  15919. +Please note the disclaimers set out in the GNU general public license
  15920. +included with this driver package.
  15921. +
  15922. +All host driver source is included in this package, and is copyrighted under
  15923. +the GNU GPL. The board "firmware" code in this package is copyright Stallion
  15924. +Technologies (the files cdk.sys and 2681.sys).
  15925. +
  15926. +
  15927. +1.1 SMART MULTIPORT BOARD DRIVER
  15928. +
  15929. +This driver supports the EasyIO and EasyConnection 8/32 range of boards.
  15930. +These boards are not classic intelligent multiport boards, but are host
  15931. +based multiport boards that use Cirrus Logic CL-CD1400 UART's, or on
  15932. +newer versions of the hardware use the Signetics 26C198 UART. Both of
  15933. +these are high performance UART's with built in FIFO's, automatic flow
  15934. +control and a host of other features.
  15935. +
  15936. +The EasyIO range of cards comes in 4 forms, the EasyIO-4, EasyIO-8,
  15937. +EasyIO-8M and EasyIO-8-PCI. The first three are ISA based boards while
  15938. +the last is a PCI bus board. All of these are non-expandable, low cost,
  15939. +multiport boards with 4 or 8 RS-232C ports. Each ISA EasyIO board requires 8
  15940. +bytes of I/O address space and 1 interrupt. The PCI EasyIO board uses 64
  15941. +bytes of I/O address space and 1 interrupt. On EISA and PCI systems it is
  15942. +possible to share 1 interrupt between multiple boards. The EasyIO-4 has 10
  15943. +pin RJ connectors, and the EasyIO-8 comes with a dongle cable with either 10
  15944. +pin RJ connectors or DB-25 connectors. The EasyIO-8M has 6 pin RJ connectors.
  15945. +
  15946. +The EasyConnection 8/32 family of boards is a relatively low cost modular
  15947. +range of multiport serial boards. The EasyConnection 8/32 boards can be
  15948. +configured to have from 8 to 32 serial ports by plugging in external serial
  15949. +port modules that contain either 8 or 16 ports each. There is a wide range
  15950. +of external modules available that offer: DB-25 connectors, RJ-45 connectors
  15951. +(both with RS-232 D and E compatible drivers), and also RS-422 and RS-485
  15952. +ports. The EasyConnection 8/32 boards come in ISA, PCI and MCA bus versions.
  15953. +The board takes the form of a host adapter card, with an external connector
  15954. +cable that plugs into the external modules. The external modules just clip
  15955. +together to add ports (BTW, they are NOT hot pluggable). Each ISA
  15956. +EasyConnection 8/32 board requires two separate I/O address ranges, one two
  15957. +bytes in size and a secondary region of 32 bytes. Each PCI EasyConnection
  15958. +8/32 requires two regions of I/O address space, normally these will be
  15959. +automatically allocated by the system BIOS at power on time. Each MCA
  15960. +EasyConnection board requires one I/O address region 64 bytes in size. All
  15961. +board types also require one interrupt. On EISA systems multiple boards can
  15962. +share one interrupt. The secondary I/O range of the ISA board (the 32 byte
  15963. +range) can be shared between multiple boards on any bus type.
  15964. +
  15965. +The EasyConnection 8/64-PCI family is similar to the EasyConnection 8/32-PCI
  15966. +board, and uses the same external modules. It is supported by the smart
  15967. +board driver - not the intelligent board driver. It uses 2 regions of I/O
  15968. +address space, both 64 bytes in size, and 1 interrupt.
  15969. +
  15970. +
  15971. +
  15972. +1.2 INTELLIGENT MULTIPORT BOARD DRIVER
  15973. +
  15974. +This driver is for Stallion's range of true intelligent multiport boards.
  15975. +It supports the EasyConnection 8/64, ONboard and Brumby families of multiport
  15976. +boards. The EasyConnection 8/64 and ONboard boards come in ISA, EISA and
  15977. +Microchannel bus versions. The Brumby boards are only available in ISA
  15978. +versions. This driver can also work with the original Stallion board, but
  15979. +these are no longer supported by Stallion Technologies.
  15980. +
  15981. +The EasyConnection 8/64 family of boards is a medium cost, high performance,
  15982. +modular range of intelligent multiport serial boards. The EasyConnection 8/64
  15983. +boards can be configured to have from 8 to 64 serial ports by plugging in
  15984. +external serial port modules that contain either 8 or 16 ports each (these
  15985. +modules are the same used by the EasyConnection 8/32 board). There is a wide
  15986. +range of external modules available that offer: DB-25 connectors, RJ-45
  15987. +connectors (both with RS-232 D and E compatible drivers), and also RS-422 and
  15988. +RS-485 ports. The board takes the form of a host adapter card, with an external
  15989. +connector cable that plugs into the external modules. The external modules
  15990. +just clip together to add ports (BTW, they are NOT hot pluggable). Each
  15991. +EasyConnection 8/64 board requires 4 bytes of I/O address space and a region
  15992. +of memory space. The size of the memory region required depends on the exact
  15993. +board type. The EISA version requires 64 Kbytes of address space (that can
  15994. +reside anywhere in the 4 Gigabyte physical address space). The ISA and MCA
  15995. +boards require 4 Kbytes of address space (which must reside in the lower
  15996. +1 Mbyte of physical address space - typically in the c8000 to e0000 range).
  15997. +No interrupts are required. The physical memory region of multiple
  15998. +EasyConnection 8/64 boards can be shared, but each board must have a separate
  15999. +I/O address.
  16000. +
  16001. +The ONboard family of boards are traditional intelligent multiport serial
  16002. +boards. They are Stallion's older range of boards with a limited expansion
  16003. +capability. They come in 4, 8, 12, 16 and 32 port versions. The board uses
  16004. +the same base card (which has 4 ports on it) and is expanded to more ports via
  16005. +a mezzanine board that attaches directly onto the base card. External panels
  16006. +plug into the ONboard providing RS-232C ports with DB-25 plugs. An RS-422
  16007. +DB-25 dual interface panel is also available. The ISA and microchannel
  16008. +ONboards require 16 bytes of I/O address space and 64K bytes of memory
  16009. +space. The memory space can be anywhere in the 16 Mbyte ISA bus address
  16010. +range. No interrupt is required. The EISA ONboard requires 64 Kbytes of
  16011. +memory space that can be anywhere in the 4 Gigabyte physical address space.
  16012. +All ONboard boards can share their memory region with other ONboards (or
  16013. +EasyConnection 8/64 boards).
  16014. +
  16015. +The Brumby family of boards are traditional, low cost intelligent multiport
  16016. +serial boards. They are non-expandable and come in 4, 8 and 16 port versions.
  16017. +They are only available for the ISA bus. The serial ports are all on DB-25
  16018. +"dongle" cables that attach to the rear of the board. Each Brumby board
  16019. +requires 16 bytes of I/O address space and 16 Kbytes of memory space. No
  16020. +interrupts are required.
  16021. +
  16022. +The original Stallion boards are old. They went out of production some years
  16023. +back and are no longer supported. They offer limited expandability and are
  16024. +available in 8 or 16 port configurations. An external panel houses 16 RS-232C
  16025. +ports with DB-9 connectors. They require 16 bytes of I/O address space, and
  16026. +either 64K or 128K of memory space. No interrupt is required.
  16027. +
  16028. +That's the boards supported by the second driver. The ONboard, Brumby and
  16029. +Stallion boards are Stallion's older range of intelligent multiports - so
  16030. +there are lots of them around. They only support a maximum baud rate of
  16031. +38400. The EasyConnection 8/64 is a true high performance intelligent
  16032. +multiport board, having much greater throughput than any of Stallion's
  16033. +older boards. It also supports speeds up to 460800 baud.
  16034. +
  16035. +
  16036. +1.3 HOW TO GET BOARDS
  16037. +
  16038. +Stallion Technologies has offices all over the world, as well as many more
  16039. +distributors and resellers. To find out about local availability please
  16040. +contact the nearest Stallion office and they can give you all the information
  16041. +you need. Look in the "Offices" file in the driver package for a current list
  16042. +of Stallion Technologies offices.
  16043. +
  16044. +Another good source of information about the Stallion range of boards and
  16045. +local availability is on the Stallion Web page. Check it out at
  16046. +http://www.stallion.com.
  16047.  
  16048.  
  16049.  
  16050.  2. INSTALLATION
  16051.  
  16052. +This version of the driver is intended for kernel versions 2.0.0 and later.
  16053. +It will not work on earlier kernel versions, due to kernel interface changes.
  16054. +(Note that older versions of these drivers do work on older kernels.)
  16055. +If you are using a more recent development kernel (versions 2.1.X and
  16056. +greater) you should use the Stallion drivers supplied with that kernel,
  16057. +they are more up to date.
  16058. +
  16059.  The drivers can be used as loadable modules or compiled into the kernel.
  16060. -You can choose which when doing a "make config" on the kernel.
  16061. +Depending on which form of driver loading you decide to use, the installation
  16062. +procedure will be a little different.
  16063.  
  16064.  All ISA, EISA and MCA boards that you want to use need to be entered into
  16065. -the driver(s) configuration structures. All PCI boards will be automatically
  16066. +the driver(s) configuration structures. PCI boards will be automatically
  16067.  detected when you load the driver - so they do not need to be entered into
  16068.  the driver(s) configuration structure. (Note that kernel PCI BIOS32 support
  16069.  is required to use PCI boards.)
  16070. @@ -54,45 +185,135 @@
  16071.  Entering ISA, EISA and MCA boards into the driver(s) configuration structure
  16072.  involves editing the driver(s) source file. It's pretty easy if you follow
  16073.  the instructions below. Both drivers can support up to 4 boards. The smart
  16074. -card driver (the stallion.c driver) supports any combination of EasyIO and
  16075. -EasyConnection 8/32 boards (up to a total of 4). The intelligent driver
  16076. -supports any combination of ONboards, Brumbys, Stallions and EasyConnection
  16077. -8/64 boards (up to a total of 4).
  16078. -
  16079. -To set up the driver(s) for the boards that you want to use you need to
  16080. -edit the appropriate driver file and add configuration entries.
  16081. -
  16082. -If using EasyIO or EasyConnection 8/32 ISA or MCA boards, do:
  16083. +card driver supports any combination of EasyIO, EasyConnection 8/32 and
  16084. +EasyConnection 8/64-PCI boards (up to a total of 4). The intelligent driver
  16085. +supports any combination of ONboards, Brumbys, Stallions and
  16086. +EasyConnection 8/64 boards (up to a total of 4).
  16087. +
  16088. +
  16089. +2.1 LOADABLE MODULE DRIVERS
  16090. +
  16091. +You will need the gcc compiler and make installed on your system to make the
  16092. +driver modules. You will also need to have the kernel source on the system,
  16093. +and have at least done a "make config" and "make dep" on it. (If you haven't
  16094. +done this before then you may want to read the kernel source README file,
  16095. +usually found in /usr/src/linux.)
  16096. +
  16097. +To build the driver modules:
  16098. +1. Setup the driver configuration for the boards. If using EasyIO or
  16099. +   EasyConnection 8/32 ISA or MCA boards, do:
  16100.     vi stallion.c
  16101.        - find the definition of the stl_brdconf array (of structures)
  16102.          near the top of the file
  16103.        - modify this to match the boards you are going to install
  16104.      (the comments before this structure should help)
  16105.        - save and exit
  16106. -
  16107. -If using ONboard, Brumby, Stallion or EasyConnection 8/64 boards then do:
  16108. +   If using ONboard, Brumby, Stallion or EasyConnection 8/64 boards then do:
  16109. +   vi istallion.c
  16110. +      - find the definition of the stli_brdconf array (of structures)
  16111. +        near the top of the file
  16112. +      - modify this to match the boards you are going to install
  16113. +    (the comments before this structure should help)
  16114. +      - save and exit
  16115. +2. cp stallion.h cd1400.h sc26198.h /usr/include/linux/include/linux
  16116. +   cp istallion.h cdk.h comstats.h /usr/include/linux/include/linux
  16117. +3. make modules
  16118. +   This will compile the driver modules, as stallion and istallion.
  16119. +
  16120. +The stallion module is the EasyIO, EasyConnection 8/32 and
  16121. +EasyConnection 8/64-PCI driver, the istallion module is the ONboard,
  16122. +Brumby, Stallion and EasyConnection 8/64 driver.
  16123. +
  16124. +To load up the smart board driver use:
  16125. +    insmod ./stallion
  16126. +This will load the EasyIO and EasyConnection 8/32 driver. It will output a
  16127. +message to say that it loaded and print the driver version number. It
  16128. +will also print out whether it found the configured boards or not. (These
  16129. +messages may appear in your /var/adm/messages file depending on how the
  16130. +klogd and syslogd daemons are setup on your system).
  16131. +
  16132. +To load the intelligent board driver use:
  16133. +    insmod ./istallion
  16134. +It will output similar messages to the smart board driver.
  16135. +
  16136. +
  16137. +2.2 STATIC DRIVERS (KERNEL LINKED)
  16138. +
  16139. +You will need to build a new kernel to link in the Stallion drivers. The first
  16140. +thing you need is to have the full kernel source. Most people will have this.
  16141. +The following assumes that the kernel source is in /usr/src/linux.
  16142. +
  16143. +To install the drivers:
  16144. +1. cp stallion.c istallion.c /usr/src/linux/drivers/char
  16145. +   cp stallion.h cd1400.h sc26198.h /usr/include/linux/include/linux
  16146. +   cp istallion.h cdk.h comstats.h /usr/include/linux/include/linux
  16147. +2. cd /usr/src/linux/drivers/char
  16148. +3. Setup the driver configuration for the boards. If using EasyIO,
  16149. +   EasyConnection 8/32 or EasyConnection 8/64-PCI boards, do:
  16150. +   vi stallion.c
  16151. +      - find the definition of the stl_brdconf array (of structures)
  16152. +        near the top of the file
  16153. +      - modify this to match the boards you are going to install
  16154. +    (the comments before this structure should help)
  16155. +      - save and exit
  16156. +   If using ONboard, Brumby, Stallion or EasyConnection 8/64 boards then do:
  16157.     vi istallion.c
  16158.        - find the definition of the stli_brdconf array (of structures)
  16159.          near the top of the file
  16160.        - modify this to match the boards you are going to install
  16161.      (the comments before this structure should help)
  16162.        - save and exit
  16163. +4. cd /usr/src/linux
  16164. +5. build a new kernel - if you haven't done this before you may want to
  16165. +   read the README file in /usr/src/linux.
  16166. +
  16167. +Once you have a new kernel built, reboot to start it up. On startup the
  16168. +driver will output a message to say it is operational (with the driver
  16169. +version number). It will also print out if it could find the boards listed
  16170. +in its configuration structure or not.
  16171. +
  16172. +
  16173. +2.3 INTELLIGENT DRIVER OPERATION
  16174. +
  16175. +The intelligent boards also need to have their "firmware" code downloaded
  16176. +to them. This is done via a user level application supplied in the driver
  16177. +package called "stlload". Compile this program where ever you dropped the
  16178. +package files, by typing "make". In its simplest form you can then type
  16179. +    ./stlload -i cdk.sys
  16180. +in this directory and that will download board 0 (assuming board 0 is an
  16181. +EasyConnection 8/64 board). To download to an ONboard, Brumby or Stallion do:
  16182. +    ./stlload -i 2681.sys
  16183. +
  16184. +Normally you would want all boards to be downloaded as part of the standard
  16185. +system startup. To achieve this, add one of the lines above into the
  16186. +/etc/rc.d/rc.S or /etc/rc.d/rc.serial file. To download each board just add
  16187. +the "-b <brd-number>" option to the line. You will need to download code for
  16188. +every board. You should probably move the stlload program into a system
  16189. +directory, such as /usr/sbin. Also, the default location of the cdk.sys image
  16190. +file in the stlload down-loader is /usr/lib/stallion. Create that directory
  16191. +and put the cdk.sys and 2681.sys files in it. (It's a convenient place to put
  16192. +them anyway). As an example your /etc/rc.d/rc.S file might have the
  16193. +following lines added to it (if you had 3 boards):
  16194. +    /usr/sbin/stlload -b 0 -i /usr/lib/stallion/cdk.sys
  16195. +    /usr/sbin/stlload -b 1 -i /usr/lib/stallion/2681.sys
  16196. +    /usr/sbin/stlload -b 2 -i /usr/lib/stallion/2681.sys
  16197.  
  16198. -Once you have set up the board configurations then you are ready to build
  16199. -the kernel or modules.
  16200. +The image files cdk.sys and 2681.sys are specific to the board types. The
  16201. +cdk.sys will only function correctly on an EasyConnection 8/64 board. Similarly
  16202. +the 2681.sys image fill only operate on ONboard, Brumby and Stallion boards.
  16203. +If you load the wrong image file into a board it will fail to start up, and
  16204. +of course the ports will not be operational!
  16205.  
  16206. -When the new kernel is booted, or the loadable module loaded then the
  16207. -driver will emit some kernel trace messages about whether the configured
  16208. -boards where detected or not. Depending on how your system logger is set
  16209. -up these may come out on the console, or just be logged to
  16210. -/var/adm/messages. You should check the messages to confirm that all is well.
  16211. +If you are using the module version of the driver you might want to put the
  16212. +insmod calls in the startup script as well (before the download lines
  16213. +obviously).
  16214.  
  16215.  
  16216. -2.1 SHARING INTERRUPTS
  16217. +2.4 SHARING INTERRUPTS
  16218.  
  16219. -It is possible to share interrupts between multiple EasyIO and
  16220. -EasyConnection 8/32 boards in an EISA system. To do this you will need to
  16221. -do a couple of things:
  16222. +As mentioned in the introduction, it is possible to share interrupts between
  16223. +multiple EasyIO and EasyConnection 8/32 boards in an EISA system. To do this
  16224. +you will need to do a couple of things:
  16225.  
  16226.  1. When entering the board resources into the stallion.c file you need to
  16227.     mark the boards as using level triggered interrupts. Do this by replacing
  16228. @@ -109,17 +330,17 @@
  16229.     that are sharing interrupts. The Stallion EasyIO and EasyConnection 8/32
  16230.     EISA configuration files required are supplied by Stallion Technologies
  16231.     on the DOS Utilities floppy (usually supplied in the box with the board
  16232. -   when purchased. If not, you can pick it up from Stallion's FTP site,
  16233. -   ftp.stallion.com). You will need to edit the board resources to choose
  16234. -   level triggered interrupts, and make sure to set each board's interrupt
  16235. -   to the same IRQ number.
  16236. +   when purchased. If not, you can pick it up from Stallion's FTP site
  16237. +   ftp.stallion.com or web site http://www.stallion.com). You will need to
  16238. +   edit the board resources to choose level triggered interrupts, and make
  16239. +   sure to set each board's interrupt to the same IRQ number.
  16240.  
  16241.  You must complete both the above steps for this to work. When you reboot
  16242.  or load the driver your EasyIO and EasyConnection 8/32 boards will be
  16243.  sharing interrupts.
  16244.  
  16245.  
  16246. -2.2 USING HIGH SHARED MEMORY
  16247. +2.5 USING HIGH SHARED MEMORY
  16248.  
  16249.  The EasyConnection 8/64-EI, ONboard and Stallion boards are capable of
  16250.  using shared memory addresses above the usual 640K - 1Mb range. The ONboard
  16251. @@ -128,75 +349,52 @@
  16252.  ONboard/E can be programmed for memory addresses up to 4Gb (the EISA bus
  16253.  addressing limit).
  16254.  
  16255. -The higher than 1Mb memory addresses are fully supported by this driver.
  16256. -Just enter the address as you normally would for a lower than 1Mb address
  16257. -(in the drivers board configuration structure).
  16258. +The istallion driver offers direct support for these higher memory regions.
  16259. +To use them just enter the high memory address as if it were a low memory
  16260. +address (in the driver board configuration structure).
  16261. +
  16262.  
  16263. +2.6 LINUX KERNEL VERSIONS 2.1.X
  16264.  
  16265. +There may be some minor differences between the driver source code in this
  16266. +package and that in the Linux kernel source. This will be due to changes
  16267. +needed in the drivers so that they work correctly on newer kernels. The
  16268. +driver source included in this package is intended for use with 2.0.X
  16269. +series kernels. If you have a kernel version 2.1.0 or later then use the
  16270. +source provided with the kernel - it will be more up to date. Stallion
  16271. +Technologies regularly submits the latest driver source to be included in
  16272. +the new kernel source releases.
  16273.  
  16274. -2.3 TROUBLE SHOOTING
  16275. +
  16276. +2.7 TROUBLE SHOOTING
  16277.  
  16278.  If a board is not found by the driver but is actually in the system then the
  16279.  most likely problem is that the I/O address is wrong. Change it in the driver
  16280. -stallion.c or istallion.c configuration structure and rebuild the kernel or
  16281. -modules, or change it on the board. On EasyIO and EasyConnection 8/32 boards
  16282. -the IRQ is software programmable, so if there is a conflict you may need to
  16283. -change the IRQ used for a board in the stallion.c configuration structure.
  16284. -There are no interrupts to worry about for ONboard, Brumby, Stallion or
  16285. -EasyConnection 8/64 boards. The memory region on EasyConnection 8/64 and
  16286. -ONboard boards is software programmable, but not on the Brumbys or Stallions.
  16287. +stallion.c or istallion.c configuration structure and rebuild the kernel
  16288. +or modules, or change it on the board. On EasyIO and EasyConnection 8/32
  16289. +boards the IRQ is software programmable, so if there is a conflict you may
  16290. +need to change the IRQ used for a board in the stallion.c configuration
  16291. +structure. There are no interrupts to worry about for ONboard, Brumby,
  16292. +Stallion or EasyConnection 8/64 boards. The memory region on EasyConnection
  16293. +8/64 and ONboard boards is software programmable, but not on the Brumbys or
  16294. +Stallions.
  16295.  
  16296.  
  16297.  
  16298.  3. USING THE DRIVERS
  16299.  
  16300. -3.1 INTELLIGENT DRIVER OPERATION
  16301. -
  16302. -The intelligent boards also need to have their "firmware" code downloaded
  16303. -to them. This is done via a user level application supplied in the driver
  16304. -package called "stlload". Compile this program where ever you dropped the
  16305. -package files, by typing "make". In its simplest form you can then type
  16306. -    ./stlload -i cdk.sys
  16307. -in this directory and that will download board 0 (assuming board 0 is an
  16308. -EasyConnection 8/64 board). To download to an ONboard, Brumby or Stallion do:
  16309. -    ./stlload -i 2681.sys
  16310. -
  16311. -Normally you would want all boards to be downloaded as part of the standard
  16312. -system startup. To achieve this, add one of the lines above into the
  16313. -/etc/rc.d/rc.S or /etc/rc.d/rc.serial file. To download each board just add
  16314. -the "-b <brd-number>" option to the line. You will need to download code for
  16315. -every board. You should probably move the stlload program into a system
  16316. -directory, such as /usr/sbin. Also, the default location of the cdk.sys image
  16317. -file in the stlload down-loader is /usr/lib/stallion. Create that directory
  16318. -and put the cdk.sys and 2681.sys files in it. (It's a convenient place to put
  16319. -them anyway). As an example your /etc/rc.d/rc.S file might have the
  16320. -following lines added to it (if you had 3 boards):
  16321. -    /usr/sbin/stlload -b 0 -i /usr/lib/stallion/cdk.sys
  16322. -    /usr/sbin/stlload -b 1 -i /usr/lib/stallion/2681.sys
  16323. -    /usr/sbin/stlload -b 2 -i /usr/lib/stallion/2681.sys
  16324. -
  16325. -The image files cdk.sys and 2681.sys are specific to the board types. The
  16326. -cdk.sys will only function correctly on an EasyConnection 8/64 board. Similarly
  16327. -the 2681.sys image fill only operate on ONboard, Brumby and Stallion boards.
  16328. -If you load the wrong image file into a board it will fail to start up, and
  16329. -of course the ports will not be operational!
  16330. -
  16331. -If you are using the modularized version of the driver you might want to put
  16332. -the insmod calls in the startup script as well (before the download lines
  16333. -obviously).
  16334. -
  16335. -
  16336. -3.2 USING THE SERIAL PORTS
  16337. -
  16338.  Once the driver is installed you will need to setup some device nodes to
  16339. -access the serial ports. The simplest method is to use the stallion utility
  16340. -"mkdevnods" script. It will automatically create all possible device entries
  16341. -required for all 4 boards. This will create the normal serial port devices as
  16342. -/dev/ttyE# where # is the port number starting from 0. A bank of 64 minor
  16343. -device numbers is allocated to each board, so the first port on the second
  16344. -board is port 64, etc. A set of callout type devices is also created. They
  16345. -are created as the devices /dev/cue# where # is the same as for the ttyE
  16346. -devices.
  16347. +access the serial ports. Use the supplied "mkdevnods" script to automatically
  16348. +create all required device entries for one board. This will create the normal
  16349. +serial port devices as /dev/ttyE# where # is the port number starting from 0.
  16350. +A set of callout type devices is also created. They are created as the devices
  16351. +/dev/cue# where # is the same as for the ttyE devices.
  16352. +
  16353. +A bank of 64 minor device numbers is allocated to each board. To create
  16354. +device nodes for ports on multiple boards supply a number of boards argument
  16355. +to the "mkdevnods" script. For example to create nodes for four boards use
  16356. +"mkdevnods 4". This means that the first port on the second board is port 64,
  16357. +the first port on the third board is 128, etc.
  16358.  
  16359.  For the most part the Stallion driver tries to emulate the standard PC system
  16360.  COM ports and the standard Linux serial driver. The idea is that you should
  16361. @@ -214,9 +412,18 @@
  16362.  also be used (excepting the ability to auto-configure the I/O and IRQ
  16363.  addresses of boards). Higher baud rates are supported in the usual fashion
  16364.  through setserial or using the CBAUDEX extensions. Note that the EasyIO and
  16365. -EasyConnection (all types) support 57600 and 115200 baud. The older boards
  16366. -including ONboard, Brumby and the original Stallion support a maximum baud
  16367. -rate of 38400.
  16368. +EasyConnection (all types) support 57600 and 115200 baud, and the newer XP
  16369. +versions also support 230400 and 460800 baud. The older boards including
  16370. +ONboard, Brumby and the original Stallion support a maximum baud rate of
  16371. +38400.
  16372. +
  16373. +This driver should work with anything that works on standard Linux serial
  16374. +ports. Having said that, it has been used on at least the following types of
  16375. +"things" under Linux:
  16376. +    a) standard dumb terminals (using agetty, getty)
  16377. +    b) serial mice (under X)
  16378. +    c) modems (using cu, uucp, minicom, seyon, uugetty)
  16379. +    d) slip and ppp connections
  16380.  
  16381.  If you are unfamiliar with how to use serial ports, then get the Serial-HOWTO
  16382.  by Greg Hankins. It will explain everything you need to know!
  16383. @@ -225,6 +432,11 @@
  16384.  
  16385.  4. NOTES
  16386.  
  16387. +The major device numbers used by this driver are conformant with the Linux
  16388. +Device Registry, so they shouldn't clash with any other devices. Also the
  16389. +device naming scheme is the "standard" used by most Linux serial port
  16390. +devices.
  16391. +
  16392.  You can use both drivers at once if you have a mix of board types installed
  16393.  in a system. However to do this you will need to change the major numbers
  16394.  used by one of the drivers. Currently both drivers use major numbers 24, 25
  16395. @@ -234,20 +446,17 @@
  16396.  major numbers 60, 61 and 62. You will also need to create device nodes with
  16397.  different names for the ports, for example ttyF# and cuf#.
  16398.  
  16399. -The original Stallion board is no longer supported by Stallion Technologies.
  16400. -Although it is known to work with the istallion driver.
  16401. -
  16402.  Finding a free physical memory address range can be a problem. The older
  16403.  boards like the Stallion and ONboard need large areas (64K or even 128K), so
  16404.  they can be very difficult to get into a system. If you have 16 Mb of RAM
  16405.  then you have no choice but to put them somewhere in the 640K -> 1Mb range.
  16406.  ONboards require 64K, so typically 0xd0000 is good, or 0xe0000 on some
  16407. -systems. If you have an original Stallion board, "V4.0" or Rev.O, then you
  16408. -need a 64K memory address space, so again 0xd0000 and 0xe0000 are good.
  16409. -Older Stallion boards are a much bigger problem. They need 128K of address
  16410. -space and must be on a 128K boundary. If you don't have a VGA card then
  16411. -0xc0000 might be usable - there is really no other place you can put them
  16412. -below 1Mb.
  16413. +systems. If you have an original Stallion board, "V4.0" or Rev.O,
  16414. +then you need a 64K memory address space, so again 0xd0000 and 0xe0000 are
  16415. +good. Older Stallion boards are a much bigger problem. They need 128K of
  16416. +address space and must be on a 128K boundary. If you don't have a VGA card
  16417. +then 0xc0000 might be usable - there is really no other place you can put
  16418. +them below 1Mb.
  16419.  
  16420.  Both the ONboard and old Stallion boards can use higher memory addresses as
  16421.  well, but you must have less than 16Mb of RAM to be able to use them. Usual
  16422. @@ -265,19 +474,48 @@
  16423.  ranges is the best option. Typically the 2Gb range is convenient for them,
  16424.  and gets them well out of the way.
  16425.  
  16426. +There is a new utility program included called "stlstty". Most people
  16427. +will not need to use this. If you have an ONboard/16 which has partial
  16428. +signals on the upper 12 ports then this program can be used to set the
  16429. +upper ports to have modem control instead of hardware flow control. Use
  16430. +the "mapcts maprts" flag options to this utility on the port(s) that you
  16431. +wish to do this mapping on, eg
  16432. +    ./stlstty maprts mapcts < /dev/cue0
  16433. +This enables RTS to act like DTR and CTS to act like DCD on the specified
  16434. +port.
  16435. +
  16436.  The ports of the EasyIO-8M board do not have DCD or DTR signals. So these
  16437. -ports cannot be used as real modem devices. Generally, when using these
  16438. +ports cannot be used as real modem devices. Generally when using these
  16439.  ports you should only use the cueX devices.
  16440.  
  16441. -The driver utility package contains a couple of very useful programs. One 
  16442. -is a serial port statistics collection and display program - very handy
  16443. -for solving serial port problems. The other is an extended option setting
  16444. -program that works with the intelligent boards.
  16445. +There is another new utility in this package that reports statistics on
  16446. +the serial ports. You will need to have the curses libray installed on
  16447. +your system to build it.
  16448. +
  16449. +To build the statistics display program type:
  16450. +    make stlstats
  16451. +Once compiled simply run it (you will need to be root) and it will display
  16452. +a port sumary for the first board and panel installed. Use the digits to
  16453. +select different board numbers, or 'n' to cycle through the panels on a
  16454. +board. To look at detailed port information then hit 'p', that will display
  16455. +detailed port 0 information. Use the digits and letters 'a' through 'f' to
  16456. +select the different ports (on this board and panel).
  16457. +
  16458. +
  16459. +
  16460. +5. ACKNOWLEDGEMENTS
  16461. +
  16462. +This driver is loosely based on code written by Theodore T'so, Linus
  16463. +Torvalds, and others, so a big thanks to them all.
  16464.  
  16465.  
  16466.  
  16467. -5. DISCLAIMER
  16468. +6. DISCLAIMER
  16469.  
  16470. -I do not speak for Stallion Technologies in any capacity, officially or
  16471. -unofficially.
  16472. +The information contained in this document is believed to be accurate and
  16473. +reliable. However, no responsibility is assumed by Stallion Technologies
  16474. +Pty. Ltd. for its use, nor any infringements of patents or other rights
  16475. +of third parties resulting from its use. Stallion Technologies reserves
  16476. +the right to modify the design of its products and will endeavour to change
  16477. +the information in manuals and accompanying documentation accordingly.
  16478.  
  16479. diff -u --recursive --new-file v2.0.34/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c
  16480. --- v2.0.34/linux/drivers/char/apm_bios.c    Mon Jul 13 13:46:26 1998
  16481. +++ linux/drivers/char/apm_bios.c    Mon Jul 13 13:47:29 1998
  16482. @@ -36,7 +36,7 @@
  16483.   *         Linux 1.3.85
  16484.   *    1.1: support user-space standby and suspend, power off after system
  16485.   *         halted, Linux 1.3.98
  16486. - *    1.2: When resetting RTC after resume, take care so that the the time
  16487. + *    1.2: When resetting RTC after resume, take care so that the time
  16488.   *         is only incorrect by 30-60mS (vs. 1S previously) (Gabor J. Toth
  16489.   *         <jtoth@princeton.edu>); improve interaction between
  16490.   *         screen-blanking and gpm (Stephen Rothwell); Linux 1.99.4
  16491. diff -u --recursive --new-file v2.0.34/linux/drivers/char/baycom.c linux/drivers/char/baycom.c
  16492. --- v2.0.34/linux/drivers/char/baycom.c    Mon Jul  8 00:21:45 1996
  16493. +++ linux/drivers/char/baycom.c    Mon Jul 13 13:47:29 1998
  16494. @@ -1,2327 +0,0 @@
  16495. -/*****************************************************************************/
  16496. -
  16497. -/*
  16498. - *    baycom.c  -- baycom ser12 and par96 radio modem driver.
  16499. - *
  16500. - *    Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
  16501. - *
  16502. - *    This program is free software; you can redistribute it and/or modify
  16503. - *    it under the terms of the GNU General Public License as published by
  16504. - *    the Free Software Foundation; either version 2 of the License, or
  16505. - *    (at your option) any later version.
  16506. - *
  16507. - *    This program is distributed in the hope that it will be useful,
  16508. - *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16509. - *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16510. - *    GNU General Public License for more details.
  16511. - *
  16512. - *    You should have received a copy of the GNU General Public License
  16513. - *    along with this program; if not, write to the Free Software
  16514. - *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16515. - *
  16516. - *  Please note that the GPL allows you to use the driver, NOT the radio.
  16517. - *  In order to use the radio, you need a license from the communications
  16518. - *  authority of your country.
  16519. - *
  16520. - *
  16521. - *  Supported modems
  16522. - *
  16523. - *  ser12: This is a very simple 1200 baud AFSK modem. The modem consists only
  16524. - *         of a modulator/demodulator chip, usually a TI TCM3105. The computer
  16525. - *         is responsible for regenerating the receiver bit clock, as well as
  16526. - *         for handling the HDLC protocol. The modem connects to a serial port,
  16527. - *         hence the name. Since the serial port is not used as an async serial
  16528. - *         port, the kernel driver for serial ports cannot be used, and this
  16529. - *         driver only supports standard serial hardware (8250, 16450, 16550)
  16530. - *  
  16531. - *  par96: This is a modem for 9600 baud FSK compatible to the G3RUH standard.
  16532. - *         The modem does all the filtering and regenerates the receiver clock.
  16533. - *         Data is transferred from and to the PC via a shift register.
  16534. - *         The shift register is filled with 16 bits and an interrupt is
  16535. - *         signalled. The PC then empties the shift register in a burst. This
  16536. - *         modem connects to the parallel port, hence the name. The modem
  16537. - *         leaves the implementation of the HDLC protocol and the scrambler
  16538. - *         polynomial to the PC.
  16539. - *  
  16540. - *  par97: This is a redesign of the par96 modem by Henning Rech, DF9IC. The
  16541. - *         modem is protocol compatible to par96, but uses only three low
  16542. - *         power ICs and can therefore be fed from the parallel port and
  16543. - *         does not require an additional power supply.
  16544. - *
  16545. - *
  16546. - *  Command line options (insmod command line)
  16547. - * 
  16548. - *  major    major number the driver should use; default 60 
  16549. - *  modem    modem type of the first channel (minor 0); 1=ser12,
  16550. - *           2=par96/par97, any other value invalid
  16551. - *  iobase   base address of the port; common values are for ser12 0x3f8,
  16552. - *           0x2f8, 0x3e8, 0x2e8 and for par96/par97 0x378, 0x278, 0x3bc
  16553. - *  irq      interrupt line of the port; common values are for ser12 3,4
  16554. - *           and for par96/par97 7
  16555. - *  options  0=use hardware DCD, 1=use software DCD
  16556. - * 
  16557. - *
  16558. - *  History:
  16559. - *   0.1  03.05.96  Renamed from ser12 0.5 and added support for par96
  16560. - *                  Various resource allocation cleanups
  16561. - *   0.2  12.05.96  Changed major to allocated 51. Integrated into kernel
  16562. - *                  source tree
  16563. - *   0.3  04.06.96  Major bug fixed (forgot to wake up after write) which
  16564. - *                  interestingly manifested only with kernel ax25
  16565. - *                  (the slip line discipline)
  16566. - *                  introduced bottom half and tq_baycom
  16567. - *                  HDLC processing now done with interrupts on
  16568. - */
  16569. -
  16570. -/*****************************************************************************/
  16571. -
  16572. -#include <linux/module.h>
  16573. -#include <linux/version.h>
  16574. -
  16575. -#include <linux/kernel.h>
  16576. -#include <linux/errno.h>
  16577. -#include <linux/fs.h>
  16578. -#include <linux/major.h>
  16579. -#include <asm/segment.h>
  16580. -#include <linux/kernel.h>
  16581. -#include <linux/signal.h>
  16582. -#include <linux/sched.h>
  16583. -#include <linux/malloc.h>
  16584. -#include <asm/io.h>
  16585. -#include <asm/irq.h>
  16586. -#include <linux/fs.h>
  16587. -#include <linux/mm.h>
  16588. -#include <linux/ioport.h>
  16589. -#include <linux/tty.h>
  16590. -#include <linux/tty_flip.h>
  16591. -#include <linux/interrupt.h>
  16592. -#include <linux/tqueue.h>
  16593. -#include <linux/baycom.h>
  16594. -
  16595. -/* --------------------------------------------------------------------- */
  16596. -
  16597. -#define BAYCOM_TYPE_NORMAL 0        /* not used */
  16598. -#define TTY_DRIVER_TYPE_BAYCOM 6
  16599. -
  16600. -/*
  16601. - * ser12 options:
  16602. - * BAYCOM_OPTIONS_SOFTDCD: if undefined, you must use the transmitters
  16603. - * hardware carrier detect circuitry, the driver will report DCD as soon as
  16604. - * there are transitions on the input line. Advantage: lower interrupt load
  16605. - * on the system. Disadvantage: slower, since hardware carrier detect
  16606. - * circuitry is usually slow.
  16607. - */
  16608. -
  16609. -#define BUFLEN_RX 8192
  16610. -#define BUFLEN_TX 8192
  16611. -
  16612. -#define NR_PORTS 4
  16613. -
  16614. -#define KISS_VERBOSE
  16615. -
  16616. -#define BAYCOM_MAGIC 0x3105bac0
  16617. -
  16618. -/* --------------------------------------------------------------------- */
  16619. -
  16620. -/*
  16621. - * user settable parameters (from the command line)
  16622. - */
  16623. -#ifndef MODULE
  16624. -static
  16625. -#endif /* MODULE */
  16626. -int major = BAYCOM_MAJOR;
  16627. -
  16628. -/* --------------------------------------------------------------------- */
  16629. -
  16630. -static struct tty_struct *baycom_table[NR_PORTS];
  16631. -static struct termios *baycom_termios[NR_PORTS];
  16632. -static struct termios *baycom_termios_locked[NR_PORTS];
  16633. -
  16634. -static int baycom_refcount;
  16635. -
  16636. -static struct tty_driver baycom_driver;
  16637. -
  16638. -static struct {
  16639. -    int modem, iobase, irq, options;
  16640. -} baycom_ports[NR_PORTS] = { { BAYCOM_MODEM_INVALID, 0, 0, 0, }, };
  16641. -
  16642. -/* --------------------------------------------------------------------- */
  16643. -
  16644. -#define RBR(iobase) (iobase+0)
  16645. -#define THR(iobase) (iobase+0)
  16646. -#define IER(iobase) (iobase+1)
  16647. -#define IIR(iobase) (iobase+2)
  16648. -#define FCR(iobase) (iobase+2)
  16649. -#define LCR(iobase) (iobase+3)
  16650. -#define MCR(iobase) (iobase+4)
  16651. -#define LSR(iobase) (iobase+5)
  16652. -#define MSR(iobase) (iobase+6)
  16653. -#define SCR(iobase) (iobase+7)
  16654. -#define DLL(iobase) (iobase+0)
  16655. -#define DLM(iobase) (iobase+1)
  16656. -
  16657. -#define SER12_EXTENT 8
  16658. -
  16659. -#define LPT_DATA(iobase)    (iobase+0)
  16660. -#define LPT_STATUS(iobase)  (iobase+1)
  16661. -#define LPT_CONTROL(iobase) (iobase+2)
  16662. -#define LPT_IRQ_ENABLE      0x10
  16663. -#define PAR96_BURSTBITS 16
  16664. -#define PAR96_BURST     4
  16665. -#define PAR96_PTT       2
  16666. -#define PAR96_TXBIT     1
  16667. -#define PAR96_ACK       0x40
  16668. -#define PAR96_RXBIT     0x20
  16669. -#define PAR96_DCD       0x10
  16670. -#define PAR97_POWER     0xf8
  16671. -
  16672. -#define PAR96_EXTENT 3
  16673. -
  16674. -/* ---------------------------------------------------------------------- */
  16675. -
  16676. -struct access_params {
  16677. -    int tx_delay;
  16678. -    int tx_tail;
  16679. -    int slottime;
  16680. -    int ppersist;
  16681. -    int fulldup;
  16682. -};
  16683. -
  16684. -struct hdlc_state_rx {
  16685. -    int rx_state;    /* 0 = sync hunt, != 0 receiving */
  16686. -    unsigned int bitstream;
  16687. -    unsigned int bitbuf;
  16688. -    int numbits;
  16689. -    unsigned int shreg1, shreg2;
  16690. -
  16691. -    int len;
  16692. -    unsigned char *bp;
  16693. -    unsigned char buffer[BAYCOM_MAXFLEN+2];       /* make room for CRC */
  16694. -};
  16695. -
  16696. -struct hdlc_state_tx {
  16697. -    /*
  16698. -     * 0 = send flags
  16699. -     * 1 = send txtail (flags)
  16700. -     * 2 = send packet
  16701. -     */
  16702. -    int tx_state;    
  16703. -    int numflags;
  16704. -    unsigned int bitstream;
  16705. -    unsigned int current_byte;
  16706. -    unsigned char ptt;
  16707. -
  16708. -    unsigned int bitbuf;
  16709. -    int numbits;
  16710. -    unsigned int shreg1, shreg2;
  16711. -
  16712. -    int len;
  16713. -    unsigned char *bp;
  16714. -    unsigned char buffer[BAYCOM_MAXFLEN+2];        /* make room for CRC */
  16715. -};
  16716. -
  16717. -struct modem_state_ser12 {
  16718. -    unsigned char last_sample;
  16719. -    unsigned char interm_sample;
  16720. -    unsigned int bit_pll;
  16721. -    unsigned int dcd_shreg;
  16722. -    int dcd_sum0, dcd_sum1, dcd_sum2;
  16723. -    unsigned int dcd_time;
  16724. -    unsigned char last_rxbit;
  16725. -    unsigned char tx_bit;
  16726. -};
  16727. -
  16728. -struct modem_state_par96 {
  16729. -    int dcd_count;
  16730. -    unsigned int dcd_shreg;
  16731. -    unsigned long descram;
  16732. -    unsigned long scram;
  16733. -};
  16734. -
  16735. -struct modem_state {
  16736. -    unsigned char dcd;
  16737. -    short arb_divider;
  16738. -    unsigned char flags;
  16739. -    struct modem_state_ser12 ser12;
  16740. -    struct modem_state_par96 par96;
  16741. -};
  16742. -
  16743. -struct packet_buffer {
  16744. -    unsigned int rd;
  16745. -    unsigned int wr;
  16746. -    
  16747. -    unsigned int buflen;
  16748. -    unsigned char *buffer;
  16749. -};
  16750. -
  16751. -struct packet_hdr {
  16752. -    unsigned int next;
  16753. -    unsigned int len;
  16754. -    /* packet following */
  16755. -};
  16756. -
  16757. -#ifdef BAYCOM_DEBUG
  16758. -struct bit_buffer {
  16759. -    unsigned int rd;
  16760. -    unsigned int wr;
  16761. -    unsigned int shreg;
  16762. -    unsigned char buffer[64];
  16763. -};
  16764. -
  16765. -struct debug_vals {
  16766. -    unsigned long last_jiffies;
  16767. -    unsigned cur_intcnt;
  16768. -    unsigned last_intcnt;
  16769. -    int cur_pllcorr;
  16770. -    int last_pllcorr;
  16771. -};
  16772. -#endif /* BAYCOM_DEBUG */
  16773. -
  16774. -struct kiss_decode {
  16775. -    unsigned char dec_state; /* 0 = hunt FEND */
  16776. -    unsigned char escaped;
  16777. -    unsigned char pkt_buf[BAYCOM_MAXFLEN+1];
  16778. -    unsigned int wr;
  16779. -};
  16780. -
  16781. -/* ---------------------------------------------------------------------- */
  16782. -
  16783. -struct baycom_state {
  16784. -    int magic;
  16785. -
  16786. -    unsigned char modem_type;
  16787. -
  16788. -    unsigned int iobase;
  16789. -    unsigned int irq;
  16790. -    unsigned int options;
  16791. -
  16792. -    int opened;
  16793. -    struct tty_struct *tty;
  16794. -
  16795. -#ifdef BAYCOM_USE_BH
  16796. -    struct tq_struct tq_receiver, tq_transmitter, tq_arbitrate;
  16797. -#endif /* BAYCOM_USE_BH */
  16798. -
  16799. -    struct packet_buffer rx_buf;
  16800. -    struct packet_buffer tx_buf;
  16801. -
  16802. -    struct access_params ch_params;
  16803. -
  16804. -    struct hdlc_state_rx hdlc_rx;
  16805. -    struct hdlc_state_tx hdlc_tx;
  16806. -
  16807. -    int calibrate;
  16808. -
  16809. -    struct modem_state modem;
  16810. -
  16811. -#ifdef BAYCOM_DEBUG
  16812. -    struct bit_buffer bitbuf_channel;
  16813. -    struct bit_buffer bitbuf_hdlc;
  16814. -    
  16815. -    struct debug_vals debug_vals;
  16816. -#endif /* BAYCOM_DEBUG */
  16817. -
  16818. -    struct kiss_decode kiss_decode;
  16819. -
  16820. -    struct baycom_statistics stat;
  16821. -};
  16822. -
  16823. -/* --------------------------------------------------------------------- */
  16824. -
  16825. -struct baycom_state baycom_state[NR_PORTS];
  16826. -
  16827. -#ifdef BAYCOM_USE_BH
  16828. -DECLARE_TASK_QUEUE(tq_baycom);
  16829. -#endif /* BAYCOM_USE_BH */
  16830. -
  16831. -/* --------------------------------------------------------------------- */
  16832. -
  16833. -/*
  16834. - * the CRC routines are stolen from WAMPES
  16835. - * by Dieter Deyke
  16836. - */
  16837. -
  16838. -static const unsigned short crc_ccitt_table[] = {
  16839. -    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
  16840. -    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
  16841. -    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
  16842. -    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
  16843. -    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
  16844. -    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
  16845. -    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
  16846. -    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
  16847. -    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
  16848. -    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
  16849. -    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
  16850. -    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
  16851. -    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
  16852. -    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
  16853. -    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
  16854. -    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
  16855. -    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
  16856. -    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
  16857. -    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
  16858. -    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
  16859. -    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
  16860. -    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
  16861. -    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
  16862. -    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
  16863. -    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
  16864. -    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
  16865. -    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
  16866. -    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
  16867. -    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
  16868. -    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
  16869. -    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
  16870. -    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
  16871. -};
  16872. -
  16873. -/*---------------------------------------------------------------------------*/
  16874. -
  16875. -static inline void append_crc_ccitt(unsigned char *buffer, int len)
  16876. -{
  16877. -     unsigned int crc = 0xffff;
  16878. -
  16879. -    for (;len>0;len--)
  16880. -        crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buffer++) & 0xff];
  16881. -    crc ^= 0xffff;
  16882. -    *buffer++ = crc;
  16883. -    *buffer++ = crc >> 8;
  16884. -}
  16885. -
  16886. -/*---------------------------------------------------------------------------*/
  16887. -
  16888. -static inline int check_crc_ccitt(const unsigned char *buf,int cnt)
  16889. -{
  16890. -    unsigned int crc = 0xffff;
  16891. -
  16892. -    for (; cnt > 0; cnt--)
  16893. -        crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
  16894. -    return (crc & 0xffff) == 0xf0b8;
  16895. -}
  16896. -
  16897. -/*---------------------------------------------------------------------------*/
  16898. -
  16899. -#if 0
  16900. -static int calc_crc_ccitt(const unsigned char *buf,int cnt)
  16901. -{
  16902. -    unsigned int crc = 0xffff;
  16903. -
  16904. -    for (; cnt > 0; cnt--)
  16905. -        crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
  16906. -    crc ^= 0xffff;
  16907. -    return (crc & 0xffff);
  16908. -}
  16909. -#endif
  16910. -
  16911. -/* ---------------------------------------------------------------------- */
  16912. -
  16913. -static int store_packet(struct packet_buffer *buf, unsigned char *data,
  16914. -    char from_user, unsigned int len)
  16915. -{
  16916. -    unsigned int free;
  16917. -    struct packet_hdr *hdr;
  16918. -    unsigned int needed = sizeof(struct packet_hdr)+len;
  16919. -    
  16920. -    free = buf->rd-buf->wr;
  16921. -    if(buf->rd <= buf->wr) {
  16922. -        free = buf->buflen - buf->wr;
  16923. -        if((free < needed) && (buf->rd >= needed)) {
  16924. -            hdr = (struct packet_hdr *)(buf->buffer+buf->wr);
  16925. -            hdr->next = 0;
  16926. -            hdr->len = 0;
  16927. -            buf->wr = 0;
  16928. -            free = buf->rd;
  16929. -        }
  16930. -    }
  16931. -    if(free < needed) return 0;        /* buffer overrun */
  16932. -    hdr = (struct packet_hdr *)(buf->buffer+buf->wr);
  16933. -    if (from_user) 
  16934. -        memcpy_fromfs(hdr+1,data,len);
  16935. -    else
  16936. -        memcpy(hdr+1,data,len);
  16937. -    hdr->len = len;
  16938. -    hdr->next = buf->wr+needed;
  16939. -    if (hdr->next + sizeof(struct packet_hdr) >= buf->buflen)
  16940. -        hdr->next = 0;
  16941. -    buf->wr = hdr->next;
  16942. -    return 1;
  16943. -}
  16944. -    
  16945. -/* ---------------------------------------------------------------------- */
  16946. -
  16947. -static void get_packet(struct packet_buffer *buf, unsigned char **data,
  16948. -    unsigned int *len)
  16949. -{
  16950. -    struct packet_hdr *hdr;
  16951. -    
  16952. -    *data = NULL;
  16953. -    *len = 0;
  16954. -    if (buf->rd == buf->wr)
  16955. -        return;
  16956. -    hdr = (struct packet_hdr *)(buf->buffer+buf->rd);
  16957. -    while (!(hdr->len)) {
  16958. -        buf->rd = hdr->next;
  16959. -        if (buf->rd == buf->wr)
  16960. -            return;
  16961. -        hdr = (struct packet_hdr *)(buf->buffer+buf->rd);
  16962. -    }
  16963. -    *data = (unsigned char *)(hdr+1);
  16964. -    *len = hdr->len;
  16965. -}
  16966. -
  16967. -/* ---------------------------------------------------------------------- */
  16968. -
  16969. -static void ack_packet(struct packet_buffer *buf)
  16970. -{
  16971. -    struct packet_hdr *hdr;
  16972. -    
  16973. -    if (buf->rd == buf->wr)
  16974. -        return;
  16975. -    hdr = (struct packet_hdr *)(buf->buffer+buf->rd);
  16976. -    buf->rd = hdr->next;
  16977. -}
  16978. -
  16979. -/* ---------------------------------------------------------------------- */
  16980. -
  16981. -static int store_kiss_packet(struct packet_buffer *buf, unsigned char *data,
  16982. -    unsigned int len)
  16983. -{
  16984. -    unsigned char *bp = data;
  16985. -    int ln = len;
  16986. -    /*
  16987. -     * variables of buf
  16988. -     */
  16989. -    unsigned int rd;
  16990. -    unsigned int wr;
  16991. -    unsigned int buflen;
  16992. -    unsigned char *buffer;
  16993. -
  16994. -    if (!len || !data || !buf)
  16995. -        return 0;
  16996. -    buflen = buf->buflen;
  16997. -    rd = buf->rd;
  16998. -    wr = buf->wr;
  16999. -    buffer = buf->buffer;
  17000. -    
  17001. -#define ADD_CHAR(c) {\
  17002. -        buffer[wr++] = c;\
  17003. -        if (wr >= buflen) wr = 0;\
  17004. -        if (wr == rd) return 0;\
  17005. -    }
  17006. -#define ADD_KISSCHAR(c) {\
  17007. -        if (((c) & 0xff) == KISS_FEND) {\
  17008. -            ADD_CHAR(KISS_FESC);\
  17009. -            ADD_CHAR(KISS_TFEND);\
  17010. -        } else if (((c) & 0xff) == KISS_FESC) {\
  17011. -            ADD_CHAR(KISS_FESC);\
  17012. -            ADD_CHAR(KISS_TFESC);\
  17013. -        } else {\
  17014. -            ADD_CHAR(c);\
  17015. -        }\
  17016. -    }
  17017. -
  17018. -    ADD_CHAR(KISS_FEND);
  17019. -    ADD_KISSCHAR(KISS_CMD_DATA);
  17020. -    for(; ln > 0; ln--,bp++) {
  17021. -        ADD_KISSCHAR(*bp);
  17022. -    }
  17023. -    ADD_CHAR(KISS_FEND);
  17024. -    buf->wr = wr;
  17025. -#undef ADD_CHAR
  17026. -#undef ADD_KISSCHAR
  17027. -    return 1;
  17028. -}
  17029. -
  17030. -/* ---------------------------------------------------------------------- */
  17031. -
  17032. -#ifdef BAYCOM_DEBUG
  17033. -static inline void add_bitbuffer(struct bit_buffer * buf, unsigned int bit)
  17034. -{
  17035. -    unsigned char new;
  17036. -
  17037. -    if (!buf) return;
  17038. -    new = buf->shreg & 1;
  17039. -    buf->shreg >>= 1;
  17040. -    if (bit)
  17041. -        buf->shreg |= 0x80;
  17042. -    if (new) {
  17043. -        buf->buffer[buf->wr] = buf->shreg;
  17044. -        buf->wr = (buf->wr+1) % sizeof(buf->buffer);
  17045. -        buf->shreg = 0x80;
  17046. -    }
  17047. -}
  17048. -
  17049. -static inline void add_bitbuffer_word(struct bit_buffer * buf, 
  17050. -                      unsigned int bits)
  17051. -{
  17052. -    buf->buffer[buf->wr] = bits & 0xff;
  17053. -    buf->wr = (buf->wr+1) % sizeof(buf->buffer);
  17054. -    buf->buffer[buf->wr] = (bits >> 8) & 0xff;
  17055. -    buf->wr = (buf->wr+1) % sizeof(buf->buffer);
  17056. -
  17057. -}
  17058. -#endif /* BAYCOM_DEBUG */
  17059. -
  17060. -/* ---------------------------------------------------------------------- */
  17061. -
  17062. -static inline unsigned int tenms_to_2flags(struct baycom_state *bc, 
  17063. -                      unsigned int tenms)
  17064. -{
  17065. -    switch (bc->modem_type) {
  17066. -    case BAYCOM_MODEM_SER12:
  17067. -        return tenms * 3 / 4;
  17068. -    case BAYCOM_MODEM_PAR96:
  17069. -        return tenms * 6;
  17070. -    default:
  17071. -        return 0;
  17072. -    }
  17073. -}
  17074. -
  17075. -/* ---------------------------------------------------------------------- */
  17076. -/*
  17077. - * The HDLC routines
  17078. - */
  17079. -
  17080. -static inline int hdlc_rx_add_bytes(struct baycom_state *bc, 
  17081. -                    unsigned int bits, int num)
  17082. -{
  17083. -    int added = 0;
  17084. -    while (bc->hdlc_rx.rx_state && num >= 8) {
  17085. -        if (bc->hdlc_rx.len >= sizeof(bc->hdlc_rx.buffer)) {
  17086. -            bc->hdlc_rx.rx_state = 0;
  17087. -            return 0;
  17088. -        }
  17089. -        *bc->hdlc_rx.bp++ = bits >> (32-num);
  17090. -        bc->hdlc_rx.len++;
  17091. -        num -= 8;
  17092. -        added += 8;
  17093. -    }
  17094. -    return added;
  17095. -}
  17096. -
  17097. -static inline void hdlc_rx_flag(struct baycom_state *bc)
  17098. -{
  17099. -    if (bc->hdlc_rx.len < 4) 
  17100. -        return;
  17101. -    if (!check_crc_ccitt(bc->hdlc_rx.buffer, bc->hdlc_rx.len)) 
  17102. -        return;
  17103. -           bc->stat.rx_packets++;
  17104. -    if (!store_kiss_packet(&bc->rx_buf,
  17105. -                   bc->hdlc_rx.buffer,
  17106. -                   bc->hdlc_rx.len-2))
  17107. -        bc->stat.rx_bufferoverrun++;
  17108. -}
  17109. -
  17110. -static void hdlc_rx_word(struct baycom_state *bc, unsigned int word)
  17111. -{
  17112. -    int i;
  17113. -    unsigned int mask1, mask2, mask3, mask4, mask5, mask6;
  17114. -    
  17115. -    if (!bc) return;
  17116. -
  17117. -    word &= 0xffff;
  17118. -#ifdef BAYCOM_DEBUG
  17119. -    add_bitbuffer_word(&bc->bitbuf_hdlc, word);
  17120. -#endif /* BAYCOM_DEBUG */
  17121. -           bc->hdlc_rx.bitstream >>= 16;
  17122. -    bc->hdlc_rx.bitstream |= word << 16;
  17123. -    bc->hdlc_rx.bitbuf >>= 16;
  17124. -    bc->hdlc_rx.bitbuf |= word << 16;
  17125. -    bc->hdlc_rx.numbits += 16;
  17126. -    for(i = 15, mask1 = 0x1fc00, mask2 = 0x1fe00, mask3 = 0x0fc00,
  17127. -        mask4 = 0x1f800, mask5 = 0xf800, mask6 = 0xffff; 
  17128. -        i >= 0; 
  17129. -        i--, mask1 <<= 1, mask2 <<= 1, mask3 <<= 1, mask4 <<= 1, 
  17130. -        mask5 <<= 1, mask6 = (mask6 << 1) | 1) {
  17131. -        if ((bc->hdlc_rx.bitstream & mask1) == mask1)
  17132. -            bc->hdlc_rx.rx_state = 0; /* abort received */
  17133. -        else if ((bc->hdlc_rx.bitstream & mask2) == mask3) {
  17134. -            /* flag received */
  17135. -            if (bc->hdlc_rx.rx_state) {
  17136. -                hdlc_rx_add_bytes(bc, bc->hdlc_rx.bitbuf << 
  17137. -                          (8 + i), bc->hdlc_rx.numbits
  17138. -                          - 8 - i);
  17139. -                hdlc_rx_flag(bc);
  17140. -            }
  17141. -            bc->hdlc_rx.len = 0;
  17142. -            bc->hdlc_rx.bp = bc->hdlc_rx.buffer;
  17143. -            bc->hdlc_rx.rx_state = 1;
  17144. -            bc->hdlc_rx.numbits = i;
  17145. -        } else if ((bc->hdlc_rx.bitstream & mask4) == mask5) {
  17146. -            /* stuffed bit */
  17147. -            bc->hdlc_rx.numbits--;
  17148. -            bc->hdlc_rx.bitbuf = (bc->hdlc_rx.bitbuf & (~mask6)) |
  17149. -                ((bc->hdlc_rx.bitbuf & mask6) << 1);
  17150. -        }
  17151. -    }
  17152. -    bc->hdlc_rx.numbits -= hdlc_rx_add_bytes(bc, bc->hdlc_rx.bitbuf,
  17153. -                         bc->hdlc_rx.numbits);
  17154. -}
  17155. -
  17156. -/* ---------------------------------------------------------------------- */
  17157. -
  17158. -static unsigned int hdlc_tx_word(struct baycom_state *bc)
  17159. -{
  17160. -    unsigned int mask1, mask2, mask3;
  17161. -    int i;
  17162. -
  17163. -    if (!bc || !bc->hdlc_tx.ptt)
  17164. -        return 0;
  17165. -    for (;;) {
  17166. -        if (bc->hdlc_tx.numbits >= 16) {
  17167. -            unsigned int ret = bc->hdlc_tx.bitbuf & 0xffff;
  17168. -            bc->hdlc_tx.bitbuf >>= 16;
  17169. -            bc->hdlc_tx.numbits -= 16;
  17170. -            return ret;
  17171. -        }
  17172. -        switch (bc->hdlc_tx.tx_state) {
  17173. -        default:
  17174. -            bc->hdlc_tx.ptt = 0;
  17175. -            bc->hdlc_tx.tx_state = 0;
  17176. -            return 0;
  17177. -        case 0:
  17178. -        case 1:
  17179. -            if (bc->hdlc_tx.numflags) {
  17180. -                bc->hdlc_tx.numflags--;
  17181. -                bc->hdlc_tx.bitbuf |= 
  17182. -                    0x7e7e << bc->hdlc_tx.numbits;
  17183. -                bc->hdlc_tx.numbits += 16;
  17184. -                break;
  17185. -            }
  17186. -            if (bc->hdlc_tx.tx_state == 1) {
  17187. -                bc->hdlc_tx.ptt = 0;
  17188. -                return 0;
  17189. -            }
  17190. -            get_packet(&bc->tx_buf, &bc->hdlc_tx.bp,
  17191. -                   &bc->hdlc_tx.len);
  17192. -            if (!bc->hdlc_tx.bp || !bc->hdlc_tx.len) {
  17193. -                bc->hdlc_tx.tx_state = 1;
  17194. -                bc->hdlc_tx.numflags = tenms_to_2flags
  17195. -                    (bc, bc->ch_params.tx_tail);
  17196. -                break;
  17197. -            }
  17198. -            if (bc->hdlc_tx.len >= BAYCOM_MAXFLEN) {
  17199. -                bc->hdlc_tx.tx_state = 0;
  17200. -                bc->hdlc_tx.numflags = 1;
  17201. -                ack_packet(&bc->tx_buf);
  17202. -                break;
  17203. -            }
  17204. -            memcpy(bc->hdlc_tx.buffer, bc->hdlc_tx.bp, 
  17205. -                   bc->hdlc_tx.len);
  17206. -            ack_packet(&bc->tx_buf);
  17207. -            bc->hdlc_tx.bp = bc->hdlc_tx.buffer;
  17208. -            append_crc_ccitt(bc->hdlc_tx.buffer, bc->hdlc_tx.len);
  17209. -            /* the appended CRC */
  17210. -            bc->hdlc_tx.len += 2; 
  17211. -            bc->hdlc_tx.tx_state = 2;
  17212. -            bc->hdlc_tx.bitstream = 0;
  17213. -            bc->stat.tx_packets++;
  17214. -            break;
  17215. -        case 2:
  17216. -            if (!bc->hdlc_tx.len) {
  17217. -                bc->hdlc_tx.tx_state = 0;
  17218. -                bc->hdlc_tx.numflags = 1;
  17219. -                break;
  17220. -            }
  17221. -            bc->hdlc_tx.len--;
  17222. -            bc->hdlc_tx.bitbuf |= *bc->hdlc_tx.bp <<
  17223. -                bc->hdlc_tx.numbits;
  17224. -            bc->hdlc_tx.bitstream >>= 8;
  17225. -            bc->hdlc_tx.bitstream |= (*bc->hdlc_tx.bp++) << 16;
  17226. -            mask1 = 0x1f000;
  17227. -            mask2 = 0x10000;
  17228. -            mask3 = 0xffffffff >> (31-bc->hdlc_tx.numbits);
  17229. -            bc->hdlc_tx.numbits += 8;
  17230. -            for(i = 0; i < 8; i++, mask1 <<= 1, mask2 <<= 1, 
  17231. -                mask3 = (mask3 << 1) | 1) {
  17232. -                if ((bc->hdlc_tx.bitstream & mask1) != mask1) 
  17233. -                    continue;
  17234. -                bc->hdlc_tx.bitstream &= ~mask2;
  17235. -                bc->hdlc_tx.bitbuf = 
  17236. -                    (bc->hdlc_tx.bitbuf & mask3) |
  17237. -                        ((bc->hdlc_tx.bitbuf & 
  17238. -                         (~mask3)) << 1);
  17239. -                bc->hdlc_tx.numbits++;
  17240. -                mask3 = (mask3 << 1) | 1;
  17241. -            }
  17242. -            break;
  17243. -        }
  17244. -    }
  17245. -}
  17246. -
  17247. -/* ---------------------------------------------------------------------- */
  17248. -
  17249. -static unsigned short random_seed;
  17250. -
  17251. -static inline unsigned short random_num(void)
  17252. -{
  17253. -    random_seed = 28629 * random_seed + 157;
  17254. -    return random_seed;
  17255. -}
  17256. -
  17257. -/* ---------------------------------------------------------------------- */
  17258. -
  17259. -static inline void tx_arbitrate(struct baycom_state *bc)
  17260. -{
  17261. -    unsigned char *bp;
  17262. -    unsigned int len;
  17263. -    
  17264. -    if (!bc || bc->hdlc_tx.ptt || bc->modem.dcd)
  17265. -        return;
  17266. -    get_packet(&bc->tx_buf, &bp, &len);
  17267. -    if (!bp || !len)
  17268. -        return;
  17269. -    
  17270. -    if (!bc->ch_params.fulldup) {
  17271. -        if ((random_num() % 256) > bc->ch_params.ppersist)
  17272. -            return;
  17273. -    }
  17274. -    bc->hdlc_tx.tx_state = 0;
  17275. -    bc->hdlc_tx.numflags = tenms_to_2flags(bc, bc->ch_params.tx_delay);
  17276. -    bc->hdlc_tx.numbits = bc->hdlc_tx.bitbuf = bc->hdlc_tx.bitstream = 0;
  17277. -    bc->hdlc_tx.ptt = 1;
  17278. -    bc->stat.ptt_keyed++;
  17279. -}
  17280. -
  17281. -/* --------------------------------------------------------------------- */
  17282. -
  17283. -#ifdef BAYCOM_DEBUG
  17284. -static void inline baycom_int_freq(struct baycom_state *bc)
  17285. -{
  17286. -    unsigned long cur_jiffies = jiffies;
  17287. -    /* 
  17288. -     * measure the interrupt frequency
  17289. -     */
  17290. -    bc->debug_vals.cur_intcnt++;
  17291. -    if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) {
  17292. -        bc->debug_vals.last_jiffies = cur_jiffies;
  17293. -        bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
  17294. -        bc->debug_vals.cur_intcnt = 0;
  17295. -        bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
  17296. -        bc->debug_vals.cur_pllcorr = 0;
  17297. -    }
  17298. -}
  17299. -#endif /* BAYCOM_DEBUG */
  17300. -
  17301. -/* --------------------------------------------------------------------- */
  17302. -
  17303. -static inline void rx_chars_to_flip(struct baycom_state *bc) 
  17304. -{
  17305. -    int flip_free;
  17306. -    unsigned int cnt;
  17307. -    unsigned int new_rd;
  17308. -    unsigned long flags;
  17309. -
  17310. -    if ((!bc) || (!bc->tty) || (bc->tty->flip.count >= TTY_FLIPBUF_SIZE) ||
  17311. -        (bc->rx_buf.rd == bc->rx_buf.wr) || 
  17312. -        (!bc->tty->flip.char_buf_ptr) ||
  17313. -        (!bc->tty->flip.flag_buf_ptr))
  17314. -        return;
  17315. -    for(;;) {
  17316. -        flip_free = TTY_FLIPBUF_SIZE - bc->tty->flip.count;
  17317. -        if (bc->rx_buf.rd <= bc->rx_buf.wr)
  17318. -            cnt = bc->rx_buf.wr - bc->rx_buf.rd;
  17319. -        else
  17320. -            cnt = bc->rx_buf.buflen - bc->rx_buf.rd;
  17321. -        if ((flip_free <= 0) || (!cnt)) {
  17322. -            tty_schedule_flip(bc->tty);
  17323. -            return;
  17324. -        }
  17325. -        if (cnt > flip_free)
  17326. -            cnt = flip_free;
  17327. -        save_flags(flags); cli();
  17328. -        memcpy(bc->tty->flip.char_buf_ptr, bc->rx_buf.buffer+bc->rx_buf.rd, cnt);
  17329. -        memset(bc->tty->flip.flag_buf_ptr, TTY_NORMAL, cnt);
  17330. -        bc->tty->flip.count += cnt;
  17331. -        bc->tty->flip.char_buf_ptr += cnt;
  17332. -        bc->tty->flip.flag_buf_ptr += cnt;
  17333. -        restore_flags(flags);
  17334. -        new_rd = bc->rx_buf.rd+cnt;
  17335. -        if (new_rd >= bc->rx_buf.buflen)
  17336. -            new_rd -= bc->rx_buf.buflen;
  17337. -        bc->rx_buf.rd = new_rd;
  17338. -    }
  17339. -}
  17340. -
  17341. -/* --------------------------------------------------------------------- */
  17342. -/*
  17343. - * ===================== SER12 specific routines =========================
  17344. - */
  17345. -
  17346. -static void inline ser12_set_divisor(struct baycom_state *bc, 
  17347. -                     unsigned char divisor)
  17348. -{
  17349. -    outb(0x81, LCR(bc->iobase));    /* DLAB = 1 */
  17350. -    outb(divisor, DLL(bc->iobase));
  17351. -    outb(0, DLM(bc->iobase));
  17352. -    outb(0x01, LCR(bc->iobase));    /* word length = 6 */
  17353. -}
  17354. -
  17355. -/* --------------------------------------------------------------------- */
  17356. -
  17357. -/*
  17358. - * must call the TX arbitrator every 10ms
  17359. - */
  17360. -#define SER12_ARB_DIVIDER(bc) ((bc->options & BAYCOM_OPTIONS_SOFTDCD) ? \
  17361. -                   36 : 24)
  17362. -#define SER12_DCD_INTERVAL(bc) ((bc->options & BAYCOM_OPTIONS_SOFTDCD) ? \
  17363. -                240 : 12)
  17364. -
  17365. -static void baycom_ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  17366. -{
  17367. -    struct baycom_state *bc = (struct baycom_state *)dev_id;
  17368. -    unsigned char cur_s;
  17369. -    
  17370. -    if (!bc || bc->magic != BAYCOM_MAGIC)
  17371. -        return;
  17372. -    /*
  17373. -     * make sure the next interrupt is generated;
  17374. -     * 0 must be used to power the modem; the modem draws its
  17375. -     * power from the TxD line
  17376. -     */    
  17377. -    outb(0x00, THR(bc->iobase));
  17378. -    rx_chars_to_flip(bc);
  17379. -#ifdef BAYCOM_DEBUG
  17380. -    baycom_int_freq(bc);
  17381. -#endif /* BAYCOM_DEBUG */
  17382. -    /*
  17383. -     * check if transmitter active
  17384. -     */
  17385. -    if (bc->hdlc_tx.ptt || bc->calibrate > 0) {
  17386. -        ser12_set_divisor(bc, 12); /* one interrupt per channel bit */
  17387. -        /*
  17388. -         * first output the last bit (!) then call HDLC transmitter,
  17389. -         * since this may take quite long
  17390. -         */
  17391. -        outb(0x0e | (bc->modem.ser12.tx_bit ? 1 : 0), MCR(bc->iobase));
  17392. -        if (bc->hdlc_tx.shreg1 <= 1) {
  17393. -            if (bc->calibrate > 0) {
  17394. -                bc->hdlc_tx.shreg1 = 0x10000;
  17395. -                bc->calibrate--;
  17396. -            } else {
  17397. -#ifdef BAYCOM_USE_BH
  17398. -                bc->hdlc_tx.shreg1 = bc->hdlc_tx.shreg2;
  17399. -                bc->hdlc_tx.shreg2 = 0;
  17400. -                queue_task_irq_off(&bc->tq_transmitter, 
  17401. -                           &tq_baycom);
  17402. -                mark_bh(BAYCOM_BH);
  17403. -#ifdef HDLC_LOOPBACK
  17404. -                bc->hdlc_rx.shreg2 = bc->hdlc_tx.shreg1;
  17405. -                queue_task_irq_off(&bc->tq_receiver, 
  17406. -                           &tq_baycom);
  17407. -#endif /* HDLC_LOOPBACK */
  17408. -#else /* BAYCOM_USE_BH */
  17409. -                bc->hdlc_tx.shreg1 = hdlc_tx_word(bc) 
  17410. -                    | 0x10000;
  17411. -#ifdef HDLC_LOOPBACK
  17412. -                hdlc_rx_word(bc, bc->hdlc_tx.shreg1);
  17413. -#endif /* HDLC_LOOPBACK */
  17414. -#endif /* BAYCOM_USE_BH */
  17415. -            }    
  17416. -        }
  17417. -        if (!(bc->hdlc_tx.shreg1 & 1))
  17418. -            bc->modem.ser12.tx_bit = !bc->modem.ser12.tx_bit;
  17419. -        bc->hdlc_tx.shreg1 >>= 1;
  17420. -        return;
  17421. -    }
  17422. -    /*
  17423. -     * do demodulator
  17424. -     */
  17425. -    outb(0x0d, MCR(bc->iobase));            /* transmitter off */
  17426. -    cur_s = inb(MSR(bc->iobase)) & 0x10;    /* the CTS line */
  17427. -#ifdef BAYCOM_DEBUG
  17428. -    add_bitbuffer(&bc->bitbuf_channel, cur_s);
  17429. -#endif /* BAYCOM_DEBUG */
  17430. -    bc->modem.ser12.dcd_shreg <<= 1;
  17431. -    if(cur_s != bc->modem.ser12.last_sample) {
  17432. -        bc->modem.ser12.dcd_shreg |= 1;
  17433. -
  17434. -        if (bc->options & BAYCOM_OPTIONS_SOFTDCD) {
  17435. -            unsigned int dcdspos, dcdsneg;
  17436. -
  17437. -            dcdspos = dcdsneg = 0;
  17438. -            dcdspos += ((bc->modem.ser12.dcd_shreg >> 1) & 1);
  17439. -            if (!(bc->modem.ser12.dcd_shreg & 0x7ffffffe))
  17440. -                dcdspos += 2;
  17441. -            dcdsneg += ((bc->modem.ser12.dcd_shreg >> 2) & 1);
  17442. -            dcdsneg += ((bc->modem.ser12.dcd_shreg >> 3) & 1);
  17443. -            dcdsneg += ((bc->modem.ser12.dcd_shreg >> 4) & 1);
  17444. -
  17445. -            bc->modem.ser12.dcd_sum0 += 16*dcdspos - dcdsneg;
  17446. -        } else
  17447. -            bc->modem.ser12.dcd_sum0--;
  17448. -    }
  17449. -    bc->modem.ser12.last_sample = cur_s;
  17450. -    if(!bc->modem.ser12.dcd_time) {
  17451. -        bc->modem.dcd = (bc->modem.ser12.dcd_sum0 + 
  17452. -                 bc->modem.ser12.dcd_sum1 +
  17453. -                 bc->modem.ser12.dcd_sum2) < 0;
  17454. -        bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
  17455. -        bc->modem.ser12.dcd_sum1 = bc->modem.ser12.dcd_sum0;
  17456. -        /* offset to ensure DCD off on silent input */
  17457. -        bc->modem.ser12.dcd_sum0 = 2;
  17458. -        bc->modem.ser12.dcd_time = SER12_DCD_INTERVAL(bc);
  17459. -    }
  17460. -    bc->modem.ser12.dcd_time--;
  17461. -    if (bc->options & BAYCOM_OPTIONS_SOFTDCD) {
  17462. -        /*
  17463. -         * PLL code for the improved software DCD algorithm
  17464. -         */
  17465. -        if (bc->modem.ser12.interm_sample) {
  17466. -            /*
  17467. -             * intermediate sample; set timing correction to normal
  17468. -             */
  17469. -            ser12_set_divisor(bc, 4);
  17470. -        } else {
  17471. -            /*
  17472. -             * do PLL correction and call HDLC receiver
  17473. -             */
  17474. -            switch (bc->modem.ser12.dcd_shreg & 7) {
  17475. -            case 1: /* transition too late */
  17476. -                ser12_set_divisor(bc, 5);
  17477. -#ifdef BAYCOM_DEBUG
  17478. -                bc->debug_vals.cur_pllcorr++;
  17479. -#endif /* BAYCOM_DEBUG */
  17480. -                break;
  17481. -            case 4:    /* transition too early */
  17482. -                ser12_set_divisor(bc, 3);
  17483. -#ifdef BAYCOM_DEBUG
  17484. -                bc->debug_vals.cur_pllcorr--;
  17485. -#endif /* BAYCOM_DEBUG */
  17486. -                break;
  17487. -            default:
  17488. -                ser12_set_divisor(bc, 4);
  17489. -                break;
  17490. -            }
  17491. -            bc->hdlc_rx.shreg1 >>= 1;
  17492. -            if (bc->modem.ser12.last_sample == 
  17493. -                bc->modem.ser12.last_rxbit)
  17494. -                bc->hdlc_rx.shreg1 |= 0x10000;
  17495. -            bc->modem.ser12.last_rxbit = 
  17496. -                bc->modem.ser12.last_sample;
  17497. -        }
  17498. -        if (++bc->modem.ser12.interm_sample >= 3)
  17499. -            bc->modem.ser12.interm_sample = 0;        
  17500. -    } else {
  17501. -        /*
  17502. -         * PLL algorithm for the hardware squelch DCD algorithm
  17503. -         */
  17504. -        if (bc->modem.ser12.interm_sample) {
  17505. -            /*
  17506. -             * intermediate sample; set timing correction to normal
  17507. -             */
  17508. -            ser12_set_divisor(bc, 6);
  17509. -        } else {
  17510. -            /*
  17511. -             * do PLL correction and call HDLC receiver
  17512. -             */
  17513. -            switch (bc->modem.ser12.dcd_shreg & 3) {
  17514. -            case 1: /* transition too late */
  17515. -                ser12_set_divisor(bc, 7);
  17516. -#ifdef BAYCOM_DEBUG
  17517. -                bc->debug_vals.cur_pllcorr++;
  17518. -#endif /* BAYCOM_DEBUG */
  17519. -                break;
  17520. -            case 2:    /* transition too early */
  17521. -                ser12_set_divisor(bc, 5);
  17522. -#ifdef BAYCOM_DEBUG
  17523. -                bc->debug_vals.cur_pllcorr--;
  17524. -#endif /* BAYCOM_DEBUG */
  17525. -                break;
  17526. -            default:
  17527. -                ser12_set_divisor(bc, 6);
  17528. -                break;
  17529. -            }
  17530. -            bc->hdlc_rx.shreg1 >>= 1;
  17531. -            if (bc->modem.ser12.last_sample == 
  17532. -                bc->modem.ser12.last_rxbit)
  17533. -                bc->hdlc_rx.shreg1 |= 0x10000;
  17534. -            bc->modem.ser12.last_rxbit = 
  17535. -                bc->modem.ser12.last_sample;
  17536. -        }
  17537. -        bc->modem.ser12.interm_sample = !bc->modem.ser12.interm_sample;
  17538. -    }
  17539. -    if (bc->hdlc_rx.shreg1 & 1) {
  17540. -#ifdef BAYCOM_USE_BH
  17541. -        bc->hdlc_rx.shreg2 = (bc->hdlc_rx.shreg1 >> 1) | 0x10000;
  17542. -        queue_task_irq_off(&bc->tq_receiver, &tq_baycom);
  17543. -        mark_bh(BAYCOM_BH);
  17544. -#else /* BAYCOM_USE_BH */
  17545. -        hdlc_rx_word(bc, bc->hdlc_rx.shreg1 >> 1);
  17546. -#endif /* BAYCOM_USE_BH */
  17547. -        bc->hdlc_rx.shreg1 = 0x10000;
  17548. -    }
  17549. -    if (--bc->modem.arb_divider <= 0) {
  17550. -#ifdef BAYCOM_USE_BH
  17551. -        queue_task_irq_off(&bc->tq_arbitrate, &tq_baycom);
  17552. -        mark_bh(BAYCOM_BH);
  17553. -#else /* BAYCOM_USE_BH */
  17554. -        tx_arbitrate(bc);
  17555. -#endif /* BAYCOM_USE_BH */
  17556. -        bc->modem.arb_divider = bc->ch_params.slottime * 
  17557. -            SER12_ARB_DIVIDER(bc);
  17558. -    }
  17559. -}
  17560. -
  17561. -/* --------------------------------------------------------------------- */
  17562. -
  17563. -enum uart { c_uart_unknown, c_uart_8250,
  17564. -    c_uart_16450, c_uart_16550, c_uart_16550A};
  17565. -static const char *uart_str[] =
  17566. -    { "unknown", "8250", "16450", "16550", "16550A" };
  17567. -
  17568. -static enum uart ser12_check_uart(unsigned int iobase)
  17569. -{
  17570. -    unsigned char b1,b2,b3;
  17571. -    enum uart u;
  17572. -    enum uart uart_tab[] =
  17573. -        { c_uart_16450, c_uart_unknown, c_uart_16550, c_uart_16550A };
  17574. -
  17575. -    b1 = inb(MCR(iobase));
  17576. -    outb(b1 | 0x10, MCR(iobase));    /* loopback mode */
  17577. -    b2 = inb(MSR(iobase));
  17578. -    outb(0x1a, MCR(iobase));
  17579. -    b3 = inb(MSR(iobase)) & 0xf0;
  17580. -    outb(b1, MCR(iobase));            /* restore old values */
  17581. -    outb(b2, MSR(iobase));
  17582. -    if (b3 != 0x90) 
  17583. -        return c_uart_unknown;
  17584. -    inb(RBR(iobase));
  17585. -    inb(RBR(iobase));
  17586. -    outb(0x01, FCR(iobase));        /* enable FIFOs */
  17587. -    u = uart_tab[(inb(IIR(iobase)) >> 6) & 3];
  17588. -    if (u == c_uart_16450) {
  17589. -        outb(0x5a, SCR(iobase));
  17590. -        b1 = inb(SCR(iobase));
  17591. -        outb(0xa5, SCR(iobase));
  17592. -        b2 = inb(SCR(iobase));
  17593. -        if ((b1 != 0x5a) || (b2 != 0xa5)) 
  17594. -            u = c_uart_8250;
  17595. -    }
  17596. -    return u;
  17597. -}
  17598. -
  17599. -/* --------------------------------------------------------------------- */
  17600. -
  17601. -static int ser12_allocate_resources(unsigned int iobase, unsigned int irq,
  17602. -                    unsigned int options)
  17603. -{
  17604. -    enum uart u;
  17605. -
  17606. -    if (!iobase || iobase > 0xfff || irq < 2 || irq > 15)
  17607. -        return -ENXIO;
  17608. -    if (check_region(iobase, SER12_EXTENT))
  17609. -        return -EACCES;
  17610. -    if ((u = ser12_check_uart(iobase)) == c_uart_unknown)
  17611. -        return -EIO;
  17612. -    request_region(iobase, SER12_EXTENT, "baycom_ser12");
  17613. -    outb(0, FCR(iobase));        /* disable FIFOs */
  17614. -    outb(0x0d, MCR(iobase));
  17615. -    printk(KERN_INFO "baycom: ser12 at iobase 0x%x irq %u options 0x%x "
  17616. -           "uart %s\n", iobase, irq, options, uart_str[u]);
  17617. -    return 0;
  17618. -}
  17619. -    
  17620. -/* --------------------------------------------------------------------- */
  17621. -
  17622. -static void ser12_deallocate_resources(struct baycom_state *bc) 
  17623. -{
  17624. -    if (!bc || bc->modem_type != BAYCOM_MODEM_SER12)
  17625. -        return;
  17626. -    /*
  17627. -     * disable interrupts
  17628. -     */
  17629. -    outb(0, IER(bc->iobase));
  17630. -    outb(1, MCR(bc->iobase));
  17631. -    /* 
  17632. -     * this should prevent kernel: Trying to free IRQx
  17633. -     * messages
  17634. -     */
  17635. -    if (bc->opened > 0)
  17636. -        free_irq(bc->irq, bc);
  17637. -    release_region(bc->iobase, SER12_EXTENT);
  17638. -    bc->modem_type = BAYCOM_MODEM_INVALID;
  17639. -    printk(KERN_INFO "baycom: release ser12 at iobase 0x%x irq %u\n",
  17640. -           bc->iobase, bc->irq);
  17641. -    bc->iobase = bc->irq = bc->options = 0;
  17642. -}
  17643. -
  17644. -/* --------------------------------------------------------------------- */
  17645. -
  17646. -static int ser12_on_open(struct baycom_state *bc) 
  17647. -{
  17648. -    if (!bc || bc->modem_type != BAYCOM_MODEM_SER12)
  17649. -        return -ENXIO;
  17650. -    /*
  17651. -     * set the SIO to 6 Bits/character and 19200 or 28800 baud, so that
  17652. -     * we get exactly (hopefully) 2 or 3 interrupts per radio symbol,
  17653. -     * depending on the usage of the software DCD routine
  17654. -     */
  17655. -    ser12_set_divisor(bc, (bc->options & BAYCOM_OPTIONS_SOFTDCD) ? 4 : 6);
  17656. -    outb(0x0d, MCR(bc->iobase));
  17657. -    outb(0, IER(bc->iobase));
  17658. -    if (request_irq(bc->irq, baycom_ser12_interrupt, SA_INTERRUPT, 
  17659. -            "baycom_ser12", bc))
  17660. -        return -EBUSY;
  17661. -    /*
  17662. -     * enable transmitter empty interrupt
  17663. -     */
  17664. -    outb(2, IER(bc->iobase));  
  17665. -    /* 
  17666. -     * the value here serves to power the modem
  17667. -     */     
  17668. -    outb(0x00, THR(bc->iobase));
  17669. -    return 0;
  17670. -}
  17671. -
  17672. -/* --------------------------------------------------------------------- */
  17673. -
  17674. -static void ser12_on_close(struct baycom_state *bc) 
  17675. -{
  17676. -    if (!bc || bc->modem_type != BAYCOM_MODEM_SER12)
  17677. -        return;
  17678. -    /*
  17679. -     * disable interrupts
  17680. -     */
  17681. -    outb(0, IER(bc->iobase));
  17682. -    outb(1, MCR(bc->iobase));
  17683. -    free_irq(bc->irq, bc);    
  17684. -}
  17685. -
  17686. -/* --------------------------------------------------------------------- */
  17687. -/*
  17688. - * ===================== PAR96 specific routines =========================
  17689. - */
  17690. -
  17691. -#define PAR96_DESCRAM_TAP1 0x20000
  17692. -#define PAR96_DESCRAM_TAP2 0x01000
  17693. -#define PAR96_DESCRAM_TAP3 0x00001
  17694. -
  17695. -#define PAR96_DESCRAM_TAPSH1 17
  17696. -#define PAR96_DESCRAM_TAPSH2 12
  17697. -#define PAR96_DESCRAM_TAPSH3 0
  17698. -
  17699. -#define PAR96_SCRAM_TAP1 0x20000 /* X^17 */
  17700. -#define PAR96_SCRAM_TAPN 0x00021 /* X^0+X^5 */
  17701. -
  17702. -/* --------------------------------------------------------------------- */
  17703. -
  17704. -static void baycom_par96_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  17705. -{
  17706. -    register struct baycom_state *bc = (struct baycom_state *)dev_id;
  17707. -    int i;
  17708. -    unsigned int data, descx, mask, mask2;
  17709. -    
  17710. -    if (!bc || bc->magic != BAYCOM_MAGIC)
  17711. -        return;
  17712. -
  17713. -    rx_chars_to_flip(bc);
  17714. -#ifdef BAYCOM_DEBUG
  17715. -    baycom_int_freq(bc);
  17716. -#endif /* BAYCOM_DEBUG */
  17717. -    /*
  17718. -     * check if transmitter active
  17719. -     */
  17720. -    if (bc->hdlc_tx.ptt || bc->calibrate > 0) {
  17721. -        /*
  17722. -         * first output the last 16 bits (!) then call HDLC
  17723. -         * transmitter, since this may take quite long
  17724. -         * do the differential encoder and the scrambler on the fly
  17725. -         */
  17726. -        data = bc->hdlc_tx.shreg1;
  17727. -        for(i = 0; i < PAR96_BURSTBITS; i++, data >>= 1) {
  17728. -            unsigned char val = PAR97_POWER;
  17729. -            bc->modem.par96.scram = ((bc->modem.par96.scram << 1) |
  17730. -                         (bc->modem.par96.scram & 1));
  17731. -            if (!(data & 1))
  17732. -                bc->modem.par96.scram ^= 1;
  17733. -            if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 1))
  17734. -                bc->modem.par96.scram ^= 
  17735. -                    (PAR96_SCRAM_TAPN << 1);
  17736. -            if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 2))
  17737. -                val |= PAR96_TXBIT;
  17738. -            outb(val, LPT_DATA(bc->iobase));
  17739. -            outb(val | PAR96_BURST, LPT_DATA(bc->iobase));
  17740. -        }
  17741. -        if (bc->calibrate > 0) {
  17742. -            bc->hdlc_tx.shreg1 = 0x10000;
  17743. -            bc->calibrate--;
  17744. -        } else {
  17745. -#ifdef BAYCOM_USE_BH
  17746. -            bc->hdlc_tx.shreg1 = bc->hdlc_tx.shreg2;
  17747. -            bc->hdlc_tx.shreg2 = 0;
  17748. -            queue_task_irq_off(&bc->tq_transmitter, &tq_baycom);
  17749. -            mark_bh(BAYCOM_BH);
  17750. -#ifdef HDLC_LOOPBACK
  17751. -            bc->hdlc_rx.shreg2 = bc->hdlc_tx.shreg1;
  17752. -            queue_task_irq_off(&bc->tq_receiver, &tq_baycom);
  17753. -#endif /* HDLC_LOOPBACK */
  17754. -#else /* BAYCOM_USE_BH */
  17755. -            bc->hdlc_tx.shreg1 = hdlc_tx_word(bc);
  17756. -#ifdef HDLC_LOOPBACK
  17757. -            hdlc_rx_word(bc, bc->hdlc_tx.shreg1);
  17758. -#endif /* HDLC_LOOPBACK */
  17759. -#endif /* BAYCOM_USE_BH */
  17760. -        }
  17761. -        return;
  17762. -    }
  17763. -    /*
  17764. -     * do receiver; differential decode and descramble on the fly
  17765. -     */
  17766. -    for(data = i = 0; i < PAR96_BURSTBITS; i++) {
  17767. -        bc->modem.par96.descram = (bc->modem.par96.descram << 1);
  17768. -        if (inb(LPT_STATUS(bc->iobase)) & PAR96_RXBIT)
  17769. -            bc->modem.par96.descram |= 1;
  17770. -        descx = bc->modem.par96.descram ^ 
  17771. -            (bc->modem.par96.descram >> 1);
  17772. -        /* now the diff decoded data is inverted in descram */
  17773. -        outb(PAR97_POWER | PAR96_PTT, LPT_DATA(bc->iobase));
  17774. -        descx ^= ((descx >> PAR96_DESCRAM_TAPSH1) ^
  17775. -              (descx >> PAR96_DESCRAM_TAPSH2));
  17776. -        data >>= 1;
  17777. -        if (!(descx & 1))
  17778. -            data |= 0x8000;
  17779. -        outb(PAR97_POWER | PAR96_PTT | PAR96_BURST, 
  17780. -             LPT_DATA(bc->iobase));
  17781. -    }
  17782. -#ifdef BAYCOM_USE_BH
  17783. -    bc->hdlc_rx.shreg2 = bc->hdlc_rx.shreg1;
  17784. -    bc->hdlc_rx.shreg1 = data | 0x10000;
  17785. -    queue_task_irq_off(&bc->tq_receiver, &tq_baycom);
  17786. -    mark_bh(BAYCOM_BH);
  17787. -#else /* BAYCOM_USE_BH */
  17788. -    hdlc_rx_word(bc, data);
  17789. -#endif /* BAYCOM_USE_BH */
  17790. -    /*
  17791. -     * do DCD algorithm
  17792. -     */
  17793. -    if (bc->options & BAYCOM_OPTIONS_SOFTDCD) {
  17794. -        bc->modem.par96.dcd_shreg = (bc->modem.par96.dcd_shreg >> 16)
  17795. -            | (data << 16);
  17796. -        /* search for flags and set the dcd counter appropriately */
  17797. -        for(mask = 0x1fe00, mask2 = 0xfc00, i = 0; 
  17798. -            i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
  17799. -            if ((bc->modem.par96.dcd_shreg & mask) == mask2)
  17800. -                bc->modem.par96.dcd_count = BAYCOM_MAXFLEN+4;
  17801. -        /* check for abort/noise sequences */
  17802. -        for(mask = 0x1fe00, mask2 = 0x1fe00, i = 0; 
  17803. -            i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
  17804. -            if (((bc->modem.par96.dcd_shreg & mask) == mask2) &&
  17805. -                (bc->modem.par96.dcd_count >= 0))
  17806. -                bc->modem.par96.dcd_count -= BAYCOM_MAXFLEN-10;
  17807. -        /* decrement and set the dcd variable */
  17808. -        if (bc->modem.par96.dcd_count >= 0)
  17809. -            bc->modem.par96.dcd_count -= 2;
  17810. -        bc->modem.dcd = bc->modem.par96.dcd_count > 0;
  17811. -    } else {
  17812. -        bc->modem.dcd = !!(inb(LPT_STATUS(bc->iobase))
  17813. -                   & PAR96_DCD);
  17814. -    }
  17815. -    if (--bc->modem.arb_divider <= 0) {
  17816. -#ifdef BAYCOM_USE_BH
  17817. -        queue_task_irq_off(&bc->tq_arbitrate, &tq_baycom);
  17818. -        mark_bh(BAYCOM_BH);
  17819. -#else /* BAYCOM_USE_BH */
  17820. -        tx_arbitrate(bc);
  17821. -#endif /* BAYCOM_USE_BH */
  17822. -        bc->modem.arb_divider = bc->ch_params.slottime * 6;
  17823. -    }
  17824. -}
  17825. -
  17826. -/* --------------------------------------------------------------------- */
  17827. -
  17828. -static int par96_check_lpt(unsigned int iobase)
  17829. -{
  17830. -    unsigned char b1,b2;
  17831. -    int i;
  17832. -
  17833. -    b1 = inb(LPT_DATA(iobase));
  17834. -    b2 = inb(LPT_CONTROL(iobase));
  17835. -    outb(0xaa, LPT_DATA(iobase));
  17836. -    i = inb(LPT_DATA(iobase)) == 0xaa;
  17837. -    outb(0x55, LPT_DATA(iobase));
  17838. -    i &= inb(LPT_DATA(iobase)) == 0x55;
  17839. -    outb(0x0a, LPT_CONTROL(iobase));
  17840. -    i &= (inb(LPT_CONTROL(iobase)) & 0xf) == 0x0a;
  17841. -    outb(0x05, LPT_CONTROL(iobase));
  17842. -    i &= (inb(LPT_CONTROL(iobase)) & 0xf) == 0x05;
  17843. -    outb(b1, LPT_DATA(iobase));
  17844. -    outb(b2, LPT_CONTROL(iobase));
  17845. -    return !i;
  17846. -}
  17847. -
  17848. -/* --------------------------------------------------------------------- */
  17849. -
  17850. -static int par96_allocate_resources(unsigned int iobase, unsigned int irq,
  17851. -                    unsigned int options)
  17852. -{
  17853. -    if (!iobase || iobase > 0xfff || irq < 2 || irq > 15)
  17854. -        return -ENXIO;
  17855. -    if (check_region(iobase, PAR96_EXTENT))
  17856. -        return -EACCES;
  17857. -    if (par96_check_lpt(iobase))
  17858. -        return -EIO;
  17859. -    request_region(iobase, PAR96_EXTENT, "baycom_par96");
  17860. -    outb(0, LPT_CONTROL(iobase));                 /* disable interrupt */
  17861. -    outb(PAR96_PTT | PAR97_POWER, LPT_DATA(iobase)); /* switch off PTT */
  17862. -    printk(KERN_INFO "baycom: par96 at iobase 0x%x irq %u options 0x%x\n", 
  17863. -           iobase, irq, options);
  17864. -    return 0;
  17865. -}
  17866. -    
  17867. -/* --------------------------------------------------------------------- */
  17868. -
  17869. -static void par96_deallocate_resources(struct baycom_state *bc) 
  17870. -{
  17871. -    if (!bc || bc->modem_type != BAYCOM_MODEM_PAR96)
  17872. -        return;
  17873. -    outb(0, LPT_CONTROL(bc->iobase));      /* disable interrupt */
  17874. -    outb(PAR96_PTT, LPT_DATA(bc->iobase)); /* switch off PTT */
  17875. -    /* 
  17876. -     * this should prevent kernel: Trying to free IRQx
  17877. -     * messages
  17878. -     */
  17879. -    if (bc->opened > 0)
  17880. -        free_irq(bc->irq, bc);
  17881. -    release_region(bc->iobase, PAR96_EXTENT);
  17882. -    bc->modem_type = BAYCOM_MODEM_INVALID;
  17883. -    printk(KERN_INFO "baycom: release par96 at iobase 0x%x irq %u\n",
  17884. -           bc->iobase, bc->irq);
  17885. -    bc->iobase = bc->irq = bc->options = 0;
  17886. -}
  17887. -
  17888. -/* --------------------------------------------------------------------- */
  17889. -
  17890. -static int par96_on_open(struct baycom_state *bc) 
  17891. -{
  17892. -    if (!bc || bc->modem_type != BAYCOM_MODEM_PAR96)
  17893. -        return -ENXIO;
  17894. -    outb(0, LPT_CONTROL(bc->iobase));      /* disable interrupt */
  17895. -     /* switch off PTT */
  17896. -    outb(PAR96_PTT | PAR97_POWER, LPT_DATA(bc->iobase));
  17897. -    if (request_irq(bc->irq, baycom_par96_interrupt, SA_INTERRUPT, 
  17898. -            "baycom_par96", bc))
  17899. -        return -EBUSY;
  17900. -    outb(LPT_IRQ_ENABLE, LPT_CONTROL(bc->iobase));  /* enable interrupt */
  17901. -    return 0;
  17902. -}
  17903. -
  17904. -/* --------------------------------------------------------------------- */
  17905. -
  17906. -static void par96_on_close(struct baycom_state *bc) 
  17907. -{
  17908. -    if (!bc || bc->modem_type != BAYCOM_MODEM_PAR96)
  17909. -        return;
  17910. -    outb(0, LPT_CONTROL(bc->iobase));  /* disable interrupt */
  17911. -    /* switch off PTT */
  17912. -    outb(PAR96_PTT | PAR97_POWER, LPT_DATA(bc->iobase));
  17913. -    free_irq(bc->irq, bc);    
  17914. -}
  17915. -
  17916. -/* --------------------------------------------------------------------- */
  17917. -/*
  17918. - * ===================== Bottom half (soft interrupt) ====================
  17919. - */
  17920. -
  17921. -#ifdef BAYCOM_USE_BH
  17922. -static void bh_receiver(void *private)
  17923. -{
  17924. -    struct baycom_state *bc = (struct baycom_state *)private;
  17925. -    unsigned int temp;
  17926. -
  17927. -    if (!bc || bc->magic != BAYCOM_MAGIC)
  17928. -        return;
  17929. -    if (!bc->hdlc_rx.shreg2)
  17930. -        return;
  17931. -    temp = bc->hdlc_rx.shreg2;
  17932. -    bc->hdlc_rx.shreg2 = 0;
  17933. -    hdlc_rx_word(bc, temp);
  17934. -}
  17935. -
  17936. -/* --------------------------------------------------------------------- */
  17937. -
  17938. -static void bh_transmitter(void *private)
  17939. -{
  17940. -    struct baycom_state *bc = (struct baycom_state *)private;
  17941. -
  17942. -    if (!bc || bc->magic != BAYCOM_MAGIC)
  17943. -        return;
  17944. -    if (bc->hdlc_tx.shreg2)
  17945. -        return;
  17946. -    bc->hdlc_tx.shreg2 = hdlc_tx_word(bc) | 0x10000;
  17947. -}
  17948. -
  17949. -/* --------------------------------------------------------------------- */
  17950. -
  17951. -static void bh_arbitrate(void *private)
  17952. -{
  17953. -    struct baycom_state *bc = (struct baycom_state *)private;
  17954. -
  17955. -    if (!bc || bc->magic != BAYCOM_MAGIC)
  17956. -        return;
  17957. -    tx_arbitrate(bc);
  17958. -}
  17959. -
  17960. -/* --------------------------------------------------------------------- */
  17961. -
  17962. -static void baycom_bottom_half(void)
  17963. -{
  17964. -    run_task_queue(&tq_baycom);
  17965. -}
  17966. -#endif /* BAYCOM_USE_BH */
  17967. -
  17968. -/* --------------------------------------------------------------------- */
  17969. -/*
  17970. - * ===================== TTY interface routines ==========================
  17971. - */
  17972. -
  17973. -static inline int baycom_paranoia_check(struct baycom_state *bc, 
  17974. -                    const char *routine)
  17975. -{
  17976. -    if (!bc || bc->magic != BAYCOM_MAGIC) {
  17977. -        printk(KERN_ERR "baycom: bad magic number for baycom struct "
  17978. -               "in routine %s\n", routine);
  17979. -        return 1;
  17980. -    }
  17981. -    return 0;
  17982. -}
  17983. -
  17984. -/* --------------------------------------------------------------------- */
  17985. -/*
  17986. - * Here the tty driver code starts
  17987. - */
  17988. -
  17989. -static void baycom_put_fend(struct baycom_state *bc)
  17990. -{
  17991. -    if (bc->kiss_decode.wr <= 0 ||
  17992. -        (bc->kiss_decode.pkt_buf[0] & 0xf0) != 0)
  17993. -        return;
  17994. -
  17995. -    switch (bc->kiss_decode.pkt_buf[0] & 0xf) {
  17996. -    case KISS_CMD_DATA:
  17997. -        if (bc->kiss_decode.wr <= 8) 
  17998. -            break;
  17999. -        if (!store_packet(&bc->tx_buf, bc->kiss_decode.pkt_buf+1, 0, 
  18000. -                  bc->kiss_decode.wr-1))
  18001. -            bc->stat.tx_bufferoverrun++;
  18002. -        break;
  18003. -
  18004. -    case KISS_CMD_TXDELAY:
  18005. -        if (bc->kiss_decode.wr < 2) 
  18006. -            break;
  18007. -        bc->ch_params.tx_delay = bc->kiss_decode.pkt_buf[1];
  18008. -#ifdef KISS_VERBOSE
  18009. -        printk(KERN_INFO "baycom: TX delay = %ums\n", 
  18010. -               bc->ch_params.tx_delay * 10);
  18011. -#endif /* KISS_VERBOSE */
  18012. -        break;
  18013. -
  18014. -    case KISS_CMD_PPERSIST:
  18015. -        if (bc->kiss_decode.wr < 2) 
  18016. -            break;
  18017. -        bc->ch_params.ppersist = bc->kiss_decode.pkt_buf[1];
  18018. -#ifdef KISS_VERBOSE
  18019. -        printk(KERN_INFO "baycom: p-persistence = %u\n", 
  18020. -               bc->ch_params.ppersist);
  18021. -#endif /* KISS_VERBOSE */
  18022. -        break;
  18023. -
  18024. -    case KISS_CMD_SLOTTIME:
  18025. -        if (bc->kiss_decode.wr < 2) 
  18026. -            break;
  18027. -        bc->ch_params.slottime = bc->kiss_decode.pkt_buf[1];
  18028. -#ifdef KISS_VERBOSE
  18029. -        printk(KERN_INFO "baycom: slottime = %ums\n", 
  18030. -               bc->ch_params.slottime * 10);
  18031. -#endif /* KISS_VERBOSE */
  18032. -        break;
  18033. -
  18034. -    case KISS_CMD_TXTAIL:
  18035. -        if (bc->kiss_decode.wr < 2) 
  18036. -            break;
  18037. -        bc->ch_params.tx_tail = bc->kiss_decode.pkt_buf[1];
  18038. -#ifdef KISS_VERBOSE
  18039. -        printk(KERN_INFO "baycom: TX tail = %ums\n",
  18040. -               bc->ch_params.tx_tail * 10);
  18041. -#endif /* KISS_VERBOSE */
  18042. -        break;
  18043. -
  18044. -    case KISS_CMD_FULLDUP:
  18045. -        if (bc->kiss_decode.wr < 2) 
  18046. -            break;
  18047. -        bc->ch_params.fulldup = bc->kiss_decode.pkt_buf[1];
  18048. -#ifdef KISS_VERBOSE
  18049. -        printk(KERN_INFO "baycom: %s duplex\n", 
  18050. -               bc->ch_params.fulldup ? "full" : "half");
  18051. -#endif /* KISS_VERBOSE */
  18052. -        break;
  18053. -
  18054. -    default:
  18055. -#ifdef KISS_VERBOSE
  18056. -        printk(KERN_INFO "baycom: unhandled KISS packet code %u\n",
  18057. -               bc->kiss_decode.pkt_buf[0] & 0xf);
  18058. -#endif /* KISS_VERBOSE */
  18059. -        break;
  18060. -    }
  18061. -}
  18062. -
  18063. -/* --------------------------------------------------------------------- */
  18064. -
  18065. -static void baycom_put_char(struct tty_struct *tty, unsigned char ch)
  18066. -{
  18067. -    struct baycom_state *bc;
  18068. -        
  18069. -    if (!tty)
  18070. -        return;
  18071. -    if (baycom_paranoia_check(bc = tty->driver_data, "put_char"))
  18072. -        return;
  18073. -        
  18074. -    if (ch == KISS_FEND) {
  18075. -        baycom_put_fend(bc);
  18076. -        bc->kiss_decode.wr = 0;
  18077. -        bc->kiss_decode.escaped = 0;
  18078. -        bc->kiss_decode.dec_state = 1;
  18079. -        return;
  18080. -    }
  18081. -    if (!bc->kiss_decode.dec_state)
  18082. -        return;
  18083. -    if (ch == KISS_FESC) {
  18084. -        bc->kiss_decode.escaped = 1;
  18085. -        return;
  18086. -    }
  18087. -    if (bc->kiss_decode.wr >= sizeof(bc->kiss_decode.pkt_buf)) {
  18088. -        bc->kiss_decode.wr = 0;
  18089. -        bc->kiss_decode.dec_state = 0;
  18090. -        return;
  18091. -    }
  18092. -    if (bc->kiss_decode.escaped) {
  18093. -        if (ch == KISS_TFEND)
  18094. -            bc->kiss_decode.pkt_buf[bc->kiss_decode.wr++] = 
  18095. -                KISS_FEND;
  18096. -        else if (ch == KISS_TFESC)
  18097. -            bc->kiss_decode.pkt_buf[bc->kiss_decode.wr++] = 
  18098. -                KISS_FESC;
  18099. -        else {
  18100. -            bc->kiss_decode.wr = 0;
  18101. -            bc->kiss_decode.dec_state = 0;
  18102. -        }
  18103. -        bc->kiss_decode.escaped = 0;
  18104. -        return;
  18105. -    }
  18106. -    bc->kiss_decode.pkt_buf[bc->kiss_decode.wr++] = ch;
  18107. -}
  18108. -    
  18109. -/* --------------------------------------------------------------------- */
  18110. -
  18111. -static int baycom_write(struct tty_struct * tty, int from_user,
  18112. -    const unsigned char *buf, int count)
  18113. -{
  18114. -    int c;
  18115. -    const unsigned char *bp;
  18116. -    struct baycom_state *bc;
  18117. -        
  18118. -    if (!tty || !buf || count <= 0)
  18119. -        return count;
  18120. -    
  18121. -    if (baycom_paranoia_check(bc = tty->driver_data, "write"))
  18122. -        return count; 
  18123. -        
  18124. -    if (from_user) {
  18125. -        for(c = count, bp = buf; c > 0; c--,bp++)
  18126. -            baycom_put_char(tty, get_user(bp));
  18127. -    } else {
  18128. -        for(c = count, bp = buf; c > 0; c--,bp++)
  18129. -            baycom_put_char(tty, *bp);
  18130. -    }
  18131. -    if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  18132. -        tty->ldisc.write_wakeup)
  18133. -            (tty->ldisc.write_wakeup)(tty);
  18134. -    wake_up_interruptible(&tty->write_wait);
  18135. -    return count;
  18136. -}
  18137. -
  18138. -/* --------------------------------------------------------------------- */
  18139. -
  18140. -static int baycom_write_room(struct tty_struct *tty)
  18141. -{
  18142. -    int free;
  18143. -    struct baycom_state *bc;
  18144. -        
  18145. -    if (!tty)
  18146. -        return 0;
  18147. -    if (baycom_paranoia_check(bc = tty->driver_data, "write_room"))
  18148. -        return 0;
  18149. -        
  18150. -    free = bc->tx_buf.rd - bc->tx_buf.wr;
  18151. -    if (free <= 0) {
  18152. -        free = bc->tx_buf.buflen - bc->tx_buf.wr;
  18153. -        if (free < bc->tx_buf.rd)
  18154. -            free = bc->tx_buf.rd;    /* we may fold */
  18155. -    }
  18156. -
  18157. -    return free / 2; /* a rather pessimistic estimate */
  18158. -}
  18159. -
  18160. -/* --------------------------------------------------------------------- */
  18161. -
  18162. -static int baycom_chars_in_buffer(struct tty_struct *tty)
  18163. -{
  18164. -    int cnt;
  18165. -    struct baycom_state *bc;
  18166. -        
  18167. -    if (!tty)
  18168. -        return 0;
  18169. -    if (baycom_paranoia_check(bc = tty->driver_data, "chars_in_buffer"))
  18170. -        return 0;
  18171. -
  18172. -    cnt = bc->tx_buf.wr - bc->tx_buf.rd;
  18173. -    if (cnt < 0)
  18174. -        cnt += bc->tx_buf.buflen;
  18175. -        
  18176. -    return cnt;
  18177. -}
  18178. -
  18179. -/* --------------------------------------------------------------------- */
  18180. -
  18181. -static void baycom_flush_buffer(struct tty_struct *tty)
  18182. -{
  18183. -    struct baycom_state *bc;
  18184. -        
  18185. -    if (!tty)
  18186. -        return;
  18187. -    if (baycom_paranoia_check(bc = tty->driver_data, "flush_buffer"))
  18188. -        return;
  18189. -
  18190. -    wake_up_interruptible(&tty->write_wait);
  18191. -    if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  18192. -        tty->ldisc.write_wakeup)
  18193. -            (tty->ldisc.write_wakeup)(tty);
  18194. -}
  18195. -
  18196. -/* --------------------------------------------------------------------- */
  18197. -
  18198. -static inline void baycom_dealloc_hw(struct baycom_state *bc) 
  18199. -{
  18200. -    if (!bc || bc->magic != BAYCOM_MAGIC || 
  18201. -        bc->modem_type == BAYCOM_MODEM_INVALID)
  18202. -        return;
  18203. -    switch(bc->modem_type) {
  18204. -    case BAYCOM_MODEM_SER12:
  18205. -        ser12_deallocate_resources(bc);
  18206. -        break;
  18207. -    case BAYCOM_MODEM_PAR96:
  18208. -        par96_deallocate_resources(bc);
  18209. -        break;
  18210. -    }
  18211. -}
  18212. -
  18213. -/* --------------------------------------------------------------------- */
  18214. -
  18215. -static int baycom_set_hardware(struct baycom_state *bc,
  18216. -                   unsigned int modem_type, unsigned int iobase, 
  18217. -                   unsigned int irq, unsigned int options)
  18218. -{
  18219. -    int i;
  18220. -
  18221. -    if (!bc)
  18222. -        return -EINVAL;
  18223. -
  18224. -    if (modem_type == BAYCOM_MODEM_SER12) {
  18225. -        i = ser12_allocate_resources(iobase, irq, options);
  18226. -        if (i < 0)
  18227. -            return i;
  18228. -    } else if (modem_type == BAYCOM_MODEM_PAR96) {
  18229. -        i = par96_allocate_resources(iobase, irq, options);
  18230. -        if (i < 0)
  18231. -            return i;
  18232. -    } else if (modem_type == BAYCOM_MODEM_INVALID) {
  18233. -        iobase = irq = options = 0;
  18234. -    } else {
  18235. -        return -ENXIO;
  18236. -    }
  18237. -    baycom_dealloc_hw(bc);
  18238. -    bc->modem_type = modem_type;
  18239. -    bc->iobase = iobase;
  18240. -    bc->irq = irq;
  18241. -    bc->options = options;
  18242. -    i = 0;
  18243. -    if (bc->opened > 0) {
  18244. -        switch(bc->modem_type) {
  18245. -        case BAYCOM_MODEM_SER12:
  18246. -            i = ser12_on_open(bc);
  18247. -            break;
  18248. -        case BAYCOM_MODEM_PAR96:
  18249. -            i = par96_on_open(bc);
  18250. -            break;
  18251. -        }
  18252. -    }
  18253. -    return i;
  18254. -}
  18255. -
  18256. -/* --------------------------------------------------------------------- */
  18257. -
  18258. -static int baycom_ioctl(struct tty_struct *tty, struct file * file,
  18259. -    unsigned int cmd, unsigned long arg)
  18260. -{
  18261. -    int i;
  18262. -    struct baycom_state *bc;
  18263. -    struct baycom_params par;
  18264. -        
  18265. -    if (!tty)
  18266. -        return -EINVAL;
  18267. -    if (baycom_paranoia_check(bc = tty->driver_data, "ioctl"))
  18268. -        return -EINVAL;
  18269. -        
  18270. -    switch (cmd) {
  18271. -    default:
  18272. -        return -ENOIOCTLCMD;
  18273. -
  18274. -    case TIOCMGET:
  18275. -        i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(int));
  18276. -        if (i)
  18277. -            return i;
  18278. -        i = (bc->modem.dcd ? TIOCM_CAR : 0) |
  18279. -            (bc->hdlc_tx.ptt ? TIOCM_RTS : 0);
  18280. -        put_user(i, (int *) arg);
  18281. -        return 0;
  18282. -        
  18283. -    case BAYCOMCTL_GETDCD:
  18284. -        i = verify_area(VERIFY_WRITE, (void *) arg,
  18285. -                sizeof(unsigned char));
  18286. -        if (!i)
  18287. -            put_user(bc->modem.dcd, (unsigned char *) arg);
  18288. -        return i;
  18289. -        
  18290. -    case BAYCOMCTL_GETPTT:
  18291. -        i = verify_area(VERIFY_WRITE, (void *) arg, 
  18292. -                sizeof(unsigned char));
  18293. -        if (!i)
  18294. -            put_user(bc->hdlc_tx.ptt, (unsigned char *) arg);
  18295. -        return i;
  18296. -        
  18297. -    case BAYCOMCTL_PARAM_TXDELAY:
  18298. -        if (arg > 255)
  18299. -            return -EINVAL;
  18300. -        bc->ch_params.tx_delay = arg;
  18301. -        return 0;
  18302. -        
  18303. -    case BAYCOMCTL_PARAM_PPERSIST:
  18304. -        if (arg > 255)
  18305. -            return -EINVAL;
  18306. -        bc->ch_params.ppersist = arg;
  18307. -        return 0;
  18308. -        
  18309. -    case BAYCOMCTL_PARAM_SLOTTIME:
  18310. -        if (arg > 255)
  18311. -            return -EINVAL;
  18312. -        bc->ch_params.slottime = arg;
  18313. -        return 0;
  18314. -        
  18315. -    case BAYCOMCTL_PARAM_TXTAIL:
  18316. -        if (arg > 255)
  18317. -            return -EINVAL;
  18318. -        bc->ch_params.tx_tail = arg;
  18319. -        return 0;
  18320. -        
  18321. -    case BAYCOMCTL_PARAM_FULLDUP:
  18322. -        bc->ch_params.fulldup = arg ? 1 : 0;
  18323. -        return 0;
  18324. -        
  18325. -    case BAYCOMCTL_CALIBRATE:
  18326. -        bc->calibrate = arg * ((bc->modem_type == BAYCOM_MODEM_PAR96) ?
  18327. -                       600 : 75);
  18328. -        return 0;
  18329. -
  18330. -    case BAYCOMCTL_GETPARAMS:
  18331. -        i = verify_area(VERIFY_WRITE, (void *) arg, 
  18332. -                sizeof(par));
  18333. -        if (i)
  18334. -            return i;
  18335. -        par.modem_type = bc->modem_type;
  18336. -        par.iobase = bc->iobase;
  18337. -        par.irq = bc->irq;
  18338. -        par.options = bc->options;
  18339. -        par.tx_delay = bc->ch_params.tx_delay;
  18340. -        par.tx_tail = bc->ch_params.tx_tail;
  18341. -        par.slottime = bc->ch_params.slottime;
  18342. -        par.ppersist = bc->ch_params.ppersist;
  18343. -        par.fulldup = bc->ch_params.fulldup;
  18344. -        memcpy_tofs((void *)arg, &par, sizeof(par));
  18345. -        return 0;
  18346. -
  18347. -    case BAYCOMCTL_SETPARAMS:
  18348. -        if (!suser())
  18349. -            return -EPERM;
  18350. -        i = verify_area(VERIFY_READ, (void *) arg, 
  18351. -                sizeof(par));
  18352. -        if (i)
  18353. -            return i;
  18354. -        memcpy_fromfs(&par, (void *)arg, sizeof(par));
  18355. -        printk(KERN_INFO "baycom: changing hardware type: modem %u "
  18356. -               "iobase 0x%x irq %u options 0x%x\n", par.modem_type,
  18357. -               par.iobase, par.irq, par.options);
  18358. -        i = baycom_set_hardware(bc, par.modem_type, par.iobase,
  18359. -                    par.irq, par.options); 
  18360. -        if (i)
  18361. -            return i;
  18362. -        bc->ch_params.tx_delay = par.tx_delay;
  18363. -        bc->ch_params.tx_tail = par.tx_tail;
  18364. -        bc->ch_params.slottime = par.slottime;
  18365. -        bc->ch_params.ppersist = par.ppersist;
  18366. -        bc->ch_params.fulldup = par.fulldup;
  18367. -        return 0;
  18368. -
  18369. -    case BAYCOMCTL_GETSTAT:
  18370. -        i = verify_area(VERIFY_WRITE, (void *) arg, 
  18371. -                sizeof(struct baycom_statistics));
  18372. -        if (i)
  18373. -            return i;
  18374. -        memcpy_tofs((void *)arg, &bc->stat, 
  18375. -                sizeof(struct baycom_statistics));
  18376. -        return 0;
  18377. -        
  18378. -
  18379. -#ifdef BAYCOM_DEBUG
  18380. -    case BAYCOMCTL_GETSAMPLES:
  18381. -        if (bc->bitbuf_channel.rd == bc->bitbuf_channel.wr) 
  18382. -            return -EAGAIN;
  18383. -        i = verify_area(VERIFY_WRITE, (void *) arg, 
  18384. -                sizeof(unsigned char));
  18385. -        if (!i) {
  18386. -            put_user(bc->bitbuf_channel.buffer
  18387. -                 [bc->bitbuf_channel.rd],
  18388. -                 (unsigned char *) arg);
  18389. -            bc->bitbuf_channel.rd = (bc->bitbuf_channel.rd+1) %
  18390. -                sizeof(bc->bitbuf_channel.buffer);
  18391. -        }
  18392. -        return i;
  18393. -        
  18394. -    case BAYCOMCTL_GETBITS:
  18395. -        if (bc->bitbuf_hdlc.rd == bc->bitbuf_hdlc.wr) 
  18396. -            return -EAGAIN;
  18397. -        i = verify_area(VERIFY_WRITE, (void *) arg, 
  18398. -                sizeof(unsigned char));
  18399. -        if (!i) {
  18400. -            put_user(bc->bitbuf_hdlc.buffer[bc->bitbuf_hdlc.rd],
  18401. -                 (unsigned char *) arg);
  18402. -            bc->bitbuf_hdlc.rd = (bc->bitbuf_hdlc.rd+1) %
  18403. -                sizeof(bc->bitbuf_hdlc.buffer);
  18404. -        }
  18405. -        return i;
  18406. -        
  18407. -    case BAYCOMCTL_DEBUG1:
  18408. -        i = verify_area(VERIFY_WRITE, (void *) arg,
  18409. -                sizeof(unsigned long));
  18410. -        if (!i)
  18411. -            put_user((bc->rx_buf.wr-bc->rx_buf.rd) % 
  18412. -                 bc->rx_buf.buflen, (unsigned long *)arg);
  18413. -        return i;
  18414. -        
  18415. -    case BAYCOMCTL_DEBUG2:
  18416. -        i = verify_area(VERIFY_WRITE, (void *) arg,
  18417. -                sizeof(unsigned long));
  18418. -        if (!i)
  18419. -            put_user(bc->debug_vals.last_intcnt, 
  18420. -                 (unsigned long *)arg);
  18421. -        return i;
  18422. -        
  18423. -    case BAYCOMCTL_DEBUG3:
  18424. -        i = verify_area(VERIFY_WRITE, (void *) arg, 
  18425. -                sizeof(unsigned long));
  18426. -        if (!i)
  18427. -            put_user((long)bc->debug_vals.last_pllcorr,
  18428. -                 (long *)arg);
  18429. -        return i;        
  18430. -#endif /* BAYCOM_DEBUG */
  18431. -    }
  18432. -}
  18433. -
  18434. -/* --------------------------------------------------------------------- */
  18435. -
  18436. -int baycom_open(struct tty_struct *tty, struct file * filp)
  18437. -{
  18438. -    int line;
  18439. -    struct baycom_state *bc;
  18440. -    int i;
  18441. -
  18442. -    if(!tty)
  18443. -        return -ENODEV;
  18444. -
  18445. -    line = MINOR(tty->device) - tty->driver.minor_start;
  18446. -    if (line < 0 || line >= NR_PORTS)
  18447. -        return -ENODEV;
  18448. -    bc = baycom_state+line;
  18449. -
  18450. -    if (bc->opened > 0) {
  18451. -        bc->opened++;
  18452. -        MOD_INC_USE_COUNT;
  18453. -        return 0;
  18454. -    }
  18455. -    /*
  18456. -     * initialise some variables
  18457. -     */
  18458. -    bc->calibrate = 0;
  18459. -
  18460. -    /*
  18461. -     * allocate the buffer space
  18462. -     */
  18463. -    if (bc->rx_buf.buffer)
  18464. -        kfree_s(bc->rx_buf.buffer, bc->rx_buf.buflen);
  18465. -    if (bc->tx_buf.buffer)
  18466. -        kfree_s(bc->tx_buf.buffer, bc->tx_buf.buflen);
  18467. -    bc->rx_buf.buflen = BUFLEN_RX;
  18468. -    bc->tx_buf.buflen = BUFLEN_TX;
  18469. -    bc->rx_buf.rd = bc->rx_buf.wr = 0;
  18470. -    bc->tx_buf.rd = bc->tx_buf.wr = 0;
  18471. -    bc->rx_buf.buffer = kmalloc(bc->rx_buf.buflen, GFP_KERNEL);
  18472. -    bc->tx_buf.buffer = kmalloc(bc->tx_buf.buflen, GFP_KERNEL);
  18473. -    if (!bc->rx_buf.buffer || !bc->tx_buf.buffer) {
  18474. -        if (bc->rx_buf.buffer)
  18475. -            kfree_s(bc->rx_buf.buffer, bc->rx_buf.buflen);
  18476. -        if (bc->tx_buf.buffer)
  18477. -            kfree_s(bc->tx_buf.buffer, bc->tx_buf.buflen);
  18478. -        bc->rx_buf.buffer = bc->tx_buf.buffer = NULL;
  18479. -        bc->rx_buf.buflen = bc->tx_buf.buflen = 0;
  18480. -        return -ENOMEM;
  18481. -    }
  18482. -    /*
  18483. -     * check if the modem type has been set
  18484. -     */
  18485. -    switch(bc->modem_type) {
  18486. -    case BAYCOM_MODEM_SER12:
  18487. -        i = ser12_on_open(bc);
  18488. -        break;
  18489. -    case BAYCOM_MODEM_PAR96:
  18490. -        i = par96_on_open(bc);
  18491. -        break;
  18492. -    case BAYCOM_MODEM_INVALID:
  18493. -        /*
  18494. -         * may open even if no hardware specified, in order to
  18495. -         * subsequently allow the BAYCOMCTL_SETPARAMS ioctl
  18496. -         */
  18497. -        i = 0;
  18498. -        break;
  18499. -    default:
  18500. -        return -ENODEV;
  18501. -    }
  18502. -    if (i) 
  18503. -        return i;
  18504. -
  18505. -    bc->opened++;
  18506. -    MOD_INC_USE_COUNT;
  18507. -
  18508. -    tty->driver_data = bc;
  18509. -    bc->tty = tty;
  18510. -
  18511. -    return 0;   
  18512. -}
  18513. -
  18514. -
  18515. -/* --------------------------------------------------------------------- */
  18516. -    
  18517. -static void baycom_close(struct tty_struct *tty, struct file * filp)
  18518. -{
  18519. -    struct baycom_state *bc;
  18520. -        
  18521. -    if(!tty) return;
  18522. -    if (baycom_paranoia_check(bc = tty->driver_data, "close"))
  18523. -        return;
  18524. -
  18525. -    MOD_DEC_USE_COUNT;
  18526. -    bc->opened--;
  18527. -    if (bc->opened <= 0) {
  18528. -        switch(bc->modem_type) {
  18529. -        case BAYCOM_MODEM_SER12:
  18530. -            ser12_on_close(bc);
  18531. -            break;
  18532. -        case BAYCOM_MODEM_PAR96:
  18533. -            par96_on_close(bc);
  18534. -            break;
  18535. -        }
  18536. -        tty->driver_data = NULL;
  18537. -        bc->tty = NULL;
  18538. -        bc->opened = 0;
  18539. -        /*
  18540. -         * free the buffers 
  18541. -         */
  18542. -        bc->rx_buf.rd = bc->rx_buf.wr = 0;
  18543. -        bc->tx_buf.rd = bc->tx_buf.wr = 0;
  18544. -        if (bc->rx_buf.buffer)
  18545. -            kfree_s(bc->rx_buf.buffer, bc->rx_buf.buflen);
  18546. -        if (bc->tx_buf.buffer)
  18547. -            kfree_s(bc->tx_buf.buffer, bc->tx_buf.buflen);
  18548. -        bc->rx_buf.buffer = bc->tx_buf.buffer = NULL;
  18549. -        bc->rx_buf.buflen = bc->tx_buf.buflen = 0;
  18550. -    }
  18551. -}
  18552. -
  18553. -/* --------------------------------------------------------------------- */
  18554. -/*
  18555. - * And now the modules code and kernel interface.
  18556. - */
  18557. -
  18558. -static void init_channel(struct baycom_state *bc)
  18559. -{
  18560. -    struct access_params dflt_ch_params = { 20, 2, 10, 40, 0 };
  18561. -
  18562. -    if (!bc)
  18563. -        return;
  18564. -
  18565. -    bc->hdlc_rx.rx_state = 0;
  18566. -
  18567. -    bc->hdlc_tx.tx_state = bc->hdlc_tx.numflags = 0;
  18568. -    bc->hdlc_tx.bitstream = 0;
  18569. -    bc->hdlc_tx.current_byte = bc->hdlc_tx.ptt = 0;
  18570. -
  18571. -    memset(&bc->modem, 0, sizeof(bc->modem));
  18572. -
  18573. -#ifdef BAYCOM_DEBUG
  18574. -    bc->bitbuf_channel.rd = bc->bitbuf_channel.wr = 0;
  18575. -    bc->bitbuf_channel.shreg = 0x80;
  18576. -
  18577. -    bc->bitbuf_hdlc.rd = bc->bitbuf_hdlc.wr = 0;
  18578. -    bc->bitbuf_hdlc.shreg = 0x80;
  18579. -#endif /* BAYCOM_DEBUG */
  18580. -
  18581. -    bc->kiss_decode.dec_state = bc->kiss_decode.escaped = 
  18582. -    bc->kiss_decode.wr = 0;
  18583. -
  18584. -    bc->ch_params = dflt_ch_params;
  18585. -
  18586. -#ifdef BAYCOM_USE_BH
  18587. -    bc->tq_receiver.next = bc->tq_transmitter.next =
  18588. -        bc->tq_arbitrate.next = NULL;
  18589. -    bc->tq_receiver.sync = bc->tq_transmitter.sync =
  18590. -        bc->tq_arbitrate.sync = 0;
  18591. -    bc->tq_receiver.data = bc->tq_transmitter.data =
  18592. -        bc->tq_arbitrate.data = bc;
  18593. -    bc->tq_receiver.routine = bh_receiver;
  18594. -    bc->tq_transmitter.routine = bh_transmitter;
  18595. -    bc->tq_arbitrate.routine = bh_arbitrate;
  18596. -#endif /* BAYCOM_USE_BH */
  18597. -}
  18598. -
  18599. -static void init_datastructs(void)
  18600. -{
  18601. -    int i;
  18602. -
  18603. -    for(i = 0; i < NR_PORTS; i++) {
  18604. -        struct baycom_state *bc = baycom_state+i;
  18605. -
  18606. -        bc->magic = BAYCOM_MAGIC;
  18607. -        bc->modem_type = BAYCOM_MODEM_INVALID;
  18608. -        bc->iobase = bc->irq = bc->options = bc->opened = 0;
  18609. -        bc->tty = NULL;
  18610. -
  18611. -        bc->rx_buf.rd = bc->rx_buf.wr = 0;
  18612. -        bc->rx_buf.buflen = 0;
  18613. -        bc->rx_buf.buffer = NULL;
  18614. -
  18615. -        bc->tx_buf.rd = bc->tx_buf.wr = 0;
  18616. -        bc->tx_buf.buflen = 0;
  18617. -        bc->tx_buf.buffer = NULL;
  18618. -
  18619. -        memset(&bc->stat, 0, sizeof(bc->stat));
  18620. -
  18621. -        init_channel(bc);
  18622. -    }
  18623. -}
  18624. -
  18625. -int baycom_init(void) {
  18626. -    int i, j;
  18627. -
  18628. -    /*
  18629. -     * initialize the data structures
  18630. -     */
  18631. -    init_datastructs();
  18632. -    /*
  18633. -     * initialize bottom half handler
  18634. -      */
  18635. -#ifdef BAYCOM_USE_BH
  18636. -    init_bh(BAYCOM_BH, baycom_bottom_half);
  18637. -#endif /* BAYCOM_USE_BH */
  18638. -    /*
  18639. -     * register the driver as tty driver
  18640. -     */
  18641. -    memset(&baycom_driver, 0, sizeof(struct tty_driver));
  18642. -    baycom_driver.magic = TTY_DRIVER_MAGIC;
  18643. -    baycom_driver.name = "baycom";
  18644. -    baycom_driver.major = major;
  18645. -    baycom_driver.minor_start = 0;
  18646. -    baycom_driver.num = NR_PORTS;
  18647. -    baycom_driver.type = TTY_DRIVER_TYPE_BAYCOM;
  18648. -    baycom_driver.subtype = BAYCOM_TYPE_NORMAL;
  18649. -    baycom_driver.init_termios.c_iflag = 0;
  18650. -    baycom_driver.init_termios.c_oflag = 0;
  18651. -    baycom_driver.init_termios.c_cflag = CS8 | B1200 | CREAD | CLOCAL;
  18652. -    baycom_driver.init_termios.c_lflag = 0;
  18653. -    baycom_driver.flags = TTY_DRIVER_REAL_RAW;
  18654. -    baycom_driver.refcount = &baycom_refcount;
  18655. -    baycom_driver.table = baycom_table;
  18656. -    baycom_driver.termios = baycom_termios;
  18657. -    baycom_driver.termios_locked = baycom_termios_locked;
  18658. -    /*
  18659. -     * the functions
  18660. -     */
  18661. -    baycom_driver.open = baycom_open;
  18662. -    baycom_driver.close = baycom_close;
  18663. -    baycom_driver.write = baycom_write;
  18664. -    baycom_driver.put_char = baycom_put_char;
  18665. -    baycom_driver.flush_chars = NULL;
  18666. -    baycom_driver.write_room = baycom_write_room;
  18667. -    baycom_driver.chars_in_buffer = baycom_chars_in_buffer;
  18668. -    baycom_driver.flush_buffer = baycom_flush_buffer;
  18669. -    baycom_driver.ioctl = baycom_ioctl;
  18670. -    /*
  18671. -     * cannot throttle the transmitter on this layer
  18672. -     */
  18673. -    baycom_driver.throttle = NULL;
  18674. -    baycom_driver.unthrottle = NULL;
  18675. -    /*
  18676. -     * no special actions on termio changes
  18677. -     */
  18678. -    baycom_driver.set_termios = NULL;
  18679. -    /*
  18680. -     * no XON/XOFF and no hangup on the radio port
  18681. -     */
  18682. -    baycom_driver.stop = NULL;
  18683. -    baycom_driver.start = NULL;
  18684. -    baycom_driver.hangup = NULL;
  18685. -    baycom_driver.set_ldisc = NULL;
  18686. -
  18687. -    if (tty_register_driver(&baycom_driver)) {
  18688. -        printk(KERN_WARNING "baycom: tty_register_driver failed\n");
  18689. -        return -EIO;
  18690. -    }
  18691. -
  18692. -    for (i = 0; i < NR_PORTS && 
  18693. -         baycom_ports[i].modem != BAYCOM_MODEM_INVALID; i++) {
  18694. -        j = baycom_set_hardware(baycom_state+i, 
  18695. -                    baycom_ports[i].modem,
  18696. -                    baycom_ports[i].iobase, 
  18697. -                    baycom_ports[i].irq, 
  18698. -                    baycom_ports[i].options);
  18699. -        if (j < 0) {
  18700. -            const char *s;
  18701. -            switch (-j) {
  18702. -            case ENXIO:
  18703. -                s = "invalid iobase and/or irq";
  18704. -                break;
  18705. -            case EACCES:
  18706. -                s = "io region already used";
  18707. -                break;
  18708. -            case EIO:
  18709. -                s = "no uart/lpt port at iobase";
  18710. -                break;
  18711. -            case EBUSY:
  18712. -                s = "interface already in use";
  18713. -                break;
  18714. -            case EINVAL:
  18715. -                s = "internal error";
  18716. -                break;
  18717. -            default:
  18718. -                s = "unknown error";
  18719. -                break;
  18720. -            }
  18721. -            printk(KERN_WARNING "baycom: modem %u iobase 0x%x "
  18722. -                   "irq %u: (%i) %s\n", baycom_ports[i].modem, 
  18723. -                   baycom_ports[i].iobase, baycom_ports[i].irq, 
  18724. -                   j, s);
  18725. -        }
  18726. -    }
  18727. -
  18728. -    return 0;
  18729. -}
  18730. -
  18731. -/* --------------------------------------------------------------------- */
  18732. -
  18733. -#ifdef MODULE
  18734. -
  18735. -int modem = BAYCOM_MODEM_INVALID;
  18736. -int iobase = 0x3f8;
  18737. -int irq = 4;
  18738. -int options = BAYCOM_OPTIONS_SOFTDCD;
  18739. -
  18740. -int init_module(void)
  18741. -{
  18742. -    int i;
  18743. -
  18744. -    printk(KERN_INFO "baycom: init_module called\n");
  18745. -
  18746. -    baycom_ports[0].modem = modem;
  18747. -    baycom_ports[0].iobase = iobase;
  18748. -    baycom_ports[0].irq = irq;
  18749. -    baycom_ports[0].options = options;
  18750. -    baycom_ports[1].modem = BAYCOM_MODEM_INVALID;
  18751. -
  18752. -    i = baycom_init();
  18753. -    if (i)
  18754. -        return i;
  18755. -
  18756. -    printk(KERN_INFO "baycom: version 0.3; "
  18757. -           "(C) 1996 by Thomas Sailer HB9JNX, sailer@ife.ee.ethz.ch\n");
  18758. -
  18759. -    return 0;
  18760. -}
  18761. -
  18762. -/* --------------------------------------------------------------------- */
  18763. -
  18764. -void cleanup_module(void)
  18765. -{
  18766. -    int i;
  18767. -
  18768. -    printk(KERN_INFO "baycom: cleanup_module called\n");
  18769. -
  18770. -    disable_bh(BAYCOM_BH);
  18771. -    if (tty_unregister_driver(&baycom_driver))
  18772. -        printk(KERN_WARNING "baycom: failed to unregister tty "
  18773. -               "driver\n");
  18774. -    for(i = 0; i < NR_PORTS; i++) {
  18775. -        struct baycom_state *bc = baycom_state+i;
  18776. -
  18777. -        if (bc->magic != BAYCOM_MAGIC)
  18778. -            printk(KERN_ERR "baycom: invalid magic in "
  18779. -                   "cleanup_module\n");
  18780. -        else {
  18781. -            baycom_dealloc_hw(bc);
  18782. -            /*
  18783. -             * free the buffers 
  18784. -             */
  18785. -            bc->rx_buf.rd = bc->rx_buf.wr = 0;
  18786. -            bc->tx_buf.rd = bc->tx_buf.wr = 0;
  18787. -            if (bc->rx_buf.buffer)
  18788. -                kfree_s(bc->rx_buf.buffer, bc->rx_buf.buflen);
  18789. -            if (bc->tx_buf.buffer)
  18790. -                kfree_s(bc->tx_buf.buffer, bc->tx_buf.buflen);
  18791. -            bc->rx_buf.buffer = bc->tx_buf.buffer = NULL;
  18792. -            bc->rx_buf.buflen = bc->tx_buf.buflen = 0;
  18793. -        }
  18794. -    }
  18795. -}
  18796. -
  18797. -#else /* MODULE */
  18798. -/* --------------------------------------------------------------------- */
  18799. -/*
  18800. - * format: baycom=modem,io,irq,options[,modem,io,irq,options]
  18801. - * modem=1: ser12, modem=2: par96
  18802. - * options=0: hardware DCD, options=1: software DCD
  18803. - */
  18804. -
  18805. -void baycom_setup(char *str, int *ints)
  18806. -{
  18807. -    int i;
  18808. -
  18809. -    for (i = 0; i < NR_PORTS; i++) 
  18810. -        if (ints[0] >= 4*i+4) {
  18811. -            baycom_ports[i].modem = ints[4*i+1];
  18812. -            baycom_ports[i].iobase = ints[4*i+2];
  18813. -            baycom_ports[i].irq = ints[4*i+3];
  18814. -            baycom_ports[i].options = ints[4*i+4];
  18815. -        } else
  18816. -            baycom_ports[i].modem = BAYCOM_MODEM_INVALID;
  18817. -
  18818. -}
  18819. -
  18820. -#endif /* MODULE */
  18821. -/* --------------------------------------------------------------------- */
  18822. diff -u --recursive --new-file v2.0.34/linux/drivers/char/ftape/ftape-bsm.h linux/drivers/char/ftape/ftape-bsm.h
  18823. --- v2.0.34/linux/drivers/char/ftape/ftape-bsm.h    Wed Mar  6 05:07:19 1996
  18824. +++ linux/drivers/char/ftape/ftape-bsm.h    Mon Jul 13 13:47:29 1998
  18825. @@ -44,7 +44,7 @@
  18826.  /*
  18827.   *      ftape-io.c defined global vars.
  18828.   */
  18829. -extern bad_sector_map_changed;
  18830. +extern int bad_sector_map_changed;
  18831.  
  18832.  /*
  18833.   *      ftape-io.c defined global functions.
  18834. diff -u --recursive --new-file v2.0.34/linux/drivers/char/ftape/ftape-ctl.h linux/drivers/char/ftape/ftape-ctl.h
  18835. --- v2.0.34/linux/drivers/char/ftape/ftape-ctl.h    Wed Oct 15 15:10:48 1997
  18836. +++ linux/drivers/char/ftape/ftape-ctl.h    Mon Jul 13 13:47:29 1998
  18837. @@ -61,7 +61,7 @@
  18838.   */
  18839.  extern int ftape_failure;
  18840.  extern int write_protected;
  18841. -extern ftape_offline;
  18842. +extern int ftape_offline;
  18843.  extern int formatted;
  18844.  extern int no_tape;
  18845.  extern history_record history;
  18846. diff -u --recursive --new-file v2.0.34/linux/drivers/char/ftape/kernel-interface.h linux/drivers/char/ftape/kernel-interface.h
  18847. --- v2.0.34/linux/drivers/char/ftape/kernel-interface.h    Wed Oct 15 15:10:48 1997
  18848. +++ linux/drivers/char/ftape/kernel-interface.h    Mon Jul 13 13:47:29 1998
  18849. @@ -59,7 +59,7 @@
  18850.  /*      kernel global functions not (yet) standard accessible
  18851.   *      (linked at load time by modules package).
  18852.   */
  18853. -asmlinkage extern sys_sgetmask(void);
  18854. -asmlinkage extern sys_ssetmask(int);
  18855. +asmlinkage extern int sys_sgetmask(void);
  18856. +asmlinkage extern int sys_ssetmask(int);
  18857.  
  18858.  #endif
  18859. diff -u --recursive --new-file v2.0.34/linux/drivers/char/istallion.c linux/drivers/char/istallion.c
  18860. --- v2.0.34/linux/drivers/char/istallion.c    Mon May  6 02:26:05 1996
  18861. +++ linux/drivers/char/istallion.c    Mon Jul 13 13:47:29 1998
  18862. @@ -3,6 +3,7 @@
  18863.  /*
  18864.   *    istallion.c  -- stallion intelligent multiport serial driver.
  18865.   *
  18866. + *    Copyright (C) 1996-1998  Stallion Technologies (support@stallion.oz.au).
  18867.   *    Copyright (C) 1994-1996  Greg Ungerer (gerg@stallion.oz.au).
  18868.   *
  18869.   *    This code is loosely based on the Linux serial driver, written by
  18870. @@ -73,6 +74,8 @@
  18871.  #define BRD_ECPE    24
  18872.  #define    BRD_ECPMC    25
  18873.  #define    BRD_ECHPCI    26
  18874. +#define    BRD_ECH64PCI    27
  18875. +#define    BRD_EASYIOPCI    28
  18876.  
  18877.  #define    BRD_BRUMBY    BRD_BRUMBY4
  18878.  
  18879. @@ -90,6 +93,12 @@
  18880.   *    boards can share the same shared memory address space. No interrupt
  18881.   *    is required for this board type.
  18882.   *    Another example:
  18883. + *        { BRD_ECPE, 0x5000, 0, 0x80000000, 0, 0 },
  18884. + *    This line will configure an EasyConnection 8/64 EISA in slot 5 and
  18885. + *    shared memory address of 0x80000000 (2 GByte). Multiple
  18886. + *    EasyConnection 8/64 EISA boards can share the same shared memory
  18887. + *    address space. No interrupt is required for this board type.
  18888. + *    Another example:
  18889.   *        { BRD_ONBOARD, 0x240, 0, 0xd0000, 0, 0 },
  18890.   *    This line will configure an ONboard (ISA type) at io address 240,
  18891.   *    and shared memory address of d0000. Multiple ONboards can share
  18892. @@ -156,8 +165,8 @@
  18893.   *    Define our local driver identity first. Set up stuff to deal with
  18894.   *    all the local structures required by a serial tty driver.
  18895.   */
  18896. -static char    *stli_drvname = "Stallion Intelligent Multiport Serial Driver";
  18897. -static char    *stli_drvversion = "1.1.3";
  18898. +static char    *stli_drvtitle = "Stallion Intelligent Multiport Serial Driver";
  18899. +static char    *stli_drvversion = "5.4.4";
  18900.  static char    *stli_serialname = "ttyE";
  18901.  static char    *stli_calloutname = "cue";
  18902.  
  18903. @@ -281,6 +290,8 @@
  18904.      "EC8/64-EI",
  18905.      "EC8/64-MC",
  18906.      "EC8/32-PCI",
  18907. +    "EC8/64-PCI",
  18908. +    "EasyIO-PCI",
  18909.  };
  18910.  
  18911.  /*
  18912. @@ -436,6 +447,7 @@
  18913.  #define    ECH_PNLSTATUS    2
  18914.  #define    ECH_PNL16PORT    0x20
  18915.  #define    ECH_PNLIDMASK    0x07
  18916. +#define    ECH_PNLXPID    0x40
  18917.  #define    ECH_PNLINTRPEND    0x80
  18918.  
  18919.  /*
  18920. @@ -473,9 +485,9 @@
  18921.  /*
  18922.   *    Define the maximal baud rate, and the default baud base for ports.
  18923.   */
  18924. -#define    STL_MAXBAUD    230400
  18925. +#define    STL_MAXBAUD    460800
  18926.  #define    STL_BAUDBASE    115200
  18927. -#define    STL_CLOSEDELAY    50
  18928. +#define    STL_CLOSEDELAY    (5 * HZ / 10)
  18929.  
  18930.  /*****************************************************************************/
  18931.  
  18932. @@ -492,7 +504,7 @@
  18933.   */
  18934.  static unsigned int    stli_baudrates[] = {
  18935.      0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
  18936. -    9600, 19200, 38400, 57600, 115200, 230400
  18937. +    9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
  18938.  };
  18939.  
  18940.  /*****************************************************************************/
  18941. @@ -530,19 +542,16 @@
  18942.  static void    stli_flushbuffer(struct tty_struct *tty);
  18943.  static void    stli_hangup(struct tty_struct *tty);
  18944.  
  18945. -static int    stli_initbrds(void);
  18946.  static int    stli_brdinit(stlibrd_t *brdp);
  18947. -static int    stli_initecp(stlibrd_t *brdp);
  18948. -static int    stli_initonb(stlibrd_t *brdp);
  18949. -static int    stli_eisamemprobe(stlibrd_t *brdp);
  18950. -static int    stli_findeisabrds(void);
  18951. -static int    stli_initports(stlibrd_t *brdp);
  18952.  static int    stli_startbrd(stlibrd_t *brdp);
  18953. +static int    stli_memopen(struct inode *ip, struct file *fp);
  18954. +static void    stli_memclose(struct inode *ip, struct file *fp);
  18955.  static int    stli_memread(struct inode *ip, struct file *fp, char *buf, int count);
  18956.  static int    stli_memwrite(struct inode *ip, struct file *fp, const char *buf, int count);
  18957.  static int    stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
  18958. +static void    stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp);
  18959.  static void    stli_poll(unsigned long arg);
  18960. -static int    stli_hostcmd(stlibrd_t *brdp, int channr);
  18961. +static int    stli_hostcmd(stlibrd_t *brdp, stliport_t *portp);
  18962.  static int    stli_initopen(stlibrd_t *brdp, stliport_t *portp);
  18963.  static int    stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
  18964.  static int    stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
  18965. @@ -561,6 +570,7 @@
  18966.  static int    stli_setserial(stliport_t *portp, struct serial_struct *sp);
  18967.  static int    stli_getbrdstats(combrd_t *bp);
  18968.  static int    stli_getportstats(stliport_t *portp, comstats_t *cp);
  18969. +static int    stli_portcmdstats(stliport_t *portp);
  18970.  static int    stli_clrportstats(stliport_t *portp, comstats_t *cp);
  18971.  static int    stli_getportstruct(unsigned long arg);
  18972.  static int    stli_getbrdstruct(unsigned long arg);
  18973. @@ -601,6 +611,13 @@
  18974.  
  18975.  static stliport_t *stli_getport(int brdnr, int panelnr, int portnr);
  18976.  
  18977. +static inline int    stli_initbrds(void);
  18978. +static inline int    stli_initecp(stlibrd_t *brdp);
  18979. +static inline int    stli_initonb(stlibrd_t *brdp);
  18980. +static inline int    stli_findeisabrds(void);
  18981. +static inline int    stli_eisamemprobe(stlibrd_t *brdp);
  18982. +static inline int    stli_initports(stlibrd_t *brdp);
  18983. +
  18984.  /*****************************************************************************/
  18985.  
  18986.  /*
  18987. @@ -617,8 +634,8 @@
  18988.      NULL,
  18989.      stli_memioctl,
  18990.      NULL,
  18991. -    NULL,
  18992. -    NULL,
  18993. +    stli_memopen,
  18994. +    stli_memclose,
  18995.      NULL
  18996.  };
  18997.  
  18998. @@ -678,7 +695,8 @@
  18999.      printk("cleanup_module()\n");
  19000.  #endif
  19001.  
  19002. -    printk(KERN_INFO "Unloading %s: version %s\n", stli_drvname, stli_drvversion);
  19003. +    printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle,
  19004. +        stli_drvversion);
  19005.  
  19006.      save_flags(flags);
  19007.      cli();
  19008. @@ -695,12 +713,14 @@
  19009.      i = tty_unregister_driver(&stli_serial);
  19010.      j = tty_unregister_driver(&stli_callout);
  19011.      if (i || j) {
  19012. -        printk("STALLION: failed to un-register tty driver, errno=%d,%d\n", -i, -j);
  19013. +        printk("STALLION: failed to un-register tty driver, "
  19014. +            "errno=%d,%d\n", -i, -j);
  19015.          restore_flags(flags);
  19016.          return;
  19017.      }
  19018.      if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
  19019. -        printk("STALLION: failed to un-register serial memory device, errno=%d\n", -i);
  19020. +        printk("STALLION: failed to un-register serial memory device, "
  19021. +            "errno=%d\n", -i);
  19022.  
  19023.      if (stli_tmpwritebuf != (char *) NULL)
  19024.          kfree_s(stli_tmpwritebuf, STLI_TXBUFSIZE);
  19025. @@ -722,10 +742,8 @@
  19026.  
  19027.          if (brdp->memaddr >= 0x100000)
  19028.              vfree(brdp->membase);
  19029. -        if ((brdp->brdtype == BRD_ECP) || (brdp->brdtype == BRD_ECPE) || (brdp->brdtype == BRD_ECPMC))
  19030. -            release_region(brdp->iobase, ECP_IOSIZE);
  19031. -        else
  19032. -            release_region(brdp->iobase, ONB_IOSIZE);
  19033. +        if (brdp->iosize > 0)
  19034. +            release_region(brdp->iobase, brdp->iosize);
  19035.          kfree_s(brdp, sizeof(stlibrd_t));
  19036.          stli_brds[i] = (stlibrd_t *) NULL;
  19037.      }
  19038. @@ -756,7 +774,8 @@
  19039.      int        brdnr, portnr, rc;
  19040.  
  19041.  #if DEBUG
  19042. -    printk("stli_open(tty=%x,filp=%x): device=%x\n", (int) tty, (int) filp, tty->device);
  19043. +    printk("stli_open(tty=%x,filp=%x): device=%x\n", (int) tty,
  19044. +        (int) filp, tty->device);
  19045.  #endif
  19046.  
  19047.      minordev = MINOR(tty->device);
  19048. @@ -778,6 +797,8 @@
  19049.      if (portp->devnr < 1)
  19050.          return(-ENODEV);
  19051.  
  19052. +    MOD_INC_USE_COUNT;
  19053. +
  19054.  /*
  19055.   *    Check if this port is in the middle of closing. If so then wait
  19056.   *    until it is closed then return error status based on flag settings.
  19057. @@ -842,10 +863,10 @@
  19058.              return(-EBUSY);
  19059.          if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
  19060.              if ((portp->flags & ASYNC_SESSION_LOCKOUT) &&
  19061. -                    (portp->session != current->session))
  19062. +                (portp->session != current->session))
  19063.                  return(-EBUSY);
  19064.              if ((portp->flags & ASYNC_PGRP_LOCKOUT) &&
  19065. -                    (portp->pgrp != current->pgrp))
  19066. +                (portp->pgrp != current->pgrp))
  19067.                  return(-EBUSY);
  19068.          }
  19069.          portp->flags |= ASYNC_CALLOUT_ACTIVE;
  19070. @@ -892,10 +913,14 @@
  19071.      save_flags(flags);
  19072.      cli();
  19073.      if (tty_hung_up_p(filp)) {
  19074. +        MOD_DEC_USE_COUNT;
  19075.          restore_flags(flags);
  19076.          return;
  19077.      }
  19078. +    if ((tty->count == 1) && (portp->refcount != 1))
  19079. +        portp->refcount = 1;
  19080.      if (portp->refcount-- > 1) {
  19081. +        MOD_DEC_USE_COUNT;
  19082.          restore_flags(flags);
  19083.          return;
  19084.      }
  19085. @@ -916,10 +941,8 @@
  19086.      if (tty == stli_txcooktty)
  19087.          stli_flushchars(tty);
  19088.      tty->closing = 1;
  19089. -    if (test_bit(ST_TXBUSY, &portp->state)) {
  19090. -        if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
  19091. -            tty_wait_until_sent(tty, portp->closing_wait);
  19092. -    }
  19093. +    if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
  19094. +        tty_wait_until_sent(tty, portp->closing_wait);
  19095.  
  19096.      portp->flags &= ~ASYNC_INITIALIZED;
  19097.      brdp = stli_brds[portp->brdnr];
  19098. @@ -929,7 +952,8 @@
  19099.          if (test_bit(ST_CMDING, &portp->state))
  19100.              set_bit(ST_DOSIGS, &portp->state);
  19101.          else
  19102. -            stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
  19103. +            stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig,
  19104. +                sizeof(asysigs_t), 0);
  19105.      }
  19106.      clear_bit(ST_TXBUSY, &portp->state);
  19107.      clear_bit(ST_RXSTOP, &portp->state);
  19108. @@ -940,7 +964,6 @@
  19109.      stli_flushbuffer(tty);
  19110.  
  19111.      tty->closing = 0;
  19112. -    tty->driver_data = (void *) NULL;
  19113.      portp->tty = (struct tty_struct *) NULL;
  19114.  
  19115.      if (portp->openwaitcnt) {
  19116. @@ -949,8 +972,10 @@
  19117.          wake_up_interruptible(&portp->open_wait);
  19118.      }
  19119.  
  19120. -    portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
  19121. +    portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE |
  19122. +        ASYNC_CLOSING);
  19123.      wake_up_interruptible(&portp->close_wait);
  19124. +    MOD_DEC_USE_COUNT;
  19125.      restore_flags(flags);
  19126.  }
  19127.  
  19128. @@ -981,23 +1006,27 @@
  19129.      memset(&nt, 0, sizeof(asynotify_t));
  19130.      nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK);
  19131.      nt.signal = SG_DCD;
  19132. -    if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt, sizeof(asynotify_t), 0)) < 0)
  19133. +    if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt,
  19134. +        sizeof(asynotify_t), 0)) < 0)
  19135.          return(rc);
  19136.  
  19137.      tty = portp->tty;
  19138.      if (tty == (struct tty_struct *) NULL)
  19139.          return(-ENODEV);
  19140.      stli_mkasyport(portp, &aport, tty->termios);
  19141. -    if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)) < 0)
  19142. +    if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport,
  19143. +        sizeof(asyport_t), 0)) < 0)
  19144.          return(rc);
  19145.  
  19146.      set_bit(ST_GETSIGS, &portp->state);
  19147. -    if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0)
  19148. +    if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig,
  19149. +        sizeof(asysigs_t), 1)) < 0)
  19150.          return(rc);
  19151.      if (clear_bit(ST_GETSIGS, &portp->state))
  19152.          portp->sigs = stli_mktiocm(portp->asig.sigvalue);
  19153.      stli_mkasysigs(&portp->asig, 1, 1);
  19154. -    if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0)) < 0)
  19155. +    if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
  19156. +        sizeof(asysigs_t), 0)) < 0)
  19157.          return(rc);
  19158.  
  19159.      return(0);
  19160. @@ -1021,7 +1050,8 @@
  19161.      int            rc;
  19162.  
  19163.  #if DEBUG
  19164. -    printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n", (int) brdp, (int) portp, (int) arg, wait);
  19165. +    printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n",
  19166. +        (int) brdp, (int) portp, (int) arg, wait);
  19167.  #endif
  19168.  
  19169.  /*
  19170. @@ -1054,8 +1084,8 @@
  19171.      cp->openarg = arg;
  19172.      cp->open = 1;
  19173.      hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
  19174. -    hdrp->slavereq |= portp->reqbit;
  19175. -    bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
  19176. +    bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
  19177. +        portp->portidx;
  19178.      *bits |= portp->portbit;
  19179.      EBRDDISABLE(brdp);
  19180.  
  19181. @@ -1101,7 +1131,8 @@
  19182.      int            rc;
  19183.  
  19184.  #if DEBUG
  19185. -    printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n", (int) brdp, (int) portp, (int) arg, wait);
  19186. +    printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n",
  19187. +        (int) brdp, (int) portp, (int) arg, wait);
  19188.  #endif
  19189.  
  19190.      save_flags(flags);
  19191. @@ -1129,8 +1160,8 @@
  19192.      cp->closearg = arg;
  19193.      cp->close = 1;
  19194.      hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
  19195. -    hdrp->slavereq |= portp->reqbit;
  19196. -    bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
  19197. +    bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
  19198. +        portp->portidx;
  19199.      *bits |= portp->portbit;
  19200.      EBRDDISABLE(brdp);
  19201.  
  19202. @@ -1173,7 +1204,9 @@
  19203.      unsigned long    flags;
  19204.  
  19205.  #if DEBUG
  19206. -    printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, (int) arg, size, copyback);
  19207. +    printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
  19208. +        "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
  19209. +        (int) arg, size, copyback);
  19210.  #endif
  19211.  
  19212.      save_flags(flags);
  19213. @@ -1243,7 +1276,7 @@
  19214.  static void stli_delay(int len)
  19215.  {
  19216.  #if DEBUG
  19217. -    printk("stl_delay(len=%d)\n", len);
  19218. +    printk("stli_delay(len=%d)\n", len);
  19219.  #endif
  19220.      if (len > 0) {
  19221.          current->state = TASK_INTERRUPTIBLE;
  19222. @@ -1265,7 +1298,8 @@
  19223.      int        rc, doclocal;
  19224.  
  19225.  #if DEBUG
  19226. -    printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n", (int) brdp, (int) portp, (int) filp);
  19227. +    printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n",
  19228. +        (int) brdp, (int) portp, (int) filp);
  19229.  #endif
  19230.  
  19231.      rc = 0;
  19232. @@ -1282,16 +1316,18 @@
  19233.      save_flags(flags);
  19234.      cli();
  19235.      portp->openwaitcnt++;
  19236. -    if (portp->refcount > 0)
  19237. +    if (! tty_hung_up_p(filp))
  19238.          portp->refcount--;
  19239.  
  19240.      for (;;) {
  19241.          if ((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) {
  19242.              stli_mkasysigs(&portp->asig, 1, 1);
  19243. -            if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0)) < 0)
  19244. +            if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
  19245. +                &portp->asig, sizeof(asysigs_t), 0)) < 0)
  19246.                  break;
  19247.          }
  19248. -        if (tty_hung_up_p(filp) || ((portp->flags & ASYNC_INITIALIZED) == 0)) {
  19249. +        if (tty_hung_up_p(filp) ||
  19250. +            ((portp->flags & ASYNC_INITIALIZED) == 0)) {
  19251.              if (portp->flags & ASYNC_HUP_NOTIFY)
  19252.                  rc = -EBUSY;
  19253.              else
  19254. @@ -1299,8 +1335,8 @@
  19255.              break;
  19256.          }
  19257.          if (((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) &&
  19258. -                ((portp->flags & ASYNC_CLOSING) == 0) &&
  19259. -                (doclocal || (portp->sigs & TIOCM_CD))) {
  19260. +            ((portp->flags & ASYNC_CLOSING) == 0) &&
  19261. +            (doclocal || (portp->sigs & TIOCM_CD))) {
  19262.              break;
  19263.          }
  19264.          if (current->signal & ~current->blocked) {
  19265. @@ -1338,10 +1374,12 @@
  19266.      unsigned long        flags;
  19267.  
  19268.  #if DEBUG
  19269. -    printk("stli_write(tty=%x,from_user=%d,buf=%x,count=%d)\n", (int) tty, from_user, (int) buf, count);
  19270. +    printk("stli_write(tty=%x,from_user=%d,buf=%x,count=%d)\n",
  19271. +        (int) tty, from_user, (int) buf, count);
  19272.  #endif
  19273.  
  19274. -    if ((tty == (struct tty_struct *) NULL) || (stli_tmpwritebuf == (char *) NULL))
  19275. +    if ((tty == (struct tty_struct *) NULL) ||
  19276. +        (stli_tmpwritebuf == (char *) NULL))
  19277.          return(0);
  19278.      if (tty == stli_txcooktty)
  19279.          stli_flushchars(tty);
  19280. @@ -1375,7 +1413,8 @@
  19281.          tail = (unsigned int) ap->txq.tail;
  19282.          if (tail != ((unsigned int) ap->txq.tail))
  19283.              tail = (unsigned int) ap->txq.tail;
  19284. -        len = (head >= tail) ? (portp->txsize - (head - tail) - 1) : (tail - head - 1);
  19285. +        len = (head >= tail) ? (portp->txsize - (head - tail) - 1) :
  19286. +            (tail - head - 1);
  19287.          count = MIN(len, count);
  19288.          EBRDDISABLE(brdp);
  19289.  
  19290. @@ -1430,8 +1469,8 @@
  19291.              ap->changed.data &= ~DT_TXEMPTY;
  19292.      }
  19293.      hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
  19294. -    hdrp->slavereq |= portp->reqbit;
  19295. -    bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
  19296. +    bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
  19297. +        portp->portidx;
  19298.      *bits |= portp->portbit;
  19299.      set_bit(ST_TXBUSY, &portp->state);
  19300.  
  19301. @@ -1562,8 +1601,8 @@
  19302.              ap->changed.data &= ~DT_TXEMPTY;
  19303.      }
  19304.      hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
  19305. -    hdrp->slavereq |= portp->reqbit;
  19306. -    bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
  19307. +    bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
  19308. +        portp->portidx;
  19309.      *bits |= portp->portbit;
  19310.      set_bit(ST_TXBUSY, &portp->state);
  19311.  
  19312. @@ -1729,12 +1768,14 @@
  19313.      memcpy_fromfs(&sio, sp, sizeof(struct serial_struct));
  19314.      if (!suser()) {
  19315.          if ((sio.baud_base != portp->baud_base) ||
  19316. -                (sio.close_delay != portp->close_delay) ||
  19317. -                ((sio.flags & ~ASYNC_USR_MASK) != (portp->flags & ~ASYNC_USR_MASK)))
  19318. +            (sio.close_delay != portp->close_delay) ||
  19319. +            ((sio.flags & ~ASYNC_USR_MASK) !=
  19320. +            (portp->flags & ~ASYNC_USR_MASK)))
  19321.              return(-EPERM);
  19322.      } 
  19323.  
  19324. -    portp->flags = (portp->flags & ~ASYNC_USR_MASK) | (sio.flags & ASYNC_USR_MASK);
  19325. +    portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
  19326. +        (sio.flags & ASYNC_USR_MASK);
  19327.      portp->baud_base = sio.baud_base;
  19328.      portp->close_delay = sio.close_delay;
  19329.      portp->closing_wait = sio.closing_wait;
  19330. @@ -1755,7 +1796,8 @@
  19331.      int        rc;
  19332.  
  19333.  #if DEBUG
  19334. -    printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n", (int) tty, (int) file, cmd, (int) arg);
  19335. +    printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n",
  19336. +        (int) tty, (int) file, cmd, (int) arg);
  19337.  #endif
  19338.  
  19339.      if (tty == (struct tty_struct *) NULL)
  19340. @@ -1769,6 +1811,12 @@
  19341.      if (brdp == (stlibrd_t *) NULL)
  19342.          return(0);
  19343.  
  19344. +    if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
  19345. +         (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
  19346. +        if (tty->flags & (1 << TTY_IO_ERROR))
  19347. +            return(-EIO);
  19348. +    }
  19349. +
  19350.      rc = 0;
  19351.  
  19352.      switch (cmd) {
  19353. @@ -1777,7 +1825,8 @@
  19354.              tty_wait_until_sent(tty, 0);
  19355.              if (! arg) {
  19356.                  val = 250;
  19357. -                rc = stli_cmdwait(brdp, portp, A_BREAK, &val, sizeof(unsigned long), 0);
  19358. +                rc = stli_cmdwait(brdp, portp, A_BREAK, &val,
  19359. +                    sizeof(unsigned long), 0);
  19360.              }
  19361.          }
  19362.          break;
  19363. @@ -1785,72 +1834,98 @@
  19364.          if ((rc = tty_check_change(tty)) == 0) {
  19365.              tty_wait_until_sent(tty, 0);
  19366.              val = (arg ? (arg * 100) : 250);
  19367. -            rc = stli_cmdwait(brdp, portp, A_BREAK, &val, sizeof(unsigned long), 0);
  19368. +            rc = stli_cmdwait(brdp, portp, A_BREAK, &val,
  19369. +                sizeof(unsigned long), 0);
  19370.          }
  19371.          break;
  19372.      case TIOCGSOFTCAR:
  19373. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long))) == 0)
  19374. -            put_fs_long(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), (unsigned long *) arg);
  19375. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  19376. +            sizeof(long))) == 0)
  19377. +            put_fs_long(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
  19378. +                (unsigned long *) arg);
  19379.          break;
  19380.      case TIOCSSOFTCAR:
  19381. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
  19382. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  19383. +            sizeof(long))) == 0) {
  19384.              arg = get_fs_long((unsigned long *) arg);
  19385. -            tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0);
  19386. +            tty->termios->c_cflag =
  19387. +                (tty->termios->c_cflag & ~CLOCAL) |
  19388. +                (arg ? CLOCAL : 0);
  19389.          }
  19390.          break;
  19391.      case TIOCMGET:
  19392. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned int))) == 0) {
  19393. -            if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0)
  19394. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  19395. +            sizeof(unsigned int))) == 0) {
  19396. +            if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS,
  19397. +                &portp->asig, sizeof(asysigs_t), 1)) < 0)
  19398.                  return(rc);
  19399.              val = stli_mktiocm(portp->asig.sigvalue);
  19400.              put_fs_long(val, (unsigned long *) arg);
  19401.          }
  19402.          break;
  19403.      case TIOCMBIS:
  19404. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
  19405. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  19406. +            sizeof(long))) == 0) {
  19407.              arg = get_fs_long((unsigned long *) arg);
  19408. -            stli_mkasysigs(&portp->asig, ((arg & TIOCM_DTR) ? 1 : -1), ((arg & TIOCM_RTS) ? 1 : -1));
  19409. -            rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
  19410. +            stli_mkasysigs(&portp->asig,
  19411. +                ((arg & TIOCM_DTR) ? 1 : -1),
  19412. +                ((arg & TIOCM_RTS) ? 1 : -1));
  19413. +            rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
  19414. +                &portp->asig, sizeof(asysigs_t), 0);
  19415.          }
  19416.          break;
  19417.      case TIOCMBIC:
  19418. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
  19419. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  19420. +            sizeof(long))) == 0) {
  19421.              arg = get_fs_long((unsigned long *) arg);
  19422. -            stli_mkasysigs(&portp->asig, ((arg & TIOCM_DTR) ? 0 : -1), ((arg & TIOCM_RTS) ? 0 : -1));
  19423. -            rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
  19424. +            stli_mkasysigs(&portp->asig,
  19425. +                ((arg & TIOCM_DTR) ? 0 : -1),
  19426. +                ((arg & TIOCM_RTS) ? 0 : -1));
  19427. +            rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
  19428. +                &portp->asig, sizeof(asysigs_t), 0);
  19429.          }
  19430.          break;
  19431.      case TIOCMSET:
  19432. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
  19433. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  19434. +            sizeof(long))) == 0) {
  19435.              arg = get_fs_long((unsigned long *) arg);
  19436. -            stli_mkasysigs(&portp->asig, ((arg & TIOCM_DTR) ? 1 : 0), ((arg & TIOCM_RTS) ? 1 : 0));
  19437. -            rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
  19438. +            stli_mkasysigs(&portp->asig,
  19439. +                ((arg & TIOCM_DTR) ? 1 : 0),
  19440. +                ((arg & TIOCM_RTS) ? 1 : 0));
  19441. +            rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
  19442. +                &portp->asig, sizeof(asysigs_t), 0);
  19443.          }
  19444.          break;
  19445.      case TIOCGSERIAL:
  19446. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct serial_struct))) == 0)
  19447. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  19448. +            sizeof(struct serial_struct))) == 0)
  19449.              stli_getserial(portp, (struct serial_struct *) arg);
  19450.          break;
  19451.      case TIOCSSERIAL:
  19452. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(struct serial_struct))) == 0)
  19453. -            rc = stli_setserial(portp, (struct serial_struct *) arg);
  19454. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  19455. +            sizeof(struct serial_struct))) == 0)
  19456. +            rc = stli_setserial(portp, (struct serial_struct *)arg);
  19457.          break;
  19458.      case STL_GETPFLAG:
  19459. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long))) == 0)
  19460. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  19461. +            sizeof(unsigned long))) == 0)
  19462.              put_fs_long(portp->pflag, (unsigned long *) arg);
  19463.          break;
  19464.      case STL_SETPFLAG:
  19465. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(unsigned long))) == 0) {
  19466. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  19467. +            sizeof(unsigned long))) == 0) {
  19468.              portp->pflag = get_fs_long((unsigned long *) arg);
  19469.              stli_setport(portp);
  19470.          }
  19471.          break;
  19472.      case COM_GETPORTSTATS:
  19473. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
  19474. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  19475. +            sizeof(comstats_t))) == 0)
  19476.              rc = stli_getportstats(portp, (comstats_t *) arg);
  19477.          break;
  19478.      case COM_CLRPORTSTATS:
  19479. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
  19480. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  19481. +            sizeof(comstats_t))) == 0)
  19482.              rc = stli_clrportstats(portp, (comstats_t *) arg);
  19483.          break;
  19484.      case TIOCSERCONFIG:
  19485. @@ -1898,13 +1973,15 @@
  19486.          return;
  19487.  
  19488.      tiosp = tty->termios;
  19489. -    if ((tiosp->c_cflag == old->c_cflag) && (tiosp->c_iflag == old->c_iflag))
  19490. +    if ((tiosp->c_cflag == old->c_cflag) &&
  19491. +        (tiosp->c_iflag == old->c_iflag))
  19492.          return;
  19493.  
  19494.      stli_mkasyport(portp, &aport, tiosp);
  19495.      stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0);
  19496.      stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1);
  19497. -    stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
  19498. +    stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
  19499. +        sizeof(asysigs_t), 0);
  19500.      if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0))
  19501.          tty->hw_stopped = 0;
  19502.      if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
  19503. @@ -1996,7 +2073,7 @@
  19504.      memset(&actrl, 0, sizeof(asyctrl_t));
  19505.      actrl.txctrl = CT_STOPFLOW;
  19506.  #if 0
  19507. -    stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t));
  19508. +    stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
  19509.  #endif
  19510.  }
  19511.  
  19512. @@ -2030,7 +2107,7 @@
  19513.      memset(&actrl, 0, sizeof(asyctrl_t));
  19514.      actrl.txctrl = CT_STARTFLOW;
  19515.  #if 0
  19516. -    stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t));
  19517. +    stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
  19518.  #endif
  19519.  }
  19520.  
  19521. @@ -2104,7 +2181,8 @@
  19522.              set_bit(ST_DOFLUSHTX, &portp->state);
  19523.              set_bit(ST_DOFLUSHRX, &portp->state);
  19524.          } else {
  19525. -            stli_sendcmd(brdp, portp, A_SETSIGNALSF, &portp->asig, sizeof(asysigs_t), 0);
  19526. +            stli_sendcmd(brdp, portp, A_SETSIGNALSF,
  19527. +                &portp->asig, sizeof(asysigs_t), 0);
  19528.          }
  19529.      }
  19530.      restore_flags(flags);
  19531. @@ -2112,7 +2190,6 @@
  19532.      clear_bit(ST_TXBUSY, &portp->state);
  19533.      clear_bit(ST_RXSTOP, &portp->state);
  19534.      set_bit(TTY_IO_ERROR, &tty->flags);
  19535. -    tty->driver_data = (void *) NULL;
  19536.      portp->tty = (struct tty_struct *) NULL;
  19537.      portp->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
  19538.      portp->refcount = 0;
  19539. @@ -2164,12 +2241,14 @@
  19540.              ftype |= FLUSHRX;
  19541.              clear_bit(ST_DOFLUSHRX, &portp->state);
  19542.          }
  19543. -        stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(unsigned long), 0);
  19544. +        stli_sendcmd(brdp, portp, A_FLUSH, &ftype,
  19545. +            sizeof(unsigned long), 0);
  19546.      }
  19547.      restore_flags(flags);
  19548.  
  19549.      wake_up_interruptible(&tty->write_wait);
  19550. -    if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
  19551. +    if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  19552. +        tty->ldisc.write_wakeup)
  19553.          (tty->ldisc.write_wakeup)(tty);
  19554.  }
  19555.  
  19556. @@ -2193,7 +2272,9 @@
  19557.      unsigned long        flags;
  19558.  
  19559.  #if DEBUG
  19560. -    printk("stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, (int) arg, size, copyback);
  19561. +    printk("stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
  19562. +        "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
  19563. +        (int) arg, size, copyback);
  19564.  #endif
  19565.  
  19566.      save_flags(flags);
  19567. @@ -2217,8 +2298,8 @@
  19568.      cp->status = 0;
  19569.      cp->cmd = cmd;
  19570.      hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
  19571. -    hdrp->slavereq |= portp->reqbit;
  19572. -    bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
  19573. +    bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
  19574. +        portp->portidx;
  19575.      *bits |= portp->portbit;
  19576.      set_bit(ST_CMDING, &portp->state);
  19577.      EBRDDISABLE(brdp);
  19578. @@ -2307,7 +2388,8 @@
  19579.      int    cmd;
  19580.  
  19581.      if (test_bit(ST_DOSIGS, &portp->state)) {
  19582. -        if (test_bit(ST_DOFLUSHTX, &portp->state) && test_bit(ST_DOFLUSHRX, &portp->state))
  19583. +        if (test_bit(ST_DOFLUSHTX, &portp->state) &&
  19584. +            test_bit(ST_DOFLUSHRX, &portp->state))
  19585.              cmd = A_SETSIGNALSF;
  19586.          else if (test_bit(ST_DOFLUSHTX, &portp->state))
  19587.              cmd = A_SETSIGNALSFTX;
  19588. @@ -2318,11 +2400,13 @@
  19589.          clear_bit(ST_DOFLUSHTX, &portp->state);
  19590.          clear_bit(ST_DOFLUSHRX, &portp->state);
  19591.          clear_bit(ST_DOSIGS, &portp->state);
  19592. -        memcpy((void *) &(cp->args[0]), (void *) &portp->asig, sizeof(asysigs_t));
  19593. +        memcpy((void *) &(cp->args[0]), (void *) &portp->asig,
  19594. +            sizeof(asysigs_t));
  19595.          cp->status = 0;
  19596.          cp->cmd = cmd;
  19597.          set_bit(ST_CMDING, &portp->state);
  19598. -    } else if (test_bit(ST_DOFLUSHTX, &portp->state) || test_bit(ST_DOFLUSHRX, &portp->state)) {
  19599. +    } else if (test_bit(ST_DOFLUSHTX, &portp->state) ||
  19600. +        test_bit(ST_DOFLUSHRX, &portp->state)) {
  19601.          cmd = ((test_bit(ST_DOFLUSHTX, &portp->state)) ? FLUSHTX : 0);
  19602.          cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0);
  19603.          clear_bit(ST_DOFLUSHTX, &portp->state);
  19604. @@ -2342,15 +2426,17 @@
  19605.   *    enabled and interrupts off when called. Notice that by servicing the
  19606.   *    read data last we don't need to change the shared memory pointer
  19607.   *    during processing (which is a slow IO operation).
  19608. + *    Return value indicates if this port is still awaiting actions from
  19609. + *    the slave (like open, command, or even TX data being sent). If 0
  19610. + *    then port is still busy, otherwise no longer busy.
  19611.   */
  19612.  
  19613. -static inline int stli_hostcmd(stlibrd_t *brdp, int channr)
  19614. +static inline int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
  19615.  {
  19616.      volatile cdkasy_t    *ap;
  19617.      volatile cdkctrl_t    *cp;
  19618.      struct tty_struct    *tty;
  19619.      asynotify_t        nt;
  19620. -    stliport_t        *portp;
  19621.      unsigned long        oldsigs;
  19622.      int            rc, donerx;
  19623.  
  19624. @@ -2358,7 +2444,6 @@
  19625.      printk("stli_hostcmd(brdp=%x,channr=%d)\n", (int) brdp, channr);
  19626.  #endif
  19627.  
  19628. -    portp = brdp->ports[(channr - 1)];
  19629.      ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
  19630.      cp = &ap->ctrl;
  19631.  
  19632. @@ -2402,7 +2487,8 @@
  19633.              if (rc > 0)
  19634.                  rc--;
  19635.              if (portp->argp != (void *) NULL) {
  19636. -                memcpy(portp->argp, (void *) &(cp->args[0]), portp->argsize);
  19637. +                memcpy(portp->argp, (void *) &(cp->args[0]),
  19638. +                    portp->argsize);
  19639.                  portp->argp = (void *) NULL;
  19640.              }
  19641.              cp->status = 0;
  19642. @@ -2429,12 +2515,14 @@
  19643.              oldsigs = portp->sigs;
  19644.              portp->sigs = stli_mktiocm(nt.sigvalue);
  19645.              clear_bit(ST_GETSIGS, &portp->state);
  19646. -            if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
  19647. +            if ((portp->sigs & TIOCM_CD) &&
  19648. +                ((oldsigs & TIOCM_CD) == 0))
  19649.                  wake_up_interruptible(&portp->open_wait);
  19650. -            if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) {
  19651. +            if ((oldsigs & TIOCM_CD) &&
  19652. +                ((portp->sigs & TIOCM_CD) == 0)) {
  19653.                  if (portp->flags & ASYNC_CHECK_CD) {
  19654.                      if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) &&
  19655. -                            (portp->flags & ASYNC_CALLOUT_NOHUP))) {
  19656. +                        (portp->flags & ASYNC_CALLOUT_NOHUP))) {
  19657.                          if (tty != (struct tty_struct *) NULL)
  19658.                              queue_task_irq_off(&portp->tqhangup, &tq_scheduler);
  19659.                      }
  19660. @@ -2446,7 +2534,8 @@
  19661.              clear_bit(ST_TXBUSY, &portp->state);
  19662.          if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {
  19663.              if (tty != (struct tty_struct *) NULL) {
  19664. -                if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {
  19665. +                if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  19666. +                    tty->ldisc.write_wakeup) {
  19667.                      (tty->ldisc.write_wakeup)(tty);
  19668.                      EBRDENABLE(brdp);
  19669.                  }
  19670. @@ -2460,12 +2549,10 @@
  19671.                      tty->flip.count++;
  19672.                      *tty->flip.flag_buf_ptr++ = TTY_BREAK;
  19673.                      *tty->flip.char_buf_ptr++ = 0;
  19674. -#ifndef MODULE
  19675.                      if (portp->flags & ASYNC_SAK) {
  19676.                          do_SAK(tty);
  19677.                          EBRDENABLE(brdp);
  19678.                      }
  19679. -#endif
  19680.                      tty_schedule_flip(tty);
  19681.                  }
  19682.              }
  19683. @@ -2490,7 +2577,74 @@
  19684.          stli_read(brdp, portp);
  19685.      }
  19686.  
  19687. -    return(0);
  19688. +    return((test_bit(ST_OPENING, &portp->state) ||
  19689. +        test_bit(ST_CLOSING, &portp->state) ||
  19690. +        test_bit(ST_CMDING, &portp->state) ||
  19691. +        test_bit(ST_TXBUSY, &portp->state) ||
  19692. +        test_bit(ST_RXING, &portp->state)) ? 0 : 1);
  19693. +}
  19694. +
  19695. +/*****************************************************************************/
  19696. +
  19697. +/*
  19698. + *    Service all ports on a particular board. Assumes that the boards
  19699. + *    shared memory is enabled, and that the page pointer is pointed
  19700. + *    at the cdk header structure.
  19701. + */
  19702. +
  19703. +static inline void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp)
  19704. +{
  19705. +    stliport_t    *portp;
  19706. +    unsigned char    hostbits[(STL_MAXCHANS / 8) + 1];
  19707. +    unsigned char    slavebits[(STL_MAXCHANS / 8) + 1];
  19708. +    unsigned char    *slavep;
  19709. +    int        bitpos, bitat, bitsize;
  19710. +    int         channr, nrdevs, slavebitchange;
  19711. +
  19712. +    bitsize = brdp->bitsize;
  19713. +    nrdevs = brdp->nrdevs;
  19714. +
  19715. +/*
  19716. + *    Check if slave wants any service. Basically we try to do as
  19717. + *    little work as possible here. There are 2 levels of service
  19718. + *    bits. So if there is nothing to do we bail early. We check
  19719. + *    8 service bits at a time in the inner loop, so we can bypass
  19720. + *    the lot if none of them want service.
  19721. + */
  19722. +    memcpy(&hostbits[0], (((unsigned char *) hdrp) + brdp->hostoffset),
  19723. +        bitsize);
  19724. +
  19725. +    memset(&slavebits[0], 0, bitsize);
  19726. +    slavebitchange = 0;
  19727. +
  19728. +    for (bitpos = 0; (bitpos < bitsize); bitpos++) {
  19729. +        if (hostbits[bitpos] == 0)
  19730. +            continue;
  19731. +        channr = bitpos * 8;
  19732. +        for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) {
  19733. +            if (hostbits[bitpos] & bitat) {
  19734. +                portp = brdp->ports[(channr - 1)];
  19735. +                if (stli_hostcmd(brdp, portp)) {
  19736. +                    slavebitchange++;
  19737. +                    slavebits[bitpos] |= bitat;
  19738. +                }
  19739. +            }
  19740. +        }
  19741. +    }
  19742. +
  19743. +/*
  19744. + *    If any of the ports are no longer busy then update them in the
  19745. + *    slave request bits. We need to do this after, since a host port
  19746. + *    service may initiate more slave requests.
  19747. + */
  19748. +    if (slavebitchange) {
  19749. +        hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
  19750. +        slavep = ((unsigned char *) hdrp) + brdp->slaveoffset;
  19751. +        for (bitpos = 0; (bitpos < bitsize); bitpos++) {
  19752. +            if (slavebits[bitpos])
  19753. +                slavep[bitpos] &= ~slavebits[bitpos];
  19754. +        }
  19755. +    }
  19756.  }
  19757.  
  19758.  /*****************************************************************************/
  19759. @@ -2507,12 +2661,8 @@
  19760.  static void stli_poll(unsigned long arg)
  19761.  {
  19762.      volatile cdkhdr_t    *hdrp;
  19763. -    unsigned char        bits[(STL_MAXCHANS / 8) + 1];
  19764. -    unsigned char        hostreq, slavereq;
  19765. -    stliport_t        *portp;
  19766.      stlibrd_t        *brdp;
  19767. -    int            bitpos, bitat, bitsize;
  19768. -    int             brdnr, channr, nrdevs;
  19769. +    int             brdnr;
  19770.  
  19771.      stli_timerlist.expires = STLI_TIMEOUT;
  19772.      add_timer(&stli_timerlist);
  19773. @@ -2529,67 +2679,8 @@
  19774.  
  19775.          EBRDENABLE(brdp);
  19776.          hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
  19777. -        hostreq = hdrp->hostreq;
  19778. -        slavereq = hdrp->slavereq;
  19779. -        bitsize = brdp->bitsize;
  19780. -        nrdevs = brdp->nrdevs;
  19781. -
  19782. -/*
  19783. - *        Check if slave wants any service. Basically we try to do as
  19784. - *        little work as possible here. There are 2 levels of service
  19785. - *        bits. So if there is nothing to do we bail early. We check
  19786. - *        8 service bits at a time in the inner loop, so we can bypass
  19787. - *        the lot if none of them want service.
  19788. - */
  19789. -        if (hostreq) {
  19790. -            memcpy(&bits[0], (((unsigned char *) hdrp) + brdp->hostoffset), bitsize);
  19791. -
  19792. -            for (bitpos = 0; (bitpos < bitsize); bitpos++) {
  19793. -                if (bits[bitpos] == 0)
  19794. -                    continue;
  19795. -                channr = bitpos * 8;
  19796. -                for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) {
  19797. -                    if (bits[bitpos] & bitat) {
  19798. -                        stli_hostcmd(brdp, channr);
  19799. -                    }
  19800. -                }
  19801. -            }
  19802. -        }
  19803. -
  19804. -/*
  19805. - *        Check if any of the out-standing host commands have completed.
  19806. - *        It is a bit unfortunate that we need to check stuff that we
  19807. - *        initiated!  This ain't pretty, but it needs to be fast.
  19808. - */
  19809. -        if (slavereq) {
  19810. -            slavereq = 0;
  19811. -            hostreq = 0;
  19812. -            memcpy(&bits[0], (((unsigned char *) hdrp) + brdp->slaveoffset), bitsize);
  19813. -
  19814. -            for (bitpos = 0; (bitpos < bitsize); bitpos++) {
  19815. -                if (bits[bitpos] == 0)
  19816. -                    continue;
  19817. -                channr = bitpos * 8;
  19818. -                for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) {
  19819. -                    if (bits[bitpos] & bitat) {
  19820. -                        portp = brdp->ports[(channr - 1)];
  19821. -                        if (test_bit(ST_OPENING, &portp->state) ||
  19822. -                                test_bit(ST_CLOSING, &portp->state) ||
  19823. -                                test_bit(ST_CMDING, &portp->state) ||
  19824. -                                test_bit(ST_TXBUSY, &portp->state)) {
  19825. -                            slavereq |= portp->reqbit;
  19826. -                        } else {
  19827. -                            bits[bitpos] &= ~bitat;
  19828. -                            hostreq++;
  19829. -                        }
  19830. -                    }
  19831. -                }
  19832. -            }
  19833. -            hdrp->slavereq = slavereq;
  19834. -            if (hostreq)
  19835. -                memcpy((((unsigned char *) hdrp) + brdp->slaveoffset), &bits[0], bitsize);
  19836. -        }
  19837. -
  19838. +        if (hdrp->hostreq)
  19839. +            stli_brdpoll(brdp, hdrp);
  19840.          EBRDDISABLE(brdp);
  19841.      }
  19842.  }
  19843. @@ -2604,7 +2695,8 @@
  19844.  static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp)
  19845.  {
  19846.  #if DEBUG
  19847. -    printk("stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n", (int) portp, (int) pp, (int) tiosp);
  19848. +    printk("stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n",
  19849. +        (int) portp, (int) pp, (int) tiosp);
  19850.  #endif
  19851.  
  19852.      memset(pp, 0, sizeof(asyport_t));
  19853. @@ -2615,7 +2707,7 @@
  19854.      pp->baudout = tiosp->c_cflag & CBAUD;
  19855.      if (pp->baudout & CBAUDEX) {
  19856.          pp->baudout &= ~CBAUDEX;
  19857. -        if ((pp->baudout < 1) || (pp->baudout > 2))
  19858. +        if ((pp->baudout < 1) || (pp->baudout > 5))
  19859.              tiosp->c_cflag &= ~CBAUDEX;
  19860.          else
  19861.              pp->baudout += 15;
  19862. @@ -2706,7 +2798,10 @@
  19863.  /*
  19864.   *    Transfer any persistent flags into the asyport structure.
  19865.   */
  19866. -    pp->pflag = portp->pflag;
  19867. +    pp->pflag = (portp->pflag & 0xffff);
  19868. +    pp->vmin = (portp->pflag & P_RXIMIN) ? 1 : 0;
  19869. +    pp->vtime = (portp->pflag & P_RXITIME) ? 1 : 0;
  19870. +    pp->cc[1] = (portp->pflag & P_RXTHOLD) ? 1 : 0;
  19871.  }
  19872.  
  19873.  /*****************************************************************************/
  19874. @@ -2765,7 +2860,7 @@
  19875.   *    we need to do here is set up the appropriate per port data structures.
  19876.   */
  19877.  
  19878. -static int stli_initports(stlibrd_t *brdp)
  19879. +static inline int stli_initports(stlibrd_t *brdp)
  19880.  {
  19881.      stliport_t    *portp;
  19882.      int        i, panelnr, panelport;
  19883. @@ -2855,11 +2950,14 @@
  19884.      unsigned char    val;
  19885.  
  19886.  #if DEBUG
  19887. -    printk("stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
  19888. +    printk("stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
  19889. +        (int) offset);
  19890.  #endif
  19891.  
  19892.      if (offset > brdp->memsize) {
  19893. -        printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
  19894. +        printk("STALLION: shared memory pointer=%x out of range at "
  19895. +            "line=%d(%d), brd=%d\n", (int) offset, line,
  19896. +            __LINE__, brdp->brdnr);
  19897.          ptr = 0;
  19898.          val = 0;
  19899.      } else {
  19900. @@ -2942,11 +3040,14 @@
  19901.      unsigned char    val;
  19902.  
  19903.  #if DEBUG
  19904. -    printk("stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n", (int) brdp, (int) offset, line);
  19905. +    printk("stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n",
  19906. +        (int) brdp, (int) offset, line);
  19907.  #endif
  19908.  
  19909.      if (offset > brdp->memsize) {
  19910. -        printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
  19911. +        printk("STALLION: shared memory pointer=%x out of range at "
  19912. +            "line=%d(%d), brd=%d\n", (int) offset, line,
  19913. +            __LINE__, brdp->brdnr);
  19914.          ptr = 0;
  19915.          val = 0;
  19916.      } else {
  19917. @@ -2996,7 +3097,9 @@
  19918.      unsigned char    val;
  19919.  
  19920.      if (offset > brdp->memsize) {
  19921. -        printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
  19922. +        printk("STALLION: shared memory pointer=%x out of range at "
  19923. +            "line=%d(%d), brd=%d\n", (int) offset, line,
  19924. +            __LINE__, brdp->brdnr);
  19925.          ptr = 0;
  19926.          val = 0;
  19927.      } else {
  19928. @@ -3071,11 +3174,14 @@
  19929.      void    *ptr;
  19930.  
  19931.  #if DEBUG
  19932. -    printk("stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
  19933. +    printk("stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
  19934. +        (int) offset);
  19935.  #endif
  19936.  
  19937.      if (offset > brdp->memsize) {
  19938. -        printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
  19939. +        printk("STALLION: shared memory pointer=%x out of range at "
  19940. +            "line=%d(%d), brd=%d\n", (int) offset, line,
  19941. +            __LINE__, brdp->brdnr);
  19942.          ptr = 0;
  19943.      } else {
  19944.          ptr = brdp->membase + (offset % ONB_ATPAGESIZE);
  19945. @@ -3158,11 +3264,14 @@
  19946.      unsigned char    val;
  19947.  
  19948.  #if DEBUG
  19949. -    printk("stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n", (int) brdp, (int) offset, line);
  19950. +    printk("stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n",
  19951. +        (int) brdp, (int) offset, line);
  19952.  #endif
  19953.  
  19954.      if (offset > brdp->memsize) {
  19955. -        printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
  19956. +        printk("STALLION: shared memory pointer=%x out of range at "
  19957. +            "line=%d(%d), brd=%d\n", (int) offset, line,
  19958. +            __LINE__, brdp->brdnr);
  19959.          ptr = 0;
  19960.          val = 0;
  19961.      } else {
  19962. @@ -3224,11 +3333,14 @@
  19963.      unsigned char    val;
  19964.  
  19965.  #if DEBUG
  19966. -    printk("stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
  19967. +    printk("stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
  19968. +        (int) offset);
  19969.  #endif
  19970.  
  19971.      if (offset > brdp->memsize) {
  19972. -        printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
  19973. +        printk("STALLION: shared memory pointer=%x out of range at "
  19974. +            "line=%d(%d), brd=%d\n", (int) offset, line,
  19975. +            __LINE__, brdp->brdnr);
  19976.          ptr = 0;
  19977.          val = 0;
  19978.      } else {
  19979. @@ -3282,11 +3394,14 @@
  19980.      void    *ptr;
  19981.  
  19982.  #if DEBUG
  19983. -    printk("stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
  19984. +    printk("stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
  19985. +        (int) offset);
  19986.  #endif
  19987.  
  19988.      if (offset > brdp->memsize) {
  19989. -        printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
  19990. +        printk("STALLION: shared memory pointer=%x out of range at "
  19991. +            "line=%d(%d), brd=%d\n", (int) offset, line,
  19992. +            __LINE__, brdp->brdnr);
  19993.          ptr = 0;
  19994.      } else {
  19995.          ptr = brdp->membase + (offset % STAL_PAGESIZE);
  19996. @@ -3319,12 +3434,13 @@
  19997.   *    board types.
  19998.   */
  19999.  
  20000. -static int stli_initecp(stlibrd_t *brdp)
  20001. +static inline int stli_initecp(stlibrd_t *brdp)
  20002.  {
  20003.      cdkecpsig_t    sig;
  20004.      cdkecpsig_t    *sigsp;
  20005.      unsigned int    status, nxtid;
  20006. -    int        panelnr;
  20007. +    char        *name;
  20008. +    int        panelnr, nrports;
  20009.  
  20010.  #if DEBUG
  20011.      printk("stli_initecp(brdp=%x)\n", (int) brdp);
  20012. @@ -3336,6 +3452,11 @@
  20013.      if ((brdp->iobase == 0) || (brdp->memaddr == 0))
  20014.          return(-ENODEV);
  20015.  
  20016. +    brdp->iosize = ECP_IOSIZE;
  20017. +    if (check_region(brdp->iobase, brdp->iosize))
  20018. +        printk("STALLION: Warning, unit %d I/O address %x conflicts "
  20019. +            "with another device\n", brdp->brdnr, brdp->iobase);
  20020. +
  20021.  /*
  20022.   *    Based on the specific board type setup the common vars to access
  20023.   *    and enable shared memory. Set all board specific information now
  20024. @@ -3353,6 +3474,7 @@
  20025.          brdp->getmemptr = stli_ecpgetmemptr;
  20026.          brdp->intr = stli_ecpintr;
  20027.          brdp->reset = stli_ecpreset;
  20028. +        name = "serial(EC8/64)";
  20029.          break;
  20030.  
  20031.      case BRD_ECPE:
  20032. @@ -3366,6 +3488,7 @@
  20033.          brdp->getmemptr = stli_ecpeigetmemptr;
  20034.          brdp->intr = stli_ecpintr;
  20035.          brdp->reset = stli_ecpeireset;
  20036. +        name = "serial(EC8/64-EI)";
  20037.          break;
  20038.  
  20039.      case BRD_ECPMC:
  20040. @@ -3379,6 +3502,7 @@
  20041.          brdp->getmemptr = stli_ecpmcgetmemptr;
  20042.          brdp->intr = stli_ecpintr;
  20043.          brdp->reset = stli_ecpmcreset;
  20044. +        name = "serial(EC8/64-MCA)";
  20045.          break;
  20046.  
  20047.      default:
  20048. @@ -3410,10 +3534,11 @@
  20049.      EBRDDISABLE(brdp);
  20050.  
  20051.  #if 0
  20052. -    printk("%s(%d): sig-> magic=%x romver=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n",
  20053. +    printk("%s(%d): sig-> magic=%x rom=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n",
  20054.          __FILE__, __LINE__, (int) sig.magic, sig.romver, sig.panelid[0],
  20055. -        (int) sig.panelid[1], (int) sig.panelid[2], (int) sig.panelid[3],
  20056. -        (int) sig.panelid[4], (int) sig.panelid[5], (int) sig.panelid[6],
  20057. +        (int) sig.panelid[1], (int) sig.panelid[2],
  20058. +        (int) sig.panelid[3], (int) sig.panelid[4],
  20059. +        (int) sig.panelid[5], (int) sig.panelid[6],
  20060.          (int) sig.panelid[7]);
  20061.  #endif
  20062.  
  20063. @@ -3428,20 +3553,18 @@
  20064.          status = sig.panelid[nxtid];
  20065.          if ((status & ECH_PNLIDMASK) != nxtid)
  20066.              break;
  20067. -        if (status & ECH_PNL16PORT) {
  20068. -            brdp->panels[panelnr] = 16;
  20069. -            brdp->nrports += 16;
  20070. -            nxtid += 2;
  20071. -        } else {
  20072. -            brdp->panels[panelnr] = 8;
  20073. -            brdp->nrports += 8;
  20074. -            nxtid++;
  20075. -        }
  20076. +
  20077.          brdp->panelids[panelnr] = status;
  20078. +        nrports = (status & ECH_PNL16PORT) ? 16 : 8;
  20079. +        if ((nrports == 16) && ((status & ECH_PNLXPID) == 0))
  20080. +            nxtid++;
  20081. +        brdp->panels[panelnr] = nrports;
  20082. +        brdp->nrports += nrports;
  20083. +        nxtid++;
  20084.          brdp->nrpanels++;
  20085.      }
  20086.  
  20087. -    request_region(brdp->iobase, ECP_IOSIZE, "serial(ECP)");
  20088. +    request_region(brdp->iobase, brdp->iosize, name);
  20089.      brdp->state |= BST_FOUND;
  20090.      return(0);
  20091.  }
  20092. @@ -3453,10 +3576,11 @@
  20093.   *    This handles only these board types.
  20094.   */
  20095.  
  20096. -static int stli_initonb(stlibrd_t *brdp)
  20097. +static inline int stli_initonb(stlibrd_t *brdp)
  20098.  {
  20099.      cdkonbsig_t    sig;
  20100.      cdkonbsig_t    *sigsp;
  20101. +    char        *name;
  20102.      int        i;
  20103.  
  20104.  #if DEBUG
  20105. @@ -3469,6 +3593,11 @@
  20106.      if ((brdp->iobase == 0) || (brdp->memaddr == 0))
  20107.          return(-ENODEV);
  20108.  
  20109. +    brdp->iosize = ONB_IOSIZE;
  20110. +    if (check_region(brdp->iobase, brdp->iosize))
  20111. +        printk("STALLION: Warning, unit %d I/O address %x conflicts "
  20112. +            "with another device\n", brdp->brdnr, brdp->iobase);
  20113. +
  20114.  /*
  20115.   *    Based on the specific board type setup the common vars to access
  20116.   *    and enable shared memory. Set all board specific information now
  20117. @@ -3494,6 +3623,7 @@
  20118.              brdp->enabval = ONB_MEMENABHI;
  20119.          else
  20120.              brdp->enabval = ONB_MEMENABLO;
  20121. +        name = "serial(ONBoard)";
  20122.          break;
  20123.  
  20124.      case BRD_ONBOARDE:
  20125. @@ -3507,6 +3637,7 @@
  20126.          brdp->getmemptr = stli_onbegetmemptr;
  20127.          brdp->intr = stli_ecpintr;
  20128.          brdp->reset = stli_onbereset;
  20129. +        name = "serial(ONBoard/E)";
  20130.          break;
  20131.  
  20132.      case BRD_BRUMBY4:
  20133. @@ -3522,6 +3653,7 @@
  20134.          brdp->getmemptr = stli_bbygetmemptr;
  20135.          brdp->intr = stli_ecpintr;
  20136.          brdp->reset = stli_bbyreset;
  20137. +        name = "serial(Brumby)";
  20138.          break;
  20139.  
  20140.      case BRD_STALLION:
  20141. @@ -3535,6 +3667,7 @@
  20142.          brdp->getmemptr = stli_stalgetmemptr;
  20143.          brdp->intr = stli_ecpintr;
  20144.          brdp->reset = stli_stalreset;
  20145. +        name = "serial(Stallion)";
  20146.          break;
  20147.  
  20148.      default:
  20149. @@ -3572,7 +3705,7 @@
  20150.  #endif
  20151.  
  20152.      if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) ||
  20153. -            (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3))
  20154. +        (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3))
  20155.          return(-ENODEV);
  20156.  
  20157.  /*
  20158. @@ -3591,7 +3724,7 @@
  20159.      }
  20160.      brdp->panels[0] = brdp->nrports;
  20161.  
  20162. -    request_region(brdp->iobase, ONB_IOSIZE, "serial(ONB/BBY)");
  20163. +    request_region(brdp->iobase, brdp->iosize, name);
  20164.      brdp->state |= BST_FOUND;
  20165.      return(0);
  20166.  }
  20167. @@ -3626,14 +3759,16 @@
  20168.      nrdevs = hdrp->nrdevs;
  20169.  
  20170.  #if 0
  20171. -    printk("%s(%d): CDK version %d.%d.%d --> nrdevs=%d memp=%x hostp=%x slavep=%x\n",
  20172. +    printk("%s(%d): CDK version %d.%d.%d --> "
  20173. +        "nrdevs=%d memp=%x hostp=%x slavep=%x\n",
  20174.           __FILE__, __LINE__, hdrp->ver_release, hdrp->ver_modification,
  20175.           hdrp->ver_fix, nrdevs, (int) hdrp->memp, (int) hdrp->hostp,
  20176.           (int) hdrp->slavep);
  20177.  #endif
  20178.  
  20179.      if (nrdevs < (brdp->nrports + 1)) {
  20180. -        printk("STALLION: slave failed to allocate memory for all devices, devices=%d\n", nrdevs);
  20181. +        printk("STALLION: slave failed to allocate memory for all "
  20182. +            "devices, devices=%d\n", nrdevs);
  20183.          brdp->nrports = nrdevs - 1;
  20184.      }
  20185.      brdp->nrdevs = nrdevs;
  20186. @@ -3671,6 +3806,8 @@
  20187.          portp->portbit = (unsigned char) (0x1 << (i % 8));
  20188.      }
  20189.  
  20190. +    hdrp->slavereq = 0xff;
  20191. +
  20192.  /*
  20193.   *    For each port setup a local copy of the RX and TX buffer offsets
  20194.   *    and sizes. We do this separate from the above, because we need to
  20195. @@ -3743,20 +3880,27 @@
  20196.      case BRD_ECH:
  20197.      case BRD_ECHMC:
  20198.      case BRD_ECHPCI:
  20199. -        printk("STALLION: %s board type not supported in this driver\n", stli_brdnames[brdp->brdtype]);
  20200. +        printk("STALLION: %s board type not supported in this driver\n",
  20201. +            stli_brdnames[brdp->brdtype]);
  20202.          return(ENODEV);
  20203.      default:
  20204. -        printk("STALLION: unit=%d is unknown board type=%d\n", brdp->brdnr, brdp->brdtype);
  20205. +        printk("STALLION: unit=%d is unknown board type=%d\n",
  20206. +            brdp->brdnr, brdp->brdtype);
  20207.          return(ENODEV);
  20208.      }
  20209.  
  20210.      if ((brdp->state & BST_FOUND) == 0) {
  20211. -        printk("STALLION: %s board not found, unit=%d io=%x mem=%x\n", stli_brdnames[brdp->brdtype], brdp->brdnr, brdp->iobase, (int) brdp->memaddr);
  20212. +        printk("STALLION: %s board not found, unit=%d io=%x mem=%x\n",
  20213. +            stli_brdnames[brdp->brdtype], brdp->brdnr,
  20214. +            brdp->iobase, (int) brdp->memaddr);
  20215.          return(ENODEV);
  20216.      }
  20217.  
  20218.      stli_initports(brdp);
  20219. -    printk("STALLION: %s found, unit=%d io=%x mem=%x nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], brdp->brdnr, brdp->iobase, (int) brdp->memaddr, brdp->nrpanels, brdp->nrports);
  20220. +    printk("STALLION: %s found, unit=%d io=%x mem=%x "
  20221. +        "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],
  20222. +        brdp->brdnr, brdp->iobase, (int) brdp->memaddr,
  20223. +        brdp->nrpanels, brdp->nrports);
  20224.      return(0);
  20225.  }
  20226.  
  20227. @@ -3767,7 +3911,7 @@
  20228.   *    might be. This is a bit if hack, but it is the best we can do.
  20229.   */
  20230.  
  20231. -static int stli_eisamemprobe(stlibrd_t *brdp)
  20232. +static inline int stli_eisamemprobe(stlibrd_t *brdp)
  20233.  {
  20234.      cdkecpsig_t    ecpsig, *ecpsigp;
  20235.      cdkonbsig_t    onbsig, *onbsigp;
  20236. @@ -3820,15 +3964,19 @@
  20237.                  continue;
  20238.          }
  20239.          if (brdp->brdtype == BRD_ECPE) {
  20240. -            ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp, CDK_SIGADDR, __LINE__);
  20241. +            ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp,
  20242. +                CDK_SIGADDR, __LINE__);
  20243.              memcpy(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));
  20244.              if (ecpsig.magic == ECP_MAGIC)
  20245.                  foundit = 1;
  20246.          } else {
  20247. -            onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp, CDK_SIGADDR, __LINE__);
  20248. +            onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp,
  20249. +                CDK_SIGADDR, __LINE__);
  20250.              memcpy(&onbsig, onbsigp, sizeof(cdkonbsig_t));
  20251. -            if ((onbsig.magic0 == ONB_MAGIC0) && (onbsig.magic1 == ONB_MAGIC1) &&
  20252. -                    (onbsig.magic2 == ONB_MAGIC2) && (onbsig.magic3 == ONB_MAGIC3))
  20253. +            if ((onbsig.magic0 == ONB_MAGIC0) &&
  20254. +                (onbsig.magic1 == ONB_MAGIC1) &&
  20255. +                (onbsig.magic2 == ONB_MAGIC2) &&
  20256. +                (onbsig.magic3 == ONB_MAGIC3))
  20257.                  foundit = 1;
  20258.          }
  20259.          if (brdp->memaddr >= 0x100000)
  20260. @@ -3849,7 +3997,9 @@
  20261.      if (! foundit) {
  20262.          brdp->memaddr = 0;
  20263.          brdp->membase = 0;
  20264. -        printk("STALLION: failed to probe shared memory region for %s in EISA slot=%d\n", stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));
  20265. +        printk("STALLION: failed to probe shared memory region for "
  20266. +            "%s in EISA slot=%d\n", stli_brdnames[brdp->brdtype],
  20267. +            (brdp->iobase >> 12));
  20268.          return(-ENODEV);
  20269.      }
  20270.      return(0);
  20271. @@ -3867,7 +4017,7 @@
  20272.   *    do is go probing around in the usual places hoping we can find it.
  20273.   */
  20274.  
  20275. -static int stli_findeisabrds()
  20276. +static inline int stli_findeisabrds()
  20277.  {
  20278.      stlibrd_t    *brdp;
  20279.      unsigned int    iobase, eid;
  20280. @@ -3915,7 +4065,8 @@
  20281.   *        info table.
  20282.   */
  20283.          if (stli_nrbrds >= STL_MAXBRDS) {
  20284. -            printk("STALLION: no room for more probed boards, maximum supported %d\n", STL_MAXBRDS);
  20285. +            printk("STALLION: no room for more probed boards, "
  20286. +                "maximum supported %d\n", STL_MAXBRDS);
  20287.              break;
  20288.          }
  20289.  
  20290. @@ -3925,7 +4076,8 @@
  20291.   */
  20292.          brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t));
  20293.          if (brdp == (stlibrd_t *) NULL) {
  20294. -            printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlibrd_t));
  20295. +            printk("STALLION: failed to allocate memory "
  20296. +                "(size=%d)\n", sizeof(stlibrd_t));
  20297.              return(-ENOMEM);
  20298.          }
  20299.          memset(brdp, 0, sizeof(stlibrd_t));
  20300. @@ -3956,7 +4108,7 @@
  20301.   *    can find.
  20302.   */
  20303.  
  20304. -static int stli_initbrds()
  20305. +static inline int stli_initbrds()
  20306.  {
  20307.      stlibrd_t    *brdp, *nxtbrdp;
  20308.      stlconf_t    *confp;
  20309. @@ -3967,7 +4119,8 @@
  20310.  #endif
  20311.  
  20312.      if (stli_nrbrds > STL_MAXBRDS) {
  20313. -        printk("STALLION: too many boards in configuration table, truncating to %d\n", STL_MAXBRDS);
  20314. +        printk("STALLION: too many boards in configuration table, "
  20315. +            "truncating to %d\n", STL_MAXBRDS);
  20316.          stli_nrbrds = STL_MAXBRDS;
  20317.      }
  20318.  
  20319. @@ -3979,7 +4132,8 @@
  20320.          confp = &stli_brdconf[i];
  20321.          brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t));
  20322.          if (brdp == (stlibrd_t *) NULL) {
  20323. -            printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlibrd_t));
  20324. +            printk("STALLION: failed to allocate memory "
  20325. +                "(size=%d)\n", sizeof(stlibrd_t));
  20326.              return(-ENOMEM);
  20327.          }
  20328.          memset(brdp, 0, sizeof(stlibrd_t));
  20329. @@ -4013,7 +4167,9 @@
  20330.                  nxtbrdp = stli_brds[j];
  20331.                  if (nxtbrdp == (stlibrd_t *) NULL)
  20332.                      continue;
  20333. -                if ((brdp->membase >= nxtbrdp->membase) && (brdp->membase <= (nxtbrdp->membase + nxtbrdp->memsize - 1))) {
  20334. +                if ((brdp->membase >= nxtbrdp->membase) &&
  20335. +                    (brdp->membase <= (nxtbrdp->membase +
  20336. +                    nxtbrdp->memsize - 1))) {
  20337.                      stli_shared++;
  20338.                      break;
  20339.                  }
  20340. @@ -4053,7 +4209,8 @@
  20341.      int        brdnr, size, n;
  20342.  
  20343.  #if DEBUG
  20344. -    printk("stli_memread(ip=%x,fp=%x,buf=%x,count=%d)\n", (int) ip, (int) fp, (int) buf, count);
  20345. +    printk("stli_memread(ip=%x,fp=%x,buf=%x,count=%d)\n", (int) ip,
  20346. +        (int) fp, (int) buf, count);
  20347.  #endif
  20348.  
  20349.      brdnr = MINOR(ip->i_rdev);
  20350. @@ -4103,7 +4260,8 @@
  20351.      int        brdnr, size, n;
  20352.  
  20353.  #if DEBUG
  20354. -    printk("stli_memwrite(ip=%x,fp=%x,buf=%x,count=%x)\n", (int) ip, (int) fp, (int) buf, count);
  20355. +    printk("stli_memwrite(ip=%x,fp=%x,buf=%x,count=%x)\n", (int) ip,
  20356. +        (int) fp, (int) buf, count);
  20357.  #endif
  20358.  
  20359.      brdnr = MINOR(ip->i_rdev);
  20360. @@ -4205,31 +4363,28 @@
  20361.   *    what port to get stats for (used through board control device).
  20362.   */
  20363.  
  20364. -static int stli_getportstats(stliport_t *portp, comstats_t *cp)
  20365. +static int stli_portcmdstats(stliport_t *portp)
  20366.  {
  20367.      unsigned long    flags;
  20368.      stlibrd_t    *brdp;
  20369.      int        rc;
  20370.  
  20371. -    if (portp == (stliport_t *) NULL) {
  20372. -        memcpy_fromfs(&stli_comstats, cp, sizeof(comstats_t));
  20373. -        portp = stli_getport(stli_comstats.brd, stli_comstats.panel, stli_comstats.port);
  20374. -        if (portp == (stliport_t *) NULL)
  20375. -            return(-ENODEV);
  20376. -    }
  20377. +    memset(&stli_comstats, 0, sizeof(comstats_t));
  20378.  
  20379. +    if (portp == (stliport_t *) NULL)
  20380. +        return(-ENODEV);
  20381.      brdp = stli_brds[portp->brdnr];
  20382.      if (brdp == (stlibrd_t *) NULL)
  20383.          return(-ENODEV);
  20384.  
  20385.      if (brdp->state & BST_STARTED) {
  20386. -        if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, &stli_cdkstats, sizeof(asystats_t), 1)) < 0)
  20387. +        if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS,
  20388. +            &stli_cdkstats, sizeof(asystats_t), 1)) < 0)
  20389.              return(rc);
  20390.      } else {
  20391.          memset(&stli_cdkstats, 0, sizeof(asystats_t));
  20392.      }
  20393.  
  20394. -    memset(&stli_comstats, 0, sizeof(comstats_t));
  20395.      stli_comstats.brd = portp->brdnr;
  20396.      stli_comstats.panel = portp->panelnr;
  20397.      stli_comstats.port = portp->portnr;
  20398. @@ -4272,6 +4427,37 @@
  20399.      stli_comstats.hwid = stli_cdkstats.hwid;
  20400.      stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);
  20401.  
  20402. +    return(0);
  20403. +}
  20404. +
  20405. +/*****************************************************************************/
  20406. +
  20407. +/*
  20408. + *    Return the port stats structure to user app. A NULL port struct
  20409. + *    pointer passed in means that we need to find out from the app
  20410. + *    what port to get stats for (used through board control device).
  20411. + */
  20412. +
  20413. +static int stli_getportstats(stliport_t *portp, comstats_t *cp)
  20414. +{
  20415. +    stlibrd_t    *brdp;
  20416. +    int        rc;
  20417. +
  20418. +    if (portp == (stliport_t *) NULL) {
  20419. +        memcpy_fromfs(&stli_comstats, cp, sizeof(comstats_t));
  20420. +        portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
  20421. +            stli_comstats.port);
  20422. +        if (portp == (stliport_t *) NULL)
  20423. +            return(-ENODEV);
  20424. +    }
  20425. +
  20426. +    brdp = stli_brds[portp->brdnr];
  20427. +    if (brdp == (stlibrd_t *) NULL)
  20428. +        return(-ENODEV);
  20429. +
  20430. +    if ((rc = stli_portcmdstats(portp)) < 0)
  20431. +        return(rc);
  20432. +
  20433.      memcpy_tofs(cp, &stli_comstats, sizeof(comstats_t));
  20434.      return(0);
  20435.  }
  20436. @@ -4289,7 +4475,8 @@
  20437.  
  20438.      if (portp == (stliport_t *) NULL) {
  20439.          memcpy_fromfs(&stli_comstats, cp, sizeof(comstats_t));
  20440. -        portp = stli_getport(stli_comstats.brd, stli_comstats.panel, stli_comstats.port);
  20441. +        portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
  20442. +            stli_comstats.port);
  20443.          if (portp == (stliport_t *) NULL)
  20444.              return(-ENODEV);
  20445.      }
  20446. @@ -4354,6 +4541,26 @@
  20447.  /*****************************************************************************/
  20448.  
  20449.  /*
  20450. + *    Memory device open code. Need to keep track of opens and close
  20451. + *    for module handling.
  20452. + */
  20453. +
  20454. +static int stli_memopen(struct inode *ip, struct file *fp)
  20455. +{
  20456. +    MOD_INC_USE_COUNT;
  20457. +    return(0);
  20458. +}
  20459. +
  20460. +/*****************************************************************************/
  20461. +
  20462. +static void stli_memclose(struct inode *ip, struct file *fp)
  20463. +{
  20464. +    MOD_DEC_USE_COUNT;
  20465. +}
  20466. +
  20467. +/*****************************************************************************/
  20468. +
  20469. +/*
  20470.   *    The "staliomem" device is also required to do some special operations on
  20471.   *    the board. We need to be able to send an interrupt to the board,
  20472.   *    reset it, and start/stop it.
  20473. @@ -4365,7 +4572,8 @@
  20474.      int        brdnr, rc, done;
  20475.  
  20476.  #if DEBUG
  20477. -    printk("stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip, (int) fp, cmd, (int) arg);
  20478. +    printk("stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip,
  20479. +        (int) fp, cmd, (int) arg);
  20480.  #endif
  20481.  
  20482.  /*
  20483. @@ -4376,27 +4584,34 @@
  20484.  
  20485.      switch (cmd) {
  20486.      case COM_GETPORTSTATS:
  20487. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
  20488. -            rc = stli_getportstats((stliport_t *) NULL, (comstats_t *) arg);
  20489. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  20490. +            sizeof(comstats_t))) == 0)
  20491. +            rc = stli_getportstats((stliport_t *) NULL,
  20492. +                (comstats_t *) arg);
  20493.          done++;
  20494.          break;
  20495.      case COM_CLRPORTSTATS:
  20496. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
  20497. -            rc = stli_clrportstats((stliport_t *) NULL, (comstats_t *) arg);
  20498. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  20499. +            sizeof(comstats_t))) == 0)
  20500. +            rc = stli_clrportstats((stliport_t *) NULL,
  20501. +                (comstats_t *) arg);
  20502.          done++;
  20503.          break;
  20504.      case COM_GETBRDSTATS:
  20505. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(combrd_t))) == 0)
  20506. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  20507. +            sizeof(combrd_t))) == 0)
  20508.              rc = stli_getbrdstats((combrd_t *) arg);
  20509.          done++;
  20510.          break;
  20511.      case COM_READPORT:
  20512. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stliport_t))) == 0)
  20513. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  20514. +            sizeof(stliport_t))) == 0)
  20515.              rc = stli_getportstruct(arg);
  20516.          done++;
  20517.          break;
  20518.      case COM_READBOARD:
  20519. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stlibrd_t))) == 0)
  20520. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  20521. +            sizeof(stlibrd_t))) == 0)
  20522.              rc = stli_getbrdstruct(arg);
  20523.          done++;
  20524.          break;
  20525. @@ -4450,7 +4665,7 @@
  20526.  
  20527.  int stli_init()
  20528.  {
  20529. -    printk(KERN_INFO "%s: version %s\n", stli_drvname, stli_drvversion);
  20530. +    printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion);
  20531.  
  20532.      stli_initbrds();
  20533.  
  20534. @@ -4459,10 +4674,12 @@
  20535.   */
  20536.      stli_tmpwritebuf = (char *) stli_memalloc(STLI_TXBUFSIZE);
  20537.      if (stli_tmpwritebuf == (char *) NULL)
  20538. -        printk("STALLION: failed to allocate memory (size=%d)\n", STLI_TXBUFSIZE);
  20539. +        printk("STALLION: failed to allocate memory (size=%d)\n",
  20540. +            STLI_TXBUFSIZE);
  20541.      stli_txcookbuf = (char *) stli_memalloc(STLI_TXBUFSIZE);
  20542.      if (stli_txcookbuf == (char *) NULL)
  20543. -        printk("STALLION: failed to allocate memory (size=%d)\n", STLI_TXBUFSIZE);
  20544. +        printk("STALLION: failed to allocate memory (size=%d)\n",
  20545. +            STLI_TXBUFSIZE);
  20546.  
  20547.  /*
  20548.   *    Set up a character driver for the shared memory region. We need this
  20549. diff -u --recursive --new-file v2.0.34/linux/drivers/char/lp.c linux/drivers/char/lp.c
  20550. --- v2.0.34/linux/drivers/char/lp.c    Thu Apr  3 19:15:34 1997
  20551. +++ linux/drivers/char/lp.c    Mon Jul 13 13:47:29 1998
  20552. @@ -89,7 +89,14 @@
  20553.      while(wait != LP_WAIT(minor)) wait++;
  20554.      /* control port takes strobe high */
  20555.      outb_p(( LP_PSELECP | LP_PINITP | LP_PSTROBE ), ( LP_C( minor )));
  20556. -    while(wait) wait--;
  20557. +    /* Wait until NBUSY line goes high */
  20558. +    count = 0;
  20559. +    do {
  20560. +        status = LP_S(minor);
  20561. +        count++;
  20562. +        if (need_resched)
  20563. +            schedule();
  20564. +    } while (LP_READY(minor, status) && (count<LP_CHAR(minor)));
  20565.      /* take strobe low */
  20566.      outb_p(( LP_PSELECP | LP_PINITP ), ( LP_C( minor )));
  20567.      /* update waittime statistics */
  20568. diff -u --recursive --new-file v2.0.34/linux/drivers/char/pcxx.c linux/drivers/char/pcxx.c
  20569. --- v2.0.34/linux/drivers/char/pcxx.c    Sun Dec 22 05:07:00 1996
  20570. +++ linux/drivers/char/pcxx.c    Mon Jul 13 13:47:29 1998
  20571. @@ -591,7 +591,7 @@
  20572.  ** worth noting that while I'm not sure what this hunk of code is supposed
  20573.  ** to do, it is not present in the serial.c driver.  Hmmm.  If you know,
  20574.  ** please send me a note.  brian@ilinx.com
  20575. -** Dont know either what this is supposed to do clameter@waterf.org.
  20576. +** Don't know either what this is supposed to do clameter@waterf.org.
  20577.  */
  20578.          if(tty->ldisc.num != ldiscs[N_TTY].num) {
  20579.              if(tty->ldisc.close)
  20580. diff -u --recursive --new-file v2.0.34/linux/drivers/char/stallion.c linux/drivers/char/stallion.c
  20581. --- v2.0.34/linux/drivers/char/stallion.c    Mon May  6 02:26:06 1996
  20582. +++ linux/drivers/char/stallion.c    Mon Jul 13 13:47:30 1998
  20583. @@ -3,6 +3,7 @@
  20584.  /*
  20585.   *    stallion.c  -- stallion multiport serial driver.
  20586.   *
  20587. + *    Copyright (C) 1996-1998  Stallion Technologies (support@stallion.oz.au).
  20588.   *    Copyright (C) 1994-1996  Greg Ungerer (gerg@stallion.oz.au).
  20589.   *
  20590.   *    This code is loosely based on the Linux serial driver, written by
  20591. @@ -37,12 +38,13 @@
  20592.  #include <linux/tty_flip.h>
  20593.  #include <linux/serial.h>
  20594.  #include <linux/cd1400.h>
  20595. +#include <linux/sc26198.h>
  20596.  #include <linux/comstats.h>
  20597.  #include <linux/stallion.h>
  20598.  #include <linux/string.h>
  20599.  #include <linux/malloc.h>
  20600.  #include <linux/ioport.h>
  20601. -#include <linux/config.h>    /* for CONFIG_PCI */
  20602. +#include <linux/config.h>
  20603.  #include <asm/system.h>
  20604.  #include <asm/io.h>
  20605.  #include <asm/segment.h>
  20606. @@ -55,16 +57,16 @@
  20607.  /*****************************************************************************/
  20608.  
  20609.  /*
  20610. - *    Define different board types. At the moment I have only declared
  20611. - *    those boards that this driver supports. But I will use the standard
  20612. - *    "assigned" board numbers. In the future this driver will support
  20613. - *    some of the other Stallion boards. Currently supported boards are
  20614. - *    abbreviated as EIO = EasyIO and ECH = EasyConnection 8/32.
  20615. + *    Define different board types. Use the standard Stallion "assigned"
  20616. + *    board numbers. Boards supported in this driver are abbreviated as
  20617. + *    EIO = EasyIO and ECH = EasyConnection 8/32.
  20618.   */
  20619.  #define    BRD_EASYIO    20
  20620.  #define    BRD_ECH        21
  20621.  #define    BRD_ECHMC    22
  20622.  #define    BRD_ECHPCI    26
  20623. +#define    BRD_ECH64PCI    27
  20624. +#define    BRD_EASYIOPCI    28
  20625.  
  20626.  /*
  20627.   *    Define a configuration structure to hold the board configuration.
  20628. @@ -126,12 +128,11 @@
  20629.  #define    STL_DRVTYPCALLOUT    2
  20630.  
  20631.  /*
  20632. - *    I haven't really decided (or measured) what TX buffer size gives
  20633. - *    a good balance between performance and memory usage. These seem
  20634. - *    to work pretty well...
  20635. + *    Set the TX buffer size. Bigger is better, but we don't want
  20636. + *    to chew too much memory with buffers!
  20637.   */
  20638. -#define    STL_TXBUFLOW        256
  20639. -#define    STL_TXBUFSIZE        2048
  20640. +#define    STL_TXBUFLOW        512
  20641. +#define    STL_TXBUFSIZE        4096
  20642.  
  20643.  /*****************************************************************************/
  20644.  
  20645. @@ -139,8 +140,8 @@
  20646.   *    Define our local driver identity first. Set up stuff to deal with
  20647.   *    all the local structures required by a serial tty driver.
  20648.   */
  20649. -static char    *stl_drvname = "Stallion Multiport Serial Driver";
  20650. -static char    *stl_drvversion = "1.1.3";
  20651. +static char    *stl_drvtitle = "Stallion Multiport Serial Driver";
  20652. +static char    *stl_drvversion = "5.4.4";
  20653.  static char    *stl_serialname = "ttyE";
  20654.  static char    *stl_calloutname = "cue";
  20655.  
  20656. @@ -185,6 +186,11 @@
  20657.  static stlport_t    stl_dummyport;
  20658.  
  20659.  /*
  20660. + *    Define global place to put buffer overflow characters.
  20661. + */
  20662. +static char        stl_unwanted[SC26198_RXFIFOSIZE];
  20663. +
  20664. +/*
  20665.   *    Keep track of what interrupts we have requested for us.
  20666.   *    We don't need to request an interrupt twice if it is being
  20667.   *    shared with another Stallion board.
  20668. @@ -198,7 +204,7 @@
  20669.  
  20670.  /*
  20671.   *    Per board state flags. Used with the state field of the board struct.
  20672. - *    Not really much here yet!
  20673. + *    Not really much here!
  20674.   */
  20675.  #define    BRD_FOUND    0x1
  20676.  
  20677. @@ -210,6 +216,7 @@
  20678.  #define    ASYI_TXBUSY    1
  20679.  #define    ASYI_TXLOW    2
  20680.  #define    ASYI_DCDCHANGE    3
  20681. +#define    ASYI_TXFLOWED    4
  20682.  
  20683.  /*
  20684.   *    Define an array of board names as printable strings. Handy for
  20685. @@ -243,23 +250,33 @@
  20686.      (char *) NULL,
  20687.      (char *) NULL,
  20688.      "EC8/32-PCI",
  20689. +    "EC8/64-PCI",
  20690. +    "EasyIO-PCI",
  20691.  };
  20692.  
  20693.  /*****************************************************************************/
  20694.  
  20695.  /*
  20696.   *    Hardware ID bits for the EasyIO and ECH boards. These defines apply
  20697. - *    to the directly accessible io ports of these boards (not the cd1400
  20698. - *    uarts - they are in cd1400.h).
  20699. + *    to the directly accessible io ports of these boards (not the uarts -
  20700. + *    they are in cd1400.h and sc26198.h).
  20701.   */
  20702.  #define    EIO_8PORTRS    0x04
  20703.  #define    EIO_4PORTRS    0x05
  20704.  #define    EIO_8PORTDI    0x00
  20705.  #define    EIO_8PORTM    0x06
  20706. +#define    EIO_MK3        0x03
  20707.  #define    EIO_IDBITMASK    0x07
  20708. +
  20709. +#define    EIO_BRDMASK    0xf0
  20710. +#define    ID_BRD4        0x10
  20711. +#define    ID_BRD8        0x20
  20712. +#define    ID_BRD16    0x30
  20713. +
  20714.  #define    EIO_INTRPEND    0x08
  20715.  #define    EIO_INTEDGE    0x00
  20716.  #define    EIO_INTLEVEL    0x08
  20717. +#define    EIO_0WS        0x10
  20718.  
  20719.  #define    ECH_ID        0xa0
  20720.  #define    ECH_IDBITMASK    0xe0
  20721. @@ -278,24 +295,10 @@
  20722.  #define    ECH_PNLSTATUS    2
  20723.  #define    ECH_PNL16PORT    0x20
  20724.  #define    ECH_PNLIDMASK    0x07
  20725. +#define    ECH_PNLXPID    0x40
  20726.  #define    ECH_PNLINTRPEND    0x80
  20727. -#define    ECH_ADDR2MASK    0x1e0
  20728. -
  20729. -#define    EIO_CLK        25000000
  20730. -#define    EIO_CLK8M    20000000
  20731. -#define    ECH_CLK        EIO_CLK
  20732. -
  20733. -/*
  20734. - *    Define the offsets within the register bank for all io registers.
  20735. - *    These io address offsets are common to both the EIO and ECH.
  20736. - */
  20737. -#define    EREG_ADDR    0
  20738. -#define    EREG_DATA    4
  20739. -#define    EREG_RXACK    5
  20740. -#define    EREG_TXACK    6
  20741. -#define    EREG_MDACK    7
  20742.  
  20743. -#define    EREG_BANKSIZE    8
  20744. +#define    ECH_ADDR2MASK    0x1e0
  20745.  
  20746.  /*
  20747.   *    Define the vector mapping bits for the programmable interrupt board
  20748. @@ -326,18 +329,51 @@
  20749.          outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDDISABLE),    \
  20750.              stl_brds[(brdnr)]->ioctrl);
  20751.  
  20752. +#define    STL_CD1400MAXBAUD    230400
  20753. +#define    STL_SC26198MAXBAUD    460800
  20754. +
  20755. +#define    STL_BAUDBASE        115200
  20756. +#define    STL_CLOSEDELAY        (5 * HZ / 10)
  20757. +
  20758. +/*****************************************************************************/
  20759. +
  20760. +#ifdef CONFIG_PCI
  20761. +
  20762.  /*
  20763. - *    Define the cd1400 baud rate clocks. These are used when calculating
  20764. - *    what clock and divisor to use for the required baud rate. Also
  20765. - *    define the maximum baud rate allowed, and the default base baud.
  20766. + *    Define the Stallion PCI vendor and device IDs.
  20767.   */
  20768. -static int    stl_cd1400clkdivs[] = {
  20769. -    CD1400_CLK0, CD1400_CLK1, CD1400_CLK2, CD1400_CLK3, CD1400_CLK4
  20770. +#ifndef    PCI_VENDOR_ID_STALLION
  20771. +#define    PCI_VENDOR_ID_STALLION        0x124d
  20772. +#endif
  20773. +#ifndef PCI_DEVICE_ID_ECHPCI832
  20774. +#define    PCI_DEVICE_ID_ECHPCI832        0x0000
  20775. +#endif
  20776. +#ifndef PCI_DEVICE_ID_ECHPCI864
  20777. +#define    PCI_DEVICE_ID_ECHPCI864        0x0002
  20778. +#endif
  20779. +#ifndef PCI_DEVICE_ID_EIOPCI
  20780. +#define    PCI_DEVICE_ID_EIOPCI        0x0003
  20781. +#endif
  20782. +
  20783. +/*
  20784. + *    Define structure to hold all Stallion PCI boards.
  20785. + */
  20786. +typedef struct stlpcibrd {
  20787. +    unsigned short        vendid;
  20788. +    unsigned short        devid;
  20789. +    int            brdtype;
  20790. +} stlpcibrd_t;
  20791. +
  20792. +static stlpcibrd_t    stl_pcibrds[] = {
  20793. +    { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864, BRD_ECH64PCI },
  20794. +    { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI, BRD_EASYIOPCI },
  20795. +    { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832, BRD_ECHPCI },
  20796. +    { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, BRD_ECHPCI },
  20797.  };
  20798.  
  20799. -#define    STL_MAXBAUD    230400
  20800. -#define    STL_BAUDBASE    115200
  20801. -#define    STL_CLOSEDELAY    50
  20802. +static int    stl_nrpcibrds = sizeof(stl_pcibrds) / sizeof(stlpcibrd_t);
  20803. +
  20804. +#endif
  20805.  
  20806.  /*****************************************************************************/
  20807.  
  20808. @@ -349,16 +385,14 @@
  20809.  
  20810.  /*
  20811.   *    Define a baud rate table that converts termios baud rate selector
  20812. - *    into the actual baud rate value. All baud rate calculates are based
  20813. - *    on the actual baud rate required.
  20814. + *    into the actual baud rate value. All baud rate calculations are
  20815. + *    based on the actual baud rate required.
  20816.   */
  20817.  static unsigned int    stl_baudrates[] = {
  20818.      0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
  20819. -    9600, 19200, 38400, 57600, 115200, 230400
  20820. +    9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
  20821.  };
  20822.  
  20823. -/*****************************************************************************/
  20824. -
  20825.  /*
  20826.   *    Define some handy local macros...
  20827.   */
  20828. @@ -392,15 +426,15 @@
  20829.  static void    stl_stop(struct tty_struct *tty);
  20830.  static void    stl_start(struct tty_struct *tty);
  20831.  static void    stl_flushbuffer(struct tty_struct *tty);
  20832. +static void    stl_waituntilsent(struct tty_struct *tty, int timeout);
  20833.  static void    stl_hangup(struct tty_struct *tty);
  20834. +static int    stl_memopen(struct inode *ip, struct file *fp);
  20835. +static void    stl_memclose(struct inode *ip, struct file *fp);
  20836.  static int    stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
  20837.  
  20838. -static int    stl_initbrds(void);
  20839.  static int    stl_brdinit(stlbrd_t *brdp);
  20840. -static int    stl_initeio(stlbrd_t *brdp);
  20841. -static int    stl_initech(stlbrd_t *brdp);
  20842.  static int    stl_initports(stlbrd_t *brdp, stlpanel_t *panelp);
  20843. -static int    stl_mapirq(int irq);
  20844. +static int    stl_mapirq(int irq, char *name);
  20845.  static void    stl_getserial(stlport_t *portp, struct serial_struct *sp);
  20846.  static int    stl_setserial(stlport_t *portp, struct serial_struct *sp);
  20847.  static int    stl_getbrdstats(combrd_t *bp);
  20848. @@ -408,28 +442,212 @@
  20849.  static int    stl_clrportstats(stlport_t *portp, comstats_t *cp);
  20850.  static int    stl_getportstruct(unsigned long arg);
  20851.  static int    stl_getbrdstruct(unsigned long arg);
  20852. -static void    stl_setreg(stlport_t *portp, int regnr, int value);
  20853. -static int    stl_getreg(stlport_t *portp, int regnr);
  20854. -static int    stl_updatereg(stlport_t *portp, int regnr, int value);
  20855. -static void    stl_setport(stlport_t *portp, struct termios *tiosp);
  20856. -static int    stl_getsignals(stlport_t *portp);
  20857. -static void    stl_setsignals(stlport_t *portp, int dtr, int rts);
  20858. -static void    stl_ccrwait(stlport_t *portp);
  20859. -static void    stl_enablerxtx(stlport_t *portp, int rx, int tx);
  20860. -static void    stl_startrxtx(stlport_t *portp, int rx, int tx);
  20861. -static void    stl_disableintrs(stlport_t *portp);
  20862. -static void    stl_sendbreak(stlport_t *portp, long len);
  20863.  static int    stl_waitcarrier(stlport_t *portp, struct file *filp);
  20864.  static void    stl_delay(int len);
  20865.  static void    stl_intr(int irq, void *dev_id, struct pt_regs *regs);
  20866. +static void    stl_eiointr(stlbrd_t *brdp);
  20867. +static void    stl_echatintr(stlbrd_t *brdp);
  20868. +static void    stl_echmcaintr(stlbrd_t *brdp);
  20869. +static void    stl_echpciintr(stlbrd_t *brdp);
  20870. +static void    stl_echpci64intr(stlbrd_t *brdp);
  20871.  static void    stl_offintr(void *private);
  20872.  static void    *stl_memalloc(int len);
  20873.  static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
  20874.  
  20875. +static inline int    stl_initbrds(void);
  20876. +static inline int    stl_initeio(stlbrd_t *brdp);
  20877. +static inline int    stl_initech(stlbrd_t *brdp);
  20878. +
  20879.  #ifdef    CONFIG_PCI
  20880. -static int    stl_findpcibrds(void);
  20881. +static inline int    stl_findpcibrds(void);
  20882. +static inline int    stl_initpcibrd(int brdtype, unsigned char busnr, unsigned char devnr);
  20883.  #endif
  20884.  
  20885. +/*
  20886. + *    CD1400 uart specific handling functions.
  20887. + */
  20888. +static void    stl_cd1400setreg(stlport_t *portp, int regnr, int value);
  20889. +static int    stl_cd1400getreg(stlport_t *portp, int regnr);
  20890. +static int    stl_cd1400updatereg(stlport_t *portp, int regnr, int value);
  20891. +static int    stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp);
  20892. +static void    stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
  20893. +static void    stl_cd1400setport(stlport_t *portp, struct termios *tiosp);
  20894. +static int    stl_cd1400getsignals(stlport_t *portp);
  20895. +static void    stl_cd1400setsignals(stlport_t *portp, int dtr, int rts);
  20896. +static void    stl_cd1400ccrwait(stlport_t *portp);
  20897. +static void    stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx);
  20898. +static void    stl_cd1400startrxtx(stlport_t *portp, int rx, int tx);
  20899. +static void    stl_cd1400disableintrs(stlport_t *portp);
  20900. +static void    stl_cd1400sendbreak(stlport_t *portp, long len);
  20901. +static void    stl_cd1400flowctrl(stlport_t *portp, int state);
  20902. +static void    stl_cd1400sendflow(stlport_t *portp, int state);
  20903. +static void    stl_cd1400flush(stlport_t *portp);
  20904. +static int    stl_cd1400datastate(stlport_t *portp);
  20905. +static void    stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase);
  20906. +static void    stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase);
  20907. +static void    stl_cd1400txisr(stlpanel_t *panelp, int ioaddr);
  20908. +static void    stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr);
  20909. +static void    stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr);
  20910. +
  20911. +/*
  20912. + *    SC26198 uart specific handling functions.
  20913. + */
  20914. +static void    stl_sc26198setreg(stlport_t *portp, int regnr, int value);
  20915. +static int    stl_sc26198getreg(stlport_t *portp, int regnr);
  20916. +static int    stl_sc26198updatereg(stlport_t *portp, int regnr, int value);
  20917. +static int    stl_sc26198getglobreg(stlport_t *portp, int regnr);
  20918. +static int    stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp);
  20919. +static void    stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
  20920. +static void    stl_sc26198setport(stlport_t *portp, struct termios *tiosp);
  20921. +static int    stl_sc26198getsignals(stlport_t *portp);
  20922. +static void    stl_sc26198setsignals(stlport_t *portp, int dtr, int rts);
  20923. +static void    stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx);
  20924. +static void    stl_sc26198startrxtx(stlport_t *portp, int rx, int tx);
  20925. +static void    stl_sc26198disableintrs(stlport_t *portp);
  20926. +static void    stl_sc26198sendbreak(stlport_t *portp, long len);
  20927. +static void    stl_sc26198flowctrl(stlport_t *portp, int state);
  20928. +static void    stl_sc26198sendflow(stlport_t *portp, int state);
  20929. +static void    stl_sc26198flush(stlport_t *portp);
  20930. +static int    stl_sc26198datastate(stlport_t *portp);
  20931. +static void    stl_sc26198wait(stlport_t *portp);
  20932. +static void    stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty);
  20933. +static void    stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase);
  20934. +static void    stl_sc26198txisr(stlport_t *port);
  20935. +static void    stl_sc26198rxisr(stlport_t *port, unsigned int iack);
  20936. +static void    stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch);
  20937. +static void    stl_sc26198rxbadchars(stlport_t *portp);
  20938. +static void    stl_sc26198otherisr(stlport_t *port, unsigned int iack);
  20939. +
  20940. +/*****************************************************************************/
  20941. +
  20942. +/*
  20943. + *    Generic UART support structure.
  20944. + */
  20945. +typedef struct uart {
  20946. +    int    (*panelinit)(stlbrd_t *brdp, stlpanel_t *panelp);
  20947. +    void    (*portinit)(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
  20948. +    void    (*setport)(stlport_t *portp, struct termios *tiosp);
  20949. +    int    (*getsignals)(stlport_t *portp);
  20950. +    void    (*setsignals)(stlport_t *portp, int dtr, int rts);
  20951. +    void    (*enablerxtx)(stlport_t *portp, int rx, int tx);
  20952. +    void    (*startrxtx)(stlport_t *portp, int rx, int tx);
  20953. +    void    (*disableintrs)(stlport_t *portp);
  20954. +    void    (*sendbreak)(stlport_t *portp, long len);
  20955. +    void    (*flowctrl)(stlport_t *portp, int state);
  20956. +    void    (*sendflow)(stlport_t *portp, int state);
  20957. +    void    (*flush)(stlport_t *portp);
  20958. +    int    (*datastate)(stlport_t *portp);
  20959. +    void    (*intr)(stlpanel_t *panelp, unsigned int iobase);
  20960. +} uart_t;
  20961. +
  20962. +/*
  20963. + *    Define some macros to make calling these functions nice and clean.
  20964. + */
  20965. +#define    stl_panelinit        (* ((uart_t *) panelp->uartp)->panelinit)
  20966. +#define    stl_portinit        (* ((uart_t *) portp->uartp)->portinit)
  20967. +#define    stl_setport        (* ((uart_t *) portp->uartp)->setport)
  20968. +#define    stl_getsignals        (* ((uart_t *) portp->uartp)->getsignals)
  20969. +#define    stl_setsignals        (* ((uart_t *) portp->uartp)->setsignals)
  20970. +#define    stl_enablerxtx        (* ((uart_t *) portp->uartp)->enablerxtx)
  20971. +#define    stl_startrxtx        (* ((uart_t *) portp->uartp)->startrxtx)
  20972. +#define    stl_disableintrs    (* ((uart_t *) portp->uartp)->disableintrs)
  20973. +#define    stl_sendbreak        (* ((uart_t *) portp->uartp)->sendbreak)
  20974. +#define    stl_flowctrl        (* ((uart_t *) portp->uartp)->flowctrl)
  20975. +#define    stl_sendflow        (* ((uart_t *) portp->uartp)->sendflow)
  20976. +#define    stl_flush        (* ((uart_t *) portp->uartp)->flush)
  20977. +#define    stl_datastate        (* ((uart_t *) portp->uartp)->datastate)
  20978. +
  20979. +/*****************************************************************************/
  20980. +
  20981. +/*
  20982. + *    CD1400 UART specific data initialization.
  20983. + */
  20984. +static uart_t stl_cd1400uart = {
  20985. +    stl_cd1400panelinit,
  20986. +    stl_cd1400portinit,
  20987. +    stl_cd1400setport,
  20988. +    stl_cd1400getsignals,
  20989. +    stl_cd1400setsignals,
  20990. +    stl_cd1400enablerxtx,
  20991. +    stl_cd1400startrxtx,
  20992. +    stl_cd1400disableintrs,
  20993. +    stl_cd1400sendbreak,
  20994. +    stl_cd1400flowctrl,
  20995. +    stl_cd1400sendflow,
  20996. +    stl_cd1400flush,
  20997. +    stl_cd1400datastate,
  20998. +    stl_cd1400eiointr
  20999. +};
  21000. +
  21001. +/*
  21002. + *    Define the offsets within the register bank of a cd1400 based panel.
  21003. + *    These io address offsets are common to the EasyIO board as well.
  21004. + */
  21005. +#define    EREG_ADDR    0
  21006. +#define    EREG_DATA    4
  21007. +#define    EREG_RXACK    5
  21008. +#define    EREG_TXACK    6
  21009. +#define    EREG_MDACK    7
  21010. +
  21011. +#define    EREG_BANKSIZE    8
  21012. +
  21013. +#define    CD1400_CLK    25000000
  21014. +#define    CD1400_CLK8M    20000000
  21015. +
  21016. +/*
  21017. + *    Define the cd1400 baud rate clocks. These are used when calculating
  21018. + *    what clock and divisor to use for the required baud rate. Also
  21019. + *    define the maximum baud rate allowed, and the default base baud.
  21020. + */
  21021. +static int    stl_cd1400clkdivs[] = {
  21022. +    CD1400_CLK0, CD1400_CLK1, CD1400_CLK2, CD1400_CLK3, CD1400_CLK4
  21023. +};
  21024. +
  21025. +/*****************************************************************************/
  21026. +
  21027. +/*
  21028. + *    SC26198 UART specific data initization.
  21029. + */
  21030. +static uart_t stl_sc26198uart = {
  21031. +    stl_sc26198panelinit,
  21032. +    stl_sc26198portinit,
  21033. +    stl_sc26198setport,
  21034. +    stl_sc26198getsignals,
  21035. +    stl_sc26198setsignals,
  21036. +    stl_sc26198enablerxtx,
  21037. +    stl_sc26198startrxtx,
  21038. +    stl_sc26198disableintrs,
  21039. +    stl_sc26198sendbreak,
  21040. +    stl_sc26198flowctrl,
  21041. +    stl_sc26198sendflow,
  21042. +    stl_sc26198flush,
  21043. +    stl_sc26198datastate,
  21044. +    stl_sc26198intr
  21045. +};
  21046. +
  21047. +/*
  21048. + *    Define the offsets within the register bank of a sc26198 based panel.
  21049. + */
  21050. +#define    XP_DATA        0
  21051. +#define    XP_ADDR        1
  21052. +#define    XP_MODID    2
  21053. +#define    XP_STATUS    2
  21054. +#define    XP_IACK        3
  21055. +
  21056. +#define    XP_BANKSIZE    4
  21057. +
  21058. +/*
  21059. + *    Define the sc26198 baud rate table. Offsets within the table
  21060. + *    represent the actual baud rate selector of sc26198 registers.
  21061. + */
  21062. +static unsigned int    sc26198_baudtable[] = {
  21063. +    50, 75, 150, 200, 300, 450, 600, 900, 1200, 1800, 2400, 3600,
  21064. +    4800, 7200, 9600, 14400, 19200, 28800, 38400, 57600, 115200,
  21065. +    230400, 460800, 921600
  21066. +};
  21067. +
  21068. +#define    SC26198_NRBAUDS        (sizeof(sc26198_baudtable) / sizeof(unsigned int))
  21069. +
  21070.  /*****************************************************************************/
  21071.  
  21072.  /*
  21073. @@ -444,8 +662,8 @@
  21074.      NULL,
  21075.      stl_memioctl,
  21076.      NULL,
  21077. -    NULL,
  21078. -    NULL,
  21079. +    stl_memopen,
  21080. +    stl_memclose,
  21081.      NULL
  21082.  };
  21083.  
  21084. @@ -487,7 +705,8 @@
  21085.      printk("cleanup_module()\n");
  21086.  #endif
  21087.  
  21088. -    printk(KERN_INFO "Unloading %s: version %s\n", stl_drvname, stl_drvversion);
  21089. +    printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle,
  21090. +        stl_drvversion);
  21091.  
  21092.      save_flags(flags);
  21093.      cli();
  21094. @@ -501,12 +720,14 @@
  21095.      i = tty_unregister_driver(&stl_serial);
  21096.      j = tty_unregister_driver(&stl_callout);
  21097.      if (i || j) {
  21098. -        printk("STALLION: failed to un-register tty driver, errno=%d,%d\n", -i, -j);
  21099. +        printk("STALLION: failed to un-register tty driver, "
  21100. +            "errno=%d,%d\n", -i, -j);
  21101.          restore_flags(flags);
  21102.          return;
  21103.      }
  21104.      if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
  21105. -        printk("STALLION: failed to un-register serial memory device, errno=%d\n", -i);
  21106. +        printk("STALLION: failed to un-register serial memory device, "
  21107. +            "errno=%d\n", -i);
  21108.  
  21109.      if (stl_tmpwritebuf != (char *) NULL)
  21110.          kfree_s(stl_tmpwritebuf, STL_TXBUFSIZE);
  21111. @@ -515,33 +736,24 @@
  21112.          brdp = stl_brds[i];
  21113.          for (j = 0; (j < STL_MAXPANELS); j++) {
  21114.              panelp = brdp->panels[j];
  21115. -            if (panelp != (stlpanel_t *) NULL) {
  21116. -                for (k = 0; (k < STL_PORTSPERPANEL); k++) {
  21117. -                    portp = panelp->ports[k];
  21118. -                    if (portp != (stlport_t *) NULL) {
  21119. -                        if (portp->tty != (struct tty_struct *) NULL)
  21120. -                            stl_hangup(portp->tty);
  21121. -                        if (portp->tx.buf != (char *) NULL)
  21122. -                            kfree_s(portp->tx.buf, STL_TXBUFSIZE);
  21123. -                        kfree_s(portp, sizeof(stlport_t));
  21124. -                    }
  21125. -                }
  21126. -                kfree_s(panelp, sizeof(stlpanel_t));
  21127. +            if (panelp == (stlpanel_t *) NULL)
  21128. +                continue;
  21129. +            for (k = 0; (k < STL_PORTSPERPANEL); k++) {
  21130. +                portp = panelp->ports[k];
  21131. +                if (portp == (stlport_t *) NULL)
  21132. +                    continue;
  21133. +                if (portp->tty != (struct tty_struct *) NULL)
  21134. +                    stl_hangup(portp->tty);
  21135. +                if (portp->tx.buf != (char *) NULL)
  21136. +                    kfree_s(portp->tx.buf, STL_TXBUFSIZE);
  21137. +                kfree_s(portp, sizeof(stlport_t));
  21138.              }
  21139. -            
  21140. +            kfree_s(panelp, sizeof(stlpanel_t));
  21141.          }
  21142.  
  21143. -        if (brdp->brdtype == BRD_ECH) {
  21144. -            release_region(brdp->ioaddr1, 2);
  21145. -            release_region(brdp->ioaddr2, 32);
  21146. -        } else if (brdp->brdtype == BRD_ECHPCI) {
  21147. -            release_region(brdp->ioaddr1, 4);
  21148. -            release_region(brdp->ioaddr2, 8);
  21149. -        } else if (brdp->brdtype == BRD_ECHMC) {
  21150. -            release_region(brdp->ioaddr1, 64);
  21151. -        } else if (brdp->brdtype == BRD_EASYIO) {
  21152. -            release_region(brdp->ioaddr1, 8);
  21153. -        }
  21154. +        release_region(brdp->ioaddr1, brdp->iosize1);
  21155. +        if (brdp->iosize2 > 0)
  21156. +            release_region(brdp->ioaddr2, brdp->iosize2);
  21157.  
  21158.          kfree_s(brdp, sizeof(stlbrd_t));
  21159.          stl_brds[i] = (stlbrd_t *) NULL;
  21160. @@ -576,7 +788,8 @@
  21161.      int        brdnr, panelnr, portnr, rc;
  21162.  
  21163.  #if DEBUG
  21164. -    printk("stl_open(tty=%x,filp=%x): device=%x\n", (int) tty, (int) filp, tty->device);
  21165. +    printk("stl_open(tty=%x,filp=%x): device=%x\n", (int) tty,
  21166. +        (int) filp, tty->device);
  21167.  #endif
  21168.  
  21169.      minordev = MINOR(tty->device);
  21170. @@ -603,6 +816,8 @@
  21171.      if (portp == (stlport_t *) NULL)
  21172.          return(-ENODEV);
  21173.  
  21174. +    MOD_INC_USE_COUNT;
  21175. +
  21176.  /*
  21177.   *    On the first open of the device setup the port hardware, and
  21178.   *    initialize the per port data structure.
  21179. @@ -651,10 +866,10 @@
  21180.              return(-EBUSY);
  21181.          if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
  21182.              if ((portp->flags & ASYNC_SESSION_LOCKOUT) &&
  21183. -                    (portp->session != current->session))
  21184. +                (portp->session != current->session))
  21185.                  return(-EBUSY);
  21186.              if ((portp->flags & ASYNC_PGRP_LOCKOUT) &&
  21187. -                    (portp->pgrp != current->pgrp))
  21188. +                (portp->pgrp != current->pgrp))
  21189.                  return(-EBUSY);
  21190.          }
  21191.          portp->flags |= ASYNC_CALLOUT_ACTIVE;
  21192. @@ -712,13 +927,14 @@
  21193.      save_flags(flags);
  21194.      cli();
  21195.      portp->openwaitcnt++;
  21196. -    if (portp->refcount > 0)
  21197. +    if (! tty_hung_up_p(filp))
  21198.          portp->refcount--;
  21199.  
  21200.      for (;;) {
  21201.          if ((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0)
  21202.              stl_setsignals(portp, 1, 1);
  21203. -        if (tty_hung_up_p(filp) || ((portp->flags & ASYNC_INITIALIZED) == 0)) {
  21204. +        if (tty_hung_up_p(filp) ||
  21205. +            ((portp->flags & ASYNC_INITIALIZED) == 0)) {
  21206.              if (portp->flags & ASYNC_HUP_NOTIFY)
  21207.                  rc = -EBUSY;
  21208.              else
  21209. @@ -726,8 +942,8 @@
  21210.              break;
  21211.          }
  21212.          if (((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) &&
  21213. -                ((portp->flags & ASYNC_CLOSING) == 0) &&
  21214. -                (doclocal || (portp->sigs & TIOCM_CD))) {
  21215. +            ((portp->flags & ASYNC_CLOSING) == 0) &&
  21216. +            (doclocal || (portp->sigs & TIOCM_CD))) {
  21217.              break;
  21218.          }
  21219.          if (current->signal & ~current->blocked) {
  21220. @@ -763,10 +979,14 @@
  21221.      save_flags(flags);
  21222.      cli();
  21223.      if (tty_hung_up_p(filp)) {
  21224. +        MOD_DEC_USE_COUNT;
  21225.          restore_flags(flags);
  21226.          return;
  21227.      }
  21228. +    if ((tty->count == 1) && (portp->refcount != 1))
  21229. +        portp->refcount = 1;
  21230.      if (portp->refcount-- > 1) {
  21231. +        MOD_DEC_USE_COUNT;
  21232.          restore_flags(flags);
  21233.          return;
  21234.      }
  21235. @@ -781,14 +1001,14 @@
  21236.  
  21237.  /*
  21238.   *    May want to wait for any data to drain before closing. The BUSY
  21239. - *    flag keeps track of whether we are still sending or not - it allows
  21240. - *    for the FIFO in the cd1400.
  21241. + *    flag keeps track of whether we are still sending or not - it is
  21242. + *    very accurate for the cd1400, not quite so for the sc26198.
  21243. + *    (The sc26198 has no "end-of-data" interrupt only empty FIFO)
  21244.   */
  21245.      tty->closing = 1;
  21246. -    if (test_bit(ASYI_TXBUSY, &portp->istate)) {
  21247. -        if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
  21248. -            tty_wait_until_sent(tty, portp->closing_wait);
  21249. -    }
  21250. +    if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
  21251. +        tty_wait_until_sent(tty, portp->closing_wait);
  21252. +    stl_waituntilsent(tty, (HZ / 2));
  21253.  
  21254.      portp->flags &= ~ASYNC_INITIALIZED;
  21255.      stl_disableintrs(portp);
  21256. @@ -808,7 +1028,6 @@
  21257.          (tty->ldisc.flush_buffer)(tty);
  21258.  
  21259.      tty->closing = 0;
  21260. -    tty->driver_data = (void *) NULL;
  21261.      portp->tty = (struct tty_struct *) NULL;
  21262.  
  21263.      if (portp->openwaitcnt) {
  21264. @@ -817,8 +1036,10 @@
  21265.          wake_up_interruptible(&portp->open_wait);
  21266.      }
  21267.  
  21268. -    portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
  21269. +    portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE |
  21270. +        ASYNC_CLOSING);
  21271.      wake_up_interruptible(&portp->close_wait);
  21272. +    MOD_DEC_USE_COUNT;
  21273.      restore_flags(flags);
  21274.  }
  21275.  
  21276. @@ -858,10 +1079,12 @@
  21277.      char        *head, *tail;
  21278.  
  21279.  #if DEBUG
  21280. -    printk("stl_write(tty=%x,from_user=%d,buf=%x,count=%d)\n", (int) tty, from_user, (int) buf, count);
  21281. +    printk("stl_write(tty=%x,from_user=%d,buf=%x,count=%d)\n",
  21282. +        (int) tty, from_user, (int) buf, count);
  21283.  #endif
  21284.  
  21285. -    if ((tty == (struct tty_struct *) NULL) || (stl_tmpwritebuf == (char *) NULL))
  21286. +    if ((tty == (struct tty_struct *) NULL) ||
  21287. +        (stl_tmpwritebuf == (char *) NULL))
  21288.          return(0);
  21289.      portp = tty->driver_data;
  21290.      if (portp == (stlport_t *) NULL)
  21291. @@ -983,7 +1206,8 @@
  21292.          return;
  21293.  
  21294.  #if 0
  21295. -    if (tty->stopped || tty->hw_stopped || (portp->tx.head == portp->tx.tail))
  21296. +    if (tty->stopped || tty->hw_stopped ||
  21297. +        (portp->tx.head == portp->tx.tail))
  21298.          return;
  21299.  #endif
  21300.      stl_startrxtx(portp, -1, 1);
  21301. @@ -1066,7 +1290,6 @@
  21302.  #endif
  21303.  
  21304.      memset(&sio, 0, sizeof(struct serial_struct));
  21305. -    sio.type = PORT_CIRRUS;
  21306.      sio.line = portp->portnr;
  21307.      sio.port = portp->ioaddr;
  21308.      sio.flags = portp->flags;
  21309. @@ -1074,8 +1297,14 @@
  21310.      sio.close_delay = portp->close_delay;
  21311.      sio.closing_wait = portp->closing_wait;
  21312.      sio.custom_divisor = portp->custom_divisor;
  21313. -    sio.xmit_fifo_size = CD1400_TXFIFOSIZE;
  21314.      sio.hub6 = 0;
  21315. +    if (portp->uartp == &stl_cd1400uart) {
  21316. +        sio.type = PORT_CIRRUS;
  21317. +        sio.xmit_fifo_size = CD1400_TXFIFOSIZE;
  21318. +    } else {
  21319. +        sio.type = PORT_UNKNOWN;
  21320. +        sio.xmit_fifo_size = SC26198_TXFIFOSIZE;
  21321. +    }
  21322.  
  21323.      brdp = stl_brds[portp->brdnr];
  21324.      if (brdp != (stlbrd_t *) NULL)
  21325. @@ -1103,12 +1332,14 @@
  21326.      memcpy_fromfs(&sio, sp, sizeof(struct serial_struct));
  21327.      if (!suser()) {
  21328.          if ((sio.baud_base != portp->baud_base) ||
  21329. -                (sio.close_delay != portp->close_delay) ||
  21330. -                ((sio.flags & ~ASYNC_USR_MASK) != (portp->flags & ~ASYNC_USR_MASK)))
  21331. +            (sio.close_delay != portp->close_delay) ||
  21332. +            ((sio.flags & ~ASYNC_USR_MASK) !=
  21333. +            (portp->flags & ~ASYNC_USR_MASK)))
  21334.              return(-EPERM);
  21335.      } 
  21336.  
  21337. -    portp->flags = (portp->flags & ~ASYNC_USR_MASK) | (sio.flags & ASYNC_USR_MASK);
  21338. +    portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
  21339. +        (sio.flags & ASYNC_USR_MASK);
  21340.      portp->baud_base = sio.baud_base;
  21341.      portp->close_delay = sio.close_delay;
  21342.      portp->closing_wait = sio.closing_wait;
  21343. @@ -1126,7 +1357,8 @@
  21344.      int        rc;
  21345.  
  21346.  #if DEBUG
  21347. -    printk("stl_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n", (int) tty, (int) file, cmd, (int) arg);
  21348. +    printk("stl_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n",
  21349. +        (int) tty, (int) file, cmd, (int) arg);
  21350.  #endif
  21351.  
  21352.      if (tty == (struct tty_struct *) NULL)
  21353. @@ -1135,6 +1367,12 @@
  21354.      if (portp == (stlport_t *) NULL)
  21355.          return(-ENODEV);
  21356.  
  21357. +    if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
  21358. +         (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
  21359. +        if (tty->flags & (1 << TTY_IO_ERROR))
  21360. +            return(-EIO);
  21361. +    }
  21362. +
  21363.      rc = 0;
  21364.  
  21365.      switch (cmd) {
  21366. @@ -1152,53 +1390,69 @@
  21367.          }
  21368.          break;
  21369.      case TIOCGSOFTCAR:
  21370. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long))) == 0)
  21371. -            put_fs_long(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), (unsigned long *) arg);
  21372. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  21373. +            sizeof(long))) == 0)
  21374. +            put_fs_long(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
  21375. +                (unsigned long *) arg);
  21376.          break;
  21377.      case TIOCSSOFTCAR:
  21378. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
  21379. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  21380. +            sizeof(long))) == 0) {
  21381.              arg = get_fs_long((unsigned long *) arg);
  21382. -            tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0);
  21383. +            tty->termios->c_cflag =
  21384. +                (tty->termios->c_cflag & ~CLOCAL) |
  21385. +                (arg ? CLOCAL : 0);
  21386.          }
  21387.          break;
  21388.      case TIOCMGET:
  21389. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned int))) == 0) {
  21390. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  21391. +            sizeof(unsigned int))) == 0) {
  21392.              val = (unsigned long) stl_getsignals(portp);
  21393.              put_fs_long(val, (unsigned long *) arg);
  21394.          }
  21395.          break;
  21396.      case TIOCMBIS:
  21397. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
  21398. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  21399. +            sizeof(long))) == 0) {
  21400.              arg = get_fs_long((unsigned long *) arg);
  21401. -            stl_setsignals(portp, ((arg & TIOCM_DTR) ? 1 : -1), ((arg & TIOCM_RTS) ? 1 : -1));
  21402. +            stl_setsignals(portp, ((arg & TIOCM_DTR) ? 1 : -1),
  21403. +                ((arg & TIOCM_RTS) ? 1 : -1));
  21404.          }
  21405.          break;
  21406.      case TIOCMBIC:
  21407. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
  21408. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  21409. +            sizeof(long))) == 0) {
  21410.              arg = get_fs_long((unsigned long *) arg);
  21411. -            stl_setsignals(portp, ((arg & TIOCM_DTR) ? 0 : -1), ((arg & TIOCM_RTS) ? 0 : -1));
  21412. +            stl_setsignals(portp, ((arg & TIOCM_DTR) ? 0 : -1),
  21413. +                ((arg & TIOCM_RTS) ? 0 : -1));
  21414.          }
  21415.          break;
  21416.      case TIOCMSET:
  21417. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
  21418. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  21419. +            sizeof(long))) == 0) {
  21420.              arg = get_fs_long((unsigned long *) arg);
  21421. -            stl_setsignals(portp, ((arg & TIOCM_DTR) ? 1 : 0), ((arg & TIOCM_RTS) ? 1 : 0));
  21422. +            stl_setsignals(portp, ((arg & TIOCM_DTR) ? 1 : 0),
  21423. +                ((arg & TIOCM_RTS) ? 1 : 0));
  21424.          }
  21425.          break;
  21426.      case TIOCGSERIAL:
  21427. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct serial_struct))) == 0)
  21428. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  21429. +            sizeof(struct serial_struct))) == 0)
  21430.              stl_getserial(portp, (struct serial_struct *) arg);
  21431.          break;
  21432.      case TIOCSSERIAL:
  21433. -        if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(struct serial_struct))) == 0)
  21434. +        if ((rc = verify_area(VERIFY_READ, (void *) arg,
  21435. +            sizeof(struct serial_struct))) == 0)
  21436.              rc = stl_setserial(portp, (struct serial_struct *) arg);
  21437.          break;
  21438.      case COM_GETPORTSTATS:
  21439. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
  21440. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  21441. +            sizeof(comstats_t))) == 0)
  21442.              rc = stl_getportstats(portp, (comstats_t *) arg);
  21443.          break;
  21444.      case COM_CLRPORTSTATS:
  21445. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
  21446. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  21447. +            sizeof(comstats_t))) == 0)
  21448.              rc = stl_clrportstats(portp, (comstats_t *) arg);
  21449.          break;
  21450.      case TIOCSERCONFIG:
  21451. @@ -1234,11 +1488,13 @@
  21452.          return;
  21453.  
  21454.      tiosp = tty->termios;
  21455. -    if ((tiosp->c_cflag == old->c_cflag) && (tiosp->c_iflag == old->c_iflag))
  21456. +    if ((tiosp->c_cflag == old->c_cflag) &&
  21457. +        (tiosp->c_iflag == old->c_iflag))
  21458.          return;
  21459.  
  21460.      stl_setport(portp, tiosp);
  21461. -    stl_setsignals(portp, ((tiosp->c_cflag & (CBAUD & ~CBAUDEX)) ? 1 : 0), -1);
  21462. +    stl_setsignals(portp, ((tiosp->c_cflag & (CBAUD & ~CBAUDEX)) ? 1 : 0),
  21463. +        -1);
  21464.      if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) {
  21465.          tty->hw_stopped = 0;
  21466.          stl_start(tty);
  21467. @@ -1257,7 +1513,6 @@
  21468.  static void stl_throttle(struct tty_struct *tty)
  21469.  {
  21470.      stlport_t    *portp;
  21471. -    unsigned long    flags;
  21472.  
  21473.  #if DEBUG
  21474.      printk("stl_throttle(tty=%x)\n", (int) tty);
  21475. @@ -1268,24 +1523,7 @@
  21476.      portp = tty->driver_data;
  21477.      if (portp == (stlport_t *) NULL)
  21478.          return;
  21479. -
  21480. -    save_flags(flags);
  21481. -    cli();
  21482. -    BRDENABLE(portp->brdnr, portp->pagenr);
  21483. -    stl_setreg(portp, CAR, (portp->portnr & 0x03));
  21484. -    if (tty->termios->c_iflag & IXOFF) {
  21485. -        stl_ccrwait(portp);
  21486. -        stl_setreg(portp, CCR, CCR_SENDSCHR2);
  21487. -        portp->stats.rxxoff++;
  21488. -        stl_ccrwait(portp);
  21489. -    }
  21490. -    if (tty->termios->c_cflag & CRTSCTS) {
  21491. -        stl_setreg(portp, MCOR1, (stl_getreg(portp, MCOR1) & 0xf0));
  21492. -        stl_setreg(portp, MSVR2, 0);
  21493. -        portp->stats.rxrtsoff++;
  21494. -    }
  21495. -    BRDDISABLE(portp->brdnr);
  21496. -    restore_flags(flags);
  21497. +    stl_flowctrl(portp, 0);
  21498.  }
  21499.  
  21500.  /*****************************************************************************/
  21501. @@ -1297,7 +1535,6 @@
  21502.  static void stl_unthrottle(struct tty_struct *tty)
  21503.  {
  21504.      stlport_t    *portp;
  21505. -    unsigned long    flags;
  21506.  
  21507.  #if DEBUG
  21508.      printk("stl_unthrottle(tty=%x)\n", (int) tty);
  21509. @@ -1308,30 +1545,7 @@
  21510.      portp = tty->driver_data;
  21511.      if (portp == (stlport_t *) NULL)
  21512.          return;
  21513. -
  21514. -    save_flags(flags);
  21515. -    cli();
  21516. -    BRDENABLE(portp->brdnr, portp->pagenr);
  21517. -    stl_setreg(portp, CAR, (portp->portnr & 0x03));
  21518. -    if (tty->termios->c_iflag & IXOFF) {
  21519. -        stl_ccrwait(portp);
  21520. -        stl_setreg(portp, CCR, CCR_SENDSCHR1);
  21521. -        portp->stats.rxxon++;
  21522. -        stl_ccrwait(portp);
  21523. -    }
  21524. -/*
  21525. - *    Question: should we return RTS to what it was before? It may have
  21526. - *    been set by an ioctl... Suppose not, since if you have hardware
  21527. - *    flow control set then it is pretty silly to go and set the RTS line
  21528. - *    by hand.
  21529. - */
  21530. -    if (tty->termios->c_cflag & CRTSCTS) {
  21531. -        stl_setreg(portp, MCOR1, (stl_getreg(portp, MCOR1) | FIFO_RTSTHRESHOLD));
  21532. -        stl_setreg(portp, MSVR2, MSVR2_RTS);
  21533. -        portp->stats.rxrtson++;
  21534. -    }
  21535. -    BRDDISABLE(portp->brdnr);
  21536. -    restore_flags(flags);
  21537. +    stl_flowctrl(portp, 1);
  21538.  }
  21539.  
  21540.  /*****************************************************************************/
  21541. @@ -1354,7 +1568,6 @@
  21542.      portp = tty->driver_data;
  21543.      if (portp == (stlport_t *) NULL)
  21544.          return;
  21545. -
  21546.      stl_startrxtx(portp, -1, 0);
  21547.  }
  21548.  
  21549. @@ -1377,7 +1590,6 @@
  21550.      portp = tty->driver_data;
  21551.      if (portp == (stlport_t *) NULL)
  21552.          return;
  21553. -
  21554.      stl_startrxtx(portp, -1, 1);
  21555.  }
  21556.  
  21557. @@ -1417,7 +1629,6 @@
  21558.          portp->tx.head = (char *) NULL;
  21559.          portp->tx.tail = (char *) NULL;
  21560.      }
  21561. -    tty->driver_data = (void *) NULL;
  21562.      portp->tty = (struct tty_struct *) NULL;
  21563.      portp->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
  21564.      portp->refcount = 0;
  21565. @@ -1429,7 +1640,6 @@
  21566.  static void stl_flushbuffer(struct tty_struct *tty)
  21567.  {
  21568.      stlport_t    *portp;
  21569. -    unsigned long    flags;
  21570.  
  21571.  #if DEBUG
  21572.      printk("stl_flushbuffer(tty=%x)\n", (int) tty);
  21573. @@ -1441,439 +1651,183 @@
  21574.      if (portp == (stlport_t *) NULL)
  21575.          return;
  21576.  
  21577. -    save_flags(flags);
  21578. -    cli();
  21579. -    BRDENABLE(portp->brdnr, portp->pagenr);
  21580. -    stl_setreg(portp, CAR, (portp->portnr & 0x03));
  21581. -    stl_ccrwait(portp);
  21582. -    stl_setreg(portp, CCR, CCR_TXFLUSHFIFO);
  21583. -    stl_ccrwait(portp);
  21584. -    portp->tx.tail = portp->tx.head;
  21585. -    BRDDISABLE(portp->brdnr);
  21586. -    restore_flags(flags);
  21587. -
  21588. +    stl_flush(portp);
  21589.      wake_up_interruptible(&tty->write_wait);
  21590. -    if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
  21591. +    if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  21592. +        tty->ldisc.write_wakeup)
  21593.          (tty->ldisc.write_wakeup)(tty);
  21594.  }
  21595.  
  21596.  /*****************************************************************************/
  21597.  
  21598. -/*
  21599. - *    These functions get/set/update the registers of the cd1400 UARTs.
  21600. - *    Access to the cd1400 registers is via an address/data io port pair.
  21601. - *    (Maybe should make this inline...)
  21602. - */
  21603. -
  21604. -static int stl_getreg(stlport_t *portp, int regnr)
  21605. +static void stl_waituntilsent(struct tty_struct *tty, int timeout)
  21606.  {
  21607. -    outb((regnr + portp->uartaddr), portp->ioaddr);
  21608. -    return(inb(portp->ioaddr + EREG_DATA));
  21609. -}
  21610. +    stlport_t    *portp;
  21611. +    unsigned long    tend;
  21612.  
  21613. -static void stl_setreg(stlport_t *portp, int regnr, int value)
  21614. -{
  21615. -    outb((regnr + portp->uartaddr), portp->ioaddr);
  21616. -    outb(value, portp->ioaddr + EREG_DATA);
  21617. -}
  21618. +#if DEBUG
  21619. +    printk("stl_waituntilsent(tty=%x,timeout=%d)\n", (int) tty, timeout);
  21620. +#endif
  21621.  
  21622. -static int stl_updatereg(stlport_t *portp, int regnr, int value)
  21623. -{
  21624. -    outb((regnr + portp->uartaddr), portp->ioaddr);
  21625. -    if (inb(portp->ioaddr + EREG_DATA) != value) {
  21626. -        outb(value, portp->ioaddr + EREG_DATA);
  21627. -        return(1);
  21628. +    if (tty == (struct tty_struct *) NULL)
  21629. +        return;
  21630. +    portp = tty->driver_data;
  21631. +    if (portp == (stlport_t *) NULL)
  21632. +        return;
  21633. +
  21634. +    if (timeout == 0)
  21635. +        timeout = HZ;
  21636. +    tend = jiffies + timeout;
  21637. +
  21638. +    while (stl_datastate(portp)) {
  21639. +        if (current->signal & ~current->blocked)
  21640. +            break;
  21641. +        stl_delay(2);
  21642. +        if (jiffies >= tend)
  21643. +            break;
  21644.      }
  21645. -    return(0);
  21646.  }
  21647.  
  21648.  /*****************************************************************************/
  21649.  
  21650.  /*
  21651. - *    Transmit interrupt handler. This has gotta be fast!  Handling TX
  21652. - *    chars is pretty simple, stuff as many as possible from the TX buffer
  21653. - *    into the cd1400 FIFO. Must also handle TX breaks here, since they
  21654. - *    are embedded as commands in the data stream. Oh no, had to use a goto!
  21655. - *    This could be optimized more, will do when I get time...
  21656. - *    In practice it is possible that interrupts are enabled but that the
  21657. - *    port has been hung up. Need to handle not having any TX buffer here,
  21658. - *    this is done by using the side effect that head and tail will also
  21659. - *    be NULL if the buffer has been freed.
  21660. + *    All board interrupts are vectored through here first. This code then
  21661. + *    calls off to the approrpriate board interrupt handlers.
  21662.   */
  21663.  
  21664. -static inline void stl_txisr(stlpanel_t *panelp, int ioaddr)
  21665. +static void stl_intr(int irq, void *dev_id, struct pt_regs *regs)
  21666.  {
  21667. -    stlport_t    *portp;
  21668. -    int        len, stlen;
  21669. -    char        *head, *tail;
  21670. -    unsigned char    ioack, srer;
  21671. +    stlbrd_t    *brdp;
  21672. +    int        i;
  21673.  
  21674.  #if DEBUG
  21675. -    printk("stl_txisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
  21676. +    printk("stl_intr(irq=%d,regs=%x)\n", irq, (int) regs);
  21677.  #endif
  21678.  
  21679. -    ioack = inb(ioaddr + EREG_TXACK);
  21680. -    if (((ioack & panelp->ackmask) != 0) || ((ioack & ACK_TYPMASK) != ACK_TYPTX)) {
  21681. -        printk("STALLION: bad TX interrupt ack value=%x\n", ioack);
  21682. -        return;
  21683. +    for (i = 0; (i < stl_nrbrds); i++) {
  21684. +        if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
  21685. +            continue;
  21686. +        if (brdp->state == 0)
  21687. +            continue;
  21688. +        (* brdp->isr)(brdp);
  21689.      }
  21690. -    portp = panelp->ports[(ioack >> 3)];
  21691. +}
  21692. +
  21693. +/*****************************************************************************/
  21694.  
  21695.  /*
  21696. - *    Unfortunately we need to handle breaks in the data stream, since
  21697. - *    this is the only way to generate them on the cd1400. Do it now if
  21698. - *    a break is to be sent.
  21699. + *    Interrupt service routine for EasyIO board types.
  21700.   */
  21701. -    if (portp->brklen != 0) {
  21702. -        if (portp->brklen > 0) {
  21703. -            outb((TDR + portp->uartaddr), ioaddr);
  21704. -            outb(ETC_CMD, (ioaddr + EREG_DATA));
  21705. -            outb(ETC_STARTBREAK, (ioaddr + EREG_DATA));
  21706. -            outb(ETC_CMD, (ioaddr + EREG_DATA));
  21707. -            outb(ETC_DELAY, (ioaddr + EREG_DATA));
  21708. -            outb(portp->brklen, (ioaddr + EREG_DATA));
  21709. -            outb(ETC_CMD, (ioaddr + EREG_DATA));
  21710. -            outb(ETC_STOPBREAK, (ioaddr + EREG_DATA));
  21711. -            portp->brklen = -1;
  21712. -            goto stl_txalldone;
  21713. -        } else {
  21714. -            outb((COR2 + portp->uartaddr), ioaddr);
  21715. -            outb((inb(ioaddr + EREG_DATA) & ~COR2_ETC), (ioaddr + EREG_DATA));
  21716. -            portp->brklen = 0;
  21717. -        }
  21718. -    }
  21719. -
  21720. -    head = portp->tx.head;
  21721. -    tail = portp->tx.tail;
  21722. -    len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
  21723. -    if ((len == 0) || ((len < STL_TXBUFLOW) && (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
  21724. -        set_bit(ASYI_TXLOW, &portp->istate);
  21725. -        queue_task_irq_off(&portp->tqueue, &tq_scheduler);
  21726. -    }
  21727.  
  21728. -    if (len == 0) {
  21729. -        outb((SRER + portp->uartaddr), ioaddr);
  21730. -        srer = inb(ioaddr + EREG_DATA);
  21731. -        if (srer & SRER_TXDATA) {
  21732. -            srer = (srer & ~SRER_TXDATA) | SRER_TXEMPTY;
  21733. -        } else {
  21734. -            srer &= ~(SRER_TXDATA | SRER_TXEMPTY);
  21735. -            clear_bit(ASYI_TXBUSY, &portp->istate);
  21736. -        }
  21737. -        outb(srer, (ioaddr + EREG_DATA));
  21738. -    } else {
  21739. -        len = MIN(len, CD1400_TXFIFOSIZE);
  21740. -        portp->stats.txtotal += len;
  21741. -        stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
  21742. -        outb((TDR + portp->uartaddr), ioaddr);
  21743. -        outsb((ioaddr + EREG_DATA), tail, stlen);
  21744. -        len -= stlen;
  21745. -        tail += stlen;
  21746. -        if (tail >= (portp->tx.buf + STL_TXBUFSIZE))
  21747. -            tail = portp->tx.buf;
  21748. -        if (len > 0) {
  21749. -            outsb((ioaddr + EREG_DATA), tail, len);
  21750. -            tail += len;
  21751. -        }
  21752. -        portp->tx.tail = tail;
  21753. -    }
  21754. +static void stl_eiointr(stlbrd_t *brdp)
  21755. +{
  21756. +    stlpanel_t    *panelp;
  21757. +    unsigned int    iobase;
  21758.  
  21759. -stl_txalldone:
  21760. -    outb((EOSRR + portp->uartaddr), ioaddr);
  21761. -    outb(0, (ioaddr + EREG_DATA));
  21762. +    panelp = brdp->panels[0];
  21763. +    iobase = panelp->iobase;
  21764. +    while (inb(brdp->iostatus) & EIO_INTRPEND)
  21765. +        (* panelp->isr)(panelp, iobase);
  21766.  }
  21767.  
  21768.  /*****************************************************************************/
  21769.  
  21770.  /*
  21771. - *    Receive character interrupt handler. Determine if we have good chars
  21772. - *    or bad chars and then process appropriately. Good chars are easy
  21773. - *    just shove the lot into the RX buffer and set all status byte to 0.
  21774. - *    If a bad RX char then process as required. This routine needs to be
  21775. - *    fast!  In practice it is possible that we get an interrupt on a port
  21776. - *    that is closed. This can happen on hangups - since they completely
  21777. - *    shutdown a port not in user context. Need to handle this case.
  21778. + *    Interrupt service routine for ECH-AT board types.
  21779.   */
  21780.  
  21781. -static inline void stl_rxisr(stlpanel_t *panelp, int ioaddr)
  21782. +static void stl_echatintr(stlbrd_t *brdp)
  21783.  {
  21784. -    stlport_t        *portp;
  21785. -    struct tty_struct    *tty;
  21786. -    unsigned int        ioack, len, buflen;
  21787. -    unsigned char        status;
  21788. -    char            ch;
  21789. -    static char        unwanted[CD1400_RXFIFOSIZE];
  21790. +    stlpanel_t    *panelp;
  21791. +    unsigned int    ioaddr;
  21792. +    int        bnknr;
  21793.  
  21794. -#if DEBUG
  21795. -    printk("stl_rxisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
  21796. -#endif
  21797. +    outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
  21798.  
  21799. -    ioack = inb(ioaddr + EREG_RXACK);
  21800. -    if ((ioack & panelp->ackmask) != 0) {
  21801. -        printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
  21802. -        return;
  21803. -    }
  21804. -    portp = panelp->ports[(ioack >> 3)];
  21805. -    tty = portp->tty;
  21806. -
  21807. -    if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
  21808. -        outb((RDCR + portp->uartaddr), ioaddr);
  21809. -        len = inb(ioaddr + EREG_DATA);
  21810. -        if ((tty == (struct tty_struct *) NULL) || (tty->flip.char_buf_ptr == (char *) NULL) ||
  21811. -                ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
  21812. -            outb((RDSR + portp->uartaddr), ioaddr);
  21813. -            insb((ioaddr + EREG_DATA), &unwanted[0], len);
  21814. -            portp->stats.rxlost += len;
  21815. -            portp->stats.rxtotal += len;
  21816. -        } else {
  21817. -            len = MIN(len, buflen);
  21818. -            if (len > 0) {
  21819. -                outb((RDSR + portp->uartaddr), ioaddr);
  21820. -                insb((ioaddr + EREG_DATA), tty->flip.char_buf_ptr, len);
  21821. -                memset(tty->flip.flag_buf_ptr, 0, len);
  21822. -                tty->flip.flag_buf_ptr += len;
  21823. -                tty->flip.char_buf_ptr += len;
  21824. -                tty->flip.count += len;
  21825. -                tty_schedule_flip(tty);
  21826. -                portp->stats.rxtotal += len;
  21827. -            }
  21828. -        }
  21829. -    } else if ((ioack & ACK_TYPMASK) == ACK_TYPRXBAD) {
  21830. -        outb((RDSR + portp->uartaddr), ioaddr);
  21831. -        status = inb(ioaddr + EREG_DATA);
  21832. -        ch = inb(ioaddr + EREG_DATA);
  21833. -        if (status & ST_PARITY)
  21834. -            portp->stats.rxparity++;
  21835. -        if (status & ST_FRAMING)
  21836. -            portp->stats.rxframing++;
  21837. -        if (status & ST_OVERRUN)
  21838. -            portp->stats.rxoverrun++;
  21839. -        if (status & ST_BREAK)
  21840. -            portp->stats.rxbreaks++;
  21841. -        if (status & ST_SCHARMASK) {
  21842. -            if ((status & ST_SCHARMASK) == ST_SCHAR1)
  21843. -                portp->stats.txxon++;
  21844. -            if ((status & ST_SCHARMASK) == ST_SCHAR2)
  21845. -                portp->stats.txxoff++;
  21846. -            goto stl_rxalldone;
  21847. -        }
  21848. -        if ((tty != (struct tty_struct *) NULL) && ((portp->rxignoremsk & status) == 0)) {
  21849. -            if (portp->rxmarkmsk & status) {
  21850. -                if (status & ST_BREAK) {
  21851. -                    status = TTY_BREAK;
  21852. -#ifndef MODULE
  21853. -                    if (portp->flags & ASYNC_SAK) {
  21854. -                        do_SAK(tty);
  21855. -                        BRDENABLE(portp->brdnr, portp->pagenr);
  21856. -                    }
  21857. -#endif
  21858. -                } else if (status & ST_PARITY) {
  21859. -                    status = TTY_PARITY;
  21860. -                } else if (status & ST_FRAMING) {
  21861. -                    status = TTY_FRAME;
  21862. -                } else if(status & ST_OVERRUN) {
  21863. -                    status = TTY_OVERRUN;
  21864. -                } else {
  21865. -                    status = 0;
  21866. -                }
  21867. -            } else {
  21868. -                status = 0;
  21869. -            }
  21870. -            if (tty->flip.char_buf_ptr != (char *) NULL) {
  21871. -                if (tty->flip.count < TTY_FLIPBUF_SIZE) {
  21872. -                    *tty->flip.flag_buf_ptr++ = status;
  21873. -                    *tty->flip.char_buf_ptr++ = ch;
  21874. -                    tty->flip.count++;
  21875. -                }
  21876. -                tty_schedule_flip(tty);
  21877. +    while (inb(brdp->iostatus) & ECH_INTRPEND) {
  21878. +        for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
  21879. +            ioaddr = brdp->bnkstataddr[bnknr];
  21880. +            if (inb(ioaddr) & ECH_PNLINTRPEND) {
  21881. +                panelp = brdp->bnk2panel[bnknr];
  21882. +                (* panelp->isr)(panelp, (ioaddr & 0xfffc));
  21883.              }
  21884.          }
  21885. -    } else {
  21886. -        printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
  21887. -        return;
  21888.      }
  21889.  
  21890. -stl_rxalldone:
  21891. -    outb((EOSRR + portp->uartaddr), ioaddr);
  21892. -    outb(0, (ioaddr + EREG_DATA));
  21893. +    outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
  21894.  }
  21895.  
  21896.  /*****************************************************************************/
  21897.  
  21898.  /*
  21899. - *    Modem interrupt handler. The is called when the modem signal line
  21900. - *    (DCD) has changed state. Leave most of the work to the off-level
  21901. - *    processing routine.
  21902. + *    Interrupt service routine for ECH-MCA board types.
  21903.   */
  21904.  
  21905. -static inline void stl_mdmisr(stlpanel_t *panelp, int ioaddr)
  21906. +static void stl_echmcaintr(stlbrd_t *brdp)
  21907.  {
  21908. -    stlport_t    *portp;
  21909. -    unsigned int    ioack;
  21910. -    unsigned char    misr;
  21911. -
  21912. -#if DEBUG
  21913. -    printk("stl_mdmisr(panelp=%x)\n", (int) panelp);
  21914. -#endif
  21915. -
  21916. -    ioack = inb(ioaddr + EREG_MDACK);
  21917. -    if (((ioack & panelp->ackmask) != 0) || ((ioack & ACK_TYPMASK) != ACK_TYPMDM)) {
  21918. -        printk("STALLION: bad MODEM interrupt ack value=%x\n", ioack);
  21919. -        return;
  21920. -    }
  21921. -    portp = panelp->ports[(ioack >> 3)];
  21922. +    stlpanel_t    *panelp;
  21923. +    unsigned int    ioaddr;
  21924. +    int        bnknr;
  21925.  
  21926. -    outb((MISR + portp->uartaddr), ioaddr);
  21927. -    misr = inb(ioaddr + EREG_DATA);
  21928. -    if (misr & MISR_DCD) {
  21929. -        set_bit(ASYI_DCDCHANGE, &portp->istate);
  21930. -        queue_task_irq_off(&portp->tqueue, &tq_scheduler);
  21931. -        portp->stats.modem++;
  21932. +    while (inb(brdp->iostatus) & ECH_INTRPEND) {
  21933. +        for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
  21934. +            ioaddr = brdp->bnkstataddr[bnknr];
  21935. +            if (inb(ioaddr) & ECH_PNLINTRPEND) {
  21936. +                panelp = brdp->bnk2panel[bnknr];
  21937. +                (* panelp->isr)(panelp, (ioaddr & 0xfffc));
  21938. +            }
  21939. +        }
  21940.      }
  21941. -
  21942. -    outb((EOSRR + portp->uartaddr), ioaddr);
  21943. -    outb(0, (ioaddr + EREG_DATA));
  21944.  }
  21945.  
  21946.  /*****************************************************************************/
  21947.  
  21948.  /*
  21949. - *    Interrupt handler for EIO and ECH boards. This code ain't all that
  21950. - *    pretty, but the idea is to make it as fast as possible. This code is
  21951. - *    well suited to be assemblerized :-)  We don't use the general purpose
  21952. - *    register access functions here, for speed we will go strait to the
  21953. - *    io region.
  21954. + *    Interrupt service routine for ECH-PCI board types.
  21955.   */
  21956.  
  21957. -static void stl_intr(int irq, void *dev_id, struct pt_regs *regs)
  21958. +static void stl_echpciintr(stlbrd_t *brdp)
  21959.  {
  21960. -    stlbrd_t    *brdp;
  21961.      stlpanel_t    *panelp;
  21962. -    unsigned char    svrtype;
  21963. -    int        i, panelnr, iobase;
  21964. -
  21965. -#if DEBUG
  21966. -    printk("stl_intr(irq=%d,regs=%x)\n", irq, (int) regs);
  21967. -#endif
  21968. +    unsigned int    ioaddr;
  21969. +    int        bnknr, recheck;
  21970.  
  21971. -    panelp = (stlpanel_t *) NULL;
  21972. -    for (i = 0; (i < stl_nrbrds); ) {
  21973. -        if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) {
  21974. -            i++;
  21975. -            continue;
  21976. -        }
  21977. -        if (brdp->state == 0) {
  21978. -            i++;
  21979. -            continue;
  21980. -        }
  21981. -/*
  21982. - *        The following section of code handles the subtle differences
  21983. - *        between board types. It is sort of similar, but different
  21984. - *        enough to handle each separately.
  21985. - */
  21986. -        if (brdp->brdtype == BRD_EASYIO) {
  21987. -            if ((inb(brdp->iostatus) & EIO_INTRPEND) == 0) {
  21988. -                i++;
  21989. -                continue;
  21990. -            }
  21991. -            panelp = brdp->panels[0];
  21992. -            iobase = panelp->iobase;
  21993. -            outb(SVRR, iobase);
  21994. -            svrtype = inb(iobase + EREG_DATA);
  21995. -            if (brdp->nrports > 4) {
  21996. -                outb((SVRR + 0x80), iobase);
  21997. -                svrtype |= inb(iobase + EREG_DATA);
  21998. -            }
  21999. -        } else if (brdp->brdtype == BRD_ECH) {
  22000. -            if ((inb(brdp->iostatus) & ECH_INTRPEND) == 0) {
  22001. -                i++;
  22002. -                continue;
  22003. -            }
  22004. -            outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
  22005. -            for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) {
  22006. -                panelp = brdp->panels[panelnr];
  22007. -                iobase = panelp->iobase;
  22008. -                if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
  22009. -                    break;
  22010. -                if (panelp->nrports > 8) {
  22011. -                    iobase += 0x8;
  22012. -                    if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
  22013. -                        break;
  22014. -                }
  22015. -            }    
  22016. -            if (panelnr >= brdp->nrpanels) {
  22017. -                i++;
  22018. -                continue;
  22019. +    while (1) {
  22020. +        recheck = 0;
  22021. +        for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
  22022. +            outb(brdp->bnkpageaddr[bnknr], brdp->ioctrl);
  22023. +            ioaddr = brdp->bnkstataddr[bnknr];
  22024. +            if (inb(ioaddr) & ECH_PNLINTRPEND) {
  22025. +                panelp = brdp->bnk2panel[bnknr];
  22026. +                (* panelp->isr)(panelp, (ioaddr & 0xfffc));
  22027. +                recheck++;
  22028.              }
  22029. -            outb(SVRR, iobase);
  22030. -            svrtype = inb(iobase + EREG_DATA);
  22031. -            outb((SVRR + 0x80), iobase);
  22032. -            svrtype |= inb(iobase + EREG_DATA);
  22033. -        } else if (brdp->brdtype == BRD_ECHPCI) {
  22034. -            iobase = brdp->ioaddr2;
  22035. -            for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) {
  22036. -                panelp = brdp->panels[panelnr];
  22037. -                outb(panelp->pagenr, brdp->ioctrl);
  22038. -                if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
  22039. -                    break;
  22040. -                if (panelp->nrports > 8) {
  22041. -                    outb((panelp->pagenr + 1), brdp->ioctrl);
  22042. -                    if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
  22043. -                        break;
  22044. -                }
  22045. -            }    
  22046. -            if (panelnr >= brdp->nrpanels) {
  22047. -                i++;
  22048. -                continue;
  22049. -            }
  22050. -            outb(SVRR, iobase);
  22051. -            svrtype = inb(iobase + EREG_DATA);
  22052. -            outb((SVRR + 0x80), iobase);
  22053. -            svrtype |= inb(iobase + EREG_DATA);
  22054. -        } else if (brdp->brdtype == BRD_ECHMC) {
  22055. -            if ((inb(brdp->iostatus) & ECH_INTRPEND) == 0) {
  22056. -                i++;
  22057. -                continue;
  22058. -            }
  22059. -            for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) {
  22060. -                panelp = brdp->panels[panelnr];
  22061. -                iobase = panelp->iobase;
  22062. -                if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
  22063. -                    break;
  22064. -                if (panelp->nrports > 8) {
  22065. -                    iobase += 0x8;
  22066. -                    if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
  22067. -                        break;
  22068. -                }
  22069. -            }    
  22070. -            if (panelnr >= brdp->nrpanels) {
  22071. -                i++;
  22072. -                continue;
  22073. -            }
  22074. -            outb(SVRR, iobase);
  22075. -            svrtype = inb(iobase + EREG_DATA);
  22076. -            outb((SVRR + 0x80), iobase);
  22077. -            svrtype |= inb(iobase + EREG_DATA);
  22078. -        } else {
  22079. -            printk("STALLION: unknown board type=%x\n", brdp->brdtype);
  22080. -            i++;
  22081. -            continue;
  22082.          }
  22083. +        if (! recheck)
  22084. +            break;
  22085. +    }
  22086. +}
  22087. +
  22088. +/*****************************************************************************/
  22089.  
  22090.  /*
  22091. - *        We have determined what type of service is required for a
  22092. - *        port. From here on in the service of a port is the same no
  22093. - *        matter what the board type...
  22094. - */
  22095. -        if (svrtype & SVRR_RX)
  22096. -            stl_rxisr(panelp, iobase);
  22097. -        if (svrtype & SVRR_TX)
  22098. -            stl_txisr(panelp, iobase);
  22099. -        if (svrtype & SVRR_MDM)
  22100. -            stl_mdmisr(panelp, iobase);
  22101. + *    Interrupt service routine for ECH-8/64-PCI board types.
  22102. + */
  22103.  
  22104. -        if (brdp->brdtype == BRD_ECH)
  22105. -            outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
  22106. +static void stl_echpci64intr(stlbrd_t *brdp)
  22107. +{
  22108. +    stlpanel_t    *panelp;
  22109. +    unsigned int    ioaddr;
  22110. +    int        bnknr;
  22111. +
  22112. +    while (inb(brdp->ioctrl) & 0x1) {
  22113. +        for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
  22114. +            ioaddr = brdp->bnkstataddr[bnknr];
  22115. +            if (inb(ioaddr) & ECH_PNLINTRPEND) {
  22116. +                panelp = brdp->bnk2panel[bnknr];
  22117. +                (* panelp->isr)(panelp, (ioaddr & 0xfffc));
  22118. +            }
  22119. +        }
  22120.      }
  22121.  }
  22122.  
  22123. @@ -1890,6 +1844,7 @@
  22124.      unsigned int        oldsigs;
  22125.  
  22126.      portp = private;
  22127. +
  22128.  #if DEBUG
  22129.      printk("stl_offintr(portp=%x)\n", (int) portp);
  22130.  #endif
  22131. @@ -1901,7 +1856,8 @@
  22132.          return;
  22133.  
  22134.      if (test_bit(ASYI_TXLOW, &portp->istate)) {
  22135. -        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
  22136. +        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  22137. +            tty->ldisc.write_wakeup)
  22138.              (tty->ldisc.write_wakeup)(tty);
  22139.          wake_up_interruptible(&tty->write_wait);
  22140.      }
  22141. @@ -1914,7 +1870,7 @@
  22142.          if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) {
  22143.              if (portp->flags & ASYNC_CHECK_CD) {
  22144.                  if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) &&
  22145. -                        (portp->flags & ASYNC_CALLOUT_NOHUP))) {
  22146. +                    (portp->flags & ASYNC_CALLOUT_NOHUP))) {
  22147.                      tty_hangup(tty);
  22148.                  }
  22149.              }
  22150. @@ -1925,90 +1881,1233 @@
  22151.  /*****************************************************************************/
  22152.  
  22153.  /*
  22154. - *    Wait for the command register to be ready. We will poll this,
  22155. - *    since it won't usually take too long to be ready.
  22156. + *    Map in interrupt vector to this driver. Check that we don't
  22157. + *    already have this vector mapped, we might be sharing this
  22158. + *    interrupt across multiple boards.
  22159.   */
  22160.  
  22161. -static void stl_ccrwait(stlport_t *portp)
  22162. +static int stl_mapirq(int irq, char *name)
  22163.  {
  22164. -    int    i;
  22165. +    int    rc, i;
  22166.  
  22167. -    for (i = 0; (i < CCR_MAXWAIT); i++) {
  22168. -        if (stl_getreg(portp, CCR) == 0) {
  22169. -            return;
  22170. +#if DEBUG
  22171. +    printk("stl_mapirq(irq=%d,name=%s)\n", irq, name);
  22172. +#endif
  22173. +
  22174. +    rc = 0;
  22175. +    for (i = 0; (i < stl_numintrs); i++) {
  22176. +        if (stl_gotintrs[i] == irq)
  22177. +            break;
  22178. +    }
  22179. +    if (i >= stl_numintrs) {
  22180. +        if (request_irq(irq, stl_intr, SA_INTERRUPT, name, NULL) != 0) {
  22181. +            printk("STALLION: failed to register interrupt "
  22182. +                "routine for %s irq=%d\n", name, irq);
  22183. +            rc = -ENODEV;
  22184. +        } else {
  22185. +            stl_gotintrs[stl_numintrs++] = irq;
  22186.          }
  22187.      }
  22188. -
  22189. -    printk("STALLION: cd1400 device not responding, port=%d panel=%d brd=%d\n", portp->portnr, portp->panelnr, portp->brdnr);
  22190. +    return(rc);
  22191.  }
  22192.  
  22193.  /*****************************************************************************/
  22194.  
  22195.  /*
  22196. - *    Set up the cd1400 registers for a port based on the termios port
  22197. - *    settings.
  22198. + *    Initialize all the ports on a panel.
  22199.   */
  22200.  
  22201. -static void stl_setport(stlport_t *portp, struct termios *tiosp)
  22202. +static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
  22203.  {
  22204. -    stlbrd_t    *brdp;
  22205. -    unsigned long    flags;
  22206. -    unsigned int    clkdiv, baudrate;
  22207. -    unsigned char    cor1, cor2, cor3;
  22208. -    unsigned char    cor4, cor5, ccr;
  22209. -    unsigned char    srer, sreron, sreroff;
  22210. -    unsigned char    mcor1, mcor2, rtpr;
  22211. -    unsigned char    clk, div;
  22212. +    stlport_t    *portp;
  22213. +    int        chipmask, i;
  22214.  
  22215. -    cor1 = 0;
  22216. -    cor2 = 0;
  22217. -    cor3 = 0;
  22218. -    cor4 = 0;
  22219. -    cor5 = 0;
  22220. -    ccr = 0;
  22221. -    rtpr = 0;
  22222. -    clk = 0;
  22223. -    div = 0;
  22224. -    mcor1 = 0;
  22225. -    mcor2 = 0;
  22226. -    sreron = 0;
  22227. -    sreroff = 0;
  22228. +#if DEBUG
  22229. +    printk("stl_initports(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp);
  22230. +#endif
  22231.  
  22232. -    brdp = stl_brds[portp->brdnr];
  22233. -    if (brdp == (stlbrd_t *) NULL)
  22234. -        return;
  22235. +    chipmask = stl_panelinit(brdp, panelp);
  22236.  
  22237.  /*
  22238. - *    Set up the RX char ignore mask with those RX error types we
  22239. - *    can ignore. We can get the cd1400 to help us out a little here,
  22240. - *    it will ignore parity errors and breaks for us.
  22241. + *    All UART's are initialized (if found!). Now go through and setup
  22242. + *    each ports data structures.
  22243.   */
  22244. -    portp->rxignoremsk = 0;
  22245. -    if (tiosp->c_iflag & IGNPAR) {
  22246. -        portp->rxignoremsk |= (ST_PARITY | ST_FRAMING | ST_OVERRUN);
  22247. -        cor1 |= COR1_PARIGNORE;
  22248. -    }
  22249. -    if (tiosp->c_iflag & IGNBRK) {
  22250. -        portp->rxignoremsk |= ST_BREAK;
  22251. -        cor4 |= COR4_IGNBRK;
  22252. +    for (i = 0; (i < panelp->nrports); i++) {
  22253. +        portp = (stlport_t *) stl_memalloc(sizeof(stlport_t));
  22254. +        if (portp == (stlport_t *) NULL) {
  22255. +            printk("STALLION: failed to allocate memory "
  22256. +                "(size=%d)\n", sizeof(stlport_t));
  22257. +            break;
  22258. +        }
  22259. +        memset(portp, 0, sizeof(stlport_t));
  22260. +
  22261. +        portp->magic = STL_PORTMAGIC;
  22262. +        portp->portnr = i;
  22263. +        portp->brdnr = panelp->brdnr;
  22264. +        portp->panelnr = panelp->panelnr;
  22265. +        portp->uartp = panelp->uartp;
  22266. +        portp->clk = brdp->clk;
  22267. +        portp->baud_base = STL_BAUDBASE;
  22268. +        portp->close_delay = STL_CLOSEDELAY;
  22269. +        portp->closing_wait = 30 * HZ;
  22270. +        portp->normaltermios = stl_deftermios;
  22271. +        portp->callouttermios = stl_deftermios;
  22272. +        portp->tqueue.routine = stl_offintr;
  22273. +        portp->tqueue.data = portp;
  22274. +        portp->stats.brd = portp->brdnr;
  22275. +        portp->stats.panel = portp->panelnr;
  22276. +        portp->stats.port = portp->portnr;
  22277. +        panelp->ports[i] = portp;
  22278. +        stl_portinit(brdp, panelp, portp);
  22279.      }
  22280.  
  22281. -    portp->rxmarkmsk = ST_OVERRUN;
  22282. -    if (tiosp->c_iflag & (INPCK | PARMRK))
  22283. -        portp->rxmarkmsk |= (ST_PARITY | ST_FRAMING);
  22284. -    if (tiosp->c_iflag & BRKINT)
  22285. -        portp->rxmarkmsk |= ST_BREAK;
  22286. +    return(0);
  22287. +}
  22288. +
  22289. +/*****************************************************************************/
  22290.  
  22291.  /*
  22292. - *    Go through the char size, parity and stop bits and set all the
  22293. - *    option register appropriately.
  22294. + *    Try to find and initialize an EasyIO board.
  22295.   */
  22296. -    switch (tiosp->c_cflag & CSIZE) {
  22297. -    case CS5:
  22298. -        cor1 |= COR1_CHL5;
  22299. -        break;
  22300. -    case CS6:
  22301. -        cor1 |= COR1_CHL6;
  22302. +
  22303. +static inline int stl_initeio(stlbrd_t *brdp)
  22304. +{
  22305. +    stlpanel_t    *panelp;
  22306. +    unsigned int    status;
  22307. +    char        *name;
  22308. +    int        rc;
  22309. +
  22310. +#if DEBUG
  22311. +    printk("stl_initeio(brdp=%x)\n", (int) brdp);
  22312. +#endif
  22313. +
  22314. +    brdp->ioctrl = brdp->ioaddr1 + 1;
  22315. +    brdp->iostatus = brdp->ioaddr1 + 2;
  22316. +
  22317. +    status = inb(brdp->iostatus);
  22318. +    if ((status & EIO_IDBITMASK) == EIO_MK3)
  22319. +        brdp->ioctrl++;
  22320. +
  22321. +/*
  22322. + *    Handle board specific stuff now. The real difference is PCI
  22323. + *    or not PCI.
  22324. + */
  22325. +    if (brdp->brdtype == BRD_EASYIOPCI) {
  22326. +        brdp->iosize1 = 0x80;
  22327. +        brdp->iosize2 = 0x80;
  22328. +        name = "serial(EIO-PCI)";
  22329. +        outb(0x41, (brdp->ioaddr2 + 0x4c));
  22330. +    } else {
  22331. +        brdp->iosize1 = 8;
  22332. +        name = "serial(EIO)";
  22333. +        if ((brdp->irq < 0) || (brdp->irq > 15) ||
  22334. +            (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
  22335. +            printk("STALLION: invalid irq=%d for brd=%d\n",
  22336. +                brdp->irq, brdp->brdnr);
  22337. +            return(-EINVAL);
  22338. +        }
  22339. +        outb((stl_vecmap[brdp->irq] | EIO_0WS |
  22340. +            ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)),
  22341. +            brdp->ioctrl);
  22342. +    }
  22343. +
  22344. +    if (check_region(brdp->ioaddr1, brdp->iosize1)) {
  22345. +        printk("STALLION: Warning, unit %d I/O address %x conflicts "
  22346. +            "with another device\n", brdp->brdnr, brdp->ioaddr1);
  22347. +    }
  22348. +    if (brdp->iosize2 > 0) {
  22349. +        if (check_region(brdp->ioaddr2, brdp->iosize2)) {
  22350. +            printk("STALLION: Warning, unit %d I/O address %x "
  22351. +                "conflicts with another device\n",
  22352. +                brdp->brdnr, brdp->ioaddr2);
  22353. +        }
  22354. +    }
  22355. +/*
  22356. + *    Everything looks OK, so lets go ahead and probe for the hardware.
  22357. + */
  22358. +    brdp->clk = CD1400_CLK;
  22359. +    brdp->isr = stl_eiointr;
  22360. +
  22361. +    switch (status & EIO_IDBITMASK) {
  22362. +    case EIO_8PORTM:
  22363. +        brdp->clk = CD1400_CLK8M;
  22364. +        /* fall thru */
  22365. +    case EIO_8PORTRS:
  22366. +    case EIO_8PORTDI:
  22367. +        brdp->nrports = 8;
  22368. +        break;
  22369. +    case EIO_4PORTRS:
  22370. +        brdp->nrports = 4;
  22371. +        break;
  22372. +    case EIO_MK3:
  22373. +        switch (status & EIO_BRDMASK) {
  22374. +        case ID_BRD4:
  22375. +            brdp->nrports = 4;
  22376. +            break;
  22377. +        case ID_BRD8:
  22378. +            brdp->nrports = 8;
  22379. +            break;
  22380. +        case ID_BRD16:
  22381. +            brdp->nrports = 16;
  22382. +            break;
  22383. +        default:
  22384. +            return(-ENODEV);
  22385. +        }
  22386. +        break;
  22387. +    default:
  22388. +        return(-ENODEV);
  22389. +    }
  22390. +
  22391. +/*
  22392. + *    We have verfied that the board is actually present, so now we
  22393. + *    can complete the setup.
  22394. + */
  22395. +    request_region(brdp->ioaddr1, brdp->iosize1, name);
  22396. +    if (brdp->iosize2 > 0)
  22397. +        request_region(brdp->ioaddr2, brdp->iosize2, name);
  22398. +
  22399. +    panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t));
  22400. +    if (panelp == (stlpanel_t *) NULL) {
  22401. +        printk("STALLION: failed to allocate memory (size=%d)\n",
  22402. +            sizeof(stlpanel_t));
  22403. +        return(-ENOMEM);
  22404. +    }
  22405. +    memset(panelp, 0, sizeof(stlpanel_t));
  22406. +
  22407. +    panelp->magic = STL_PANELMAGIC;
  22408. +    panelp->brdnr = brdp->brdnr;
  22409. +    panelp->panelnr = 0;
  22410. +    panelp->nrports = brdp->nrports;
  22411. +    panelp->iobase = brdp->ioaddr1;
  22412. +    panelp->hwid = status;
  22413. +    if ((status & EIO_IDBITMASK) == EIO_MK3) {
  22414. +        panelp->uartp = (void *) &stl_sc26198uart;
  22415. +        panelp->isr = stl_sc26198intr;
  22416. +    } else {
  22417. +        panelp->uartp = (void *) &stl_cd1400uart;
  22418. +        panelp->isr = stl_cd1400eiointr;
  22419. +    }
  22420. +
  22421. +    brdp->panels[0] = panelp;
  22422. +    brdp->nrpanels = 1;
  22423. +    brdp->state |= BRD_FOUND;
  22424. +    brdp->hwid = status;
  22425. +    rc = stl_mapirq(brdp->irq, name);
  22426. +    return(rc);
  22427. +}
  22428. +
  22429. +/*****************************************************************************/
  22430. +
  22431. +/*
  22432. + *    Try to find an ECH board and initialize it. This code is capable of
  22433. + *    dealing with all types of ECH board.
  22434. + */
  22435. +
  22436. +static inline int stl_initech(stlbrd_t *brdp)
  22437. +{
  22438. +    stlpanel_t    *panelp;
  22439. +    unsigned int    status, nxtid, ioaddr, conflict;
  22440. +    int        panelnr, banknr, i;
  22441. +    char        *name;
  22442. +
  22443. +#if DEBUG
  22444. +    printk("stl_initech(brdp=%x)\n", (int) brdp);
  22445. +#endif
  22446. +
  22447. +    status = 0;
  22448. +    conflict = 0;
  22449. +
  22450. +/*
  22451. + *    Set up the initial board register contents for boards. This varies a
  22452. + *    bit between the different board types. So we need to handle each
  22453. + *    separately. Also do a check that the supplied IRQ is good.
  22454. + */
  22455. +    switch (brdp->brdtype) {
  22456. +
  22457. +    case BRD_ECH:
  22458. +        brdp->isr = stl_echatintr;
  22459. +        brdp->ioctrl = brdp->ioaddr1 + 1;
  22460. +        brdp->iostatus = brdp->ioaddr1 + 1;
  22461. +        status = inb(brdp->iostatus);
  22462. +        if ((status & ECH_IDBITMASK) != ECH_ID)
  22463. +            return(-ENODEV);
  22464. +        if ((brdp->irq < 0) || (brdp->irq > 15) ||
  22465. +            (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
  22466. +            printk("STALLION: invalid irq=%d for brd=%d\n",
  22467. +                brdp->irq, brdp->brdnr);
  22468. +            return(-EINVAL);
  22469. +        }
  22470. +        status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1);
  22471. +        status |= (stl_vecmap[brdp->irq] << 1);
  22472. +        outb((status | ECH_BRDRESET), brdp->ioaddr1);
  22473. +        brdp->ioctrlval = ECH_INTENABLE |
  22474. +            ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE);
  22475. +        for (i = 0; (i < 10); i++)
  22476. +            outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
  22477. +        brdp->iosize1 = 2;
  22478. +        brdp->iosize2 = 32;
  22479. +        name = "serial(EC8/32)";
  22480. +        outb(status, brdp->ioaddr1);
  22481. +        break;
  22482. +
  22483. +    case BRD_ECHMC:
  22484. +        brdp->isr = stl_echmcaintr;
  22485. +        brdp->ioctrl = brdp->ioaddr1 + 0x20;
  22486. +        brdp->iostatus = brdp->ioctrl;
  22487. +        status = inb(brdp->iostatus);
  22488. +        if ((status & ECH_IDBITMASK) != ECH_ID)
  22489. +            return(-ENODEV);
  22490. +        if ((brdp->irq < 0) || (brdp->irq > 15) ||
  22491. +            (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
  22492. +            printk("STALLION: invalid irq=%d for brd=%d\n",
  22493. +                brdp->irq, brdp->brdnr);
  22494. +            return(-EINVAL);
  22495. +        }
  22496. +        outb(ECHMC_BRDRESET, brdp->ioctrl);
  22497. +        outb(ECHMC_INTENABLE, brdp->ioctrl);
  22498. +        brdp->iosize1 = 64;
  22499. +        name = "serial(EC8/32-MC)";
  22500. +        break;
  22501. +
  22502. +    case BRD_ECHPCI:
  22503. +        brdp->isr = stl_echpciintr;
  22504. +        brdp->ioctrl = brdp->ioaddr1 + 2;
  22505. +        brdp->iosize1 = 4;
  22506. +        brdp->iosize2 = 8;
  22507. +        name = "serial(EC8/32-PCI)";
  22508. +        break;
  22509. +
  22510. +    case BRD_ECH64PCI:
  22511. +        brdp->isr = stl_echpci64intr;
  22512. +        brdp->ioctrl = brdp->ioaddr2 + 0x40;
  22513. +        outb(0x43, (brdp->ioaddr1 + 0x4c));
  22514. +        brdp->iosize1 = 0x80;
  22515. +        brdp->iosize2 = 0x80;
  22516. +        name = "serial(EC8/64-PCI)";
  22517. +        break;
  22518. +
  22519. +    default:
  22520. +        printk("STALLION: unknown board type=%d\n", brdp->brdtype);
  22521. +        return(-EINVAL);
  22522. +        break;
  22523. +    }
  22524. +
  22525. +/*
  22526. + *    Check boards for possible IO address conflicts. We won't actually
  22527. + *    do anything about it here, just issue a warning...
  22528. + */
  22529. +    conflict = check_region(brdp->ioaddr1, brdp->iosize1) ?
  22530. +        brdp->ioaddr1 : 0;
  22531. +    if ((conflict == 0) && (brdp->iosize2 > 0))
  22532. +        conflict = check_region(brdp->ioaddr2, brdp->iosize2) ?
  22533. +            brdp->ioaddr2 : 0;
  22534. +    if (conflict) {
  22535. +        printk("STALLION: Warning, unit %d I/O address %x conflicts "
  22536. +            "with another device\n", brdp->brdnr, conflict);
  22537. +    }
  22538. +
  22539. +    request_region(brdp->ioaddr1, brdp->iosize1, name);
  22540. +    if (brdp->iosize2 > 0)
  22541. +        request_region(brdp->ioaddr2, brdp->iosize2, name);
  22542. +
  22543. +/*
  22544. + *    Scan through the secondary io address space looking for panels.
  22545. + *    As we find'em allocate and initialize panel structures for each.
  22546. + */
  22547. +    brdp->clk = CD1400_CLK;
  22548. +    brdp->hwid = status;
  22549. +
  22550. +    ioaddr = brdp->ioaddr2;
  22551. +    banknr = 0;
  22552. +    panelnr = 0;
  22553. +    nxtid = 0;
  22554. +
  22555. +    for (i = 0; (i < STL_MAXPANELS); i++) {
  22556. +        if (brdp->brdtype == BRD_ECHPCI) {
  22557. +            outb(nxtid, brdp->ioctrl);
  22558. +            ioaddr = brdp->ioaddr2;
  22559. +        }
  22560. +        status = inb(ioaddr + ECH_PNLSTATUS);
  22561. +        if ((status & ECH_PNLIDMASK) != nxtid)
  22562. +            break;
  22563. +        panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t));
  22564. +        if (panelp == (stlpanel_t *) NULL) {
  22565. +            printk("STALLION: failed to allocate memory "
  22566. +                "(size=%d)\n", sizeof(stlpanel_t));
  22567. +            break;
  22568. +        }
  22569. +        memset(panelp, 0, sizeof(stlpanel_t));
  22570. +        panelp->magic = STL_PANELMAGIC;
  22571. +        panelp->brdnr = brdp->brdnr;
  22572. +        panelp->panelnr = panelnr;
  22573. +        panelp->iobase = ioaddr;
  22574. +        panelp->pagenr = nxtid;
  22575. +        panelp->hwid = status;
  22576. +        brdp->bnk2panel[banknr] = panelp;
  22577. +        brdp->bnkpageaddr[banknr] = nxtid;
  22578. +        brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS;
  22579. +
  22580. +        if (status & ECH_PNLXPID) {
  22581. +            panelp->uartp = (void *) &stl_sc26198uart;
  22582. +            panelp->isr = stl_sc26198intr;
  22583. +            if (status & ECH_PNL16PORT) {
  22584. +                panelp->nrports = 16;
  22585. +                brdp->bnk2panel[banknr] = panelp;
  22586. +                brdp->bnkpageaddr[banknr] = nxtid;
  22587. +                brdp->bnkstataddr[banknr++] = ioaddr + 4 +
  22588. +                    ECH_PNLSTATUS;
  22589. +            } else {
  22590. +                panelp->nrports = 8;
  22591. +            }
  22592. +        } else {
  22593. +            panelp->uartp = (void *) &stl_cd1400uart;
  22594. +            panelp->isr = stl_cd1400echintr;
  22595. +            if (status & ECH_PNL16PORT) {
  22596. +                panelp->nrports = 16;
  22597. +                panelp->ackmask = 0x80;
  22598. +                if (brdp->brdtype != BRD_ECHPCI)
  22599. +                    ioaddr += EREG_BANKSIZE;
  22600. +                brdp->bnk2panel[banknr] = panelp;
  22601. +                brdp->bnkpageaddr[banknr] = ++nxtid;
  22602. +                brdp->bnkstataddr[banknr++] = ioaddr +
  22603. +                    ECH_PNLSTATUS;
  22604. +            } else {
  22605. +                panelp->nrports = 8;
  22606. +                panelp->ackmask = 0xc0;
  22607. +            }
  22608. +        }
  22609. +
  22610. +        nxtid++;
  22611. +        ioaddr += EREG_BANKSIZE;
  22612. +        brdp->nrports += panelp->nrports;
  22613. +        brdp->panels[panelnr++] = panelp;
  22614. +        if ((brdp->brdtype != BRD_ECHPCI) &&
  22615. +            (ioaddr >= (brdp->ioaddr2 + brdp->iosize2)))
  22616. +            break;
  22617. +    }
  22618. +
  22619. +    brdp->nrpanels = panelnr;
  22620. +    brdp->nrbnks = banknr;
  22621. +    if (brdp->brdtype == BRD_ECH)
  22622. +        outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
  22623. +
  22624. +    brdp->state |= BRD_FOUND;
  22625. +    i = stl_mapirq(brdp->irq, name);
  22626. +    return(i);
  22627. +}
  22628. +
  22629. +/*****************************************************************************/
  22630. +
  22631. +/*
  22632. + *    Initialize and configure the specified board.
  22633. + *    Scan through all the boards in the configuration and see what we
  22634. + *    can find. Handle EIO and the ECH boards a little differently here
  22635. + *    since the initial search and setup is very different.
  22636. + */
  22637. +
  22638. +static int stl_brdinit(stlbrd_t *brdp)
  22639. +{
  22640. +    int    i;
  22641. +
  22642. +#if DEBUG
  22643. +    printk("stl_brdinit(brdp=%x)\n", (int) brdp);
  22644. +#endif
  22645. +
  22646. +    switch (brdp->brdtype) {
  22647. +    case BRD_EASYIO:
  22648. +    case BRD_EASYIOPCI:
  22649. +        stl_initeio(brdp);
  22650. +        break;
  22651. +    case BRD_ECH:
  22652. +    case BRD_ECHMC:
  22653. +    case BRD_ECHPCI:
  22654. +    case BRD_ECH64PCI:
  22655. +        stl_initech(brdp);
  22656. +        break;
  22657. +    default:
  22658. +        printk("STALLION: unit=%d is unknown board type=%d\n",
  22659. +            brdp->brdnr, brdp->brdtype);
  22660. +        return(ENODEV);
  22661. +    }
  22662. +
  22663. +    stl_brds[brdp->brdnr] = brdp;
  22664. +    if ((brdp->state & BRD_FOUND) == 0) {
  22665. +        printk("STALLION: %s board not found, unit=%d io=%x irq=%d\n",
  22666. +            stl_brdnames[brdp->brdtype], brdp->brdnr,
  22667. +            brdp->ioaddr1, brdp->irq);
  22668. +        return(ENODEV);
  22669. +    }
  22670. +
  22671. +    for (i = 0; (i < STL_MAXPANELS); i++)
  22672. +        if (brdp->panels[i] != (stlpanel_t *) NULL)
  22673. +            stl_initports(brdp, brdp->panels[i]);
  22674. +
  22675. +    printk("STALLION: %s found, unit=%d io=%x irq=%d "
  22676. +        "nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype],
  22677. +        brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels,
  22678. +        brdp->nrports);
  22679. +    return(0);
  22680. +}
  22681. +
  22682. +/*****************************************************************************/
  22683. +
  22684. +#ifdef    CONFIG_PCI
  22685. +
  22686. +/*
  22687. + *    We have a Stallion board. Allocate a board structure and
  22688. + *    initialize it. Read its IO and IRQ resources from PCI
  22689. + *    configuration space.
  22690. + */
  22691. +
  22692. +static inline int stl_initpcibrd(int brdtype, unsigned char busnr, unsigned char devnr)
  22693. +{
  22694. +    unsigned int    bar[4];
  22695. +    stlbrd_t    *brdp;
  22696. +    int        i, rc;
  22697. +    unsigned char    irq;
  22698. +
  22699. +#if DEBUG
  22700. +    printk("stl_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n",
  22701. +        brdtype, busnr, devnr);
  22702. +#endif
  22703. +
  22704. +    brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t));
  22705. +    if (brdp == (stlbrd_t *) NULL) {
  22706. +        printk("STALLION: failed to allocate memory (size=%d)\n",
  22707. +            sizeof(stlbrd_t));
  22708. +        return(-ENOMEM);
  22709. +    }
  22710. +
  22711. +    memset(brdp, 0, sizeof(stlbrd_t));
  22712. +    brdp->magic = STL_BOARDMAGIC;
  22713. +    brdp->brdnr = stl_nrbrds++;
  22714. +    brdp->brdtype = brdtype;
  22715. +
  22716. +/*
  22717. + *    Read in all the BAR registers from this board. Different Stallion
  22718. + *    boards use these in different ways, so we just read in the whole
  22719. + *    lot and then figure out what is what later.
  22720. + */
  22721. +    for (i = 0; (i < 4); i++) {
  22722. +        rc = pcibios_read_config_dword(busnr, devnr,
  22723. +            (PCI_BASE_ADDRESS_0 + (i * 0x4)), &bar[i]);
  22724. +        if (rc) {
  22725. +            printk("STALLION: failed to read BAR register %d "
  22726. +                "from PCI board, errno=%x\n", i, rc);
  22727. +            return(0);
  22728. +        }
  22729. +    }
  22730. +
  22731. +    rc = pcibios_read_config_byte(busnr, devnr, PCI_INTERRUPT_LINE, &irq);
  22732. +    if (rc) {
  22733. +        printk("STALLION: failed to read INTERRUPT register "
  22734. +            "from PCI board, errno=%x\n", rc);
  22735. +        return(0);
  22736. +    }
  22737. +
  22738. +#if DEBUG
  22739. +    printk("%s(%d): BAR[]=%x,%x,%x,%x IRQ=%x\n", __FILE__, __LINE__,
  22740. +        bar[0], bar[1], bar[2], bar[3], irq);
  22741. +#endif
  22742. +
  22743. +/*
  22744. + *    We have all resources from the board, so lets setup the actual
  22745. + *    board structure now.
  22746. + */
  22747. +    switch (brdtype) {
  22748. +    case BRD_ECHPCI:
  22749. +        brdp->ioaddr2 = (bar[0] & PCI_BASE_ADDRESS_IO_MASK);
  22750. +        brdp->ioaddr1 = (bar[1] & PCI_BASE_ADDRESS_IO_MASK);
  22751. +        break;
  22752. +    case BRD_ECH64PCI:
  22753. +        brdp->ioaddr2 = (bar[2] & PCI_BASE_ADDRESS_IO_MASK);
  22754. +        brdp->ioaddr1 = (bar[1] & PCI_BASE_ADDRESS_IO_MASK);
  22755. +        break;
  22756. +    case BRD_EASYIOPCI:
  22757. +        brdp->ioaddr1 = (bar[2] & PCI_BASE_ADDRESS_IO_MASK);
  22758. +        brdp->ioaddr2 = (bar[1] & PCI_BASE_ADDRESS_IO_MASK);
  22759. +        break;
  22760. +    default:
  22761. +        printk("STALLION: unknown PCI board type=%d\n", brdtype);
  22762. +        break;
  22763. +    }
  22764. +
  22765. +    brdp->irq = irq;
  22766. +    stl_brdinit(brdp);
  22767. +
  22768. +    return(0);
  22769. +}
  22770. +
  22771. +
  22772. +/*****************************************************************************/
  22773. +
  22774. +/*
  22775. + *    Find all Stallion PCI boards that might be installed. Initialize each
  22776. + *    one as it is found.
  22777. + */
  22778. +
  22779. +
  22780. +static inline int stl_findpcibrds()
  22781. +{
  22782. +    unsigned char    busnr, devnr;
  22783. +    unsigned short    class;
  22784. +    int        i, rc, brdtypnr;
  22785. +
  22786. +#if DEBUG
  22787. +    printk("stl_findpcibrds()\n");
  22788. +#endif
  22789. +
  22790. +    if (! pcibios_present())
  22791. +        return(0);
  22792. +
  22793. +    for (i = 0; (i < stl_nrpcibrds); i++) {
  22794. +        for (brdtypnr = 0; ; brdtypnr++) {
  22795. +
  22796. +            rc = pcibios_find_device(stl_pcibrds[i].vendid,
  22797. +                stl_pcibrds[i].devid, brdtypnr, &busnr, &devnr);
  22798. +            if (rc)
  22799. +                break;
  22800. +
  22801. +/*
  22802. + *            Check that we can handle more boards...
  22803. + */
  22804. +            if (stl_nrbrds >= STL_MAXBRDS) {
  22805. +                printk("STALLION: too many boards found, "
  22806. +                    "maximum supported %d\n", STL_MAXBRDS);
  22807. +                i = stl_nrpcibrds;
  22808. +                break;
  22809. +            }
  22810. +
  22811. +/*
  22812. + *            Found a device on the PCI bus that has our vendor and
  22813. + *            device ID. Need to check now that it is really us.
  22814. + */
  22815. +            rc = pcibios_read_config_word(busnr, devnr,
  22816. +                PCI_CLASS_DEVICE, &class);
  22817. +            if (rc) {
  22818. +                printk("STALLION: failed to read class type "
  22819. +                    "from PCI board, errno=%x\n", rc);
  22820. +                continue;
  22821. +            }
  22822. +            if (class == PCI_CLASS_STORAGE_IDE)
  22823. +                continue;
  22824. +
  22825. +            rc = stl_initpcibrd(stl_pcibrds[i].brdtype, busnr,
  22826. +                devnr);
  22827. +            if (rc)
  22828. +                return(rc);
  22829. +        }
  22830. +    }
  22831. +
  22832. +    return(0);
  22833. +}
  22834. +
  22835. +#endif
  22836. +
  22837. +/*****************************************************************************/
  22838. +
  22839. +/*
  22840. + *    Scan through all the boards in the configuration and see what we
  22841. + *    can find. Handle EIO and the ECH boards a little differently here
  22842. + *    since the initial search and setup is too different.
  22843. + */
  22844. +
  22845. +static inline int stl_initbrds()
  22846. +{
  22847. +    stlbrd_t    *brdp;
  22848. +    stlconf_t    *confp;
  22849. +    int        i;
  22850. +
  22851. +#if DEBUG
  22852. +    printk("stl_initbrds()\n");
  22853. +#endif
  22854. +
  22855. +    if (stl_nrbrds > STL_MAXBRDS) {
  22856. +        printk("STALLION: too many boards in configuration table, "
  22857. +            "truncating to %d\n", STL_MAXBRDS);
  22858. +        stl_nrbrds = STL_MAXBRDS;
  22859. +    }
  22860. +
  22861. +/*
  22862. + *    Firstly scan the list of static boards configured. Allocate
  22863. + *    resources and initialize the boards as found.
  22864. + */
  22865. +    for (i = 0; (i < stl_nrbrds); i++) {
  22866. +        confp = &stl_brdconf[i];
  22867. +        brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t));
  22868. +        if (brdp == (stlbrd_t *) NULL) {
  22869. +            printk("STALLION: failed to allocate memory "
  22870. +                "(size=%d)\n", sizeof(stlbrd_t));
  22871. +            return(-ENOMEM);
  22872. +        }
  22873. +        memset(brdp, 0, sizeof(stlbrd_t));
  22874. +
  22875. +        brdp->magic = STL_BOARDMAGIC;
  22876. +        brdp->brdnr = i;
  22877. +        brdp->brdtype = confp->brdtype;
  22878. +        brdp->ioaddr1 = confp->ioaddr1;
  22879. +        brdp->ioaddr2 = confp->ioaddr2;
  22880. +        brdp->irq = confp->irq;
  22881. +        brdp->irqtype = confp->irqtype;
  22882. +        stl_brdinit(brdp);
  22883. +    }
  22884. +
  22885. +#ifdef CONFIG_PCI
  22886. +/*
  22887. + *    If the PCI BIOS support is compiled in then let's go looking for
  22888. + *    ECH-PCI boards.
  22889. + */
  22890. +    stl_findpcibrds();
  22891. +#endif
  22892. +
  22893. +    return(0);
  22894. +}
  22895. +
  22896. +/*****************************************************************************/
  22897. +
  22898. +/*
  22899. + *    Return the board stats structure to user app.
  22900. + */
  22901. +
  22902. +static int stl_getbrdstats(combrd_t *bp)
  22903. +{
  22904. +    stlbrd_t    *brdp;
  22905. +    stlpanel_t    *panelp;
  22906. +    int        i;
  22907. +
  22908. +    memcpy_fromfs(&stl_brdstats, bp, sizeof(combrd_t));
  22909. +    if (stl_brdstats.brd >= STL_MAXBRDS)
  22910. +        return(-ENODEV);
  22911. +    brdp = stl_brds[stl_brdstats.brd];
  22912. +    if (brdp == (stlbrd_t *) NULL)
  22913. +        return(-ENODEV);
  22914. +
  22915. +    memset(&stl_brdstats, 0, sizeof(combrd_t));
  22916. +    stl_brdstats.brd = brdp->brdnr;
  22917. +    stl_brdstats.type = brdp->brdtype;
  22918. +    stl_brdstats.hwid = brdp->hwid;
  22919. +    stl_brdstats.state = brdp->state;
  22920. +    stl_brdstats.ioaddr = brdp->ioaddr1;
  22921. +    stl_brdstats.ioaddr2 = brdp->ioaddr2;
  22922. +    stl_brdstats.irq = brdp->irq;
  22923. +    stl_brdstats.nrpanels = brdp->nrpanels;
  22924. +    stl_brdstats.nrports = brdp->nrports;
  22925. +    for (i = 0; (i < brdp->nrpanels); i++) {
  22926. +        panelp = brdp->panels[i];
  22927. +        stl_brdstats.panels[i].panel = i;
  22928. +        stl_brdstats.panels[i].hwid = panelp->hwid;
  22929. +        stl_brdstats.panels[i].nrports = panelp->nrports;
  22930. +    }
  22931. +
  22932. +    memcpy_tofs(bp, &stl_brdstats, sizeof(combrd_t));
  22933. +    return(0);
  22934. +}
  22935. +
  22936. +/*****************************************************************************/
  22937. +
  22938. +/*
  22939. + *    Resolve the referenced port number into a port struct pointer.
  22940. + */
  22941. +
  22942. +static stlport_t *stl_getport(int brdnr, int panelnr, int portnr)
  22943. +{
  22944. +    stlbrd_t    *brdp;
  22945. +    stlpanel_t    *panelp;
  22946. +
  22947. +    if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
  22948. +        return((stlport_t *) NULL);
  22949. +    brdp = stl_brds[brdnr];
  22950. +    if (brdp == (stlbrd_t *) NULL)
  22951. +        return((stlport_t *) NULL);
  22952. +    if ((panelnr < 0) || (panelnr >= brdp->nrpanels))
  22953. +        return((stlport_t *) NULL);
  22954. +    panelp = brdp->panels[panelnr];
  22955. +    if (panelp == (stlpanel_t *) NULL)
  22956. +        return((stlport_t *) NULL);
  22957. +    if ((portnr < 0) || (portnr >= panelp->nrports))
  22958. +        return((stlport_t *) NULL);
  22959. +    return(panelp->ports[portnr]);
  22960. +}
  22961. +
  22962. +/*****************************************************************************/
  22963. +
  22964. +/*
  22965. + *    Return the port stats structure to user app. A NULL port struct
  22966. + *    pointer passed in means that we need to find out from the app
  22967. + *    what port to get stats for (used through board control device).
  22968. + */
  22969. +
  22970. +static int stl_getportstats(stlport_t *portp, comstats_t *cp)
  22971. +{
  22972. +    unsigned char    *head, *tail;
  22973. +    unsigned long    flags;
  22974. +
  22975. +    if (portp == (stlport_t *) NULL) {
  22976. +        memcpy_fromfs(&stl_comstats, cp, sizeof(comstats_t));
  22977. +        portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
  22978. +            stl_comstats.port);
  22979. +        if (portp == (stlport_t *) NULL)
  22980. +            return(-ENODEV);
  22981. +    }
  22982. +
  22983. +    portp->stats.state = portp->istate;
  22984. +    portp->stats.flags = portp->flags;
  22985. +    portp->stats.hwid = portp->hwid;
  22986. +
  22987. +    portp->stats.ttystate = 0;
  22988. +    portp->stats.cflags = 0;
  22989. +    portp->stats.iflags = 0;
  22990. +    portp->stats.oflags = 0;
  22991. +    portp->stats.lflags = 0;
  22992. +    portp->stats.rxbuffered = 0;
  22993. +
  22994. +    save_flags(flags);
  22995. +    cli();
  22996. +    if (portp->tty != (struct tty_struct *) NULL) {
  22997. +        if (portp->tty->driver_data == portp) {
  22998. +            portp->stats.ttystate = portp->tty->flags;
  22999. +            portp->stats.rxbuffered = portp->tty->flip.count;
  23000. +            if (portp->tty->termios != (struct termios *) NULL) {
  23001. +                portp->stats.cflags = portp->tty->termios->c_cflag;
  23002. +                portp->stats.iflags = portp->tty->termios->c_iflag;
  23003. +                portp->stats.oflags = portp->tty->termios->c_oflag;
  23004. +                portp->stats.lflags = portp->tty->termios->c_lflag;
  23005. +            }
  23006. +        }
  23007. +    }
  23008. +    restore_flags(flags);
  23009. +
  23010. +    head = portp->tx.head;
  23011. +    tail = portp->tx.tail;
  23012. +    portp->stats.txbuffered = ((head >= tail) ? (head - tail) :
  23013. +        (STL_TXBUFSIZE - (tail - head)));
  23014. +
  23015. +    portp->stats.signals = (unsigned long) stl_getsignals(portp);
  23016. +
  23017. +    memcpy_tofs(cp, &portp->stats, sizeof(comstats_t));
  23018. +    return(0);
  23019. +}
  23020. +
  23021. +/*****************************************************************************/
  23022. +
  23023. +/*
  23024. + *    Clear the port stats structure. We also return it zeroed out...
  23025. + */
  23026. +
  23027. +static int stl_clrportstats(stlport_t *portp, comstats_t *cp)
  23028. +{
  23029. +    if (portp == (stlport_t *) NULL) {
  23030. +        memcpy_fromfs(&stl_comstats, cp, sizeof(comstats_t));
  23031. +        portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
  23032. +            stl_comstats.port);
  23033. +        if (portp == (stlport_t *) NULL)
  23034. +            return(-ENODEV);
  23035. +    }
  23036. +
  23037. +    memset(&portp->stats, 0, sizeof(comstats_t));
  23038. +    portp->stats.brd = portp->brdnr;
  23039. +    portp->stats.panel = portp->panelnr;
  23040. +    portp->stats.port = portp->portnr;
  23041. +    memcpy_tofs(cp, &portp->stats, sizeof(comstats_t));
  23042. +    return(0);
  23043. +}
  23044. +
  23045. +/*****************************************************************************/
  23046. +
  23047. +/*
  23048. + *    Return the entire driver ports structure to a user app.
  23049. + */
  23050. +
  23051. +static int stl_getportstruct(unsigned long arg)
  23052. +{
  23053. +    stlport_t    *portp;
  23054. +
  23055. +    memcpy_fromfs(&stl_dummyport, (void *) arg, sizeof(stlport_t));
  23056. +    portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr,
  23057. +         stl_dummyport.portnr);
  23058. +    if (portp == (stlport_t *) NULL)
  23059. +        return(-ENODEV);
  23060. +    memcpy_tofs((void *) arg, portp, sizeof(stlport_t));
  23061. +    return(0);
  23062. +}
  23063. +
  23064. +/*****************************************************************************/
  23065. +
  23066. +/*
  23067. + *    Return the entire driver board structure to a user app.
  23068. + */
  23069. +
  23070. +static int stl_getbrdstruct(unsigned long arg)
  23071. +{
  23072. +    stlbrd_t    *brdp;
  23073. +
  23074. +    memcpy_fromfs(&stl_dummybrd, (void *) arg, sizeof(stlbrd_t));
  23075. +    if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS))
  23076. +        return(-ENODEV);
  23077. +    brdp = stl_brds[stl_dummybrd.brdnr];
  23078. +    if (brdp == (stlbrd_t *) NULL)
  23079. +        return(-ENODEV);
  23080. +    memcpy_tofs((void *) arg, brdp, sizeof(stlbrd_t));
  23081. +    return(0);
  23082. +}
  23083. +
  23084. +/*****************************************************************************/
  23085. +
  23086. +/*
  23087. + *    Memory device open code. Need to keep track of opens and close
  23088. + *    for module handling.
  23089. + */
  23090. +
  23091. +static int stl_memopen(struct inode *ip, struct file *fp)
  23092. +{
  23093. +    MOD_INC_USE_COUNT;
  23094. +    return(0);
  23095. +}
  23096. +
  23097. +/*****************************************************************************/
  23098. +
  23099. +static void stl_memclose(struct inode *ip, struct file *fp)
  23100. +{
  23101. +    MOD_DEC_USE_COUNT;
  23102. +}
  23103. +
  23104. +/*****************************************************************************/
  23105. +
  23106. +/*
  23107. + *    The "staliomem" device is also required to do some special operations
  23108. + *    on the board and/or ports. In this driver it is mostly used for stats
  23109. + *    collection.
  23110. + */
  23111. +
  23112. +static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
  23113. +{
  23114. +    int    brdnr, rc;
  23115. +
  23116. +#if DEBUG
  23117. +    printk("stl_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip,
  23118. +        (int) fp, cmd, (int) arg);
  23119. +#endif
  23120. +
  23121. +    brdnr = MINOR(ip->i_rdev);
  23122. +    if (brdnr >= STL_MAXBRDS)
  23123. +        return(-ENODEV);
  23124. +    rc = 0;
  23125. +
  23126. +    switch (cmd) {
  23127. +    case COM_GETPORTSTATS:
  23128. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  23129. +            sizeof(comstats_t))) == 0)
  23130. +            rc = stl_getportstats((stlport_t *) NULL,
  23131. +                (comstats_t *) arg);
  23132. +        break;
  23133. +    case COM_CLRPORTSTATS:
  23134. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  23135. +            sizeof(comstats_t))) == 0)
  23136. +            rc = stl_clrportstats((stlport_t *) NULL,
  23137. +                (comstats_t *) arg);
  23138. +        break;
  23139. +    case COM_GETBRDSTATS:
  23140. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  23141. +            sizeof(combrd_t))) == 0)
  23142. +            rc = stl_getbrdstats((combrd_t *) arg);
  23143. +        break;
  23144. +    case COM_READPORT:
  23145. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  23146. +            sizeof(stlport_t))) == 0)
  23147. +            rc = stl_getportstruct(arg);
  23148. +        break;
  23149. +    case COM_READBOARD:
  23150. +        if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
  23151. +            sizeof(stlbrd_t))) == 0)
  23152. +            rc = stl_getbrdstruct(arg);
  23153. +        break;
  23154. +    default:
  23155. +        rc = -ENOIOCTLCMD;
  23156. +        break;
  23157. +    }
  23158. +
  23159. +    return(rc);
  23160. +}
  23161. +
  23162. +/*****************************************************************************/
  23163. +
  23164. +int stl_init(void)
  23165. +{
  23166. +    printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
  23167. +
  23168. +    stl_initbrds();
  23169. +
  23170. +/*
  23171. + *    Allocate a temporary write buffer.
  23172. + */
  23173. +    stl_tmpwritebuf = (char *) stl_memalloc(STL_TXBUFSIZE);
  23174. +    if (stl_tmpwritebuf == (char *) NULL)
  23175. +        printk("STALLION: failed to allocate memory (size=%d)\n",
  23176. +            STL_TXBUFSIZE);
  23177. +
  23178. +/*
  23179. + *    Set up a character driver for per board stuff. This is mainly used
  23180. + *    to do stats ioctls on the ports.
  23181. + */
  23182. +    if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
  23183. +        printk("STALLION: failed to register serial board device\n");
  23184. +
  23185. +/*
  23186. + *    Set up the tty driver structure and register us as a driver.
  23187. + *    Also setup the callout tty device.
  23188. + */
  23189. +    memset(&stl_serial, 0, sizeof(struct tty_driver));
  23190. +    stl_serial.magic = TTY_DRIVER_MAGIC;
  23191. +    stl_serial.name = stl_serialname;
  23192. +    stl_serial.major = STL_SERIALMAJOR;
  23193. +    stl_serial.minor_start = 0;
  23194. +    stl_serial.num = STL_MAXBRDS * STL_MAXPORTS;
  23195. +    stl_serial.type = TTY_DRIVER_TYPE_SERIAL;
  23196. +    stl_serial.subtype = STL_DRVTYPSERIAL;
  23197. +    stl_serial.init_termios = stl_deftermios;
  23198. +    stl_serial.flags = TTY_DRIVER_REAL_RAW;
  23199. +    stl_serial.refcount = &stl_refcount;
  23200. +    stl_serial.table = stl_ttys;
  23201. +    stl_serial.termios = stl_termios;
  23202. +    stl_serial.termios_locked = stl_termioslocked;
  23203. +    
  23204. +    stl_serial.open = stl_open;
  23205. +    stl_serial.close = stl_close;
  23206. +    stl_serial.write = stl_write;
  23207. +    stl_serial.put_char = stl_putchar;
  23208. +    stl_serial.flush_chars = stl_flushchars;
  23209. +    stl_serial.write_room = stl_writeroom;
  23210. +    stl_serial.chars_in_buffer = stl_charsinbuffer;
  23211. +    stl_serial.ioctl = stl_ioctl;
  23212. +    stl_serial.set_termios = stl_settermios;
  23213. +    stl_serial.throttle = stl_throttle;
  23214. +    stl_serial.unthrottle = stl_unthrottle;
  23215. +    stl_serial.stop = stl_stop;
  23216. +    stl_serial.start = stl_start;
  23217. +    stl_serial.hangup = stl_hangup;
  23218. +    stl_serial.flush_buffer = stl_flushbuffer;
  23219. +
  23220. +    stl_callout = stl_serial;
  23221. +    stl_callout.name = stl_calloutname;
  23222. +    stl_callout.major = STL_CALLOUTMAJOR;
  23223. +    stl_callout.subtype = STL_DRVTYPCALLOUT;
  23224. +
  23225. +    if (tty_register_driver(&stl_serial))
  23226. +        printk("STALLION: failed to register serial driver\n");
  23227. +    if (tty_register_driver(&stl_callout))
  23228. +        printk("STALLION: failed to register callout driver\n");
  23229. +
  23230. +    return(0);
  23231. +}
  23232. +
  23233. +/*****************************************************************************/
  23234. +/*                       CD1400 HARDWARE FUNCTIONS                           */
  23235. +/*****************************************************************************/
  23236. +
  23237. +/*
  23238. + *    These functions get/set/update the registers of the cd1400 UARTs.
  23239. + *    Access to the cd1400 registers is via an address/data io port pair.
  23240. + *    (Maybe should make this inline...)
  23241. + */
  23242. +
  23243. +static int stl_cd1400getreg(stlport_t *portp, int regnr)
  23244. +{
  23245. +    outb((regnr + portp->uartaddr), portp->ioaddr);
  23246. +    return(inb(portp->ioaddr + EREG_DATA));
  23247. +}
  23248. +
  23249. +static void stl_cd1400setreg(stlport_t *portp, int regnr, int value)
  23250. +{
  23251. +    outb((regnr + portp->uartaddr), portp->ioaddr);
  23252. +    outb(value, portp->ioaddr + EREG_DATA);
  23253. +}
  23254. +
  23255. +static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value)
  23256. +{
  23257. +    outb((regnr + portp->uartaddr), portp->ioaddr);
  23258. +    if (inb(portp->ioaddr + EREG_DATA) != value) {
  23259. +        outb(value, portp->ioaddr + EREG_DATA);
  23260. +        return(1);
  23261. +    }
  23262. +    return(0);
  23263. +}
  23264. +
  23265. +/*****************************************************************************/
  23266. +
  23267. +/*
  23268. + *    Inbitialize the UARTs in a panel. We don't care what sort of board
  23269. + *    these ports are on - since the port io registers are almost
  23270. + *    identical when dealing with ports.
  23271. + */
  23272. +
  23273. +static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
  23274. +{
  23275. +    unsigned int    gfrcr;
  23276. +    int        chipmask, i, j;
  23277. +    int        nrchips, uartaddr, ioaddr;
  23278. +
  23279. +#if DEBUG
  23280. +    printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp);
  23281. +#endif
  23282. +
  23283. +    BRDENABLE(panelp->brdnr, panelp->pagenr);
  23284. +
  23285. +/*
  23286. + *    Check that each chip is present and started up OK.
  23287. + */
  23288. +    chipmask = 0;
  23289. +    nrchips = panelp->nrports / CD1400_PORTS;
  23290. +    for (i = 0; (i < nrchips); i++) {
  23291. +        if (brdp->brdtype == BRD_ECHPCI) {
  23292. +            outb((panelp->pagenr + (i >> 1)), brdp->ioctrl);
  23293. +            ioaddr = panelp->iobase;
  23294. +        } else {
  23295. +            ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1));
  23296. +        }
  23297. +        uartaddr = (i & 0x01) ? 0x080 : 0;
  23298. +        outb((GFRCR + uartaddr), ioaddr);
  23299. +        outb(0, (ioaddr + EREG_DATA));
  23300. +        outb((CCR + uartaddr), ioaddr);
  23301. +        outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
  23302. +        outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
  23303. +        outb((GFRCR + uartaddr), ioaddr);
  23304. +        for (j = 0; (j < CCR_MAXWAIT); j++) {
  23305. +            if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0)
  23306. +                break;
  23307. +        }
  23308. +        if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) {
  23309. +            printk("STALLION: cd1400 not responding, "
  23310. +                "brd=%d panel=%d chip=%d\n",
  23311. +                panelp->brdnr, panelp->panelnr, i);
  23312. +            continue;
  23313. +        }
  23314. +        chipmask |= (0x1 << i);
  23315. +        outb((PPR + uartaddr), ioaddr);
  23316. +        outb(PPR_SCALAR, (ioaddr + EREG_DATA));
  23317. +    }
  23318. +
  23319. +    BRDDISABLE(panelp->brdnr);
  23320. +    return(chipmask);
  23321. +}
  23322. +
  23323. +/*****************************************************************************/
  23324. +
  23325. +/*
  23326. + *    Initialize hardware specific port registers.
  23327. + */
  23328. +
  23329. +static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp)
  23330. +{
  23331. +#if DEBUG
  23332. +    printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n",
  23333. +        (int) brdp, (int) panelp, (int) portp);
  23334. +#endif
  23335. +
  23336. +    if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) ||
  23337. +        (portp == (stlport_t *) NULL))
  23338. +        return;
  23339. +
  23340. +    portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) ||
  23341. +        (portp->portnr < 8)) ? 0 : EREG_BANKSIZE);
  23342. +    portp->uartaddr = (portp->portnr & 0x04) << 5;
  23343. +    portp->pagenr = panelp->pagenr + (portp->portnr >> 3);
  23344. +
  23345. +    BRDENABLE(portp->brdnr, portp->pagenr);
  23346. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
  23347. +    stl_cd1400setreg(portp, LIVR, (portp->portnr << 3));
  23348. +    portp->hwid = stl_cd1400getreg(portp, GFRCR);
  23349. +    BRDDISABLE(portp->brdnr);
  23350. +}
  23351. +
  23352. +/*****************************************************************************/
  23353. +
  23354. +/*
  23355. + *    Wait for the command register to be ready. We will poll this,
  23356. + *    since it won't usually take too long to be ready.
  23357. + */
  23358. +
  23359. +static void stl_cd1400ccrwait(stlport_t *portp)
  23360. +{
  23361. +    int    i;
  23362. +
  23363. +    for (i = 0; (i < CCR_MAXWAIT); i++) {
  23364. +        if (stl_cd1400getreg(portp, CCR) == 0) {
  23365. +            return;
  23366. +        }
  23367. +    }
  23368. +
  23369. +    printk("STALLION: cd1400 not responding, port=%d panel=%d brd=%d\n",
  23370. +        portp->portnr, portp->panelnr, portp->brdnr);
  23371. +}
  23372. +
  23373. +/*****************************************************************************/
  23374. +
  23375. +/*
  23376. + *    Set up the cd1400 registers for a port based on the termios port
  23377. + *    settings.
  23378. + */
  23379. +
  23380. +static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp)
  23381. +{
  23382. +    stlbrd_t    *brdp;
  23383. +    unsigned long    flags;
  23384. +    unsigned int    clkdiv, baudrate;
  23385. +    unsigned char    cor1, cor2, cor3;
  23386. +    unsigned char    cor4, cor5, ccr;
  23387. +    unsigned char    srer, sreron, sreroff;
  23388. +    unsigned char    mcor1, mcor2, rtpr;
  23389. +    unsigned char    clk, div;
  23390. +
  23391. +    cor1 = 0;
  23392. +    cor2 = 0;
  23393. +    cor3 = 0;
  23394. +    cor4 = 0;
  23395. +    cor5 = 0;
  23396. +    ccr = 0;
  23397. +    rtpr = 0;
  23398. +    clk = 0;
  23399. +    div = 0;
  23400. +    mcor1 = 0;
  23401. +    mcor2 = 0;
  23402. +    sreron = 0;
  23403. +    sreroff = 0;
  23404. +
  23405. +    brdp = stl_brds[portp->brdnr];
  23406. +    if (brdp == (stlbrd_t *) NULL)
  23407. +        return;
  23408. +
  23409. +/*
  23410. + *    Set up the RX char ignore mask with those RX error types we
  23411. + *    can ignore. We can get the cd1400 to help us out a little here,
  23412. + *    it will ignore parity errors and breaks for us.
  23413. + */
  23414. +    portp->rxignoremsk = 0;
  23415. +    if (tiosp->c_iflag & IGNPAR) {
  23416. +        portp->rxignoremsk |= (ST_PARITY | ST_FRAMING | ST_OVERRUN);
  23417. +        cor1 |= COR1_PARIGNORE;
  23418. +    }
  23419. +    if (tiosp->c_iflag & IGNBRK) {
  23420. +        portp->rxignoremsk |= ST_BREAK;
  23421. +        cor4 |= COR4_IGNBRK;
  23422. +    }
  23423. +
  23424. +    portp->rxmarkmsk = ST_OVERRUN;
  23425. +    if (tiosp->c_iflag & (INPCK | PARMRK))
  23426. +        portp->rxmarkmsk |= (ST_PARITY | ST_FRAMING);
  23427. +    if (tiosp->c_iflag & BRKINT)
  23428. +        portp->rxmarkmsk |= ST_BREAK;
  23429. +
  23430. +/*
  23431. + *    Go through the char size, parity and stop bits and set all the
  23432. + *    option register appropriately.
  23433. + */
  23434. +    switch (tiosp->c_cflag & CSIZE) {
  23435. +    case CS5:
  23436. +        cor1 |= COR1_CHL5;
  23437. +        break;
  23438. +    case CS6:
  23439. +        cor1 |= COR1_CHL6;
  23440.          break;
  23441.      case CS7:
  23442.          cor1 |= COR1_CHL7;
  23443. @@ -2064,8 +3163,8 @@
  23444.          else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
  23445.              baudrate = (portp->baud_base / portp->custom_divisor);
  23446.      }
  23447. -    if (baudrate > STL_MAXBAUD)
  23448. -        baudrate = STL_MAXBAUD;
  23449. +    if (baudrate > STL_CD1400MAXBAUD)
  23450. +        baudrate = STL_CD1400MAXBAUD;
  23451.  
  23452.      if (baudrate > 0) {
  23453.          for (clk = 0; (clk < CD1400_NUMCLKS); clk++) {
  23454. @@ -2101,165 +3200,396 @@
  23455.              cor2 |= COR2_IXM;
  23456.      }
  23457.  
  23458. -    if (tiosp->c_cflag & CRTSCTS) {
  23459. -        cor2 |= COR2_CTSAE;
  23460. -        mcor1 |= FIFO_RTSTHRESHOLD;
  23461. -    }
  23462. +    if (tiosp->c_cflag & CRTSCTS) {
  23463. +        cor2 |= COR2_CTSAE;
  23464. +        mcor1 |= FIFO_RTSTHRESHOLD;
  23465. +    }
  23466. +
  23467. +/*
  23468. + *    All cd1400 register values calculated so go through and set
  23469. + *    them all up.
  23470. + */
  23471. +
  23472. +#if DEBUG
  23473. +    printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
  23474. +        portp->portnr, portp->panelnr, portp->brdnr);
  23475. +    printk("    cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n",
  23476. +        cor1, cor2, cor3, cor4, cor5);
  23477. +    printk("    mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n",
  23478. +        mcor1, mcor2, rtpr, sreron, sreroff);
  23479. +    printk("    tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div);
  23480. +    printk("    schr1=%x schr2=%x schr3=%x schr4=%x\n",
  23481. +        tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP],
  23482. +        tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
  23483. +#endif
  23484. +
  23485. +    save_flags(flags);
  23486. +    cli();
  23487. +    BRDENABLE(portp->brdnr, portp->pagenr);
  23488. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3));
  23489. +    srer = stl_cd1400getreg(portp, SRER);
  23490. +    stl_cd1400setreg(portp, SRER, 0);
  23491. +    if (stl_cd1400updatereg(portp, COR1, cor1))
  23492. +        ccr = 1;
  23493. +    if (stl_cd1400updatereg(portp, COR2, cor2))
  23494. +        ccr = 1;
  23495. +    if (stl_cd1400updatereg(portp, COR3, cor3))
  23496. +        ccr = 1;
  23497. +    if (ccr) {
  23498. +        stl_cd1400ccrwait(portp);
  23499. +        stl_cd1400setreg(portp, CCR, CCR_CORCHANGE);
  23500. +    }
  23501. +    stl_cd1400setreg(portp, COR4, cor4);
  23502. +    stl_cd1400setreg(portp, COR5, cor5);
  23503. +    stl_cd1400setreg(portp, MCOR1, mcor1);
  23504. +    stl_cd1400setreg(portp, MCOR2, mcor2);
  23505. +    if (baudrate > 0) {
  23506. +        stl_cd1400setreg(portp, TCOR, clk);
  23507. +        stl_cd1400setreg(portp, TBPR, div);
  23508. +        stl_cd1400setreg(portp, RCOR, clk);
  23509. +        stl_cd1400setreg(portp, RBPR, div);
  23510. +    }
  23511. +    stl_cd1400setreg(portp, SCHR1, tiosp->c_cc[VSTART]);
  23512. +    stl_cd1400setreg(portp, SCHR2, tiosp->c_cc[VSTOP]);
  23513. +    stl_cd1400setreg(portp, SCHR3, tiosp->c_cc[VSTART]);
  23514. +    stl_cd1400setreg(portp, SCHR4, tiosp->c_cc[VSTOP]);
  23515. +    stl_cd1400setreg(portp, RTPR, rtpr);
  23516. +    mcor1 = stl_cd1400getreg(portp, MSVR1);
  23517. +    if (mcor1 & MSVR1_DCD)
  23518. +        portp->sigs |= TIOCM_CD;
  23519. +    else
  23520. +        portp->sigs &= ~TIOCM_CD;
  23521. +    stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron));
  23522. +    BRDDISABLE(portp->brdnr);
  23523. +    restore_flags(flags);
  23524. +}
  23525. +
  23526. +/*****************************************************************************/
  23527. +
  23528. +/*
  23529. + *    Set the state of the DTR and RTS signals.
  23530. + */
  23531. +
  23532. +static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts)
  23533. +{
  23534. +    unsigned char    msvr1, msvr2;
  23535. +    unsigned long    flags;
  23536. +
  23537. +#if DEBUG
  23538. +    printk("stl_cd1400setsignals(portp=%x,dtr=%d,rts=%d)\n",
  23539. +        (int) portp, dtr, rts);
  23540. +#endif
  23541. +
  23542. +    msvr1 = 0;
  23543. +    msvr2 = 0;
  23544. +    if (dtr > 0)
  23545. +        msvr1 = MSVR1_DTR;
  23546. +    if (rts > 0)
  23547. +        msvr2 = MSVR2_RTS;
  23548. +
  23549. +    save_flags(flags);
  23550. +    cli();
  23551. +    BRDENABLE(portp->brdnr, portp->pagenr);
  23552. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
  23553. +    if (rts >= 0)
  23554. +        stl_cd1400setreg(portp, MSVR2, msvr2);
  23555. +    if (dtr >= 0)
  23556. +        stl_cd1400setreg(portp, MSVR1, msvr1);
  23557. +    BRDDISABLE(portp->brdnr);
  23558. +    restore_flags(flags);
  23559. +}
  23560. +
  23561. +/*****************************************************************************/
  23562. +
  23563. +/*
  23564. + *    Return the state of the signals.
  23565. + */
  23566. +
  23567. +static int stl_cd1400getsignals(stlport_t *portp)
  23568. +{
  23569. +    unsigned char    msvr1, msvr2;
  23570. +    unsigned long    flags;
  23571. +    int        sigs;
  23572. +
  23573. +#if DEBUG
  23574. +    printk("stl_cd1400getsignals(portp=%x)\n", (int) portp);
  23575. +#endif
  23576. +
  23577. +    save_flags(flags);
  23578. +    cli();
  23579. +    BRDENABLE(portp->brdnr, portp->pagenr);
  23580. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
  23581. +    msvr1 = stl_cd1400getreg(portp, MSVR1);
  23582. +    msvr2 = stl_cd1400getreg(portp, MSVR2);
  23583. +    BRDDISABLE(portp->brdnr);
  23584. +    restore_flags(flags);
  23585. +
  23586. +    sigs = 0;
  23587. +    sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0;
  23588. +    sigs |= (msvr1 & MSVR1_CTS) ? TIOCM_CTS : 0;
  23589. +    sigs |= (msvr1 & MSVR1_DTR) ? TIOCM_DTR : 0;
  23590. +    sigs |= (msvr2 & MSVR2_RTS) ? TIOCM_RTS : 0;
  23591. +#if 0
  23592. +    sigs |= (msvr1 & MSVR1_RI) ? TIOCM_RI : 0;
  23593. +    sigs |= (msvr1 & MSVR1_DSR) ? TIOCM_DSR : 0;
  23594. +#else
  23595. +    sigs |= TIOCM_DSR;
  23596. +#endif
  23597. +    return(sigs);
  23598. +}
  23599. +
  23600. +/*****************************************************************************/
  23601. +
  23602. +/*
  23603. + *    Enable/Disable the Transmitter and/or Receiver.
  23604. + */
  23605. +
  23606. +static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx)
  23607. +{
  23608. +    unsigned char    ccr;
  23609. +    unsigned long    flags;
  23610. +
  23611. +#if DEBUG
  23612. +    printk("stl_cd1400enablerxtx(portp=%x,rx=%d,tx=%d)\n",
  23613. +        (int) portp, rx, tx);
  23614. +#endif
  23615. +    ccr = 0;
  23616. +
  23617. +    if (tx == 0)
  23618. +        ccr |= CCR_TXDISABLE;
  23619. +    else if (tx > 0)
  23620. +        ccr |= CCR_TXENABLE;
  23621. +    if (rx == 0)
  23622. +        ccr |= CCR_RXDISABLE;
  23623. +    else if (rx > 0)
  23624. +        ccr |= CCR_RXENABLE;
  23625. +
  23626. +    save_flags(flags);
  23627. +    cli();
  23628. +    BRDENABLE(portp->brdnr, portp->pagenr);
  23629. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
  23630. +    stl_cd1400ccrwait(portp);
  23631. +    stl_cd1400setreg(portp, CCR, ccr);
  23632. +    stl_cd1400ccrwait(portp);
  23633. +    BRDDISABLE(portp->brdnr);
  23634. +    restore_flags(flags);
  23635. +}
  23636. +
  23637. +/*****************************************************************************/
  23638.  
  23639.  /*
  23640. - *    All register cd1400 register values calculated so go through and set
  23641. - *    them all up.
  23642. + *    Start/stop the Transmitter and/or Receiver.
  23643.   */
  23644.  
  23645. +static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx)
  23646. +{
  23647. +    unsigned char    sreron, sreroff;
  23648. +    unsigned long    flags;
  23649. +
  23650.  #if DEBUG
  23651. -    printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", portp->portnr, portp->panelnr, portp->brdnr);
  23652. -    printk("    cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n", cor1, cor2, cor3, cor4, cor5);
  23653. -    printk("    mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n", mcor1, mcor2, rtpr, sreron, sreroff);
  23654. -    printk("    tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div);
  23655. -    printk("    schr1=%x schr2=%x schr3=%x schr4=%x\n", tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
  23656. +    printk("stl_cd1400startrxtx(portp=%x,rx=%d,tx=%d)\n",
  23657. +        (int) portp, rx, tx);
  23658.  #endif
  23659.  
  23660. +    sreron = 0;
  23661. +    sreroff = 0;
  23662. +    if (tx == 0)
  23663. +        sreroff |= (SRER_TXDATA | SRER_TXEMPTY);
  23664. +    else if (tx == 1)
  23665. +        sreron |= SRER_TXDATA;
  23666. +    else if (tx >= 2)
  23667. +        sreron |= SRER_TXEMPTY;
  23668. +    if (rx == 0)
  23669. +        sreroff |= SRER_RXDATA;
  23670. +    else if (rx > 0)
  23671. +        sreron |= SRER_RXDATA;
  23672. +
  23673.      save_flags(flags);
  23674.      cli();
  23675.      BRDENABLE(portp->brdnr, portp->pagenr);
  23676. -    stl_setreg(portp, CAR, (portp->portnr & 0x3));
  23677. -    srer = stl_getreg(portp, SRER);
  23678. -    stl_setreg(portp, SRER, 0);
  23679. -    if (stl_updatereg(portp, COR1, cor1))
  23680. -        ccr = 1;
  23681. -    if (stl_updatereg(portp, COR2, cor2))
  23682. -        ccr = 1;
  23683. -    if (stl_updatereg(portp, COR3, cor3))
  23684. -        ccr = 1;
  23685. -    if (ccr) {
  23686. -        stl_ccrwait(portp);
  23687. -        stl_setreg(portp, CCR, CCR_CORCHANGE);
  23688. -    }
  23689. -    stl_setreg(portp, COR4, cor4);
  23690. -    stl_setreg(portp, COR5, cor5);
  23691. -    stl_setreg(portp, MCOR1, mcor1);
  23692. -    stl_setreg(portp, MCOR2, mcor2);
  23693. -    if (baudrate > 0) {
  23694. -        stl_setreg(portp, TCOR, clk);
  23695. -        stl_setreg(portp, TBPR, div);
  23696. -        stl_setreg(portp, RCOR, clk);
  23697. -        stl_setreg(portp, RBPR, div);
  23698. -    }
  23699. -    stl_setreg(portp, SCHR1, tiosp->c_cc[VSTART]);
  23700. -    stl_setreg(portp, SCHR2, tiosp->c_cc[VSTOP]);
  23701. -    stl_setreg(portp, SCHR3, tiosp->c_cc[VSTART]);
  23702. -    stl_setreg(portp, SCHR4, tiosp->c_cc[VSTOP]);
  23703. -    stl_setreg(portp, RTPR, rtpr);
  23704. -    mcor1 = stl_getreg(portp, MSVR1);
  23705. -    if (mcor1 & MSVR1_DCD)
  23706. -        portp->sigs |= TIOCM_CD;
  23707. -    else
  23708. -        portp->sigs &= ~TIOCM_CD;
  23709. -    stl_setreg(portp, SRER, ((srer & ~sreroff) | sreron));
  23710. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
  23711. +    stl_cd1400setreg(portp, SRER,
  23712. +        ((stl_cd1400getreg(portp, SRER) & ~sreroff) | sreron));
  23713.      BRDDISABLE(portp->brdnr);
  23714. +    if (tx > 0)
  23715. +        set_bit(ASYI_TXBUSY, &portp->istate);
  23716.      restore_flags(flags);
  23717.  }
  23718.  
  23719.  /*****************************************************************************/
  23720.  
  23721.  /*
  23722. - *    Set the state of the DTR and RTS signals.
  23723. + *    Disable all interrupts from this port.
  23724.   */
  23725.  
  23726. -static void stl_setsignals(stlport_t *portp, int dtr, int rts)
  23727. +static void stl_cd1400disableintrs(stlport_t *portp)
  23728.  {
  23729. -    unsigned char    msvr1, msvr2;
  23730.      unsigned long    flags;
  23731.  
  23732.  #if DEBUG
  23733. -    printk("stl_setsignals(portp=%x,dtr=%d,rts=%d)\n", (int) portp, dtr, rts);
  23734. +    printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp);
  23735.  #endif
  23736. +    save_flags(flags);
  23737. +    cli();
  23738. +    BRDENABLE(portp->brdnr, portp->pagenr);
  23739. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
  23740. +    stl_cd1400setreg(portp, SRER, 0);
  23741. +    BRDDISABLE(portp->brdnr);
  23742. +    restore_flags(flags);
  23743. +}
  23744.  
  23745. -    msvr1 = 0;
  23746. -    msvr2 = 0;
  23747. -    if (dtr > 0)
  23748. -        msvr1 = MSVR1_DTR;
  23749. -    if (rts > 0)
  23750. -        msvr2 = MSVR2_RTS;
  23751. +/*****************************************************************************/
  23752. +
  23753. +static void stl_cd1400sendbreak(stlport_t *portp, long len)
  23754. +{
  23755. +    unsigned long    flags;
  23756. +
  23757. +#if DEBUG
  23758. +    printk("stl_cd1400sendbreak(portp=%x,len=%d)\n",
  23759. +        (int) portp, (int) len);
  23760. +#endif
  23761.  
  23762.      save_flags(flags);
  23763.      cli();
  23764.      BRDENABLE(portp->brdnr, portp->pagenr);
  23765. -    stl_setreg(portp, CAR, (portp->portnr & 0x03));
  23766. -    if (rts >= 0)
  23767. -        stl_setreg(portp, MSVR2, msvr2);
  23768. -    if (dtr >= 0)
  23769. -        stl_setreg(portp, MSVR1, msvr1);
  23770. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
  23771. +    stl_cd1400setreg(portp, COR2,
  23772. +        (stl_cd1400getreg(portp, COR2) | COR2_ETC));
  23773. +    stl_cd1400setreg(portp, SRER,
  23774. +        ((stl_cd1400getreg(portp, SRER) & ~SRER_TXDATA) | SRER_TXEMPTY));
  23775.      BRDDISABLE(portp->brdnr);
  23776. +    len = len / 5;
  23777. +    portp->brklen = (len > 255) ? 255 : len;
  23778. +    portp->stats.txbreaks++;
  23779.      restore_flags(flags);
  23780.  }
  23781.  
  23782.  /*****************************************************************************/
  23783.  
  23784.  /*
  23785. - *    Return the state of the signals.
  23786. + *    Take flow control actions...
  23787.   */
  23788.  
  23789. -static int stl_getsignals(stlport_t *portp)
  23790. +static void stl_cd1400flowctrl(stlport_t *portp, int state)
  23791.  {
  23792. -    unsigned char    msvr1, msvr2;
  23793. -    unsigned long    flags;
  23794. -    int        sigs;
  23795. +    struct tty_struct    *tty;
  23796. +    unsigned long        flags;
  23797.  
  23798.  #if DEBUG
  23799. -    printk("stl_getsignals(portp=%x)\n", (int) portp);
  23800. +    printk("stl_cd1400flowctrl(portp=%x,state=%x)\n", (int) portp, state);
  23801.  #endif
  23802.  
  23803. +    if (portp == (stlport_t *) NULL)
  23804. +        return;
  23805. +    tty = portp->tty;
  23806. +    if (tty == (struct tty_struct *) NULL)
  23807. +        return;
  23808. +
  23809.      save_flags(flags);
  23810.      cli();
  23811.      BRDENABLE(portp->brdnr, portp->pagenr);
  23812. -    stl_setreg(portp, CAR, (portp->portnr & 0x03));
  23813. -    msvr1 = stl_getreg(portp, MSVR1);
  23814. -    msvr2 = stl_getreg(portp, MSVR2);
  23815. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
  23816. +
  23817. +    if (state) {
  23818. +        if (tty->termios->c_iflag & IXOFF) {
  23819. +            stl_cd1400ccrwait(portp);
  23820. +            stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1);
  23821. +            portp->stats.rxxon++;
  23822. +            stl_cd1400ccrwait(portp);
  23823. +        }
  23824. +/*
  23825. + *        Question: should we return RTS to what it was before? It may
  23826. + *        have been set by an ioctl... Suppose not, since if you have
  23827. + *        hardware flow control set then it is pretty silly to go and
  23828. + *        set the RTS line by hand.
  23829. + */
  23830. +        if (tty->termios->c_cflag & CRTSCTS) {
  23831. +            stl_cd1400setreg(portp, MCOR1,
  23832. +                (stl_cd1400getreg(portp, MCOR1) |
  23833. +                FIFO_RTSTHRESHOLD));
  23834. +            stl_cd1400setreg(portp, MSVR2, MSVR2_RTS);
  23835. +            portp->stats.rxrtson++;
  23836. +        }
  23837. +    } else {
  23838. +        if (tty->termios->c_iflag & IXOFF) {
  23839. +            stl_cd1400ccrwait(portp);
  23840. +            stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2);
  23841. +            portp->stats.rxxoff++;
  23842. +            stl_cd1400ccrwait(portp);
  23843. +        }
  23844. +        if (tty->termios->c_cflag & CRTSCTS) {
  23845. +            stl_cd1400setreg(portp, MCOR1,
  23846. +                (stl_cd1400getreg(portp, MCOR1) & 0xf0));
  23847. +            stl_cd1400setreg(portp, MSVR2, 0);
  23848. +            portp->stats.rxrtsoff++;
  23849. +        }
  23850. +    }
  23851. +
  23852.      BRDDISABLE(portp->brdnr);
  23853. -    sigs = 0;
  23854. -    sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0;
  23855. -    sigs |= (msvr1 & MSVR1_CTS) ? TIOCM_CTS : 0;
  23856. -    sigs |= (msvr1 & MSVR1_RI) ? TIOCM_RI : 0;
  23857. -    sigs |= (msvr1 & MSVR1_DSR) ? TIOCM_DSR : 0;
  23858. -    sigs |= (msvr1 & MSVR1_DTR) ? TIOCM_DTR : 0;
  23859. -    sigs |= (msvr2 & MSVR2_RTS) ? TIOCM_RTS : 0;
  23860.      restore_flags(flags);
  23861. -    return(sigs);
  23862.  }
  23863.  
  23864.  /*****************************************************************************/
  23865.  
  23866.  /*
  23867. - *    Enable/Disable the Transmitter and/or Receiver.
  23868. + *    Send a flow control character...
  23869.   */
  23870.  
  23871. -static void stl_enablerxtx(stlport_t *portp, int rx, int tx)
  23872. +static void stl_cd1400sendflow(stlport_t *portp, int state)
  23873. +{
  23874. +    struct tty_struct    *tty;
  23875. +    unsigned long        flags;
  23876. +
  23877. +#if DEBUG
  23878. +    printk("stl_cd1400sendflow(portp=%x,state=%x)\n", (int) portp, state);
  23879. +#endif
  23880. +
  23881. +    if (portp == (stlport_t *) NULL)
  23882. +        return;
  23883. +    tty = portp->tty;
  23884. +    if (tty == (struct tty_struct *) NULL)
  23885. +        return;
  23886. +
  23887. +    save_flags(flags);
  23888. +    cli();
  23889. +    BRDENABLE(portp->brdnr, portp->pagenr);
  23890. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
  23891. +    if (state) {
  23892. +        stl_cd1400ccrwait(portp);
  23893. +        stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1);
  23894. +        portp->stats.rxxon++;
  23895. +        stl_cd1400ccrwait(portp);
  23896. +    } else {
  23897. +        stl_cd1400ccrwait(portp);
  23898. +        stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2);
  23899. +        portp->stats.rxxoff++;
  23900. +        stl_cd1400ccrwait(portp);
  23901. +    }
  23902. +    BRDDISABLE(portp->brdnr);
  23903. +    restore_flags(flags);
  23904. +}
  23905. +
  23906. +/*****************************************************************************/
  23907. +
  23908. +static void stl_cd1400flush(stlport_t *portp)
  23909.  {
  23910. -    unsigned char    ccr;
  23911.      unsigned long    flags;
  23912.  
  23913.  #if DEBUG
  23914. -    printk("stl_enablerxtx(portp=%x,rx=%d,tx=%d)\n", (int) portp, rx, tx);
  23915. +    printk("stl_cd1400flush(portp=%x)\n", (int) portp);
  23916.  #endif
  23917. -    ccr = 0;
  23918.  
  23919. -    if (tx == 0)
  23920. -        ccr |= CCR_TXDISABLE;
  23921. -    else if (tx > 0)
  23922. -        ccr |= CCR_TXENABLE;
  23923. -    if (rx == 0)
  23924. -        ccr |= CCR_RXDISABLE;
  23925. -    else if (rx > 0)
  23926. -        ccr |= CCR_RXENABLE;
  23927. +    if (portp == (stlport_t *) NULL)
  23928. +        return;
  23929.  
  23930.      save_flags(flags);
  23931.      cli();
  23932.      BRDENABLE(portp->brdnr, portp->pagenr);
  23933. -    stl_setreg(portp, CAR, (portp->portnr & 0x03));
  23934. -    stl_ccrwait(portp);
  23935. -    stl_setreg(portp, CCR, ccr);
  23936. -    stl_ccrwait(portp);
  23937. +    stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
  23938. +    stl_cd1400ccrwait(portp);
  23939. +    stl_cd1400setreg(portp, CCR, CCR_TXFLUSHFIFO);
  23940. +    stl_cd1400ccrwait(portp);
  23941. +    portp->tx.tail = portp->tx.head;
  23942.      BRDDISABLE(portp->brdnr);
  23943.      restore_flags(flags);
  23944.  }
  23945. @@ -2267,137 +3597,400 @@
  23946.  /*****************************************************************************/
  23947.  
  23948.  /*
  23949. - *    Start/stop the Transmitter and/or Receiver.
  23950. + *    Return the current state of data flow on this port. This is only
  23951. + *    really interresting when determining if data has fully completed
  23952. + *    transmission or not... This is easy for the cd1400, it accurately
  23953. + *    maintains the busy port flag.
  23954. + */
  23955. +
  23956. +static int stl_cd1400datastate(stlport_t *portp)
  23957. +{
  23958. +#if DEBUG
  23959. +    printk("stl_cd1400datastate(portp=%x)\n", (int) portp);
  23960. +#endif
  23961. +
  23962. +    if (portp == (stlport_t *) NULL)
  23963. +        return(0);
  23964. +
  23965. +    return(test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0);
  23966. +}
  23967. +
  23968. +/*****************************************************************************/
  23969. +
  23970. +/*
  23971. + *    Interrupt service routine for cd1400 EasyIO boards.
  23972. + */
  23973. +
  23974. +static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase)
  23975. +{
  23976. +    unsigned char    svrtype;
  23977. +
  23978. +#if DEBUG
  23979. +    printk("stl_cd1400eiointr(panelp=%x,iobase=%x)\n",
  23980. +        (int) panelp, iobase);
  23981. +#endif
  23982. +
  23983. +    outb(SVRR, iobase);
  23984. +    svrtype = inb(iobase + EREG_DATA);
  23985. +    if (panelp->nrports > 4) {
  23986. +        outb((SVRR + 0x80), iobase);
  23987. +        svrtype |= inb(iobase + EREG_DATA);
  23988. +    }
  23989. +
  23990. +    if (svrtype & SVRR_RX)
  23991. +        stl_cd1400rxisr(panelp, iobase);
  23992. +    else if (svrtype & SVRR_TX)
  23993. +        stl_cd1400txisr(panelp, iobase);
  23994. +    else if (svrtype & SVRR_MDM)
  23995. +        stl_cd1400mdmisr(panelp, iobase);
  23996. +}
  23997. +
  23998. +/*****************************************************************************/
  23999. +
  24000. +/*
  24001. + *    Interrupt service routine for cd1400 panels.
  24002. + */
  24003. +
  24004. +static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase)
  24005. +{
  24006. +    unsigned char    svrtype;
  24007. +
  24008. +#if DEBUG
  24009. +    printk("stl_cd1400echintr(panelp=%x,iobase=%x)\n", (int) panelp,
  24010. +        iobase);
  24011. +#endif
  24012. +
  24013. +    outb(SVRR, iobase);
  24014. +    svrtype = inb(iobase + EREG_DATA);
  24015. +    outb((SVRR + 0x80), iobase);
  24016. +    svrtype |= inb(iobase + EREG_DATA);
  24017. +    if (svrtype & SVRR_RX)
  24018. +        stl_cd1400rxisr(panelp, iobase);
  24019. +    else if (svrtype & SVRR_TX)
  24020. +        stl_cd1400txisr(panelp, iobase);
  24021. +    else if (svrtype & SVRR_MDM)
  24022. +        stl_cd1400mdmisr(panelp, iobase);
  24023. +}
  24024. +
  24025. +/*****************************************************************************/
  24026. +
  24027. +/*
  24028. + *    Transmit interrupt handler. This has gotta be fast!  Handling TX
  24029. + *    chars is pretty simple, stuff as many as possible from the TX buffer
  24030. + *    into the cd1400 FIFO. Must also handle TX breaks here, since they
  24031. + *    are embedded as commands in the data stream. Oh no, had to use a goto!
  24032. + *    This could be optimized more, will do when I get time...
  24033. + *    In practice it is possible that interrupts are enabled but that the
  24034. + *    port has been hung up. Need to handle not having any TX buffer here,
  24035. + *    this is done by using the side effect that head and tail will also
  24036. + *    be NULL if the buffer has been freed.
  24037. + */
  24038. +
  24039. +static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr)
  24040. +{
  24041. +    stlport_t    *portp;
  24042. +    int        len, stlen;
  24043. +    char        *head, *tail;
  24044. +    unsigned char    ioack, srer;
  24045. +
  24046. +#if DEBUG
  24047. +    printk("stl_cd1400txisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
  24048. +#endif
  24049. +
  24050. +    ioack = inb(ioaddr + EREG_TXACK);
  24051. +    if (((ioack & panelp->ackmask) != 0) ||
  24052. +        ((ioack & ACK_TYPMASK) != ACK_TYPTX)) {
  24053. +        printk("STALLION: bad TX interrupt ack value=%x\n", ioack);
  24054. +        return;
  24055. +    }
  24056. +    portp = panelp->ports[(ioack >> 3)];
  24057. +
  24058. +/*
  24059. + *    Unfortunately we need to handle breaks in the data stream, since
  24060. + *    this is the only way to generate them on the cd1400. Do it now if
  24061. + *    a break is to be sent.
  24062. + */
  24063. +    if (portp->brklen != 0) {
  24064. +        if (portp->brklen > 0) {
  24065. +            outb((TDR + portp->uartaddr), ioaddr);
  24066. +            outb(ETC_CMD, (ioaddr + EREG_DATA));
  24067. +            outb(ETC_STARTBREAK, (ioaddr + EREG_DATA));
  24068. +            outb(ETC_CMD, (ioaddr + EREG_DATA));
  24069. +            outb(ETC_DELAY, (ioaddr + EREG_DATA));
  24070. +            outb(portp->brklen, (ioaddr + EREG_DATA));
  24071. +            outb(ETC_CMD, (ioaddr + EREG_DATA));
  24072. +            outb(ETC_STOPBREAK, (ioaddr + EREG_DATA));
  24073. +            portp->brklen = -1;
  24074. +            goto stl_txalldone;
  24075. +        } else {
  24076. +            outb((COR2 + portp->uartaddr), ioaddr);
  24077. +            outb((inb(ioaddr + EREG_DATA) & ~COR2_ETC),
  24078. +                (ioaddr + EREG_DATA));
  24079. +            portp->brklen = 0;
  24080. +        }
  24081. +    }
  24082. +
  24083. +    head = portp->tx.head;
  24084. +    tail = portp->tx.tail;
  24085. +    len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
  24086. +    if ((len == 0) || ((len < STL_TXBUFLOW) &&
  24087. +        (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
  24088. +        set_bit(ASYI_TXLOW, &portp->istate);
  24089. +        queue_task_irq_off(&portp->tqueue, &tq_scheduler);
  24090. +    }
  24091. +
  24092. +    if (len == 0) {
  24093. +        outb((SRER + portp->uartaddr), ioaddr);
  24094. +        srer = inb(ioaddr + EREG_DATA);
  24095. +        if (srer & SRER_TXDATA) {
  24096. +            srer = (srer & ~SRER_TXDATA) | SRER_TXEMPTY;
  24097. +        } else {
  24098. +            srer &= ~(SRER_TXDATA | SRER_TXEMPTY);
  24099. +            clear_bit(ASYI_TXBUSY, &portp->istate);
  24100. +        }
  24101. +        outb(srer, (ioaddr + EREG_DATA));
  24102. +    } else {
  24103. +        len = MIN(len, CD1400_TXFIFOSIZE);
  24104. +        portp->stats.txtotal += len;
  24105. +        stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
  24106. +        outb((TDR + portp->uartaddr), ioaddr);
  24107. +        outsb((ioaddr + EREG_DATA), tail, stlen);
  24108. +        len -= stlen;
  24109. +        tail += stlen;
  24110. +        if (tail >= (portp->tx.buf + STL_TXBUFSIZE))
  24111. +            tail = portp->tx.buf;
  24112. +        if (len > 0) {
  24113. +            outsb((ioaddr + EREG_DATA), tail, len);
  24114. +            tail += len;
  24115. +        }
  24116. +        portp->tx.tail = tail;
  24117. +    }
  24118. +
  24119. +stl_txalldone:
  24120. +    outb((EOSRR + portp->uartaddr), ioaddr);
  24121. +    outb(0, (ioaddr + EREG_DATA));
  24122. +}
  24123. +
  24124. +/*****************************************************************************/
  24125. +
  24126. +/*
  24127. + *    Receive character interrupt handler. Determine if we have good chars
  24128. + *    or bad chars and then process appropriately. Good chars are easy
  24129. + *    just shove the lot into the RX buffer and set all status byte to 0.
  24130. + *    If a bad RX char then process as required. This routine needs to be
  24131. + *    fast!  In practice it is possible that we get an interrupt on a port
  24132. + *    that is closed. This can happen on hangups - since they completely
  24133. + *    shutdown a port not in user context. Need to handle this case.
  24134.   */
  24135.  
  24136. -static void stl_startrxtx(stlport_t *portp, int rx, int tx)
  24137. +static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
  24138.  {
  24139. -    unsigned char    sreron, sreroff;
  24140. -    unsigned long    flags;
  24141. +    stlport_t        *portp;
  24142. +    struct tty_struct    *tty;
  24143. +    unsigned int        ioack, len, buflen;
  24144. +    unsigned char        status;
  24145. +    char            ch;
  24146.  
  24147.  #if DEBUG
  24148. -    printk("stl_startrxtx(portp=%x,rx=%d,tx=%d)\n", (int) portp, rx, tx);
  24149. +    printk("stl_cd1400rxisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
  24150.  #endif
  24151.  
  24152. -    sreron = 0;
  24153. -    sreroff = 0;
  24154. -    if (tx == 0)
  24155. -        sreroff |= (SRER_TXDATA | SRER_TXEMPTY);
  24156. -    else if (tx == 1)
  24157. -        sreron |= SRER_TXDATA;
  24158. -    else if (tx >= 2)
  24159. -        sreron |= SRER_TXEMPTY;
  24160. -    if (rx == 0)
  24161. -        sreroff |= SRER_RXDATA;
  24162. -    else if (rx > 0)
  24163. -        sreron |= SRER_RXDATA;
  24164. +    ioack = inb(ioaddr + EREG_RXACK);
  24165. +    if ((ioack & panelp->ackmask) != 0) {
  24166. +        printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
  24167. +        return;
  24168. +    }
  24169. +    portp = panelp->ports[(ioack >> 3)];
  24170. +    tty = portp->tty;
  24171.  
  24172. -    save_flags(flags);
  24173. -    cli();
  24174. -    BRDENABLE(portp->brdnr, portp->pagenr);
  24175. -    stl_setreg(portp, CAR, (portp->portnr & 0x03));
  24176. -    stl_setreg(portp, SRER, ((stl_getreg(portp, SRER) & ~sreroff) | sreron));
  24177. -    BRDDISABLE(portp->brdnr);
  24178. -    if (tx > 0)
  24179. -        set_bit(ASYI_TXBUSY, &portp->istate);
  24180. -    restore_flags(flags);
  24181. +    if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
  24182. +        outb((RDCR + portp->uartaddr), ioaddr);
  24183. +        len = inb(ioaddr + EREG_DATA);
  24184. +        if ((tty == (struct tty_struct *) NULL) ||
  24185. +            (tty->flip.char_buf_ptr == (char *) NULL) ||
  24186. +            ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
  24187. +            outb((RDSR + portp->uartaddr), ioaddr);
  24188. +            insb((ioaddr + EREG_DATA), &stl_unwanted[0], len);
  24189. +            portp->stats.rxlost += len;
  24190. +            portp->stats.rxtotal += len;
  24191. +        } else {
  24192. +            len = MIN(len, buflen);
  24193. +            if (len > 0) {
  24194. +                outb((RDSR + portp->uartaddr), ioaddr);
  24195. +                insb((ioaddr + EREG_DATA), tty->flip.char_buf_ptr, len);
  24196. +                memset(tty->flip.flag_buf_ptr, 0, len);
  24197. +                tty->flip.flag_buf_ptr += len;
  24198. +                tty->flip.char_buf_ptr += len;
  24199. +                tty->flip.count += len;
  24200. +                tty_schedule_flip(tty);
  24201. +                portp->stats.rxtotal += len;
  24202. +            }
  24203. +        }
  24204. +    } else if ((ioack & ACK_TYPMASK) == ACK_TYPRXBAD) {
  24205. +        outb((RDSR + portp->uartaddr), ioaddr);
  24206. +        status = inb(ioaddr + EREG_DATA);
  24207. +        ch = inb(ioaddr + EREG_DATA);
  24208. +        if (status & ST_PARITY)
  24209. +            portp->stats.rxparity++;
  24210. +        if (status & ST_FRAMING)
  24211. +            portp->stats.rxframing++;
  24212. +        if (status & ST_OVERRUN)
  24213. +            portp->stats.rxoverrun++;
  24214. +        if (status & ST_BREAK)
  24215. +            portp->stats.rxbreaks++;
  24216. +        if (status & ST_SCHARMASK) {
  24217. +            if ((status & ST_SCHARMASK) == ST_SCHAR1)
  24218. +                portp->stats.txxon++;
  24219. +            if ((status & ST_SCHARMASK) == ST_SCHAR2)
  24220. +                portp->stats.txxoff++;
  24221. +            goto stl_rxalldone;
  24222. +        }
  24223. +        if ((tty != (struct tty_struct *) NULL) &&
  24224. +            ((portp->rxignoremsk & status) == 0)) {
  24225. +            if (portp->rxmarkmsk & status) {
  24226. +                if (status & ST_BREAK) {
  24227. +                    status = TTY_BREAK;
  24228. +                    if (portp->flags & ASYNC_SAK) {
  24229. +                        do_SAK(tty);
  24230. +                        BRDENABLE(portp->brdnr, portp->pagenr);
  24231. +                    }
  24232. +                } else if (status & ST_PARITY) {
  24233. +                    status = TTY_PARITY;
  24234. +                } else if (status & ST_FRAMING) {
  24235. +                    status = TTY_FRAME;
  24236. +                } else if(status & ST_OVERRUN) {
  24237. +                    status = TTY_OVERRUN;
  24238. +                } else {
  24239. +                    status = 0;
  24240. +                }
  24241. +            } else {
  24242. +                status = 0;
  24243. +            }
  24244. +            if (tty->flip.char_buf_ptr != (char *) NULL) {
  24245. +                if (tty->flip.count < TTY_FLIPBUF_SIZE) {
  24246. +                    *tty->flip.flag_buf_ptr++ = status;
  24247. +                    *tty->flip.char_buf_ptr++ = ch;
  24248. +                    tty->flip.count++;
  24249. +                }
  24250. +                tty_schedule_flip(tty);
  24251. +            }
  24252. +        }
  24253. +    } else {
  24254. +        printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
  24255. +        return;
  24256. +    }
  24257. +
  24258. +stl_rxalldone:
  24259. +    outb((EOSRR + portp->uartaddr), ioaddr);
  24260. +    outb(0, (ioaddr + EREG_DATA));
  24261.  }
  24262.  
  24263.  /*****************************************************************************/
  24264.  
  24265.  /*
  24266. - *    Disable all interrupts from this port.
  24267. + *    Modem interrupt handler. The is called when the modem signal line
  24268. + *    (DCD) has changed state. Leave most of the work to the off-level
  24269. + *    processing routine.
  24270.   */
  24271.  
  24272. -static void stl_disableintrs(stlport_t *portp)
  24273. +static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr)
  24274.  {
  24275. -    unsigned long    flags;
  24276. +    stlport_t    *portp;
  24277. +    unsigned int    ioack;
  24278. +    unsigned char    misr;
  24279.  
  24280.  #if DEBUG
  24281. -    printk("stl_disableintrs(portp=%x)\n", (int) portp);
  24282. +    printk("stl_cd1400mdmisr(panelp=%x)\n", (int) panelp);
  24283.  #endif
  24284. -    save_flags(flags);
  24285. -    cli();
  24286. -    BRDENABLE(portp->brdnr, portp->pagenr);
  24287. -    stl_setreg(portp, CAR, (portp->portnr & 0x03));
  24288. -    stl_setreg(portp, SRER, 0);
  24289. -    BRDDISABLE(portp->brdnr);
  24290. -    restore_flags(flags);
  24291. +
  24292. +    ioack = inb(ioaddr + EREG_MDACK);
  24293. +    if (((ioack & panelp->ackmask) != 0) ||
  24294. +        ((ioack & ACK_TYPMASK) != ACK_TYPMDM)) {
  24295. +        printk("STALLION: bad MODEM interrupt ack value=%x\n", ioack);
  24296. +        return;
  24297. +    }
  24298. +    portp = panelp->ports[(ioack >> 3)];
  24299. +
  24300. +    outb((MISR + portp->uartaddr), ioaddr);
  24301. +    misr = inb(ioaddr + EREG_DATA);
  24302. +    if (misr & MISR_DCD) {
  24303. +        set_bit(ASYI_DCDCHANGE, &portp->istate);
  24304. +        queue_task_irq_off(&portp->tqueue, &tq_scheduler);
  24305. +        portp->stats.modem++;
  24306. +    }
  24307. +
  24308. +    outb((EOSRR + portp->uartaddr), ioaddr);
  24309. +    outb(0, (ioaddr + EREG_DATA));
  24310.  }
  24311.  
  24312.  /*****************************************************************************/
  24313. +/*                      SC26198 HARDWARE FUNCTIONS                           */
  24314. +/*****************************************************************************/
  24315.  
  24316. -static void stl_sendbreak(stlport_t *portp, long len)
  24317. +/*
  24318. + *    These functions get/set/update the registers of the sc26198 UARTs.
  24319. + *    Access to the sc26198 registers is via an address/data io port pair.
  24320. + *    (Maybe should make this inline...)
  24321. + */
  24322. +
  24323. +static int stl_sc26198getreg(stlport_t *portp, int regnr)
  24324.  {
  24325. -    unsigned long    flags;
  24326. +    outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
  24327. +    return(inb(portp->ioaddr + XP_DATA));
  24328. +}
  24329.  
  24330. -#if DEBUG
  24331. -    printk("stl_sendbreak(portp=%x,len=%d)\n", (int) portp, (int) len);
  24332. -#endif
  24333. +static void stl_sc26198setreg(stlport_t *portp, int regnr, int value)
  24334. +{
  24335. +    outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
  24336. +    outb(value, (portp->ioaddr + XP_DATA));
  24337. +}
  24338.  
  24339. -    save_flags(flags);
  24340. -    cli();
  24341. -    BRDENABLE(portp->brdnr, portp->pagenr);
  24342. -    stl_setreg(portp, CAR, (portp->portnr & 0x03));
  24343. -    stl_setreg(portp, COR2, (stl_getreg(portp, COR2) | COR2_ETC));
  24344. -    stl_setreg(portp, SRER, ((stl_getreg(portp, SRER) & ~SRER_TXDATA) | SRER_TXEMPTY));
  24345. -    BRDDISABLE(portp->brdnr);
  24346. -    len = len / 5;
  24347. -    portp->brklen = (len > 255) ? 255 : len;
  24348. -    portp->stats.txbreaks++;
  24349. -    restore_flags(flags);
  24350. +static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value)
  24351. +{
  24352. +    outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
  24353. +    if (inb(portp->ioaddr + XP_DATA) != value) {
  24354. +        outb(value, (portp->ioaddr + XP_DATA));
  24355. +        return(1);
  24356. +    }
  24357. +    return(0);
  24358.  }
  24359.  
  24360.  /*****************************************************************************/
  24361.  
  24362.  /*
  24363. - *    Map in interrupt vector to this driver. Check that we don't
  24364. - *    already have this vector mapped, we might be sharing this
  24365. - *    interrupt across multiple boards.
  24366. + *    Functions to get and set the sc26198 global registers.
  24367.   */
  24368.  
  24369. -static int stl_mapirq(int irq)
  24370. +static int stl_sc26198getglobreg(stlport_t *portp, int regnr)
  24371.  {
  24372. -    int    rc, i;
  24373. -
  24374. -#if DEBUG
  24375. -    printk("stl_mapirq(irq=%d)\n", irq);
  24376. -#endif
  24377. +    outb(regnr, (portp->ioaddr + XP_ADDR));
  24378. +    return(inb(portp->ioaddr + XP_DATA));
  24379. +}
  24380.  
  24381. -    rc = 0;
  24382. -    for (i = 0; (i < stl_numintrs); i++) {
  24383. -        if (stl_gotintrs[i] == irq)
  24384. -            break;
  24385. -    }
  24386. -    if (i >= stl_numintrs) {
  24387. -        if (request_irq(irq, stl_intr, SA_INTERRUPT, stl_drvname, NULL) != 0) {
  24388. -            printk("STALLION: failed to register interrupt routine for irq=%d\n", irq);
  24389. -            rc = -ENODEV;
  24390. -        } else {
  24391. -            stl_gotintrs[stl_numintrs++] = irq;
  24392. -        }
  24393. -    }
  24394. -    return(rc);
  24395. +#if 0
  24396. +static void stl_sc26198setglobreg(stlport_t *portp, int regnr, int value)
  24397. +{
  24398. +    outb(regnr, (portp->ioaddr + XP_ADDR));
  24399. +    outb(value, (portp->ioaddr + XP_DATA));
  24400.  }
  24401. +#endif
  24402.  
  24403.  /*****************************************************************************/
  24404.  
  24405.  /*
  24406. - *    Try to find and initialize all the ports on a panel. We don't care
  24407. - *    what sort of board these ports are on - since the port io registers
  24408. - *    are almost identical when dealing with ports.
  24409. + *    Inbitialize the UARTs in a panel. We don't care what sort of board
  24410. + *    these ports are on - since the port io registers are almost
  24411. + *    identical when dealing with ports.
  24412.   */
  24413.  
  24414. -static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
  24415. +static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
  24416.  {
  24417. -    stlport_t    *portp;
  24418. -    unsigned int    chipmask;
  24419. -    unsigned int    gfrcr;
  24420. -    int        nrchips, uartaddr, ioaddr;
  24421. -    int        i, j;
  24422. +    int    chipmask, i;
  24423. +    int    nrchips, ioaddr;
  24424.  
  24425.  #if DEBUG
  24426. -    printk("stl_initports(panelp=%x)\n", (int) panelp);
  24427. +    printk("stl_sc26198panelinit(brdp=%x,panelp=%x)\n",
  24428. +        (int) brdp, (int) panelp);
  24429.  #endif
  24430.  
  24431.      BRDENABLE(panelp->brdnr, panelp->pagenr);
  24432. @@ -2406,773 +3999,959 @@
  24433.   *    Check that each chip is present and started up OK.
  24434.   */
  24435.      chipmask = 0;
  24436. -    nrchips = panelp->nrports / CD1400_PORTS;
  24437. -    for (i = 0; (i < nrchips); i++) {
  24438. -        if (brdp->brdtype == BRD_ECHPCI) {
  24439. -            outb((panelp->pagenr + (i >> 1)), brdp->ioctrl);
  24440. -            ioaddr = panelp->iobase;
  24441. -        } else {
  24442. -            ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1));
  24443. -        }
  24444. -        uartaddr = (i & 0x01) ? 0x080 : 0;
  24445. -        outb((GFRCR + uartaddr), ioaddr);
  24446. -        outb(0, (ioaddr + EREG_DATA));
  24447. -        outb((CCR + uartaddr), ioaddr);
  24448. -        outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
  24449. -        outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
  24450. -        outb((GFRCR + uartaddr), ioaddr);
  24451. -        for (j = 0; (j < CCR_MAXWAIT); j++) {
  24452. -            if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0)
  24453. -                break;
  24454. -        }
  24455. -        if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) {
  24456. -            printk("STALLION: cd1400 not responding, brd=%d panel=%d chip=%d\n", panelp->brdnr, panelp->panelnr, i);
  24457. -            continue;
  24458. -        }
  24459. -        chipmask |= (0x1 << i);
  24460. -        outb((PPR + uartaddr), ioaddr);
  24461. -        outb(PPR_SCALAR, (ioaddr + EREG_DATA));
  24462. -    }
  24463. +    nrchips = (panelp->nrports + 4) / SC26198_PORTS;
  24464. +    if (brdp->brdtype == BRD_ECHPCI)
  24465. +        outb(panelp->pagenr, brdp->ioctrl);
  24466.  
  24467. -/*
  24468. - *    All cd1400's are initialized (if found!). Now go through and setup
  24469. - *    each ports data structures. Also init the LIVR register of cd1400
  24470. - *    for each port.
  24471. - */
  24472. -    ioaddr = panelp->iobase;
  24473. -    for (i = 0; (i < panelp->nrports); i++) {
  24474. -        if (brdp->brdtype == BRD_ECHPCI) {
  24475. -            outb((panelp->pagenr + (i >> 3)), brdp->ioctrl);
  24476. -            ioaddr = panelp->iobase;
  24477. -        } else {
  24478. -            ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 3));
  24479. -        }
  24480. -        if ((chipmask & (0x1 << (i / 4))) == 0)
  24481. -            continue;
  24482. -        portp = (stlport_t *) stl_memalloc(sizeof(stlport_t));
  24483. -        if (portp == (stlport_t *) NULL) {
  24484. -            printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlport_t));
  24485. -            break;
  24486. -        }
  24487. -        memset(portp, 0, sizeof(stlport_t));
  24488. -        portp->magic = STL_PORTMAGIC;
  24489. -        portp->portnr = i;
  24490. -        portp->brdnr = panelp->brdnr;
  24491. -        portp->panelnr = panelp->panelnr;
  24492. -        portp->ioaddr = ioaddr;
  24493. -        portp->uartaddr = (i & 0x04) << 5;
  24494. -        portp->pagenr = panelp->pagenr + (i >> 3);
  24495. -        portp->clk = brdp->clk;
  24496. -        portp->baud_base = STL_BAUDBASE;
  24497. -        portp->close_delay = STL_CLOSEDELAY;
  24498. -        portp->closing_wait = 30 * HZ;
  24499. -        portp->normaltermios = stl_deftermios;
  24500. -        portp->callouttermios = stl_deftermios;
  24501. -        portp->tqueue.routine = stl_offintr;
  24502. -        portp->tqueue.data = portp;
  24503. -        portp->stats.brd = portp->brdnr;
  24504. -        portp->stats.panel = portp->panelnr;
  24505. -        portp->stats.port = portp->portnr;
  24506. -        stl_setreg(portp, CAR, (i & 0x03));
  24507. -        stl_setreg(portp, LIVR, (i << 3));
  24508. -        portp->hwid = stl_getreg(portp, GFRCR);
  24509. -        panelp->ports[i] = portp;
  24510. +    for (i = 0; (i < nrchips); i++) {
  24511. +        ioaddr = panelp->iobase + (i * 4); 
  24512. +        outb(SCCR, (ioaddr + XP_ADDR));
  24513. +        outb(CR_RESETALL, (ioaddr + XP_DATA));
  24514. +        outb(TSTR, (ioaddr + XP_ADDR));
  24515. +        if (inb(ioaddr + XP_DATA) != 0) {
  24516. +            printk("STALLION: sc26198 not responding, "
  24517. +                "brd=%d panel=%d chip=%d\n",
  24518. +                panelp->brdnr, panelp->panelnr, i);
  24519. +            continue;
  24520. +        }
  24521. +        chipmask |= (0x1 << i);
  24522. +        outb(GCCR, (ioaddr + XP_ADDR));
  24523. +        outb(GCCR_IVRTYPCHANACK, (ioaddr + XP_DATA));
  24524. +        outb(WDTRCR, (ioaddr + XP_ADDR));
  24525. +        outb(0xff, (ioaddr + XP_DATA));
  24526.      }
  24527.  
  24528.      BRDDISABLE(panelp->brdnr);
  24529. -    return(0);
  24530. +    return(chipmask);
  24531.  }
  24532.  
  24533.  /*****************************************************************************/
  24534.  
  24535.  /*
  24536. - *    Try to find and initialize an EasyIO board.
  24537. + *    Initialize hardware specific port registers.
  24538.   */
  24539.  
  24540. -static int stl_initeio(stlbrd_t *brdp)
  24541. +static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp)
  24542.  {
  24543. -    stlpanel_t    *panelp;
  24544. -    unsigned int    status;
  24545. -    int        rc;
  24546. -
  24547.  #if DEBUG
  24548. -    printk("stl_initeio(brdp=%x)\n", (int) brdp);
  24549. +    printk("stl_sc26198portinit(brdp=%x,panelp=%x,portp=%x)\n",
  24550. +        (int) brdp, (int) panelp, (int) portp);
  24551.  #endif
  24552.  
  24553. -    brdp->ioctrl = brdp->ioaddr1 + 1;
  24554. -    brdp->iostatus = brdp->ioaddr1 + 2;
  24555. -    brdp->clk = EIO_CLK;
  24556. +    if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) ||
  24557. +        (portp == (stlport_t *) NULL))
  24558. +        return;
  24559.  
  24560. -    status = inb(brdp->iostatus);
  24561. -    switch (status & EIO_IDBITMASK) {
  24562. -    case EIO_8PORTM:
  24563. -        brdp->clk = EIO_CLK8M;
  24564. -        /* fall thru */
  24565. -    case EIO_8PORTRS:
  24566. -    case EIO_8PORTDI:
  24567. -        brdp->nrports = 8;
  24568. +    portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4);
  24569. +    portp->uartaddr = (portp->portnr & 0x07) << 4;
  24570. +    portp->pagenr = panelp->pagenr;
  24571. +    portp->hwid = 0x1;
  24572. +
  24573. +    BRDENABLE(portp->brdnr, portp->pagenr);
  24574. +    stl_sc26198setreg(portp, IOPCR, IOPCR_SETSIGS);
  24575. +    BRDDISABLE(portp->brdnr);
  24576. +}
  24577. +
  24578. +/*****************************************************************************/
  24579. +
  24580. +/*
  24581. + *    Set up the sc26198 registers for a port based on the termios port
  24582. + *    settings.
  24583. + */
  24584. +
  24585. +static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
  24586. +{
  24587. +    stlbrd_t    *brdp;
  24588. +    unsigned long    flags;
  24589. +    unsigned int    baudrate;
  24590. +    unsigned char    mr0, mr1, mr2, clk;
  24591. +    unsigned char    imron, imroff, iopr, ipr;
  24592. +
  24593. +    mr0 = 0;
  24594. +    mr1 = 0;
  24595. +    mr2 = 0;
  24596. +    clk = 0;
  24597. +    iopr = 0;
  24598. +    imron = 0;
  24599. +    imroff = 0;
  24600. +
  24601. +    brdp = stl_brds[portp->brdnr];
  24602. +    if (brdp == (stlbrd_t *) NULL)
  24603. +        return;
  24604. +
  24605. +/*
  24606. + *    Set up the RX char ignore mask with those RX error types we
  24607. + *    can ignore.
  24608. + */
  24609. +    portp->rxignoremsk = 0;
  24610. +    if (tiosp->c_iflag & IGNPAR)
  24611. +        portp->rxignoremsk |= (SR_RXPARITY | SR_RXFRAMING |
  24612. +            SR_RXOVERRUN);
  24613. +    if (tiosp->c_iflag & IGNBRK)
  24614. +        portp->rxignoremsk |= SR_RXBREAK;
  24615. +
  24616. +    portp->rxmarkmsk = SR_RXOVERRUN;
  24617. +    if (tiosp->c_iflag & (INPCK | PARMRK))
  24618. +        portp->rxmarkmsk |= (SR_RXPARITY | SR_RXFRAMING);
  24619. +    if (tiosp->c_iflag & BRKINT)
  24620. +        portp->rxmarkmsk |= SR_RXBREAK;
  24621. +
  24622. +/*
  24623. + *    Go through the char size, parity and stop bits and set all the
  24624. + *    option register appropriately.
  24625. + */
  24626. +    switch (tiosp->c_cflag & CSIZE) {
  24627. +    case CS5:
  24628. +        mr1 |= MR1_CS5;
  24629.          break;
  24630. -    case EIO_4PORTRS:
  24631. -        brdp->nrports = 4;
  24632. +    case CS6:
  24633. +        mr1 |= MR1_CS6;
  24634. +        break;
  24635. +    case CS7:
  24636. +        mr1 |= MR1_CS7;
  24637.          break;
  24638.      default:
  24639. -        return(-ENODEV);
  24640. +        mr1 |= MR1_CS8;
  24641. +        break;
  24642. +    }
  24643. +
  24644. +    if (tiosp->c_cflag & CSTOPB)
  24645. +        mr2 |= MR2_STOP2;
  24646. +    else
  24647. +        mr2 |= MR2_STOP1;
  24648. +
  24649. +    if (tiosp->c_cflag & PARENB) {
  24650. +        if (tiosp->c_cflag & PARODD)
  24651. +            mr1 |= (MR1_PARENB | MR1_PARODD);
  24652. +        else
  24653. +            mr1 |= (MR1_PARENB | MR1_PAREVEN);
  24654. +    } else {
  24655. +        mr1 |= MR1_PARNONE;
  24656.      }
  24657.  
  24658. -    request_region(brdp->ioaddr1, 8, "serial(EIO)");
  24659. +    mr1 |= MR1_ERRBLOCK;
  24660. +
  24661. +/*
  24662. + *    Set the RX FIFO threshold at 8 chars. This gives a bit of breathing
  24663. + *    space for hardware flow control and the like. This should be set to
  24664. + *    VMIN.
  24665. + */
  24666. +    mr2 |= MR2_RXFIFOHALF;
  24667.  
  24668.  /*
  24669. - *    Check that the supplied IRQ is good and then use it to setup the
  24670. - *    programmable interrupt bits on EIO board. Also set the edge/level
  24671. - *    triggered interrupt bit.
  24672. + *    Calculate the baud rate timers. For now we will just assume that
  24673. + *    the input and output baud are the same. The sc26198 has a fixed
  24674. + *    baud rate table, so only discrete baud rates possible.
  24675.   */
  24676. -    if ((brdp->irq < 0) || (brdp->irq > 15) ||
  24677. -            (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
  24678. -        printk("STALLION: invalid irq=%d for brd=%d\n", brdp->irq, brdp->brdnr);
  24679. -        return(-EINVAL);
  24680. +    baudrate = tiosp->c_cflag & CBAUD;
  24681. +    if (baudrate & CBAUDEX) {
  24682. +        baudrate &= ~CBAUDEX;
  24683. +        if ((baudrate < 1) || (baudrate > 5))
  24684. +            tiosp->c_cflag &= ~CBAUDEX;
  24685. +        else
  24686. +            baudrate += 15;
  24687. +    }
  24688. +    baudrate = stl_baudrates[baudrate];
  24689. +    if ((tiosp->c_cflag & CBAUD) == B38400) {
  24690. +        if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
  24691. +            baudrate = 57600;
  24692. +        else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
  24693. +            baudrate = 115200;
  24694. +        else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
  24695. +            baudrate = (portp->baud_base / portp->custom_divisor);
  24696.      }
  24697. -    outb((stl_vecmap[brdp->irq] | ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)), brdp->ioctrl);
  24698. +    if (baudrate > STL_SC26198MAXBAUD)
  24699. +        baudrate = STL_SC26198MAXBAUD;
  24700.  
  24701. -    panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t));
  24702. -    if (panelp == (stlpanel_t *) NULL) {
  24703. -        printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlpanel_t));
  24704. -        return(-ENOMEM);
  24705. +    if (baudrate > 0) {
  24706. +        for (clk = 0; (clk < SC26198_NRBAUDS); clk++) {
  24707. +            if (baudrate <= sc26198_baudtable[clk])
  24708. +                break;
  24709. +        }
  24710.      }
  24711. -    memset(panelp, 0, sizeof(stlpanel_t));
  24712.  
  24713. -    panelp->magic = STL_PANELMAGIC;
  24714. -    panelp->brdnr = brdp->brdnr;
  24715. -    panelp->panelnr = 0;
  24716. -    panelp->nrports = brdp->nrports;
  24717. -    panelp->iobase = brdp->ioaddr1;
  24718. -    panelp->hwid = status;
  24719. -    brdp->panels[0] = panelp;
  24720. -    brdp->nrpanels = 1;
  24721. -    brdp->state |= BRD_FOUND;
  24722. -    brdp->hwid = status;
  24723. -    rc = stl_mapirq(brdp->irq);
  24724. -    return(rc);
  24725. +/*
  24726. + *    Check what form of modem signaling is required and set it up.
  24727. + */
  24728. +    if (tiosp->c_cflag & CLOCAL) {
  24729. +        portp->flags &= ~ASYNC_CHECK_CD;
  24730. +    } else {
  24731. +        iopr |= IOPR_DCDCOS;
  24732. +        imron |= IR_IOPORT;
  24733. +        portp->flags |= ASYNC_CHECK_CD;
  24734. +    }
  24735. +
  24736. +/*
  24737. + *    Setup sc26198 enhanced modes if we can. In particular we want to
  24738. + *    handle as much of the flow control as possible automatically. As
  24739. + *    well as saving a few CPU cycles it will also greatly improve flow
  24740. + *    control reliability.
  24741. + */
  24742. +    if (tiosp->c_iflag & IXON) {
  24743. +        mr0 |= MR0_SWFTX | MR0_SWFT;
  24744. +        imron |= IR_XONXOFF;
  24745. +    } else {
  24746. +        imroff |= IR_XONXOFF;
  24747. +    }
  24748. +    if (tiosp->c_iflag & IXOFF)
  24749. +        mr0 |= MR0_SWFRX;
  24750. +
  24751. +    if (tiosp->c_cflag & CRTSCTS) {
  24752. +        mr2 |= MR2_AUTOCTS;
  24753. +        mr1 |= MR1_AUTORTS;
  24754. +    }
  24755. +
  24756. +/*
  24757. + *    All sc26198 register values calculated so go through and set
  24758. + *    them all up.
  24759. + */
  24760. +
  24761. +#if DEBUG
  24762. +    printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
  24763. +        portp->portnr, portp->panelnr, portp->brdnr);
  24764. +    printk("    mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk);
  24765. +    printk("    iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff);
  24766. +    printk("    schr1=%x schr2=%x schr3=%x schr4=%x\n",
  24767. +        tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP],
  24768. +        tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
  24769. +#endif
  24770. +
  24771. +    save_flags(flags);
  24772. +    cli();
  24773. +    BRDENABLE(portp->brdnr, portp->pagenr);
  24774. +    stl_sc26198setreg(portp, IMR, 0);
  24775. +    stl_sc26198updatereg(portp, MR0, mr0);
  24776. +    stl_sc26198updatereg(portp, MR1, mr1);
  24777. +    stl_sc26198setreg(portp, SCCR, CR_RXERRBLOCK);
  24778. +    stl_sc26198updatereg(portp, MR2, mr2);
  24779. +    stl_sc26198updatereg(portp, IOPIOR,
  24780. +        ((stl_sc26198getreg(portp, IOPIOR) & ~IPR_CHANGEMASK) | iopr));
  24781. +
  24782. +    if (baudrate > 0) {
  24783. +        stl_sc26198setreg(portp, TXCSR, clk);
  24784. +        stl_sc26198setreg(portp, RXCSR, clk);
  24785. +    }
  24786. +
  24787. +    stl_sc26198setreg(portp, XONCR, tiosp->c_cc[VSTART]);
  24788. +    stl_sc26198setreg(portp, XOFFCR, tiosp->c_cc[VSTOP]);
  24789. +
  24790. +    ipr = stl_sc26198getreg(portp, IPR);
  24791. +    if (ipr & IPR_DCD)
  24792. +        portp->sigs &= ~TIOCM_CD;
  24793. +    else
  24794. +        portp->sigs |= TIOCM_CD;
  24795. +
  24796. +    portp->imr = (portp->imr & ~imroff) | imron;
  24797. +    stl_sc26198setreg(portp, IMR, portp->imr);
  24798. +    BRDDISABLE(portp->brdnr);
  24799. +    restore_flags(flags);
  24800.  }
  24801.  
  24802.  /*****************************************************************************/
  24803.  
  24804.  /*
  24805. - *    Try to find an ECH board and initialize it. This code is capable of
  24806. - *    dealing with all types of ECH board.
  24807. + *    Set the state of the DTR and RTS signals.
  24808.   */
  24809.  
  24810. -static int stl_initech(stlbrd_t *brdp)
  24811. +static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts)
  24812.  {
  24813. -    stlpanel_t    *panelp;
  24814. -    unsigned int    status, nxtid;
  24815. -    int        panelnr, ioaddr, i;
  24816. +    unsigned char    iopioron, iopioroff;
  24817. +    unsigned long    flags;
  24818.  
  24819.  #if DEBUG
  24820. -    printk("stl_initech(brdp=%x)\n", (int) brdp);
  24821. +    printk("stl_sc26198setsignals(portp=%x,dtr=%d,rts=%d)\n",
  24822. +        (int) portp, dtr, rts);
  24823.  #endif
  24824.  
  24825. -    status = 0;
  24826. +    iopioron = 0;
  24827. +    iopioroff = 0;
  24828. +    if (dtr == 0)
  24829. +        iopioroff |= IPR_DTR;
  24830. +    else if (dtr > 0)
  24831. +        iopioron |= IPR_DTR;
  24832. +    if (rts == 0)
  24833. +        iopioroff |= IPR_RTS;
  24834. +    else if (rts > 0)
  24835. +        iopioron |= IPR_RTS;
  24836. +
  24837. +    save_flags(flags);
  24838. +    cli();
  24839. +    BRDENABLE(portp->brdnr, portp->pagenr);
  24840. +    stl_sc26198setreg(portp, IOPIOR,
  24841. +        ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron));
  24842. +    BRDDISABLE(portp->brdnr);
  24843. +    restore_flags(flags);
  24844. +}
  24845. +
  24846. +/*****************************************************************************/
  24847.  
  24848.  /*
  24849. - *    Set up the initial board register contents for boards. This varies a
  24850. - *    bit between the different board types. So we need to handle each
  24851. - *    separately. Also do a check that the supplied IRQ is good.
  24852. + *    Return the state of the signals.
  24853.   */
  24854. -    if (brdp->brdtype == BRD_ECH) {
  24855. -        brdp->ioctrl = brdp->ioaddr1 + 1;
  24856. -        brdp->iostatus = brdp->ioaddr1 + 1;
  24857. -        status = inb(brdp->iostatus);
  24858. -        if ((status & ECH_IDBITMASK) != ECH_ID)
  24859. -            return(-ENODEV);
  24860.  
  24861. -        if ((brdp->irq < 0) || (brdp->irq > 15) ||
  24862. -                (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
  24863. -            printk("STALLION: invalid irq=%d for brd=%d\n", brdp->irq, brdp->brdnr);
  24864. -            return(-EINVAL);
  24865. -        }
  24866. -        status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1);
  24867. -        status |= (stl_vecmap[brdp->irq] << 1);
  24868. -        outb((status | ECH_BRDRESET), brdp->ioaddr1);
  24869. -        brdp->ioctrlval = ECH_INTENABLE | ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE);
  24870. -        outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
  24871. -        outb(status, brdp->ioaddr1);
  24872. +static int stl_sc26198getsignals(stlport_t *portp)
  24873. +{
  24874. +    unsigned char    ipr;
  24875. +    unsigned long    flags;
  24876. +    int        sigs;
  24877.  
  24878. -        request_region(brdp->ioaddr1, 2, "serial(EC8/32)");
  24879. -        request_region(brdp->ioaddr2, 32, "serial(EC8/32-secondary)");
  24880. -    } else if (brdp->brdtype == BRD_ECHMC) {
  24881. -        brdp->ioctrl = brdp->ioaddr1 + 0x20;
  24882. -        brdp->iostatus = brdp->ioctrl;
  24883. -        status = inb(brdp->iostatus);
  24884. -        if ((status & ECH_IDBITMASK) != ECH_ID)
  24885. -            return(-ENODEV);
  24886. +#if DEBUG
  24887. +    printk("stl_sc26198getsignals(portp=%x)\n", (int) portp);
  24888. +#endif
  24889.  
  24890. -        if ((brdp->irq < 0) || (brdp->irq > 15) ||
  24891. -                (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
  24892. -            printk("STALLION: invalid irq=%d for brd=%d\n", brdp->irq, brdp->brdnr);
  24893. -            return(-EINVAL);
  24894. -        }
  24895. -        outb(ECHMC_BRDRESET, brdp->ioctrl);
  24896. -        outb(ECHMC_INTENABLE, brdp->ioctrl);
  24897. +    save_flags(flags);
  24898. +    cli();
  24899. +    BRDENABLE(portp->brdnr, portp->pagenr);
  24900. +    ipr = stl_sc26198getreg(portp, IPR);
  24901. +    BRDDISABLE(portp->brdnr);
  24902. +    restore_flags(flags);
  24903.  
  24904. -        request_region(brdp->ioaddr1, 64, "serial(EC8/32-MC)");
  24905. -    } else if (brdp->brdtype == BRD_ECHPCI) {
  24906. -        brdp->ioctrl = brdp->ioaddr1 + 2;
  24907. -        request_region(brdp->ioaddr1, 4, "serial(EC8/32-PCI)");
  24908. -        request_region(brdp->ioaddr2, 8, "serial(EC8/32-PCI-secondary)");
  24909. -    }
  24910. +    sigs = 0;
  24911. +    sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD;
  24912. +    sigs |= (ipr & IPR_CTS) ? 0 : TIOCM_CTS;
  24913. +    sigs |= (ipr & IPR_DTR) ? 0: TIOCM_DTR;
  24914. +    sigs |= (ipr & IPR_RTS) ? 0: TIOCM_RTS;
  24915. +    sigs |= TIOCM_DSR;
  24916. +    return(sigs);
  24917. +}
  24918.  
  24919. -    brdp->clk = ECH_CLK;
  24920. -    brdp->hwid = status;
  24921. +/*****************************************************************************/
  24922.  
  24923.  /*
  24924. - *    Scan through the secondary io address space looking for panels.
  24925. - *    As we find'em allocate and initialize panel structures for each.
  24926. + *    Enable/Disable the Transmitter and/or Receiver.
  24927.   */
  24928. -    ioaddr = brdp->ioaddr2;
  24929. -    panelnr = 0;
  24930. -    nxtid = 0;
  24931.  
  24932. -    for (i = 0; (i < STL_MAXPANELS); i++) {
  24933. -        if (brdp->brdtype == BRD_ECHPCI) {
  24934. -            outb(nxtid, brdp->ioctrl);
  24935. -            ioaddr = brdp->ioaddr2;
  24936. -        }
  24937. -        status = inb(ioaddr + ECH_PNLSTATUS);
  24938. -        if ((status & ECH_PNLIDMASK) != nxtid)
  24939. -            break;
  24940. -        panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t));
  24941. -        if (panelp == (stlpanel_t *) NULL) {
  24942. -            printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlpanel_t));
  24943. -            break;
  24944. -        }
  24945. -        memset(panelp, 0, sizeof(stlpanel_t));
  24946. -        panelp->magic = STL_PANELMAGIC;
  24947. -        panelp->brdnr = brdp->brdnr;
  24948. -        panelp->panelnr = panelnr;
  24949. -        panelp->iobase = ioaddr;
  24950. -        panelp->pagenr = nxtid;
  24951. -        panelp->hwid = status;
  24952. -        if (status & ECH_PNL16PORT) {
  24953. -            if ((brdp->nrports + 16) > 32)
  24954. -                break;
  24955. -            panelp->nrports = 16;
  24956. -            panelp->ackmask = 0x80;
  24957. -            brdp->nrports += 16;
  24958. -            ioaddr += (EREG_BANKSIZE * 2);
  24959. -            nxtid += 2;
  24960. -        } else {
  24961. -            panelp->nrports = 8;
  24962. -            panelp->ackmask = 0xc0;
  24963. -            brdp->nrports += 8;
  24964. -            ioaddr += EREG_BANKSIZE;
  24965. -            nxtid++;
  24966. -        }
  24967. -        brdp->panels[panelnr++] = panelp;
  24968. -        brdp->nrpanels++;
  24969. -        if (ioaddr >= (brdp->ioaddr2 + 0x20))
  24970. -            break;
  24971. -    }
  24972. +static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx)
  24973. +{
  24974. +    unsigned char    ccr;
  24975. +    unsigned long    flags;
  24976.  
  24977. -    if (brdp->brdtype == BRD_ECH)
  24978. -        outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
  24979. +#if DEBUG
  24980. +    printk("stl_sc26198enablerxtx(portp=%x,rx=%d,tx=%d)\n",
  24981. +        (int) portp, rx, tx);
  24982. +#endif
  24983.  
  24984. -    brdp->state |= BRD_FOUND;
  24985. -    i = stl_mapirq(brdp->irq);
  24986. -    return(i);
  24987. +    ccr = portp->crenable;
  24988. +    if (tx == 0)
  24989. +        ccr &= ~CR_TXENABLE;
  24990. +    else if (tx > 0)
  24991. +        ccr |= CR_TXENABLE;
  24992. +    if (rx == 0)
  24993. +        ccr &= ~CR_RXENABLE;
  24994. +    else if (rx > 0)
  24995. +        ccr |= CR_RXENABLE;
  24996. +
  24997. +    save_flags(flags);
  24998. +    cli();
  24999. +    BRDENABLE(portp->brdnr, portp->pagenr);
  25000. +    stl_sc26198setreg(portp, SCCR, ccr);
  25001. +    BRDDISABLE(portp->brdnr);
  25002. +    portp->crenable = ccr;
  25003. +    restore_flags(flags);
  25004.  }
  25005.  
  25006.  /*****************************************************************************/
  25007.  
  25008.  /*
  25009. - *    Initialize and configure the specified board.
  25010. - *    Scan through all the boards in the configuration and see what we
  25011. - *    can find. Handle EIO and the ECH boards a little differently here
  25012. - *    since the initial search and setup is too different.
  25013. + *    Start/stop the Transmitter and/or Receiver.
  25014.   */
  25015.  
  25016. -static int stl_brdinit(stlbrd_t *brdp)
  25017. +static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx)
  25018.  {
  25019. -    int    i;
  25020. +    unsigned char    imr;
  25021. +    unsigned long    flags;
  25022.  
  25023.  #if DEBUG
  25024. -    printk("stl_brdinit(brdp=%x)\n", (int) brdp);
  25025. +    printk("stl_sc26198startrxtx(portp=%x,rx=%d,tx=%d)\n",
  25026. +        (int) portp, rx, tx);
  25027.  #endif
  25028.  
  25029. -    switch (brdp->brdtype) {
  25030. -    case BRD_EASYIO:
  25031. -        stl_initeio(brdp);
  25032. -        break;
  25033. -    case BRD_ECH:
  25034. -    case BRD_ECHMC:
  25035. -    case BRD_ECHPCI:
  25036. -        stl_initech(brdp);
  25037. -        break;
  25038. -    default:
  25039. -        printk("STALLION: unit=%d is unknown board type=%d\n", brdp->brdnr, brdp->brdtype);
  25040. -        return(ENODEV);
  25041. -    }
  25042. -
  25043. -    stl_brds[brdp->brdnr] = brdp;
  25044. -    if ((brdp->state & BRD_FOUND) == 0) {
  25045. -        printk("STALLION: %s board not found, unit=%d io=%x irq=%d\n", stl_brdnames[brdp->brdtype], brdp->brdnr, brdp->ioaddr1, brdp->irq);
  25046. -        return(ENODEV);
  25047. -    }
  25048. -
  25049. -    for (i = 0; (i < STL_MAXPANELS); i++)
  25050. -        if (brdp->panels[i] != (stlpanel_t *) NULL)
  25051. -            stl_initports(brdp, brdp->panels[i]);
  25052. +    imr = portp->imr;
  25053. +    if (tx == 0)
  25054. +        imr &= ~IR_TXRDY;
  25055. +    else if (tx == 1)
  25056. +        imr |= IR_TXRDY;
  25057. +    if (rx == 0)
  25058. +        imr &= ~(IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG);
  25059. +    else if (rx > 0)
  25060. +        imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG;
  25061.  
  25062. -    printk("STALLION: %s found, unit=%d io=%x irq=%d nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype], brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels, brdp->nrports);
  25063. -    return(0);
  25064. +    save_flags(flags);
  25065. +    cli();
  25066. +    BRDENABLE(portp->brdnr, portp->pagenr);
  25067. +    stl_sc26198setreg(portp, IMR, imr);
  25068. +    BRDDISABLE(portp->brdnr);
  25069. +    portp->imr = imr;
  25070. +    if (tx > 0)
  25071. +        set_bit(ASYI_TXBUSY, &portp->istate);
  25072. +    restore_flags(flags);
  25073.  }
  25074.  
  25075.  /*****************************************************************************/
  25076.  
  25077.  /*
  25078. - *    Find any ECH-PCI boards that might be installed. Initialize each
  25079. - *    one as it is found.
  25080. + *    Disable all interrupts from this port.
  25081.   */
  25082.  
  25083. -#ifdef    CONFIG_PCI
  25084. -
  25085. -static int stl_findpcibrds()
  25086. +static void stl_sc26198disableintrs(stlport_t *portp)
  25087.  {
  25088. -    stlbrd_t    *brdp;
  25089. -    unsigned char    busnr, devnr, irq;
  25090. -    unsigned short    class;
  25091. -    unsigned int    ioaddr;
  25092. -    int        i, rc;
  25093. +    unsigned long    flags;
  25094.  
  25095.  #if DEBUG
  25096. -    printk("stl_findpcibrds()\n");
  25097. +    printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp);
  25098.  #endif
  25099.  
  25100. -    if (pcibios_present()) {
  25101. -        for (i = 0; (i < STL_MAXBRDS); i++) {
  25102. -            if (pcibios_find_device(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, i, &busnr, &devnr))
  25103. -                break;
  25104. -
  25105. -/*
  25106. - *            Found a device on the PCI bus that has our vendor and
  25107. - *            device ID. Need to check now that it is really us.
  25108. - */
  25109. -            if ((rc = pcibios_read_config_word(busnr, devnr, PCI_CLASS_DEVICE, &class))) {
  25110. -                printk("STALLION: failed to read class type from PCI board, errno=%x\n", rc);
  25111. -                continue;
  25112. -            }
  25113. -            if (class == PCI_CLASS_STORAGE_IDE)
  25114. -                continue;
  25115. -
  25116. -            if (stl_nrbrds >= STL_MAXBRDS) {
  25117. -                printk("STALLION: too many boards found, maximum supported %d\n", STL_MAXBRDS);
  25118. -                break;
  25119. -            }
  25120. +    save_flags(flags);
  25121. +    cli();
  25122. +    BRDENABLE(portp->brdnr, portp->pagenr);
  25123. +    portp->imr = 0;
  25124. +    stl_sc26198setreg(portp, IMR, 0);
  25125. +    BRDDISABLE(portp->brdnr);
  25126. +    restore_flags(flags);
  25127. +}
  25128.  
  25129. -/*
  25130. - *            We have a Stallion board. Allocate a board structure
  25131. - *            and initialize it. Read its IO and IRQ resources
  25132. - *            from conf space.
  25133. - */
  25134. -            brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t));
  25135. -            if (brdp == (stlbrd_t *) NULL) {
  25136. -                printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlbrd_t));
  25137. -                return(-ENOMEM);
  25138. -            }
  25139. -            memset(brdp, 0, sizeof(stlbrd_t));
  25140. -            brdp->magic = STL_BOARDMAGIC;
  25141. -            brdp->brdnr = stl_nrbrds++;
  25142. -            brdp->brdtype = BRD_ECHPCI;
  25143. +/*****************************************************************************/
  25144.  
  25145. -            if ((rc = pcibios_read_config_dword(busnr, devnr, PCI_BASE_ADDRESS_0, &ioaddr))) {
  25146. -                printk("STALLION: failed to read BAR register from PCI board, errno=%x\n", rc);
  25147. -                continue;
  25148. -            }
  25149. -            brdp->ioaddr2 = (ioaddr & PCI_BASE_ADDRESS_IO_MASK);
  25150. +static void stl_sc26198sendbreak(stlport_t *portp, long len)
  25151. +{
  25152. +    unsigned long    flags;
  25153.  
  25154. -            if ((rc = pcibios_read_config_dword(busnr, devnr, PCI_BASE_ADDRESS_1, &ioaddr))) {
  25155. -                printk("STALLION: failed to read BAR register from PCI board, errno=%x\n", rc);
  25156. -                continue;
  25157. -            }
  25158. -            brdp->ioaddr1 = (ioaddr & PCI_BASE_ADDRESS_IO_MASK);
  25159.  #if DEBUG
  25160. -            printk("%s(%d): BAR0=%x BAR1=%x\n", __FILE__, __LINE__, brdp->ioaddr2, brdp->ioaddr1);
  25161. +    printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp,
  25162. +        (int) len);
  25163.  #endif
  25164.  
  25165. -            if ((rc = pcibios_read_config_byte(busnr, devnr, PCI_INTERRUPT_LINE, &irq))) {
  25166. -                printk("STALLION: failed to read BAR register from PCI board, errno=%x\n", rc);
  25167. -                continue;
  25168. -            }
  25169. -            brdp->irq = irq;
  25170. +    current->state = TASK_INTERRUPTIBLE;
  25171. +    current->timeout = jiffies + (len / (1000 / HZ));
  25172.  
  25173. -            stl_brdinit(brdp);
  25174. -        }
  25175. -    }
  25176. +    save_flags(flags);
  25177. +    cli();
  25178. +    BRDENABLE(portp->brdnr, portp->pagenr);
  25179. +    stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK);
  25180. +    BRDDISABLE(portp->brdnr);
  25181. +    portp->stats.txbreaks++;
  25182.  
  25183. -    return(0);
  25184. -}
  25185. +    schedule();
  25186.  
  25187. -#endif
  25188. +    BRDENABLE(portp->brdnr, portp->pagenr);
  25189. +    stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK);
  25190. +    BRDDISABLE(portp->brdnr);
  25191. +    restore_flags(flags);
  25192. +}
  25193.  
  25194.  /*****************************************************************************/
  25195.  
  25196.  /*
  25197. - *    Scan through all the boards in the configuration and see what we
  25198. - *    can find. Handle EIO and the ECH boards a little differently here
  25199. - *    since the initial search and setup is too different.
  25200. + *    Take flow control actions...
  25201.   */
  25202.  
  25203. -static int stl_initbrds()
  25204. +static void stl_sc26198flowctrl(stlport_t *portp, int state)
  25205.  {
  25206. -    stlbrd_t    *brdp;
  25207. -    stlconf_t    *confp;
  25208. -    int        i;
  25209. +    struct tty_struct    *tty;
  25210. +    unsigned long        flags;
  25211. +    unsigned char        mr0;
  25212.  
  25213.  #if DEBUG
  25214. -    printk("stl_initbrds()\n");
  25215. +    printk("stl_sc26198flowctrl(portp=%x,state=%x)\n", (int) portp, state);
  25216.  #endif
  25217.  
  25218. -    if (stl_nrbrds > STL_MAXBRDS) {
  25219. -        printk("STALLION: too many boards in configuration table, truncating to %d\n", STL_MAXBRDS);
  25220. -        stl_nrbrds = STL_MAXBRDS;
  25221. -    }
  25222. +    if (portp == (stlport_t *) NULL)
  25223. +        return;
  25224. +    tty = portp->tty;
  25225. +    if (tty == (struct tty_struct *) NULL)
  25226. +        return;
  25227.  
  25228. -/*
  25229. - *    Firstly scan the list of static boards configured. Allocate
  25230. - *    resources and initialize the boards as found.
  25231. - */
  25232. -    for (i = 0; (i < stl_nrbrds); i++) {
  25233. -        confp = &stl_brdconf[i];
  25234. -        brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t));
  25235. -        if (brdp == (stlbrd_t *) NULL) {
  25236. -            printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlbrd_t));
  25237. -            return(-ENOMEM);
  25238. -        }
  25239. -        memset(brdp, 0, sizeof(stlbrd_t));
  25240. +    save_flags(flags);
  25241. +    cli();
  25242. +    BRDENABLE(portp->brdnr, portp->pagenr);
  25243.  
  25244. -        brdp->magic = STL_BOARDMAGIC;
  25245. -        brdp->brdnr = i;
  25246. -        brdp->brdtype = confp->brdtype;
  25247. -        brdp->ioaddr1 = confp->ioaddr1;
  25248. -        brdp->ioaddr2 = confp->ioaddr2;
  25249. -        brdp->irq = confp->irq;
  25250. -        brdp->irqtype = confp->irqtype;
  25251. -        stl_brdinit(brdp);
  25252. +    if (state) {
  25253. +        if (tty->termios->c_iflag & IXOFF) {
  25254. +            mr0 = stl_sc26198getreg(portp, MR0);
  25255. +            stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
  25256. +            stl_sc26198setreg(portp, SCCR, CR_TXSENDXON);
  25257. +            mr0 |= MR0_SWFRX;
  25258. +            portp->stats.rxxon++;
  25259. +            stl_sc26198wait(portp);
  25260. +            stl_sc26198setreg(portp, MR0, mr0);
  25261. +        }
  25262. +/*
  25263. + *        Question: should we return RTS to what it was before? It may
  25264. + *        have been set by an ioctl... Suppose not, since if you have
  25265. + *        hardware flow control set then it is pretty silly to go and
  25266. + *        set the RTS line by hand.
  25267. + */
  25268. +        if (tty->termios->c_cflag & CRTSCTS) {
  25269. +            stl_sc26198setreg(portp, MR1,
  25270. +                (stl_sc26198getreg(portp, MR1) | MR1_AUTORTS));
  25271. +            stl_sc26198setreg(portp, IOPIOR,
  25272. +                (stl_sc26198getreg(portp, IOPIOR) | IOPR_RTS));
  25273. +            portp->stats.rxrtson++;
  25274. +        }
  25275. +    } else {
  25276. +        if (tty->termios->c_iflag & IXOFF) {
  25277. +            mr0 = stl_sc26198getreg(portp, MR0);
  25278. +            stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
  25279. +            stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF);
  25280. +            mr0 &= ~MR0_SWFRX;
  25281. +            portp->stats.rxxoff++;
  25282. +            stl_sc26198wait(portp);
  25283. +            stl_sc26198setreg(portp, MR0, mr0);
  25284. +        }
  25285. +        if (tty->termios->c_cflag & CRTSCTS) {
  25286. +            stl_sc26198setreg(portp, MR1,
  25287. +                (stl_sc26198getreg(portp, MR1) & ~MR1_AUTORTS));
  25288. +            stl_sc26198setreg(portp, IOPIOR,
  25289. +                (stl_sc26198getreg(portp, IOPIOR) & ~IOPR_RTS));
  25290. +            portp->stats.rxrtsoff++;
  25291. +        }
  25292.      }
  25293.  
  25294. -#ifdef CONFIG_PCI
  25295. -/*
  25296. - *    If the PCI BIOS support is compiled in then let's go looking for
  25297. - *    ECH-PCI boards.
  25298. - */
  25299. -    stl_findpcibrds();
  25300. -#endif
  25301. -
  25302. -    return(0);
  25303. +    BRDDISABLE(portp->brdnr);
  25304. +    restore_flags(flags);
  25305.  }
  25306.  
  25307.  /*****************************************************************************/
  25308.  
  25309.  /*
  25310. - *    Return the board stats structure to user app.
  25311. + *    Send a flow control character.
  25312.   */
  25313.  
  25314. -static int stl_getbrdstats(combrd_t *bp)
  25315. +static void stl_sc26198sendflow(stlport_t *portp, int state)
  25316.  {
  25317. -    stlbrd_t    *brdp;
  25318. -    stlpanel_t    *panelp;
  25319. -    int        i;
  25320. +    struct tty_struct    *tty;
  25321. +    unsigned long        flags;
  25322. +    unsigned char        mr0;
  25323.  
  25324. -    memcpy_fromfs(&stl_brdstats, bp, sizeof(combrd_t));
  25325. -    if (stl_brdstats.brd >= STL_MAXBRDS)
  25326. -        return(-ENODEV);
  25327. -    brdp = stl_brds[stl_brdstats.brd];
  25328. -    if (brdp == (stlbrd_t *) NULL)
  25329. -        return(-ENODEV);
  25330. +#if DEBUG
  25331. +    printk("stl_sc26198sendflow(portp=%x,state=%x)\n", (int) portp, state);
  25332. +#endif
  25333.  
  25334. -    memset(&stl_brdstats, 0, sizeof(combrd_t));
  25335. -    stl_brdstats.brd = brdp->brdnr;
  25336. -    stl_brdstats.type = brdp->brdtype;
  25337. -    stl_brdstats.hwid = brdp->hwid;
  25338. -    stl_brdstats.state = brdp->state;
  25339. -    stl_brdstats.ioaddr = brdp->ioaddr1;
  25340. -    stl_brdstats.ioaddr2 = brdp->ioaddr2;
  25341. -    stl_brdstats.irq = brdp->irq;
  25342. -    stl_brdstats.nrpanels = brdp->nrpanels;
  25343. -    stl_brdstats.nrports = brdp->nrports;
  25344. -    for (i = 0; (i < brdp->nrpanels); i++) {
  25345. -        panelp = brdp->panels[i];
  25346. -        stl_brdstats.panels[i].panel = i;
  25347. -        stl_brdstats.panels[i].hwid = panelp->hwid;
  25348. -        stl_brdstats.panels[i].nrports = panelp->nrports;
  25349. -    }
  25350. +    if (portp == (stlport_t *) NULL)
  25351. +        return;
  25352. +    tty = portp->tty;
  25353. +    if (tty == (struct tty_struct *) NULL)
  25354. +        return;
  25355.  
  25356. -    memcpy_tofs(bp, &stl_brdstats, sizeof(combrd_t));
  25357. -    return(0);
  25358. +    save_flags(flags);
  25359. +    cli();
  25360. +    BRDENABLE(portp->brdnr, portp->pagenr);
  25361. +    if (state) {
  25362. +        mr0 = stl_sc26198getreg(portp, MR0);
  25363. +        stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
  25364. +        stl_sc26198setreg(portp, SCCR, CR_TXSENDXON);
  25365. +        mr0 |= MR0_SWFRX;
  25366. +        portp->stats.rxxon++;
  25367. +        stl_sc26198wait(portp);
  25368. +        stl_sc26198setreg(portp, MR0, mr0);
  25369. +    } else {
  25370. +        mr0 = stl_sc26198getreg(portp, MR0);
  25371. +        stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
  25372. +        stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF);
  25373. +        mr0 &= ~MR0_SWFRX;
  25374. +        portp->stats.rxxoff++;
  25375. +        stl_sc26198wait(portp);
  25376. +        stl_sc26198setreg(portp, MR0, mr0);
  25377. +    }
  25378. +    BRDDISABLE(portp->brdnr);
  25379. +    restore_flags(flags);
  25380.  }
  25381.  
  25382.  /*****************************************************************************/
  25383.  
  25384. -/*
  25385. - *    Resolve the referenced port number into a port struct pointer.
  25386. - */
  25387. -
  25388. -static stlport_t *stl_getport(int brdnr, int panelnr, int portnr)
  25389. +static void stl_sc26198flush(stlport_t *portp)
  25390.  {
  25391. -    stlbrd_t    *brdp;
  25392. -    stlpanel_t    *panelp;
  25393. +    unsigned long    flags;
  25394.  
  25395. -    if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
  25396. -        return((stlport_t *) NULL);
  25397. -    brdp = stl_brds[brdnr];
  25398. -    if (brdp == (stlbrd_t *) NULL)
  25399. -        return((stlport_t *) NULL);
  25400. -    if ((panelnr < 0) || (panelnr >= brdp->nrpanels))
  25401. -        return((stlport_t *) NULL);
  25402. -    panelp = brdp->panels[panelnr];
  25403. -    if (panelp == (stlpanel_t *) NULL)
  25404. -        return((stlport_t *) NULL);
  25405. -    if ((portnr < 0) || (portnr >= panelp->nrports))
  25406. -        return((stlport_t *) NULL);
  25407. -    return(panelp->ports[portnr]);
  25408. +#if DEBUG
  25409. +    printk("stl_sc26198flush(portp=%x)\n", (int) portp);
  25410. +#endif
  25411. +
  25412. +    if (portp == (stlport_t *) NULL)
  25413. +        return;
  25414. +
  25415. +    save_flags(flags);
  25416. +    cli();
  25417. +    BRDENABLE(portp->brdnr, portp->pagenr);
  25418. +    stl_sc26198setreg(portp, SCCR, CR_TXRESET);
  25419. +    stl_sc26198setreg(portp, SCCR, portp->crenable);
  25420. +    BRDDISABLE(portp->brdnr);
  25421. +    portp->tx.tail = portp->tx.head;
  25422. +    restore_flags(flags);
  25423.  }
  25424.  
  25425.  /*****************************************************************************/
  25426.  
  25427.  /*
  25428. - *    Return the port stats structure to user app. A NULL port struct
  25429. - *    pointer passed in means that we need to find out from the app
  25430. - *    what port to get stats for (used through board control device).
  25431. + *    Return the current state of data flow on this port. This is only
  25432. + *    really interresting when determining if data has fully completed
  25433. + *    transmission or not... The sc26198 interrupt scheme cannot
  25434. + *    determine when all data has actually drained, so we need to
  25435. + *    check the port statusy register to be sure.
  25436.   */
  25437.  
  25438. -static int stl_getportstats(stlport_t *portp, comstats_t *cp)
  25439. +static int stl_sc26198datastate(stlport_t *portp)
  25440.  {
  25441. -    unsigned char    *head, *tail;
  25442.      unsigned long    flags;
  25443. +    unsigned char    sr;
  25444.  
  25445. -    if (portp == (stlport_t *) NULL) {
  25446. -        memcpy_fromfs(&stl_comstats, cp, sizeof(comstats_t));
  25447. -        portp = stl_getport(stl_comstats.brd, stl_comstats.panel, stl_comstats.port);
  25448. -        if (portp == (stlport_t *) NULL)
  25449. -            return(-ENODEV);
  25450. -    }
  25451. -
  25452. -    portp->stats.state = portp->istate;
  25453. -    portp->stats.flags = portp->flags;
  25454. -    portp->stats.hwid = portp->hwid;
  25455. -
  25456. -    portp->stats.ttystate = 0;
  25457. -    portp->stats.cflags = 0;
  25458. -    portp->stats.iflags = 0;
  25459. -    portp->stats.oflags = 0;
  25460. -    portp->stats.lflags = 0;
  25461. -    portp->stats.rxbuffered = 0;
  25462. +#if DEBUG
  25463. +    printk("stl_sc26198datastate(portp=%x)\n", (int) portp);
  25464. +#endif
  25465. +
  25466. +    if (portp == (stlport_t *) NULL)
  25467. +        return(0);
  25468. +    if (test_bit(ASYI_TXBUSY, &portp->istate))
  25469. +        return(1);
  25470.  
  25471.      save_flags(flags);
  25472.      cli();
  25473. -    if (portp->tty != (struct tty_struct *) NULL) {
  25474. -        if (portp->tty->driver_data == portp) {
  25475. -            portp->stats.ttystate = portp->tty->flags;
  25476. -            portp->stats.rxbuffered = portp->tty->flip.count;
  25477. -            if (portp->tty->termios != (struct termios *) NULL) {
  25478. -                portp->stats.cflags = portp->tty->termios->c_cflag;
  25479. -                portp->stats.iflags = portp->tty->termios->c_iflag;
  25480. -                portp->stats.oflags = portp->tty->termios->c_oflag;
  25481. -                portp->stats.lflags = portp->tty->termios->c_lflag;
  25482. -            }
  25483. -        }
  25484. -    }
  25485. +    BRDENABLE(portp->brdnr, portp->pagenr);
  25486. +    sr = stl_sc26198getreg(portp, SR);
  25487. +    BRDDISABLE(portp->brdnr);
  25488.      restore_flags(flags);
  25489.  
  25490. -    head = portp->tx.head;
  25491. -    tail = portp->tx.tail;
  25492. -    portp->stats.txbuffered = ((head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head)));
  25493. +    return((sr & SR_TXEMPTY) ? 0 : 1);
  25494. +}
  25495.  
  25496. -    portp->stats.signals = (unsigned long) stl_getsignals(portp);
  25497. +/*****************************************************************************/
  25498.  
  25499. -    memcpy_tofs(cp, &portp->stats, sizeof(comstats_t));
  25500. -    return(0);
  25501. +/*
  25502. + *    Delay for a small amount of time, to give the sc26198 a chance
  25503. + *    to process a command...
  25504. + */
  25505. +
  25506. +static void stl_sc26198wait(stlport_t *portp)
  25507. +{
  25508. +    int    i;
  25509. +
  25510. +#if DEBUG
  25511. +    printk("stl_sc26198wait(portp=%x)\n", (int) portp);
  25512. +#endif
  25513. +
  25514. +    if (portp == (stlport_t *) NULL)
  25515. +        return;
  25516. +
  25517. +    for (i = 0; (i < 20); i++)
  25518. +        stl_sc26198getglobreg(portp, TSTR);
  25519.  }
  25520.  
  25521.  /*****************************************************************************/
  25522.  
  25523.  /*
  25524. - *    Clear the port stats structure. We also return it zeroed out...
  25525. + *    If we are TX flow controlled and in IXANY mode then we may
  25526. + *    need to unflow control here. We gotta do this because of the
  25527. + *    automatic flow control modes of the sc26198.
  25528.   */
  25529.  
  25530. -static int stl_clrportstats(stlport_t *portp, comstats_t *cp)
  25531. +static inline void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty)
  25532.  {
  25533. -    if (portp == (stlport_t *) NULL) {
  25534. -        memcpy_fromfs(&stl_comstats, cp, sizeof(comstats_t));
  25535. -        portp = stl_getport(stl_comstats.brd, stl_comstats.panel, stl_comstats.port);
  25536. -        if (portp == (stlport_t *) NULL)
  25537. -            return(-ENODEV);
  25538. -    }
  25539. +    unsigned char    mr0;
  25540.  
  25541. -    memset(&portp->stats, 0, sizeof(comstats_t));
  25542. -    portp->stats.brd = portp->brdnr;
  25543. -    portp->stats.panel = portp->panelnr;
  25544. -    portp->stats.port = portp->portnr;
  25545. -    memcpy_tofs(cp, &portp->stats, sizeof(comstats_t));
  25546. -    return(0);
  25547. +    mr0 = stl_sc26198getreg(portp, MR0);
  25548. +    stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
  25549. +    stl_sc26198setreg(portp, SCCR, CR_HOSTXON);
  25550. +    stl_sc26198wait(portp);
  25551. +    stl_sc26198setreg(portp, MR0, mr0);
  25552. +    clear_bit(ASYI_TXFLOWED, &portp->istate);
  25553.  }
  25554.  
  25555.  /*****************************************************************************/
  25556.  
  25557.  /*
  25558. - *    Return the entire driver ports structure to a user app.
  25559. + *    Interrupt service routine for sc26198 panels.
  25560.   */
  25561.  
  25562. -static int stl_getportstruct(unsigned long arg)
  25563. +static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase)
  25564.  {
  25565.      stlport_t    *portp;
  25566. +    unsigned int    iack;
  25567.  
  25568. -    memcpy_fromfs(&stl_dummyport, (void *) arg, sizeof(stlport_t));
  25569. -    portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr,
  25570. -         stl_dummyport.portnr);
  25571. -    if (portp == (stlport_t *) NULL)
  25572. -        return(-ENODEV);
  25573. -    memcpy_tofs((void *) arg, portp, sizeof(stlport_t));
  25574. -    return(0);
  25575. +/* 
  25576. + *    Work around bug in sc26198 chip... Cannot have A6 address
  25577. + *    line of UART high, else iack will be returned as 0.
  25578. + */
  25579. +    outb(0, (iobase + 1));
  25580. +
  25581. +    iack = inb(iobase + XP_IACK);
  25582. +    portp = panelp->ports[(iack & IVR_CHANMASK) + ((iobase & 0x4) << 1)];
  25583. +
  25584. +    if (iack & IVR_RXDATA)
  25585. +        stl_sc26198rxisr(portp, iack);
  25586. +    else if (iack & IVR_TXDATA)
  25587. +        stl_sc26198txisr(portp);
  25588. +    else
  25589. +        stl_sc26198otherisr(portp, iack);
  25590.  }
  25591.  
  25592.  /*****************************************************************************/
  25593.  
  25594.  /*
  25595. - *    Return the entire driver board structure to a user app.
  25596. + *    Transmit interrupt handler. This has gotta be fast!  Handling TX
  25597. + *    chars is pretty simple, stuff as many as possible from the TX buffer
  25598. + *    into the sc26198 FIFO.
  25599. + *    In practice it is possible that interrupts are enabled but that the
  25600. + *    port has been hung up. Need to handle not having any TX buffer here,
  25601. + *    this is done by using the side effect that head and tail will also
  25602. + *    be NULL if the buffer has been freed.
  25603.   */
  25604.  
  25605. -static int stl_getbrdstruct(unsigned long arg)
  25606. +static void stl_sc26198txisr(stlport_t *portp)
  25607.  {
  25608. -    stlbrd_t    *brdp;
  25609. +    unsigned int    ioaddr;
  25610. +    unsigned char    mr0;
  25611. +    int        len, stlen;
  25612. +    char        *head, *tail;
  25613.  
  25614. -    memcpy_fromfs(&stl_dummybrd, (void *) arg, sizeof(stlbrd_t));
  25615. -    if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS))
  25616. -        return(-ENODEV);
  25617. -    brdp = stl_brds[stl_dummybrd.brdnr];
  25618. -    if (brdp == (stlbrd_t *) NULL)
  25619. -        return(-ENODEV);
  25620. -    memcpy_tofs((void *) arg, brdp, sizeof(stlbrd_t));
  25621. -    return(0);
  25622. +#if DEBUG
  25623. +    printk("stl_sc26198txisr(portp=%x)\n", (int) portp);
  25624. +#endif
  25625. +
  25626. +    ioaddr = portp->ioaddr;
  25627. +    head = portp->tx.head;
  25628. +    tail = portp->tx.tail;
  25629. +    len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
  25630. +    if ((len == 0) || ((len < STL_TXBUFLOW) &&
  25631. +        (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
  25632. +        set_bit(ASYI_TXLOW, &portp->istate);
  25633. +        queue_task_irq_off(&portp->tqueue, &tq_scheduler);
  25634. +    }
  25635. +
  25636. +    if (len == 0) {
  25637. +        outb((MR0 | portp->uartaddr), (ioaddr + XP_ADDR));
  25638. +        mr0 = inb(ioaddr + XP_DATA);
  25639. +        if ((mr0 & MR0_TXMASK) == MR0_TXEMPTY) {
  25640. +            portp->imr &= ~IR_TXRDY;
  25641. +            outb((IMR | portp->uartaddr), (ioaddr + XP_ADDR));
  25642. +            outb(portp->imr, (ioaddr + XP_DATA));
  25643. +            clear_bit(ASYI_TXBUSY, &portp->istate);
  25644. +        } else {
  25645. +            mr0 |= ((mr0 & ~MR0_TXMASK) | MR0_TXEMPTY);
  25646. +            outb(mr0, (ioaddr + XP_DATA));
  25647. +        }
  25648. +    } else {
  25649. +        len = MIN(len, SC26198_TXFIFOSIZE);
  25650. +        portp->stats.txtotal += len;
  25651. +        stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
  25652. +        outb(GTXFIFO, (ioaddr + XP_ADDR));
  25653. +        outsb((ioaddr + XP_DATA), tail, stlen);
  25654. +        len -= stlen;
  25655. +        tail += stlen;
  25656. +        if (tail >= (portp->tx.buf + STL_TXBUFSIZE))
  25657. +            tail = portp->tx.buf;
  25658. +        if (len > 0) {
  25659. +            outsb((ioaddr + XP_DATA), tail, len);
  25660. +            tail += len;
  25661. +        }
  25662. +        portp->tx.tail = tail;
  25663. +    }
  25664.  }
  25665.  
  25666.  /*****************************************************************************/
  25667.  
  25668.  /*
  25669. - *    The "staliomem" device is also required to do some special operations
  25670. - *    on the board and/or ports. In this driver it is mostly used for stats
  25671. - *    collection.
  25672. + *    Receive character interrupt handler. Determine if we have good chars
  25673. + *    or bad chars and then process appropriately. Good chars are easy
  25674. + *    just shove the lot into the RX buffer and set all status byte to 0.
  25675. + *    If a bad RX char then process as required. This routine needs to be
  25676. + *    fast!  In practice it is possible that we get an interrupt on a port
  25677. + *    that is closed. This can happen on hangups - since they completely
  25678. + *    shutdown a port not in user context. Need to handle this case.
  25679.   */
  25680.  
  25681. -static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
  25682. +static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack)
  25683.  {
  25684. -    int    brdnr, rc;
  25685. +    struct tty_struct    *tty;
  25686. +    unsigned int        len, buflen, ioaddr;
  25687.  
  25688.  #if DEBUG
  25689. -    printk("stl_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip, (int) fp, cmd, (int) arg);
  25690. +    printk("stl_sc26198rxisr(portp=%x,iack=%x)\n", (int) portp, iack);
  25691.  #endif
  25692.  
  25693. -    brdnr = MINOR(ip->i_rdev);
  25694. -    if (brdnr >= STL_MAXBRDS)
  25695. -        return(-ENODEV);
  25696. -    rc = 0;
  25697. -
  25698. -    switch (cmd) {
  25699. -    case COM_GETPORTSTATS:
  25700. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
  25701. -            rc = stl_getportstats((stlport_t *) NULL, (comstats_t *) arg);
  25702. -        break;
  25703. -    case COM_CLRPORTSTATS:
  25704. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
  25705. -            rc = stl_clrportstats((stlport_t *) NULL, (comstats_t *) arg);
  25706. -        break;
  25707. -    case COM_GETBRDSTATS:
  25708. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(combrd_t))) == 0)
  25709. -            rc = stl_getbrdstats((combrd_t *) arg);
  25710. -        break;
  25711. -    case COM_READPORT:
  25712. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stlport_t))) == 0)
  25713. -            rc = stl_getportstruct(arg);
  25714. -        break;
  25715. -    case COM_READBOARD:
  25716. -        if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stlbrd_t))) == 0)
  25717. -            rc = stl_getbrdstruct(arg);
  25718. -        break;
  25719. -    default:
  25720. -        rc = -ENOIOCTLCMD;
  25721. -        break;
  25722. +    tty = portp->tty;
  25723. +    ioaddr = portp->ioaddr;
  25724. +    outb(GIBCR, (ioaddr + XP_ADDR));
  25725. +    len = inb(ioaddr + XP_DATA) + 1;
  25726. +
  25727. +    if ((iack & IVR_TYPEMASK) == IVR_RXDATA) {
  25728. +        if ((tty == (struct tty_struct *) NULL) ||
  25729. +            (tty->flip.char_buf_ptr == (char *) NULL) ||
  25730. +            ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
  25731. +            outb(GRXFIFO, (ioaddr + XP_ADDR));
  25732. +            insb((ioaddr + XP_DATA), &stl_unwanted[0], len);
  25733. +            portp->stats.rxlost += len;
  25734. +            portp->stats.rxtotal += len;
  25735. +        } else {
  25736. +            len = MIN(len, buflen);
  25737. +            if (len > 0) {
  25738. +                outb(GRXFIFO, (ioaddr + XP_ADDR));
  25739. +                insb((ioaddr + XP_DATA), tty->flip.char_buf_ptr, len);
  25740. +                memset(tty->flip.flag_buf_ptr, 0, len);
  25741. +                tty->flip.flag_buf_ptr += len;
  25742. +                tty->flip.char_buf_ptr += len;
  25743. +                tty->flip.count += len;
  25744. +                tty_schedule_flip(tty);
  25745. +                portp->stats.rxtotal += len;
  25746. +            }
  25747. +        }
  25748. +    } else {
  25749. +        stl_sc26198rxbadchars(portp);
  25750.      }
  25751.  
  25752. -    return(rc);
  25753. +/*
  25754. + *    If we are TX flow controlled and in IXANY mode then we may need
  25755. + *    to unflow control here. We gotta do this because of the automatic
  25756. + *    flow control modes of the sc26198.
  25757. + */
  25758. +    if (test_bit(ASYI_TXFLOWED, &portp->istate)) {
  25759. +        if ((tty != (struct tty_struct *) NULL) &&
  25760. +            (tty->termios != (struct termios *) NULL) &&
  25761. +            (tty->termios->c_iflag & IXANY)) {
  25762. +            stl_sc26198txunflow(portp, tty);
  25763. +        }
  25764. +    }
  25765.  }
  25766.  
  25767.  /*****************************************************************************/
  25768.  
  25769. -int stl_init(void)
  25770. +/*
  25771. + *    Process an RX bad character.
  25772. + */
  25773. +
  25774. +static void inline stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch)
  25775.  {
  25776. -    printk(KERN_INFO "%s: version %s\n", stl_drvname, stl_drvversion);
  25777. +    struct tty_struct    *tty;
  25778. +    unsigned int        ioaddr;
  25779.  
  25780. -    stl_initbrds();
  25781. +    tty = portp->tty;
  25782. +    ioaddr = portp->ioaddr;
  25783. +
  25784. +    if (status & SR_RXPARITY)
  25785. +        portp->stats.rxparity++;
  25786. +    if (status & SR_RXFRAMING)
  25787. +        portp->stats.rxframing++;
  25788. +    if (status & SR_RXOVERRUN)
  25789. +        portp->stats.rxoverrun++;
  25790. +    if (status & SR_RXBREAK)
  25791. +        portp->stats.rxbreaks++;
  25792. +
  25793. +    if ((tty != (struct tty_struct *) NULL) &&
  25794. +        ((portp->rxignoremsk & status) == 0)) {
  25795. +        if (portp->rxmarkmsk & status) {
  25796. +            if (status & SR_RXBREAK) {
  25797. +                status = TTY_BREAK;
  25798. +                if (portp->flags & ASYNC_SAK) {
  25799. +                    do_SAK(tty);
  25800. +                    BRDENABLE(portp->brdnr, portp->pagenr);
  25801. +                }
  25802. +            } else if (status & SR_RXPARITY) {
  25803. +                status = TTY_PARITY;
  25804. +            } else if (status & SR_RXFRAMING) {
  25805. +                status = TTY_FRAME;
  25806. +            } else if(status & SR_RXOVERRUN) {
  25807. +                status = TTY_OVERRUN;
  25808. +            } else {
  25809. +                status = 0;
  25810. +            }
  25811. +        } else {
  25812. +            status = 0;
  25813. +        }
  25814. +
  25815. +        if (tty->flip.char_buf_ptr != (char *) NULL) {
  25816. +            if (tty->flip.count < TTY_FLIPBUF_SIZE) {
  25817. +                *tty->flip.flag_buf_ptr++ = status;
  25818. +                *tty->flip.char_buf_ptr++ = ch;
  25819. +                tty->flip.count++;
  25820. +            }
  25821. +            tty_schedule_flip(tty);
  25822. +        }
  25823. +
  25824. +        if (status == 0)
  25825. +            portp->stats.rxtotal++;
  25826. +    }
  25827. +}
  25828. +
  25829. +/*****************************************************************************/
  25830.  
  25831.  /*
  25832. - *    Allocate a temporary write buffer.
  25833. + *    Process all characters in the RX FIFO of the UART. Check all char
  25834. + *    status bytes as well, and process as required. We need to check
  25835. + *    all bytes in the FIFO, in case some more enter the FIFO while we
  25836. + *    are here. To get the exact character error type we need to switch
  25837. + *    into CHAR error mode (that is why we need to make sure we empty
  25838. + *    the FIFO).
  25839.   */
  25840. -    stl_tmpwritebuf = (char *) stl_memalloc(STL_TXBUFSIZE);
  25841. -    if (stl_tmpwritebuf == (char *) NULL)
  25842. -        printk("STALLION: failed to allocate memory (size=%d)\n", STL_TXBUFSIZE);
  25843. +
  25844. +static void stl_sc26198rxbadchars(stlport_t *portp)
  25845. +{
  25846. +    unsigned char    status, mr1;
  25847. +    char        ch;
  25848.  
  25849.  /*
  25850. - *    Set up a character driver for per board stuff. This is mainly used
  25851. - *    to do stats ioctls on the ports.
  25852. + *    To get the precise error type for each character we must switch
  25853. + *    back into CHAR error mode.
  25854.   */
  25855. -    if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
  25856. -        printk("STALLION: failed to register serial board device\n");
  25857. +    mr1 = stl_sc26198getreg(portp, MR1);
  25858. +    stl_sc26198setreg(portp, MR1, (mr1 & ~MR1_ERRBLOCK));
  25859. +
  25860. +    while ((status = stl_sc26198getreg(portp, SR)) & SR_RXRDY) {
  25861. +        stl_sc26198setreg(portp, SCCR, CR_CLEARRXERR);
  25862. +        ch = stl_sc26198getreg(portp, RXFIFO);
  25863. +        stl_sc26198rxbadch(portp, status, ch);
  25864. +    }
  25865.  
  25866.  /*
  25867. - *    Set up the tty driver structure and register us as a driver.
  25868. - *    Also setup the callout tty device.
  25869. + *    To get correct interrupt class we must switch back into BLOCK
  25870. + *    error mode.
  25871.   */
  25872. -    memset(&stl_serial, 0, sizeof(struct tty_driver));
  25873. -    stl_serial.magic = TTY_DRIVER_MAGIC;
  25874. -    stl_serial.name = stl_serialname;
  25875. -    stl_serial.major = STL_SERIALMAJOR;
  25876. -    stl_serial.minor_start = 0;
  25877. -    stl_serial.num = STL_MAXBRDS * STL_MAXPORTS;
  25878. -    stl_serial.type = TTY_DRIVER_TYPE_SERIAL;
  25879. -    stl_serial.subtype = STL_DRVTYPSERIAL;
  25880. -    stl_serial.init_termios = stl_deftermios;
  25881. -    stl_serial.flags = TTY_DRIVER_REAL_RAW;
  25882. -    stl_serial.refcount = &stl_refcount;
  25883. -    stl_serial.table = stl_ttys;
  25884. -    stl_serial.termios = stl_termios;
  25885. -    stl_serial.termios_locked = stl_termioslocked;
  25886. -    
  25887. -    stl_serial.open = stl_open;
  25888. -    stl_serial.close = stl_close;
  25889. -    stl_serial.write = stl_write;
  25890. -    stl_serial.put_char = stl_putchar;
  25891. -    stl_serial.flush_chars = stl_flushchars;
  25892. -    stl_serial.write_room = stl_writeroom;
  25893. -    stl_serial.chars_in_buffer = stl_charsinbuffer;
  25894. -    stl_serial.ioctl = stl_ioctl;
  25895. -    stl_serial.set_termios = stl_settermios;
  25896. -    stl_serial.throttle = stl_throttle;
  25897. -    stl_serial.unthrottle = stl_unthrottle;
  25898. -    stl_serial.stop = stl_stop;
  25899. -    stl_serial.start = stl_start;
  25900. -    stl_serial.hangup = stl_hangup;
  25901. -    stl_serial.flush_buffer = stl_flushbuffer;
  25902. +    stl_sc26198setreg(portp, MR1, mr1);
  25903. +}
  25904.  
  25905. -    stl_callout = stl_serial;
  25906. -    stl_callout.name = stl_calloutname;
  25907. -    stl_callout.major = STL_CALLOUTMAJOR;
  25908. -    stl_callout.subtype = STL_DRVTYPCALLOUT;
  25909. +/*****************************************************************************/
  25910.  
  25911. -    if (tty_register_driver(&stl_serial))
  25912. -        printk("STALLION: failed to register serial driver\n");
  25913. -    if (tty_register_driver(&stl_callout))
  25914. -        printk("STALLION: failed to register callout driver\n");
  25915. +/*
  25916. + *    Other interrupt handler. This includes modem signals, flow
  25917. + *    control actions, etc. Most stuff is left to off-level interrupt
  25918. + *    processing time.
  25919. + */
  25920.  
  25921. -    return(0);
  25922. +static void stl_sc26198otherisr(stlport_t *portp, unsigned int iack)
  25923. +{
  25924. +    unsigned char    cir, ipr, xisr;
  25925. +
  25926. +#if DEBUG
  25927. +    printk("stl_sc26198otherisr(portp=%x,iack=%x)\n", (int) portp, iack);
  25928. +#endif
  25929. +
  25930. +    cir = stl_sc26198getglobreg(portp, CIR);
  25931. +
  25932. +    switch (cir & CIR_SUBTYPEMASK) {
  25933. +    case CIR_SUBCOS:
  25934. +        ipr = stl_sc26198getreg(portp, IPR);
  25935. +        if (ipr & IPR_DCDCHANGE) {
  25936. +            set_bit(ASYI_DCDCHANGE, &portp->istate);
  25937. +            queue_task_irq_off(&portp->tqueue, &tq_scheduler);
  25938. +            portp->stats.modem++;
  25939. +        }
  25940. +        break;
  25941. +    case CIR_SUBXONXOFF:
  25942. +        xisr = stl_sc26198getreg(portp, XISR);
  25943. +        if (xisr & XISR_RXXONGOT) {
  25944. +            set_bit(ASYI_TXFLOWED, &portp->istate);
  25945. +            portp->stats.txxoff++;
  25946. +        }
  25947. +        if (xisr & XISR_RXXOFFGOT) {
  25948. +            clear_bit(ASYI_TXFLOWED, &portp->istate);
  25949. +            portp->stats.txxon++;
  25950. +        }
  25951. +        break;
  25952. +    case CIR_SUBBREAK:
  25953. +        stl_sc26198setreg(portp, SCCR, CR_BREAKRESET);
  25954. +        stl_sc26198rxbadchars(portp);
  25955. +        break;
  25956. +    default:
  25957. +        break;
  25958. +    }
  25959.  }
  25960.  
  25961.  /*****************************************************************************/
  25962. diff -u --recursive --new-file v2.0.34/linux/drivers/char/vt.c linux/drivers/char/vt.c
  25963. --- v2.0.34/linux/drivers/char/vt.c    Sun May 12 21:36:19 1996
  25964. +++ linux/drivers/char/vt.c    Mon Jul 13 13:47:30 1998
  25965. @@ -23,6 +23,7 @@
  25966.  
  25967.  #include <asm/io.h>
  25968.  #include <asm/segment.h>
  25969. +#include <asm/bitops.h>
  25970.  
  25971.  #include "kbd_kern.h"
  25972.  #include "vt_kern.h"
  25973. @@ -147,11 +148,16 @@
  25974.   * We also return immediately, which is what was implied within the X
  25975.   * comments - KDMKTONE doesn't put the process to sleep.
  25976.   */
  25977. +
  25978. +static unsigned int mksound_lock = 0;
  25979. +
  25980.  static void
  25981.  kd_nosound(unsigned long ignored)
  25982.  {
  25983. -    /* disable counter 2 */
  25984. -    outb(inb_p(0x61)&0xFC, 0x61);
  25985. +    /* if sound is being set up, don't turn it off */
  25986. +    if (!mksound_lock)
  25987. +               /* disable counter 2 */
  25988. +               outb(inb_p(0x61)&0xFC, 0x61);
  25989.      return;
  25990.  }
  25991.  
  25992. @@ -165,25 +171,29 @@
  25993.  
  25994.      if (hz > 20 && hz < 32767)
  25995.          count = 1193180 / hz;
  25996. -    
  25997. -    cli();
  25998. -    del_timer(&sound_timer);
  25999. -    if (count) {
  26000. -        /* enable counter 2 */
  26001. -        outb_p(inb_p(0x61)|3, 0x61);
  26002. -        /* set command for counter 2, 2 byte write */
  26003. -        outb_p(0xB6, 0x43);
  26004. -        /* select desired HZ */
  26005. -        outb_p(count & 0xff, 0x42);
  26006. -        outb((count >> 8) & 0xff, 0x42);
  26007. -
  26008. -        if (ticks) {
  26009. -            sound_timer.expires = jiffies+ticks;
  26010. -            add_timer(&sound_timer);
  26011. -        }
  26012. -    } else
  26013. -        kd_nosound(0);
  26014. -    sti();
  26015. +        
  26016. +        /* ignore multiple simultaneous requests for sound */
  26017. +        if (!set_bit(0, &mksound_lock)) {
  26018. +        /* set_bit in 2.0.x is same as test-and-set in 2.1.x */
  26019. +                del_timer(&sound_timer);
  26020. +                if (count) {
  26021. +                        /* enable counter 2 */
  26022. +                        outb_p(inb_p(0x61)|3, 0x61);
  26023. +                        /* set command for counter 2, 2 byte write */
  26024. +                        outb_p(0xB6, 0x43);
  26025. +                        /* select desired HZ */
  26026. +                        outb_p(count & 0xff, 0x42);
  26027. +                        outb((count >> 8) & 0xff, 0x42);
  26028. +                        if (ticks) {
  26029. +                                sound_timer.expires = jiffies+ticks;
  26030. +                                add_timer(&sound_timer);
  26031. +                        }
  26032. +                } else
  26033. +                        kd_nosound(0);
  26034. +                mksound_lock = 0;
  26035. +        }    
  26036.      return;
  26037.  }
  26038.  
  26039. diff -u --recursive --new-file v2.0.34/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
  26040. --- v2.0.34/linux/drivers/isdn/isdn_net.c    Mon Jul 13 13:46:28 1998
  26041. +++ linux/drivers/isdn/isdn_net.c    Mon Jul 13 13:47:30 1998
  26042. @@ -229,7 +229,8 @@
  26043.  {
  26044.      printk(KERN_DEBUG "isdn_net: %s: %s, send ICMP\n",
  26045.             dev->name, reason);
  26046. -    icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0
  26047. +    if(skb->protocol==htons(ETH_P_IP))
  26048. +        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0
  26049.  #if (LINUX_VERSION_CODE < 0x02010f)    /* 2.1.15 */
  26050.            ,dev
  26051.  #endif
  26052. diff -u --recursive --new-file v2.0.34/linux/drivers/isdn/sc/interrupt.c linux/drivers/isdn/sc/interrupt.c
  26053. --- v2.0.34/linux/drivers/isdn/sc/interrupt.c    Mon Aug  4 17:34:01 1997
  26054. +++ linux/drivers/isdn/sc/interrupt.c    Mon Jul 13 13:47:30 1998
  26055. @@ -32,7 +32,7 @@
  26056.  #include "message.h"
  26057.  #include "card.h"
  26058.  
  26059. -extern indicate_status(int, int, ulong, char *);
  26060. +extern int indicate_status(int, int, ulong, char *);
  26061.  extern void check_phystat(unsigned long);
  26062.  extern void dump_messages(int);
  26063.  extern int receivemessage(int, RspMessage *);
  26064. diff -u --recursive --new-file v2.0.34/linux/drivers/net/3c503.c linux/drivers/net/3c503.c
  26065. --- v2.0.34/linux/drivers/net/3c503.c    Thu Apr 11 23:49:36 1996
  26066. +++ linux/drivers/net/3c503.c    Mon Jul 13 13:47:30 1998
  26067. @@ -75,7 +75,7 @@
  26068.  static void el2_reset_8390(struct device *dev);
  26069.  static void el2_init_card(struct device *dev);
  26070.  static void el2_block_output(struct device *dev, int count,
  26071. -                 const unsigned char *buf, const start_page);
  26072. +                 const unsigned char *buf, const int start_page);
  26073.  static void el2_block_input(struct device *dev, int count, struct sk_buff *skb,
  26074.                 int ring_offset);
  26075.  static void el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
  26076. @@ -432,7 +432,7 @@
  26077.   */
  26078.  static void
  26079.  el2_block_output(struct device *dev, int count,
  26080. -         const unsigned char *buf, const start_page)
  26081. +         const unsigned char *buf, const int start_page)
  26082.  {
  26083.      unsigned short int *wrd;
  26084.      int boguscount;        /* timeout counter */
  26085. diff -u --recursive --new-file v2.0.34/linux/drivers/net/3c515.c linux/drivers/net/3c515.c
  26086. --- v2.0.34/linux/drivers/net/3c515.c    Mon Jul 13 13:46:29 1998
  26087. +++ linux/drivers/net/3c515.c    Mon Jul 13 13:47:31 1998
  26088. @@ -18,9 +18,9 @@
  26089.  /* "Knobs" that adjust features and parameters. */
  26090.  /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
  26091.     Setting to > 1512 effectively disables this feature. */
  26092. -static const rx_copybreak = 200;
  26093. +static const int rx_copybreak = 200;
  26094.  /* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
  26095. -static const mtu = 1500;
  26096. +static const int mtu = 1500;
  26097.  /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
  26098.  static int max_interrupt_work = 20;
  26099.  
  26100. @@ -149,7 +149,7 @@
  26101.  PCI cards, with the bus master interface extensively modified to work with
  26102.  the ISA bus.
  26103.  
  26104. -The card is capable of full-bus-master transfers with seperate
  26105. +The card is capable of full-bus-master transfers with separate
  26106.  lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
  26107.  DEC Tulip and Intel Speedo3.
  26108.  
  26109. diff -u --recursive --new-file v2.0.34/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
  26110. --- v2.0.34/linux/drivers/net/3c59x.c    Mon Jul 13 13:46:29 1998
  26111. +++ linux/drivers/net/3c59x.c    Mon Jul 13 13:47:31 1998
  26112. @@ -20,9 +20,9 @@
  26113.  /* "Knobs" that adjust features and parameters. */
  26114.  /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
  26115.     Setting to > 1512 effectively disables this feature. */
  26116. -static const rx_copybreak = 200;
  26117. +static const int rx_copybreak = 200;
  26118.  /* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
  26119. -static const mtu = 1500;
  26120. +static const int mtu = 1500;
  26121.  /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
  26122.  static int max_interrupt_work = 20;
  26123.  
  26124. @@ -194,7 +194,7 @@
  26125.  versions of the FastEtherLink cards.  The supported product IDs are
  26126.    3c590, 3c592, 3c595, 3c597, 3c900, 3c905
  26127.  
  26128. -The ISA 3c515 is supported with a seperate driver, 3c515.c, included with
  26129. +The ISA 3c515 is supported with a separate driver, 3c515.c, included with
  26130.  the kernel source or available from
  26131.      cesdis.gsfc.nasa.gov:/pub/linux/drivers/3c515.html
  26132.  
  26133. @@ -212,7 +212,7 @@
  26134.  series.  The primary interface is two programmed-I/O FIFOs, with an
  26135.  alternate single-contiguous-region bus-master transfer (see next).
  26136.  
  26137. -The 3c900 "Boomerang" series uses a full-bus-master interface with seperate
  26138. +The 3c900 "Boomerang" series uses a full-bus-master interface with separate
  26139.  lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
  26140.  DEC Tulip and Intel Speedo3.  The first chip version retains a compatible
  26141.  programmed-I/O interface that will be removed in the 'B' and subsequent
  26142. @@ -1342,7 +1342,7 @@
  26143.  }
  26144.  
  26145.  /*
  26146. - * Handle uncommon interrupt sources.  This is a seperate routine to minimize
  26147. + * Handle uncommon interrupt sources.  This is a separate routine to minimize
  26148.   * the cache impact.
  26149.   */
  26150.  static void
  26151. diff -u --recursive --new-file v2.0.34/linux/drivers/net/Changelog.tlan linux/drivers/net/Changelog.tlan
  26152. --- v2.0.34/linux/drivers/net/Changelog.tlan    Mon Jul 13 13:46:29 1998
  26153. +++ linux/drivers/net/Changelog.tlan    Mon Jul 13 13:47:31 1998
  26154. @@ -1,5 +1,52 @@
  26155.  TLan Device Driver change log.
  26156.  
  26157. +0.43    - Changed the id strings of the Compaq devices to their real
  26158. +      names.
  26159. +    - Added 2 other Olicom devices with a patch provided by
  26160. +      Henrik Storner of Olicom.
  26161. +    - Changed AN so the driver won't try to autonegotiate with
  26162. +      a partner that doesn't autonegotiate.
  26163. +    - Added a section to verify whether in full or half duplex.
  26164. +    - Added value checking for speed and duplex inputs.
  26165. +    - Added B012 and B030 Compaq devices.
  26166. +      
  26167. +0.42    - Coverted tranceiver from misused per-tranceiver functions
  26168. +      to a timer-oriented path that covers four possible classes
  26169. +      of tranceivers:
  26170. +        1. Unmanaged
  26171. +        2. Manual configuration
  26172. +        3. Autonegotiation w/ manual configuration
  26173. +        4. Autonegotiation w/ auto configuration
  26174. +    - Added ability to force speed and duplex settings.
  26175. +    - Made speed, duplex, sa_int, etc, to be set per adapter with
  26176. +      ether= command.
  26177. +    - Added support for Olicom OC-2326
  26178. +
  26179. +0.41    - Added non-bounce buffer paths.  Added TLan_FreeLists to
  26180. +      dispose of unused sk_buff's at device close time.
  26181. +    - Discovered inlined functions aren't being inlined, or at
  26182. +      least take up more space than macros would.
  26183. +
  26184. +0.40    - Refined polarity checking to handle case when polarity
  26185. +      changes to normal from abnormal.
  26186. +    - Cleaned up TLan_Probe routine.
  26187. +    - Added an option for the SA_INTERRUPT flag to be set.
  26188. +    - Created FAQ.
  26189. +    - Removed all C++ style comments.
  26190. +    - Added error message if devices busmastering is inactive.
  26191. +      Also will now skip device.
  26192. +    - Put cli and sti back into TLan_HandleInterrupt.  It makes
  26193. +      me feel better.
  26194. +    - Moved the code that checks for boot parameter options to 
  26195. +      tlan_probe.
  26196. +
  26197. +0.39    - Minor cosmetic cleanups (especially variable declarations).
  26198. +    - Changes low level TLAN functions to use dev structures instead
  26199. +      individual data elements.
  26200. +        - Changed low level TLAN functions not to play with sti and cli
  26201. +      if in an interrupt routine.
  26202. +    - Removed cli and sti from TLan_HandleInterrupt.
  26203. +
  26204.  0.38    - Added code to isolate the external PHY if the internal PHY is
  26205.        being used for AUI/BNC connectivity.  Also set the aui and
  26206.        debug variables from mem_start and mem_end if the driver is
  26207. @@ -19,7 +66,7 @@
  26208.        100Mbs should work now on 0xAE32.
  26209.      - Fixed a small bug where heartbeat and PHY interrupts were
  26210.        always being enabled.
  26211. -    - Force the driver into Unmanaged PHY mode for 0xF130 devices,
  26212. +    - Force the the driver into Unmanaged PHY mode for 0xF130 devices,
  26213.        even if a managed (ie, the built-in one) PHY is detected.
  26214.      - Moved the PHY initialization to after the onboard PHY is enabled,
  26215.        if selected.
  26216. diff -u --recursive --new-file v2.0.34/linux/drivers/net/Config.in linux/drivers/net/Config.in
  26217. --- v2.0.34/linux/drivers/net/Config.in    Mon Jul 13 13:46:29 1998
  26218. +++ linux/drivers/net/Config.in    Mon Jul 13 13:47:31 1998
  26219. @@ -25,16 +25,28 @@
  26220.  bool 'Radio network interfaces' CONFIG_NET_RADIO
  26221.  if [ "$CONFIG_NET_RADIO" != "n" ]; then
  26222.    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
  26223. -    tristate 'BAYCOM ser12 and par96 kiss emulation driver for AX.25' CONFIG_BAYCOM
  26224. -  fi
  26225. -  if [ "$CONFIG_AX25" = "y" ]; then
  26226. -    bool 'Gracilis PackeTwin support' CONFIG_PT
  26227. -    bool 'Ottawa PI and PI/2 support' CONFIG_PI
  26228. +    tristate 'BAYCOM ser12 and par96 driver for AX.25' CONFIG_BAYCOM
  26229. +    tristate 'Soundcard modem driver for AX.25' CONFIG_SOUNDMODEM
  26230. +    if [ "$CONFIG_SOUNDMODEM" != "n" ]; then
  26231. +      bool 'Soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC
  26232. +      bool 'Soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS
  26233. +      bool 'Soundmodem support for 1200 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK1200
  26234. +      bool 'Soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_7
  26235. +      bool 'Soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8
  26236. +      bool 'Soundmodem support for 2666 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK2666
  26237. +      bool 'Soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800
  26238. +      bool 'Soundmodem support for 4800 baud PSK modulation' CONFIG_SOUNDMODEM_PSK4800
  26239. +      bool 'Soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600
  26240. +    fi
  26241.    fi
  26242. +  tristate 'Serial port KISS driver for AX.25' CONFIG_MKISS
  26243. +  tristate 'BPQ Ethernet driver for AX.25' CONFIG_BPQETHER
  26244. +  tristate 'Gracilis PackeTwin support for AX.25' CONFIG_PT
  26245. +  tristate 'Ottawa PI and PI/2 support for AX.25' CONFIG_PI
  26246. +  tristate 'Z8530 SCC KISS emulation driver for AX.25' CONFIG_SCC
  26247.    tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP
  26248.    tristate 'AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN
  26249.    tristate 'WIC Radio IP bridge (EXPERIMENTAL)' CONFIG_WIC
  26250. -  tristate 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC
  26251.  fi
  26252.  #
  26253.  #    Ethernet
  26254. diff -u --recursive --new-file v2.0.34/linux/drivers/net/Makefile linux/drivers/net/Makefile
  26255. --- v2.0.34/linux/drivers/net/Makefile    Mon Jul 13 13:46:29 1998
  26256. +++ linux/drivers/net/Makefile    Mon Jul 13 13:47:31 1998
  26257. @@ -7,6 +7,10 @@
  26258.  # are difficult for users to deal with.
  26259.  include CONFIG
  26260.  
  26261. +SUB_DIRS     := 
  26262. +MOD_SUB_DIRS := $(SUB_DIRS)
  26263. +ALL_SUB_DIRS := $(SUB_DIRS)
  26264. +
  26265.  L_TARGET := net.a
  26266.  L_OBJS   := auto_irq.o
  26267.  M_OBJS   :=
  26268. @@ -18,6 +22,8 @@
  26269.  CONFIG_8390_MODULE  :=
  26270.  CONFIG_SLHC_BUILTIN :=
  26271.  CONFIG_SLHC_MODULE  :=
  26272. +CONFIG_HDLCDRV_BUILTIN :=
  26273. +CONFIG_HDLCDRV_MODULE  :=
  26274.  
  26275.  ifeq ($(CONFIG_ISDN),y)
  26276.    ifeq ($(CONFIG_ISDN_PPP),y)
  26277. @@ -501,12 +507,36 @@
  26278.    endif
  26279.  endif
  26280.  
  26281. +ifeq ($(CONFIG_MKISS),y)
  26282. +L_OBJS += mkiss.o
  26283. +else
  26284. +  ifeq ($(CONFIG_MKISS),m)
  26285. +  M_OBJS += mkiss.o
  26286. +  endif
  26287. +endif
  26288. +
  26289.  ifeq ($(CONFIG_PI),y)
  26290.  L_OBJS += pi2.o
  26291. +else
  26292. +  ifeq ($(CONFIG_PI),m)
  26293. +  M_OBJS += pi2.o
  26294. +  endif
  26295.  endif
  26296.  
  26297.  ifeq ($(CONFIG_PT),y)
  26298.  L_OBJS += pt.o
  26299. +else
  26300. +  ifeq ($(CONFIG_PT),m)
  26301. +  M_OBJS += pt.o
  26302. +  endif
  26303. +endif
  26304. +
  26305. +ifeq ($(CONFIG_BPQETHER),y)
  26306. +L_OBJS += bpqether.o
  26307. +else
  26308. +  ifeq ($(CONFIG_BPQETHER),m)
  26309. +  M_OBJS += bpqether.o
  26310. +  endif
  26311.  endif
  26312.  
  26313.  # If anything built-in uses slhc, then build it into the kernel also.
  26314. @@ -516,6 +546,40 @@
  26315.  else
  26316.    ifdef CONFIG_SLHC_MODULE
  26317.    MX_OBJS += slhc.o
  26318. +  endif
  26319. +endif
  26320. +
  26321. +
  26322. +ifeq ($(CONFIG_BAYCOM),y)
  26323. +L_OBJS += baycom.o
  26324. +CONFIG_HDLCDRV_BUILTIN = y
  26325. +else
  26326. +  ifeq ($(CONFIG_BAYCOM),m)
  26327. +  CONFIG_HDLCDRV_MODULE = y
  26328. +  M_OBJS += baycom.o
  26329. +  endif
  26330. +endif
  26331. +
  26332. +ifeq ($(CONFIG_SOUNDMODEM),y)
  26333. +ALL_SUB_DIRS += soundmodem
  26334. +SUB_DIRS += soundmodem
  26335. +L_OBJS += soundmodem/soundmodem.o
  26336. +CONFIG_HDLCDRV_BUILTIN = y
  26337. +else
  26338. +  ifeq ($(CONFIG_SOUNDMODEM),m)
  26339. +  CONFIG_HDLCDRV_MODULE = y
  26340. +  ALL_SUB_DIRS += soundmodem
  26341. +  MOD_SUB_DIRS += soundmodem
  26342. +  endif
  26343. +endif
  26344. +
  26345. +# If anything built-in uses the hdlcdrv, then build it into the kernel also.
  26346. +# If not, but a module uses it, build as a module.
  26347. +ifdef CONFIG_HDLCDRV_BUILTIN
  26348. +LX_OBJS += hdlcdrv.o
  26349. +else
  26350. +  ifdef CONFIG_HDLCDRV_MODULE
  26351. +  MX_OBJS += hdlcdrv.o
  26352.    endif
  26353.  endif
  26354.  
  26355. diff -u --recursive --new-file v2.0.34/linux/drivers/net/Space.c linux/drivers/net/Space.c
  26356. --- v2.0.34/linux/drivers/net/Space.c    Mon Jul 13 13:46:29 1998
  26357. +++ linux/drivers/net/Space.c    Mon Jul 13 13:47:31 1998
  26358. @@ -153,13 +153,13 @@
  26359.  #if defined(CONFIG_SMC9194)
  26360.      && smc_init(dev)
  26361.  #endif
  26362. -#if defined(CONFIG_WD80x3) || defined(WD80x3)
  26363. +#if defined(CONFIG_WD80x3)
  26364.      && wd_probe(dev)
  26365.  #endif
  26366. -#if defined(CONFIG_EL2) || defined(EL2)    /* 3c503 */
  26367. +#if defined(CONFIG_EL2)        /* 3c503 */
  26368.      && el2_probe(dev)
  26369.  #endif
  26370. -#if defined(CONFIG_HPLAN) || defined(HPLAN)
  26371. +#if defined(CONFIG_HPLAN)
  26372.      && hp_probe(dev)
  26373.  #endif
  26374.  #if defined(CONFIG_HPLAN_PLUS)
  26375. @@ -255,9 +255,6 @@
  26376.  #ifdef CONFIG_TLAN
  26377.      && tlan_probe(dev)
  26378.  #endif
  26379. -#ifdef CONFIG_PCNET32
  26380. -    && pcnet32_probe(dev)
  26381. -#endif
  26382.  #ifdef CONFIG_LANCE
  26383.      && lance_probe(dev)
  26384.  #endif
  26385. @@ -275,18 +272,6 @@
  26386.  #   define NEXT_DEV    (&sdla0_dev)
  26387.  #endif
  26388.  
  26389. -#ifdef CONFIG_NETROM
  26390. -    extern int nr_init(struct device *);
  26391. -    
  26392. -    static struct device nr3_dev = { "nr3", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, nr_init, };
  26393. -    static struct device nr2_dev = { "nr2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &nr3_dev, nr_init, };
  26394. -    static struct device nr1_dev = { "nr1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &nr2_dev, nr_init, };
  26395. -    static struct device nr0_dev = { "nr0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &nr1_dev, nr_init, };
  26396. -
  26397. -#   undef NEXT_DEV
  26398. -#   define    NEXT_DEV    (&nr0_dev)
  26399. -#endif
  26400. -
  26401.  /* Run-time ATtachable (Pocket) devices have a different (not "eth#") name. */
  26402.  #ifdef CONFIG_ATP        /* AT-LAN-TEC (RealTek) pocket adaptor. */
  26403.  static struct device atp_dev = {
  26404. @@ -356,6 +341,16 @@
  26405.  #undef NEXT_DEV
  26406.  #define NEXT_DEV (&slip_bootstrap)
  26407.  #endif    /* SLIP */
  26408. +  
  26409. +#if defined(CONFIG_MKISS)
  26410. +    /* To be exact, this node just hooks the initialization
  26411. +       routines to the device structures.            */
  26412. +extern int mkiss_init_ctrl_dev(struct device *);
  26413. +static struct device mkiss_bootstrap = {
  26414. +  "mkiss_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, mkiss_init_ctrl_dev, };
  26415. +#undef NEXT_DEV
  26416. +#define NEXT_DEV (&mkiss_bootstrap)
  26417. +#endif    /* MKISS */
  26418.    
  26419.  #if defined(CONFIG_STRIP)
  26420.  extern int strip_init_ctrl_dev(struct device *);
  26421. diff -u --recursive --new-file v2.0.34/linux/drivers/net/baycom.c linux/drivers/net/baycom.c
  26422. --- v2.0.34/linux/drivers/net/baycom.c    Wed Dec 31 16:00:00 1969
  26423. +++ linux/drivers/net/baycom.c    Mon Jul 13 13:47:31 1998
  26424. @@ -0,0 +1,1068 @@
  26425. +/*****************************************************************************/
  26426. +
  26427. +/*
  26428. + *    baycom.c  -- baycom ser12 and par96 radio modem driver.
  26429. + *
  26430. + *    Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
  26431. + *
  26432. + *    This program is free software; you can redistribute it and/or modify
  26433. + *    it under the terms of the GNU General Public License as published by
  26434. + *    the Free Software Foundation; either version 2 of the License, or
  26435. + *    (at your option) any later version.
  26436. + *
  26437. + *    This program is distributed in the hope that it will be useful,
  26438. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  26439. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26440. + *    GNU General Public License for more details.
  26441. + *
  26442. + *    You should have received a copy of the GNU General Public License
  26443. + *    along with this program; if not, write to the Free Software
  26444. + *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26445. + *
  26446. + *  Please note that the GPL allows you to use the driver, NOT the radio.
  26447. + *  In order to use the radio, you need a license from the communications
  26448. + *  authority of your country.
  26449. + *
  26450. + *
  26451. + *  Supported modems
  26452. + *
  26453. + *  ser12:  This is a very simple 1200 baud AFSK modem. The modem consists only
  26454. + *          of a modulator/demodulator chip, usually a TI TCM3105. The computer
  26455. + *          is responsible for regenerating the receiver bit clock, as well as
  26456. + *          for handling the HDLC protocol. The modem connects to a serial port,
  26457. + *          hence the name. Since the serial port is not used as an async serial
  26458. + *          port, the kernel driver for serial ports cannot be used, and this
  26459. + *          driver only supports standard serial hardware (8250, 16450, 16550)
  26460. + *
  26461. + *  par96:  This is a modem for 9600 baud FSK compatible to the G3RUH standard.
  26462. + *          The modem does all the filtering and regenerates the receiver clock.
  26463. + *          Data is transferred from and to the PC via a shift register.
  26464. + *          The shift register is filled with 16 bits and an interrupt is
  26465. + *          signalled. The PC then empties the shift register in a burst. This
  26466. + *          modem connects to the parallel port, hence the name. The modem
  26467. + *          leaves the implementation of the HDLC protocol and the scrambler
  26468. + *          polynomial to the PC. This modem is no longer available (at least
  26469. + *          from Baycom) and has been replaced by the PICPAR modem (see below).
  26470. + *          You may however still build one from the schematics published in
  26471. + *          cq-DL :-).
  26472. + *
  26473. + *  picpar: This is a redesign of the par96 modem by Henning Rech, DF9IC. The
  26474. + *          modem is protocol compatible to par96, but uses only three low
  26475. + *          power ICs and can therefore be fed from the parallel port and
  26476. + *          does not require an additional power supply. It features
  26477. + *          built in DCD circuitry. The driver should therefore be configured
  26478. + *          for hardware DCD.
  26479. + *
  26480. + *
  26481. + *  Command line options (insmod command line)
  26482. + *
  26483. + *  mode     driver mode string. Valid choices are ser12 and par96. An
  26484. + *           optional * enables software DCD.
  26485. + *           2=par96/par97, any other value invalid
  26486. + *  iobase   base address of the port; common values are for ser12 0x3f8,
  26487. + *           0x2f8, 0x3e8, 0x2e8 and for par96/par97 0x378, 0x278, 0x3bc
  26488. + *  irq      interrupt line of the port; common values are for ser12 3,4
  26489. + *           and for par96/par97 7
  26490. + *
  26491. + *
  26492. + *  History:
  26493. + *   0.1  26.06.96  Adapted from baycom.c and made network driver interface
  26494. + *        18.10.96  Changed to new user space access routines (copy_{to,from}_user)
  26495. + *   0.3  26.04.96  init code/data tagged
  26496. + */
  26497. +
  26498. +/*****************************************************************************/
  26499. +
  26500. +#include <linux/module.h>
  26501. +#include <linux/kernel.h>
  26502. +#include <linux/sched.h>
  26503. +#include <linux/types.h>
  26504. +#include <linux/fcntl.h>
  26505. +#include <linux/interrupt.h>
  26506. +#include <linux/ioport.h>
  26507. +#include <linux/in.h>
  26508. +#include <linux/string.h>
  26509. +#include <asm/system.h>
  26510. +#include <asm/bitops.h>
  26511. +#include <asm/io.h>
  26512. +#include <linux/delay.h>
  26513. +#include <linux/errno.h>
  26514. +#include <linux/netdevice.h>
  26515. +#include <linux/hdlcdrv.h>
  26516. +#include <linux/baycom.h>
  26517. +
  26518. +/* --------------------------------------------------------------------- */
  26519. +
  26520. +/*
  26521. + * currently this module is supposed to support both module styles, i.e.
  26522. + * the old one present up to about 2.1.9, and the new one functioning
  26523. + * starting with 2.1.21. The reason is I have a kit allowing to compile
  26524. + * this module also under 2.0.x which was requested by several people.
  26525. + * This will go in 2.2
  26526. + */
  26527. +#include <linux/version.h>
  26528. +
  26529. +#if LINUX_VERSION_CODE >= 0x20100
  26530. +#include <asm/uaccess.h>
  26531. +#else
  26532. +#include <asm/segment.h>
  26533. +#include <linux/mm.h>
  26534. +
  26535. +#undef put_user
  26536. +#undef get_user
  26537. +
  26538. +#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
  26539. +#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
  26540. +
  26541. +extern inline int copy_from_user(void *to, const void *from, unsigned long n)
  26542. +{
  26543. +        int i = verify_area(VERIFY_READ, from, n);
  26544. +        if (i)
  26545. +                return i;
  26546. +        memcpy_fromfs(to, from, n);
  26547. +        return 0;
  26548. +}
  26549. +
  26550. +extern inline int copy_to_user(void *to, const void *from, unsigned long n)
  26551. +{
  26552. +        int i = verify_area(VERIFY_WRITE, to, n);
  26553. +        if (i)
  26554. +                return i;
  26555. +        memcpy_tofs(to, from, n);
  26556. +        return 0;
  26557. +}
  26558. +#endif
  26559. +
  26560. +#if LINUX_VERSION_CODE >= 0x20123
  26561. +#include <linux/init.h>
  26562. +#else
  26563. +#define __init
  26564. +#define __initdata
  26565. +#define __initfunc(x) x
  26566. +#endif
  26567. +
  26568. +/* --------------------------------------------------------------------- */
  26569. +
  26570. +#define BAYCOM_DEBUG
  26571. +
  26572. +/*
  26573. + * modem options; bit mask
  26574. + */
  26575. +#define BAYCOM_OPTIONS_SOFTDCD  1
  26576. +
  26577. +/* --------------------------------------------------------------------- */
  26578. +
  26579. +static const char bc_drvname[] = "baycom";
  26580. +static const char bc_drvinfo[] = KERN_INFO "baycom: (C) 1996 Thomas Sailer, HB9JNX/AE4WA\n"
  26581. +KERN_INFO "baycom: version 0.3 compiled " __TIME__ " " __DATE__ "\n";
  26582. +
  26583. +/* --------------------------------------------------------------------- */
  26584. +
  26585. +#define NR_PORTS 4
  26586. +
  26587. +static struct device baycom_device[NR_PORTS];
  26588. +
  26589. +static struct {
  26590. +    char *mode;
  26591. +    int iobase, irq;
  26592. +} baycom_ports[NR_PORTS] = { { NULL, 0, 0 }, };
  26593. +
  26594. +/* --------------------------------------------------------------------- */
  26595. +
  26596. +#define RBR(iobase) (iobase+0)
  26597. +#define THR(iobase) (iobase+0)
  26598. +#define IER(iobase) (iobase+1)
  26599. +#define IIR(iobase) (iobase+2)
  26600. +#define FCR(iobase) (iobase+2)
  26601. +#define LCR(iobase) (iobase+3)
  26602. +#define MCR(iobase) (iobase+4)
  26603. +#define LSR(iobase) (iobase+5)
  26604. +#define MSR(iobase) (iobase+6)
  26605. +#define SCR(iobase) (iobase+7)
  26606. +#define DLL(iobase) (iobase+0)
  26607. +#define DLM(iobase) (iobase+1)
  26608. +
  26609. +#define SER12_EXTENT 8
  26610. +
  26611. +#define LPT_DATA(iobase)    (iobase+0)
  26612. +#define LPT_STATUS(iobase)  (iobase+1)
  26613. +#define LPT_CONTROL(iobase) (iobase+2)
  26614. +#define LPT_IRQ_ENABLE      0x10
  26615. +#define PAR96_BURSTBITS 16
  26616. +#define PAR96_BURST     4
  26617. +#define PAR96_PTT       2
  26618. +#define PAR96_TXBIT     1
  26619. +#define PAR96_ACK       0x40
  26620. +#define PAR96_RXBIT     0x20
  26621. +#define PAR96_DCD       0x10
  26622. +#define PAR97_POWER     0xf8
  26623. +
  26624. +#define PAR96_EXTENT 3
  26625. +
  26626. +/* ---------------------------------------------------------------------- */
  26627. +/*
  26628. + * Information that need to be kept for each board.
  26629. + */
  26630. +
  26631. +struct baycom_state {
  26632. +    struct hdlcdrv_state hdrv;
  26633. +
  26634. +    unsigned int options;
  26635. +
  26636. +    struct modem_state {
  26637. +        short arb_divider;
  26638. +        unsigned char flags;
  26639. +        unsigned int shreg;
  26640. +        struct modem_state_ser12 {
  26641. +            unsigned char last_sample;
  26642. +            unsigned char interm_sample;
  26643. +            unsigned int bit_pll;
  26644. +            unsigned int dcd_shreg;
  26645. +            int dcd_sum0, dcd_sum1, dcd_sum2;
  26646. +            unsigned int dcd_time;
  26647. +            unsigned char last_rxbit;
  26648. +            unsigned char tx_bit;
  26649. +        } ser12;
  26650. +        struct modem_state_par96 {
  26651. +            int dcd_count;
  26652. +            unsigned int dcd_shreg;
  26653. +            unsigned long descram;
  26654. +            unsigned long scram;
  26655. +        } par96;
  26656. +    } modem;
  26657. +
  26658. +#ifdef BAYCOM_DEBUG
  26659. +    struct debug_vals {
  26660. +        unsigned long last_jiffies;
  26661. +        unsigned cur_intcnt;
  26662. +        unsigned last_intcnt;
  26663. +        int cur_pllcorr;
  26664. +        int last_pllcorr;
  26665. +    } debug_vals;
  26666. +#endif /* BAYCOM_DEBUG */
  26667. +};
  26668. +
  26669. +/* --------------------------------------------------------------------- */
  26670. +
  26671. +#define min(a, b) (((a) < (b)) ? (a) : (b))
  26672. +#define max(a, b) (((a) > (b)) ? (a) : (b))
  26673. +
  26674. +/* --------------------------------------------------------------------- */
  26675. +
  26676. +static void inline baycom_int_freq(struct baycom_state *bc)
  26677. +{
  26678. +#ifdef BAYCOM_DEBUG
  26679. +    unsigned long cur_jiffies = jiffies;
  26680. +    /*
  26681. +     * measure the interrupt frequency
  26682. +     */
  26683. +    bc->debug_vals.cur_intcnt++;
  26684. +    if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) {
  26685. +        bc->debug_vals.last_jiffies = cur_jiffies;
  26686. +        bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
  26687. +        bc->debug_vals.cur_intcnt = 0;
  26688. +        bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
  26689. +        bc->debug_vals.cur_pllcorr = 0;
  26690. +    }
  26691. +#endif /* BAYCOM_DEBUG */
  26692. +}
  26693. +
  26694. +/* --------------------------------------------------------------------- */
  26695. +/*
  26696. + * ===================== SER12 specific routines =========================
  26697. + */
  26698. +
  26699. +static void inline ser12_set_divisor(struct device *dev,
  26700. +                     unsigned char divisor)
  26701. +{
  26702. +    outb(0x81, LCR(dev->base_addr));    /* DLAB = 1 */
  26703. +    outb(divisor, DLL(dev->base_addr));
  26704. +    outb(0, DLM(dev->base_addr));
  26705. +    outb(0x01, LCR(dev->base_addr));    /* word length = 6 */
  26706. +    /*
  26707. +     * make sure the next interrupt is generated;
  26708. +     * 0 must be used to power the modem; the modem draws its
  26709. +     * power from the TxD line
  26710. +     */
  26711. +    outb(0x00, THR(dev->base_addr));
  26712. +    /*
  26713. +     * it is important not to set the divider while transmitting;
  26714. +     * this reportedly makes some UARTs generating interrupts
  26715. +     * in the hundredthousands per second region
  26716. +     * Reported by: Ignacio.Arenaza@studi.epfl.ch (Ignacio Arenaza Nuno)
  26717. +     */
  26718. +}
  26719. +
  26720. +/* --------------------------------------------------------------------- */
  26721. +
  26722. +/*
  26723. + * must call the TX arbitrator every 10ms
  26724. + */
  26725. +#define SER12_ARB_DIVIDER(bc) ((bc->options & BAYCOM_OPTIONS_SOFTDCD) ? \
  26726. +                   36 : 24)
  26727. +#define SER12_DCD_INTERVAL(bc) ((bc->options & BAYCOM_OPTIONS_SOFTDCD) ? \
  26728. +                240 : 12)
  26729. +
  26730. +static inline void ser12_tx(struct device *dev, struct baycom_state *bc)
  26731. +{
  26732. +    /* one interrupt per channel bit */
  26733. +    ser12_set_divisor(dev, 12);
  26734. +    /*
  26735. +     * first output the last bit (!) then call HDLC transmitter,
  26736. +     * since this may take quite long
  26737. +     */
  26738. +    outb(0x0e | (!!bc->modem.ser12.tx_bit), MCR(dev->base_addr));
  26739. +    if (bc->modem.shreg <= 1)
  26740. +        bc->modem.shreg = 0x10000 | hdlcdrv_getbits(&bc->hdrv);
  26741. +    bc->modem.ser12.tx_bit = !(bc->modem.ser12.tx_bit ^
  26742. +                   (bc->modem.shreg & 1));
  26743. +    bc->modem.shreg >>= 1;
  26744. +}
  26745. +
  26746. +/* --------------------------------------------------------------------- */
  26747. +
  26748. +static inline void ser12_rx(struct device *dev, struct baycom_state *bc)
  26749. +{
  26750. +    unsigned char cur_s;
  26751. +    /*
  26752. +     * do demodulator
  26753. +     */
  26754. +    cur_s = inb(MSR(dev->base_addr)) & 0x10;    /* the CTS line */
  26755. +    hdlcdrv_channelbit(&bc->hdrv, cur_s);
  26756. +    bc->modem.ser12.dcd_shreg = (bc->modem.ser12.dcd_shreg << 1) |
  26757. +        (cur_s != bc->modem.ser12.last_sample);
  26758. +    bc->modem.ser12.last_sample = cur_s;
  26759. +    if(bc->modem.ser12.dcd_shreg & 1) {
  26760. +        if (bc->options & BAYCOM_OPTIONS_SOFTDCD) {
  26761. +            unsigned int dcdspos, dcdsneg;
  26762. +
  26763. +            dcdspos = dcdsneg = 0;
  26764. +            dcdspos += ((bc->modem.ser12.dcd_shreg >> 1) & 1);
  26765. +            if (!(bc->modem.ser12.dcd_shreg & 0x7ffffffe))
  26766. +                dcdspos += 2;
  26767. +            dcdsneg += ((bc->modem.ser12.dcd_shreg >> 2) & 1);
  26768. +            dcdsneg += ((bc->modem.ser12.dcd_shreg >> 3) & 1);
  26769. +            dcdsneg += ((bc->modem.ser12.dcd_shreg >> 4) & 1);
  26770. +
  26771. +            bc->modem.ser12.dcd_sum0 += 16*dcdspos - dcdsneg;
  26772. +        } else
  26773. +            bc->modem.ser12.dcd_sum0--;
  26774. +    }
  26775. +    if(!bc->modem.ser12.dcd_time) {
  26776. +        hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
  26777. +                       bc->modem.ser12.dcd_sum1 +
  26778. +                       bc->modem.ser12.dcd_sum2) < 0);
  26779. +        bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
  26780. +        bc->modem.ser12.dcd_sum1 = bc->modem.ser12.dcd_sum0;
  26781. +        /* offset to ensure DCD off on silent input */
  26782. +        bc->modem.ser12.dcd_sum0 = 2;
  26783. +        bc->modem.ser12.dcd_time = SER12_DCD_INTERVAL(bc);
  26784. +    }
  26785. +    bc->modem.ser12.dcd_time--;
  26786. +    if (bc->options & BAYCOM_OPTIONS_SOFTDCD) {
  26787. +        /*
  26788. +         * PLL code for the improved software DCD algorithm
  26789. +         */
  26790. +        if (bc->modem.ser12.interm_sample) {
  26791. +            /*
  26792. +             * intermediate sample; set timing correction to normal
  26793. +             */
  26794. +            ser12_set_divisor(dev, 4);
  26795. +        } else {
  26796. +            /*
  26797. +             * do PLL correction and call HDLC receiver
  26798. +             */
  26799. +            switch (bc->modem.ser12.dcd_shreg & 7) {
  26800. +            case 1: /* transition too late */
  26801. +                ser12_set_divisor(dev, 5);
  26802. +#ifdef BAYCOM_DEBUG
  26803. +                bc->debug_vals.cur_pllcorr++;
  26804. +#endif /* BAYCOM_DEBUG */
  26805. +                break;
  26806. +            case 4:    /* transition too early */
  26807. +                ser12_set_divisor(dev, 3);
  26808. +#ifdef BAYCOM_DEBUG
  26809. +                bc->debug_vals.cur_pllcorr--;
  26810. +#endif /* BAYCOM_DEBUG */
  26811. +                break;
  26812. +            default:
  26813. +                ser12_set_divisor(dev, 4);
  26814. +                break;
  26815. +            }
  26816. +            bc->modem.shreg >>= 1;
  26817. +            if (bc->modem.ser12.last_sample ==
  26818. +                bc->modem.ser12.last_rxbit)
  26819. +                bc->modem.shreg |= 0x10000;
  26820. +            bc->modem.ser12.last_rxbit =
  26821. +                bc->modem.ser12.last_sample;
  26822. +        }
  26823. +        if (++bc->modem.ser12.interm_sample >= 3)
  26824. +            bc->modem.ser12.interm_sample = 0;
  26825. +        /*
  26826. +         * DCD stuff
  26827. +         */
  26828. +        if (bc->modem.ser12.dcd_shreg & 1) {
  26829. +            unsigned int dcdspos, dcdsneg;
  26830. +
  26831. +            dcdspos = dcdsneg = 0;
  26832. +            dcdspos += ((bc->modem.ser12.dcd_shreg >> 1) & 1);
  26833. +            dcdspos += (!(bc->modem.ser12.dcd_shreg & 0x7ffffffe))
  26834. +                << 1;
  26835. +            dcdsneg += ((bc->modem.ser12.dcd_shreg >> 2) & 1);
  26836. +            dcdsneg += ((bc->modem.ser12.dcd_shreg >> 3) & 1);
  26837. +            dcdsneg += ((bc->modem.ser12.dcd_shreg >> 4) & 1);
  26838. +
  26839. +            bc->modem.ser12.dcd_sum0 += 16*dcdspos - dcdsneg;
  26840. +        }
  26841. +    } else {
  26842. +        /*
  26843. +         * PLL algorithm for the hardware squelch DCD algorithm
  26844. +         */
  26845. +        if (bc->modem.ser12.interm_sample) {
  26846. +            /*
  26847. +             * intermediate sample; set timing correction to normal
  26848. +             */
  26849. +            ser12_set_divisor(dev, 6);
  26850. +        } else {
  26851. +            /*
  26852. +             * do PLL correction and call HDLC receiver
  26853. +             */
  26854. +            switch (bc->modem.ser12.dcd_shreg & 3) {
  26855. +            case 1: /* transition too late */
  26856. +                ser12_set_divisor(dev, 7);
  26857. +#ifdef BAYCOM_DEBUG
  26858. +                bc->debug_vals.cur_pllcorr++;
  26859. +#endif /* BAYCOM_DEBUG */
  26860. +                break;
  26861. +            case 2:    /* transition too early */
  26862. +                ser12_set_divisor(dev, 5);
  26863. +#ifdef BAYCOM_DEBUG
  26864. +                bc->debug_vals.cur_pllcorr--;
  26865. +#endif /* BAYCOM_DEBUG */
  26866. +                break;
  26867. +            default:
  26868. +                ser12_set_divisor(dev, 6);
  26869. +                break;
  26870. +            }
  26871. +            bc->modem.shreg >>= 1;
  26872. +            if (bc->modem.ser12.last_sample ==
  26873. +                bc->modem.ser12.last_rxbit)
  26874. +                bc->modem.shreg |= 0x10000;
  26875. +            bc->modem.ser12.last_rxbit =
  26876. +                bc->modem.ser12.last_sample;
  26877. +        }
  26878. +        bc->modem.ser12.interm_sample = !bc->modem.ser12.interm_sample;
  26879. +        /*
  26880. +         * DCD stuff
  26881. +         */
  26882. +        bc->modem.ser12.dcd_sum0 -= (bc->modem.ser12.dcd_shreg & 1);
  26883. +    }
  26884. +    outb(0x0d, MCR(dev->base_addr));        /* transmitter off */
  26885. +    if (bc->modem.shreg & 1) {
  26886. +        hdlcdrv_putbits(&bc->hdrv, bc->modem.shreg >> 1);
  26887. +        bc->modem.shreg = 0x10000;
  26888. +    }
  26889. +    if(!bc->modem.ser12.dcd_time) {
  26890. +        hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
  26891. +                       bc->modem.ser12.dcd_sum1 +
  26892. +                       bc->modem.ser12.dcd_sum2) < 0);
  26893. +        bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
  26894. +        bc->modem.ser12.dcd_sum1 = bc->modem.ser12.dcd_sum0;
  26895. +        /* offset to ensure DCD off on silent input */
  26896. +        bc->modem.ser12.dcd_sum0 = 2;
  26897. +        bc->modem.ser12.dcd_time = SER12_DCD_INTERVAL(bc);
  26898. +    }
  26899. +    bc->modem.ser12.dcd_time--;
  26900. +}
  26901. +
  26902. +/* --------------------------------------------------------------------- */
  26903. +
  26904. +static void ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  26905. +{
  26906. +    struct device *dev = (struct device *)dev_id;
  26907. +    struct baycom_state *bc = (struct baycom_state *)dev->priv;
  26908. +
  26909. +    if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC)
  26910. +        return;
  26911. +
  26912. +    baycom_int_freq(bc);
  26913. +    /*
  26914. +     * check if transmitter active
  26915. +     */
  26916. +    if (hdlcdrv_ptt(&bc->hdrv))
  26917. +        ser12_tx(dev, bc);
  26918. +    else {
  26919. +        ser12_rx(dev, bc);
  26920. +        if (--bc->modem.arb_divider <= 0) {
  26921. +            bc->modem.arb_divider = SER12_ARB_DIVIDER(bc);
  26922. +            sti();
  26923. +            hdlcdrv_arbitrate(dev, &bc->hdrv);
  26924. +        }
  26925. +    }
  26926. +    sti();
  26927. +    hdlcdrv_transmitter(dev, &bc->hdrv);
  26928. +    hdlcdrv_receiver(dev, &bc->hdrv);
  26929. +}
  26930. +
  26931. +/* --------------------------------------------------------------------- */
  26932. +
  26933. +enum uart { c_uart_unknown, c_uart_8250,
  26934. +    c_uart_16450, c_uart_16550, c_uart_16550A};
  26935. +static const char *uart_str[] =
  26936. +    { "unknown", "8250", "16450", "16550", "16550A" };
  26937. +
  26938. +static enum uart ser12_check_uart(unsigned int iobase)
  26939. +{
  26940. +    unsigned char b1,b2,b3;
  26941. +    enum uart u;
  26942. +    enum uart uart_tab[] =
  26943. +        { c_uart_16450, c_uart_unknown, c_uart_16550, c_uart_16550A };
  26944. +
  26945. +    b1 = inb(MCR(iobase));
  26946. +    outb(b1 | 0x10, MCR(iobase));    /* loopback mode */
  26947. +    b2 = inb(MSR(iobase));
  26948. +    outb(0x1a, MCR(iobase));
  26949. +    b3 = inb(MSR(iobase)) & 0xf0;
  26950. +    outb(b1, MCR(iobase));            /* restore old values */
  26951. +    outb(b2, MSR(iobase));
  26952. +    if (b3 != 0x90)
  26953. +        return c_uart_unknown;
  26954. +    inb(RBR(iobase));
  26955. +    inb(RBR(iobase));
  26956. +    outb(0x01, FCR(iobase));        /* enable FIFOs */
  26957. +    u = uart_tab[(inb(IIR(iobase)) >> 6) & 3];
  26958. +    if (u == c_uart_16450) {
  26959. +        outb(0x5a, SCR(iobase));
  26960. +        b1 = inb(SCR(iobase));
  26961. +        outb(0xa5, SCR(iobase));
  26962. +        b2 = inb(SCR(iobase));
  26963. +        if ((b1 != 0x5a) || (b2 != 0xa5))
  26964. +            u = c_uart_8250;
  26965. +    }
  26966. +    return u;
  26967. +}
  26968. +
  26969. +/* --------------------------------------------------------------------- */
  26970. +
  26971. +static int ser12_open(struct device *dev)
  26972. +{
  26973. +    struct baycom_state *bc = (struct baycom_state *)dev->priv;
  26974. +    enum uart u;
  26975. +
  26976. +    if (!dev || !bc)
  26977. +        return -ENXIO;
  26978. +    if (!dev->base_addr || dev->base_addr > 0x1000-SER12_EXTENT ||
  26979. +        dev->irq < 2 || dev->irq > 15)
  26980. +        return -ENXIO;
  26981. +    if (check_region(dev->base_addr, SER12_EXTENT))
  26982. +        return -EACCES;
  26983. +    memset(&bc->modem, 0, sizeof(bc->modem));
  26984. +    bc->hdrv.par.bitrate = 1200;
  26985. +    if ((u = ser12_check_uart(dev->base_addr)) == c_uart_unknown)
  26986. +        return -EIO;
  26987. +    outb(0, FCR(dev->base_addr));  /* disable FIFOs */
  26988. +    outb(0x0d, MCR(dev->base_addr));
  26989. +    outb(0x0d, MCR(dev->base_addr));
  26990. +    outb(0, IER(dev->base_addr));
  26991. +    if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT,
  26992. +            "baycom_ser12", dev))
  26993. +        return -EBUSY;
  26994. +    request_region(dev->base_addr, SER12_EXTENT, "baycom_ser12");
  26995. +    /*
  26996. +     * enable transmitter empty interrupt
  26997. +     */
  26998. +    outb(2, IER(dev->base_addr));
  26999. +    /*
  27000. +     * set the SIO to 6 Bits/character and 19200 or 28800 baud, so that
  27001. +     * we get exactly (hopefully) 2 or 3 interrupts per radio symbol,
  27002. +     * depending on the usage of the software DCD routine
  27003. +     */
  27004. +    ser12_set_divisor(dev, (bc->options & BAYCOM_OPTIONS_SOFTDCD) ? 4 : 6);
  27005. +    printk(KERN_INFO "%s: ser12 at iobase 0x%lx irq %u options "
  27006. +           "0x%x uart %s\n", bc_drvname, dev->base_addr, dev->irq,
  27007. +           bc->options, uart_str[u]);
  27008. +    MOD_INC_USE_COUNT;
  27009. +    return 0;
  27010. +}
  27011. +
  27012. +/* --------------------------------------------------------------------- */
  27013. +
  27014. +static int ser12_close(struct device *dev)
  27015. +{
  27016. +    struct baycom_state *bc = (struct baycom_state *)dev->priv;
  27017. +
  27018. +    if (!dev || !bc)
  27019. +        return -EINVAL;
  27020. +    /*
  27021. +     * disable interrupts
  27022. +     */
  27023. +    outb(0, IER(dev->base_addr));
  27024. +    outb(1, MCR(dev->base_addr));
  27025. +    free_irq(dev->irq, dev);
  27026. +    release_region(dev->base_addr, SER12_EXTENT);
  27027. +    printk(KERN_INFO "%s: close ser12 at iobase 0x%lx irq %u\n",
  27028. +           bc_drvname, dev->base_addr, dev->irq);
  27029. +    MOD_DEC_USE_COUNT;
  27030. +    return 0;
  27031. +}
  27032. +
  27033. +/* --------------------------------------------------------------------- */
  27034. +/*
  27035. + * ===================== PAR96 specific routines =========================
  27036. + */
  27037. +
  27038. +#define PAR96_DESCRAM_TAP1 0x20000
  27039. +#define PAR96_DESCRAM_TAP2 0x01000
  27040. +#define PAR96_DESCRAM_TAP3 0x00001
  27041. +
  27042. +#define PAR96_DESCRAM_TAPSH1 17
  27043. +#define PAR96_DESCRAM_TAPSH2 12
  27044. +#define PAR96_DESCRAM_TAPSH3 0
  27045. +
  27046. +#define PAR96_SCRAM_TAP1 0x20000 /* X^17 */
  27047. +#define PAR96_SCRAM_TAPN 0x00021 /* X^0+X^5 */
  27048. +
  27049. +/* --------------------------------------------------------------------- */
  27050. +
  27051. +static inline void par96_tx(struct device *dev, struct baycom_state *bc)
  27052. +{
  27053. +    int i;
  27054. +    unsigned int data = hdlcdrv_getbits(&bc->hdrv);
  27055. +
  27056. +    for(i = 0; i < PAR96_BURSTBITS; i++, data >>= 1) {
  27057. +        unsigned char val = PAR97_POWER;
  27058. +        bc->modem.par96.scram = ((bc->modem.par96.scram << 1) |
  27059. +                     (bc->modem.par96.scram & 1));
  27060. +        if (!(data & 1))
  27061. +            bc->modem.par96.scram ^= 1;
  27062. +        if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 1))
  27063. +            bc->modem.par96.scram ^=
  27064. +                (PAR96_SCRAM_TAPN << 1);
  27065. +        if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 2))
  27066. +            val |= PAR96_TXBIT;
  27067. +        outb(val, LPT_DATA(dev->base_addr));
  27068. +        outb(val | PAR96_BURST, LPT_DATA(dev->base_addr));
  27069. +    }
  27070. +}
  27071. +
  27072. +/* --------------------------------------------------------------------- */
  27073. +
  27074. +static inline void par96_rx(struct device *dev, struct baycom_state *bc)
  27075. +{
  27076. +    int i;
  27077. +    unsigned int data, mask, mask2, descx;
  27078. +
  27079. +    /*
  27080. +     * do receiver; differential decode and descramble on the fly
  27081. +     */
  27082. +    for(data = i = 0; i < PAR96_BURSTBITS; i++) {
  27083. +        bc->modem.par96.descram = (bc->modem.par96.descram << 1);
  27084. +        if (inb(LPT_STATUS(dev->base_addr)) & PAR96_RXBIT)
  27085. +            bc->modem.par96.descram |= 1;
  27086. +        descx = bc->modem.par96.descram ^
  27087. +            (bc->modem.par96.descram >> 1);
  27088. +        /* now the diff decoded data is inverted in descram */
  27089. +        outb(PAR97_POWER | PAR96_PTT, LPT_DATA(dev->base_addr));
  27090. +        descx ^= ((descx >> PAR96_DESCRAM_TAPSH1) ^
  27091. +              (descx >> PAR96_DESCRAM_TAPSH2));
  27092. +        data >>= 1;
  27093. +        if (!(descx & 1))
  27094. +            data |= 0x8000;
  27095. +        outb(PAR97_POWER | PAR96_PTT | PAR96_BURST,
  27096. +             LPT_DATA(dev->base_addr));
  27097. +    }
  27098. +    hdlcdrv_putbits(&bc->hdrv, data);
  27099. +    /*
  27100. +     * do DCD algorithm
  27101. +     */
  27102. +    if (bc->options & BAYCOM_OPTIONS_SOFTDCD) {
  27103. +        bc->modem.par96.dcd_shreg = (bc->modem.par96.dcd_shreg >> 16)
  27104. +            | (data << 16);
  27105. +        /* search for flags and set the dcd counter appropriately */
  27106. +        for(mask = 0x1fe00, mask2 = 0xfc00, i = 0;
  27107. +            i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
  27108. +            if ((bc->modem.par96.dcd_shreg & mask) == mask2)
  27109. +                bc->modem.par96.dcd_count = HDLCDRV_MAXFLEN+4;
  27110. +        /* check for abort/noise sequences */
  27111. +        for(mask = 0x1fe00, mask2 = 0x1fe00, i = 0;
  27112. +            i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
  27113. +            if (((bc->modem.par96.dcd_shreg & mask) == mask2) &&
  27114. +                (bc->modem.par96.dcd_count >= 0))
  27115. +                bc->modem.par96.dcd_count -= HDLCDRV_MAXFLEN-10;
  27116. +        /* decrement and set the dcd variable */
  27117. +        if (bc->modem.par96.dcd_count >= 0)
  27118. +            bc->modem.par96.dcd_count -= 2;
  27119. +        hdlcdrv_setdcd(&bc->hdrv, bc->modem.par96.dcd_count > 0);
  27120. +    } else {
  27121. +        hdlcdrv_setdcd(&bc->hdrv, !!(inb(LPT_STATUS(dev->base_addr))
  27122. +                         & PAR96_DCD));
  27123. +    }
  27124. +}
  27125. +
  27126. +/* --------------------------------------------------------------------- */
  27127. +
  27128. +static void par96_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  27129. +{
  27130. +    struct device *dev = (struct device *)dev_id;
  27131. +    struct baycom_state *bc = (struct baycom_state *)dev->priv;
  27132. +
  27133. +    if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC)
  27134. +        return;
  27135. +
  27136. +    baycom_int_freq(bc);
  27137. +    /*
  27138. +     * check if transmitter active
  27139. +     */
  27140. +    if (hdlcdrv_ptt(&bc->hdrv))
  27141. +        par96_tx(dev, bc);
  27142. +    else {
  27143. +        par96_rx(dev, bc);
  27144. +        if (--bc->modem.arb_divider <= 0) {
  27145. +            bc->modem.arb_divider = 6;
  27146. +            sti();
  27147. +            hdlcdrv_arbitrate(dev, &bc->hdrv);
  27148. +        }
  27149. +    }
  27150. +    sti();
  27151. +    hdlcdrv_transmitter(dev, &bc->hdrv);
  27152. +    hdlcdrv_receiver(dev, &bc->hdrv);
  27153. +}
  27154. +
  27155. +/* --------------------------------------------------------------------- */
  27156. +
  27157. +static int par96_check_lpt(unsigned int iobase)
  27158. +{
  27159. +    unsigned char b1,b2;
  27160. +    int i;
  27161. +
  27162. +    b1 = inb(LPT_DATA(iobase));
  27163. +    b2 = inb(LPT_CONTROL(iobase));
  27164. +    outb(0xaa, LPT_DATA(iobase));
  27165. +    i = inb(LPT_DATA(iobase)) == 0xaa;
  27166. +    outb(0x55, LPT_DATA(iobase));
  27167. +    i &= inb(LPT_DATA(iobase)) == 0x55;
  27168. +    outb(0x0a, LPT_CONTROL(iobase));
  27169. +    i &= (inb(LPT_CONTROL(iobase)) & 0xf) == 0x0a;
  27170. +    outb(0x05, LPT_CONTROL(iobase));
  27171. +    i &= (inb(LPT_CONTROL(iobase)) & 0xf) == 0x05;
  27172. +    outb(b1, LPT_DATA(iobase));
  27173. +    outb(b2, LPT_CONTROL(iobase));
  27174. +    return !i;
  27175. +}
  27176. +
  27177. +/* --------------------------------------------------------------------- */
  27178. +
  27179. +static int par96_open(struct device *dev)
  27180. +{
  27181. +    struct baycom_state *bc = (struct baycom_state *)dev->priv;
  27182. +
  27183. +    if (!dev || !bc)
  27184. +        return -ENXIO;
  27185. +    if (!dev->base_addr || dev->base_addr > 0x1000-PAR96_EXTENT ||
  27186. +        dev->irq < 2 || dev->irq > 15)
  27187. +        return -ENXIO;
  27188. +    if (check_region(dev->base_addr, PAR96_EXTENT))
  27189. +        return -EACCES;
  27190. +    memset(&bc->modem, 0, sizeof(bc->modem));
  27191. +    bc->hdrv.par.bitrate = 9600;
  27192. +    if (par96_check_lpt(dev->base_addr))
  27193. +        return -EIO;
  27194. +    /* disable interrupt */
  27195. +    outb(0, LPT_CONTROL(dev->base_addr));
  27196. +     /* switch off PTT */
  27197. +    outb(PAR96_PTT | PAR97_POWER, LPT_DATA(dev->base_addr));
  27198. +    printk(KERN_INFO "%s: par96 at iobase 0x%lx irq %u options 0x%x\n",
  27199. +           bc_drvname, dev->base_addr, dev->irq, bc->options);
  27200. +    if (request_irq(dev->irq, par96_interrupt, SA_INTERRUPT,
  27201. +            "baycom_par96", dev))
  27202. +        return -EBUSY;
  27203. +    request_region(dev->base_addr, PAR96_EXTENT, "baycom_par96");
  27204. +    /* enable interrupt */
  27205. +    outb(LPT_IRQ_ENABLE, LPT_CONTROL(dev->base_addr));
  27206. +    MOD_INC_USE_COUNT;
  27207. +    return 0;
  27208. +}
  27209. +
  27210. +/* --------------------------------------------------------------------- */
  27211. +
  27212. +static int par96_close(struct device *dev)
  27213. +{
  27214. +    struct baycom_state *bc = (struct baycom_state *)dev->priv;
  27215. +
  27216. +    if (!dev || !bc)
  27217. +        return -EINVAL;
  27218. +    /* disable interrupt */
  27219. +    outb(0, LPT_CONTROL(dev->base_addr));
  27220. +    /* switch off PTT */
  27221. +    outb(PAR96_PTT | PAR97_POWER, LPT_DATA(dev->base_addr));
  27222. +    free_irq(dev->irq, dev);
  27223. +    release_region(dev->base_addr, PAR96_EXTENT);
  27224. +    printk(KERN_INFO "%s: close par96 at iobase 0x%lx irq %u\n",
  27225. +           bc_drvname, dev->base_addr, dev->irq);
  27226. +    MOD_DEC_USE_COUNT;
  27227. +    return 0;
  27228. +}
  27229. +
  27230. +/* --------------------------------------------------------------------- */
  27231. +/*
  27232. + * ===================== hdlcdrv driver interface =========================
  27233. + */
  27234. +
  27235. +/* --------------------------------------------------------------------- */
  27236. +
  27237. +static int baycom_ioctl(struct device *dev, struct ifreq *ifr,
  27238. +            struct hdlcdrv_ioctl *hi, int cmd);
  27239. +
  27240. +/* --------------------------------------------------------------------- */
  27241. +
  27242. +static struct hdlcdrv_ops ser12_ops = {
  27243. +    bc_drvname,
  27244. +    bc_drvinfo,
  27245. +    ser12_open,
  27246. +    ser12_close,
  27247. +    baycom_ioctl
  27248. +};
  27249. +
  27250. +/* --------------------------------------------------------------------- */
  27251. +
  27252. +static struct hdlcdrv_ops par96_ops = {
  27253. +    bc_drvname,
  27254. +    bc_drvinfo,
  27255. +    par96_open,
  27256. +    par96_close,
  27257. +    baycom_ioctl
  27258. +};
  27259. +
  27260. +/* --------------------------------------------------------------------- */
  27261. +
  27262. +static struct hdlcdrv_ops dummy_ops = {
  27263. +    bc_drvname,
  27264. +    bc_drvinfo,
  27265. +    NULL,
  27266. +    NULL,
  27267. +    baycom_ioctl
  27268. +};
  27269. +
  27270. +/* --------------------------------------------------------------------- */
  27271. +
  27272. +static int baycom_setmode(struct baycom_state *bc, char *modestr)
  27273. +{
  27274. +    struct hdlcdrv_ops *newops = NULL;
  27275. +    unsigned long flags;
  27276. +
  27277. +    if (!strncmp(modestr, "off", 3))
  27278. +        newops = &dummy_ops;
  27279. +    else if (!strncmp(modestr, "ser12", 5))
  27280. +        newops = &ser12_ops;
  27281. +    else if (!strncmp(modestr, "par96", 5))
  27282. +        newops = &par96_ops;
  27283. +    else
  27284. +        return -EINVAL;
  27285. +    save_flags(flags);
  27286. +    cli();
  27287. +    bc->hdrv.ops = newops;
  27288. +    bc->options = !!strchr(modestr, '*');
  27289. +    restore_flags(flags);
  27290. +    return 0;
  27291. +}
  27292. +
  27293. +/* --------------------------------------------------------------------- */
  27294. +
  27295. +static int baycom_ioctl(struct device *dev, struct ifreq *ifr,
  27296. +            struct hdlcdrv_ioctl *hi, int cmd)
  27297. +{
  27298. +    struct baycom_state *bc;
  27299. +    struct baycom_ioctl bi;
  27300. +    int cmd2;
  27301. +
  27302. +    if (!dev || !dev->priv ||
  27303. +        ((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
  27304. +        printk(KERN_ERR "bc_ioctl: invalid device struct\n");
  27305. +        return -EINVAL;
  27306. +    }
  27307. +    bc = (struct baycom_state *)dev->priv;
  27308. +
  27309. +    if (cmd != SIOCDEVPRIVATE)
  27310. +        return -ENOIOCTLCMD;
  27311. +    if (get_user(cmd2, (int *)ifr->ifr_data))
  27312. +        return -EFAULT;
  27313. +    switch (hi->cmd) {
  27314. +    default:
  27315. +        break;
  27316. +
  27317. +    case HDLCDRVCTL_GETMODE:
  27318. +        if (bc->hdrv.ops == &ser12_ops)
  27319. +            strcpy(hi->data.modename, "ser12");
  27320. +        else if (bc->hdrv.ops == &par96_ops)
  27321. +            strcpy(hi->data.modename, "par96");
  27322. +        else if (bc->hdrv.ops == &dummy_ops)
  27323. +            strcpy(hi->data.modename, "off");
  27324. +        else
  27325. +            strcpy(hi->data.modename, "invalid");
  27326. +        if (bc->options & 1)
  27327. +            strcat(hi->data.modename, "*");
  27328. +        if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
  27329. +            return -EFAULT;
  27330. +        return 0;
  27331. +
  27332. +    case HDLCDRVCTL_SETMODE:
  27333. +        if (!suser() || dev->start)
  27334. +            return -EACCES;
  27335. +        hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
  27336. +        return baycom_setmode(bc, hi->data.modename);
  27337. +
  27338. +    case HDLCDRVCTL_MODELIST:
  27339. +        strcpy(hi->data.modename, "ser12,par96");
  27340. +        if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
  27341. +            return -EFAULT;
  27342. +        return 0;
  27343. +
  27344. +    case HDLCDRVCTL_MODEMPARMASK:
  27345. +        return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ;
  27346. +
  27347. +    }
  27348. +
  27349. +    if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
  27350. +        return -EFAULT;
  27351. +    switch (bi.cmd) {
  27352. +    default:
  27353. +        return -ENOIOCTLCMD;
  27354. +
  27355. +#ifdef BAYCOM_DEBUG
  27356. +    case BAYCOMCTL_GETDEBUG:
  27357. +        bi.data.dbg.debug1 = bc->hdrv.ptt_keyed;
  27358. +        bi.data.dbg.debug2 = bc->debug_vals.last_intcnt;
  27359. +        bi.data.dbg.debug3 = bc->debug_vals.last_pllcorr;
  27360. +        break;
  27361. +#endif /* BAYCOM_DEBUG */
  27362. +
  27363. +    }
  27364. +    if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
  27365. +        return -EFAULT;
  27366. +    return 0;
  27367. +
  27368. +}
  27369. +
  27370. +/* --------------------------------------------------------------------- */
  27371. +
  27372. +__initfunc(int baycom_init(void))
  27373. +{
  27374. +    int i, j, found = 0;
  27375. +    char set_hw = 1;
  27376. +    struct baycom_state *bc;
  27377. +    char ifname[HDLCDRV_IFNAMELEN];
  27378. +
  27379. +
  27380. +    printk(bc_drvinfo);
  27381. +    /*
  27382. +     * register net devices
  27383. +     */
  27384. +    for (i = 0; i < NR_PORTS; i++) {
  27385. +        struct device *dev = baycom_device+i;
  27386. +        sprintf(ifname, "bc%d", i);
  27387. +
  27388. +        if (!baycom_ports[i].mode)
  27389. +            set_hw = 0;
  27390. +        if (!set_hw)
  27391. +            baycom_ports[i].iobase = baycom_ports[i].irq = 0;
  27392. +        j = hdlcdrv_register_hdlcdrv(dev, &dummy_ops,
  27393. +                         sizeof(struct baycom_state),
  27394. +                         ifname, baycom_ports[i].iobase,
  27395. +                         baycom_ports[i].irq, 0);
  27396. +        if (!j) {
  27397. +            bc = (struct baycom_state *)dev->priv;
  27398. +            if (set_hw && baycom_setmode(bc, baycom_ports[i].mode))
  27399. +                set_hw = 0;
  27400. +            found++;
  27401. +        } else {
  27402. +            printk(KERN_WARNING "%s: cannot register net device\n",
  27403. +                   bc_drvname);
  27404. +        }
  27405. +    }
  27406. +    if (!found)
  27407. +        return -ENXIO;
  27408. +    return 0;
  27409. +}
  27410. +
  27411. +/* --------------------------------------------------------------------- */
  27412. +
  27413. +#ifdef MODULE
  27414. +
  27415. +/*
  27416. + * command line settable parameters
  27417. + */
  27418. +static char *mode = NULL;
  27419. +static int iobase = 0x3f8;
  27420. +static int irq = 4;
  27421. +
  27422. +#if LINUX_VERSION_CODE >= 0x20115
  27423. +
  27424. +MODULE_PARM(mode, "s");
  27425. +MODULE_PARM_DESC(mode, "baycom operating mode; eg. ser12* or par96");
  27426. +MODULE_PARM(iobase, "i");
  27427. +MODULE_PARM_DESC(iobase, "baycom io base address");
  27428. +MODULE_PARM(irq, "i");
  27429. +MODULE_PARM_DESC(irq, "baycom irq number");
  27430. +
  27431. +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
  27432. +MODULE_DESCRIPTION("Baycom ser12, par96 and picpar amateur radio modem driver");
  27433. +
  27434. +#endif
  27435. +
  27436. +__initfunc(int init_module(void))
  27437. +{
  27438. +    baycom_ports[0].mode = mode;
  27439. +    baycom_ports[0].iobase = iobase;
  27440. +    baycom_ports[0].irq = irq;
  27441. +    baycom_ports[1].mode = NULL;
  27442. +
  27443. +    return baycom_init();
  27444. +}
  27445. +
  27446. +/* --------------------------------------------------------------------- */
  27447. +
  27448. +void cleanup_module(void)
  27449. +{
  27450. +    int i;
  27451. +
  27452. +    for(i = 0; i < NR_PORTS; i++) {
  27453. +        struct device *dev = baycom_device+i;
  27454. +        struct baycom_state *bc = (struct baycom_state *)dev->priv;
  27455. +
  27456. +        if (bc) {
  27457. +            if (bc->hdrv.magic != HDLCDRV_MAGIC)
  27458. +                printk(KERN_ERR "baycom: invalid magic in "
  27459. +                       "cleanup_module\n");
  27460. +            else
  27461. +                hdlcdrv_unregister_hdlcdrv(dev);
  27462. +        }
  27463. +    }
  27464. +}
  27465. +
  27466. +#else /* MODULE */
  27467. +/* --------------------------------------------------------------------- */
  27468. +/*
  27469. + * format: baycom=io,irq,mode
  27470. + * mode: {ser12,par96}[*]
  27471. + * * indicates sofware DCD
  27472. + */
  27473. +
  27474. +__initfunc(void baycom_setup(char *str, int *ints))
  27475. +{
  27476. +    int i;
  27477. +
  27478. +    for (i = 0; (i < NR_PORTS) && (baycom_ports[i].mode); i++);
  27479. +    if ((i >= NR_PORTS) || (ints[0] < 2)) {
  27480. +        printk(KERN_INFO "%s: too many or invalid interface "
  27481. +               "specifications\n", bc_drvname);
  27482. +        return;
  27483. +    }
  27484. +    baycom_ports[i].mode = str;
  27485. +    baycom_ports[i].iobase = ints[1];
  27486. +    baycom_ports[i].irq = ints[2];
  27487. +    if (i < NR_PORTS-1)
  27488. +        baycom_ports[i+1].mode = NULL;
  27489. +}
  27490. +
  27491. +#endif /* MODULE */
  27492. +/* --------------------------------------------------------------------- */
  27493. diff -u --recursive --new-file v2.0.34/linux/drivers/net/bpqether.c linux/drivers/net/bpqether.c
  27494. --- v2.0.34/linux/drivers/net/bpqether.c    Wed Dec 31 16:00:00 1969
  27495. +++ linux/drivers/net/bpqether.c    Mon Jul 13 13:47:31 1998
  27496. @@ -0,0 +1,685 @@
  27497. +/*
  27498. + *    G8BPQ compatible "AX.25 via ethernet" driver release 003
  27499. + *
  27500. + *    This is ALPHA test software. This code may break your machine, randomly
  27501. + *    fail to work with new releases, misbehave and/or generally screw up.
  27502. + *    It might even work.
  27503. + *
  27504. + *    This code REQUIRES 2.0.0 or higher/ NET3.029
  27505. + *
  27506. + *    This module:
  27507. + *        This module is free software; you can redistribute it and/or
  27508. + *        modify it under the terms of the GNU General Public License
  27509. + *        as published by the Free Software Foundation; either version
  27510. + *        2 of the License, or (at your option) any later version.
  27511. + *
  27512. + *    This is a "pseudo" network driver to allow AX.25 over Ethernet
  27513. + *    using G8BPQ encapsulation. It has been extracted from the protocol
  27514. + *    implementation because
  27515. + *
  27516. + *        - things got unreadable within the protocol stack
  27517. + *        - to cure the protocol stack from "feature-ism"
  27518. + *        - a protocol implementation shouldn't need to know on
  27519. + *          which hardware it is running
  27520. + *        - user-level programs like the AX.25 utilities shouldn't
  27521. + *          need to know about the hardware.
  27522. + *        - IP over ethernet encapsulated AX.25 was impossible
  27523. + *        - rxecho.c did not work
  27524. + *        - to have room for extensions
  27525. + *        - it just deserves to "live" as an own driver
  27526. + *
  27527. + *    This driver can use any ethernet destination address, and can be
  27528. + *    limited to accept frames from one dedicated ethernet card only.
  27529. + *
  27530. + *    Note that the driver sets up the BPQ devices automagically on
  27531. + *    startup or (if started before the "insmod" of an ethernet device)
  27532. + *    on "ifconfig up". It hopefully will remove the BPQ on "rmmod"ing
  27533. + *    the ethernet device (in fact: as soon as another ethernet or bpq
  27534. + *    device gets "ifconfig"ured).
  27535. + *
  27536. + *    I have heard that several people are thinking of experiments
  27537. + *    with highspeed packet radio using existing ethernet cards.
  27538. + *    Well, this driver is prepared for this purpose, just add
  27539. + *    your tx key control and a txdelay / tailtime algorithm,
  27540. + *    probably some buffering, and /voila/...
  27541. + *
  27542. + *    History
  27543. + *    BPQ   001    Joerg(DL1BKE)        Extracted BPQ code from AX.25
  27544. + *                        protocol stack and added my own
  27545. + *                        yet existing patches
  27546. + *    BPQ   002    Joerg(DL1BKE)        Scan network device list on
  27547. + *                        startup.
  27548. + *    BPQ   003    Joerg(DL1BKE)        Ethernet destination address
  27549. + *                        and accepted source address
  27550. + *                        can be configured by an ioctl()
  27551. + *                        call.
  27552. + */
  27553. +
  27554. +#include <linux/config.h>
  27555. +#include <linux/errno.h>
  27556. +#include <linux/types.h>
  27557. +#include <linux/socket.h>
  27558. +#include <linux/in.h>
  27559. +#include <linux/kernel.h>
  27560. +#include <linux/string.h>
  27561. +#include <linux/net.h>
  27562. +#include <net/ax25.h>
  27563. +#include <linux/inet.h>
  27564. +#include <linux/netdevice.h>
  27565. +#include <linux/if_arp.h>
  27566. +#include <linux/skbuff.h>
  27567. +#include <net/sock.h>
  27568. +#include <asm/segment.h>
  27569. +#include <asm/system.h>
  27570. +#include <linux/mm.h>
  27571. +#include <linux/interrupt.h>
  27572. +#include <linux/notifier.h>
  27573. +#include <linux/proc_fs.h>
  27574. +#include <linux/stat.h>
  27575. +#include <linux/firewall.h>
  27576. +#include <linux/module.h>
  27577. +#include <linux/net_alias.h>
  27578. +
  27579. +#include <net/ip.h>
  27580. +#include <net/arp.h>
  27581. +
  27582. +#include <linux/bpqether.h>
  27583. +
  27584. +static unsigned char ax25_bcast[AX25_ADDR_LEN] =
  27585. +    {'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
  27586. +static unsigned char ax25_defaddr[AX25_ADDR_LEN] =
  27587. +    {'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
  27588. +
  27589. +static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  27590. +
  27591. +static char bpq_eth_addr[6];
  27592. +
  27593. +static int bpq_rcv(struct sk_buff *, struct device *, struct packet_type *);
  27594. +static int bpq_device_event(struct notifier_block *, unsigned long, void *);
  27595. +static char *bpq_print_ethaddr(unsigned char *);
  27596. +
  27597. +static struct packet_type bpq_packet_type = {
  27598. +    0,        /* ntohs(ETH_P_BPQ),*/
  27599. +    0,        /* copy */
  27600. +    bpq_rcv,
  27601. +    NULL,
  27602. +    NULL,
  27603. +};
  27604. +
  27605. +static struct notifier_block bpq_dev_notifier = {
  27606. +    bpq_device_event,
  27607. +    0
  27608. +};
  27609. +
  27610. +
  27611. +#define MAXBPQDEV 100
  27612. +
  27613. +static struct bpqdev {
  27614. +    struct bpqdev *next;
  27615. +    char   ethname[14];        /* ether device name */
  27616. +    struct device *ethdev;        /* link to ethernet device */
  27617. +    struct device axdev;        /* bpq device (bpq#) */
  27618. +    struct enet_statistics stats;    /* some statistics */
  27619. +    char   dest_addr[6];        /* ether destination address */
  27620. +    char   acpt_addr[6];        /* accept ether frames from this address only */
  27621. +} *bpq_devices = NULL;
  27622. +
  27623. +
  27624. +/* ------------------------------------------------------------------------ */
  27625. +
  27626. +
  27627. +/*
  27628. + *    Get the ethernet device for a BPQ device
  27629. + */
  27630. +static __inline__ struct device *bpq_get_ether_dev(struct device *dev)
  27631. +{
  27632. +    struct bpqdev *bpq;
  27633. +
  27634. +    bpq = (struct bpqdev *)dev->priv;
  27635. +
  27636. +    return (bpq != NULL) ? bpq->ethdev : NULL;
  27637. +}
  27638. +
  27639. +/*
  27640. + *    Get the BPQ device for the ethernet device
  27641. + */
  27642. +static __inline__ struct device *bpq_get_ax25_dev(struct device *dev)
  27643. +{
  27644. +    struct bpqdev *bpq;
  27645. +
  27646. +    for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next)
  27647. +        if (bpq->ethdev == dev)
  27648. +            return &bpq->axdev;
  27649. +
  27650. +    return NULL;
  27651. +}
  27652. +
  27653. +static __inline__ int dev_is_ethdev(struct device *dev)
  27654. +{
  27655. +    return (
  27656. +            dev->type == ARPHRD_ETHER
  27657. +            && strncmp(dev->name, "dummy", 5)
  27658. +#ifdef CONFIG_NET_ALIAS
  27659. +            && !net_alias_is(dev)
  27660. +#endif
  27661. +    );
  27662. +}
  27663. +
  27664. +/*
  27665. + *    Sanity check: remove all devices that ceased to exists and
  27666. + *    return '1' if the given BPQ device was affected.
  27667. + */
  27668. +static int bpq_check_devices(struct device *dev)
  27669. +{
  27670. +    struct bpqdev *bpq, *bpq_prev;
  27671. +    int result = 0;
  27672. +    unsigned long flags;
  27673. +
  27674. +    save_flags(flags);
  27675. +    cli();
  27676. +
  27677. +    bpq_prev = NULL;
  27678. +
  27679. +    for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next) {
  27680. +        if (!dev_get(bpq->ethname)) {
  27681. +            if (bpq_prev)
  27682. +                bpq_prev->next = bpq->next;
  27683. +            else
  27684. +                bpq_devices = bpq->next;
  27685. +
  27686. +            if (&bpq->axdev == dev)
  27687. +                result = 1;
  27688. +
  27689. +            unregister_netdev(&bpq->axdev);
  27690. +            kfree(bpq);
  27691. +        }
  27692. +
  27693. +        bpq_prev = bpq;
  27694. +    }
  27695. +
  27696. +    restore_flags(flags);
  27697. +
  27698. +    return result;
  27699. +}
  27700. +
  27701. +
  27702. +/* ------------------------------------------------------------------------ */
  27703. +
  27704. +
  27705. +/*
  27706. + *    Receive an AX.25 frame via an ethernet interface.
  27707. + */
  27708. +static int bpq_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *ptype)
  27709. +{
  27710. +    int len;
  27711. +    char * ptr;
  27712. +    struct ethhdr *eth = (struct ethhdr *)skb->mac.raw;
  27713. +    struct bpqdev *bpq;
  27714. +
  27715. +    skb->sk = NULL;        /* Initially we don't know who it's for */
  27716. +
  27717. +    dev = bpq_get_ax25_dev(dev);
  27718. +
  27719. +    if (dev == NULL || dev->start == 0) {
  27720. +        kfree_skb(skb, FREE_READ);
  27721. +        return 0;
  27722. +    }
  27723. +
  27724. +    /*
  27725. +     * if we want to accept frames from just one ethernet device
  27726. +     * we check the source address of the sender.
  27727. +     */
  27728. +
  27729. +    bpq = (struct bpqdev *)dev->priv;
  27730. +
  27731. +    if (!(bpq->acpt_addr[0] & 0x01) && memcmp(eth->h_source, bpq->acpt_addr, ETH_ALEN)) {
  27732. +        printk(KERN_DEBUG "bpqether: wrong dest %s\n", bpq_print_ethaddr(eth->h_source));
  27733. +        kfree_skb(skb, FREE_READ);
  27734. +        return 0;
  27735. +    }
  27736. +
  27737. +    ((struct bpqdev *)dev->priv)->stats.rx_packets++;
  27738. +
  27739. +    len = skb->data[0] + skb->data[1] * 256 - 5;
  27740. +
  27741. +    skb_pull(skb, 2);    /* Remove the length bytes */
  27742. +    skb_trim(skb, len);    /* Set the length of the data */
  27743. +
  27744. +    ptr = skb_push(skb, 1);
  27745. +    *ptr = 0;
  27746. +
  27747. +    skb->dev = dev;
  27748. +    skb->protocol = htons(ETH_P_AX25);
  27749. +    skb->mac.raw = skb->data;
  27750. +    skb->pkt_type = PACKET_HOST;
  27751. +
  27752. +    netif_rx(skb);
  27753. +
  27754. +    return 0;
  27755. +}
  27756. +
  27757. +/*
  27758. + *     Send an AX.25 frame via an ethernet interface
  27759. + */
  27760. +static int bpq_xmit(struct sk_buff *skb, struct device *dev)
  27761. +{
  27762. +    unsigned char *ptr;
  27763. +    struct bpqdev *bpq;
  27764. +    int size;
  27765. +
  27766. +    /*
  27767. +     * Just to be *really* sure not to send anything if the interface
  27768. +     * is down, the ethernet device may have gone.
  27769. +     */
  27770. +    if (!dev->start) {
  27771. +        bpq_check_devices(dev);
  27772. +        dev_kfree_skb(skb, FREE_WRITE);
  27773. +        return -ENODEV;
  27774. +    }
  27775. +
  27776. +    skb_pull(skb, 1);
  27777. +    size = skb->len;
  27778. +
  27779. +    /*
  27780. +     * The AX.25 code leaves enough room for the ethernet header, but
  27781. +     * sendto() does not.
  27782. +     */
  27783. +    if (skb_headroom(skb) < AX25_BPQ_HEADER_LEN) {    /* Ough! */
  27784. +        struct sk_buff *newskb = alloc_skb(skb->len + AX25_BPQ_HEADER_LEN, GFP_ATOMIC);
  27785. +
  27786. +        if (newskb == NULL) {            /* Argh! */
  27787. +            printk(KERN_WARNING "bpq_xmit: not enough space to add BPQ Ether header\n");
  27788. +            dev_kfree_skb(skb, FREE_WRITE);
  27789. +            return -ENOMEM;
  27790. +        }
  27791. +
  27792. +        newskb->free = 1;
  27793. +        newskb->arp  = 1;
  27794. +        if (skb->sk != NULL)
  27795. +            atomic_add(newskb->truesize, &skb->sk->wmem_alloc);
  27796. +        newskb->sk   = skb->sk;
  27797. +
  27798. +        skb_reserve(newskb, AX25_BPQ_HEADER_LEN);
  27799. +        memcpy(skb_put(newskb, size), skb->data, size);
  27800. +        dev_kfree_skb(skb, FREE_WRITE);
  27801. +        skb = newskb;
  27802. +    }
  27803. +
  27804. +    skb->protocol = htons(ETH_P_AX25);
  27805. +
  27806. +    ptr = skb_push(skb, 2);
  27807. +
  27808. +    *ptr++ = (size + 5) % 256;
  27809. +    *ptr++ = (size + 5) / 256;
  27810. +
  27811. +    bpq = (struct bpqdev *)dev->priv;
  27812. +    bpq->stats.tx_packets++;
  27813. +
  27814. +    if ((dev = bpq_get_ether_dev(dev)) == NULL) {
  27815. +        bpq->stats.tx_dropped++;
  27816. +        dev_kfree_skb(skb, FREE_WRITE);
  27817. +        return -ENODEV;
  27818. +    }
  27819. +
  27820. +    skb->dev = dev;
  27821. +    dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
  27822. +
  27823. +    dev_queue_xmit(skb, dev, SOPRI_NORMAL);
  27824. +
  27825. +    return 0;
  27826. +}
  27827. +
  27828. +/*
  27829. + *    Statistics
  27830. + */
  27831. +static struct enet_statistics *bpq_get_stats(struct device *dev)
  27832. +{
  27833. +    struct bpqdev *bpq;
  27834. +
  27835. +    bpq = (struct bpqdev *)dev->priv;
  27836. +
  27837. +    return &bpq->stats;
  27838. +}
  27839. +
  27840. +/*
  27841. + *    Set AX.25 callsign
  27842. + */
  27843. +static int bpq_set_mac_address(struct device *dev, void *addr)
  27844. +{
  27845. +    struct sockaddr *sa = (struct sockaddr *)addr;
  27846. +
  27847. +    memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
  27848. +
  27849. +    return 0;
  27850. +}
  27851. +
  27852. +/*    Ioctl commands
  27853. + *
  27854. + *        SIOCSBPQETHOPT        reserved for enhancements
  27855. + *        SIOCSBPQETHADDR        set the destination and accepted
  27856. + *                    source ethernet address (broadcast
  27857. + *                    or multicast: accept all)
  27858. + */
  27859. +static int bpq_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
  27860. +{
  27861. +    int err;
  27862. +    struct bpq_ethaddr *ethaddr = (struct bpq_ethaddr *)ifr->ifr_data;
  27863. +    struct bpqdev *bpq = dev->priv;
  27864. +    struct bpq_req req;
  27865. +
  27866. +    if (!suser())
  27867. +        return -EPERM;
  27868. +
  27869. +    if (bpq == NULL)        /* woops! */
  27870. +        return -ENODEV;
  27871. +
  27872. +    switch (cmd) {
  27873. +        case SIOCSBPQETHOPT:
  27874. +            if ((err = verify_area(VERIFY_WRITE, ifr->ifr_data, sizeof(struct bpq_req))) != 0)
  27875. +                return err;
  27876. +            memcpy_fromfs(&req, ifr->ifr_data, sizeof(struct bpq_req));
  27877. +            switch (req.cmd) {
  27878. +                case SIOCGBPQETHPARAM:
  27879. +                case SIOCSBPQETHPARAM:
  27880. +                default:
  27881. +                    return -EINVAL;
  27882. +            }
  27883. +
  27884. +            break;
  27885. +
  27886. +        case SIOCSBPQETHADDR:
  27887. +            if ((err = verify_area(VERIFY_READ, ethaddr, sizeof(struct bpq_ethaddr))) != 0)
  27888. +                return err;
  27889. +            memcpy_fromfs(bpq->dest_addr, ethaddr->destination, ETH_ALEN);
  27890. +            memcpy_fromfs(bpq->acpt_addr, ethaddr->accept, ETH_ALEN);
  27891. +            break;
  27892. +
  27893. +        default:
  27894. +            return -EINVAL;
  27895. +    }
  27896. +
  27897. +    return 0;
  27898. +}
  27899. +
  27900. +/*
  27901. + * open/close a device
  27902. + */
  27903. +static int bpq_open(struct device *dev)
  27904. +{
  27905. +    if (bpq_check_devices(dev))
  27906. +        return -ENODEV;        /* oops, it's gone */
  27907. +
  27908. +    dev->tbusy = 0;
  27909. +    dev->start = 1;
  27910. +
  27911. +    MOD_INC_USE_COUNT;
  27912. +
  27913. +    return 0;
  27914. +}
  27915. +
  27916. +static int bpq_close(struct device *dev)
  27917. +{
  27918. +    dev->tbusy = 1;
  27919. +    dev->start = 0;
  27920. +
  27921. +    MOD_DEC_USE_COUNT;
  27922. +
  27923. +    return 0;
  27924. +}
  27925. +
  27926. +/*
  27927. + * currently unused
  27928. + */
  27929. +static int bpq_dev_init(struct device *dev)
  27930. +{
  27931. +    return 0;
  27932. +}
  27933. +
  27934. +
  27935. +/* ------------------------------------------------------------------------ */
  27936. +
  27937. +
  27938. +/*
  27939. + *    Proc filesystem
  27940. + */
  27941. +static char * bpq_print_ethaddr(unsigned char *e)
  27942. +{
  27943. +    static char buf[18];
  27944. +
  27945. +    sprintf(buf, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
  27946. +        e[0], e[1], e[2], e[3], e[4], e[5]);
  27947. +
  27948. +    return buf;
  27949. +}
  27950. +
  27951. +int bpq_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
  27952. +{
  27953. +    struct bpqdev *bpqdev;
  27954. +    int len     = 0;
  27955. +    off_t pos   = 0;
  27956. +    off_t begin = 0;
  27957. +
  27958. +    cli();
  27959. +
  27960. +    len += sprintf(buffer, "dev   ether      destination        accept from\n");
  27961. +
  27962. +    for (bpqdev = bpq_devices; bpqdev != NULL; bpqdev = bpqdev->next) {
  27963. +        len += sprintf(buffer + len, "%-5s %-10s %s  ",
  27964. +            bpqdev->axdev.name, bpqdev->ethname,
  27965. +            bpq_print_ethaddr(bpqdev->dest_addr));
  27966. +
  27967. +        len += sprintf(buffer + len, "%s\n",
  27968. +            (bpqdev->acpt_addr[0] & 0x01) ? "*" : bpq_print_ethaddr(bpqdev->acpt_addr));
  27969. +
  27970. +        pos = begin + len;
  27971. +
  27972. +        if (pos < offset) {
  27973. +            len   = 0;
  27974. +            begin = pos;
  27975. +        }
  27976. +
  27977. +        if (pos > offset + length)
  27978. +            break;
  27979. +    }
  27980. +
  27981. +    sti();
  27982. +
  27983. +    *start = buffer + (offset - begin);
  27984. +    len   -= (offset - begin);
  27985. +
  27986. +    if (len > length) len = length;
  27987. +
  27988. +    return len;
  27989. +}
  27990. +
  27991. +
  27992. +/* ------------------------------------------------------------------------ */
  27993. +
  27994. +
  27995. +/*
  27996. + *    Setup a new device.
  27997. + */
  27998. +static int bpq_new_device(struct device *dev)
  27999. +{
  28000. +    int k;
  28001. +    unsigned char *buf;
  28002. +    struct bpqdev *bpq, *bpq2;
  28003. +
  28004. +    if ((bpq = (struct bpqdev *)kmalloc(sizeof(struct bpqdev), GFP_KERNEL)) == NULL)
  28005. +        return -ENOMEM;
  28006. +
  28007. +    memset(bpq, 0, sizeof(struct bpqdev));
  28008. +
  28009. +    bpq->ethdev = dev;
  28010. +
  28011. +    bpq->ethname[sizeof(bpq->ethname)-1] = '\0';
  28012. +    strncpy(bpq->ethname, dev->name, sizeof(bpq->ethname)-1);
  28013. +
  28014. +    memcpy(bpq->dest_addr, bcast_addr, sizeof(bpq_eth_addr));
  28015. +    memcpy(bpq->acpt_addr, bcast_addr, sizeof(bpq_eth_addr));
  28016. +
  28017. +    dev = &bpq->axdev;
  28018. +    buf = (unsigned char *)kmalloc(14, GFP_KERNEL);
  28019. +
  28020. +    for (k = 0; k < MAXBPQDEV; k++) {
  28021. +        struct device *odev;
  28022. +
  28023. +        sprintf(buf, "bpq%d", k);
  28024. +
  28025. +        if ((odev = dev_get(buf)) == NULL || bpq_check_devices(odev))
  28026. +            break;
  28027. +    }
  28028. +
  28029. +    if (k == MAXBPQDEV) {
  28030. +        kfree(bpq);
  28031. +        return -ENODEV;
  28032. +    }
  28033. +
  28034. +    dev->priv = (void *)bpq;    /* pointer back */
  28035. +    dev->name = buf;
  28036. +    dev->init = bpq_dev_init;
  28037. +
  28038. +    if (register_netdev(dev) != 0) {
  28039. +        kfree(bpq);
  28040. +                return -EIO;
  28041. +        }
  28042. +
  28043. +    for (k=0; k < DEV_NUMBUFFS; k++)
  28044. +        skb_queue_head_init(&dev->buffs[k]);
  28045. +
  28046. +    dev->hard_start_xmit = bpq_xmit;
  28047. +    dev->open         = bpq_open;
  28048. +    dev->stop         = bpq_close;
  28049. +    dev->set_mac_address = bpq_set_mac_address;
  28050. +    dev->get_stats         = bpq_get_stats;
  28051. +    dev->do_ioctl         = bpq_ioctl;
  28052. +
  28053. +    memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
  28054. +    memcpy(dev->dev_addr,  ax25_defaddr, AX25_ADDR_LEN);
  28055. +
  28056. +    /* preset with reasonable values */
  28057. +
  28058. +    dev->flags      = 0;
  28059. +    dev->family     = AF_INET;
  28060. +
  28061. +#ifdef CONFIG_INET
  28062. +    dev->pa_addr    = in_aton("192.168.0.1");
  28063. +    dev->pa_brdaddr = in_aton("192.168.0.255");
  28064. +    dev->pa_mask    = in_aton("255.255.255.0");
  28065. +    dev->pa_alen    = 4;
  28066. +#endif
  28067. +
  28068. +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
  28069. +    dev->hard_header     = ax25_encapsulate;
  28070. +    dev->rebuild_header  = ax25_rebuild_header;
  28071. +#endif
  28072. +
  28073. +    dev->type            = ARPHRD_AX25;
  28074. +    dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
  28075. +    dev->mtu             = AX25_DEF_PACLEN;
  28076. +    dev->addr_len        = AX25_ADDR_LEN;
  28077. +
  28078. +    cli();
  28079. +
  28080. +    if (bpq_devices == NULL) {
  28081. +        bpq_devices = bpq;
  28082. +    } else {
  28083. +        for (bpq2 = bpq_devices; bpq2->next != NULL; bpq2 = bpq2->next);
  28084. +        bpq2->next = bpq;
  28085. +    }
  28086. +
  28087. +    sti();
  28088. +
  28089. +    return 0;
  28090. +}
  28091. +
  28092. +
  28093. +/*
  28094. + *    Handle device status changes.
  28095. + */
  28096. +static int bpq_device_event(struct notifier_block *this,unsigned long event, void *ptr)
  28097. +{
  28098. +    struct device *dev = (struct device *)ptr;
  28099. +
  28100. +    if (!dev_is_ethdev(dev))
  28101. +        return NOTIFY_DONE;
  28102. +
  28103. +    bpq_check_devices(NULL);
  28104. +
  28105. +    switch (event) {
  28106. +        case NETDEV_UP:        /* new ethernet device -> new BPQ interface */
  28107. +            if (bpq_get_ax25_dev(dev) == NULL)
  28108. +                bpq_new_device(dev);
  28109. +            break;
  28110. +
  28111. +        case NETDEV_DOWN:    /* ethernet device closed -> close BPQ interface */
  28112. +            if ((dev = bpq_get_ax25_dev(dev)) != NULL)
  28113. +                dev_close(dev);
  28114. +            break;
  28115. +
  28116. +        default:
  28117. +            break;
  28118. +    }
  28119. +
  28120. +    return NOTIFY_DONE;
  28121. +}
  28122. +
  28123. +
  28124. +/* ------------------------------------------------------------------------ */
  28125. +
  28126. +/*
  28127. + * Initialize driver. To be called from af_ax25 if not compiled as a
  28128. + * module
  28129. + */
  28130. +int bpq_init(void)
  28131. +{
  28132. +    struct device *dev;
  28133. +
  28134. +    bpq_packet_type.type  = htons(ETH_P_BPQ);
  28135. +    dev_add_pack(&bpq_packet_type);
  28136. +
  28137. +    register_netdevice_notifier(&bpq_dev_notifier);
  28138. +
  28139. +    printk(KERN_INFO "AX.25 ethernet driver version 0.01\n");
  28140. +
  28141. +#ifdef CONFIG_PROC_FS
  28142. +    proc_net_register(&(struct proc_dir_entry) {
  28143. +        PROC_NET_AX25_BPQETHER, 8, "bpqether",
  28144. +        S_IFREG | S_IRUGO, 1, 0, 0,
  28145. +        0, &proc_net_inode_operations,
  28146. +        bpq_get_info
  28147. +    });
  28148. +#endif
  28149. +
  28150. +    for (dev = dev_base; dev != NULL; dev = dev->next) {
  28151. +        if (dev_is_ethdev(dev))
  28152. +            bpq_new_device(dev);
  28153. +    }
  28154. +
  28155. +    return 0;
  28156. +}
  28157. +
  28158. +#ifdef MODULE
  28159. +int init_module(void)
  28160. +{
  28161. +    register_symtab(NULL);
  28162. +
  28163. +    return bpq_init();
  28164. +}
  28165. +
  28166. +void cleanup_module(void)
  28167. +{
  28168. +    struct bpqdev *bpq;
  28169. +
  28170. +    dev_remove_pack(&bpq_packet_type);
  28171. +
  28172. +    unregister_netdevice_notifier(&bpq_dev_notifier);
  28173. +
  28174. +#ifdef CONFIG_PROC_FS
  28175. +    proc_net_unregister(PROC_NET_AX25_BPQETHER);
  28176. +#endif
  28177. +
  28178. +    for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next)
  28179. +        unregister_netdev(&bpq->axdev);
  28180. +}
  28181. +#endif
  28182. diff -u --recursive --new-file v2.0.34/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c
  28183. --- v2.0.34/linux/drivers/net/dgrs.c    Tue Aug 12 16:05:23 1997
  28184. +++ linux/drivers/net/dgrs.c    Mon Jul 13 13:47:31 1998
  28185. @@ -405,7 +405,7 @@
  28186.           */
  28187.          udelay(1);
  28188.  
  28189. -        csr = (volatile) priv->vplxdma[PLX_DMA_CSR/4];
  28190. +        csr = (volatile int) priv->vplxdma[PLX_DMA_CSR/4];
  28191.  
  28192.                  if (csr & PLX_DMA_CSR_0_DONE)
  28193.                          break;
  28194. @@ -876,7 +876,7 @@
  28195.          /* Wait for old command to finish */
  28196.          for (i = 0; i < 1000; ++i)
  28197.          {
  28198. -            if ( (volatile) privN->bcomm->bc_filter_cmd <= 0 )
  28199. +            if ( (volatile int) privN->bcomm->bc_filter_cmd <= 0 )
  28200.                  break;
  28201.              udelay(1);
  28202.          }
  28203. diff -u --recursive --new-file v2.0.34/linux/drivers/net/e2100.c linux/drivers/net/e2100.c
  28204. --- v2.0.34/linux/drivers/net/e2100.c    Thu Feb 29 21:50:43 1996
  28205. +++ linux/drivers/net/e2100.c    Mon Jul 13 13:47:31 1998
  28206. @@ -101,7 +101,7 @@
  28207.  static void e21_block_input(struct device *dev, int count,
  28208.                             struct sk_buff *skb, int ring_offset);
  28209.  static void e21_block_output(struct device *dev, int count,
  28210. -                             const unsigned char *buf, const start_page);
  28211. +                             const unsigned char *buf, const int start_page);
  28212.  static void e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
  28213.                              int ring_page);
  28214.  
  28215. @@ -330,7 +330,7 @@
  28216.  
  28217.  static void
  28218.  e21_block_output(struct device *dev, int count, const unsigned char *buf,
  28219. -                 int start_page)
  28220. +                 const int start_page)
  28221.  {
  28222.      short ioaddr = dev->base_addr;
  28223.      volatile char *shared_mem = (char *)dev->mem_start;
  28224. diff -u --recursive --new-file v2.0.34/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c
  28225. --- v2.0.34/linux/drivers/net/eepro100.c    Mon Jul 13 13:46:29 1998
  28226. +++ linux/drivers/net/eepro100.c    Mon Jul 13 13:47:31 1998
  28227. @@ -1,4 +1,4 @@
  28228. -/* drivers/net/eepro100.c: An Intel i82557 ethernet driver for linux. */
  28229. +/* drivers/net/eepro100.c: An Intel i82557 Ethernet driver for Linux. */
  28230.  /*
  28231.     NOTICE: this version tested with kernels 1.3.72 and later only!
  28232.      Written 1996-1998 by Donald Becker.
  28233. @@ -109,7 +109,7 @@
  28234.  I. Board Compatibility
  28235.  
  28236.  This device driver is designed for the Intel i82557 "Speedo3" chip, Intel's
  28237. -single-chip fast ethernet controller for PCI, as used on the Intel
  28238. +single-chip fast Ethernet controller for PCI, as used on the Intel
  28239.  EtherExpress Pro 100 adapter.
  28240.  
  28241.  II. Board-specific settings
  28242. @@ -163,7 +163,7 @@
  28243.  added asynchronous to the normal transmit queue, so we disable interrupts
  28244.  whenever the Tx descriptor ring is manipulated.
  28245.  
  28246. -A notable aspect of the these special configure commands is that they do
  28247. +A notable aspect of these special configure commands is that they do
  28248.  work with the normal Tx ring entry scavenge method.  The Tx ring scavenge
  28249.  is done at interrupt time using the 'dirty_tx' index, and checking for the
  28250.  command-complete bit.  While the setup frames may have the NoOp command on the
  28251. diff -u --recursive --new-file v2.0.34/linux/drivers/net/eth16i.c linux/drivers/net/eth16i.c
  28252. --- v2.0.34/linux/drivers/net/eth16i.c    Mon Jul 13 13:46:29 1998
  28253. +++ linux/drivers/net/eth16i.c    Mon Jul 13 13:47:31 1998
  28254. @@ -714,7 +714,7 @@
  28255.    creg[0] &= 0x0F;      /* Mask collision cnr */
  28256.    creg[2] &= 0x7F;      /* Mask DCLEN bit */
  28257.  
  28258. -#ifdef 0
  28259. +#if 0
  28260.  /* 
  28261.      This was removed because the card was sometimes left to state
  28262.        from which it couldn't be find anymore. If there is need
  28263. diff -u --recursive --new-file v2.0.34/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
  28264. --- v2.0.34/linux/drivers/net/ewrk3.c    Tue Apr  8 08:47:46 1997
  28265. +++ linux/drivers/net/ewrk3.c    Mon Jul 13 13:47:31 1998
  28266. @@ -1141,7 +1141,7 @@
  28267.  
  28268.    /*
  28269.    ** Clean out the TX and RX queues here (note that one entry
  28270. -  ** may get added to either the TXD or RX queues if the the TX or RX
  28271. +  ** may get added to either the TXD or RX queues if the TX or RX
  28272.    ** just starts processing a packet before the STOP_EWRK3 command
  28273.    ** is received. This will be flushed in the ewrk3_open() call).
  28274.    */
  28275. diff -u --recursive --new-file v2.0.34/linux/drivers/net/hdlcdrv.c linux/drivers/net/hdlcdrv.c
  28276. --- v2.0.34/linux/drivers/net/hdlcdrv.c    Wed Dec 31 16:00:00 1969
  28277. +++ linux/drivers/net/hdlcdrv.c    Mon Jul 13 13:47:31 1998
  28278. @@ -0,0 +1,1037 @@
  28279. +/*****************************************************************************/
  28280. +
  28281. +/*
  28282. + *    hdlcdrv.c  -- HDLC packet radio network driver.
  28283. + *
  28284. + *    Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
  28285. + *
  28286. + *    This program is free software; you can redistribute it and/or modify
  28287. + *    it under the terms of the GNU General Public License as published by
  28288. + *    the Free Software Foundation; either version 2 of the License, or
  28289. + *    (at your option) any later version.
  28290. + *
  28291. + *    This program is distributed in the hope that it will be useful,
  28292. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  28293. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  28294. + *    GNU General Public License for more details.
  28295. + *
  28296. + *    You should have received a copy of the GNU General Public License
  28297. + *    along with this program; if not, write to the Free Software
  28298. + *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  28299. + *
  28300. + *  Please note that the GPL allows you to use the driver, NOT the radio.
  28301. + *  In order to use the radio, you need a license from the communications
  28302. + *  authority of your country.
  28303. + *
  28304. + *  The driver was derived from Donald Beckers skeleton.c
  28305. + *    Written 1993-94 by Donald Becker.
  28306. + *
  28307. + *  History:
  28308. + *   0.1  21.09.96  Started
  28309. + *        18.10.96  Changed to new user space access routines 
  28310. + *                  (copy_{to,from}_user)
  28311. + *   0.2  21.11.96  various small changes
  28312. + *   0.3  03.03.97  fixed (hopefully) IP not working with ax.25 as a module
  28313. + *   0.4  16.04.97  init code/data tagged
  28314. + */
  28315. +
  28316. +/*****************************************************************************/
  28317. +
  28318. +#include <linux/config.h>
  28319. +#include <linux/module.h>
  28320. +#include <linux/types.h>
  28321. +#include <linux/net.h>
  28322. +#include <linux/in.h>
  28323. +#include <linux/if.h>
  28324. +#include <linux/malloc.h>
  28325. +#include <linux/errno.h>
  28326. +#include <asm/bitops.h>
  28327. +
  28328. +#include <linux/netdevice.h>
  28329. +#include <linux/if_arp.h>
  28330. +#include <linux/etherdevice.h>
  28331. +#include <linux/skbuff.h>
  28332. +#include <linux/hdlcdrv.h>
  28333. +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
  28334. +/* prototypes for ax25_encapsulate and ax25_rebuild_header */
  28335. +#include <net/ax25.h> 
  28336. +#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
  28337. +
  28338. +/* make genksyms happy */
  28339. +#include <linux/ip.h>
  28340. +#include <linux/udp.h>
  28341. +#include <linux/tcp.h>
  28342. +#include <linux/net_alias.h>
  28343. +
  28344. +/* --------------------------------------------------------------------- */
  28345. +
  28346. +/*
  28347. + * currently this module is supposed to support both module styles, i.e.
  28348. + * the old one present up to about 2.1.9, and the new one functioning
  28349. + * starting with 2.1.21. The reason is I have a kit allowing to compile
  28350. + * this module also under 2.0.x which was requested by several people.
  28351. + * This will go in 2.2
  28352. + */
  28353. +#include <linux/version.h>
  28354. +
  28355. +#if LINUX_VERSION_CODE >= 0x20100
  28356. +#include <asm/uaccess.h>
  28357. +#else
  28358. +#include <asm/segment.h>
  28359. +#include <linux/mm.h>
  28360. +
  28361. +#undef put_user
  28362. +#undef get_user
  28363. +
  28364. +#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
  28365. +#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
  28366. +
  28367. +extern inline int copy_from_user(void *to, const void *from, unsigned long n)
  28368. +{
  28369. +        int i = verify_area(VERIFY_READ, from, n);
  28370. +        if (i)
  28371. +                return i;
  28372. +        memcpy_fromfs(to, from, n);
  28373. +        return 0;
  28374. +}
  28375. +
  28376. +extern inline int copy_to_user(void *to, const void *from, unsigned long n)
  28377. +{
  28378. +        int i = verify_area(VERIFY_WRITE, to, n);
  28379. +        if (i)
  28380. +                return i;
  28381. +        memcpy_tofs(to, from, n);
  28382. +        return 0;
  28383. +}
  28384. +#endif
  28385. +
  28386. +/* --------------------------------------------------------------------- */
  28387. +
  28388. +#if LINUX_VERSION_CODE < 0x20115
  28389. +extern __inline__ void dev_init_buffers(struct device *dev)
  28390. +{
  28391. +        int i;
  28392. +        for(i=0;i<DEV_NUMBUFFS;i++)
  28393. +        {
  28394. +                skb_queue_head_init(&dev->buffs[i]);
  28395. +        }
  28396. +}
  28397. +#endif
  28398. +
  28399. +/* --------------------------------------------------------------------- */
  28400. +
  28401. +#if LINUX_VERSION_CODE >= 0x20123
  28402. +#include <linux/init.h>
  28403. +#else
  28404. +#define __init
  28405. +#define __initdata
  28406. +#define __initfunc(x) x
  28407. +#endif
  28408. +
  28409. +/* --------------------------------------------------------------------- */
  28410. +
  28411. +#if LINUX_VERSION_CODE < 0x20125
  28412. +#define test_and_set_bit set_bit
  28413. +#define test_and_clear_bit clear_bit
  28414. +#endif
  28415. +
  28416. +/* --------------------------------------------------------------------- */
  28417. +
  28418. +/*
  28419. + * The name of the card. Is used for messages and in the requests for
  28420. + * io regions, irqs and dma channels
  28421. + */
  28422. +
  28423. +static char ax25_bcast[7] =
  28424. +{'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
  28425. +static char ax25_test[7] =
  28426. +{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
  28427. +
  28428. +/* --------------------------------------------------------------------- */
  28429. +
  28430. +#define KISS_VERBOSE
  28431. +
  28432. +/* --------------------------------------------------------------------- */
  28433. +
  28434. +#define PARAM_TXDELAY   1
  28435. +#define PARAM_PERSIST   2
  28436. +#define PARAM_SLOTTIME  3
  28437. +#define PARAM_TXTAIL    4
  28438. +#define PARAM_FULLDUP   5
  28439. +#define PARAM_HARDWARE  6
  28440. +#define PARAM_RETURN    255
  28441. +
  28442. +/* --------------------------------------------------------------------- */
  28443. +
  28444. +#define min(a, b) (((a) < (b)) ? (a) : (b))
  28445. +#define max(a, b) (((a) > (b)) ? (a) : (b))
  28446. +
  28447. +/* --------------------------------------------------------------------- */
  28448. +/*
  28449. + * the CRC routines are stolen from WAMPES
  28450. + * by Dieter Deyke
  28451. + */
  28452. +
  28453. +static const unsigned short crc_ccitt_table[] = {
  28454. +    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
  28455. +    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
  28456. +    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
  28457. +    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
  28458. +    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
  28459. +    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
  28460. +    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
  28461. +    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
  28462. +    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
  28463. +    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
  28464. +    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
  28465. +    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
  28466. +    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
  28467. +    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
  28468. +    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
  28469. +    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
  28470. +    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
  28471. +    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
  28472. +    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
  28473. +    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
  28474. +    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
  28475. +    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
  28476. +    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
  28477. +    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
  28478. +    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
  28479. +    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
  28480. +    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
  28481. +    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
  28482. +    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
  28483. +    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
  28484. +    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
  28485. +    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
  28486. +};
  28487. +
  28488. +/*---------------------------------------------------------------------------*/
  28489. +
  28490. +static inline void append_crc_ccitt(unsigned char *buffer, int len)
  28491. +{
  28492. +     unsigned int crc = 0xffff;
  28493. +
  28494. +    for (;len>0;len--)
  28495. +        crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buffer++) & 0xff];
  28496. +    crc ^= 0xffff;
  28497. +    *buffer++ = crc;
  28498. +    *buffer++ = crc >> 8;
  28499. +}
  28500. +
  28501. +/*---------------------------------------------------------------------------*/
  28502. +
  28503. +static inline int check_crc_ccitt(const unsigned char *buf, int cnt)
  28504. +{
  28505. +    unsigned int crc = 0xffff;
  28506. +
  28507. +    for (; cnt > 0; cnt--)
  28508. +        crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
  28509. +    return (crc & 0xffff) == 0xf0b8;
  28510. +}
  28511. +
  28512. +/*---------------------------------------------------------------------------*/
  28513. +
  28514. +#if 0
  28515. +static int calc_crc_ccitt(const unsigned char *buf, int cnt)
  28516. +{
  28517. +    unsigned int crc = 0xffff;
  28518. +
  28519. +    for (; cnt > 0; cnt--)
  28520. +        crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
  28521. +    crc ^= 0xffff;
  28522. +    return (crc & 0xffff);
  28523. +}
  28524. +#endif
  28525. +
  28526. +/* ---------------------------------------------------------------------- */
  28527. +
  28528. +#define tenms_to_2flags(s,tenms) ((tenms * s->par.bitrate) / 100 / 16)
  28529. +
  28530. +/* ---------------------------------------------------------------------- */
  28531. +/*
  28532. + * The HDLC routines
  28533. + */
  28534. +
  28535. +static int hdlc_rx_add_bytes(struct hdlcdrv_state *s, unsigned int bits, 
  28536. +                 int num)
  28537. +{
  28538. +    int added = 0;
  28539. +    
  28540. +    while (s->hdlcrx.rx_state && num >= 8) {
  28541. +        if (s->hdlcrx.len >= sizeof(s->hdlcrx.buffer)) {
  28542. +            s->hdlcrx.rx_state = 0;
  28543. +            return 0;
  28544. +        }
  28545. +        *s->hdlcrx.bp++ = bits >> (32-num);
  28546. +        s->hdlcrx.len++;
  28547. +        num -= 8;
  28548. +        added += 8;
  28549. +    }
  28550. +    return added;
  28551. +}
  28552. +
  28553. +static void hdlc_rx_flag(struct device *dev, struct hdlcdrv_state *s)
  28554. +{
  28555. +    struct sk_buff *skb;
  28556. +    int pkt_len;
  28557. +    unsigned char *cp;
  28558. +
  28559. +    if (s->hdlcrx.len < 4) 
  28560. +        return;
  28561. +    if (!check_crc_ccitt(s->hdlcrx.buffer, s->hdlcrx.len)) 
  28562. +        return;
  28563. +    pkt_len = s->hdlcrx.len - 2 + 1; /* KISS kludge */
  28564. +    if (!(skb = dev_alloc_skb(pkt_len))) {
  28565. +        printk("%s: memory squeeze, dropping packet\n", 
  28566. +               s->ifname);
  28567. +        s->stats.rx_dropped++;
  28568. +        return;
  28569. +    }
  28570. +    skb->dev = dev;
  28571. +    cp = skb_put(skb, pkt_len);
  28572. +    *cp++ = 0; /* KISS kludge */
  28573. +    memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
  28574. +    skb->protocol = htons(ETH_P_AX25);
  28575. +    skb->mac.raw = skb->data;
  28576. +    netif_rx(skb);
  28577. +    s->stats.rx_packets++;
  28578. +}
  28579. +
  28580. +void hdlcdrv_receiver(struct device *dev, struct hdlcdrv_state *s)
  28581. +{
  28582. +    int i;
  28583. +    unsigned int mask1, mask2, mask3, mask4, mask5, mask6, word;
  28584. +    
  28585. +    if (!s || s->magic != HDLCDRV_MAGIC) 
  28586. +        return;
  28587. +    if (test_and_set_bit(0, &s->hdlcrx.in_hdlc_rx))
  28588. +        return;
  28589. +
  28590. +    while (!hdlcdrv_hbuf_empty(&s->hdlcrx.hbuf)) {
  28591. +        word = hdlcdrv_hbuf_get(&s->hdlcrx.hbuf);    
  28592. +
  28593. +#ifdef HDLCDRV_DEBUG
  28594. +        hdlcdrv_add_bitbuffer_word(&s->bitbuf_hdlc, word);
  28595. +#endif /* HDLCDRV_DEBUG */
  28596. +               s->hdlcrx.bitstream >>= 16;
  28597. +        s->hdlcrx.bitstream |= word << 16;
  28598. +        s->hdlcrx.bitbuf >>= 16;
  28599. +        s->hdlcrx.bitbuf |= word << 16;
  28600. +        s->hdlcrx.numbits += 16;
  28601. +        for(i = 15, mask1 = 0x1fc00, mask2 = 0x1fe00, mask3 = 0x0fc00,
  28602. +            mask4 = 0x1f800, mask5 = 0xf800, mask6 = 0xffff; 
  28603. +            i >= 0; 
  28604. +            i--, mask1 <<= 1, mask2 <<= 1, mask3 <<= 1, mask4 <<= 1, 
  28605. +            mask5 <<= 1, mask6 = (mask6 << 1) | 1) {
  28606. +            if ((s->hdlcrx.bitstream & mask1) == mask1)
  28607. +                s->hdlcrx.rx_state = 0; /* abort received */
  28608. +            else if ((s->hdlcrx.bitstream & mask2) == mask3) {
  28609. +                /* flag received */
  28610. +                if (s->hdlcrx.rx_state) {
  28611. +                    hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf 
  28612. +                              << (8+i),
  28613. +                              s->hdlcrx.numbits
  28614. +                              -8-i);
  28615. +                    hdlc_rx_flag(dev, s);
  28616. +                }
  28617. +                s->hdlcrx.len = 0;
  28618. +                s->hdlcrx.bp = s->hdlcrx.buffer;
  28619. +                s->hdlcrx.rx_state = 1;
  28620. +                s->hdlcrx.numbits = i;
  28621. +            } else if ((s->hdlcrx.bitstream & mask4) == mask5) {
  28622. +                /* stuffed bit */
  28623. +                s->hdlcrx.numbits--;
  28624. +                s->hdlcrx.bitbuf = (s->hdlcrx.bitbuf & (~mask6)) |
  28625. +                    ((s->hdlcrx.bitbuf & mask6) << 1);
  28626. +            }
  28627. +        }
  28628. +        s->hdlcrx.numbits -= hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf,
  28629. +                               s->hdlcrx.numbits);
  28630. +    }
  28631. +    clear_bit(0, &s->hdlcrx.in_hdlc_rx);
  28632. +}
  28633. +
  28634. +/* ---------------------------------------------------------------------- */
  28635. +
  28636. +static void inline do_kiss_params(struct hdlcdrv_state *s,
  28637. +                  unsigned char *data, unsigned long len)
  28638. +{
  28639. +
  28640. +#ifdef KISS_VERBOSE
  28641. +#define PKP(a,b) printk(KERN_INFO "%s: channel params: " a "\n", s->ifname, b)
  28642. +#else /* KISS_VERBOSE */          
  28643. +#define PKP(a,b) 
  28644. +#endif /* KISS_VERBOSE */          
  28645. +
  28646. +    if (len < 2)
  28647. +        return;
  28648. +    switch(data[0]) {
  28649. +    case PARAM_TXDELAY:
  28650. +        s->ch_params.tx_delay = data[1];
  28651. +        PKP("TX delay = %ums", 10 * s->ch_params.tx_delay);
  28652. +        break;
  28653. +    case PARAM_PERSIST:   
  28654. +        s->ch_params.ppersist = data[1];
  28655. +        PKP("p persistence = %u", s->ch_params.ppersist);
  28656. +        break;
  28657. +    case PARAM_SLOTTIME:  
  28658. +        s->ch_params.slottime = data[1];
  28659. +        PKP("slot time = %ums", s->ch_params.slottime);
  28660. +        break;
  28661. +    case PARAM_TXTAIL:    
  28662. +        s->ch_params.tx_tail = data[1];
  28663. +        PKP("TX tail = %ums", s->ch_params.tx_tail);
  28664. +        break;
  28665. +    case PARAM_FULLDUP:   
  28666. +        s->ch_params.fulldup = !!data[1];
  28667. +        PKP("%s duplex", s->ch_params.fulldup ? "full" : "half");
  28668. +        break;
  28669. +    default:
  28670. +        break;
  28671. +    }
  28672. +#undef PKP
  28673. +}
  28674. +
  28675. +/* ---------------------------------------------------------------------- */
  28676. +
  28677. +void hdlcdrv_transmitter(struct device *dev, struct hdlcdrv_state *s)
  28678. +{
  28679. +    unsigned int mask1, mask2, mask3;
  28680. +    int i;
  28681. +    struct sk_buff *skb;
  28682. +    int pkt_len;
  28683. +
  28684. +    if (!s || s->magic != HDLCDRV_MAGIC) 
  28685. +        return;
  28686. +    if (test_and_set_bit(0, &s->hdlctx.in_hdlc_tx))
  28687. +        return;
  28688. +    for (;;) {
  28689. +        if (s->hdlctx.numbits >= 16) {
  28690. +            if (hdlcdrv_hbuf_full(&s->hdlctx.hbuf)) {
  28691. +                clear_bit(0, &s->hdlctx.in_hdlc_tx);
  28692. +                return;
  28693. +            }
  28694. +            hdlcdrv_hbuf_put(&s->hdlctx.hbuf, s->hdlctx.bitbuf);
  28695. +            s->hdlctx.bitbuf >>= 16;
  28696. +            s->hdlctx.numbits -= 16;
  28697. +        }
  28698. +        switch (s->hdlctx.tx_state) {
  28699. +        default:
  28700. +            clear_bit(0, &s->hdlctx.in_hdlc_tx);
  28701. +            return;
  28702. +        case 0:
  28703. +        case 1:
  28704. +            if (s->hdlctx.numflags) {
  28705. +                s->hdlctx.numflags--;
  28706. +                s->hdlctx.bitbuf |= 
  28707. +                    0x7e7e << s->hdlctx.numbits;
  28708. +                s->hdlctx.numbits += 16;
  28709. +                break;
  28710. +            }
  28711. +            if (s->hdlctx.tx_state == 1) {
  28712. +                clear_bit(0, &s->hdlctx.in_hdlc_tx);
  28713. +                return;
  28714. +            }
  28715. +            if (!(skb = skb_dequeue(&s->send_queue))) {
  28716. +                int flgs = tenms_to_2flags
  28717. +                    (s, s->ch_params.tx_tail);
  28718. +                if (flgs < 2)
  28719. +                    flgs = 2;
  28720. +                s->hdlctx.tx_state = 1;
  28721. +                s->hdlctx.numflags = flgs;
  28722. +                break;
  28723. +            }
  28724. +            if (skb->data[0] != 0) {
  28725. +                do_kiss_params(s, skb->data, skb->len);
  28726. +                dev_kfree_skb(skb, FREE_WRITE);
  28727. +                break;
  28728. +            }
  28729. +            pkt_len = skb->len-1; /* strip KISS byte */
  28730. +            if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) {
  28731. +                s->hdlctx.tx_state = 0;
  28732. +                s->hdlctx.numflags = 1;
  28733. +                dev_kfree_skb(skb, FREE_WRITE);
  28734. +                break;
  28735. +            }
  28736. +            memcpy(s->hdlctx.buffer, skb->data+1, pkt_len);
  28737. +            dev_kfree_skb(skb, FREE_WRITE);
  28738. +            s->hdlctx.bp = s->hdlctx.buffer;
  28739. +            append_crc_ccitt(s->hdlctx.buffer, pkt_len);
  28740. +            s->hdlctx.len = pkt_len+2; /* the appended CRC */
  28741. +            s->hdlctx.tx_state = 2;
  28742. +            s->hdlctx.bitstream = 0;
  28743. +            s->stats.tx_packets++;
  28744. +            break;
  28745. +        case 2:
  28746. +            if (!s->hdlctx.len) {
  28747. +                s->hdlctx.tx_state = 0;
  28748. +                s->hdlctx.numflags = 1;
  28749. +                break;
  28750. +            }
  28751. +            s->hdlctx.len--;
  28752. +            s->hdlctx.bitbuf |= *s->hdlctx.bp <<
  28753. +                s->hdlctx.numbits;
  28754. +            s->hdlctx.bitstream >>= 8;
  28755. +            s->hdlctx.bitstream |= (*s->hdlctx.bp++) << 16;
  28756. +            mask1 = 0x1f000;
  28757. +            mask2 = 0x10000;
  28758. +            mask3 = 0xffffffff >> (31-s->hdlctx.numbits);
  28759. +            s->hdlctx.numbits += 8;
  28760. +            for(i = 0; i < 8; i++, mask1 <<= 1, mask2 <<= 1, 
  28761. +                mask3 = (mask3 << 1) | 1) {
  28762. +                if ((s->hdlctx.bitstream & mask1) != mask1) 
  28763. +                    continue;
  28764. +                s->hdlctx.bitstream &= ~mask2;
  28765. +                s->hdlctx.bitbuf = 
  28766. +                    (s->hdlctx.bitbuf & mask3) |
  28767. +                        ((s->hdlctx.bitbuf & 
  28768. +                         (~mask3)) << 1);
  28769. +                s->hdlctx.numbits++;
  28770. +                mask3 = (mask3 << 1) | 1;
  28771. +            }
  28772. +            break;
  28773. +        }
  28774. +    }
  28775. +}
  28776. +
  28777. +/* ---------------------------------------------------------------------- */
  28778. +
  28779. +static void start_tx(struct device *dev, struct hdlcdrv_state *s)
  28780. +{
  28781. +    s->hdlctx.tx_state = 0;
  28782. +    s->hdlctx.numflags = tenms_to_2flags(s, s->ch_params.tx_delay);
  28783. +    s->hdlctx.bitbuf = s->hdlctx.bitstream = s->hdlctx.numbits = 0;
  28784. +    hdlcdrv_transmitter(dev, s);
  28785. +    s->hdlctx.ptt = 1;
  28786. +    s->ptt_keyed++;
  28787. +}
  28788. +
  28789. +/* ---------------------------------------------------------------------- */
  28790. +
  28791. +static unsigned short random_seed;
  28792. +
  28793. +static inline unsigned short random_num(void)
  28794. +{
  28795. +    random_seed = 28629 * random_seed + 157;
  28796. +    return random_seed;
  28797. +}
  28798. +
  28799. +/* ---------------------------------------------------------------------- */
  28800. +
  28801. +void hdlcdrv_arbitrate(struct device *dev, struct hdlcdrv_state *s)
  28802. +{
  28803. +    if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || 
  28804. +        skb_queue_empty(&s->send_queue)) 
  28805. +        return;
  28806. +    if (s->ch_params.fulldup) {
  28807. +        start_tx(dev, s);
  28808. +        return;
  28809. +    }
  28810. +    if (s->hdlcrx.dcd) {
  28811. +        s->hdlctx.slotcnt = s->ch_params.slottime;
  28812. +        return;
  28813. +    }
  28814. +    if ((--s->hdlctx.slotcnt) > 0)
  28815. +        return;
  28816. +    s->hdlctx.slotcnt = s->ch_params.slottime;
  28817. +    if ((random_num() % 256) > s->ch_params.ppersist)
  28818. +        return;
  28819. +    start_tx(dev, s);
  28820. +}
  28821. +
  28822. +/* --------------------------------------------------------------------- */
  28823. +/*
  28824. + * ===================== network driver interface =========================
  28825. + */
  28826. +
  28827. +static inline int hdlcdrv_paranoia_check(struct device *dev,
  28828. +                    const char *routine)
  28829. +{
  28830. +    if (!dev || !dev->priv || 
  28831. +        ((struct hdlcdrv_state *)dev->priv)->magic != HDLCDRV_MAGIC) {
  28832. +        printk(KERN_ERR "hdlcdrv: bad magic number for hdlcdrv_state "
  28833. +               "struct in routine %s\n", routine);
  28834. +        return 1;
  28835. +    }
  28836. +    return 0;
  28837. +}
  28838. +
  28839. +/* --------------------------------------------------------------------- */
  28840. +
  28841. +static int hdlcdrv_send_packet(struct sk_buff *skb, struct device *dev)
  28842. +{
  28843. +    struct hdlcdrv_state *sm;
  28844. +
  28845. +    if (hdlcdrv_paranoia_check(dev, "hdlcdrv_send_packet"))
  28846. +        return 0;
  28847. +    sm = (struct hdlcdrv_state *)dev->priv;
  28848. +    /*
  28849. +     * If some higher layer thinks we've missed an tx-done interrupt
  28850. +         * we are passed NULL. Caution: dev_tint() handles the cli()/sti()
  28851. +     * itself. 
  28852. +     */
  28853. +    if (skb == NULL) {
  28854. +        dev_tint(dev);
  28855. +        return 0;
  28856. +    }
  28857. +    skb_queue_tail(&sm->send_queue, skb);
  28858. +    dev->trans_start = jiffies;    
  28859. +    return 0;
  28860. +}
  28861. +
  28862. +/* --------------------------------------------------------------------- */
  28863. +
  28864. +static int hdlcdrv_set_mac_address(struct device *dev, void *addr)
  28865. +{
  28866. +    struct sockaddr *sa = (struct sockaddr *)addr;
  28867. +
  28868. +    /* addr is an AX.25 shifted ASCII mac address */
  28869. +    memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); 
  28870. +    return 0;                                         
  28871. +}
  28872. +
  28873. +/* --------------------------------------------------------------------- */
  28874. +
  28875. +#if LINUX_VERSION_CODE >= 0x20119
  28876. +static struct net_device_stats *hdlcdrv_get_stats(struct device *dev)
  28877. +#else
  28878. +static struct enet_statistics *hdlcdrv_get_stats(struct device *dev)
  28879. +#endif
  28880. +{
  28881. +    struct hdlcdrv_state *sm;
  28882. +
  28883. +    if (hdlcdrv_paranoia_check(dev, "hdlcdrv_get_stats"))
  28884. +        return NULL;
  28885. +    sm = (struct hdlcdrv_state *)dev->priv;
  28886. +    /* 
  28887. +     * Get the current statistics.  This may be called with the
  28888. +     * card open or closed. 
  28889. +     */
  28890. +    return &sm->stats;
  28891. +}
  28892. +
  28893. +/* --------------------------------------------------------------------- */
  28894. +/*
  28895. + * Open/initialize the board. This is called (in the current kernel)
  28896. + * sometime after booting when the 'ifconfig' program is run.
  28897. + *
  28898. + * This routine should set everything up anew at each open, even
  28899. + * registers that "should" only need to be set once at boot, so that
  28900. + * there is non-reboot way to recover if something goes wrong.
  28901. + */
  28902. +
  28903. +static int hdlcdrv_open(struct device *dev)
  28904. +{
  28905. +    struct hdlcdrv_state *s;
  28906. +    int i;
  28907. +
  28908. +    if (hdlcdrv_paranoia_check(dev, "hdlcdrv_open"))
  28909. +        return -EINVAL;
  28910. +    s = (struct hdlcdrv_state *)dev->priv;
  28911. +
  28912. +    if (dev->start)
  28913. +        return 0;
  28914. +    if (!s->ops || !s->ops->open)
  28915. +        return -ENODEV;
  28916. +
  28917. +    dev->start = 1;
  28918. +    /*
  28919. +     * initialise some variables
  28920. +     */
  28921. +    s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
  28922. +    s->hdlcrx.in_hdlc_rx = 0;
  28923. +    s->hdlcrx.rx_state = 0;
  28924. +    
  28925. +    s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
  28926. +    s->hdlctx.in_hdlc_tx = 0;
  28927. +    s->hdlctx.tx_state = 1;
  28928. +    s->hdlctx.numflags = 0;
  28929. +    s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
  28930. +    s->hdlctx.ptt = 0;
  28931. +    s->hdlctx.slotcnt = s->ch_params.slottime;
  28932. +    s->hdlctx.calibrate = 0;
  28933. +
  28934. +    i = s->ops->open(dev);
  28935. +    if (i) {
  28936. +        dev->start = 0;
  28937. +        return i;
  28938. +    }
  28939. +
  28940. +    dev->tbusy = 0;
  28941. +    dev->interrupt = 0;
  28942. +
  28943. +    return 0;
  28944. +}
  28945. +
  28946. +/* --------------------------------------------------------------------- */
  28947. +/* 
  28948. + * The inverse routine to hdlcdrv_open(). 
  28949. + */
  28950. +
  28951. +static int hdlcdrv_close(struct device *dev)
  28952. +{
  28953. +    struct hdlcdrv_state *s;
  28954. +    struct sk_buff *skb;
  28955. +    int i = 0;
  28956. +
  28957. +    if (hdlcdrv_paranoia_check(dev, "hdlcdrv_close"))
  28958. +        return -EINVAL;
  28959. +    s = (struct hdlcdrv_state *)dev->priv;
  28960. +
  28961. +    if (!dev->start)
  28962. +        return 0;
  28963. +    dev->start = 0;
  28964. +    dev->tbusy = 1;
  28965. +
  28966. +    if (s->ops && s->ops->close)
  28967. +        i = s->ops->close(dev);
  28968. +        /* Free any buffers left in the hardware transmit queue */
  28969. +        while ((skb = skb_dequeue(&s->send_queue)))
  28970. +            dev_kfree_skb(skb, FREE_WRITE);
  28971. +    return i;
  28972. +}
  28973. +
  28974. +/* --------------------------------------------------------------------- */
  28975. +
  28976. +static int hdlcdrv_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
  28977. +{
  28978. +    struct hdlcdrv_state *s;
  28979. +    struct hdlcdrv_ioctl bi;
  28980. +        
  28981. +    if (hdlcdrv_paranoia_check(dev, "hdlcdrv_ioctl"))
  28982. +        return -EINVAL;
  28983. +    s = (struct hdlcdrv_state *)dev->priv;
  28984. +
  28985. +    if (cmd != SIOCDEVPRIVATE) {
  28986. +        if (s->ops && s->ops->ioctl)
  28987. +            return s->ops->ioctl(dev, ifr, &bi, cmd);
  28988. +        return -ENOIOCTLCMD;
  28989. +    }
  28990. +    if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
  28991. +        return -EFAULT;
  28992. +
  28993. +    switch (bi.cmd) {
  28994. +    default:
  28995. +        if (s->ops && s->ops->ioctl)
  28996. +            return s->ops->ioctl(dev, ifr, &bi, cmd);
  28997. +        return -ENOIOCTLCMD;
  28998. +
  28999. +    case HDLCDRVCTL_GETCHANNELPAR:
  29000. +        bi.data.cp.tx_delay = s->ch_params.tx_delay;
  29001. +        bi.data.cp.tx_tail = s->ch_params.tx_tail;
  29002. +        bi.data.cp.slottime = s->ch_params.slottime;
  29003. +        bi.data.cp.ppersist = s->ch_params.ppersist;
  29004. +        bi.data.cp.fulldup = s->ch_params.fulldup;
  29005. +        break;
  29006. +
  29007. +    case HDLCDRVCTL_SETCHANNELPAR:
  29008. +        if (!suser())
  29009. +            return -EACCES;
  29010. +        s->ch_params.tx_delay = bi.data.cp.tx_delay;
  29011. +        s->ch_params.tx_tail = bi.data.cp.tx_tail;
  29012. +        s->ch_params.slottime = bi.data.cp.slottime;
  29013. +        s->ch_params.ppersist = bi.data.cp.ppersist;
  29014. +        s->ch_params.fulldup = bi.data.cp.fulldup;
  29015. +        s->hdlctx.slotcnt = 1;
  29016. +        return 0;
  29017. +        
  29018. +    case HDLCDRVCTL_GETMODEMPAR:
  29019. +        bi.data.mp.iobase = dev->base_addr;
  29020. +        bi.data.mp.irq = dev->irq;
  29021. +        bi.data.mp.dma = dev->dma;
  29022. +        bi.data.mp.dma2 = s->ptt_out.dma2;
  29023. +        bi.data.mp.seriobase = s->ptt_out.seriobase;
  29024. +        bi.data.mp.pariobase = s->ptt_out.pariobase;
  29025. +        bi.data.mp.midiiobase = s->ptt_out.midiiobase;
  29026. +        break;
  29027. +
  29028. +    case HDLCDRVCTL_SETMODEMPAR:
  29029. +        if ((!suser()) || dev->start)
  29030. +            return -EACCES;
  29031. +        dev->base_addr = bi.data.mp.iobase;
  29032. +        dev->irq = bi.data.mp.irq;
  29033. +        dev->dma = bi.data.mp.dma;
  29034. +        s->ptt_out.dma2 = bi.data.mp.dma2;
  29035. +        s->ptt_out.seriobase = bi.data.mp.seriobase;
  29036. +        s->ptt_out.pariobase = bi.data.mp.pariobase;
  29037. +        s->ptt_out.midiiobase = bi.data.mp.midiiobase;
  29038. +        return 0;    
  29039. +    
  29040. +    case HDLCDRVCTL_GETSTAT:
  29041. +        bi.data.cs.ptt = hdlcdrv_ptt(s);
  29042. +        bi.data.cs.dcd = s->hdlcrx.dcd;
  29043. +        bi.data.cs.ptt_keyed = s->ptt_keyed;
  29044. +        bi.data.cs.tx_packets = s->stats.tx_packets;
  29045. +        bi.data.cs.tx_errors = s->stats.tx_errors;
  29046. +        bi.data.cs.rx_packets = s->stats.rx_packets;
  29047. +        bi.data.cs.rx_errors = s->stats.rx_errors;
  29048. +        break;        
  29049. +
  29050. +    case HDLCDRVCTL_OLDGETSTAT:
  29051. +        bi.data.ocs.ptt = hdlcdrv_ptt(s);
  29052. +        bi.data.ocs.dcd = s->hdlcrx.dcd;
  29053. +        bi.data.ocs.ptt_keyed = s->ptt_keyed;
  29054. +#if LINUX_VERSION_CODE < 0x20100
  29055. +        bi.data.ocs.stats = s->stats;
  29056. +#endif
  29057. +        break;        
  29058. +
  29059. +    case HDLCDRVCTL_CALIBRATE:
  29060. +        s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
  29061. +        return 0;
  29062. +
  29063. +    case HDLCDRVCTL_GETSAMPLES:
  29064. +#ifndef HDLCDRV_DEBUG
  29065. +        return -EPERM;
  29066. +#else /* HDLCDRV_DEBUG */
  29067. +        if (s->bitbuf_channel.rd == s->bitbuf_channel.wr) 
  29068. +            return -EAGAIN;
  29069. +        bi.data.bits = 
  29070. +            s->bitbuf_channel.buffer[s->bitbuf_channel.rd];
  29071. +        s->bitbuf_channel.rd = (s->bitbuf_channel.rd+1) %
  29072. +            sizeof(s->bitbuf_channel.buffer);
  29073. +        break;
  29074. +#endif /* HDLCDRV_DEBUG */
  29075. +                
  29076. +    case HDLCDRVCTL_GETBITS:
  29077. +#ifndef HDLCDRV_DEBUG
  29078. +        return -EPERM;
  29079. +#else /* HDLCDRV_DEBUG */
  29080. +        if (s->bitbuf_hdlc.rd == s->bitbuf_hdlc.wr) 
  29081. +            return -EAGAIN;
  29082. +        bi.data.bits = 
  29083. +            s->bitbuf_hdlc.buffer[s->bitbuf_hdlc.rd];
  29084. +        s->bitbuf_hdlc.rd = (s->bitbuf_hdlc.rd+1) %
  29085. +            sizeof(s->bitbuf_hdlc.buffer);
  29086. +        break;        
  29087. +#endif /* HDLCDRV_DEBUG */
  29088. +
  29089. +    case HDLCDRVCTL_DRIVERNAME:
  29090. +        if (s->ops && s->ops->drvname) {
  29091. +            strncpy(bi.data.drivername, s->ops->drvname, 
  29092. +                sizeof(bi.data.drivername));
  29093. +            break;
  29094. +        }
  29095. +        bi.data.drivername[0] = '\0';
  29096. +        break;
  29097. +        
  29098. +    }
  29099. +    if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
  29100. +        return -EFAULT;
  29101. +    return 0;
  29102. +
  29103. +}
  29104. +
  29105. +/* --------------------------------------------------------------------- */
  29106. +
  29107. +/*
  29108. + * Check for a network adaptor of this type, and return '0' if one exists.
  29109. + * If dev->base_addr == 0, probe all likely locations.
  29110. + * If dev->base_addr == 1, always return failure.
  29111. + * If dev->base_addr == 2, allocate space for the device and return success
  29112. + * (detachable devices only).
  29113. + */
  29114. +static int hdlcdrv_probe(struct device *dev)
  29115. +{
  29116. +    const struct hdlcdrv_channel_params dflt_ch_params = { 
  29117. +        20, 2, 10, 40, 0 
  29118. +    };
  29119. +    struct hdlcdrv_state *s;
  29120. +
  29121. +    if (!dev)
  29122. +        return -ENXIO;
  29123. +    /*
  29124. +     * not a real probe! only initialize data structures
  29125. +     */
  29126. +    s = (struct hdlcdrv_state *)dev->priv;
  29127. +    /*
  29128. +     * initialize the hdlcdrv_state struct
  29129. +     */
  29130. +    s->ch_params = dflt_ch_params;
  29131. +    s->ptt_keyed = 0;
  29132. +
  29133. +    s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
  29134. +    s->hdlcrx.in_hdlc_rx = 0;
  29135. +    s->hdlcrx.rx_state = 0;
  29136. +    
  29137. +    s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
  29138. +    s->hdlctx.in_hdlc_tx = 0;
  29139. +    s->hdlctx.tx_state = 1;
  29140. +    s->hdlctx.numflags = 0;
  29141. +    s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
  29142. +    s->hdlctx.ptt = 0;
  29143. +    s->hdlctx.slotcnt = s->ch_params.slottime;
  29144. +    s->hdlctx.calibrate = 0;
  29145. +
  29146. +#ifdef HDLCDRV_DEBUG
  29147. +    s->bitbuf_channel.rd = s->bitbuf_channel.wr = 0;
  29148. +    s->bitbuf_channel.shreg = 0x80;
  29149. +
  29150. +    s->bitbuf_hdlc.rd = s->bitbuf_hdlc.wr = 0;
  29151. +    s->bitbuf_hdlc.shreg = 0x80;
  29152. +#endif /* HDLCDRV_DEBUG */
  29153. +
  29154. +    /*
  29155. +     * initialize the device struct
  29156. +     */
  29157. +    dev->open = hdlcdrv_open;
  29158. +    dev->stop = hdlcdrv_close;
  29159. +    dev->do_ioctl = hdlcdrv_ioctl;
  29160. +    dev->hard_start_xmit = hdlcdrv_send_packet;
  29161. +    dev->get_stats = hdlcdrv_get_stats;
  29162. +
  29163. +    /* Fill in the fields of the device structure */
  29164. +
  29165. +    dev_init_buffers(dev);
  29166. +
  29167. +    skb_queue_head_init(&s->send_queue);
  29168. +    
  29169. +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
  29170. +    dev->hard_header = ax25_encapsulate;
  29171. +    dev->rebuild_header = ax25_rebuild_header;
  29172. +#else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
  29173. +    dev->hard_header = NULL;
  29174. +    dev->rebuild_header = NULL;
  29175. +#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
  29176. +    dev->set_mac_address = hdlcdrv_set_mac_address;
  29177. +    
  29178. +    dev->type = ARPHRD_AX25;           /* AF_AX25 device */
  29179. +    dev->hard_header_len = 73;         /* We do digipeaters now */
  29180. +    dev->mtu = 1500;                   /* eth_mtu is the default */
  29181. +    dev->addr_len = 7;                 /* sizeof an ax.25 address */
  29182. +    memcpy(dev->broadcast, ax25_bcast, 7);
  29183. +    memcpy(dev->dev_addr, ax25_test, 7);
  29184. +
  29185. +    /* New style flags */
  29186. +    dev->flags = 0;
  29187. +    dev->family = AF_INET;
  29188. +    dev->pa_addr = 0;
  29189. +    dev->pa_brdaddr = 0;
  29190. +    dev->pa_mask = 0;
  29191. +    dev->pa_alen = sizeof(unsigned long);
  29192. +
  29193. +    return 0;
  29194. +}
  29195. +
  29196. +/* --------------------------------------------------------------------- */
  29197. +
  29198. +int hdlcdrv_register_hdlcdrv(struct device *dev, const struct hdlcdrv_ops *ops,
  29199. +                 unsigned int privsize, char *ifname,
  29200. +                 unsigned int baseaddr, unsigned int irq, 
  29201. +                 unsigned int dma) 
  29202. +{
  29203. +    struct hdlcdrv_state *s;
  29204. +
  29205. +    if (!dev || !ops)
  29206. +        return -EACCES;
  29207. +    if (privsize < sizeof(struct hdlcdrv_state))
  29208. +        privsize = sizeof(struct hdlcdrv_state);
  29209. +    memset(dev, 0, sizeof(struct device));
  29210. +    if (!(s = dev->priv = kmalloc(privsize, GFP_KERNEL)))
  29211. +        return -ENOMEM;
  29212. +    /*
  29213. +     * initialize part of the hdlcdrv_state struct
  29214. +     */
  29215. +    memset(s, 0, privsize);
  29216. +    s->magic = HDLCDRV_MAGIC;
  29217. +    strncpy(s->ifname, ifname, sizeof(s->ifname));
  29218. +    s->ops = ops;
  29219. +    /*
  29220. +     * initialize part of the device struct
  29221. +     */
  29222. +    dev->name = s->ifname;
  29223. +    dev->if_port = 0;
  29224. +    dev->init = hdlcdrv_probe;
  29225. +    dev->start = 0;
  29226. +    dev->tbusy = 1;
  29227. +    dev->base_addr = baseaddr;
  29228. +    dev->irq = irq;
  29229. +    dev->dma = dma;
  29230. +    if (register_netdev(dev)) {
  29231. +        printk(KERN_WARNING "hdlcdrv: cannot register net "
  29232. +               "device %s\n", s->ifname);
  29233. +        kfree(dev->priv);
  29234. +        return -ENXIO;
  29235. +    }
  29236. +    MOD_INC_USE_COUNT;
  29237. +    return 0;
  29238. +}
  29239. +
  29240. +/* --------------------------------------------------------------------- */
  29241. +
  29242. +int hdlcdrv_unregister_hdlcdrv(struct device *dev) 
  29243. +{
  29244. +    struct hdlcdrv_state *s;
  29245. +
  29246. +    if (!dev)
  29247. +        return -EINVAL;
  29248. +    if (!(s = (struct hdlcdrv_state *)dev->priv))
  29249. +        return -EINVAL;
  29250. +    if (s->magic != HDLCDRV_MAGIC)
  29251. +        return -EINVAL;
  29252. +    if (dev->start && s->ops->close)
  29253. +        s->ops->close(dev);
  29254. +    unregister_netdev(dev);
  29255. +    kfree(s);
  29256. +    MOD_DEC_USE_COUNT;
  29257. +    return 0;
  29258. +}
  29259. +
  29260. +/* --------------------------------------------------------------------- */
  29261. +
  29262. +#if LINUX_VERSION_CODE >= 0x20115
  29263. +
  29264. +EXPORT_SYMBOL(hdlcdrv_receiver);
  29265. +EXPORT_SYMBOL(hdlcdrv_transmitter);
  29266. +EXPORT_SYMBOL(hdlcdrv_arbitrate);
  29267. +EXPORT_SYMBOL(hdlcdrv_register_hdlcdrv);
  29268. +EXPORT_SYMBOL(hdlcdrv_unregister_hdlcdrv);
  29269. +
  29270. +#else
  29271. +
  29272. +static struct symbol_table hdlcdrv_syms = {
  29273. +#include <linux/symtab_begin.h>
  29274. +        X(hdlcdrv_receiver),
  29275. +        X(hdlcdrv_transmitter),
  29276. +        X(hdlcdrv_arbitrate),
  29277. +        X(hdlcdrv_register_hdlcdrv),
  29278. +        X(hdlcdrv_unregister_hdlcdrv),
  29279. +#include <linux/symtab_end.h>
  29280. +};
  29281. +
  29282. +#endif
  29283. +
  29284. +/* --------------------------------------------------------------------- */
  29285. +
  29286. +#ifdef MODULE
  29287. +
  29288. +#if LINUX_VERSION_CODE >= 0x20115
  29289. +
  29290. +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
  29291. +MODULE_DESCRIPTION("Packet Radio network interface HDLC encoder/decoder");
  29292. +
  29293. +#endif
  29294. +
  29295. +/* --------------------------------------------------------------------- */
  29296. +
  29297. +__initfunc(int init_module(void))
  29298. +{
  29299. +    printk(KERN_INFO "hdlcdrv: (C) 1996 Thomas Sailer HB9JNX/AE4WA\n");
  29300. +    printk(KERN_INFO "hdlcdrv: version 0.4 compiled " __TIME__ " " __DATE__ "\n");
  29301. +#if LINUX_VERSION_CODE < 0x20115
  29302. +        register_symtab(&hdlcdrv_syms);
  29303. +#endif
  29304. +    return 0;
  29305. +}
  29306. +
  29307. +/* --------------------------------------------------------------------- */
  29308. +
  29309. +void cleanup_module(void)
  29310. +{
  29311. +    printk(KERN_INFO "hdlcdrv: cleanup\n");
  29312. +}
  29313. +
  29314. +#endif /* MODULE */
  29315. +/* --------------------------------------------------------------------- */
  29316. diff -u --recursive --new-file v2.0.34/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c
  29317. --- v2.0.34/linux/drivers/net/hp-plus.c    Thu Feb 29 21:50:44 1996
  29318. +++ linux/drivers/net/hp-plus.c    Mon Jul 13 13:47:31 1998
  29319. @@ -101,13 +101,13 @@
  29320.  static void hpp_mem_block_input(struct device *dev, int count,
  29321.                            struct sk_buff *skb, int ring_offset);
  29322.  static void hpp_mem_block_output(struct device *dev, int count,
  29323. -                            const unsigned char *buf, const start_page);
  29324. +                            const unsigned char *buf, const int start_page);
  29325.  static void hpp_mem_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
  29326.                            int ring_page);
  29327.  static void hpp_io_block_input(struct device *dev, int count,
  29328.                            struct sk_buff *skb, int ring_offset);
  29329.  static void hpp_io_block_output(struct device *dev, int count,
  29330. -                            const unsigned char *buf, const start_page);
  29331. +                            const unsigned char *buf, const int start_page);
  29332.  static void hpp_io_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
  29333.                            int ring_page);
  29334.  
  29335. @@ -385,7 +385,7 @@
  29336.     It's always safe to round up, so we do. */
  29337.  static void
  29338.  hpp_io_block_output(struct device *dev, int count,
  29339. -                    const unsigned char *buf, const start_page)
  29340. +                    const unsigned char *buf, const int start_page)
  29341.  {
  29342.      int ioaddr = dev->base_addr - NIC_OFFSET;
  29343.      outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
  29344. @@ -395,7 +395,7 @@
  29345.  
  29346.  static void
  29347.  hpp_mem_block_output(struct device *dev, int count,
  29348. -                const unsigned char *buf, const start_page)
  29349. +                const unsigned char *buf, const int start_page)
  29350.  {
  29351.      int ioaddr = dev->base_addr - NIC_OFFSET;
  29352.      int option_reg = inw(ioaddr + HPP_OPTION);
  29353. diff -u --recursive --new-file v2.0.34/linux/drivers/net/hp.c linux/drivers/net/hp.c
  29354. --- v2.0.34/linux/drivers/net/hp.c    Thu Feb 29 21:50:44 1996
  29355. +++ linux/drivers/net/hp.c    Mon Jul 13 13:47:31 1998
  29356. @@ -65,7 +65,7 @@
  29357.  static void hp_block_input(struct device *dev, int count,
  29358.                      struct sk_buff *skb , int ring_offset);
  29359.  static void hp_block_output(struct device *dev, int count,
  29360. -                            const unsigned char *buf, const start_page);
  29361. +                            const unsigned char *buf, const int start_page);
  29362.  
  29363.  static void hp_init_card(struct device *dev);
  29364.  
  29365. @@ -309,7 +309,7 @@
  29366.  
  29367.  static void
  29368.  hp_block_output(struct device *dev, int count,
  29369. -                const unsigned char *buf, const start_page)
  29370. +                const unsigned char *buf, const int start_page)
  29371.  {
  29372.      int nic_base = dev->base_addr;
  29373.      int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE);
  29374. diff -u --recursive --new-file v2.0.34/linux/drivers/net/hp100.h linux/drivers/net/hp100.h
  29375. --- v2.0.34/linux/drivers/net/hp100.h    Tue Aug  5 09:11:35 1997
  29376. +++ linux/drivers/net/hp100.h    Mon Jul 13 13:47:31 1998
  29377. @@ -529,7 +529,7 @@
  29378.   */
  29379.  
  29380.  #define MAX_RX_PDL              30   /* Card limit = 31 */
  29381. -#define MAX_RX_FRAG             2    /* Dont need more... */
  29382. +#define MAX_RX_FRAG             2    /* Don't need more... */
  29383.  #define MAX_TX_PDL              29
  29384.  #define MAX_TX_FRAG             2   /* Limit = 31 */
  29385.  
  29386. diff -u --recursive --new-file v2.0.34/linux/drivers/net/mkiss.c linux/drivers/net/mkiss.c
  29387. --- v2.0.34/linux/drivers/net/mkiss.c    Wed Dec 31 16:00:00 1969
  29388. +++ linux/drivers/net/mkiss.c    Mon Jul 13 13:47:31 1998
  29389. @@ -0,0 +1,1132 @@
  29390. +/*
  29391. + *    MKISS Driver
  29392. + *
  29393. + *    This module:
  29394. + *        This module is free software; you can redistribute it and/or
  29395. + *        modify it under the terms of the GNU General Public License
  29396. + *        as published by the Free Software Foundation; either version
  29397. + *        2 of the License, or (at your option) any later version.
  29398. + *
  29399. + *         This module implements the AX.25 protocol for kernel-based
  29400. + *        devices like TTYs. It interfaces between a raw TTY, and the
  29401. + *        kernel's AX.25 protocol layers, just like slip.c.
  29402. + *        AX.25 needs to be seperated from slip.c while slip.c is no
  29403. + *        longer a static kernel device since it is a module.
  29404. + *        This method clears the way to implement other kiss protocols
  29405. + *        like mkiss smack g8bpq ..... so far only mkiss is implemented.
  29406. + *
  29407. + * Hans Alblas <hans@esrac.ele.tue.nl>
  29408. + *
  29409. + *    History
  29410. + */
  29411. +
  29412. +#include <linux/config.h>
  29413. +#include <linux/module.h>
  29414. +#include <asm/system.h>
  29415. +#include <asm/segment.h>
  29416. +#include <asm/bitops.h>
  29417. +#include <linux/string.h>
  29418. +#include <linux/mm.h>
  29419. +#include <linux/interrupt.h>
  29420. +#include <linux/in.h>
  29421. +#include <linux/inet.h>
  29422. +#include <linux/tty.h>
  29423. +#include <linux/errno.h>
  29424. +#include <linux/netdevice.h>
  29425. +#include <linux/major.h>
  29426. +
  29427. +#include <linux/timer.h>
  29428. +
  29429. +#include <linux/etherdevice.h>
  29430. +#include <linux/skbuff.h>
  29431. +#include <linux/if_arp.h>
  29432. +
  29433. +#include <net/ax25.h>
  29434. +
  29435. +#include "mkiss.h"
  29436. +
  29437. +#ifdef CONFIG_INET
  29438. +#include <linux/ip.h>
  29439. +#include <linux/tcp.h>
  29440. +#endif
  29441. +
  29442. +#ifdef MODULE
  29443. +#define AX25_VERSION    "AX25-MODULAR-NET3.019-NEWTTY"
  29444. +#define    min(a,b)    (a < b ? a : b)
  29445. +#else
  29446. +#define    AX25_VERSION    "AX25-NET3.019-NEWTTY"
  29447. +#endif
  29448. +
  29449. +#define NR_MKISS 4
  29450. +#define MKISS_SERIAL_TYPE_NORMAL 1
  29451. +
  29452. +struct mkiss_channel {
  29453. +    int magic;        /* magic word */
  29454. +    int init;        /* channel exists? */
  29455. +    struct tty_struct *tty; /* link to tty control structure */
  29456. +};
  29457. +
  29458. +typedef struct ax25_ctrl {
  29459. +    char if_name[8];    /* "ax0\0" .. "ax99999\0"    */
  29460. +    struct ax_disp ctrl;    /*                 */
  29461. +    struct device  dev;    /* the device            */
  29462. +} ax25_ctrl_t;
  29463. +
  29464. +static ax25_ctrl_t **ax25_ctrls = NULL;
  29465. +int ax25_maxdev = AX25_MAXDEV;        /* Can be overridden with insmod! */
  29466. +
  29467. +static struct tty_ldisc    ax_ldisc;
  29468. +static struct tty_driver mkiss_driver;
  29469. +static int mkiss_refcount;
  29470. +static struct tty_struct *mkiss_table[NR_MKISS];
  29471. +static struct termios *mkiss_termios[NR_MKISS];
  29472. +static struct termios *mkiss_termios_locked[NR_MKISS];
  29473. +struct mkiss_channel MKISS_Info[NR_MKISS];
  29474. +
  29475. +static int ax25_init(struct device *);
  29476. +static int mkiss_init(void);
  29477. +static int mkiss_write(struct tty_struct *, int, const unsigned char *, int);
  29478. +static int kiss_esc(unsigned char *, unsigned char *, int);
  29479. +static void kiss_unesc(struct ax_disp *, unsigned char);
  29480. +
  29481. +/* Find a free channel, and link in this `tty' line. */
  29482. +static inline struct ax_disp *ax_alloc(void)
  29483. +{
  29484. +    ax25_ctrl_t *axp;
  29485. +    int i;
  29486. +
  29487. +    if (ax25_ctrls == NULL)        /* Master array missing ! */
  29488. +        return NULL;
  29489. +
  29490. +    for (i = 0; i < ax25_maxdev; i++) {
  29491. +        axp = ax25_ctrls[i];
  29492. +
  29493. +        /* Not allocated ? */
  29494. +        if (axp == NULL)
  29495. +            break;
  29496. +
  29497. +        /* Not in use ? */
  29498. +        if (!set_bit(AXF_INUSE, &axp->ctrl.flags))
  29499. +            break;
  29500. +    }
  29501. +
  29502. +    /* Sorry, too many, all slots in use */
  29503. +    if (i >= ax25_maxdev)
  29504. +        return NULL;
  29505. +
  29506. +    /* If no channels are available, allocate one */
  29507. +    if (axp == NULL && (ax25_ctrls[i] = (ax25_ctrl_t *)kmalloc(sizeof(ax25_ctrl_t), GFP_KERNEL)) != NULL) {
  29508. +        axp = ax25_ctrls[i];
  29509. +        memset(axp, 0, sizeof(ax25_ctrl_t));
  29510. +
  29511. +        /* Initialize channel control data */
  29512. +        set_bit(AXF_INUSE, &axp->ctrl.flags);
  29513. +        sprintf(axp->if_name, "ax%d", i++);
  29514. +        axp->ctrl.tty      = NULL;
  29515. +        axp->dev.name      = axp->if_name;
  29516. +        axp->dev.base_addr = i;
  29517. +        axp->dev.priv      = (void *)&axp->ctrl;
  29518. +        axp->dev.next      = NULL;
  29519. +        axp->dev.init      = ax25_init;
  29520. +    }
  29521. +
  29522. +    if (axp != NULL) {
  29523. +        /*
  29524. +         * register device so that it can be ifconfig'ed
  29525. +         * ax25_init() will be called as a side-effect
  29526. +         * SIDE-EFFECT WARNING: ax25_init() CLEARS axp->ctrl !
  29527. +         */
  29528. +        if (register_netdev(&axp->dev) == 0) {
  29529. +            /* (Re-)Set the INUSE bit.   Very Important! */
  29530. +            set_bit(AXF_INUSE, &axp->ctrl.flags);
  29531. +            axp->ctrl.dev = &axp->dev;
  29532. +            axp->dev.priv = (void *)&axp->ctrl;
  29533. +
  29534. +            return &axp->ctrl;
  29535. +        } else {
  29536. +            clear_bit(AXF_INUSE,&axp->ctrl.flags);
  29537. +            printk(KERN_ERR "ax_alloc() - register_netdev() failure.\n");
  29538. +        }
  29539. +    }
  29540. +
  29541. +    return NULL;
  29542. +}
  29543. +
  29544. +/* Free an AX25 channel. */
  29545. +static inline void ax_free(struct ax_disp *ax)
  29546. +{
  29547. +    /* Free all AX25 frame buffers. */
  29548. +    if (ax->rbuff)
  29549. +        kfree(ax->rbuff);
  29550. +    ax->rbuff = NULL;
  29551. +    if (ax->xbuff)
  29552. +        kfree(ax->xbuff);
  29553. +    ax->xbuff = NULL;
  29554. +    if (!clear_bit(AXF_INUSE, &ax->flags))
  29555. +        printk(KERN_ERR "%s: ax_free for already free unit.\n", ax->dev->name);
  29556. +}
  29557. +
  29558. +static void ax_changedmtu(struct ax_disp *ax)
  29559. +{
  29560. +    struct device *dev = ax->dev;
  29561. +    unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
  29562. +    int len;
  29563. +    unsigned long flags;
  29564. +
  29565. +    len = dev->mtu * 2;
  29566. +
  29567. +    /*
  29568. +     * allow for arrival of larger UDP packets, even if we say not to
  29569. +     * also fixes a bug in which SunOS sends 512-byte packets even with
  29570. +     * an MSS of 128
  29571. +     */
  29572. +    if (len < 576 * 2)
  29573. +        len = 576 * 2;
  29574. +
  29575. +    xbuff = (unsigned char *)kmalloc(len + 4, GFP_ATOMIC);
  29576. +    rbuff = (unsigned char *)kmalloc(len + 4, GFP_ATOMIC);
  29577. +
  29578. +    if (xbuff == NULL || rbuff == NULL)  {
  29579. +        printk(KERN_ERR "%s: unable to grow ax25 buffers, MTU change cancelled.\n",
  29580. +               ax->dev->name);
  29581. +        dev->mtu = ax->mtu;
  29582. +        if (xbuff != NULL)
  29583. +            kfree(xbuff);
  29584. +        if (rbuff != NULL)
  29585. +            kfree(rbuff);
  29586. +        return;
  29587. +    }
  29588. +
  29589. +    save_flags(flags);
  29590. +    cli();
  29591. +
  29592. +    oxbuff    = ax->xbuff;
  29593. +    ax->xbuff = xbuff;
  29594. +    orbuff    = ax->rbuff;
  29595. +    ax->rbuff = rbuff;
  29596. +
  29597. +    if (ax->xleft) {
  29598. +        if (ax->xleft <= len) {
  29599. +            memcpy(ax->xbuff, ax->xhead, ax->xleft);
  29600. +        } else  {
  29601. +            ax->xleft = 0;
  29602. +            ax->tx_dropped++;
  29603. +        }
  29604. +    }
  29605. +
  29606. +    ax->xhead = ax->xbuff;
  29607. +
  29608. +    if (ax->rcount) {
  29609. +        if (ax->rcount <= len) {
  29610. +            memcpy(ax->rbuff, orbuff, ax->rcount);
  29611. +        } else  {
  29612. +            ax->rcount = 0;
  29613. +            ax->rx_over_errors++;
  29614. +            set_bit(AXF_ERROR, &ax->flags);
  29615. +        }
  29616. +    }
  29617. +
  29618. +    ax->mtu      = dev->mtu + 73;
  29619. +    ax->buffsize = len;
  29620. +
  29621. +    restore_flags(flags);
  29622. +
  29623. +    if (oxbuff != NULL)
  29624. +        kfree(oxbuff);
  29625. +    if (orbuff != NULL)
  29626. +        kfree(orbuff);
  29627. +}
  29628. +
  29629. +
  29630. +/* Set the "sending" flag.  This must be atomic, hence the ASM. */
  29631. +static inline void ax_lock(struct ax_disp *ax)
  29632. +{
  29633. +    if (set_bit(0, (void *)&ax->dev->tbusy))
  29634. +        printk(KERN_ERR "%s: trying to lock already locked device!\n", ax->dev->name);
  29635. +}
  29636. +
  29637. +
  29638. +/* Clear the "sending" flag.  This must be atomic, hence the ASM. */
  29639. +static inline void ax_unlock(struct ax_disp *ax)
  29640. +{
  29641. +    if (!clear_bit(0, (void *)&ax->dev->tbusy))
  29642. +        printk(KERN_ERR "%s: trying to unlock already unlocked device!\n", ax->dev->name);
  29643. +}
  29644. +
  29645. +/* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
  29646. +static void ax_bump(struct ax_disp *ax)
  29647. +{
  29648. +    struct ax_disp *tmp_ax;
  29649. +    struct sk_buff *skb;
  29650. +    struct mkiss_channel *mkiss;
  29651. +    int count;
  29652. +
  29653. +        tmp_ax = ax;
  29654. +
  29655. +    if (ax->rbuff[0] > 0x0f) {
  29656. +        if (ax->mkiss != NULL) {
  29657. +            mkiss= ax->mkiss->tty->driver_data;
  29658. +            if (mkiss->magic == MKISS_DRIVER_MAGIC)
  29659. +                tmp_ax = ax->mkiss;
  29660. +        }
  29661. +     }
  29662. +
  29663. +    count = ax->rcount;
  29664. +
  29665. +    if ((skb = dev_alloc_skb(count)) == NULL) {
  29666. +        printk(KERN_ERR "%s: memory squeeze, dropping packet.\n", ax->dev->name);
  29667. +        ax->rx_dropped++;
  29668. +        return;
  29669. +    }
  29670. +
  29671. +    skb->dev      = tmp_ax->dev;
  29672. +    memcpy(skb_put(skb,count), ax->rbuff, count);
  29673. +    skb->mac.raw  = skb->data;
  29674. +    skb->protocol = htons(ETH_P_AX25);
  29675. +    netif_rx(skb);
  29676. +    tmp_ax->rx_packets++;
  29677. +}
  29678. +
  29679. +/* Encapsulate one AX.25 packet and stuff into a TTY queue. */
  29680. +static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len)
  29681. +{
  29682. +    unsigned char *p;
  29683. +    int actual, count;
  29684. +    struct mkiss_channel *mkiss = ax->tty->driver_data;
  29685. +
  29686. +    if (ax->mtu != ax->dev->mtu + 73)    /* Someone has been ifconfigging */
  29687. +        ax_changedmtu(ax);
  29688. +
  29689. +    if (len > ax->mtu) {        /* Sigh, shouldn't occur BUT ... */
  29690. +        len = ax->mtu;
  29691. +        printk(KERN_ERR "%s: truncating oversized transmit packet!\n", ax->dev->name);
  29692. +        ax->tx_dropped++;
  29693. +        ax_unlock(ax);
  29694. +        return;
  29695. +    }
  29696. +
  29697. +    p = icp;
  29698. +
  29699. +    if (mkiss->magic  != MKISS_DRIVER_MAGIC) {
  29700. +        count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
  29701. +        ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
  29702. +        actual = ax->tty->driver.write(ax->tty, 0, ax->xbuff, count);
  29703. +        ax->tx_packets++;
  29704. +        ax->dev->trans_start = jiffies;
  29705. +        ax->xleft = count - actual;
  29706. +        ax->xhead = ax->xbuff + actual;
  29707. +    } else {
  29708. +        count = kiss_esc(p, (unsigned char *) ax->mkiss->xbuff, len);
  29709. +        ax->mkiss->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
  29710. +        actual = ax->mkiss->tty->driver.write(ax->mkiss->tty, 0, ax->mkiss->xbuff, count);
  29711. +        ax->tx_packets++;
  29712. +        ax->mkiss->dev->trans_start = jiffies;
  29713. +        ax->mkiss->xleft = count - actual;
  29714. +        ax->mkiss->xhead = ax->mkiss->xbuff + actual;
  29715. +    }
  29716. +}
  29717. +
  29718. +/*
  29719. + * Called by the driver when there's room for more data.  If we have
  29720. + * more packets to send, we send them here.
  29721. + */
  29722. +static void ax25_write_wakeup(struct tty_struct *tty)
  29723. +{
  29724. +    int actual;
  29725. +    struct ax_disp *ax = (struct ax_disp *)tty->disc_data;
  29726. +    struct mkiss_channel *mkiss;
  29727. +
  29728. +    /* First make sure we're connected. */
  29729. +    if (ax == NULL || ax->magic != AX25_MAGIC || !ax->dev->start)
  29730. +        return;
  29731. +    if (ax->xleft <= 0)  {
  29732. +        /* Now serial buffer is almost free & we can start
  29733. +         * transmission of another packet
  29734. +         */
  29735. +        tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
  29736. +
  29737. +        if (ax->mkiss != NULL) {
  29738. +            mkiss= ax->mkiss->tty->driver_data;
  29739. +                if (mkiss->magic  == MKISS_DRIVER_MAGIC)
  29740. +                ax_unlock(ax->mkiss);
  29741. +            }
  29742. +
  29743. +        ax_unlock(ax);
  29744. +        mark_bh(NET_BH);
  29745. +        return;
  29746. +    }
  29747. +
  29748. +    actual = tty->driver.write(tty, 0, ax->xhead, ax->xleft);
  29749. +    ax->xleft -= actual;
  29750. +    ax->xhead += actual;
  29751. +}
  29752. +
  29753. +/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
  29754. +static int ax_xmit(struct sk_buff *skb, struct device *dev)
  29755. +{
  29756. +    struct ax_disp *ax = (struct ax_disp*)dev->priv;
  29757. +    struct mkiss_channel *mkiss = ax->tty->driver_data;
  29758. +    struct ax_disp *tmp_ax;
  29759. +
  29760. +    tmp_ax = NULL;
  29761. +
  29762. +    if (mkiss->magic  == MKISS_DRIVER_MAGIC) {
  29763. +        if (skb->data[0] < 0x10)
  29764. +            skb->data[0] = skb->data[0] + 0x10;
  29765. +        tmp_ax = ax->mkiss;
  29766. +    }
  29767. +
  29768. +    if (!dev->start)  {
  29769. +        printk(KERN_ERR "%s: xmit call when iface is down\n", dev->name);
  29770. +        return 1;
  29771. +    }
  29772. +
  29773. +    if (tmp_ax != NULL)
  29774. +        if (tmp_ax->dev->tbusy)
  29775. +            return 1;
  29776. +
  29777. +    if (tmp_ax != NULL)
  29778. +        if (dev->tbusy) {
  29779. +            printk(KERN_ERR "mkiss: dev busy while serial dev is free\n");
  29780. +            ax_unlock(ax);
  29781. +            }
  29782. +
  29783. +    if (dev->tbusy) {
  29784. +        /*
  29785. +         * May be we must check transmitter timeout here ?
  29786. +         *      14 Oct 1994 Dmitry Gorodchanin.
  29787. +         */
  29788. +        if (jiffies - dev->trans_start  < 20 * HZ) {
  29789. +            /* 20 sec timeout not reached */
  29790. +            return 1;
  29791. +        }
  29792. +
  29793. +        printk(KERN_ERR "%s: transmit timed out, %s?\n", dev->name,
  29794. +               (ax->tty->driver.chars_in_buffer(ax->tty) || ax->xleft) ?
  29795. +               "bad line quality" : "driver error");
  29796. +
  29797. +        ax->xleft = 0;
  29798. +        ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
  29799. +        ax_unlock(ax);
  29800. +    }
  29801. +
  29802. +    /* We were not busy, so we are now... :-) */
  29803. +    if (skb != NULL) {
  29804. +        ax_lock(ax);
  29805. +        if (tmp_ax != NULL)
  29806. +            ax_lock(tmp_ax);
  29807. +        ax_encaps(ax, skb->data, skb->len);
  29808. +        dev_kfree_skb(skb, FREE_WRITE);
  29809. +    }
  29810. +
  29811. +    return 0;
  29812. +}
  29813. +
  29814. +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
  29815. +
  29816. +/* Return the frame type ID */
  29817. +static int ax_header(struct sk_buff *skb, struct device *dev, unsigned short type,
  29818. +      void *daddr, void *saddr, unsigned len)
  29819. +{
  29820. +#ifdef CONFIG_INET
  29821. +    if (type != htons(ETH_P_AX25))
  29822. +        return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
  29823. +#endif
  29824. +    return 0;
  29825. +}
  29826. +
  29827. +
  29828. +static int ax_rebuild_header(void *buff, struct device *dev, unsigned long raddr, struct sk_buff *skb)
  29829. +{
  29830. +#ifdef CONFIG_INET
  29831. +    return ax25_rebuild_header(buff, dev, raddr, skb);
  29832. +#else
  29833. +    return 0;
  29834. +#endif
  29835. +}
  29836. +
  29837. +#endif /* CONFIG_{AX25,AX25_MODULE} */
  29838. +
  29839. +/* Open the low-level part of the AX25 channel. Easy! */
  29840. +static int ax_open(struct device *dev)
  29841. +{
  29842. +    struct ax_disp *ax = (struct ax_disp*)dev->priv;
  29843. +    unsigned long len;
  29844. +
  29845. +    if (ax->tty == NULL)
  29846. +        return -ENODEV;
  29847. +
  29848. +    /*
  29849. +     * Allocate the frame buffers:
  29850. +     *
  29851. +     * rbuff    Receive buffer.
  29852. +     * xbuff    Transmit buffer.
  29853. +     * cbuff        Temporary compression buffer.
  29854. +     */
  29855. +    len = dev->mtu * 2;
  29856. +
  29857. +    /*
  29858. +     * allow for arrival of larger UDP packets, even if we say not to
  29859. +     * also fixes a bug in which SunOS sends 512-byte packets even with
  29860. +     * an MSS of 128
  29861. +     */
  29862. +    if (len < 576 * 2)
  29863. +        len = 576 * 2;
  29864. +
  29865. +    if ((ax->rbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL)) == NULL)
  29866. +        goto norbuff;
  29867. +
  29868. +    if ((ax->xbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL)) == NULL)
  29869. +        goto noxbuff;
  29870. +
  29871. +    ax->mtu         = dev->mtu + 73;
  29872. +    ax->buffsize = len;
  29873. +    ax->rcount   = 0;
  29874. +    ax->xleft    = 0;
  29875. +
  29876. +    ax->flags   &= (1 << AXF_INUSE);      /* Clear ESCAPE & ERROR flags */
  29877. +    /* Needed because address '0' is special */
  29878. +    if (dev->pa_addr == 0)
  29879. +        dev->pa_addr = ntohl(0xC0A80001);
  29880. +    dev->tbusy  = 0;
  29881. +    dev->start  = 1;
  29882. +
  29883. +    return 0;
  29884. +
  29885. +    /* Cleanup */
  29886. +    kfree(ax->xbuff);
  29887. +
  29888. +noxbuff:
  29889. +    kfree(ax->rbuff);
  29890. +
  29891. +norbuff:
  29892. +    return -ENOMEM;
  29893. +}
  29894. +
  29895. +
  29896. +/* Close the low-level part of the AX25 channel. Easy! */
  29897. +static int ax_close(struct device *dev)
  29898. +{
  29899. +    struct ax_disp *ax = (struct ax_disp*)dev->priv;
  29900. +
  29901. +    if (ax->tty == NULL)
  29902. +        return -EBUSY;
  29903. +
  29904. +    ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
  29905. +
  29906. +    dev->tbusy = 1;
  29907. +    dev->start = 0;
  29908. +
  29909. +    return 0;
  29910. +}
  29911. +
  29912. +static int ax25_receive_room(struct tty_struct *tty)
  29913. +{
  29914. +    return 65536;  /* We can handle an infinite amount of data. :-) */
  29915. +}
  29916. +
  29917. +/*
  29918. + * Handle the 'receiver data ready' interrupt.
  29919. + * This function is called by the 'tty_io' module in the kernel when
  29920. + * a block of data has been received, which can now be decapsulated
  29921. + * and sent on to the AX.25 layer for further processing.
  29922. + */
  29923. +static void ax25_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
  29924. +{
  29925. +    struct ax_disp *ax = (struct ax_disp *)tty->disc_data;
  29926. +
  29927. +    if (ax == NULL || ax->magic != AX25_MAGIC || !ax->dev->start)
  29928. +        return;
  29929. +
  29930. +    /*
  29931. +     * Argh! mtu change time! - costs us the packet part received
  29932. +     * at the change
  29933. +     */
  29934. +    if (ax->mtu != ax->dev->mtu + 73)
  29935. +        ax_changedmtu(ax);
  29936. +
  29937. +    /* Read the characters out of the buffer */
  29938. +    while (count--) {
  29939. +        if (fp != NULL && *fp++) {
  29940. +            if (!set_bit(AXF_ERROR, &ax->flags))
  29941. +                ax->rx_errors++;
  29942. +            cp++;
  29943. +            continue;
  29944. +        }
  29945. +
  29946. +        kiss_unesc(ax, *cp++);
  29947. +    }
  29948. +}
  29949. +
  29950. +static int ax25_open(struct tty_struct *tty)
  29951. +{
  29952. +    struct ax_disp *ax = (struct ax_disp *)tty->disc_data;
  29953. +    struct ax_disp *tmp_ax;
  29954. +    struct mkiss_channel *mkiss;
  29955. +    int err, cnt;
  29956. +
  29957. +    /* First make sure we're not already connected. */
  29958. +    if (ax && ax->magic == AX25_MAGIC)
  29959. +        return -EEXIST;
  29960. +
  29961. +    /* OK.  Find a free AX25 channel to use. */
  29962. +    if ((ax = ax_alloc()) == NULL)
  29963. +        return -ENFILE;
  29964. +
  29965. +    ax->tty = tty;
  29966. +    tty->disc_data = ax;
  29967. +
  29968. +    ax->mkiss = NULL;
  29969. +    tmp_ax    = NULL;
  29970. +
  29971. +    if (tty->driver.flush_buffer)
  29972. +        tty->driver.flush_buffer(tty);
  29973. +    if (tty->ldisc.flush_buffer)
  29974. +        tty->ldisc.flush_buffer(tty);
  29975. +
  29976. +    /* Restore default settings */
  29977. +    ax->dev->type = ARPHRD_AX25;
  29978. +
  29979. +    /* Perform the low-level AX25 initialization. */
  29980. +    if ((err = ax_open(ax->dev)))
  29981. +        return err;
  29982. +
  29983. +    mkiss= ax->tty->driver_data;
  29984. +
  29985. +    if (mkiss->magic  == MKISS_DRIVER_MAGIC) {
  29986. +        for (cnt = 1; cnt < ax25_maxdev; cnt++) {
  29987. +            if (ax25_ctrls[cnt]) {
  29988. +                if (ax25_ctrls[cnt]->dev.start) {
  29989. +                    if (ax == &ax25_ctrls[cnt]->ctrl) {
  29990. +                        cnt--;
  29991. +                        tmp_ax = &ax25_ctrls[cnt]->ctrl;
  29992. +                        break;
  29993. +                    }
  29994. +                }
  29995. +            }
  29996. +        }
  29997. +    }
  29998. +
  29999. +    if (tmp_ax != NULL) {
  30000. +        ax->mkiss     = tmp_ax;
  30001. +        tmp_ax->mkiss = ax;
  30002. +    }
  30003. +
  30004. +    MOD_INC_USE_COUNT;
  30005. +
  30006. +    /* Done.  We have linked the TTY line to a channel. */
  30007. +    return ax->dev->base_addr;
  30008. +}
  30009. +
  30010. +static void ax25_close(struct tty_struct *tty)
  30011. +{
  30012. +    struct ax_disp *ax = (struct ax_disp *)tty->disc_data;
  30013. +    int mkiss ;
  30014. +
  30015. +    /* First make sure we're connected. */
  30016. +    if (ax == NULL || ax->magic != AX25_MAGIC)
  30017. +        return;
  30018. +
  30019. +    mkiss = ax->mode;
  30020. +    dev_close(ax->dev);
  30021. +
  30022. +    tty->disc_data = 0;
  30023. +    ax->tty        = NULL;
  30024. +
  30025. +    /* VSV = very important to remove timers */
  30026. +    ax_free(ax);
  30027. +    unregister_netdev(ax->dev);
  30028. +
  30029. +    MOD_DEC_USE_COUNT;
  30030. +}
  30031. +
  30032. +
  30033. +static struct enet_statistics *ax_get_stats(struct device *dev)
  30034. +{
  30035. +    static struct enet_statistics stats;
  30036. +    struct ax_disp *ax = (struct ax_disp*)dev->priv;
  30037. +
  30038. +    memset(&stats, 0, sizeof(struct enet_statistics));
  30039. +
  30040. +    stats.rx_packets     = ax->rx_packets;
  30041. +    stats.tx_packets     = ax->tx_packets;
  30042. +    stats.rx_dropped     = ax->rx_dropped;
  30043. +    stats.tx_dropped     = ax->tx_dropped;
  30044. +    stats.tx_errors      = ax->tx_errors;
  30045. +    stats.rx_errors      = ax->rx_errors;
  30046. +    stats.rx_over_errors = ax->rx_over_errors;
  30047. +
  30048. +    return &stats;
  30049. +}
  30050. +
  30051. +
  30052. +/************************************************************************
  30053. + *               STANDARD ENCAPSULATION                 *
  30054. + ************************************************************************/
  30055. +
  30056. +int kiss_esc(unsigned char *s, unsigned char *d, int len)
  30057. +{
  30058. +    unsigned char *ptr = d;
  30059. +    unsigned char c;
  30060. +
  30061. +    /*
  30062. +     * Send an initial END character to flush out any
  30063. +     * data that may have accumulated in the receiver
  30064. +     * due to line noise.
  30065. +     */
  30066. +
  30067. +    *ptr++ = END;
  30068. +
  30069. +    while (len-- > 0) {
  30070. +        switch (c = *s++) {
  30071. +            case END:
  30072. +                *ptr++ = ESC;
  30073. +                *ptr++ = ESC_END;
  30074. +                break;
  30075. +            case ESC:
  30076. +                *ptr++ = ESC;
  30077. +                *ptr++ = ESC_ESC;
  30078. +                break;
  30079. +            default:
  30080. +                *ptr++ = c;
  30081. +                break;
  30082. +        }
  30083. +    }
  30084. +
  30085. +    *ptr++ = END;
  30086. +
  30087. +    return ptr - d;
  30088. +}
  30089. +
  30090. +static void kiss_unesc(struct ax_disp *ax, unsigned char s)
  30091. +{
  30092. +    switch (s) {
  30093. +        case END:
  30094. +            /* drop keeptest bit = VSV */
  30095. +            if (test_bit(AXF_KEEPTEST, &ax->flags))
  30096. +                clear_bit(AXF_KEEPTEST, &ax->flags);
  30097. +
  30098. +            if (!clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
  30099. +                ax_bump(ax);
  30100. +
  30101. +            clear_bit(AXF_ESCAPE, &ax->flags);
  30102. +            ax->rcount = 0;
  30103. +            return;
  30104. +
  30105. +        case ESC:
  30106. +            set_bit(AXF_ESCAPE, &ax->flags);
  30107. +            return;
  30108. +        case ESC_ESC:
  30109. +            if (clear_bit(AXF_ESCAPE, &ax->flags))
  30110. +                s = ESC;
  30111. +            break;
  30112. +        case ESC_END:
  30113. +            if (clear_bit(AXF_ESCAPE, &ax->flags))
  30114. +                s = END;
  30115. +            break;
  30116. +    }
  30117. +
  30118. +    if (!test_bit(AXF_ERROR, &ax->flags)) {
  30119. +        if (ax->rcount < ax->buffsize) {
  30120. +            ax->rbuff[ax->rcount++] = s;
  30121. +            return;
  30122. +        }
  30123. +
  30124. +        ax->rx_over_errors++;
  30125. +        set_bit(AXF_ERROR, &ax->flags);
  30126. +    }
  30127. +}
  30128. +
  30129. +
  30130. +int ax_set_mac_address(struct device *dev, void *addr)
  30131. +{
  30132. +    int err;
  30133. +
  30134. +    if ((err = verify_area(VERIFY_READ, addr, AX25_ADDR_LEN)) != 0)
  30135. +        return err;
  30136. +
  30137. +    /* addr is an AX.25 shifted ASCII mac address */
  30138. +    memcpy_fromfs(dev->dev_addr, addr, AX25_ADDR_LEN);
  30139. +
  30140. +    return 0;
  30141. +}
  30142. +
  30143. +static int ax_set_dev_mac_address(struct device *dev, void *addr)
  30144. +{
  30145. +    struct sockaddr *sa = addr;
  30146. +
  30147. +    memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN);
  30148. +
  30149. +    return 0;
  30150. +}
  30151. +
  30152. +
  30153. +/* Perform I/O control on an active ax25 channel. */
  30154. +static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
  30155. +{
  30156. +    struct ax_disp *ax = (struct ax_disp *)tty->disc_data;
  30157. +    int err;
  30158. +    unsigned int tmp;
  30159. +
  30160. +    /* First make sure we're connected. */
  30161. +    if (ax == NULL || ax->magic != AX25_MAGIC)
  30162. +        return -EINVAL;
  30163. +
  30164. +    switch (cmd) {
  30165. +         case SIOCGIFNAME:
  30166. +            if ((err = verify_area(VERIFY_WRITE, arg, strlen(ax->dev->name) + 1)) != 0)
  30167. +                return err;
  30168. +            memcpy_tofs(arg, ax->dev->name, strlen(ax->dev->name) + 1);
  30169. +            return 0;
  30170. +
  30171. +        case SIOCGIFENCAP:
  30172. +            if ((err = verify_area(VERIFY_WRITE, arg, sizeof(int))) != 0)
  30173. +                return err;
  30174. +            put_user(4, (int *)arg);
  30175. +            return 0;
  30176. +
  30177. +        case SIOCSIFENCAP:
  30178. +            if ((err = verify_area(VERIFY_READ, arg, sizeof(int))) != 0)
  30179. +                return err;
  30180. +            tmp = get_user((int *)arg);
  30181. +             ax->mode = tmp;
  30182. +            ax->dev->addr_len        = AX25_ADDR_LEN;      /* sizeof an AX.25 addr */
  30183. +            ax->dev->hard_header_len = AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3;
  30184. +            ax->dev->type            = ARPHRD_AX25;
  30185. +            return 0;
  30186. +
  30187. +         case SIOCSIFHWADDR:
  30188. +            return ax_set_mac_address(ax->dev, arg);
  30189. +
  30190. +        default:
  30191. +            return -ENOIOCTLCMD;
  30192. +    }
  30193. +}
  30194. +
  30195. +static int ax_open_dev(struct device *dev)
  30196. +{
  30197. +    struct ax_disp *ax = (struct ax_disp*)dev->priv;
  30198. +
  30199. +    if (ax->tty==NULL)
  30200. +        return -ENODEV;
  30201. +
  30202. +    return 0;
  30203. +}
  30204. +
  30205. +/* Initialize AX25 control device -- register AX25 line discipline */
  30206. +int mkiss_init_ctrl_dev(void)
  30207. +{
  30208. +    int status;
  30209. +
  30210. +    if (ax25_maxdev < 4) ax25_maxdev = 4; /* Sanity */
  30211. +
  30212. +    if ((ax25_ctrls = (ax25_ctrl_t **)kmalloc(sizeof(void*) * ax25_maxdev, GFP_KERNEL)) == NULL) {
  30213. +        printk(KERN_ERR "mkiss: Can't allocate ax25_ctrls[] array !  No mkiss available\n");
  30214. +        return -ENOMEM;
  30215. +    }
  30216. +
  30217. +    /* Clear the pointer array, we allocate devices when we need them */
  30218. +    memset(ax25_ctrls, 0, sizeof(void*) * ax25_maxdev); /* Pointers */
  30219. +
  30220. +    /* Fill in our line protocol discipline, and register it */
  30221. +    memset(&ax_ldisc, 0, sizeof(ax_ldisc));
  30222. +    ax_ldisc.magic  = TTY_LDISC_MAGIC;
  30223. +    ax_ldisc.flags  = 0;
  30224. +    ax_ldisc.open   = ax25_open;
  30225. +    ax_ldisc.close  = ax25_close;
  30226. +    ax_ldisc.read   = NULL;
  30227. +    ax_ldisc.write  = NULL;
  30228. +    ax_ldisc.ioctl  = (int (*)(struct tty_struct *, struct file *, unsigned int, unsigned long))ax25_disp_ioctl;
  30229. +    ax_ldisc.select = NULL;
  30230. +
  30231. +    ax_ldisc.receive_buf  = ax25_receive_buf;
  30232. +    ax_ldisc.receive_room = ax25_receive_room;
  30233. +    ax_ldisc.write_wakeup = ax25_write_wakeup;
  30234. +
  30235. +    if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0)
  30236. +        printk(KERN_ERR "mkiss: can't register line discipline (err = %d)\n", status);
  30237. +
  30238. +    mkiss_init();
  30239. +
  30240. +#ifdef MODULE
  30241. +    return status;
  30242. +#else
  30243. +    /*
  30244. +     * Return "not found", so that dev_init() will unlink
  30245. +     * the placeholder device entry for us.
  30246. +     */
  30247. +    return ENODEV;
  30248. +#endif
  30249. +}
  30250. +
  30251. +
  30252. +/* Initialize the driver.  Called by network startup. */
  30253. +
  30254. +static int ax25_init(struct device *dev)
  30255. +{
  30256. +    struct ax_disp *ax = (struct ax_disp*)dev->priv;
  30257. +    int i;
  30258. +
  30259. +    static char ax25_bcast[AX25_ADDR_LEN] =
  30260. +        {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
  30261. +    static char ax25_test[AX25_ADDR_LEN] =
  30262. +        {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
  30263. +
  30264. +    if (ax == NULL)        /* Allocation failed ?? */
  30265. +        return -ENODEV;
  30266. +
  30267. +    /* Set up the "AX25 Control Block". (And clear statistics) */
  30268. +    memset(ax, 0, sizeof (struct ax_disp));
  30269. +    ax->magic  = AX25_MAGIC;
  30270. +    ax->dev       = dev;
  30271. +
  30272. +    /* Finish setting up the DEVICE info. */
  30273. +    dev->mtu             = AX_MTU;
  30274. +    dev->hard_start_xmit = ax_xmit;
  30275. +    dev->open            = ax_open_dev;
  30276. +    dev->stop            = ax_close;
  30277. +    dev->get_stats         = ax_get_stats;
  30278. +#ifdef HAVE_SET_MAC_ADDR
  30279. +    dev->set_mac_address = ax_set_dev_mac_address;
  30280. +#endif
  30281. +    dev->hard_header_len = 0;
  30282. +    dev->addr_len        = 0;
  30283. +    dev->type            = ARPHRD_AX25;
  30284. +    dev->tx_queue_len    = 10;
  30285. +
  30286. +    memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
  30287. +    memcpy(dev->dev_addr,  ax25_test,  AX25_ADDR_LEN);
  30288. +
  30289. +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
  30290. +    dev->hard_header     = ax_header;
  30291. +    dev->rebuild_header  = ax_rebuild_header;
  30292. +#endif
  30293. +
  30294. +    for (i = 0; i < DEV_NUMBUFFS; i++)
  30295. +        skb_queue_head_init(&dev->buffs[i]);
  30296. +
  30297. +    /* New-style flags. */
  30298. +    dev->flags      = 0;
  30299. +    dev->family     = AF_INET;
  30300. +
  30301. +#ifdef CONFIG_INET
  30302. +    dev->pa_addr    = in_aton("192.168.0.1");
  30303. +    dev->pa_brdaddr = in_aton("192.168.0.255");
  30304. +    dev->pa_mask    = in_aton("255.255.255.0");
  30305. +    dev->pa_alen    = 4;
  30306. +#endif
  30307. +
  30308. +    return 0;
  30309. +}
  30310. +
  30311. +static int mkiss_open(struct tty_struct *tty, struct file *filp)
  30312. +{
  30313. +    struct mkiss_channel *mkiss;
  30314. +    int chan;
  30315. +
  30316. +    chan = MINOR(tty->device) - tty->driver.minor_start;
  30317. +
  30318. +    if (chan < 0 || chan >= NR_MKISS)
  30319. +        return -ENODEV;
  30320. +
  30321. +    mkiss = &MKISS_Info[chan];
  30322. +
  30323. +    mkiss->magic =  MKISS_DRIVER_MAGIC;
  30324. +    mkiss->init  = 1;
  30325. +    mkiss->tty   = tty;
  30326. +
  30327. +    tty->driver_data = mkiss;
  30328. +
  30329. +    tty->termios->c_iflag  = IGNBRK | IGNPAR;
  30330. +    tty->termios->c_cflag  = B9600 | CS8 | CLOCAL;
  30331. +    tty->termios->c_cflag &= ~CBAUD;
  30332. +
  30333. +    return 0;
  30334. +}
  30335. +
  30336. +static void mkiss_close(struct tty_struct *tty, struct file * filp)
  30337. +{
  30338. +    struct mkiss_channel *mkiss = tty->driver_data;
  30339. +
  30340. +    if (mkiss == NULL || mkiss->magic != MKISS_DRIVER_MAGIC)
  30341. +                return;
  30342. +
  30343. +    mkiss->tty   = NULL;
  30344. +    mkiss->init  = 0;
  30345. +    tty->stopped = 0;
  30346. +}
  30347. +
  30348. +static int mkiss_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
  30349. +{
  30350. +    return 0;
  30351. +}
  30352. +
  30353. +static int mkiss_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
  30354. +{
  30355. +    /* Ignore serial ioctl's */
  30356. +    switch (cmd) {
  30357. +        case TCSBRK:
  30358. +        case TIOCMGET:
  30359. +        case TIOCMBIS:
  30360. +        case TIOCMBIC:
  30361. +        case TIOCMSET:
  30362. +        case TCSETS:
  30363. +        case TCSETSF:        /* should flush first, but... */
  30364. +        case TCSETSW:        /* should wait until flush, but... */
  30365. +            return 0;
  30366. +        default:
  30367. +            return -ENOIOCTLCMD;
  30368. +    }
  30369. +}
  30370. +
  30371. +
  30372. +static void mkiss_dummy(struct tty_struct *tty)
  30373. +{
  30374. +    struct mkiss_channel *mkiss = tty->driver_data;
  30375. +
  30376. +    if (tty == NULL)
  30377. +        return;
  30378. +
  30379. +    if (mkiss == NULL)
  30380. +        return;
  30381. +}
  30382. +
  30383. +static void mkiss_dummy2(struct tty_struct *tty, unsigned char ch)
  30384. +{
  30385. +    struct mkiss_channel *mkiss = tty->driver_data;
  30386. +
  30387. +    if (tty == NULL)
  30388. +        return;
  30389. +
  30390. +    if (mkiss == NULL)
  30391. +        return;
  30392. +}
  30393. +
  30394. +
  30395. +static int mkiss_write_room(struct tty_struct * tty)
  30396. +{
  30397. +    struct mkiss_channel *mkiss = tty->driver_data;
  30398. +
  30399. +    if (tty == NULL)
  30400. +        return 0;
  30401. +
  30402. +    if (mkiss == NULL)
  30403. +        return 0;
  30404. +
  30405. +    return 65536;  /* We can handle an infinite amount of data. :-) */
  30406. +}
  30407. +
  30408. +
  30409. +static int mkiss_chars_in_buffer(struct tty_struct *tty)
  30410. +{
  30411. +    struct mkiss_channel *mkiss = tty->driver_data;
  30412. +
  30413. +    if (tty == NULL)
  30414. +        return 0;
  30415. +
  30416. +    if (mkiss == NULL)
  30417. +        return 0;
  30418. +
  30419. +    return 0;
  30420. +}
  30421. +
  30422. +
  30423. +static void mkiss_set_termios(struct tty_struct *tty, struct termios *old_termios)
  30424. +{
  30425. +    /* we don't do termios */
  30426. +}
  30427. +
  30428. +/* ******************************************************************** */
  30429. +/* *             Init MKISS driver                   * */
  30430. +/* ******************************************************************** */
  30431. +
  30432. +static int mkiss_init(void)
  30433. +{
  30434. +    memset(&mkiss_driver, 0, sizeof(struct tty_driver));
  30435. +
  30436. +    mkiss_driver.magic       = MKISS_DRIVER_MAGIC;
  30437. +    mkiss_driver.name        = "mkiss";
  30438. +    mkiss_driver.major       = MKISS_MAJOR;
  30439. +    mkiss_driver.minor_start = 0;
  30440. +    mkiss_driver.num         = NR_MKISS;
  30441. +    mkiss_driver.type        = TTY_DRIVER_TYPE_SERIAL;
  30442. +    mkiss_driver.subtype     = MKISS_SERIAL_TYPE_NORMAL;    /* not needed */
  30443. +
  30444. +    mkiss_driver.init_termios         = tty_std_termios;
  30445. +    mkiss_driver.init_termios.c_iflag = IGNBRK | IGNPAR;
  30446. +    mkiss_driver.init_termios.c_cflag = B9600 | CS8 | CLOCAL;
  30447. +
  30448. +    mkiss_driver.flags           = TTY_DRIVER_REAL_RAW;
  30449. +    mkiss_driver.refcount        = &mkiss_refcount;
  30450. +    mkiss_driver.table           = mkiss_table;
  30451. +    mkiss_driver.termios         = (struct termios **)mkiss_termios;
  30452. +    mkiss_driver.termios_locked  = (struct termios **)mkiss_termios_locked;
  30453. +
  30454. +    mkiss_driver.ioctl           = mkiss_ioctl;
  30455. +    mkiss_driver.open            = mkiss_open;
  30456. +    mkiss_driver.close           = mkiss_close;
  30457. +    mkiss_driver.write           = mkiss_write;
  30458. +    mkiss_driver.write_room      = mkiss_write_room;
  30459. +    mkiss_driver.chars_in_buffer = mkiss_chars_in_buffer;
  30460. +    mkiss_driver.set_termios     = mkiss_set_termios;
  30461. +
  30462. +    /* some unused functions */
  30463. +    mkiss_driver.flush_buffer = mkiss_dummy;
  30464. +    mkiss_driver.throttle     = mkiss_dummy;
  30465. +    mkiss_driver.unthrottle   = mkiss_dummy;
  30466. +    mkiss_driver.stop         = mkiss_dummy;
  30467. +    mkiss_driver.start        = mkiss_dummy;
  30468. +    mkiss_driver.hangup       = mkiss_dummy;
  30469. +    mkiss_driver.flush_chars  = mkiss_dummy;
  30470. +    mkiss_driver.put_char     = mkiss_dummy2;
  30471. +
  30472. +    if (tty_register_driver(&mkiss_driver)) {
  30473. +        printk(KERN_ERR "Couldn't register Mkiss device\n");
  30474. +        return -EIO;
  30475. +    }
  30476. +
  30477. +    printk(KERN_INFO "AX.25 Multikiss device enabled\n");
  30478. +
  30479. +    return 0;
  30480. +}
  30481. +
  30482. +#ifdef MODULE
  30483. +
  30484. +int init_module(void)
  30485. +{
  30486. +    register_symtab(NULL);
  30487. +
  30488. +    return mkiss_init_ctrl_dev();
  30489. +}
  30490. +
  30491. +void cleanup_module(void)
  30492. +{
  30493. +    int i;
  30494. +
  30495. +    if (ax25_ctrls != NULL) {
  30496. +        for (i = 0; i < ax25_maxdev; i++) {
  30497. +            if (ax25_ctrls[i]) {
  30498. +                /*
  30499. +                 * VSV = if dev->start==0, then device
  30500. +                 * unregistred while close proc.
  30501. +                 */
  30502. +                if (ax25_ctrls[i]->dev.start)
  30503. +                    unregister_netdev(&(ax25_ctrls[i]->dev));
  30504. +
  30505. +                kfree(ax25_ctrls[i]);
  30506. +                ax25_ctrls[i] = NULL;
  30507. +            }
  30508. +        }
  30509. +
  30510. +        kfree(ax25_ctrls);
  30511. +        ax25_ctrls = NULL;
  30512. +    }
  30513. +
  30514. +    if ((i = tty_register_ldisc(N_AX25, NULL)))
  30515. +        printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i);
  30516. +
  30517. +    if (tty_unregister_driver(&mkiss_driver))    /* remove devive */
  30518. +        printk(KERN_ERR "mkiss: can't unregister MKISS device\n");
  30519. +}
  30520. +
  30521. +#endif /* MODULE */
  30522. diff -u --recursive --new-file v2.0.34/linux/drivers/net/mkiss.h linux/drivers/net/mkiss.h
  30523. --- v2.0.34/linux/drivers/net/mkiss.h    Wed Dec 31 16:00:00 1969
  30524. +++ linux/drivers/net/mkiss.h    Mon Jul 13 13:47:31 1998
  30525. @@ -0,0 +1,56 @@
  30526. +/****************************************************************************
  30527. + *    Defines for the Multi-KISS driver.
  30528. + ****************************************************************************/
  30529. +
  30530. +#define AX25_MAXDEV    16        /* MAX number of AX25 channels;
  30531. +                       This can be overridden with
  30532. +                       insmod -oax25_maxdev=nnn    */
  30533. +#define AX_MTU        236    
  30534. +
  30535. +/* SLIP/KISS protocol characters. */
  30536. +#define END             0300        /* indicates end of frame    */
  30537. +#define ESC             0333        /* indicates byte stuffing    */
  30538. +#define ESC_END         0334        /* ESC ESC_END means END 'data'    */
  30539. +#define ESC_ESC         0335        /* ESC ESC_ESC means ESC 'data'    */
  30540. +
  30541. +struct ax_disp {
  30542. +    int                magic;
  30543. +
  30544. +    /* Various fields. */
  30545. +    struct tty_struct  *tty;        /* ptr to TTY structure        */
  30546. +    struct device      *dev;        /* easy for intr handling    */
  30547. +    struct ax_disp     *mkiss;        /* mkiss txport if mkiss channel*/
  30548. +
  30549. +    /* These are pointers to the malloc()ed frame buffers. */
  30550. +    unsigned char      *rbuff;        /* receiver buffer        */
  30551. +    int                rcount;        /* received chars counter       */
  30552. +    unsigned char      *xbuff;        /* transmitter buffer        */
  30553. +    unsigned char      *xhead;        /* pointer to next byte to XMIT */
  30554. +    int                xleft;        /* bytes left in XMIT queue     */
  30555. +
  30556. +    /* SLIP interface statistics. */
  30557. +    unsigned long      rx_packets;        /* inbound frames counter    */
  30558. +    unsigned long      tx_packets;        /* outbound frames counter      */
  30559. +    unsigned long      rx_errors;        /* Parity, etc. errors          */
  30560. +    unsigned long      tx_errors;        /* Planned stuff                */
  30561. +    unsigned long      rx_dropped;        /* No memory for skb            */
  30562. +    unsigned long      tx_dropped;        /* When MTU change              */
  30563. +    unsigned long      rx_over_errors;    /* Frame bigger then SLIP buf.  */
  30564. +
  30565. +    /* Detailed SLIP statistics. */
  30566. +    int                 mtu;        /* Our mtu (to spot changes!)   */
  30567. +    int                 buffsize;        /* Max buffers sizes            */
  30568. +
  30569. +
  30570. +    unsigned char       flags;        /* Flag values/ mode etc    */
  30571. +#define AXF_INUSE    0        /* Channel in use               */
  30572. +#define AXF_ESCAPE    1               /* ESC received                 */
  30573. +#define AXF_ERROR    2               /* Parity, etc. error           */
  30574. +#define AXF_KEEPTEST    3        /* Keepalive test flag        */
  30575. +#define AXF_OUTWAIT    4        /* is outpacket was flag    */
  30576. +
  30577. +    int                 mode;
  30578. +};
  30579. +
  30580. +#define AX25_MAGIC        0x5316
  30581. +#define MKISS_DRIVER_MAGIC    1215
  30582. diff -u --recursive --new-file v2.0.34/linux/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c
  30583. --- v2.0.34/linux/drivers/net/ne2k-pci.c    Mon Jul 13 13:46:29 1998
  30584. +++ linux/drivers/net/ne2k-pci.c    Mon Jul 13 13:47:31 1998
  30585. @@ -45,7 +45,7 @@
  30586.  #include "8390.h"
  30587.  
  30588.  /* Set statically or when loading the driver module. */
  30589. -static debug = 1;
  30590. +static int debug = 1;
  30591.  
  30592.  /* Some defines that people can play with if so inclined. */
  30593.  
  30594. @@ -189,14 +189,6 @@
  30595.      if ( ! pcibios_present())
  30596.          return -ENODEV;
  30597.  
  30598. -#ifndef MODULE
  30599. -    {
  30600. -        static unsigned version_printed = 0;
  30601. -        if (version_printed++ == 0)
  30602. -            printk(KERN_INFO "%s", version);
  30603. -    }
  30604. -#endif
  30605. -
  30606.      for (;pci_index < 0xff; pci_index++) {
  30607.          unsigned char pci_bus, pci_device_fn;
  30608.          u8 pci_irq_line;
  30609. @@ -219,6 +211,14 @@
  30610.                  break;
  30611.          if (pci_clone_list[i].vendor == 0)
  30612.              continue;
  30613. +
  30614. +#ifndef MODULE
  30615. +        {
  30616. +            static unsigned version_printed = 0;
  30617. +            if (version_printed++ == 0)
  30618. +                printk(KERN_INFO "%s", version);
  30619. +        }
  30620. +#endif
  30621.  
  30622.          pcibios_read_config_dword(pci_bus, pci_device_fn,
  30623.                                    PCI_BASE_ADDRESS_0, &pci_ioaddr);
  30624. diff -u --recursive --new-file v2.0.34/linux/drivers/net/net_init.c linux/drivers/net/net_init.c
  30625. --- v2.0.34/linux/drivers/net/net_init.c    Wed Nov  6 04:39:42 1996
  30626. +++ linux/drivers/net/net_init.c    Mon Jul 13 13:47:31 1998
  30627. @@ -318,7 +318,7 @@
  30628.              for (i = 0; i < MAX_ETH_CARDS; ++i)
  30629.                  if (ethdev_index[i] == NULL) {
  30630.                      sprintf(dev->name, "eth%d", i);
  30631. -                    printk("loading device '%s'...\n", dev->name);
  30632. +/*                    printk("loading device '%s'...\n", dev->name);*/
  30633.                      ethdev_index[i] = dev;
  30634.                      break;
  30635.                  }
  30636. diff -u --recursive --new-file v2.0.34/linux/drivers/net/ni52.c linux/drivers/net/ni52.c
  30637. --- v2.0.34/linux/drivers/net/ni52.c    Tue Apr  8 08:47:46 1997
  30638. +++ linux/drivers/net/ni52.c    Mon Jul 13 13:47:31 1998
  30639. @@ -984,7 +984,7 @@
  30640.    }
  30641.  #endif
  30642.  
  30643. -#ifdef 0
  30644. +#if 0
  30645.    if(!at_least_one)
  30646.    { 
  30647.      int i;
  30648. diff -u --recursive --new-file v2.0.34/linux/drivers/net/pi2.c linux/drivers/net/pi2.c
  30649. --- v2.0.34/linux/drivers/net/pi2.c    Thu Feb 29 21:50:45 1996
  30650. +++ linux/drivers/net/pi2.c    Mon Jul 13 13:47:31 1998
  30651. @@ -53,6 +53,7 @@
  30652.     Oct  29, 1995 (ac)  A couple of minor fixes before this, and this release changes
  30653.                    to the proper set_mac_address semantics which will break 
  30654.                    a few programs I suspect.
  30655. +   Aug  18, 1996 (jsn) Converted to be used as a module.
  30656.  */
  30657.  
  30658.  /* The following #define invokes a hack that will improve performance (baud)
  30659. @@ -81,19 +82,12 @@
  30660.  #define DEF_B_SQUELDELAY 3    /* 30 mS */
  30661.  #define DEF_B_CLOCKMODE 0    /* Normal clock mode */
  30662.  
  30663. -static const char *version =
  30664. -"PI: V0.8 ALPHA April 23 1995 David Perry (dp@hydra.carleton.ca)\n";
  30665. -
  30666.  /* The following #define is only really required for the PI card, not
  30667.     the PI2 - but it's safer to leave it in. */
  30668.  #define REALLY_SLOW_IO 1
  30669.  
  30670. -#define PI2_MODULE 0
  30671. -
  30672. -#if PI2_MODULE > 0
  30673. +#include <linux/config.h>
  30674.  #include <linux/module.h>
  30675. -#endif
  30676. -
  30677.  #include <linux/kernel.h>
  30678.  #include <linux/sched.h>
  30679.  #include <linux/types.h>
  30680. @@ -116,11 +110,10 @@
  30681.  #include <linux/skbuff.h>
  30682.  #include <linux/timer.h>
  30683.  #include <linux/if_arp.h>
  30684. -#include "pi2.h"
  30685. +#include <linux/pi2.h>
  30686.  #include "z8530.h"
  30687.  #include <net/ax25.h>
  30688.  
  30689. -
  30690.  struct mbuf {
  30691.      struct mbuf *next;
  30692.      int cnt;
  30693. @@ -553,7 +546,7 @@
  30694.  
  30695.          skb = dev_alloc_skb(sksize);
  30696.          if (skb == NULL) {
  30697. -        printk("PI: %s: Memory squeeze, dropping packet.\n", dev->name);
  30698. +        printk(KERN_ERR "PI: %s: Memory squeeze, dropping packet.\n", dev->name);
  30699.          lp->stats.rx_dropped++;
  30700.          restore_flags(flags);
  30701.          return;
  30702. @@ -642,7 +635,7 @@
  30703.          sksize = pkt_len;
  30704.          skb = dev_alloc_skb(sksize);
  30705.          if (skb == NULL) {
  30706. -            printk("PI: %s: Memory squeeze, dropping packet.\n", dev->name);
  30707. +            printk(KERN_ERR "PI: %s: Memory squeeze, dropping packet.\n", dev->name);
  30708.              lp->stats.rx_dropped++;
  30709.              restore_flags(flags);
  30710.              return;
  30711. @@ -1214,27 +1207,27 @@
  30712.      int ports[] =
  30713.      {0x380, 0x300, 0x320, 0x340, 0x360, 0x3a0, 0};
  30714.  
  30715. -    printk(version);
  30716. +    printk(KERN_INFO "PI: V0.8 ALPHA April 23 1995 David Perry (dp@hydra.carleton.ca)\n");
  30717.  
  30718.      /* Only one card supported for now */
  30719.      for (port = &ports[0]; *port && !card_type; port++) {
  30720.      ioaddr = *port;
  30721.  
  30722.      if (check_region(ioaddr, PI_TOTAL_SIZE) == 0) {
  30723. -        printk("PI: Probing for card at address %#3x\n",ioaddr);
  30724. +        printk(KERN_INFO "PI: Probing for card at address %#3x\n",ioaddr);
  30725.          card_type = hw_probe(ioaddr);
  30726.      }
  30727.      }
  30728.  
  30729.      switch (card_type) {
  30730.      case 1:
  30731. -    printk("PI: Found a PI card at address %#3x\n", ioaddr);
  30732. +    printk(KERN_INFO "PI: Found a PI card at address %#3x\n", ioaddr);
  30733.      break;
  30734.      case 2:
  30735. -    printk("PI: Found a PI2 card at address %#3x\n", ioaddr);
  30736. +    printk(KERN_INFO "PI: Found a PI2 card at address %#3x\n", ioaddr);
  30737.      break;
  30738.      default:
  30739. -    printk("PI: ERROR: No card found\n");
  30740. +    printk(KERN_ERR "PI: ERROR: No card found\n");
  30741.      return -EIO;
  30742.      }
  30743.  
  30744. @@ -1256,6 +1249,7 @@
  30745.      register_netdev(&pi0b);
  30746.      pi0b.base_addr = ioaddr;
  30747.      pi0b.irq = 0;
  30748. +
  30749.      pi0b.priv = kmalloc(sizeof(struct pi_local) + (DMA_BUFF_SIZE + sizeof(struct mbuf)) * 4, GFP_KERNEL | GFP_DMA);
  30750.  
  30751.      /* Now initialize them */
  30752. @@ -1275,8 +1269,9 @@
  30753.      return 0;
  30754.  }
  30755.  
  30756. -static int pi_set_mac_address(struct device *dev, struct sockaddr *sa)
  30757. +static int pi_set_mac_address(struct device *dev, void *addr)
  30758.  {
  30759. +    struct sockaddr *sa = (struct sockaddr *)addr;
  30760.      memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);    /* addr is an AX.25 shifted ASCII */
  30761.      return 0;                        /* mac address */
  30762.  }
  30763. @@ -1364,7 +1359,7 @@
  30764.  
  30765.      lp->dmachan = dev->dma;
  30766.      if (lp->dmachan < 1 || lp->dmachan > 3)
  30767. -        printk("PI: DMA channel %d out of range\n", lp->dmachan);
  30768. +        printk(KERN_ERR "PI: DMA channel %d out of range\n", lp->dmachan);
  30769.  
  30770.      /* chipset_init() was already called */
  30771.  
  30772. @@ -1381,7 +1376,7 @@
  30773.          /* 20 "jiffies" should be plenty of time... */
  30774.          dev->irq = autoirq_report(20);
  30775.          if (!dev->irq) {
  30776. -        printk(". Failed to detect IRQ line.\n");
  30777. +        printk(KERN_ERR "PI: Failed to detect IRQ line.\n");
  30778.          }
  30779.          save_flags(flags);
  30780.          cli();
  30781. @@ -1391,7 +1386,7 @@
  30782.          restore_flags(flags);
  30783.      }
  30784.  
  30785. -    printk("PI: Autodetected IRQ %d, assuming DMA %d.\n",
  30786. +    printk(KERN_INFO "PI: Autodetected IRQ %d, assuming DMA %d.\n",
  30787.             dev->irq, dev->dma);
  30788.  
  30789.      /* This board has jumpered interrupts. Snarf the interrupt vector
  30790. @@ -1400,7 +1395,7 @@
  30791.      {
  30792.          int irqval = request_irq(dev->irq, &pi_interrupt,0, "pi2", NULL);
  30793.          if (irqval) {
  30794. -        printk("PI: unable to get IRQ %d (irqval=%d).\n",
  30795. +        printk(KERN_ERR "PI: unable to get IRQ %d (irqval=%d).\n",
  30796.                 dev->irq, irqval);
  30797.          return EAGAIN;
  30798.          }
  30799. @@ -1436,10 +1431,13 @@
  30800.      /* New-style flags. */
  30801.      dev->flags = 0;
  30802.      dev->family = AF_INET;
  30803. -    dev->pa_addr = 0;
  30804. -    dev->pa_brdaddr = 0;
  30805. -    dev->pa_mask = 0;
  30806. -    dev->pa_alen = 4;
  30807. +
  30808. +#ifdef CONFIG_INET
  30809. +    dev->pa_addr    = in_aton("192.168.0.1");
  30810. +    dev->pa_brdaddr = in_aton("192.168.0.255");
  30811. +    dev->pa_mask    = in_aton("255.255.255.0");
  30812. +    dev->pa_alen    = 4;
  30813. +#endif
  30814.  
  30815.      return 0;
  30816.  }
  30817. @@ -1487,6 +1485,9 @@
  30818.      dev->interrupt = 0;
  30819.      dev->start = 1;
  30820.      first_time = 0;
  30821. +
  30822. +    MOD_INC_USE_COUNT;
  30823. +
  30824.      return 0;
  30825.  }
  30826.  
  30827. @@ -1520,7 +1521,7 @@
  30828.  
  30829.  #if 0
  30830.      if (dev_a == NULL) {
  30831. -    printk("PI: pi_interrupt(): irq %d for unknown device.\n", irq);
  30832. +    printk(KERN_ERR "PI: pi_interrupt(): irq %d for unknown device.\n", irq);
  30833.      return;
  30834.      }
  30835.  #endif    
  30836. @@ -1589,6 +1590,9 @@
  30837.      free_p(ptr);
  30838.  
  30839.      restore_flags(flags);
  30840. +
  30841. +    MOD_DEC_USE_COUNT;
  30842. +
  30843.      return 0;
  30844.  }
  30845.  
  30846. @@ -1681,6 +1685,28 @@
  30847.      return &lp->stats;
  30848.  }
  30849.  
  30850. +#ifdef MODULE
  30851. +int init_module(void)
  30852. +{
  30853. +    register_symtab(NULL);
  30854. +    return pi_init();
  30855. +}
  30856. +
  30857. +void cleanup_module(void)
  30858. +{
  30859. +    free_irq(pi0a.irq, NULL);    /* IRQs and IO Ports are shared */
  30860. +    release_region(pi0a.base_addr & 0x3f0, PI_TOTAL_SIZE);
  30861. +    irq2dev_map[pi0a.irq] = NULL;
  30862. +
  30863. +    kfree(pi0a.priv);
  30864. +    pi0a.priv = NULL;
  30865. +    unregister_netdev(&pi0a);
  30866. +
  30867. +    kfree(pi0b.priv);
  30868. +    pi0b.priv = NULL;
  30869. +    unregister_netdev(&pi0b);
  30870. +}
  30871. +#endif
  30872.  
  30873.  /*
  30874.   * Local variables:
  30875. diff -u --recursive --new-file v2.0.34/linux/drivers/net/pi2.h linux/drivers/net/pi2.h
  30876. --- v2.0.34/linux/drivers/net/pi2.h    Tue Jun  6 01:22:10 1995
  30877. +++ linux/drivers/net/pi2.h    Mon Jul 13 13:47:31 1998
  30878. @@ -1,133 +0,0 @@
  30879. -
  30880. -#define DMA_BUFF_SIZE 2200
  30881. -
  30882. -/* Network statistics, with the same names as 'struct enet_statistics'. */
  30883. -#define netstats enet_statistics
  30884. -
  30885. -#define ON 1
  30886. -#define OFF 0
  30887. -
  30888. -
  30889. -/* Register offset info, specific to the PI
  30890. - * E.g., to read the data port on channel A, use
  30891. - *  inportb(pichan[dev].base + CHANA + DATA)
  30892. - */
  30893. -#define CHANB   0   /* Base of channel B regs */
  30894. -#define CHANA   2   /* Base of channel A regs */
  30895. -
  30896. -/* 8530 ports on each channel */
  30897. -#define CTL 0
  30898. -#define DATA    1
  30899. -
  30900. -#define DMAEN   0x4 /* Offset off DMA Enable register */
  30901. -
  30902. -/* Timer chip offsets */
  30903. -#define TMR0    0x8 /* Offset of timer 0 register */
  30904. -#define TMR1    0x9 /* Offset of timer 1 register */
  30905. -#define TMR2    0xA /* Offset of timer 2 register */
  30906. -#define TMRCMD  0xB /* Offset of timer command register */
  30907. -
  30908. -/* Timer chip equates */
  30909. -#define SC0 0x00 /* Select counter 0 */
  30910. -#define SC1 0x40 /* Select counter 1 */
  30911. -#define SC2 0x80 /* Select counter 2 */
  30912. -#define CLATCH  0x00 /* Counter latching operation */
  30913. -#define MSB 0x20 /* Read/load MSB only */
  30914. -#define LSB 0x10 /* Read/load LSB only */
  30915. -#define LSB_MSB 0x30 /* Read/load LSB, then MSB */
  30916. -#define MODE0   0x00 /* Interrupt on terminal count */
  30917. -#define MODE1   0x02 /* Programmable one shot */
  30918. -#define MODE2   0x04 /* Rate generator */
  30919. -#define MODE3   0x06 /* Square wave rate generator */
  30920. -#define MODE4   0x08 /* Software triggered strobe */
  30921. -#define MODE5   0x0a /* Hardware triggered strobe */
  30922. -#define BCD 0x01 /* BCD counter */
  30923. -
  30924. -/* DMA controller registers */
  30925. -#define DMA_STAT    8   /* DMA controller status register */
  30926. -#define DMA_CMD     8   /* DMA controller command register */
  30927. -#define DMA_MASK        10  /* DMA controller mask register */
  30928. -#define DMA_MODE        11  /* DMA controller mode register */
  30929. -#define DMA_RESETFF 12  /* DMA controller first/last flip flop  */
  30930. -/* DMA data */
  30931. -#define DMA_DISABLE (0x04)  /* Disable channel n */
  30932. -#define DMA_ENABLE  (0x00)  /* Enable channel n */
  30933. -/* Single transfers, incr. address, auto init, writes, ch. n */
  30934. -#define DMA_RX_MODE (0x54)
  30935. -/* Single transfers, incr. address, no auto init, reads, ch. n */
  30936. -#define DMA_TX_MODE (0x48)
  30937. -
  30938. -#define SINGLE 3686400
  30939. -#define DOUBLE 7372800
  30940. -
  30941. -#define SIOCGPIPARAM        0x5000    /* get PI parameters */
  30942. -#define SIOCSPIPARAM        0x5001    /* set */
  30943. -#define SIOCGPIBAUD        0x5002    /* get only baud rate */
  30944. -#define SIOCSPIBAUD        0x5003    
  30945. -#define SIOCGPIDMA        0x5004    /* get only DMA */
  30946. -#define SIOCSPIDMA        0x5005    
  30947. -#define SIOCGPIIRQ        0x5006    /* get only IRQ */
  30948. -#define SIOCSPIIRQ        0x5007    
  30949. -
  30950. -struct pi_req  {
  30951. -    int cmd;
  30952. -    int speed;
  30953. -    int clockmode;
  30954. -    int txdelay;
  30955. -    unsigned char persist;
  30956. -    int slotime; 
  30957. -    int squeldelay;
  30958. -    int dmachan;    
  30959. -    int irq;    
  30960. -};
  30961. -
  30962. -#ifdef __KERNEL__
  30963. -
  30964. -/* Information that needs to be kept for each channel. */
  30965. -struct pi_local {
  30966. -    struct netstats stats; /* %%%dp*/
  30967. -    long open_time;             /* Useless example local info. */
  30968. -    unsigned long xtal; 
  30969. -
  30970. -    struct mbuf *rcvbuf;/* Buffer for current rx packet */
  30971. -    struct mbuf *rxdmabuf1; /* DMA rx buffer */
  30972. -    struct mbuf *rxdmabuf2; /* DMA rx buffer */
  30973. -
  30974. -    int bufsiz;         /* Size of rcvbuf */
  30975. -    char *rcp;          /* Pointer into rcvbuf */
  30976. -
  30977. -    struct sk_buff_head sndq;  /* Packets awaiting transmission */
  30978. -    int sndcnt;         /* Number of packets on sndq */
  30979. -    struct sk_buff *sndbuf;    /* Current buffer being transmitted */
  30980. -    char *txdmabuf;     /* Transmit DMA buffer */
  30981. -    char *txptr;        /* Used by B port tx */
  30982. -    int txcnt;            
  30983. -    char tstate;        /* Transmitter state */
  30984. -#define IDLE    0       /* Transmitter off, no data pending */
  30985. -#define ACTIVE  1       /* Transmitter on, sending data */
  30986. -#define UNDERRUN 2      /* Transmitter on, flushing CRC */
  30987. -#define FLAGOUT 3       /* CRC sent - attempt to start next frame */
  30988. -#define DEFER 4         /* Receive Active - DEFER Transmit */
  30989. -#define ST_TXDELAY 5    /* Sending leading flags */
  30990. -#define CRCOUT 6
  30991. -    char rstate;        /* Set when !DCD goes to 0 (TRUE) */
  30992. -/* Normal state is ACTIVE if Receive enabled */
  30993. -#define RXERROR 2       /* Error -- Aborting current Frame */
  30994. -#define RXABORT 3       /* ABORT sequence detected */
  30995. -#define TOOBIG 4        /* too large a frame to store */
  30996. -    int dev;            /* Device number */
  30997. -    int base;       /* Base of I/O registers */
  30998. -    int cardbase;     /* Base address of card */
  30999. -    int stata;        /* address of Channel A status regs */
  31000. -    int statb;        /* address of Channel B status regs */
  31001. -    int speed;        /* Line speed, bps */
  31002. -    int clockmode;    /* tapr 9600 modem clocking option */
  31003. -    int txdelay;      /* Transmit Delay 10 ms/cnt */
  31004. -    unsigned char persist;       /* Persistence (0-255) as a % */
  31005. -    int slotime;      /* Delay to wait on persistence hit */
  31006. -    int squeldelay;   /* Delay after XMTR OFF for squelch tail */
  31007. -    struct iface *iface;    /* Associated interface */
  31008. -    int dmachan;           /* DMA channel for this port */
  31009. -};
  31010. -
  31011. -#endif
  31012. diff -u --recursive --new-file v2.0.34/linux/drivers/net/pt.c linux/drivers/net/pt.c
  31013. --- v2.0.34/linux/drivers/net/pt.c    Thu Apr 11 23:49:38 1996
  31014. +++ linux/drivers/net/pt.c    Mon Jul 13 13:47:31 1998
  31015. @@ -32,6 +32,8 @@
  31016.   * 07/10/95 cs  Fixed for 1.3.30 (hopefully)
  31017.   * 26/11/95 cs  Fixed for 1.3.43, ala 29/10 for pi2.c by ac
  31018.   * 21/12/95 cs  Got rid of those nasty warnings when compiling, for 1.3.48
  31019. + * 08/08/96 jsn Convert to use as a module. Removed send_kiss, empty_scc and
  31020. + *        pt_loopback functions - they were unused.
  31021.   */
  31022.   
  31023.  /* 
  31024. @@ -64,7 +66,9 @@
  31025.  #define    PARAM_HARDWARE    6
  31026.  #define    PARAM_RETURN    255
  31027.  
  31028. +#include <linux/config.h>
  31029.  #include <linux/kernel.h>
  31030. +#include <linux/module.h>
  31031.  #include <linux/sched.h>
  31032.  #include <linux/types.h>
  31033.  #include <linux/fcntl.h>
  31034. @@ -86,14 +90,10 @@
  31035.  #include <linux/skbuff.h>
  31036.  #include <linux/timer.h>
  31037.  #include <linux/if_arp.h>
  31038. -#include "pt.h"
  31039. +#include <linux/pt.h>
  31040.  #include "z8530.h"
  31041.  #include <net/ax25.h>
  31042.  
  31043. -static char *version =
  31044. -"PT: 0.41 ALPHA 07 October 1995 Craig Small (vk2xlz@vk2xlz.ampr.org)\n";
  31045. -
  31046. -
  31047.  struct mbuf {
  31048.      struct mbuf *next;
  31049.      int cnt;
  31050. @@ -133,9 +133,7 @@
  31051.  static int valid_dma_page(unsigned long addr, unsigned long dev_buffsize);
  31052.  static int hw_probe(int ioaddr);
  31053.  static void tdelay(struct pt_local *lp, int time);
  31054. -static void empty_scc(struct pt_local *lp);
  31055.  static void chipset_init(struct device *dev);
  31056. -static void send_kiss(struct device *dev, unsigned char arg, unsigned char val);
  31057.  
  31058.  static char ax25_bcast[7] =
  31059.  {'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
  31060. @@ -185,7 +183,9 @@
  31061.      ptr = skb->data;
  31062.      if (ptr[0] != 0 && skb->len >= 2)
  31063.      {
  31064. -        printk("Rx KISS... Control = %d, value = %d.\n", ptr[0], (skb->len > 1? ptr[1] : -1));
  31065. +#ifdef PT_DEBUG
  31066. +        printk(KERN_DEBUG "PT: Rx KISS... Control = %d, value = %d.\n", ptr[0], (skb->len > 1? ptr[1] : -1));
  31067. +#endif
  31068.          /* Kludge to get device */
  31069.          if ((struct pt_local*)(&pt0b.priv) == lp)
  31070.              dev = &pt0b;
  31071. @@ -197,21 +197,17 @@
  31072.              case PARAM_TXDELAY:
  31073.                  /*TxDelay is in 10mS increments */
  31074.                  lp->txdelay = ptr[1] * 10;
  31075. -                send_kiss(dev, PARAM_TXDELAY, (u_char)(lp->txdelay/10));
  31076.                  break;
  31077.              case PARAM_PERSIST:
  31078.                  lp->persist = ptr[1];
  31079. -                send_kiss(dev, PARAM_PERSIST, (u_char)(lp->persist));
  31080.                  break;
  31081.              case PARAM_SLOTTIME:
  31082.                  lp->slotime = ptr[1];
  31083. -                send_kiss(dev, PARAM_SLOTTIME, (u_char)(lp->slotime/10));
  31084.                  break;
  31085.              case PARAM_FULLDUP:
  31086.                  /* Yeah right, you wish!  Fullduplex is a little while to
  31087.                   * go folks, but this is how you fire it up
  31088.                   */
  31089. -                send_kiss(dev, PARAM_FULLDUP, 0);
  31090.                  break;
  31091.              /* Perhaps we should have txtail here?? */
  31092.          } /*switch */
  31093. @@ -226,7 +222,7 @@
  31094.      restore_flags(flags);
  31095.  
  31096.  #ifdef PT_DEBUG
  31097. -    printk("PTd hardware_send_packet(): kickflag = %d (%d).\n", kickflag, lp->base & CHANA);
  31098. +    printk(KERN_DEBUG "PT: hardware_send_packet(): kickflag = %d (%d).\n", kickflag, lp->base & CHANA);
  31099.  #endif    
  31100.      skb_queue_tail(&lp->sndq, skb);
  31101.      if (kickflag) {
  31102. @@ -320,21 +316,6 @@
  31103.      dev_kfree_skb(skb, FREE_WRITE);
  31104.  }
  31105.  
  31106. -static void pt_loopback(struct pt_local *lp, int onoff)
  31107. -{
  31108. -    if (lp->base & CHANA) {
  31109. -        if (onoff == ON)
  31110. -            outb_p(pt_sercfg |= PT_LOOPA_ON, lp->cardbase + SERIAL_CFG);
  31111. -        else
  31112. -            outb_p(pt_sercfg &= ~PT_LOOPA_ON, lp->cardbase + SERIAL_CFG);
  31113. -    } else {    /* it's channel B */
  31114. -        if (onoff == ON)
  31115. -            outb_p(pt_sercfg |= PT_LOOPB_ON, lp->cardbase + SERIAL_CFG);
  31116. -        else
  31117. -            outb_p(pt_sercfg &= ~PT_LOOPB_ON, lp->cardbase + SERIAL_CFG);
  31118. -    }
  31119. -} /*pt_loopback */
  31120. -
  31121.  /* Fill in the MAC-level header */
  31122.  static int pt_header (struct sk_buff *skb, struct device *dev, unsigned short type,
  31123.          void *daddr, void *saddr, unsigned len)
  31124. @@ -366,7 +347,7 @@
  31125.      int tc, br;
  31126.  
  31127.  #ifdef PT_DEBUG
  31128. -    printk("PTd scc_init(): (%d).\n", lp->base & CHANA);
  31129. +    printk(KERN_DEBUG "PT: scc_init(): (%d).\n", lp->base & CHANA);
  31130.  #endif    
  31131.      save_flags(flags);
  31132.      cli();
  31133. @@ -486,8 +467,8 @@
  31134.  
  31135.      struct pt_local *lp = (struct pt_local*) dev->priv;
  31136.  #ifdef PT_DEBUG
  31137. -    printk("PTd chipset_init(): pt0a tstate = %d.\n", ((struct pt_local*)pt0a.priv)->tstate);
  31138. -    printk("PTd chipset_init(): pt0b tstate = %d.\n", ((struct pt_local*)pt0b.priv)->tstate);    
  31139. +    printk(KERN_DEBUG "PT: chipset_init(): pt0a tstate = %d.\n", ((struct pt_local*)pt0a.priv)->tstate);
  31140. +    printk(KERN_DEBUG "PT: chipset_init(): pt0b tstate = %d.\n", ((struct pt_local*)pt0b.priv)->tstate);    
  31141.  #endif
  31142.      /* Reset SCC if both channels are to be canned */
  31143.      if ( ((lp->base & CHANA) && !(pt_sercfg & PT_DTRB_ON)) ||
  31144. @@ -498,7 +479,7 @@
  31145.              outb_p((pt_sercfg = 0), lp->cardbase + SERIAL_CFG);
  31146.              outb_p((pt_dmacfg = 0), lp->cardbase + DMA_CFG);
  31147.  #ifdef PT_DEBUG
  31148. -        printk("PTd chipset_init() Resetting SCC, called by ch (%d).\n", lp->base & CHANA);
  31149. +        printk(KERN_DEBUG "PT: chipset_init() Resetting SCC, called by ch (%d).\n", lp->base & CHANA);
  31150.  #endif                    
  31151.      }
  31152.      /* Reset individual channel */
  31153. @@ -522,20 +503,20 @@
  31154.      { 0x230, 0x240, 0x250, 0x260, 0x270, 0x280, 0x290, 0x2a0,
  31155.        0x2b0, 0x300, 0x330, 0x3f0,  0};
  31156.  
  31157. -    printk(version);
  31158. +    printk(KERN_INFO "PT: 0.41 ALPHA 07 October 1995 Craig Small (vk2xlz@vk2xlz.ampr.org)\n");
  31159.  
  31160.      for (port = &ports[0]; *port && !card_type; port++) {
  31161.          ioaddr = *port;
  31162.  
  31163.          if (check_region(ioaddr, PT_TOTAL_SIZE) == 0) {
  31164. -            printk("PT: Probing for card at address %#3x\n", ioaddr);
  31165. +            printk(KERN_INFO "PT: Probing for card at address %#3x\n", ioaddr);
  31166.              card_type = hw_probe(ioaddr);
  31167.          }
  31168.      }
  31169.      if (card_type) {
  31170. -        printk("PT: Found a PT at address %#3x\n",ioaddr);
  31171. +        printk(KERN_INFO "PT: Found a PT at address %#3x\n",ioaddr);
  31172.      } else {
  31173. -        printk("PT: ERROR: No card found.\n");
  31174. +        printk(KERN_ERR "PT: ERROR: No card found.\n");
  31175.          return -EIO;
  31176.      }
  31177.  
  31178. @@ -641,7 +622,7 @@
  31179.      long br;
  31180.      int cmd = lp->base + CTL;
  31181.  #ifdef PT_DEBUG
  31182. -    printk("PTd pt_rts(): Transmitter status will be %d (%d).\n", x, lp->base & CHANA);
  31183. +    printk(KERN_DEBUG "PT: pt_rts(): Transmitter status will be %d (%d).\n", x, lp->base & CHANA);
  31184.  #endif            
  31185.      if (x == ON) {
  31186.          /* Ex ints off to avoid int */
  31187. @@ -738,8 +719,9 @@
  31188.          return 0;
  31189.  }
  31190.  
  31191. -static int pt_set_mac_address(struct device *dev, struct sockaddr *sa)
  31192. +static int pt_set_mac_address(struct device *dev, void *addr)
  31193.  {
  31194. +    struct sockaddr *sa = (struct sockaddr *)addr;
  31195.      memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);        /* addr is an AX.25 shifted ASCII */
  31196.      return 0;        /* mac address */
  31197.  }
  31198. @@ -857,11 +839,11 @@
  31199.              restore_flags(flags);
  31200.  
  31201.              if (!dev->irq) {
  31202. -                printk("PT: ERROR: Failed to detect IRQ line, assuming IRQ7.\n");
  31203. +                printk(KERN_ERR "PT: ERROR: Failed to detect IRQ line, assuming IRQ7.\n");
  31204.              }
  31205.          }
  31206.  
  31207. -        printk("PT: Autodetected IRQ %d, assuming DMA %d\n", dev->irq, dev->dma);
  31208. +        printk(KERN_INFO "PT: Autodetected IRQ %d, assuming DMA %d\n", dev->irq, dev->dma);
  31209.  
  31210.          /* This board has jumpered interrupts. Snarf the interrupt vector
  31211.           * now.  There is no point in waiting since no other device can use
  31212. @@ -870,7 +852,7 @@
  31213.          {
  31214.              int irqval = request_irq(dev->irq, &pt_interrupt,0, "pt", NULL);
  31215.              if (irqval) {
  31216. -                printk("PT: ERROR: Unable to get IRQ %d (irqval = %d).\n",
  31217. +                printk(KERN_ERR "PT: ERROR: Unable to get IRQ %d (irqval = %d).\n",
  31218.                      dev->irq, irqval);
  31219.                  return EAGAIN;
  31220.              }
  31221. @@ -903,10 +885,13 @@
  31222.      /* New style flags */
  31223.      dev->flags = 0;
  31224.      dev->family = AF_INET;
  31225. -    dev->pa_addr = 0;
  31226. -    dev->pa_brdaddr = 0;
  31227. -    dev->pa_mask = 0;
  31228. -    dev->pa_alen = sizeof(unsigned long);
  31229. +
  31230. +#ifdef CONFIG_INET
  31231. +    dev->pa_addr    = in_aton("192.168.0.1");
  31232. +    dev->pa_brdaddr = in_aton("192.168.0.255");
  31233. +    dev->pa_mask    = in_aton("255.255.255.0");
  31234. +    dev->pa_alen    = 4;
  31235. +#endif
  31236.  
  31237.      return 0;
  31238.  } /* pt_probe() */
  31239. @@ -965,6 +950,8 @@
  31240.      dev->interrupt = 0;
  31241.      dev->start = 1;
  31242.      first_time = 0;
  31243. +
  31244. +    MOD_INC_USE_COUNT;
  31245.      
  31246.      return 0;
  31247.  } /* pt_open() */
  31248. @@ -974,7 +961,7 @@
  31249.      struct pt_local *lp = (struct pt_local *) dev->priv;
  31250.  
  31251.  #ifdef PT_DEBUG
  31252. -    printk("PTd pt_send_packet(): (%d)\n", lp->base & CHANA);
  31253. +    printk(KERN_DEBUG "PT: pt_send_packet(): (%d)\n", lp->base & CHANA);
  31254.  #endif            
  31255.      /* If some higher layer thinks we've missed an tx-done interrupt
  31256.         we are passed NULL. Caution: dev_tint() handles the cli()/sti()
  31257. @@ -1019,8 +1006,10 @@
  31258.      restore_flags(flags);
  31259.      
  31260.  #ifdef PT_DEBUG
  31261. -    printk("PTd pt_close(): Closing down channel (%d).\n", lp->base & CHANA);    
  31262. +    printk(KERN_DEBUG "PT: pt_close(): Closing down channel (%d).\n", lp->base & CHANA);    
  31263.  #endif    
  31264. +
  31265. +    MOD_DEC_USE_COUNT;
  31266.      
  31267.      return 0;
  31268.  } /* pt_close() */
  31269. @@ -1153,7 +1142,7 @@
  31270.      cmd = lp->base + CTL;
  31271.  
  31272.  #ifdef PT_DEBUG
  31273. -    printk("PTd pt_txisr(): tstate = %d (%d).\n", lp->tstate, lp->base & CHANA);
  31274. +    printk(KERN_DEBUG "PT: pt_txisr(): tstate = %d (%d).\n", lp->tstate, lp->base & CHANA);
  31275.  #endif    
  31276.      
  31277.      switch (lp->tstate) 
  31278. @@ -1253,7 +1242,7 @@
  31279.         restore_flags(flags);
  31280.         return;
  31281.      default:
  31282. -        printk("PT: pt_txisr(): Invalid tstate (%d) for chan %s.\n", lp->tstate, (cmd & CHANA? "A": "B") );
  31283. +        printk(KERN_ERR "PT: pt_txisr(): Invalid tstate (%d) for chan %s.\n", lp->tstate, (cmd & CHANA? "A": "B") );
  31284.          pt_rts(lp, OFF);
  31285.          lp->tstate = IDLE;
  31286.          break;        
  31287. @@ -1270,7 +1259,7 @@
  31288.      char rse;
  31289.      struct sk_buff *skb;
  31290.      int sksize, pkt_len;
  31291. -    struct mbuf *cur_buf;
  31292. +    struct mbuf *cur_buf = NULL;
  31293.      unsigned char *cfix;
  31294.  
  31295.      save_flags(flags);
  31296. @@ -1280,7 +1269,7 @@
  31297.      rse = rdscc(lp->cardbase, cmd, R1);
  31298.      
  31299.  #ifdef PT_DEBUG
  31300. -    printk("PTd pt_rxisr(): R1 = %#3x. (%d)\n", rse, lp->base & CHANA);
  31301. +    printk(KERN_DEBUG "PT: pt_rxisr(): R1 = %#3x. (%d)\n", rse, lp->base & CHANA);
  31302.  #endif        
  31303.  
  31304.      if (lp->dmachan && (rse & Rx_OVR))
  31305. @@ -1333,7 +1322,7 @@
  31306.       if (rse & END_FR)
  31307.       {
  31308.  #ifdef PT_DEBUG
  31309. -    printk("PTd pt_rxisr() Got end of a %u byte frame.\n", lp->rcvbuf->cnt);
  31310. +    printk(KERN_DEBUG "PT: pt_rxisr() Got end of a %u byte frame.\n", lp->rcvbuf->cnt);
  31311.  #endif         
  31312.          if (lp->dmachan)
  31313.          {
  31314. @@ -1371,7 +1360,7 @@
  31315.                       
  31316.                   }
  31317.  #ifdef PT_DEBUG
  31318. -    printk("PTd pt_rxisr() %s error.\n", (rse & CRC_ERR)? "CRC" : "state");
  31319. +    printk(KERN_DEBUG "PT: pt_rxisr() %s error.\n", (rse & CRC_ERR)? "CRC" : "state");
  31320.  #endif                 
  31321.               } else {
  31322.                   /* We have a valid frame */
  31323. @@ -1392,7 +1381,7 @@
  31324.                   skb = dev_alloc_skb(sksize);
  31325.                   if (skb == NULL)
  31326.                   {
  31327. -                     printk("PT: %s: Memory squeeze, dropping packet.\n", dev->name);
  31328. +                     printk(KERN_ERR "PT: %s: Memory squeeze, dropping packet.\n", dev->name);
  31329.                       lp->stats.rx_dropped++;
  31330.                       restore_flags(flags);
  31331.                       return;
  31332. @@ -1428,15 +1417,6 @@
  31333.       restore_flags(flags);
  31334.  } /* pt_rxisr() */
  31335.  
  31336. -/* Read the SCC channel till no more data in receiver */
  31337. -static void empty_scc(struct pt_local *lp)
  31338. -{
  31339. -    while( rdscc(lp->cardbase, lp->base + CTL, R0) & Rx_CH_AV) {
  31340. -        /* Get data from Rx buffer and toss it */
  31341. -        (void) inb_p(lp->base + DATA);
  31342. -    }
  31343. -} /* empty_scc()*/
  31344. -
  31345.  /*
  31346.   * This handles the two timer interrupts.
  31347.   * This is a real bugger, cause you have to rip it out of the pi's
  31348. @@ -1447,7 +1427,7 @@
  31349.      unsigned long flags;
  31350.  
  31351.  #ifdef PT_DEBUG
  31352. -    printk("PTd pt_tmrisr(): tstate = %d (%d).\n", lp->tstate, lp->base & CHANA);
  31353. +    printk(KERN_DEBUG "PT: pt_tmrisr(): tstate = %d (%d).\n", lp->tstate, lp->base & CHANA);
  31354.  #endif        
  31355.      
  31356.      save_flags(flags);
  31357. @@ -1467,9 +1447,9 @@
  31358.        
  31359.      default:
  31360.      if (lp->base & CHANA)
  31361. -         printk("PT: pt_tmrisr(): Invalid tstate %d for Channel A\n", lp->tstate);
  31362. +         printk(KERN_ERR "PT: pt_tmrisr(): Invalid tstate %d for Channel A\n", lp->tstate);
  31363.      else
  31364. -        printk("PT: pt_tmrisr(): Invalid tstate %d for Channel B\n", lp->tstate);
  31365. +        printk(KERN_ERR "PT: pt_tmrisr(): Invalid tstate %d for Channel B\n", lp->tstate);
  31366.      break;        
  31367.      } /* end switch */
  31368.      restore_flags(flags);
  31369. @@ -1498,11 +1478,11 @@
  31370.          {
  31371.              /* Read interrupt vector from R2, channel B */
  31372.  #ifdef PT_DEBUG
  31373. -        printk("PTd pt_interrupt(): R3 = %#3x", st);
  31374. +        printk(KERN_DEBUG "PT: pt_interrupt(): R3 = %#3x", st);
  31375.  #endif                
  31376.  /*            st = rdscc(lp->cardbase, cbase + CHANB + CTL, R2) & 0x0e;*/
  31377.  #ifdef PT_DEBUG
  31378. -        printk(" R2 = %#3x.\n", st);
  31379. +        printk(KERN_DEBUG "PI: R2 = %#3x.\n", st);
  31380.  #endif    
  31381.              if (st & CHARxIP) {
  31382.                  /* Channel A Rx */
  31383. @@ -1573,7 +1553,7 @@
  31384.      st = rdscc(lp->cardbase, cmd, R0);
  31385.  
  31386.  #ifdef PT_DEBUG
  31387. -    printk("PTd exisr(): R0 = %#3x tstate = %d (%d).\n", st, lp->tstate, lp->base & CHANA);
  31388. +    printk(KERN_DEBUG "PT: exisr(): R0 = %#3x tstate = %d (%d).\n", st, lp->tstate, lp->base & CHANA);
  31389.  #endif    
  31390.      /* Reset external status latch */
  31391.      wrtscc(lp->cardbase, cmd, R0, RES_EXT_INT);
  31392. @@ -1588,7 +1568,7 @@
  31393.      {
  31394.      case ACTIVE:        /* Unexpected underrun */
  31395.  #ifdef PT_DEBUG
  31396. -    printk("PTd exisr(): unexpected underrun detected.\n");
  31397. +    printk(KERN_DEBUG "PT: exisr(): unexpected underrun detected.\n");
  31398.  #endif        
  31399.          free_p(lp->sndbuf);
  31400.          lp->sndbuf = NULL;
  31401. @@ -1746,7 +1726,7 @@
  31402.      if ((lp->rstate == ACTIVE) && (st & BRK_ABRT) )
  31403.      {
  31404.  #ifdef PT_DEBUG
  31405. -    printk("PTd exisr(): abort detected.\n");
  31406. +    printk(KERN_DEBUG "PT: exisr(): abort detected.\n");
  31407.  #endif        
  31408.            /* read and dump all of SCC Rx FIFO */
  31409.          (void) rdscc(lp->cardbase, cmd, R8);
  31410. @@ -1765,7 +1745,7 @@
  31411.      if ( (st & DCD) != (lp->saved_RR0 & DCD))
  31412.      {
  31413.  #ifdef PT_DEBUG    
  31414. -        printk("PTd: pt_exisr(): DCD is now %s.\n", (st & DCD)? "ON" : "OFF" );
  31415. +        printk(KERN_DEBUG "PT: pt_exisr(): DCD is now %s.\n", (st & DCD)? "ON" : "OFF" );
  31416.  #endif
  31417.          if (st & DCD)
  31418.          {
  31419. @@ -1773,7 +1753,7 @@
  31420.              if (lp->rcvbuf->cnt > 0)
  31421.              {
  31422.  #ifdef PT_DEBUG
  31423. -                printk("PTd pt_exisr() dumping %u bytes from buffer.\n", lp->rcvbuf->cnt);
  31424. +                printk(KERN_DEBUG "PT: pt_exisr() dumping %u bytes from buffer.\n", lp->rcvbuf->cnt);
  31425.  #endif                    
  31426.                  /* wind back buffers */
  31427.                  lp->rcp = lp->rcvbuf->data;
  31428. @@ -1801,30 +1781,25 @@
  31429.  
  31430.  } /* pt_exisr() */
  31431.  
  31432. -/* This function is used to send the KISS params back to the kernel itself,
  31433. - * just like the TNCs do (I think)
  31434. - * It's a (bit of a) kludge
  31435. - */
  31436. -static void send_kiss(struct device *dev, unsigned char arg, unsigned char val)
  31437. +#ifdef MODULE
  31438. +int init_module(void)
  31439.  {
  31440. -    struct sk_buff *skb;
  31441. -    unsigned char *cfix;
  31442. -/*    struct pt_local *lp = (struct pt_local*)dev->priv;*/
  31443. -    
  31444. -    
  31445. -    skb = dev_alloc_skb(2);
  31446. -    if (skb == NULL)
  31447. -    {
  31448. -        printk("PT: send_kiss(): Memory squeeze, dropping KISS reply.\n");
  31449. -        return;
  31450. -    }
  31451. -    skb->dev = dev;
  31452. -    cfix = skb_put(skb, 2);
  31453. -    cfix[0]=arg;
  31454. -    cfix[1]=val;
  31455. -    skb->protocol=htons(ETH_P_AX25);
  31456. -    skb->mac.raw=skb->data;
  31457. -    IS_SKB(skb);
  31458. -    netif_rx(skb);
  31459. +    register_symtab(NULL);
  31460. +    return pt_init();
  31461.  }
  31462. -    
  31463. +
  31464. +void cleanup_module(void)
  31465. +{
  31466. +    free_irq(pt0a.irq, NULL);    /* IRQs and IO Ports are shared */
  31467. +    release_region(pt0a.base_addr & 0x3f0, PT_TOTAL_SIZE);
  31468. +    irq2dev_map[pt0a.irq] = NULL;
  31469. +
  31470. +    kfree(pt0a.priv);
  31471. +    pt0a.priv = NULL;
  31472. +    unregister_netdev(&pt0a);
  31473. +    
  31474. +    kfree(pt0b.priv);
  31475. +    pt0b.priv = NULL;
  31476. +    unregister_netdev(&pt0b);
  31477. +}
  31478. +#endif
  31479. diff -u --recursive --new-file v2.0.34/linux/drivers/net/pt.h linux/drivers/net/pt.h
  31480. --- v2.0.34/linux/drivers/net/pt.h    Mon Dec 25 20:03:00 1995
  31481. +++ linux/drivers/net/pt.h    Mon Jul 13 13:47:31 1998
  31482. @@ -1,176 +0,0 @@
  31483. -/*
  31484. - * pt.h: Linux device driver for the Gracilis PackeTwin
  31485. - * Copyright (C) 1995 Craig Small VK2XLZ (vk2xlz@vk2xlz.ampr.org.)
  31486. - *
  31487. - * Please read the notice appearing at the top of the file pt.c
  31488. - */
  31489. -#define DMA_BUFF_SIZE 2200
  31490. -
  31491. -/* Network statistics, with the same names as 'struct enet_statistics'. */
  31492. -#define netstats enet_statistics
  31493. -
  31494. -#define ON 1
  31495. -#define OFF 0
  31496. -
  31497. -
  31498. -/* Register offset info, specific to the PT
  31499. - * E.g., to read the data port on channel A, use
  31500. - *  inportb(pichan[dev].base + CHANA + DATA)
  31501. - */
  31502. -#define CHANB   0   /* Base of channel B regs */
  31503. -#define CHANA   2   /* Base of channel A regs */
  31504. -
  31505. -/* 8530 ports on each channel */
  31506. -#define CTL 0
  31507. -#define DATA    1
  31508. -
  31509. -#define DMAEN   0x8 /* Offset off DMA Enable register */
  31510. -
  31511. -/* Timer chip offsets */
  31512. -#define TMR0    0x4 /* Offset of timer 0 register */
  31513. -#define TMR1    0x5 /* Offset of timer 1 register */
  31514. -#define TMR2    0x6 /* Offset of timer 2 register */
  31515. -#define TMRCMD  0x7 /* Offset of timer command register */
  31516. -#define INT_REG    0x8
  31517. -#define TMR1CLR 0x9
  31518. -#define TMR2CLR 0xa
  31519. -
  31520. -/* Interrupt register equates */
  31521. -#define PT_SCC_MSK    0x1
  31522. -#define PT_TMR1_MSK    0x2
  31523. -#define PT_TMR2_MSK    0x4
  31524. -
  31525. -/* Serial/interrupt register equates */
  31526. -#define PT_DTRA_ON    0x1
  31527. -#define PT_DTRB_ON    0x2
  31528. -#define PT_EXTCLKA    0x4
  31529. -#define PT_EXTCLKB    0x8
  31530. -#define PT_LOOPA_ON    0x10
  31531. -#define PT_LOOPB_ON    0x20
  31532. -#define PT_EI        0x80
  31533. -
  31534. -/* Timer chip equates */
  31535. -#define SC0 0x00 /* Select counter 0 */
  31536. -#define SC1 0x40 /* Select counter 1 */
  31537. -#define SC2 0x80 /* Select counter 2 */
  31538. -#define CLATCH  0x00 /* Counter latching operation */
  31539. -#define MSB 0x20 /* Read/load MSB only */
  31540. -#define LSB 0x10 /* Read/load LSB only */
  31541. -#define LSB_MSB 0x30 /* Read/load LSB, then MSB */
  31542. -#define MODE0   0x00 /* Interrupt on terminal count */
  31543. -#define MODE1   0x02 /* Programmable one shot */
  31544. -#define MODE2   0x04 /* Rate generator */
  31545. -#define MODE3   0x06 /* Square wave rate generator */
  31546. -#define MODE4   0x08 /* Software triggered strobe */
  31547. -#define MODE5   0x0a /* Hardware triggered strobe */
  31548. -#define BCD 0x01 /* BCD counter */
  31549. -
  31550. -/* DMA controller registers */
  31551. -#define DMA_STAT    8   /* DMA controller status register */
  31552. -#define DMA_CMD     8   /* DMA controller command register */
  31553. -#define DMA_MASK        10  /* DMA controller mask register */
  31554. -#define DMA_MODE        11  /* DMA controller mode register */
  31555. -#define DMA_RESETFF 12  /* DMA controller first/last flip flop  */
  31556. -/* DMA data */
  31557. -#define DMA_DISABLE (0x04)  /* Disable channel n */
  31558. -#define DMA_ENABLE  (0x00)  /* Enable channel n */
  31559. -/* Single transfers, incr. address, auto init, writes, ch. n */
  31560. -#define DMA_RX_MODE (0x54)
  31561. -/* Single transfers, incr. address, no auto init, reads, ch. n */
  31562. -#define DMA_TX_MODE (0x48)
  31563. -
  31564. -/* Write registers */
  31565. -#define DMA_CFG        0x08
  31566. -#define SERIAL_CFG    0x09
  31567. -#define INT_CFG        0x09    /* shares with serial config */
  31568. -#define DMA_CLR_FF    0x0a
  31569. -
  31570. -#define SINGLE 3686400
  31571. -#define DOUBLE 7372800
  31572. -#define XTAL   ((long) 6144000L)
  31573. -
  31574. -#define SIOCGPIPARAM        0x5000    /* get PI parameters */
  31575. -#define SIOCSPIPARAM        0x5001    /* set */
  31576. -#define SIOCGPIBAUD        0x5002    /* get only baud rate */
  31577. -#define SIOCSPIBAUD        0x5003    
  31578. -#define SIOCGPIDMA        0x5004    /* get only DMA */
  31579. -#define SIOCSPIDMA        0x5005    
  31580. -#define SIOCGPIIRQ        0x5006    /* get only IRQ */
  31581. -#define SIOCSPIIRQ        0x5007    
  31582. -
  31583. -struct pt_req  {
  31584. -    int cmd;
  31585. -    int speed;
  31586. -    int clockmode;
  31587. -    int txdelay;
  31588. -    unsigned char persist;
  31589. -    int slotime; 
  31590. -    int squeldelay;
  31591. -    int dmachan;    
  31592. -    int irq;    
  31593. -};
  31594. -
  31595. -/* SCC Interrupt vectors, if we have set 'status low' */
  31596. -#define CHBTxIV        0x00
  31597. -#define CHBEXTIV    0x02
  31598. -#define CHBRxIV        0x04
  31599. -#define CHBSRCIV    0x06
  31600. -#define CHATxIV        0x08
  31601. -#define CHAEXTIV    0x0a
  31602. -#define CHARxIV        0x0c
  31603. -#define CHASRCIV    0x0e
  31604. -
  31605. -
  31606. -#ifdef __KERNEL__
  31607. -
  31608. -/* Information that needs to be kept for each channel. */
  31609. -struct pt_local {
  31610. -    struct netstats stats; /* %%%dp*/
  31611. -    long open_time;             /* Useless example local info. */
  31612. -    unsigned long xtal; 
  31613. -
  31614. -    struct mbuf *rcvbuf;/* Buffer for current rx packet */
  31615. -    struct mbuf *rxdmabuf1; /* DMA rx buffer */
  31616. -    struct mbuf *rxdmabuf2; /* DMA rx buffer */
  31617. -
  31618. -    int bufsiz;         /* Size of rcvbuf */
  31619. -    char *rcp;          /* Pointer into rcvbuf */
  31620. -
  31621. -    struct sk_buff_head sndq;  /* Packets awaiting transmission */
  31622. -    int sndcnt;         /* Number of packets on sndq */
  31623. -    struct sk_buff *sndbuf;/* Current buffer being transmitted */
  31624. -    char *txdmabuf;     /* Transmit DMA buffer */
  31625. -    char *txptr;        /* Used by B port tx */
  31626. -    int txcnt;            
  31627. -    char tstate;        /* Transmitter state */
  31628. -#define IDLE    0       /* Transmitter off, no data pending */
  31629. -#define ACTIVE  1       /* Transmitter on, sending data */
  31630. -#define UNDERRUN 2      /* Transmitter on, flushing CRC */
  31631. -#define FLAGOUT 3       /* CRC sent - attempt to start next frame */
  31632. -#define DEFER 4         /* Receive Active - DEFER Transmit */
  31633. -#define ST_TXDELAY 5    /* Sending leading flags */
  31634. -#define CRCOUT 6
  31635. -    char rstate;        /* Set when !DCD goes to 0 (TRUE) */
  31636. -/* Normal state is ACTIVE if Receive enabled */
  31637. -#define RXERROR 2       /* Error -- Aborting current Frame */
  31638. -#define RXABORT 3       /* ABORT sequence detected */
  31639. -#define TOOBIG 4        /* too large a frame to store */
  31640. -    
  31641. -    int dev;            /* Device number */
  31642. -    int base;       /* Base of I/O registers */
  31643. -    int cardbase;     /* Base address of card */
  31644. -    int stata;        /* address of Channel A status regs */
  31645. -    int statb;        /* address of Channel B status regs */
  31646. -    int speed;        /* Line speed, bps */
  31647. -    int clockmode;    /* tapr 9600 modem clocking option */
  31648. -    int txdelay;      /* Transmit Delay 10 ms/cnt */
  31649. -    unsigned char persist;       /* Persistence (0-255) as a % */
  31650. -    int slotime;      /* Delay to wait on persistence hit */
  31651. -    int squeldelay;   /* Delay after XMTR OFF for squelch tail */
  31652. -    struct iface *iface;    /* Associated interface */
  31653. -    int dmachan;           /* DMA channel for this port */
  31654. -    char saved_RR0;    /* The saved version of RR) that we compare with */
  31655. -    int nrzi;            /* Do we use NRZI (or NRZ) */
  31656. -};
  31657. -
  31658. -#endif
  31659. diff -u --recursive --new-file v2.0.34/linux/drivers/net/slip.c linux/drivers/net/slip.c
  31660. --- v2.0.34/linux/drivers/net/slip.c    Sun May 12 21:17:23 1996
  31661. +++ linux/drivers/net/slip.c    Mon Jul 13 13:47:31 1998
  31662. @@ -66,10 +66,6 @@
  31663.  #include <linux/tty.h>
  31664.  #include <linux/errno.h>
  31665.  #include <linux/netdevice.h>
  31666. -#ifdef CONFIG_AX25
  31667. -#include <linux/timer.h>
  31668. -#include <net/ax25.h>
  31669. -#endif
  31670.  #include <linux/etherdevice.h>
  31671.  #include <linux/skbuff.h>
  31672.  #include <linux/if_arp.h>
  31673. @@ -294,11 +290,8 @@
  31674.              set_bit(SLF_ERROR, &sl->flags);
  31675.          }
  31676.      }
  31677. -#ifdef CONFIG_AX25
  31678. -    sl->mtu      = dev->mtu + 73;
  31679. -#else
  31680.      sl->mtu      = dev->mtu;
  31681. -#endif
  31682. +    
  31683.      sl->buffsize = len;
  31684.  
  31685.      restore_flags(flags);
  31686. @@ -386,10 +379,7 @@
  31687.      skb->dev = sl->dev;
  31688.      memcpy(skb_put(skb,count), sl->rbuff, count);
  31689.      skb->mac.raw=skb->data;
  31690. -    if(sl->mode & SL_MODE_AX25)
  31691. -        skb->protocol=htons(ETH_P_AX25);
  31692. -    else
  31693. -        skb->protocol=htons(ETH_P_IP);
  31694. +    skb->protocol=htons(ETH_P_IP);
  31695.      netif_rx(skb);
  31696.      sl->rx_packets++;
  31697.  }
  31698. @@ -402,11 +392,8 @@
  31699.      int actual, count;
  31700.  
  31701.  
  31702. -#ifdef CONFIG_AX25
  31703. -    if (sl->mtu != sl->dev->mtu + 73) {    /* Someone has been ifconfigging */
  31704. -#else
  31705.      if (sl->mtu != sl->dev->mtu) {    /* Someone has been ifconfigging */
  31706. -#endif
  31707. +
  31708.          sl_changedmtu(sl);
  31709.      }
  31710.  
  31711. @@ -535,15 +522,6 @@
  31712.  sl_header(struct sk_buff *skb, struct device *dev, unsigned short type,
  31713.        void *daddr, void *saddr, unsigned len)
  31714.  {
  31715. -#ifdef CONFIG_AX25
  31716. -#ifdef CONFIG_INET
  31717. -    struct slip *sl = (struct slip*)(dev->priv);
  31718. -
  31719. -    if (sl->mode & SL_MODE_AX25 && type != htons(ETH_P_AX25))  {
  31720. -        return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
  31721. -    }
  31722. -#endif
  31723. -#endif
  31724.      return 0;
  31725.  }
  31726.  
  31727. @@ -553,15 +531,6 @@
  31728.  sl_rebuild_header(void *buff, struct device *dev, unsigned long raddr,
  31729.            struct sk_buff *skb)
  31730.  {
  31731. -#ifdef CONFIG_AX25
  31732. -#ifdef CONFIG_INET
  31733. -    struct slip *sl = (struct slip*)(dev->priv);
  31734. -
  31735. -    if (sl->mode & SL_MODE_AX25) {
  31736. -        return ax25_rebuild_header(buff, dev, raddr, skb);
  31737. -    }
  31738. -#endif
  31739. -#endif
  31740.      return 0;
  31741.  }
  31742.  
  31743. @@ -611,12 +580,7 @@
  31744.          goto noslcomp;
  31745.      }
  31746.  #endif
  31747. -
  31748. -#ifdef CONFIG_AX25
  31749. -    sl->mtu         = dev->mtu + 73;
  31750. -#else
  31751.      sl->mtu         = dev->mtu;
  31752. -#endif
  31753.      sl->buffsize = len;
  31754.      sl->rcount   = 0;
  31755.      sl->xleft    = 0;
  31756. @@ -701,11 +665,8 @@
  31757.       * Argh! mtu change time! - costs us the packet part received
  31758.       * at the change
  31759.       */
  31760. -#ifdef CONFIG_AX25
  31761. -    if (sl->mtu != sl->dev->mtu + 73)  {
  31762. -#else
  31763.      if (sl->mtu != sl->dev->mtu)  {
  31764. -#endif
  31765. +
  31766.          sl_changedmtu(sl);
  31767.      }
  31768.  
  31769. @@ -762,11 +723,6 @@
  31770.      /* Restore default settings */
  31771.      sl->mode      = SL_MODE_DEFAULT;
  31772.      sl->dev->type = ARPHRD_SLIP + sl->mode;
  31773. -#ifdef CONFIG_AX25    
  31774. -    if (sl->dev->type == 260) {        /* KISS */
  31775. -        sl->dev->type = ARPHRD_AX25;
  31776. -    }
  31777. -#endif    
  31778.      /* Perform the low-level SLIP initialization. */
  31779.      if ((err = sl_open(sl->dev)))  {
  31780.          return err;
  31781. @@ -1008,31 +964,6 @@
  31782.  }
  31783.  #endif /* CONFIG_SLIP_MODE_SLIP6 */
  31784.  
  31785. -#ifdef CONFIG_AX25
  31786. -int
  31787. -sl_set_mac_address(struct device *dev, void *addr)
  31788. -{
  31789. -    int err;
  31790. -
  31791. -    err = verify_area(VERIFY_READ, addr, AX25_ADDR_LEN);
  31792. -    if (err)  {
  31793. -        return err;
  31794. -    }
  31795. -
  31796. -    memcpy_fromfs(dev->dev_addr, addr, AX25_ADDR_LEN);    /* addr is an AX.25 shifted ASCII mac address */
  31797. -
  31798. -    return 0;
  31799. -}
  31800. -
  31801. -static int
  31802. -sl_set_dev_mac_address(struct device *dev, void *addr)
  31803. -{
  31804. -    struct sockaddr *sa=addr;
  31805. -    memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN);
  31806. -    return 0;
  31807. -}
  31808. -#endif /* CONFIG_AX25 */
  31809. -
  31810.  
  31811.  /* Perform I/O control on an active SLIP channel. */
  31812.  static int
  31813. @@ -1086,34 +1017,12 @@
  31814.              return -EINVAL;
  31815.          }
  31816.  #endif
  31817. -#ifndef CONFIG_AX25
  31818. -        if (tmp & SL_MODE_AX25) {
  31819. -            return -EINVAL;
  31820. -        }
  31821. -#else
  31822. -        if (tmp & SL_MODE_AX25) {
  31823. -            sl->dev->addr_len=AX25_ADDR_LEN;      /* sizeof an AX.25 addr */
  31824. -            sl->dev->hard_header_len=AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3;
  31825. -        } else    {
  31826. -            sl->dev->addr_len=0;    /* No mac addr in slip mode */
  31827. -            sl->dev->hard_header_len=0;
  31828. -        }
  31829. -#endif
  31830.          sl->mode = tmp;
  31831.          sl->dev->type = ARPHRD_SLIP+sl->mode;
  31832. -#ifdef CONFIG_AX25        
  31833. -        if (sl->dev->type == 260)  {
  31834. -            sl->dev->type = ARPHRD_AX25;
  31835. -        }
  31836. -#endif        
  31837.          return 0;
  31838.  
  31839.       case SIOCSIFHWADDR:
  31840. -#ifdef CONFIG_AX25
  31841. -        return sl_set_mac_address(sl->dev, arg);
  31842. -#else
  31843.          return -EINVAL;
  31844. -#endif
  31845.  
  31846.  #ifdef CONFIG_SLIP_SMART
  31847.      /* VSV changes start here */
  31848. @@ -1207,9 +1116,6 @@
  31849.  #if defined(SL_INCLUDE_CSLIP) && !defined(MODULE)
  31850.      printk("CSLIP: code copyright 1989 Regents of the University of California.\n");
  31851.  #endif
  31852. -#ifdef CONFIG_AX25
  31853. -    printk(KERN_INFO "AX25: KISS encapsulation enabled.\n");
  31854. -#endif
  31855.  #ifdef CONFIG_SLIP_SMART
  31856.      printk(KERN_INFO "SLIP linefill/keepalive option.\n");
  31857.  #endif    
  31858. @@ -1260,12 +1166,6 @@
  31859.  {
  31860.      struct slip *sl = (struct slip*)(dev->priv);
  31861.      int i;
  31862. -#ifdef CONFIG_AX25
  31863. -    static char ax25_bcast[AX25_ADDR_LEN] =
  31864. -        {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
  31865. -    static char ax25_test[AX25_ADDR_LEN] =
  31866. -        {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
  31867. -#endif
  31868.  
  31869.      if (sl == NULL)        /* Allocation failed ?? */
  31870.        return -ENODEV;
  31871. @@ -1283,22 +1183,10 @@
  31872.      dev->stop        = sl_close;
  31873.      dev->hard_header    = sl_header;
  31874.      dev->get_stats            = sl_get_stats;
  31875. -#ifdef HAVE_SET_MAC_ADDR
  31876. -#ifdef CONFIG_AX25
  31877. -    dev->set_mac_address    = sl_set_dev_mac_address;
  31878. -#endif
  31879. -#endif
  31880.      dev->hard_header_len    = 0;
  31881.      dev->addr_len        = 0;
  31882.      dev->type        = ARPHRD_SLIP + SL_MODE_DEFAULT;
  31883.      dev->tx_queue_len    = 10;
  31884. -#ifdef CONFIG_AX25
  31885. -    if (sl->dev->type == 260) {
  31886. -        sl->dev->type = ARPHRD_AX25;
  31887. -    }
  31888. -    memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);    /* Only activated in AX.25 mode */
  31889. -    memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN);    /*    ""      ""       ""    "" */
  31890. -#endif
  31891.      dev->rebuild_header    = sl_rebuild_header;
  31892.  
  31893.      for (i = 0; i < DEV_NUMBUFFS; i++)  {
  31894. diff -u --recursive --new-file v2.0.34/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
  31895. --- v2.0.34/linux/drivers/net/smc-ultra.c    Mon Jul 13 13:46:30 1998
  31896. +++ linux/drivers/net/smc-ultra.c    Mon Jul 13 13:47:31 1998
  31897. @@ -75,13 +75,13 @@
  31898.  static void ultra_block_input(struct device *dev, int count,
  31899.                            struct sk_buff *skb, int ring_offset);
  31900.  static void ultra_block_output(struct device *dev, int count,
  31901. -                            const unsigned char *buf, const start_page);
  31902. +                            const unsigned char *buf, const int start_page);
  31903.  static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
  31904.                          int ring_page);
  31905.  static void ultra_pio_input(struct device *dev, int count,
  31906.                            struct sk_buff *skb, int ring_offset);
  31907.  static void ultra_pio_output(struct device *dev, int count,
  31908. -                             const unsigned char *buf, const start_page);
  31909. +                             const unsigned char *buf, const int start_page);
  31910.  static int ultra_close_card(struct device *dev);
  31911.  
  31912.  
  31913. @@ -385,7 +385,7 @@
  31914.  }
  31915.  
  31916.  static void ultra_pio_output(struct device *dev, int count,
  31917. -                            const unsigned char *buf, const start_page)
  31918. +                            const unsigned char *buf, const int start_page)
  31919.  {
  31920.      int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
  31921.      outb(0x00, ioaddr + IOPA);    /* Set the address, LSB first. */
  31922. diff -u --recursive --new-file v2.0.34/linux/drivers/net/smc-ultra32.c linux/drivers/net/smc-ultra32.c
  31923. --- v2.0.34/linux/drivers/net/smc-ultra32.c    Mon Jul 13 13:46:30 1998
  31924. +++ linux/drivers/net/smc-ultra32.c    Mon Jul 13 13:47:31 1998
  31925. @@ -68,7 +68,7 @@
  31926.  static void ultra32_block_input(struct device *dev, int count,
  31927.                  struct sk_buff *skb, int ring_offset);
  31928.  static void ultra32_block_output(struct device *dev, int count,
  31929. -                 const unsigned char *buf, const start_page);
  31930. +                 const unsigned char *buf, const int start_page);
  31931.  static int ultra32_close(struct device *dev);
  31932.  
  31933.  #define ULTRA32_CMDREG    0    /* Offset to ASIC command register. */
  31934. @@ -238,9 +238,8 @@
  31935.  static int ultra32_open(struct device *dev)
  31936.  {
  31937.      int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC addr */
  31938. -    int irq_flags = (inb(ioaddr + ULTRA32_CFG5) & 0x08) ? 0 : SA_SHIRQ;
  31939.  
  31940. -    if (request_irq(dev->irq, ei_interrupt, irq_flags, ei_status.name, dev))
  31941. +    if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, dev))
  31942.          return -EAGAIN;
  31943.  
  31944.      outb(ULTRA32_MEMENB, ioaddr); /* Enable Shared Memory. */
  31945. @@ -268,7 +267,7 @@
  31946.  
  31947.      outb(0x00, ioaddr + ULTRA32_CFG6); /* Disable Interrupts. */
  31948.      outb(0x00, ioaddr + 6);        /* Disable interrupts. */
  31949. -    free_irq(dev->irq, NULL);
  31950. +    free_irq(dev->irq, dev);
  31951.      irq2dev_map[dev->irq] = 0;
  31952.  
  31953.      NS8390_init(dev, 0);
  31954. diff -u --recursive --new-file v2.0.34/linux/drivers/net/soundmodem/Makefile linux/drivers/net/soundmodem/Makefile
  31955. --- v2.0.34/linux/drivers/net/soundmodem/Makefile    Wed Dec 31 16:00:00 1969
  31956. +++ linux/drivers/net/soundmodem/Makefile    Mon Jul 13 13:47:31 1998
  31957. @@ -0,0 +1,60 @@
  31958. +#
  31959. +# Makefile for the soundmodem device driver.
  31960. +#
  31961. +# Note! Dependencies are done automagically by 'make dep', which also
  31962. +# removes any old dependencies. DON'T put your own dependencies here
  31963. +# unless it's something special (ie not a .c file).
  31964. +#
  31965. +# Note 2! The CFLAGS definitions are now inherited from the
  31966. +# parent makes..
  31967. +#
  31968. +
  31969. +O_TARGET    := soundmodem.o
  31970. +
  31971. +O_OBJS        := sm.o
  31972. +ifeq ($(CONFIG_SOUNDMODEM_SBC),y)
  31973. +O_OBJS        += sm_sbc.o
  31974. +endif
  31975. +ifeq ($(CONFIG_SOUNDMODEM_WSS),y)
  31976. +O_OBJS        += sm_wss.o
  31977. +endif
  31978. +ifeq ($(CONFIG_SOUNDMODEM_AFSK1200),y)
  31979. +O_OBJS        += sm_afsk1200.o
  31980. +endif
  31981. +ifeq ($(CONFIG_SOUNDMODEM_AFSK2400_7),y)
  31982. +O_OBJS        += sm_afsk2400_7.o
  31983. +endif
  31984. +ifeq ($(CONFIG_SOUNDMODEM_AFSK2400_8),y)
  31985. +O_OBJS        += sm_afsk2400_8.o
  31986. +endif
  31987. +ifeq ($(CONFIG_SOUNDMODEM_AFSK2666),y)
  31988. +O_OBJS        += sm_afsk2666.o
  31989. +endif
  31990. +ifeq ($(CONFIG_SOUNDMODEM_HAPN4800),y)
  31991. +O_OBJS        += sm_hapn4800.o
  31992. +endif
  31993. +ifeq ($(CONFIG_SOUNDMODEM_PSK4800),y)
  31994. +O_OBJS        += sm_psk4800.o
  31995. +endif
  31996. +ifeq ($(CONFIG_SOUNDMODEM_FSK9600),y)
  31997. +O_OBJS        += sm_fsk9600.o
  31998. +endif
  31999. +
  32000. +M_OBJS        := $(O_TARGET)
  32001. +
  32002. +all:        all_targets
  32003. +.PHONY:        all
  32004. +
  32005. +gentbl:        gentbl.c
  32006. +        $(HOSTCC) -Wall $< -o $@ -lm
  32007. +
  32008. +TBLHDR        := sm_tbl_afsk1200.h sm_tbl_afsk2400_8.h 
  32009. +TBLHDR        += sm_tbl_afsk2666.h sm_tbl_psk4800.h
  32010. +TBLHDR        += sm_tbl_hapn4800.h sm_tbl_fsk9600.h
  32011. +
  32012. +$(TBLHDR):    gentbl
  32013. +        ./gentbl
  32014. +
  32015. +fastdep:    $(TBLHDR)
  32016. +
  32017. +include $(TOPDIR)/Rules.make
  32018. diff -u --recursive --new-file v2.0.34/linux/drivers/net/soundmodem/gentbl.c linux/drivers/net/soundmodem/gentbl.c
  32019. --- v2.0.34/linux/drivers/net/soundmodem/gentbl.c    Wed Dec 31 16:00:00 1969
  32020. +++ linux/drivers/net/soundmodem/gentbl.c    Mon Jul 13 13:47:31 1998
  32021. @@ -0,0 +1,688 @@
  32022. +/*****************************************************************************/
  32023. +
  32024. +/*
  32025. + *      gentbl.c  -- soundcard radio modem driver table generator.
  32026. + *
  32027. + *      Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
  32028. + *
  32029. + *      This program is free software; you can redistribute it and/or modify
  32030. + *      it under the terms of the GNU General Public License as published by
  32031. + *      the Free Software Foundation; either version 2 of the License, or
  32032. + *      (at your option) any later version.
  32033. + *
  32034. + *      This program is distributed in the hope that it will be useful,
  32035. + *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  32036. + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  32037. + *      GNU General Public License for more details.
  32038. + *
  32039. + *      You should have received a copy of the GNU General Public License
  32040. + *      along with this program; if not, write to the Free Software
  32041. + *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  32042. + *
  32043. + *  Please note that the GPL allows you to use the driver, NOT the radio.
  32044. + *  In order to use the radio, you need a license from the communications
  32045. + *  authority of your country.
  32046. + *
  32047. + */
  32048. +
  32049. +#include <stdio.h>
  32050. +#include <math.h>
  32051. +#include <string.h>
  32052. +
  32053. +/* -------------------------------------------------------------------- */
  32054. +
  32055. +static void gentbl_offscostab(FILE *f, unsigned int nbits)
  32056. +{
  32057. +    int i;
  32058. +
  32059. +    fprintf(f, "\n/*\n * small cosine table in U8 format\n */\n"
  32060. +        "#define OFFSCOSTABBITS %u\n"
  32061. +        "#define OFFSCOSTABSIZE (1<<OFFSCOSTABBITS)\n\n", 
  32062. +        nbits);
  32063. +    fprintf(f, "static unsigned char offscostab[OFFSCOSTABSIZE] = {\n\t");
  32064. +    for (i = 0; i < (1<<nbits); i++) {
  32065. +        fprintf(f, "%4u", (int)
  32066. +            (128+127.0*cos(i*2.0*M_PI/(1<<nbits))));
  32067. +        if (i < (1<<nbits)-1) 
  32068. +            fprintf(f, "%s", (i & 7) == 7 ? ",\n\t" : ",");
  32069. +    }
  32070. +    fprintf(f, "\n};\n\n"
  32071. +        "#define OFFSCOS(x) offscostab[((x)>>%d)&0x%x]\n\n",
  32072. +        16-nbits, (1<<nbits)-1);
  32073. +}
  32074. +
  32075. +/* -------------------------------------------------------------------- */
  32076. +
  32077. +static void gentbl_costab(FILE *f, unsigned int nbits)
  32078. +{
  32079. +        int i;
  32080. +
  32081. +    fprintf(f, "\n/*\n * more accurate cosine table\n */\n\n"
  32082. +        "static const short costab[%d] = {", (1<<nbits));
  32083. +        for (i = 0; i < (1<<nbits); i++) {
  32084. +                if (!(i & 7))
  32085. +                        fprintf(f, "\n\t");
  32086. +                fprintf(f, "%6d", (int)(32767.0*cos(i*2.0*M_PI/(1<<nbits))));
  32087. +                if (i != ((1<<nbits)-1))
  32088. +                        fprintf(f, ", ");
  32089. +        }
  32090. +        fprintf(f, "\n};\n\n#define COS(x) costab[((x)>>%d)&0x%x]\n"
  32091. +        "#define SIN(x) COS((x)+0xc000)\n\n", 16-nbits,
  32092. +        (1<<nbits)-1);
  32093. +}
  32094. +
  32095. +/* -------------------------------------------------------------------- */
  32096. +
  32097. +#define AFSK12_SAMPLE_RATE 9600
  32098. +#define AFSK12_TX_FREQ_LO 1200
  32099. +#define AFSK12_TX_FREQ_HI 2200
  32100. +#define AFSK12_CORRLEN 8
  32101. +
  32102. +static void gentbl_afsk1200(FILE *f)
  32103. +{
  32104. +        int i, v, sum;
  32105. +
  32106. +#define ARGLO(x) 2.0*M_PI*(double)x*(double)AFSK12_TX_FREQ_LO/(double)AFSK12_SAMPLE_RATE
  32107. +#define ARGHI(x) 2.0*M_PI*(double)x*(double)AFSK12_TX_FREQ_HI/(double)AFSK12_SAMPLE_RATE
  32108. +
  32109. +    fprintf(f, "\n/*\n * afsk1200 specific tables\n */\n"
  32110. +        "#define AFSK12_SAMPLE_RATE %u\n"
  32111. +        "#define AFSK12_TX_FREQ_LO %u\n"
  32112. +        "#define AFSK12_TX_FREQ_HI %u\n"
  32113. +        "#define AFSK12_CORRLEN %u\n\n",
  32114. +        AFSK12_SAMPLE_RATE, AFSK12_TX_FREQ_LO, 
  32115. +        AFSK12_TX_FREQ_HI, AFSK12_CORRLEN);
  32116. +    fprintf(f, "static const int afsk12_tx_lo_i[] = {\n\t");
  32117. +        for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
  32118. +        sum += (v = 127.0*cos(ARGLO(i)));
  32119. +                fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
  32120. +    }
  32121. +        fprintf(f, "\n};\n#define SUM_AFSK12_TX_LO_I %d\n\n"
  32122. +        "static const int afsk12_tx_lo_q[] = {\n\t", sum);
  32123. +        for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
  32124. +        sum += (v = 127.0*sin(ARGLO(i))); 
  32125. +                fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
  32126. +    }
  32127. +        fprintf(f, "\n};\n#define SUM_AFSK12_TX_LO_Q %d\n\n"
  32128. +        "static const int afsk12_tx_hi_i[] = {\n\t", sum);
  32129. +        for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
  32130. +        sum += (v = 127.0*cos(ARGHI(i))); 
  32131. +                fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
  32132. +    }
  32133. +        fprintf(f, "\n};\n#define SUM_AFSK12_TX_HI_I %d\n\n"
  32134. +        "static const int afsk12_tx_hi_q[] = {\n\t", sum);
  32135. +        for(sum = i = 0; i < AFSK12_CORRLEN; i++)  {
  32136. +        sum += (v = 127.0*sin(ARGHI(i)));
  32137. +                fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
  32138. +    }
  32139. +    fprintf(f, "\n};\n#define SUM_AFSK12_TX_HI_Q %d\n\n", sum);
  32140. +#undef ARGLO
  32141. +#undef ARGHI
  32142. +}
  32143. +
  32144. +/* -------------------------------------------------------------------- */
  32145. +
  32146. +static const float fsk96_tx_coeff_4[32] = {
  32147. +              -0.001152,        0.000554,        0.002698,        0.002753,
  32148. +              -0.002033,       -0.008861,       -0.008002,        0.006607,
  32149. +               0.023727,        0.018905,       -0.018056,       -0.057957,
  32150. +              -0.044368,        0.055683,        0.207667,        0.322048,
  32151. +               0.322048,        0.207667,        0.055683,       -0.044368,
  32152. +              -0.057957,       -0.018056,        0.018905,        0.023727,
  32153. +               0.006607,       -0.008002,       -0.008861,       -0.002033,
  32154. +               0.002753,        0.002698,        0.000554,       -0.001152
  32155. +};
  32156. +
  32157. +static const float fsk96_tx_coeff_5[40] = {
  32158. +              -0.001009,       -0.000048,        0.001376,        0.002547,
  32159. +               0.002061,       -0.001103,       -0.005795,       -0.008170,
  32160. +              -0.004017,        0.006924,        0.018225,        0.019238,
  32161. +               0.002925,       -0.025777,       -0.048064,       -0.039683,
  32162. +               0.013760,        0.104144,        0.200355,        0.262346,
  32163. +               0.262346,        0.200355,        0.104144,        0.013760,
  32164. +              -0.039683,       -0.048064,       -0.025777,        0.002925,
  32165. +               0.019238,        0.018225,        0.006924,       -0.004017,
  32166. +              -0.008170,       -0.005795,       -0.001103,        0.002061,
  32167. +               0.002547,        0.001376,       -0.000048,       -0.001009
  32168. +};
  32169. +
  32170. +#define HAMMING(x) (0.54-0.46*cos(2*M_PI*(x)));
  32171. +
  32172. +static inline float hamming(float x)
  32173. +{
  32174. +    return 0.54-0.46*cos(2*M_PI*x);
  32175. +}
  32176. +
  32177. +static inline float sinc(float x)
  32178. +{
  32179. +    if (x == 0)
  32180. +        return 1;
  32181. +    x *= M_PI;
  32182. +    return sin(x)/x;
  32183. +}
  32184. +
  32185. +static void gentbl_fsk9600(FILE *f)
  32186. +{
  32187. +        int i, j, k, l, m;
  32188. +    float s;
  32189. +    float c[44];
  32190. +    float min, max;
  32191. +
  32192. +    fprintf(f, "\n/*\n * fsk9600 specific tables\n */\n");
  32193. +    min = max = 0;
  32194. +    memset(c, 0, sizeof(c));
  32195. +#if 0
  32196. +    memcpy(c+2, fsk96_tx_coeff_4, sizeof(fsk96_tx_coeff_4));
  32197. +#else
  32198. +    for (i = 0; i < 29; i++)
  32199. +        c[3+i] = sinc(1.2*((i-14.0)/4.0))*hamming(i/28.0)/3.5;
  32200. +#endif
  32201. +    fprintf(f, "static unsigned char fsk96_txfilt_4[] = {\n\t");
  32202. +    for (i = 0; i < 4; i++) {
  32203. +        for (j = 0; j < 256; j++) {
  32204. +            for (k = 1, s = 0, l = i; k < 256; k <<= 1) {
  32205. +                if (j & k) {
  32206. +                    for (m = 0; m < 4; m++, l++)
  32207. +                        s += c[l];
  32208. +                } else {
  32209. +                    for (m = 0; m < 4; m++, l++)
  32210. +                        s -= c[l];
  32211. +                }
  32212. +            }
  32213. +            s *= 0.75;
  32214. +            if (s > max)
  32215. +                max = s;
  32216. +            if (s < min)
  32217. +                min = s;
  32218. +            fprintf(f, "%4d", (int)(128+127*s));
  32219. +            if (i < 3 || j < 255)
  32220. +                fprintf(f, ",%s", (j & 7) == 7 
  32221. +                    ? "\n\t" : "");
  32222. +        }
  32223. +    }
  32224. +#ifdef VERBOSE
  32225. +    fprintf(stderr, "fsk9600: txfilt4: min = %f; max = %f\n", min, max);
  32226. +#endif
  32227. +    fprintf(f, "\n};\n\n");
  32228. +    min = max = 0;
  32229. +    memset(c, 0, sizeof(c));
  32230. +#if 0
  32231. +    memcpy(c+2, fsk96_tx_coeff_5, sizeof(fsk96_tx_coeff_5));
  32232. +#else
  32233. +    for (i = 0; i < 36; i++)
  32234. +        c[4+i] = sinc(1.2*((i-17.5)/5.0))*hamming(i/35.0)/4.5;
  32235. +#endif
  32236. +    fprintf(f, "static unsigned char fsk96_txfilt_5[] = {\n\t");
  32237. +    for (i = 0; i < 5; i++) {
  32238. +        for (j = 0; j < 256; j++) {
  32239. +            for (k = 1, s = 0, l = i; k < 256; k <<= 1) {
  32240. +                if (j & k) {
  32241. +                    for (m = 0; m < 5; m++, l++)
  32242. +                        s += c[l];
  32243. +                } else {
  32244. +                    for (m = 0; m < 5; m++, l++)
  32245. +                        s -= c[l];
  32246. +                }
  32247. +            }
  32248. +            s *= 0.75;
  32249. +            if (s > max)
  32250. +                max = s;
  32251. +            if (s < min)
  32252. +                min = s;
  32253. +            fprintf(f, "%4d", (int)(128+127*s));
  32254. +            if (i < 4 || j < 255)
  32255. +                fprintf(f, ",%s", (j & 7) == 7 
  32256. +                    ? "\n\t" : "");
  32257. +        }
  32258. +    }
  32259. +#ifdef VERBOSE
  32260. +    fprintf(stderr, "fsk9600: txfilt5: min = %f; max = %f\n", min, max);
  32261. +#endif
  32262. +    fprintf(f, "\n};\n\n");
  32263. +}
  32264. +    
  32265. +/* -------------------------------------------------------------------- */
  32266. +
  32267. +#define AFSK26_SAMPLERATE  16000
  32268. +
  32269. +#define AFSK26_NUMCAR      2
  32270. +#define AFSK26_FIRSTCAR    2000
  32271. +#define AFSK26_MSK_LEN     6
  32272. +#define AFSK26_RXOVER      2
  32273. +
  32274. +#define AFSK26_DEMCORRLEN (2*AFSK26_MSK_LEN)
  32275. +
  32276. +#define AFSK26_WINDOW(x) ((1-cos(2.0*M_PI*(x)))/2.0)
  32277. +
  32278. +#define AFSK26_AMPL(x) (((x)?1.0:0.7))
  32279. +
  32280. +#undef AFSK26_AMPL
  32281. +#define AFSK26_AMPL(x) 1
  32282. +
  32283. +static void gentbl_afsk2666(FILE *f)
  32284. +{
  32285. +        int i, j, k, l, o, v, sumi, sumq;
  32286. +        float window[AFSK26_DEMCORRLEN*AFSK26_RXOVER];
  32287. +    int cfreq[AFSK26_NUMCAR];
  32288. +
  32289. +    fprintf(f, "\n/*\n * afsk2666 specific tables\n */\n"
  32290. +        "#define AFSK26_DEMCORRLEN %d\n"
  32291. +        "#define AFSK26_SAMPLERATE %d\n\n", AFSK26_DEMCORRLEN,
  32292. +        AFSK26_SAMPLERATE);
  32293. +    fprintf(f, "static const unsigned int afsk26_carfreq[%d] = { ",
  32294. +        AFSK26_NUMCAR);
  32295. +    for (i = 0; i < AFSK26_NUMCAR; i++) {
  32296. +        cfreq[i] = 0x10000*AFSK26_FIRSTCAR/AFSK26_SAMPLERATE+
  32297. +            0x10000*i/AFSK26_MSK_LEN/2;
  32298. +        fprintf(f, "0x%x", cfreq[i]);
  32299. +        if (i < AFSK26_NUMCAR-1)
  32300. +            fprintf(f, ", ");
  32301. +    }
  32302. +    fprintf(f, " };\n\n");
  32303. +        for (i = 0; i < AFSK26_DEMCORRLEN*AFSK26_RXOVER; i++)
  32304. +                window[i] = AFSK26_WINDOW(((float)i)/(AFSK26_DEMCORRLEN*
  32305. +                              AFSK26_RXOVER)) * 127.0;
  32306. +        fprintf(f, "\nstatic const struct {\n\t"
  32307. +               "int i[%d];\n\tint q[%d];\n} afsk26_dem_tables[%d][%d] = {\n", 
  32308. +               AFSK26_DEMCORRLEN, AFSK26_DEMCORRLEN, AFSK26_RXOVER, AFSK26_NUMCAR);
  32309. +        for (o = AFSK26_RXOVER-1; o >= 0; o--) {
  32310. +                fprintf(f, "\t{\n");
  32311. +                for (i = 0; i < AFSK26_NUMCAR; i++) {
  32312. +                        j = cfreq[i];
  32313. +                        fprintf(f, "\t\t{{ ");
  32314. +                        for (l = AFSK26_DEMCORRLEN-1, k = (j * o)/AFSK26_RXOVER, sumi = 0; l >= 0; 
  32315. +                             l--, k = (k+j)&0xffffu) {
  32316. +                sumi += (v = AFSK26_AMPL(i)*window[l*AFSK26_RXOVER+o]*
  32317. +                     cos(M_PI*k/32768.0));
  32318. +                                fprintf(f, "%6d%s", v, l ? ", " : " }, { ");
  32319. +            }
  32320. +                        for (l = AFSK26_DEMCORRLEN-1, k = (j * o)/AFSK26_RXOVER, sumq = 0; l >= 0; 
  32321. +                             l--, k = (k+j)&0xffffu) {
  32322. +                sumq += (v = AFSK26_AMPL(i)*window[l*AFSK26_RXOVER+o]*
  32323. +                     sin(M_PI*k/32768.0));
  32324. +                                fprintf(f, "%6d%s", v, l ? ", " : " }}");
  32325. +            }
  32326. +                        if (i < 1)
  32327. +                                fprintf(f, ",");
  32328. +                        fprintf(f, "\n#define AFSK26_DEM_SUM_I_%d_%d %d\n"
  32329. +                "#define AFSK26_DEM_SUM_Q_%d_%d %d\n", 
  32330. +                AFSK26_RXOVER-1-o, i, sumi, AFSK26_RXOVER-1-o, i, sumq);
  32331. +                }
  32332. +                fprintf(f, "\t}%s\n", o ? "," : "");
  32333. +        }
  32334. +        fprintf(f, "};\n\n");
  32335. +}
  32336. +
  32337. +/* -------------------------------------------------------------------- */
  32338. +
  32339. +#define ATAN_TABLEN 1024
  32340. +
  32341. +static void gentbl_atantab(FILE *f)
  32342. +{
  32343. +        int i;
  32344. +        short x;
  32345. +
  32346. +    fprintf(f, "\n/*\n"
  32347. +        " * arctan table (indexed by i/q; should really be indexed by i/(i+q)\n"
  32348. +        " */\n""#define ATAN_TABLEN %d\n\n"
  32349. +        "static const unsigned short atan_tab[ATAN_TABLEN+2] = {",
  32350. +               ATAN_TABLEN);
  32351. +        for (i = 0; i <= ATAN_TABLEN; i++) {
  32352. +                if (!(i & 7))
  32353. +                        fprintf(f, "\n\t");
  32354. +                x = atan(i / (float)ATAN_TABLEN) / M_PI * 0x8000;
  32355. +                fprintf(f, "%6d, ", x);
  32356. +        }
  32357. +        fprintf(f, "%6d\n};\n\n", x);
  32358. +    
  32359. +}
  32360. +
  32361. +/* -------------------------------------------------------------------- */
  32362. +
  32363. +#define PSK48_TXF_OVERSAMPLING 5
  32364. +#define PSK48_TXF_NUMSAMPLES 16
  32365. +#define PSK48_RXF_LEN     64
  32366. +
  32367. +static const float psk48_tx_coeff[80] = {
  32368. +              -0.000379,       -0.000640,       -0.000000,        0.000772,
  32369. +               0.000543,       -0.000629,       -0.001187,       -0.000000,
  32370. +               0.001634,        0.001183,       -0.001382,       -0.002603,
  32371. +              -0.000000,        0.003481,        0.002472,       -0.002828,
  32372. +              -0.005215,       -0.000000,        0.006705,        0.004678,
  32373. +              -0.005269,       -0.009584,       -0.000000,        0.012065,
  32374. +               0.008360,       -0.009375,       -0.017028,       -0.000000,
  32375. +               0.021603,        0.015123,       -0.017229,       -0.032012,
  32376. +              -0.000000,        0.043774,        0.032544,       -0.040365,
  32377. +              -0.084963,       -0.000000,        0.201161,        0.374060,
  32378. +               0.374060,        0.201161,       -0.000000,       -0.084963,
  32379. +              -0.040365,        0.032544,        0.043774,       -0.000000,
  32380. +              -0.032012,       -0.017229,        0.015123,        0.021603,
  32381. +              -0.000000,       -0.017028,       -0.009375,        0.008360,
  32382. +               0.012065,       -0.000000,       -0.009584,       -0.005269,
  32383. +               0.004678,        0.006705,       -0.000000,       -0.005215,
  32384. +              -0.002828,        0.002472,        0.003481,       -0.000000,
  32385. +              -0.002603,       -0.001382,        0.001183,        0.001634,
  32386. +              -0.000000,       -0.001187,       -0.000629,        0.000543,
  32387. +               0.000772,       -0.000000,       -0.000640,       -0.000379
  32388. +};
  32389. +
  32390. +static const float psk48_rx_coeff[PSK48_RXF_LEN] = {
  32391. +              -0.000219,        0.000360,        0.000873,        0.001080,
  32392. +               0.000747,       -0.000192,       -0.001466,       -0.002436,
  32393. +              -0.002328,       -0.000699,        0.002101,        0.004809,
  32394. +               0.005696,        0.003492,       -0.001633,       -0.007660,
  32395. +              -0.011316,       -0.009627,       -0.001780,        0.009712,
  32396. +               0.019426,        0.021199,        0.011342,       -0.008583,
  32397. +              -0.030955,       -0.044093,       -0.036634,       -0.002651,
  32398. +               0.054742,        0.123101,        0.184198,        0.220219,
  32399. +               0.220219,        0.184198,        0.123101,        0.054742,
  32400. +              -0.002651,       -0.036634,       -0.044093,       -0.030955,
  32401. +              -0.008583,        0.011342,        0.021199,        0.019426,
  32402. +               0.009712,       -0.001780,       -0.009627,       -0.011316,
  32403. +              -0.007660,       -0.001633,        0.003492,        0.005696,
  32404. +               0.004809,        0.002101,       -0.000699,       -0.002328,
  32405. +              -0.002436,       -0.001466,       -0.000192,        0.000747,
  32406. +               0.001080,        0.000873,        0.000360,       -0.000219
  32407. +};
  32408. +
  32409. +static void gentbl_psk4800(FILE *f)
  32410. +{
  32411. +        int i, j, k;
  32412. +        short x;
  32413. +
  32414. +    fprintf(f, "\n/*\n * psk4800 specific tables\n */\n"
  32415. +        "#define PSK48_TXF_OVERSAMPLING %d\n"
  32416. +        "#define PSK48_TXF_NUMSAMPLES %d\n\n"
  32417. +        "#define PSK48_SAMPLERATE  8000\n"
  32418. +        "#define PSK48_CAR_FREQ    2000\n"
  32419. +        "#define PSK48_PSK_LEN     5\n"
  32420. +        "#define PSK48_RXF_LEN     %u\n"
  32421. +        "#define PSK48_PHASEINC    (0x10000*PSK48_CAR_FREQ/PSK48_SAMPLERATE)\n"
  32422. +        "#define PSK48_SPHASEINC   (0x10000/(2*PSK48_PSK_LEN))\n\n"
  32423. +        "static const short psk48_tx_table[PSK48_TXF_OVERSAMPLING*"
  32424. +        "PSK48_TXF_NUMSAMPLES*8*2] = {", 
  32425. +        PSK48_TXF_OVERSAMPLING, PSK48_TXF_NUMSAMPLES, PSK48_RXF_LEN);
  32426. +        for (i = 0; i < PSK48_TXF_OVERSAMPLING; i++) {
  32427. +                for (j = 0; j < PSK48_TXF_NUMSAMPLES; j++) {
  32428. +                        fprintf(f, "\n\t");
  32429. +                        for (k = 0; k < 8; k++) {
  32430. +                                x = 32767.0 * cos(k*M_PI/4.0) * 
  32431. +                                        psk48_tx_coeff[j * PSK48_TXF_OVERSAMPLING + i];
  32432. +                                fprintf(f, "%6d, ", x);
  32433. +                        }
  32434. +                        fprintf(f, "\n\t");
  32435. +                        for (k = 0; k < 8; k++) {
  32436. +                                x = 32767.0 * sin(k*M_PI/4.0) * 
  32437. +                                        psk48_tx_coeff[j * PSK48_TXF_OVERSAMPLING + i];
  32438. +                                fprintf(f, "%6d", x);
  32439. +                                if (k != 7 || j != PSK48_TXF_NUMSAMPLES-1 || 
  32440. +                                    i != PSK48_TXF_OVERSAMPLING-1)
  32441. +                                        fprintf(f, ", ");
  32442. +                        }
  32443. +                }
  32444. +        }
  32445. +        fprintf(f, "\n};\n\n");
  32446. +
  32447. +    fprintf(f, "static const short psk48_rx_coeff[PSK48_RXF_LEN] = {\n\t");
  32448. +    for (i = 0; i < PSK48_RXF_LEN; i++) {
  32449. +        fprintf(f, "%6d", (int)(psk48_rx_coeff[i]*32767.0));
  32450. +        if (i < PSK48_RXF_LEN-1)
  32451. +            fprintf(f, ",%s", (i & 7) == 7 ? "\n\t" : "");
  32452. +    }
  32453. +    fprintf(f, "\n};\n\n");
  32454. +}
  32455. +
  32456. +/* -------------------------------------------------------------------- */
  32457. +
  32458. +static void gentbl_hapn4800(FILE *f)
  32459. +{
  32460. +        int i, j, k, l;
  32461. +    float s;
  32462. +    float c[40];
  32463. +    float min, max;
  32464. +
  32465. +    fprintf(f, "\n/*\n * hapn4800 specific tables\n */\n\n");
  32466. +    /*
  32467. +     * firstly generate tables for the FM transmitter modulator
  32468. +     */
  32469. +    min = max = 0;
  32470. +    memset(c, 0, sizeof(c));
  32471. +    for (i = 0; i < 24; i++)
  32472. +        c[8+i] = sinc(1.5*((i-11.5)/8.0))*hamming(i/23.0)/2.4;
  32473. +    for (i = 0; i < 24; i++)
  32474. +        c[i] -= c[i+8];
  32475. +    fprintf(f, "static unsigned char hapn48_txfilt_8[] = {\n\t");
  32476. +    for (i = 0; i < 8; i++) {
  32477. +        for (j = 0; j < 16; j++) {
  32478. +            for (k = 1, s = 0, l = i; k < 16; k <<= 1, l += 8) {
  32479. +                if (j & k)
  32480. +                    s += c[l];
  32481. +                else 
  32482. +                    s -= c[l];
  32483. +            }
  32484. +            if (s > max)
  32485. +                max = s;
  32486. +            if (s < min)
  32487. +                min = s;
  32488. +            fprintf(f, "%4d", (int)(128+127*s));
  32489. +            if (i < 7 || j < 15)
  32490. +                fprintf(f, ",%s", (j & 7) == 7 
  32491. +                    ? "\n\t" : "");
  32492. +        }
  32493. +    }
  32494. +#ifdef VERBOSE
  32495. +    fprintf(stderr, "hapn4800: txfilt8: min = %f; max = %f\n", min, max);
  32496. +#endif
  32497. +    fprintf(f, "\n};\n\n");
  32498. +    min = max = 0;
  32499. +    memset(c, 0, sizeof(c));
  32500. +    for (i = 0; i < 30; i++)
  32501. +        c[10+i] = sinc(1.5*((i-14.5)/10.0))*hamming(i/29.0)/2.4;
  32502. +    for (i = 0; i < 30; i++)
  32503. +        c[i] -= c[i+10];
  32504. +    fprintf(f, "static unsigned char hapn48_txfilt_10[] = {\n\t");
  32505. +    for (i = 0; i < 10; i++) {
  32506. +        for (j = 0; j < 16; j++) {
  32507. +            for (k = 1, s = 0, l = i; k < 16; k <<= 1, l += 10) {
  32508. +                if (j & k) 
  32509. +                    s += c[l];
  32510. +                else 
  32511. +                    s -= c[l];
  32512. +            }
  32513. +            if (s > max)
  32514. +                max = s;
  32515. +            if (s < min)
  32516. +                min = s;
  32517. +            fprintf(f, "%4d", (int)(128+127*s));
  32518. +            if (i < 9 || j < 15)
  32519. +                fprintf(f, ",%s", (j & 7) == 7 
  32520. +                    ? "\n\t" : "");
  32521. +        }
  32522. +    }
  32523. +#ifdef VERBOSE
  32524. +    fprintf(stderr, "hapn4800: txfilt10: min = %f; max = %f\n", min, max);
  32525. +#endif
  32526. +    fprintf(f, "\n};\n\n");
  32527. +    /*
  32528. +     * secondly generate tables for the PM transmitter modulator
  32529. +     */
  32530. +    min = max = 0;
  32531. +    memset(c, 0, sizeof(c));
  32532. +    for (i = 0; i < 25; i++)
  32533. +        c[i] = sinc(1.4*((i-12.0)/8.0))*hamming(i/24.0)/6.3;
  32534. +    for (i = 0; i < 25; i++)
  32535. +        for (j = 1; j < 8; j++)
  32536. +            c[i] += c[i+j];
  32537. +    fprintf(f, "static unsigned char hapn48_txfilt_pm8[] = {\n\t");
  32538. +    for (i = 0; i < 8; i++) {
  32539. +        for (j = 0; j < 16; j++) {
  32540. +            for (k = 1, s = 0, l = i; k < 16; k <<= 1, l += 8) {
  32541. +                if (j & k)
  32542. +                    s += c[l];
  32543. +                else 
  32544. +                    s -= c[l];
  32545. +            }
  32546. +            if (s > max)
  32547. +                max = s;
  32548. +            if (s < min)
  32549. +                min = s;
  32550. +            fprintf(f, "%4d", (int)(128+127*s));
  32551. +            if (i < 7 || j < 15)
  32552. +                fprintf(f, ",%s", (j & 7) == 7 
  32553. +                    ? "\n\t" : "");
  32554. +        }
  32555. +    }
  32556. +#ifdef VERBOSE
  32557. +    fprintf(stderr, "hapn4800: txfiltpm8: min = %f; max = %f\n", min, max);
  32558. +#endif
  32559. +    fprintf(f, "\n};\n\n");
  32560. +    min = max = 0;
  32561. +    memset(c, 0, sizeof(c));
  32562. +    for (i = 0; i < 31; i++)
  32563. +        c[10+i] = sinc(1.4*((i-15.0)/10.0))*hamming(i/30.0)/7.9;
  32564. +    for (i = 0; i < 31; i++)
  32565. +        for (j = 1; j < 10; j++)
  32566. +            c[i] += c[i+j];
  32567. +    fprintf(f, "static unsigned char hapn48_txfilt_pm10[] = {\n\t");
  32568. +    for (i = 0; i < 10; i++) {
  32569. +        for (j = 0; j < 16; j++) {
  32570. +            for (k = 1, s = 0, l = i; k < 16; k <<= 1, l += 10) {
  32571. +                if (j & k) 
  32572. +                    s += c[l];
  32573. +                else 
  32574. +                    s -= c[l];
  32575. +            }
  32576. +            if (s > max)
  32577. +                max = s;
  32578. +            if (s < min)
  32579. +                min = s;
  32580. +            fprintf(f, "%4d", (int)(128+127*s));
  32581. +            if (i < 9 || j < 15)
  32582. +                fprintf(f, ",%s", (j & 7) == 7 
  32583. +                    ? "\n\t" : "");
  32584. +        }
  32585. +    }
  32586. +#ifdef VERBOSE
  32587. +    fprintf(stderr, "hapn4800: txfiltpm10: min = %f; max = %f\n", min, max);
  32588. +#endif
  32589. +    fprintf(f, "\n};\n\n");
  32590. +    
  32591. +}
  32592. +
  32593. +/* -------------------------------------------------------------------- */
  32594. +
  32595. +#define AFSK24_SAMPLERATE  16000
  32596. +#define AFSK24_CORRLEN     14
  32597. +
  32598. +static void gentbl_afsk2400(FILE *f, float tcm3105clk)
  32599. +{
  32600. +    int i, sum, v;
  32601. +
  32602. +    fprintf(f, "\n/*\n * afsk2400 specific tables (tcm3105 clk %7fHz)\n */\n"
  32603. +        "#define AFSK24_TX_FREQ_LO %d\n"
  32604. +        "#define AFSK24_TX_FREQ_HI %d\n"
  32605. +        "#define AFSK24_BITPLL_INC %d\n"
  32606. +        "#define AFSK24_SAMPLERATE %d\n\n", tcm3105clk, 
  32607. +        (int)(tcm3105clk/3694.0), (int)(tcm3105clk/2015.0), 
  32608. +        0x10000*2400/AFSK24_SAMPLERATE, AFSK24_SAMPLERATE);
  32609. +
  32610. +#define ARGLO(x) 2.0*M_PI*(double)x*(tcm3105clk/3694.0)/(double)AFSK24_SAMPLERATE
  32611. +#define ARGHI(x) 2.0*M_PI*(double)x*(tcm3105clk/2015.0)/(double)AFSK24_SAMPLERATE
  32612. +#define WINDOW(x) hamming((float)(x)/(AFSK24_CORRLEN-1.0))
  32613. +
  32614. +    fprintf(f, "static const int afsk24_tx_lo_i[] = {\n\t");
  32615. +        for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
  32616. +        sum += (v = 127.0*cos(ARGLO(i))*WINDOW(i));
  32617. +                fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
  32618. +    }
  32619. +        fprintf(f, "\n};\n#define SUM_AFSK24_TX_LO_I %d\n\n"
  32620. +        "static const int afsk24_tx_lo_q[] = {\n\t", sum);
  32621. +        for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
  32622. +        sum += (v = 127.0*sin(ARGLO(i))*WINDOW(i)); 
  32623. +                fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
  32624. +    }
  32625. +        fprintf(f, "\n};\n#define SUM_AFSK24_TX_LO_Q %d\n\n"
  32626. +        "static const int afsk24_tx_hi_i[] = {\n\t", sum);
  32627. +        for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
  32628. +        sum += (v = 127.0*cos(ARGHI(i))*WINDOW(i)); 
  32629. +                fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
  32630. +    }
  32631. +        fprintf(f, "\n};\n#define SUM_AFSK24_TX_HI_I %d\n\n"
  32632. +        "static const int afsk24_tx_hi_q[] = {\n\t", sum);
  32633. +        for(sum = i = 0; i < AFSK24_CORRLEN; i++)  {
  32634. +        sum += (v = 127.0*sin(ARGHI(i))*WINDOW(i));
  32635. +                fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
  32636. +    }
  32637. +    fprintf(f, "\n};\n#define SUM_AFSK24_TX_HI_Q %d\n\n", sum);
  32638. +#undef ARGLO
  32639. +#undef ARGHI
  32640. +#undef WINDOW
  32641. +}
  32642. +
  32643. +/* -------------------------------------------------------------------- */
  32644. +
  32645. +static char *progname;
  32646. +
  32647. +static void gentbl_banner(FILE *f)
  32648. +{
  32649. +    fprintf(f, "/*\n * THIS FILE IS GENERATED AUTOMATICALLY BY %s, "
  32650. +        "DO NOT EDIT!\n */\n\n", progname);
  32651. +}
  32652. +
  32653. +/* -------------------------------------------------------------------- */
  32654. +
  32655. +int main(int argc, char *argv[])
  32656. +{
  32657. +    FILE *f;
  32658. +    
  32659. +    progname = argv[0];
  32660. +    if (!(f = fopen("sm_tbl_afsk1200.h", "w")))
  32661. +        exit(1);
  32662. +    gentbl_banner(f);
  32663. +    gentbl_offscostab(f, 6);
  32664. +    gentbl_costab(f, 6);
  32665. +    gentbl_afsk1200(f);
  32666. +    fclose(f);
  32667. +    if (!(f = fopen("sm_tbl_afsk2666.h", "w")))
  32668. +        exit(1);
  32669. +    gentbl_banner(f);
  32670. +    gentbl_offscostab(f, 6);
  32671. +    gentbl_costab(f, 6);
  32672. +    gentbl_afsk2666(f);
  32673. +    fclose(f);
  32674. +    if (!(f = fopen("sm_tbl_psk4800.h", "w")))
  32675. +        exit(1);
  32676. +    gentbl_banner(f);
  32677. +    gentbl_psk4800(f);
  32678. +    gentbl_costab(f, 8);
  32679. +    gentbl_atantab(f);
  32680. +    fclose(f);
  32681. +    if (!(f = fopen("sm_tbl_hapn4800.h", "w")))
  32682. +        exit(1);
  32683. +    gentbl_banner(f);
  32684. +    gentbl_hapn4800(f);
  32685. +    fclose(f);
  32686. +    if (!(f = fopen("sm_tbl_fsk9600.h", "w")))
  32687. +        exit(1);
  32688. +    gentbl_banner(f);
  32689. +    gentbl_fsk9600(f);
  32690. +    fclose(f);
  32691. +    if (!(f = fopen("sm_tbl_afsk2400_8.h", "w")))
  32692. +        exit(1);
  32693. +    gentbl_banner(f);
  32694. +    gentbl_offscostab(f, 6);
  32695. +    gentbl_costab(f, 6);
  32696. +    gentbl_afsk2400(f, 8000000);
  32697. +    fclose(f);
  32698. +    if (!(f = fopen("sm_tbl_afsk2400_7.h", "w")))
  32699. +        exit(1);
  32700. +    gentbl_banner(f);
  32701. +    gentbl_offscostab(f, 6);
  32702. +    gentbl_costab(f, 6);
  32703. +    gentbl_afsk2400(f, 7372800);
  32704. +    fclose(f);
  32705. +    exit(0);
  32706. +}
  32707. +
  32708. +
  32709. +/* -------------------------------------------------------------------- */
  32710. diff -u --recursive --new-file v2.0.34/linux/drivers/net/soundmodem/sm.c linux/drivers/net/soundmodem/sm.c
  32711. --- v2.0.34/linux/drivers/net/soundmodem/sm.c    Wed Dec 31 16:00:00 1969
  32712. +++ linux/drivers/net/soundmodem/sm.c    Mon Jul 13 13:47:31 1998
  32713. @@ -0,0 +1,899 @@
  32714. +/*****************************************************************************/
  32715. +
  32716. +/*
  32717. + *    sm.c  -- soundcard radio modem driver.
  32718. + *
  32719. + *    Copyright (C) 1996-1998  Thomas Sailer (sailer@ife.ee.ethz.ch)
  32720. + *
  32721. + *    This program is free software; you can redistribute it and/or modify
  32722. + *    it under the terms of the GNU General Public License as published by
  32723. + *    the Free Software Foundation; either version 2 of the License, or
  32724. + *    (at your option) any later version.
  32725. + *
  32726. + *    This program is distributed in the hope that it will be useful,
  32727. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  32728. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  32729. + *    GNU General Public License for more details.
  32730. + *
  32731. + *    You should have received a copy of the GNU General Public License
  32732. + *    along with this program; if not, write to the Free Software
  32733. + *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  32734. + *
  32735. + *  Please note that the GPL allows you to use the driver, NOT the radio.
  32736. + *  In order to use the radio, you need a license from the communications
  32737. + *  authority of your country.
  32738. + *
  32739. + *
  32740. + *  Command line options (insmod command line)
  32741. + *
  32742. + *  mode     mode string; eg. "wss:afsk1200"
  32743. + *  iobase   base address of the soundcard; common values are 0x220 for sbc,
  32744. + *           0x530 for wss
  32745. + *  irq      interrupt number; common values are 7 or 5 for sbc, 11 for wss
  32746. + *  dma      dma number; common values are 0 or 1
  32747. + *
  32748. + *
  32749. + *  History:
  32750. + *   0.1  21.09.96  Started
  32751. + *        18.10.96  Changed to new user space access routines (copy_{to,from}_user)
  32752. + *   0.4  21.01.97  Separately compileable soundcard/modem modules
  32753. + *   0.5  03.03.97  fixed LPT probing (check_lpt result was interpreted the wrong way round)
  32754. + *   0.6  16.04.97  init code/data tagged
  32755. + *   0.7  30.07.97  fixed halfduplex interrupt handlers/hotfix for CS423X
  32756. + *   0.8  14.04.98  cleanups
  32757. + */
  32758. +
  32759. +/*****************************************************************************/
  32760. +
  32761. +#include <linux/config.h>
  32762. +#include <linux/module.h>
  32763. +#include <linux/ptrace.h>
  32764. +#include <linux/types.h>
  32765. +#include <linux/fcntl.h>
  32766. +#include <linux/ioport.h>
  32767. +#include <linux/net.h>
  32768. +#include <linux/in.h>
  32769. +#include <linux/string.h>
  32770. +#include <asm/system.h>
  32771. +#include <asm/io.h>
  32772. +#include <asm/bitops.h>
  32773. +#include <linux/delay.h>
  32774. +#include <linux/errno.h>
  32775. +#include "sm.h"
  32776. +
  32777. +/* --------------------------------------------------------------------- */
  32778. +
  32779. +/*
  32780. + * currently this module is supposed to support both module styles, i.e.
  32781. + * the old one present up to about 2.1.9, and the new one functioning
  32782. + * starting with 2.1.21. The reason is I have a kit allowing to compile
  32783. + * this module also under 2.0.x which was requested by several people.
  32784. + * This will go in 2.2
  32785. + */
  32786. +#include <linux/version.h>
  32787. +
  32788. +#if LINUX_VERSION_CODE >= 0x20100
  32789. +#include <asm/uaccess.h>
  32790. +#else
  32791. +#include <asm/segment.h>
  32792. +#include <linux/mm.h>
  32793. +
  32794. +#undef put_user
  32795. +#undef get_user
  32796. +
  32797. +#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
  32798. +#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
  32799. +
  32800. +extern inline int copy_from_user(void *to, const void *from, unsigned long n)
  32801. +{
  32802. +        int i = verify_area(VERIFY_READ, from, n);
  32803. +        if (i)
  32804. +                return i;
  32805. +        memcpy_fromfs(to, from, n);
  32806. +        return 0;
  32807. +}
  32808. +
  32809. +extern inline int copy_to_user(void *to, const void *from, unsigned long n)
  32810. +{
  32811. +        int i = verify_area(VERIFY_WRITE, to, n);
  32812. +        if (i)
  32813. +                return i;
  32814. +        memcpy_tofs(to, from, n);
  32815. +        return 0;
  32816. +}
  32817. +#endif
  32818. +
  32819. +#if LINUX_VERSION_CODE >= 0x20123
  32820. +#include <linux/init.h>
  32821. +#else
  32822. +#define __init
  32823. +#define __initdata
  32824. +#define __initfunc(x) x
  32825. +#endif
  32826. +
  32827. +/* --------------------------------------------------------------------- */
  32828. +
  32829. +/*static*/ const char sm_drvname[] = "soundmodem";
  32830. +static const char sm_drvinfo[] = KERN_INFO "soundmodem: (C) 1996-1998 Thomas Sailer, HB9JNX/AE4WA\n"
  32831. +KERN_INFO "soundmodem: version 0.8 compiled " __TIME__ " " __DATE__ "\n";
  32832. +
  32833. +/* --------------------------------------------------------------------- */
  32834. +
  32835. +/*static*/ const struct modem_tx_info *sm_modem_tx_table[] = {
  32836. +#ifdef CONFIG_SOUNDMODEM_AFSK1200
  32837. +    &sm_afsk1200_tx,
  32838. +#endif /* CONFIG_SOUNDMODEM_AFSK1200 */
  32839. +#ifdef CONFIG_SOUNDMODEM_AFSK2400_7
  32840. +    &sm_afsk2400_7_tx,
  32841. +#endif /* CONFIG_SOUNDMODEM_AFSK2400_7 */
  32842. +#ifdef CONFIG_SOUNDMODEM_AFSK2400_8
  32843. +    &sm_afsk2400_8_tx,
  32844. +#endif /* CONFIG_SOUNDMODEM_AFSK2400_8 */
  32845. +#ifdef CONFIG_SOUNDMODEM_AFSK2666
  32846. +    &sm_afsk2666_tx,
  32847. +#endif /* CONFIG_SOUNDMODEM_AFSK2666 */
  32848. +#ifdef CONFIG_SOUNDMODEM_PSK4800
  32849. +    &sm_psk4800_tx,
  32850. +#endif /* CONFIG_SOUNDMODEM_PSK4800 */
  32851. +#ifdef CONFIG_SOUNDMODEM_HAPN4800
  32852. +    &sm_hapn4800_8_tx,
  32853. +    &sm_hapn4800_10_tx,
  32854. +    &sm_hapn4800_pm8_tx,
  32855. +    &sm_hapn4800_pm10_tx,
  32856. +#endif /* CONFIG_SOUNDMODEM_HAPN4800 */
  32857. +#ifdef CONFIG_SOUNDMODEM_FSK9600
  32858. +    &sm_fsk9600_4_tx,
  32859. +    &sm_fsk9600_5_tx,
  32860. +#endif /* CONFIG_SOUNDMODEM_FSK9600 */
  32861. +    NULL
  32862. +};
  32863. +
  32864. +/*static*/ const struct modem_rx_info *sm_modem_rx_table[] = {
  32865. +#ifdef CONFIG_SOUNDMODEM_AFSK1200
  32866. +    &sm_afsk1200_rx,
  32867. +#endif /* CONFIG_SOUNDMODEM_AFSK1200 */
  32868. +#ifdef CONFIG_SOUNDMODEM_AFSK2400_7
  32869. +    &sm_afsk2400_7_rx,
  32870. +#endif /* CONFIG_SOUNDMODEM_AFSK2400_7 */
  32871. +#ifdef CONFIG_SOUNDMODEM_AFSK2400_8
  32872. +    &sm_afsk2400_8_rx,
  32873. +#endif /* CONFIG_SOUNDMODEM_AFSK2400_8 */
  32874. +#ifdef CONFIG_SOUNDMODEM_AFSK2666
  32875. +    &sm_afsk2666_rx,
  32876. +#endif /* CONFIG_SOUNDMODEM_AFSK2666 */
  32877. +#ifdef CONFIG_SOUNDMODEM_PSK4800
  32878. +    &sm_psk4800_rx,
  32879. +#endif /* CONFIG_SOUNDMODEM_PSK4800 */
  32880. +#ifdef CONFIG_SOUNDMODEM_HAPN4800
  32881. +    &sm_hapn4800_8_rx,
  32882. +    &sm_hapn4800_10_rx,
  32883. +    &sm_hapn4800_pm8_rx,
  32884. +    &sm_hapn4800_pm10_rx,
  32885. +#endif /* CONFIG_SOUNDMODEM_HAPN4800 */
  32886. +#ifdef CONFIG_SOUNDMODEM_FSK9600
  32887. +    &sm_fsk9600_4_rx,
  32888. +    &sm_fsk9600_5_rx,
  32889. +#endif /* CONFIG_SOUNDMODEM_FSK9600 */
  32890. +    NULL
  32891. +};
  32892. +
  32893. +static const struct hardware_info *sm_hardware_table[] = {
  32894. +#ifdef CONFIG_SOUNDMODEM_SBC
  32895. +    &sm_hw_sbc,
  32896. +    &sm_hw_sbcfdx,
  32897. +#endif /* CONFIG_SOUNDMODEM_SBC */
  32898. +#ifdef CONFIG_SOUNDMODEM_WSS
  32899. +    &sm_hw_wss,
  32900. +    &sm_hw_wssfdx,
  32901. +#endif /* CONFIG_SOUNDMODEM_WSS */
  32902. +    NULL
  32903. +};
  32904. +
  32905. +/* --------------------------------------------------------------------- */
  32906. +
  32907. +#define NR_PORTS 4
  32908. +
  32909. +/* --------------------------------------------------------------------- */
  32910. +
  32911. +static struct device sm_device[NR_PORTS];
  32912. +
  32913. +static struct {
  32914. +    char *mode;
  32915. +    int iobase, irq, dma, dma2, seriobase, pariobase, midiiobase;
  32916. +} sm_ports[NR_PORTS] = {
  32917. +    { NULL, -1, 0, 0, 0, -1, -1, -1 },
  32918. +};
  32919. +
  32920. +/* --------------------------------------------------------------------- */
  32921. +
  32922. +#define UART_RBR(iobase) (iobase+0)
  32923. +#define UART_THR(iobase) (iobase+0)
  32924. +#define UART_IER(iobase) (iobase+1)
  32925. +#define UART_IIR(iobase) (iobase+2)
  32926. +#define UART_FCR(iobase) (iobase+2)
  32927. +#define UART_LCR(iobase) (iobase+3)
  32928. +#define UART_MCR(iobase) (iobase+4)
  32929. +#define UART_LSR(iobase) (iobase+5)
  32930. +#define UART_MSR(iobase) (iobase+6)
  32931. +#define UART_SCR(iobase) (iobase+7)
  32932. +#define UART_DLL(iobase) (iobase+0)
  32933. +#define UART_DLM(iobase) (iobase+1)
  32934. +
  32935. +#define SER_EXTENT 8
  32936. +
  32937. +#define LPT_DATA(iobase)    (iobase+0)
  32938. +#define LPT_STATUS(iobase)  (iobase+1)
  32939. +#define LPT_CONTROL(iobase) (iobase+2)
  32940. +#define LPT_IRQ_ENABLE      0x10
  32941. +
  32942. +#define LPT_EXTENT 3
  32943. +
  32944. +#define MIDI_DATA(iobase)     (iobase)
  32945. +#define MIDI_STATUS(iobase)   (iobase+1)
  32946. +#define MIDI_READ_FULL 0x80   /* attention: negative logic!! */
  32947. +#define MIDI_WRITE_EMPTY 0x40 /* attention: negative logic!! */
  32948. +
  32949. +#define MIDI_EXTENT 2
  32950. +
  32951. +/* ---------------------------------------------------------------------- */
  32952. +
  32953. +#define PARAM_TXDELAY   1
  32954. +#define PARAM_PERSIST   2
  32955. +#define PARAM_SLOTTIME  3
  32956. +#define PARAM_TXTAIL    4
  32957. +#define PARAM_FULLDUP   5
  32958. +#define PARAM_HARDWARE  6
  32959. +#define PARAM_RETURN    255
  32960. +
  32961. +#define SP_SER  1
  32962. +#define SP_PAR  2
  32963. +#define SP_MIDI 4
  32964. +
  32965. +/* --------------------------------------------------------------------- */
  32966. +/*
  32967. + * ===================== port checking routines ========================
  32968. + */
  32969. +
  32970. +/*
  32971. + * returns 0 if ok and != 0 on error;
  32972. + * the same behaviour as par96_check_lpt in baycom.c
  32973. + */
  32974. +
  32975. +/*
  32976. + * returns 0 if ok and != 0 on error;
  32977. + * the same behaviour as par96_check_lpt in baycom.c
  32978. + */
  32979. +
  32980. +static int check_lpt(unsigned int iobase)
  32981. +{
  32982. +    unsigned char b1,b2;
  32983. +    int i;
  32984. +
  32985. +    if (iobase <= 0 || iobase > 0x1000-LPT_EXTENT)
  32986. +        return 0;
  32987. +    if (check_region(iobase, LPT_EXTENT))
  32988. +        return 0;
  32989. +    b1 = inb(LPT_DATA(iobase));
  32990. +    b2 = inb(LPT_CONTROL(iobase));
  32991. +    outb(0xaa, LPT_DATA(iobase));
  32992. +    i = inb(LPT_DATA(iobase)) == 0xaa;
  32993. +    outb(0x55, LPT_DATA(iobase));
  32994. +    i &= inb(LPT_DATA(iobase)) == 0x55;
  32995. +    outb(0x0a, LPT_CONTROL(iobase));
  32996. +    i &= (inb(LPT_CONTROL(iobase)) & 0xf) == 0x0a;
  32997. +    outb(0x05, LPT_CONTROL(iobase));
  32998. +    i &= (inb(LPT_CONTROL(iobase)) & 0xf) == 0x05;
  32999. +    outb(b1, LPT_DATA(iobase));
  33000. +    outb(b2, LPT_CONTROL(iobase));
  33001. +    return !i;
  33002. +}
  33003. +
  33004. +/* --------------------------------------------------------------------- */
  33005. +
  33006. +enum uart { c_uart_unknown, c_uart_8250,
  33007. +    c_uart_16450, c_uart_16550, c_uart_16550A};
  33008. +static const char *uart_str[] =
  33009. +    { "unknown", "8250", "16450", "16550", "16550A" };
  33010. +
  33011. +static enum uart check_uart(unsigned int iobase)
  33012. +{
  33013. +    unsigned char b1,b2,b3;
  33014. +    enum uart u;
  33015. +    enum uart uart_tab[] =
  33016. +        { c_uart_16450, c_uart_unknown, c_uart_16550, c_uart_16550A };
  33017. +
  33018. +    if (iobase <= 0 || iobase > 0x1000-SER_EXTENT)
  33019. +        return c_uart_unknown;
  33020. +    if (check_region(iobase, SER_EXTENT))
  33021. +        return c_uart_unknown;
  33022. +    b1 = inb(UART_MCR(iobase));
  33023. +    outb(b1 | 0x10, UART_MCR(iobase));    /* loopback mode */
  33024. +    b2 = inb(UART_MSR(iobase));
  33025. +    outb(0x1a, UART_MCR(iobase));
  33026. +    b3 = inb(UART_MSR(iobase)) & 0xf0;
  33027. +    outb(b1, UART_MCR(iobase));       /* restore old values */
  33028. +    outb(b2, UART_MSR(iobase));
  33029. +    if (b3 != 0x90)
  33030. +        return c_uart_unknown;
  33031. +    inb(UART_RBR(iobase));
  33032. +    inb(UART_RBR(iobase));
  33033. +    outb(0x01, UART_FCR(iobase));        /* enable FIFOs */
  33034. +    u = uart_tab[(inb(UART_IIR(iobase)) >> 6) & 3];
  33035. +    if (u == c_uart_16450) {
  33036. +        outb(0x5a, UART_SCR(iobase));
  33037. +        b1 = inb(UART_SCR(iobase));
  33038. +        outb(0xa5, UART_SCR(iobase));
  33039. +        b2 = inb(UART_SCR(iobase));
  33040. +        if ((b1 != 0x5a) || (b2 != 0xa5))
  33041. +            u = c_uart_8250;
  33042. +    }
  33043. +    return u;
  33044. +}
  33045. +
  33046. +/* --------------------------------------------------------------------- */
  33047. +
  33048. +static int check_midi(unsigned int iobase)
  33049. +{
  33050. +    unsigned long timeout;
  33051. +    unsigned long flags;
  33052. +    unsigned char b;
  33053. +
  33054. +    if (iobase <= 0 || iobase > 0x1000-MIDI_EXTENT)
  33055. +        return 0;
  33056. +    if (check_region(iobase, MIDI_EXTENT))
  33057. +        return 0;
  33058. +    timeout = jiffies + (HZ / 100);
  33059. +    while (inb(MIDI_STATUS(iobase)) & MIDI_WRITE_EMPTY)
  33060. +        if ((signed)(jiffies - timeout) > 0)
  33061. +            return 0;
  33062. +    save_flags(flags);
  33063. +    cli();
  33064. +    outb(0xff, MIDI_DATA(iobase));
  33065. +    b = inb(MIDI_STATUS(iobase));
  33066. +    restore_flags(flags);
  33067. +    if (!(b & MIDI_WRITE_EMPTY))
  33068. +        return 0;
  33069. +    while (inb(MIDI_STATUS(iobase)) & MIDI_WRITE_EMPTY)
  33070. +        if ((signed)(jiffies - timeout) > 0)
  33071. +            return 0;
  33072. +    return 1;
  33073. +}
  33074. +
  33075. +/* --------------------------------------------------------------------- */
  33076. +
  33077. +void sm_output_status(struct sm_state *sm)
  33078. +{
  33079. +    int invert_dcd = 0;
  33080. +    int invert_ptt = 0;
  33081. +
  33082. +    int ptt = /*hdlcdrv_ptt(&sm->hdrv)*/(sm->dma.ptt_cnt > 0) ^ invert_ptt;
  33083. +    int dcd = (!!sm->hdrv.hdlcrx.dcd) ^ invert_dcd;
  33084. +
  33085. +    if (sm->hdrv.ptt_out.flags & SP_SER) {
  33086. +        outb(dcd | (ptt << 1), UART_MCR(sm->hdrv.ptt_out.seriobase));
  33087. +        outb(0x40 & (-ptt), UART_LCR(sm->hdrv.ptt_out.seriobase));
  33088. +    }
  33089. +    if (sm->hdrv.ptt_out.flags & SP_PAR) {
  33090. +        outb(ptt | (dcd << 1), LPT_DATA(sm->hdrv.ptt_out.pariobase));
  33091. +    }
  33092. +    if (sm->hdrv.ptt_out.flags & SP_MIDI && hdlcdrv_ptt(&sm->hdrv)) {
  33093. +        outb(0, MIDI_DATA(sm->hdrv.ptt_out.midiiobase));
  33094. +    }
  33095. +}
  33096. +
  33097. +/* --------------------------------------------------------------------- */
  33098. +
  33099. +static void sm_output_open(struct sm_state *sm)
  33100. +{
  33101. +    enum uart u = c_uart_unknown;
  33102. +
  33103. +    sm->hdrv.ptt_out.flags = 0;
  33104. +    if (sm->hdrv.ptt_out.seriobase > 0 &&
  33105. +        sm->hdrv.ptt_out.seriobase <= 0x1000-SER_EXTENT &&
  33106. +        ((u = check_uart(sm->hdrv.ptt_out.seriobase))) != c_uart_unknown) {
  33107. +        sm->hdrv.ptt_out.flags |= SP_SER;
  33108. +        request_region(sm->hdrv.ptt_out.seriobase, SER_EXTENT, "sm ser ptt");
  33109. +        outb(0, UART_IER(sm->hdrv.ptt_out.seriobase));
  33110. +        /* 5 bits, 1 stop, no parity, no break, Div latch access */
  33111. +        outb(0x80, UART_LCR(sm->hdrv.ptt_out.seriobase));
  33112. +        outb(0, UART_DLM(sm->hdrv.ptt_out.seriobase));
  33113. +        outb(1, UART_DLL(sm->hdrv.ptt_out.seriobase)); /* as fast as possible */
  33114. +        /* LCR and MCR set by output_status */
  33115. +    }
  33116. +    if (sm->hdrv.ptt_out.pariobase > 0 &&
  33117. +        sm->hdrv.ptt_out.pariobase <= 0x1000-LPT_EXTENT &&
  33118. +        !check_lpt(sm->hdrv.ptt_out.pariobase)) {
  33119. +        sm->hdrv.ptt_out.flags |= SP_PAR;
  33120. +        request_region(sm->hdrv.ptt_out.pariobase, LPT_EXTENT, "sm par ptt");
  33121. +    }
  33122. +    if (sm->hdrv.ptt_out.midiiobase > 0 &&
  33123. +        sm->hdrv.ptt_out.midiiobase <= 0x1000-MIDI_EXTENT &&
  33124. +        check_midi(sm->hdrv.ptt_out.midiiobase)) {
  33125. +        sm->hdrv.ptt_out.flags |= SP_MIDI;
  33126. +        request_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT,
  33127. +                   "sm midi ptt");
  33128. +    }
  33129. +    sm_output_status(sm);
  33130. +
  33131. +    printk(KERN_INFO "%s: ptt output:", sm_drvname);
  33132. +    if (sm->hdrv.ptt_out.flags & SP_SER)
  33133. +        printk(" serial interface at 0x%x, uart %s", sm->hdrv.ptt_out.seriobase,
  33134. +               uart_str[u]);
  33135. +    if (sm->hdrv.ptt_out.flags & SP_PAR)
  33136. +        printk(" parallel interface at 0x%x", sm->hdrv.ptt_out.pariobase);
  33137. +    if (sm->hdrv.ptt_out.flags & SP_MIDI)
  33138. +        printk(" mpu401 (midi) interface at 0x%x", sm->hdrv.ptt_out.midiiobase);
  33139. +    if (!sm->hdrv.ptt_out.flags)
  33140. +        printk(" none");
  33141. +    printk("\n");
  33142. +}
  33143. +
  33144. +/* --------------------------------------------------------------------- */
  33145. +
  33146. +static void sm_output_close(struct sm_state *sm)
  33147. +{
  33148. +    /* release regions used for PTT output */
  33149. +    sm->hdrv.hdlctx.ptt = sm->hdrv.hdlctx.calibrate = 0;
  33150. +    sm_output_status(sm);
  33151. +    if (sm->hdrv.ptt_out.flags & SP_SER)
  33152. +        release_region(sm->hdrv.ptt_out.seriobase, SER_EXTENT);
  33153. +           if (sm->hdrv.ptt_out.flags & SP_PAR)
  33154. +        release_region(sm->hdrv.ptt_out.pariobase, LPT_EXTENT);
  33155. +           if (sm->hdrv.ptt_out.flags & SP_MIDI)
  33156. +        release_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT);
  33157. +    sm->hdrv.ptt_out.flags = 0;
  33158. +}
  33159. +
  33160. +/* --------------------------------------------------------------------- */
  33161. +
  33162. +static int sm_open(struct device *dev);
  33163. +static int sm_close(struct device *dev);
  33164. +static int sm_ioctl(struct device *dev, struct ifreq *ifr,
  33165. +            struct hdlcdrv_ioctl *hi, int cmd);
  33166. +
  33167. +/* --------------------------------------------------------------------- */
  33168. +
  33169. +static const struct hdlcdrv_ops sm_ops = {
  33170. +    sm_drvname, sm_drvinfo, sm_open, sm_close, sm_ioctl
  33171. +};
  33172. +
  33173. +/* --------------------------------------------------------------------- */
  33174. +
  33175. +static int sm_open(struct device *dev)
  33176. +{
  33177. +    struct sm_state *sm;
  33178. +    int err;
  33179. +
  33180. +    if (!dev || !dev->priv ||
  33181. +        ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
  33182. +        printk(KERN_ERR "sm_open: invalid device struct\n");
  33183. +        return -EINVAL;
  33184. +    }
  33185. +    sm = (struct sm_state *)dev->priv;
  33186. +
  33187. +    if (!sm->mode_tx || !sm->mode_rx || !sm->hwdrv || !sm->hwdrv->open)
  33188. +        return -ENODEV;
  33189. +    sm->hdrv.par.bitrate = sm->mode_rx->bitrate;
  33190. +    err = sm->hwdrv->open(dev, sm);
  33191. +    if (err)
  33192. +        return err;
  33193. +    sm_output_open(sm);
  33194. +    MOD_INC_USE_COUNT;
  33195. +    printk(KERN_INFO "%s: %s mode %s.%s at iobase 0x%lx irq %u dma %u dma2 %u\n",
  33196. +           sm_drvname, sm->hwdrv->hw_name, sm->mode_tx->name,
  33197. +           sm->mode_rx->name, dev->base_addr, dev->irq, dev->dma, sm->hdrv.ptt_out.dma2);
  33198. +    return 0;
  33199. +}
  33200. +
  33201. +/* --------------------------------------------------------------------- */
  33202. +
  33203. +static int sm_close(struct device *dev)
  33204. +{
  33205. +    struct sm_state *sm;
  33206. +    int err = -ENODEV;
  33207. +
  33208. +    if (!dev || !dev->priv ||
  33209. +        ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
  33210. +        printk(KERN_ERR "sm_close: invalid device struct\n");
  33211. +        return -EINVAL;
  33212. +    }
  33213. +    sm = (struct sm_state *)dev->priv;
  33214. +
  33215. +
  33216. +    if (sm->hwdrv && sm->hwdrv->close)
  33217. +        err = sm->hwdrv && sm->hwdrv->close(dev, sm);
  33218. +    sm_output_close(sm);
  33219. +    MOD_DEC_USE_COUNT;
  33220. +    printk(KERN_INFO "%s: close %s at iobase 0x%lx irq %u dma %u\n",
  33221. +           sm_drvname, sm->hwdrv->hw_name, dev->base_addr, dev->irq, dev->dma);
  33222. +    return err;
  33223. +}
  33224. +
  33225. +/* --------------------------------------------------------------------- */
  33226. +
  33227. +static int sethw(struct device *dev, struct sm_state *sm, char *mode)
  33228. +{
  33229. +    char *cp = strchr(mode, ':');
  33230. +    const struct hardware_info **hwp = sm_hardware_table;
  33231. +
  33232. +    if (!cp)
  33233. +        cp = mode;
  33234. +    else {
  33235. +        *cp++ = '\0';
  33236. +        while (hwp && (*hwp) && (*hwp)->hw_name && strcmp((*hwp)->hw_name, mode))
  33237. +            hwp++;
  33238. +        if (!hwp || !*hwp || !(*hwp)->hw_name)
  33239. +            return -EINVAL;
  33240. +        if ((*hwp)->loc_storage > sizeof(sm->hw)) {
  33241. +            printk(KERN_ERR "%s: insufficient storage for hw driver %s (%d)\n",
  33242. +                   sm_drvname, (*hwp)->hw_name, (*hwp)->loc_storage);
  33243. +            return -EINVAL;
  33244. +        }
  33245. +        sm->hwdrv = *hwp;
  33246. +    }
  33247. +    if (!*cp)
  33248. +        return 0;
  33249. +    if (sm->hwdrv && sm->hwdrv->sethw)
  33250. +        return sm->hwdrv->sethw(dev, sm, cp);
  33251. +    return -EINVAL;
  33252. +}
  33253. +
  33254. +/* --------------------------------------------------------------------- */
  33255. +
  33256. +static int sm_ioctl(struct device *dev, struct ifreq *ifr,
  33257. +            struct hdlcdrv_ioctl *hi, int cmd)
  33258. +{
  33259. +    struct sm_state *sm;
  33260. +    struct sm_ioctl bi;
  33261. +    unsigned long flags;
  33262. +    unsigned int newdiagmode;
  33263. +    unsigned int newdiagflags;
  33264. +    char *cp;
  33265. +    const struct modem_tx_info **mtp = sm_modem_tx_table;
  33266. +    const struct modem_rx_info **mrp = sm_modem_rx_table;
  33267. +    const struct hardware_info **hwp = sm_hardware_table;
  33268. +
  33269. +    if (!dev || !dev->priv ||
  33270. +        ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
  33271. +        printk(KERN_ERR "sm_ioctl: invalid device struct\n");
  33272. +        return -EINVAL;
  33273. +    }
  33274. +    sm = (struct sm_state *)dev->priv;
  33275. +
  33276. +    if (cmd != SIOCDEVPRIVATE) {
  33277. +        if (!sm->hwdrv || !sm->hwdrv->ioctl)
  33278. +            return sm->hwdrv->ioctl(dev, sm, ifr, hi, cmd);
  33279. +        return -ENOIOCTLCMD;
  33280. +    }
  33281. +    switch (hi->cmd) {
  33282. +    default:
  33283. +        if (sm->hwdrv && sm->hwdrv->ioctl)
  33284. +            return sm->hwdrv->ioctl(dev, sm, ifr, hi, cmd);
  33285. +        return -ENOIOCTLCMD;
  33286. +
  33287. +    case HDLCDRVCTL_GETMODE:
  33288. +        cp = hi->data.modename;
  33289. +        if (sm->hwdrv && sm->hwdrv->hw_name)
  33290. +            cp += sprintf(cp, "%s:", sm->hwdrv->hw_name);
  33291. +        else
  33292. +            cp += sprintf(cp, "<unspec>:");
  33293. +        if (sm->mode_tx && sm->mode_tx->name)
  33294. +            cp += sprintf(cp, "%s", sm->mode_tx->name);
  33295. +        else
  33296. +            cp += sprintf(cp, "<unspec>");
  33297. +        if (!sm->mode_rx || !sm->mode_rx ||
  33298. +            strcmp(sm->mode_rx->name, sm->mode_tx->name)) {
  33299. +            if (sm->mode_rx && sm->mode_rx->name)
  33300. +                cp += sprintf(cp, ",%s", sm->mode_rx->name);
  33301. +            else
  33302. +                cp += sprintf(cp, ",<unspec>");
  33303. +        }
  33304. +        if (copy_to_user(ifr->ifr_data, hi, sizeof(*hi)))
  33305. +            return -EFAULT;
  33306. +        return 0;
  33307. +
  33308. +    case HDLCDRVCTL_SETMODE:
  33309. +        if (dev->start || !suser())
  33310. +            return -EACCES;
  33311. +        hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
  33312. +        return sethw(dev, sm, hi->data.modename);
  33313. +
  33314. +    case HDLCDRVCTL_MODELIST:
  33315. +        cp = hi->data.modename;
  33316. +        while (*hwp) {
  33317. +            if ((*hwp)->hw_name)
  33318. +                cp += sprintf("%s:,", (*hwp)->hw_name);
  33319. +            hwp++;
  33320. +        }
  33321. +        while (*mtp) {
  33322. +            if ((*mtp)->name)
  33323. +                cp += sprintf(">%s,", (*mtp)->name);
  33324. +            mtp++;
  33325. +        }
  33326. +        while (*mrp) {
  33327. +            if ((*mrp)->name)
  33328. +                cp += sprintf("<%s,", (*mrp)->name);
  33329. +            mrp++;
  33330. +        }
  33331. +        cp[-1] = '\0';
  33332. +        if (copy_to_user(ifr->ifr_data, hi, sizeof(*hi)))
  33333. +            return -EFAULT;
  33334. +        return 0;
  33335. +
  33336. +#ifdef SM_DEBUG
  33337. +    case SMCTL_GETDEBUG:
  33338. +        if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
  33339. +            return -EFAULT;
  33340. +        bi.data.dbg.int_rate = sm->debug_vals.last_intcnt;
  33341. +        bi.data.dbg.mod_cycles = sm->debug_vals.mod_cyc;
  33342. +        bi.data.dbg.demod_cycles = sm->debug_vals.demod_cyc;
  33343. +        bi.data.dbg.dma_residue = sm->debug_vals.dma_residue;
  33344. +        sm->debug_vals.mod_cyc = sm->debug_vals.demod_cyc =
  33345. +            sm->debug_vals.dma_residue = 0;
  33346. +        if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
  33347. +            return -EFAULT;
  33348. +        return 0;
  33349. +#endif /* SM_DEBUG */
  33350. +
  33351. +    case SMCTL_DIAGNOSE:
  33352. +        if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
  33353. +            return -EFAULT;
  33354. +        newdiagmode = bi.data.diag.mode;
  33355. +        newdiagflags = bi.data.diag.flags;
  33356. +        if (newdiagmode > SM_DIAGMODE_CONSTELLATION)
  33357. +            return -EINVAL;
  33358. +        bi.data.diag.mode = sm->diag.mode;
  33359. +        bi.data.diag.flags = sm->diag.flags;
  33360. +        bi.data.diag.samplesperbit = sm->mode_rx->sperbit;
  33361. +        if (sm->diag.mode != newdiagmode) {
  33362. +            save_flags(flags);
  33363. +            cli();
  33364. +            sm->diag.ptr = -1;
  33365. +            sm->diag.flags = newdiagflags & ~SM_DIAGFLAG_VALID;
  33366. +            sm->diag.mode = newdiagmode;
  33367. +            restore_flags(flags);
  33368. +            if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
  33369. +                return -EFAULT;
  33370. +            return 0;
  33371. +        }
  33372. +        if (sm->diag.ptr < 0 || sm->diag.mode == SM_DIAGMODE_OFF) {
  33373. +            if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
  33374. +                return -EFAULT;
  33375. +            return 0;
  33376. +        }
  33377. +        if (bi.data.diag.datalen > DIAGDATALEN)
  33378. +            bi.data.diag.datalen = DIAGDATALEN;
  33379. +        if (sm->diag.ptr < bi.data.diag.datalen) {
  33380. +            if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
  33381. +                return -EFAULT;
  33382. +            return 0;
  33383. +        }
  33384. +        if (copy_to_user(bi.data.diag.data, sm->diag.data,
  33385. +                 bi.data.diag.datalen * sizeof(short)))
  33386. +            return -EFAULT;
  33387. +        bi.data.diag.flags |= SM_DIAGFLAG_VALID;
  33388. +        save_flags(flags);
  33389. +        cli();
  33390. +        sm->diag.ptr = -1;
  33391. +        sm->diag.flags = newdiagflags & ~SM_DIAGFLAG_VALID;
  33392. +        sm->diag.mode = newdiagmode;
  33393. +        restore_flags(flags);
  33394. +        if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
  33395. +            return -EFAULT;
  33396. +        return 0;
  33397. +    }
  33398. +}
  33399. +
  33400. +/* --------------------------------------------------------------------- */
  33401. +
  33402. +#ifdef __i386__
  33403. +
  33404. +int sm_x86_capability = 0;
  33405. +
  33406. +__initfunc(static void i386_capability(void))
  33407. +{
  33408. +       unsigned long flags;
  33409. +       unsigned long fl1;
  33410. +       union {
  33411. +               struct {
  33412. +                       unsigned int ebx, edx, ecx;
  33413. +               } r;
  33414. +               unsigned char s[13];
  33415. +       } id;
  33416. +       unsigned int eax;
  33417. +
  33418. +       save_flags(flags);
  33419. +       flags |= 0x200000;
  33420. +       restore_flags(flags);
  33421. +       save_flags(flags);
  33422. +       fl1 = flags;
  33423. +       flags &= ~0x200000;
  33424. +       restore_flags(flags);
  33425. +       save_flags(flags);
  33426. +       if (!(fl1 & 0x200000) || (flags & 0x200000)) {
  33427. +               printk(KERN_WARNING "%s: cpu does not support CPUID\n", sm_drvname);
  33428. +               return;
  33429. +       }
  33430. +       __asm__ ("cpuid" : "=a" (eax), "=b" (id.r.ebx), "=c" (id.r.ecx), "=d" (id.r.edx) :
  33431. +                "0" (0));
  33432. +       id.s[12] = 0;
  33433. +       if (eax < 1) {
  33434. +               printk(KERN_WARNING "%s: cpu (vendor string %s) does not support capability "
  33435. +                      "list\n", sm_drvname, id.s);
  33436. +               return;
  33437. +       }
  33438. +       printk(KERN_INFO "%s: cpu: vendor string %s ", sm_drvname, id.s);
  33439. +       __asm__ ("cpuid" : "=a" (eax), "=d" (sm_x86_capability) : "0" (1) : "ebx", "ecx");
  33440. +       printk("fam %d mdl %d step %d cap 0x%x\n", (eax >> 8) & 15, (eax >> 4) & 15,
  33441. +              eax & 15, sm_x86_capability);
  33442. +}      
  33443. +#endif /* __i386__ */  
  33444. +
  33445. +/* --------------------------------------------------------------------- */
  33446. +
  33447. +#ifdef MODULE
  33448. +__initfunc(static int sm_init(void))
  33449. +#else /* MODULE */
  33450. +__initfunc(int sm_init(void))
  33451. +#endif /* MODULE */
  33452. +{
  33453. +    int i, j, found = 0;
  33454. +    char set_hw = 1;
  33455. +    struct sm_state *sm;
  33456. +    char ifname[HDLCDRV_IFNAMELEN];
  33457. +
  33458. +    printk(sm_drvinfo);
  33459. +#ifdef __i386__
  33460. +       i386_capability();
  33461. +#endif /* __i386__ */  
  33462. +    /*
  33463. +     * register net devices
  33464. +     */
  33465. +    for (i = 0; i < NR_PORTS; i++) {
  33466. +        struct device *dev = sm_device+i;
  33467. +        sprintf(ifname, "sm%d", i);
  33468. +
  33469. +        if (!sm_ports[i].mode)
  33470. +            set_hw = 0;
  33471. +        if (!set_hw)
  33472. +            sm_ports[i].iobase = sm_ports[i].irq = 0;
  33473. +        j = hdlcdrv_register_hdlcdrv(dev, &sm_ops, sizeof(struct sm_state),
  33474. +                         ifname, sm_ports[i].iobase,
  33475. +                         sm_ports[i].irq, sm_ports[i].dma);
  33476. +        if (!j) {
  33477. +            sm = (struct sm_state *)dev->priv;
  33478. +            sm->hdrv.ptt_out.dma2 = sm_ports[i].dma2;
  33479. +            sm->hdrv.ptt_out.seriobase = sm_ports[i].seriobase;
  33480. +            sm->hdrv.ptt_out.pariobase = sm_ports[i].pariobase;
  33481. +            sm->hdrv.ptt_out.midiiobase = sm_ports[i].midiiobase;
  33482. +            if (set_hw && sethw(dev, sm, sm_ports[i].mode))
  33483. +                set_hw = 0;
  33484. +            found++;
  33485. +        } else {
  33486. +            printk(KERN_WARNING "%s: cannot register net device\n",
  33487. +                   sm_drvname);
  33488. +        }
  33489. +    }
  33490. +    if (!found)
  33491. +        return -ENXIO;
  33492. +    return 0;
  33493. +}
  33494. +
  33495. +/* --------------------------------------------------------------------- */
  33496. +
  33497. +#ifdef MODULE
  33498. +
  33499. +/*
  33500. + * command line settable parameters
  33501. + */
  33502. +static char *mode = NULL;
  33503. +static int iobase = -1;
  33504. +static int irq = -1;
  33505. +static int dma = -1;
  33506. +static int dma2 = -1;
  33507. +static int serio = 0;
  33508. +static int pario = 0;
  33509. +static int midiio = 0;
  33510. +
  33511. +#if LINUX_VERSION_CODE >= 0x20115
  33512. +
  33513. +MODULE_PARM(mode, "s");
  33514. +MODULE_PARM_DESC(mode, "soundmodem operating mode; eg. sbc:afsk1200 or wss:fsk9600");
  33515. +MODULE_PARM(iobase, "i");
  33516. +MODULE_PARM_DESC(iobase, "soundmodem base address");
  33517. +MODULE_PARM(irq, "i");
  33518. +MODULE_PARM_DESC(irq, "soundmodem interrupt");
  33519. +MODULE_PARM(dma, "i");
  33520. +MODULE_PARM_DESC(dma, "soundmodem dma channel");
  33521. +MODULE_PARM(dma2, "i");
  33522. +MODULE_PARM_DESC(dma2, "soundmodem 2nd dma channel; full duplex only");
  33523. +MODULE_PARM(serio, "i");
  33524. +MODULE_PARM_DESC(serio, "soundmodem PTT output on serial port");
  33525. +MODULE_PARM(pario, "i");
  33526. +MODULE_PARM_DESC(pario, "soundmodem PTT output on parallel port");
  33527. +MODULE_PARM(midiio, "i");
  33528. +MODULE_PARM_DESC(midiio, "soundmodem PTT output on midi port");
  33529. +
  33530. +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
  33531. +MODULE_DESCRIPTION("Soundcard amateur radio modem driver");
  33532. +
  33533. +#endif
  33534. +
  33535. +__initfunc(int init_module(void))
  33536. +{
  33537. +    if (mode) {
  33538. +        if (iobase == -1)
  33539. +            iobase = (!strncmp(mode, "sbc", 3)) ? 0x220 : 0x530;
  33540. +        if (irq == -1)
  33541. +            irq = (!strncmp(mode, "sbc", 3)) ? 5 : 11;
  33542. +        if (dma == -1)
  33543. +            dma = 1;
  33544. +    }
  33545. +    sm_ports[0].mode = mode;
  33546. +    sm_ports[0].iobase = iobase;
  33547. +    sm_ports[0].irq = irq;
  33548. +    sm_ports[0].dma = dma;
  33549. +    sm_ports[0].dma2 = dma2;
  33550. +    sm_ports[0].seriobase = serio;
  33551. +    sm_ports[0].pariobase = pario;
  33552. +    sm_ports[0].midiiobase = midiio;
  33553. +    sm_ports[1].mode = NULL;
  33554. +
  33555. +    return sm_init();
  33556. +}
  33557. +
  33558. +/* --------------------------------------------------------------------- */
  33559. +
  33560. +void cleanup_module(void)
  33561. +{
  33562. +    int i;
  33563. +
  33564. +    printk(KERN_INFO "sm: cleanup_module called\n");
  33565. +
  33566. +    for(i = 0; i < NR_PORTS; i++) {
  33567. +        struct device *dev = sm_device+i;
  33568. +        struct sm_state *sm = (struct sm_state *)dev->priv;
  33569. +
  33570. +        if (sm) {
  33571. +            if (sm->hdrv.magic != HDLCDRV_MAGIC)
  33572. +                printk(KERN_ERR "sm: invalid magic in "
  33573. +                       "cleanup_module\n");
  33574. +            else
  33575. +                hdlcdrv_unregister_hdlcdrv(dev);
  33576. +        }
  33577. +    }
  33578. +}
  33579. +
  33580. +#else /* MODULE */
  33581. +/* --------------------------------------------------------------------- */
  33582. +/*
  33583. + * format: sm=io,irq,dma[,dma2[,serio[,pario]]],mode
  33584. + * mode: hw:modem
  33585. + * hw: sbc, wss, wssfdx
  33586. + * modem: afsk1200, fsk9600
  33587. + */
  33588. +
  33589. +__initfunc(void sm_setup(char *str, int *ints))
  33590. +{
  33591. +    int i;
  33592. +
  33593. +    for (i = 0; (i < NR_PORTS) && (sm_ports[i].mode); i++);
  33594. +    if ((i >= NR_PORTS) || (ints[0] < 3)) {
  33595. +        printk(KERN_INFO "%s: too many or invalid interface "
  33596. +               "specifications\n", sm_drvname);
  33597. +        return;
  33598. +    }
  33599. +    sm_ports[i].mode = str;
  33600. +    sm_ports[i].iobase = ints[1];
  33601. +    sm_ports[i].irq = ints[2];
  33602. +    sm_ports[i].dma = ints[3];
  33603. +    sm_ports[i].dma2 = (ints[0] >= 4) ? ints[4] : 0;
  33604. +    sm_ports[i].seriobase = (ints[0] >= 5) ? ints[5] : 0;
  33605. +    sm_ports[i].pariobase = (ints[0] >= 6) ? ints[6] : 0;
  33606. +    sm_ports[i].midiiobase = (ints[0] >= 7) ? ints[7] : 0;
  33607. +    if (i < NR_PORTS-1)
  33608. +        sm_ports[i+1].mode = NULL;
  33609. +}
  33610. +
  33611. +#endif /* MODULE */
  33612. +/* --------------------------------------------------------------------- */
  33613. diff -u --recursive --new-file v2.0.34/linux/drivers/net/soundmodem/sm.h linux/drivers/net/soundmodem/sm.h
  33614. --- v2.0.34/linux/drivers/net/soundmodem/sm.h    Wed Dec 31 16:00:00 1969
  33615. +++ linux/drivers/net/soundmodem/sm.h    Mon Jul 13 13:47:31 1998
  33616. @@ -0,0 +1,382 @@
  33617. +/*****************************************************************************/
  33618. +
  33619. +/*
  33620. + *    sm.h  --  soundcard radio modem driver internal header.
  33621. + *
  33622. + *    Copyright (C) 1996-1998  Thomas Sailer (sailer@ife.ee.ethz.ch)
  33623. + *
  33624. + *    This program is free software; you can redistribute it and/or modify
  33625. + *    it under the terms of the GNU General Public License as published by
  33626. + *    the Free Software Foundation; either version 2 of the License, or
  33627. + *    (at your option) any later version.
  33628. + *
  33629. + *    This program is distributed in the hope that it will be useful,
  33630. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  33631. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  33632. + *    GNU General Public License for more details.
  33633. + *
  33634. + *    You should have received a copy of the GNU General Public License
  33635. + *    along with this program; if not, write to the Free Software
  33636. + *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  33637. + *
  33638. + *  Please note that the GPL allows you to use the driver, NOT the radio.
  33639. + *  In order to use the radio, you need a license from the communications
  33640. + *  authority of your country.
  33641. + *
  33642. + */
  33643. +
  33644. +#ifndef _SM_H
  33645. +#define _SM_H
  33646. +
  33647. +/* ---------------------------------------------------------------------- */
  33648. +
  33649. +#include <linux/hdlcdrv.h>
  33650. +#include <linux/soundmodem.h>
  33651. +
  33652. +#define SM_DEBUG
  33653. +
  33654. +/* ---------------------------------------------------------------------- */
  33655. +/*
  33656. + * Information that need to be kept for each board.
  33657. + */
  33658. +
  33659. +struct sm_state {
  33660. +    struct hdlcdrv_state hdrv;
  33661. +
  33662. +    const struct modem_tx_info *mode_tx;
  33663. +    const struct modem_rx_info *mode_rx;
  33664. +
  33665. +    const struct hardware_info *hwdrv;
  33666. +
  33667. +    /*
  33668. +     * Hardware (soundcard) access routines state
  33669. +     */
  33670. +    struct {
  33671. +        void *ibuf;
  33672. +        unsigned int ifragsz;
  33673. +        unsigned int ifragptr;
  33674. +        unsigned int i16bit;
  33675. +        void *obuf;
  33676. +        unsigned int ofragsz;
  33677. +        unsigned int ofragptr;
  33678. +        unsigned int o16bit;
  33679. +        int ptt_cnt;
  33680. +    } dma;
  33681. +
  33682. +    union {
  33683. +        long hw[32/sizeof(long)];
  33684. +    } hw;
  33685. +
  33686. +    /*
  33687. +     * state of the modem code
  33688. +     */
  33689. +    union {
  33690. +        long m[48/sizeof(long)];
  33691. +    } m;
  33692. +    union {
  33693. +        long d[256/sizeof(long)];
  33694. +    } d;
  33695. +
  33696. +#define DIAGDATALEN 64
  33697. +    struct diag_data {
  33698. +        unsigned int mode;
  33699. +        unsigned int flags;
  33700. +        volatile int ptr;
  33701. +        short data[DIAGDATALEN];
  33702. +    } diag;
  33703. +
  33704. +
  33705. +#ifdef SM_DEBUG
  33706. +    struct debug_vals {
  33707. +        unsigned long last_jiffies;
  33708. +        unsigned cur_intcnt;
  33709. +        unsigned last_intcnt;
  33710. +        unsigned mod_cyc;
  33711. +        unsigned demod_cyc;
  33712. +        unsigned dma_residue;
  33713. +    } debug_vals;
  33714. +#endif /* SM_DEBUG */
  33715. +};
  33716. +
  33717. +/* ---------------------------------------------------------------------- */
  33718. +/*
  33719. + * Mode definition structure
  33720. + */
  33721. +
  33722. +struct modem_tx_info {
  33723. +    const char *name;
  33724. +    unsigned int loc_storage;
  33725. +    int srate;
  33726. +    int bitrate;
  33727. +        void (*modulator_u8)(struct sm_state *, unsigned char *, unsigned int);
  33728. +        void (*modulator_s16)(struct sm_state *, short *, unsigned int);
  33729. +        void (*init)(struct sm_state *);
  33730. +};
  33731. +
  33732. +struct modem_rx_info {
  33733. +    const char *name;
  33734. +    unsigned int loc_storage;
  33735. +    int srate;
  33736. +    int bitrate;
  33737. +    unsigned int overlap;
  33738. +    unsigned int sperbit;
  33739. +        void (*demodulator_u8)(struct sm_state *, const unsigned char *, unsigned int);
  33740. +        void (*demodulator_s16)(struct sm_state *, const short *, unsigned int);
  33741. +        void (*init)(struct sm_state *);
  33742. +};
  33743. +
  33744. +/* ---------------------------------------------------------------------- */
  33745. +/*
  33746. + * Soundcard driver definition structure
  33747. + */
  33748. +
  33749. +struct hardware_info {
  33750. +    char *hw_name; /* used for request_{region,irq,dma} */
  33751. +    unsigned int loc_storage;
  33752. +    /*
  33753. +     * mode specific open/close
  33754. +     */
  33755. +    int (*open)(struct device *, struct sm_state *);
  33756. +    int (*close)(struct device *, struct sm_state *);
  33757. +    int (*ioctl)(struct device *, struct sm_state *, struct ifreq *,
  33758. +             struct hdlcdrv_ioctl *, int);
  33759. +    int (*sethw)(struct device *, struct sm_state *, char *);
  33760. +};
  33761. +
  33762. +/* --------------------------------------------------------------------- */
  33763. +
  33764. +#define min(a, b) (((a) < (b)) ? (a) : (b))
  33765. +#define max(a, b) (((a) > (b)) ? (a) : (b))
  33766. +
  33767. +/* --------------------------------------------------------------------- */
  33768. +
  33769. +extern const char sm_drvname[];
  33770. +extern const char sm_drvinfo[];
  33771. +
  33772. +/* --------------------------------------------------------------------- */
  33773. +/*
  33774. + * ===================== diagnostics stuff ===============================
  33775. + */
  33776. +
  33777. +extern inline void diag_trigger(struct sm_state *sm)
  33778. +{
  33779. +    if (sm->diag.ptr < 0)
  33780. +        if (!(sm->diag.flags & SM_DIAGFLAG_DCDGATE) || sm->hdrv.hdlcrx.dcd)
  33781. +            sm->diag.ptr = 0;
  33782. +}
  33783. +
  33784. +/* --------------------------------------------------------------------- */
  33785. +
  33786. +#define SHRT_MAX ((short)(((unsigned short)(~0U))>>1))
  33787. +#define SHRT_MIN (-SHRT_MAX-1)
  33788. +
  33789. +extern inline void diag_add(struct sm_state *sm, int valinp, int valdemod)
  33790. +{
  33791. +    int val;
  33792. +
  33793. +    if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
  33794. +         sm->diag.mode != SM_DIAGMODE_DEMOD) ||
  33795. +        sm->diag.ptr >= DIAGDATALEN || sm->diag.ptr < 0)
  33796. +        return;
  33797. +    val = (sm->diag.mode == SM_DIAGMODE_DEMOD) ? valdemod : valinp;
  33798. +    /* clip */
  33799. +    if (val > SHRT_MAX)
  33800. +        val = SHRT_MAX;
  33801. +    if (val < SHRT_MIN)
  33802. +        val = SHRT_MIN;
  33803. +    sm->diag.data[sm->diag.ptr++] = val;
  33804. +}
  33805. +
  33806. +/* --------------------------------------------------------------------- */
  33807. +
  33808. +extern inline void diag_add_one(struct sm_state *sm, int val)
  33809. +{
  33810. +    if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
  33811. +         sm->diag.mode != SM_DIAGMODE_DEMOD) ||
  33812. +        sm->diag.ptr >= DIAGDATALEN || sm->diag.ptr < 0)
  33813. +        return;
  33814. +    /* clip */
  33815. +    if (val > SHRT_MAX)
  33816. +        val = SHRT_MAX;
  33817. +    if (val < SHRT_MIN)
  33818. +        val = SHRT_MIN;
  33819. +    sm->diag.data[sm->diag.ptr++] = val;
  33820. +}
  33821. +
  33822. +/* --------------------------------------------------------------------- */
  33823. +
  33824. +static inline void diag_add_constellation(struct sm_state *sm, int vali, int valq)
  33825. +{
  33826. +    if ((sm->diag.mode != SM_DIAGMODE_CONSTELLATION) ||
  33827. +        sm->diag.ptr >= DIAGDATALEN-1 || sm->diag.ptr < 0)
  33828. +        return;
  33829. +    /* clip */
  33830. +    if (vali > SHRT_MAX)
  33831. +        vali = SHRT_MAX;
  33832. +    if (vali < SHRT_MIN)
  33833. +        vali = SHRT_MIN;
  33834. +    if (valq > SHRT_MAX)
  33835. +        valq = SHRT_MAX;
  33836. +    if (valq < SHRT_MIN)
  33837. +        valq = SHRT_MIN;
  33838. +    sm->diag.data[sm->diag.ptr++] = vali;
  33839. +    sm->diag.data[sm->diag.ptr++] = valq;
  33840. +}
  33841. +
  33842. +/* --------------------------------------------------------------------- */
  33843. +/*
  33844. + * ===================== utility functions ===============================
  33845. + */
  33846. +
  33847. +extern inline unsigned int hweight32(unsigned int w)
  33848. +    __attribute__ ((unused));
  33849. +extern inline unsigned int hweight16(unsigned short w)
  33850. +    __attribute__ ((unused));
  33851. +extern inline unsigned int hweight8(unsigned char w)
  33852. +        __attribute__ ((unused));
  33853. +
  33854. +extern inline unsigned int hweight32(unsigned int w)
  33855. +{
  33856. +        unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
  33857. +        res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
  33858. +        res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
  33859. +        res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
  33860. +        return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
  33861. +}
  33862. +
  33863. +extern inline unsigned int hweight16(unsigned short w)
  33864. +{
  33865. +        unsigned short res = (w & 0x5555) + ((w >> 1) & 0x5555);
  33866. +        res = (res & 0x3333) + ((res >> 2) & 0x3333);
  33867. +        res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
  33868. +        return (res & 0x00FF) + ((res >> 8) & 0x00FF);
  33869. +}
  33870. +
  33871. +extern inline unsigned int hweight8(unsigned char w)
  33872. +{
  33873. +        unsigned short res = (w & 0x55) + ((w >> 1) & 0x55);
  33874. +        res = (res & 0x33) + ((res >> 2) & 0x33);
  33875. +        return (res & 0x0F) + ((res >> 4) & 0x0F);
  33876. +}
  33877. +
  33878. +extern inline unsigned int gcd(unsigned int x, unsigned int y)
  33879. +    __attribute__ ((unused));
  33880. +extern inline unsigned int lcm(unsigned int x, unsigned int y)
  33881. +    __attribute__ ((unused));
  33882. +
  33883. +extern inline unsigned int gcd(unsigned int x, unsigned int y)
  33884. +{
  33885. +    for (;;) {
  33886. +        if (!x)
  33887. +            return y;
  33888. +        if (!y)
  33889. +            return x;
  33890. +        if (x > y)
  33891. +            x %= y;
  33892. +        else
  33893. +            y %= x;
  33894. +    }
  33895. +}
  33896. +
  33897. +extern inline unsigned int lcm(unsigned int x, unsigned int y)
  33898. +{
  33899. +    return x * y / gcd(x, y);
  33900. +}
  33901. +
  33902. +/* --------------------------------------------------------------------- */
  33903. +/*
  33904. + * ===================== profiling =======================================
  33905. + */
  33906. +
  33907. +
  33908. +#ifdef __i386__
  33909. +
  33910. +extern int sm_x86_capability;
  33911. +
  33912. +#define HAS_RDTSC (sm_x86_capability & 0x10)
  33913. +
  33914. +/*
  33915. + * only do 32bit cycle counter arithmetic; we hope we won't overflow.
  33916. + * in fact, overflowing modems would require over 2THz CPU clock speeds :-)
  33917. + */
  33918. +
  33919. +#define time_exec(var,cmd)                                              \
  33920. +({                                                                      \
  33921. +    if (HAS_RDTSC) {                                                \
  33922. +        unsigned int cnt1, cnt2, cnt3;                          \
  33923. +        __asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt3));  \
  33924. +        cmd;                                                    \
  33925. +        __asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt3));  \
  33926. +        var = cnt2-cnt1;                                        \
  33927. +    } else {                                                        \
  33928. +        cmd;                                                    \
  33929. +    }                                                               \
  33930. +})
  33931. +
  33932. +#else /* __i386__ */
  33933. +
  33934. +#define time_exec(var,cmd) cmd
  33935. +
  33936. +#endif /* __i386__ */
  33937. +
  33938. +/* --------------------------------------------------------------------- */
  33939. +
  33940. +extern const struct modem_tx_info sm_afsk1200_tx;
  33941. +extern const struct modem_tx_info sm_afsk2400_7_tx;
  33942. +extern const struct modem_tx_info sm_afsk2400_8_tx;
  33943. +extern const struct modem_tx_info sm_afsk2666_tx;
  33944. +extern const struct modem_tx_info sm_psk4800_tx;
  33945. +extern const struct modem_tx_info sm_hapn4800_8_tx;
  33946. +extern const struct modem_tx_info sm_hapn4800_10_tx;
  33947. +extern const struct modem_tx_info sm_hapn4800_pm8_tx;
  33948. +extern const struct modem_tx_info sm_hapn4800_pm10_tx;
  33949. +extern const struct modem_tx_info sm_fsk9600_4_tx;
  33950. +extern const struct modem_tx_info sm_fsk9600_5_tx;
  33951. +
  33952. +extern const struct modem_rx_info sm_afsk1200_rx;
  33953. +extern const struct modem_rx_info sm_afsk2400_7_rx;
  33954. +extern const struct modem_rx_info sm_afsk2400_8_rx;
  33955. +extern const struct modem_rx_info sm_afsk2666_rx;
  33956. +extern const struct modem_rx_info sm_psk4800_rx;
  33957. +extern const struct modem_rx_info sm_hapn4800_8_rx;
  33958. +extern const struct modem_rx_info sm_hapn4800_10_rx;
  33959. +extern const struct modem_rx_info sm_hapn4800_pm8_rx;
  33960. +extern const struct modem_rx_info sm_hapn4800_pm10_rx;
  33961. +extern const struct modem_rx_info sm_fsk9600_4_rx;
  33962. +extern const struct modem_rx_info sm_fsk9600_5_rx;
  33963. +
  33964. +extern const struct hardware_info sm_hw_sbc;
  33965. +extern const struct hardware_info sm_hw_sbcfdx;
  33966. +extern const struct hardware_info sm_hw_wss;
  33967. +extern const struct hardware_info sm_hw_wssfdx;
  33968. +
  33969. +extern const struct modem_tx_info *sm_modem_tx_table[];
  33970. +extern const struct modem_rx_info *sm_modem_rx_table[];
  33971. +extern const struct hardware_info *sm_hardware_table[];
  33972. +
  33973. +/* --------------------------------------------------------------------- */
  33974. +
  33975. +void sm_output_status(struct sm_state *sm);
  33976. +/*void sm_output_open(struct sm_state *sm);*/
  33977. +/*void sm_output_close(struct sm_state *sm);*/
  33978. +
  33979. +/* --------------------------------------------------------------------- */
  33980. +
  33981. +extern void inline sm_int_freq(struct sm_state *sm)
  33982. +{
  33983. +#ifdef SM_DEBUG
  33984. +    unsigned long cur_jiffies = jiffies;
  33985. +    /*
  33986. +     * measure the interrupt frequency
  33987. +     */
  33988. +    sm->debug_vals.cur_intcnt++;
  33989. +    if ((cur_jiffies - sm->debug_vals.last_jiffies) >= HZ) {
  33990. +        sm->debug_vals.last_jiffies = cur_jiffies;
  33991. +        sm->debug_vals.last_intcnt = sm->debug_vals.cur_intcnt;
  33992. +        sm->debug_vals.cur_intcnt = 0;
  33993. +    }
  33994. +#endif /* SM_DEBUG */
  33995. +}
  33996. +
  33997. +/* --------------------------------------------------------------------- */
  33998. +#endif /* _SM_H */
  33999. diff -u --recursive --new-file v2.0.34/linux/drivers/net/soundmodem/sm_afsk1200.c linux/drivers/net/soundmodem/sm_afsk1200.c
  34000. --- v2.0.34/linux/drivers/net/soundmodem/sm_afsk1200.c    Wed Dec 31 16:00:00 1969
  34001. +++ linux/drivers/net/soundmodem/sm_afsk1200.c    Mon Jul 13 13:47:31 1998
  34002. @@ -0,0 +1,272 @@
  34003. +/*****************************************************************************/
  34004. +
  34005. +/*
  34006. + *    sm_afsk1200.c  -- soundcard radio modem driver, 1200 baud AFSK modem
  34007. + *
  34008. + *    Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
  34009. + *
  34010. + *    This program is free software; you can redistribute it and/or modify
  34011. + *    it under the terms of the GNU General Public License as published by
  34012. + *    the Free Software Foundation; either version 2 of the License, or
  34013. + *    (at your option) any later version.
  34014. + *
  34015. + *    This program is distributed in the hope that it will be useful,
  34016. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  34017. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  34018. + *    GNU General Public License for more details.
  34019. + *
  34020. + *    You should have received a copy of the GNU General Public License
  34021. + *    along with this program; if not, write to the Free Software
  34022. + *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  34023. + *
  34024. + *  Please note that the GPL allows you to use the driver, NOT the radio.
  34025. + *  In order to use the radio, you need a license from the communications
  34026. + *  authority of your country.
  34027. + *
  34028. + */
  34029. +
  34030. +#include "sm.h"
  34031. +#include "sm_tbl_afsk1200.h"
  34032. +
  34033. +/* --------------------------------------------------------------------- */
  34034. +
  34035. +struct demod_state_afsk12 {
  34036. +    unsigned int shreg;
  34037. +    unsigned int bit_pll;
  34038. +    unsigned char last_sample;
  34039. +    unsigned int dcd_shreg;
  34040. +    int dcd_sum0, dcd_sum1, dcd_sum2;
  34041. +    unsigned int dcd_time;
  34042. +    unsigned char last_rxbit;
  34043. +};
  34044. +
  34045. +struct mod_state_afsk12 {
  34046. +    unsigned int shreg;
  34047. +    unsigned char tx_bit;
  34048. +    unsigned int bit_pll;
  34049. +    unsigned int dds_inc;
  34050. +    unsigned int txphase;
  34051. +};
  34052. +
  34053. +/* --------------------------------------------------------------------- */
  34054. +
  34055. +static const int dds_inc[2] = { 
  34056. +    AFSK12_TX_FREQ_LO*0x10000/AFSK12_SAMPLE_RATE,
  34057. +    AFSK12_TX_FREQ_HI*0x10000/AFSK12_SAMPLE_RATE 
  34058. +};
  34059. +
  34060. +static void modulator_1200_u8(struct sm_state *sm, unsigned char *buf, 
  34061. +                  unsigned int buflen)
  34062. +{
  34063. +    struct mod_state_afsk12 *st = (struct mod_state_afsk12 *)(&sm->m);
  34064. +
  34065. +    for (; buflen > 0; buflen--) {
  34066. +        if (!((st->txphase++) & 7)) {
  34067. +            if (st->shreg <= 1)
  34068. +                st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
  34069. +            st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
  34070. +            st->shreg >>= 1;
  34071. +        }
  34072. +        st->dds_inc = dds_inc[st->tx_bit & 1];
  34073. +        *buf++ = OFFSCOS(st->bit_pll);
  34074. +        st->bit_pll += st->dds_inc;
  34075. +    }
  34076. +}
  34077. +
  34078. +/* --------------------------------------------------------------------- */
  34079. +
  34080. +static void modulator_1200_s16(struct sm_state *sm, short *buf, unsigned int buflen)
  34081. +{
  34082. +    struct mod_state_afsk12 *st = (struct mod_state_afsk12 *)(&sm->m);
  34083. +
  34084. +    for (; buflen > 0; buflen--) {
  34085. +        if (!((st->txphase++) & 7)) {
  34086. +            if (st->shreg <= 1)
  34087. +                st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
  34088. +            st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
  34089. +            st->shreg >>= 1;
  34090. +        }
  34091. +        st->dds_inc = dds_inc[st->tx_bit & 1];
  34092. +        *buf++ = COS(st->bit_pll);
  34093. +        st->bit_pll += st->dds_inc;
  34094. +    }
  34095. +}
  34096. +
  34097. +/* --------------------------------------------------------------------- */
  34098. +
  34099. +extern __inline__ int convolution8_u8(const unsigned char *st, const int *coeff, int csum)
  34100. +{
  34101. +    int sum = -0x80 * csum;
  34102. +    
  34103. +    sum += (st[0] * coeff[0]);
  34104. +    sum += (st[-1] * coeff[1]);
  34105. +    sum += (st[-2] * coeff[2]);
  34106. +    sum += (st[-3] * coeff[3]);
  34107. +    sum += (st[-4] * coeff[4]);
  34108. +    sum += (st[-5] * coeff[5]);
  34109. +    sum += (st[-6] * coeff[6]);
  34110. +    sum += (st[-7] * coeff[7]);
  34111. +
  34112. +    sum >>= 7;
  34113. +    return sum * sum;
  34114. +}
  34115. +
  34116. +extern __inline__ int convolution8_s16(const short *st, const int *coeff, int csum)
  34117. +{
  34118. +    int sum = 0;
  34119. +    
  34120. +    sum += (st[0] * coeff[0]);
  34121. +    sum += (st[-1] * coeff[1]);
  34122. +    sum += (st[-2] * coeff[2]);
  34123. +    sum += (st[-3] * coeff[3]);
  34124. +    sum += (st[-4] * coeff[4]);
  34125. +    sum += (st[-5] * coeff[5]);
  34126. +    sum += (st[-6] * coeff[6]);
  34127. +    sum += (st[-7] * coeff[7]);
  34128. +
  34129. +    sum >>= 15;
  34130. +    return sum * sum;
  34131. +}
  34132. +
  34133. +extern __inline__ int do_filter_1200_u8(const unsigned char *buf)
  34134. +{
  34135. +    int sum = convolution8_u8(buf, afsk12_tx_lo_i, SUM_AFSK12_TX_LO_I);
  34136. +    sum += convolution8_u8(buf, afsk12_tx_lo_q, SUM_AFSK12_TX_LO_Q);
  34137. +    sum -= convolution8_u8(buf, afsk12_tx_hi_i, SUM_AFSK12_TX_HI_I);
  34138. +    sum -= convolution8_u8(buf, afsk12_tx_hi_q, SUM_AFSK12_TX_HI_Q);
  34139. +    return sum;
  34140. +}
  34141. +
  34142. +extern __inline__ int do_filter_1200_s16(const short *buf)
  34143. +{
  34144. +    int sum = convolution8_s16(buf, afsk12_tx_lo_i, SUM_AFSK12_TX_LO_I);
  34145. +    sum += convolution8_s16(buf, afsk12_tx_lo_q, SUM_AFSK12_TX_LO_Q);
  34146. +    sum -= convolution8_s16(buf, afsk12_tx_hi_i, SUM_AFSK12_TX_HI_I);
  34147. +    sum -= convolution8_s16(buf, afsk12_tx_hi_q, SUM_AFSK12_TX_HI_Q);
  34148. +    return sum;
  34149. +}
  34150. +
  34151. +/* --------------------------------------------------------------------- */
  34152. +
  34153. +static const int pll_corr[2] = { -0x1000, 0x1000 };
  34154. +
  34155. +static void demodulator_1200_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
  34156. +{
  34157. +    struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
  34158. +    int j;
  34159. +    int sum;
  34160. +    unsigned char newsample;
  34161. +
  34162. +    for (; buflen > 0; buflen--, buf++) {
  34163. +        sum = do_filter_1200_u8(buf);
  34164. +        st->dcd_shreg <<= 1;
  34165. +        st->bit_pll += 0x2000;
  34166. +        newsample = (sum > 0);
  34167. +        if (st->last_sample ^ newsample) {
  34168. +            st->last_sample = newsample;
  34169. +            st->dcd_shreg |= 1;
  34170. +            st->bit_pll += pll_corr
  34171. +                [st->bit_pll < 0x9000];
  34172. +            j = 4 * hweight8(st->dcd_shreg & 0x38)
  34173. +                - hweight16(st->dcd_shreg & 0x7c0);
  34174. +            st->dcd_sum0 += j;
  34175. +        }
  34176. +        hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
  34177. +        if ((--st->dcd_time) <= 0) {
  34178. +            hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 + 
  34179. +                           st->dcd_sum1 + 
  34180. +                           st->dcd_sum2) < 0);
  34181. +            st->dcd_sum2 = st->dcd_sum1;
  34182. +            st->dcd_sum1 = st->dcd_sum0;
  34183. +            st->dcd_sum0 = 2; /* slight bias */
  34184. +            st->dcd_time = 120;
  34185. +        }
  34186. +        if (st->bit_pll >= 0x10000) {
  34187. +            st->bit_pll &= 0xffff;
  34188. +            st->shreg >>= 1;
  34189. +            st->shreg |= (!(st->last_rxbit ^
  34190. +                    st->last_sample)) << 16;
  34191. +            st->last_rxbit = st->last_sample;
  34192. +            diag_trigger(sm);
  34193. +            if (st->shreg & 1) {
  34194. +                hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
  34195. +                st->shreg = 0x10000;
  34196. +            }
  34197. +        }
  34198. +        diag_add(sm, (((int)*buf)-0x80) << 8, sum);
  34199. +    }
  34200. +}
  34201. +
  34202. +/* --------------------------------------------------------------------- */
  34203. +
  34204. +static void demodulator_1200_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
  34205. +{
  34206. +    struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
  34207. +    int j;
  34208. +    int sum;
  34209. +    unsigned char newsample;
  34210. +
  34211. +    for (; buflen > 0; buflen--, buf++) {
  34212. +        sum = do_filter_1200_s16(buf);
  34213. +        st->dcd_shreg <<= 1;
  34214. +        st->bit_pll += 0x2000;
  34215. +        newsample = (sum > 0);
  34216. +        if (st->last_sample ^ newsample) {
  34217. +            st->last_sample = newsample;
  34218. +            st->dcd_shreg |= 1;
  34219. +            st->bit_pll += pll_corr
  34220. +                [st->bit_pll < 0x9000];
  34221. +            j = 4 * hweight8(st->dcd_shreg & 0x38)
  34222. +                - hweight16(st->dcd_shreg & 0x7c0);
  34223. +            st->dcd_sum0 += j;
  34224. +        }
  34225. +        hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
  34226. +        if ((--st->dcd_time) <= 0) {
  34227. +            hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 + 
  34228. +                           st->dcd_sum1 + 
  34229. +                           st->dcd_sum2) < 0);
  34230. +            st->dcd_sum2 = st->dcd_sum1;
  34231. +            st->dcd_sum1 = st->dcd_sum0;
  34232. +            st->dcd_sum0 = 2; /* slight bias */
  34233. +            st->dcd_time = 120;
  34234. +        }
  34235. +        if (st->bit_pll >= 0x10000) {
  34236. +            st->bit_pll &= 0xffff;
  34237. +            st->shreg >>= 1;
  34238. +            st->shreg |= (!(st->last_rxbit ^
  34239. +                    st->last_sample)) << 16;
  34240. +            st->last_rxbit = st->last_sample;
  34241. +            diag_trigger(sm);
  34242. +            if (st->shreg & 1) {
  34243. +                hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
  34244. +                st->shreg = 0x10000;
  34245. +            }
  34246. +        }
  34247. +        diag_add(sm, *buf, sum);
  34248. +    }
  34249. +}
  34250. +
  34251. +/* --------------------------------------------------------------------- */
  34252. +
  34253. +static void demod_init_1200(struct sm_state *sm)
  34254. +{
  34255. +    struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
  34256. +
  34257. +           st->dcd_time = 120;
  34258. +    st->dcd_sum0 = 2;    
  34259. +}
  34260. +
  34261. +/* --------------------------------------------------------------------- */
  34262. +
  34263. +const struct modem_tx_info sm_afsk1200_tx = {
  34264. +    "afsk1200", sizeof(struct mod_state_afsk12), 
  34265. +    AFSK12_SAMPLE_RATE, 1200, modulator_1200_u8, modulator_1200_s16, NULL
  34266. +};
  34267. +
  34268. +const struct modem_rx_info sm_afsk1200_rx = {
  34269. +    "afsk1200", sizeof(struct demod_state_afsk12), 
  34270. +    AFSK12_SAMPLE_RATE, 1200, 8, AFSK12_SAMPLE_RATE/1200, 
  34271. +    demodulator_1200_u8, demodulator_1200_s16, demod_init_1200
  34272. +};
  34273. +
  34274. +/* --------------------------------------------------------------------- */
  34275. diff -u --recursive --new-file v2.0.34/linux/drivers/net/soundmodem/sm_afsk2400_7.c linux/drivers/net/soundmodem/sm_afsk2400_7.c
  34276. --- v2.0.34/linux/drivers/net/soundmodem/sm_afsk2400_7.c    Wed Dec 31 16:00:00 1969
  34277. +++ linux/drivers/net/soundmodem/sm_afsk2400_7.c    Mon Jul 13 13:47:31 1998
  34278. @@ -0,0 +1,296 @@
  34279. +/*****************************************************************************/
  34280. +
  34281. +/*
  34282. + *    sm_afsk2400_7.c  -- soundcard radio modem driver, 2400 baud AFSK modem
  34283. + *
  34284. + *    Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
  34285. + *
  34286. + *    This program is free software; you can redistribute it and/or modify
  34287. + *    it under the terms of the GNU General Public License as published by
  34288. + *    the Free Software Foundation; either version 2 of the License, or
  34289. + *    (at your option) any later version.
  34290. + *
  34291. + *    This program is distributed in the hope that it will be useful,
  34292. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  34293. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  34294. + *    GNU General Public License for more details.
  34295. + *
  34296. + *    You should have received a copy of the GNU General Public License
  34297. + *    along with this program; if not, write to the Free Software
  34298. + *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  34299. + *
  34300. + *  Please note that the GPL allows you to use the driver, NOT the radio.
  34301. + *  In order to use the radio, you need a license from the communications
  34302. + *  authority of your country.
  34303. + *
  34304. + */
  34305. +
  34306. +/*
  34307. + * This driver is intended to be compatible with TCM3105 modems
  34308. + * overclocked to 7.3728MHz. The mark and space frequencies therefore
  34309. + * lie at 3658 and 1996 Hz.
  34310. + * Note that I do _not_ recommend the building of such links, I provide
  34311. + * this only for the users who live in the coverage area of such
  34312. + * a "legacy" link.
  34313. + */
  34314. +
  34315. +#include "sm.h"
  34316. +#include "sm_tbl_afsk2400_7.h"
  34317. +
  34318. +/* --------------------------------------------------------------------- */
  34319. +
  34320. +struct demod_state_afsk24 {
  34321. +    unsigned int shreg;
  34322. +    unsigned int bit_pll;
  34323. +    unsigned char last_sample;
  34324. +    unsigned int dcd_shreg;
  34325. +    int dcd_sum0, dcd_sum1, dcd_sum2;
  34326. +    unsigned int dcd_time;
  34327. +    unsigned char last_rxbit;
  34328. +};
  34329. +
  34330. +struct mod_state_afsk24 {
  34331. +    unsigned int shreg;
  34332. +    unsigned char tx_bit;
  34333. +    unsigned int bit_pll;
  34334. +    unsigned int tx_seq;
  34335. +    unsigned int phinc;
  34336. +};
  34337. +
  34338. +/* --------------------------------------------------------------------- */
  34339. +
  34340. +static const int dds_inc[2] = { AFSK24_TX_FREQ_LO*0x10000/AFSK24_SAMPLERATE,
  34341. +                AFSK24_TX_FREQ_HI*0x10000/AFSK24_SAMPLERATE };
  34342. +
  34343. +static void modulator_2400_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
  34344. +{
  34345. +    struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
  34346. +
  34347. +    for (; buflen > 0; buflen--, buf++) {
  34348. +        if (st->tx_seq < 0x5555) {
  34349. +            if (st->shreg <= 1)
  34350. +                st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
  34351. +            st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
  34352. +            st->shreg >>= 1;
  34353. +            st->phinc = dds_inc[st->tx_bit & 1];
  34354. +        }
  34355. +        st->tx_seq += 0x5555;
  34356. +        st->tx_seq &= 0xffff;
  34357. +        *buf = OFFSCOS(st->bit_pll);
  34358. +        st->bit_pll += st->phinc;
  34359. +    }
  34360. +}
  34361. +
  34362. +/* --------------------------------------------------------------------- */
  34363. +
  34364. +static void modulator_2400_s16(struct sm_state *sm, short *buf, unsigned int buflen)
  34365. +{
  34366. +    struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
  34367. +
  34368. +    for (; buflen > 0; buflen--, buf++) {
  34369. +        if (st->tx_seq < 0x5555) {
  34370. +            if (st->shreg <= 1)
  34371. +                st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
  34372. +            st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
  34373. +            st->shreg >>= 1;
  34374. +            st->phinc = dds_inc[st->tx_bit & 1];
  34375. +        }
  34376. +        st->tx_seq += 0x5555;
  34377. +        st->tx_seq &= 0xffff;
  34378. +        *buf = COS(st->bit_pll);
  34379. +        st->bit_pll += st->phinc;
  34380. +    }
  34381. +}
  34382. +
  34383. +/* --------------------------------------------------------------------- */
  34384. +
  34385. +extern __inline__ int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
  34386. +{
  34387. +    int sum = -0x80 * csum;
  34388. +    
  34389. +    sum += (st[0] * coeff[0]);
  34390. +    sum += (st[-1] * coeff[1]);
  34391. +    sum += (st[-2] * coeff[2]);
  34392. +    sum += (st[-3] * coeff[3]);
  34393. +    sum += (st[-4] * coeff[4]);
  34394. +    sum += (st[-5] * coeff[5]);
  34395. +    sum += (st[-6] * coeff[6]);
  34396. +    sum += (st[-7] * coeff[7]);
  34397. +    sum += (st[-8] * coeff[8]);
  34398. +    sum += (st[-9] * coeff[9]);
  34399. +    sum += (st[-10] * coeff[10]);
  34400. +    sum += (st[-11] * coeff[11]);
  34401. +    sum += (st[-12] * coeff[12]);
  34402. +    sum += (st[-13] * coeff[13]);
  34403. +
  34404. +    sum >>= 7;
  34405. +    return sum * sum;
  34406. +}
  34407. +
  34408. +extern __inline__ int convolution14_s16(const short *st, const int *coeff, int csum)
  34409. +{
  34410. +    int sum = 0;
  34411. +    
  34412. +    sum += (st[0] * coeff[0]);
  34413. +    sum += (st[-1] * coeff[1]);
  34414. +    sum += (st[-2] * coeff[2]);
  34415. +    sum += (st[-3] * coeff[3]);
  34416. +    sum += (st[-4] * coeff[4]);
  34417. +    sum += (st[-5] * coeff[5]);
  34418. +    sum += (st[-6] * coeff[6]);
  34419. +    sum += (st[-7] * coeff[7]);
  34420. +    sum += (st[-8] * coeff[8]);
  34421. +    sum += (st[-9] * coeff[9]);
  34422. +    sum += (st[-10] * coeff[10]);
  34423. +    sum += (st[-11] * coeff[11]);
  34424. +    sum += (st[-12] * coeff[12]);
  34425. +    sum += (st[-13] * coeff[13]);
  34426. +
  34427. +    sum >>= 15;
  34428. +    return sum * sum;
  34429. +}
  34430. +
  34431. +extern __inline__ int do_filter_2400_u8(const unsigned char *buf)
  34432. +{
  34433. +    int sum = convolution14_u8(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
  34434. +    sum += convolution14_u8(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
  34435. +    sum -= convolution14_u8(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
  34436. +    sum -= convolution14_u8(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
  34437. +    return sum;
  34438. +}
  34439. +
  34440. +extern __inline__ int do_filter_2400_s16(const short *buf)
  34441. +{
  34442. +    int sum = convolution14_s16(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
  34443. +    sum += convolution14_s16(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
  34444. +    sum -= convolution14_s16(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
  34445. +    sum -= convolution14_s16(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
  34446. +    return sum;
  34447. +}
  34448. +
  34449. +/* --------------------------------------------------------------------- */
  34450. +
  34451. +static void demodulator_2400_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
  34452. +{
  34453. +    struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
  34454. +    int j;
  34455. +    int sum;
  34456. +    unsigned char newsample;
  34457. +
  34458. +    for (; buflen > 0; buflen--, buf++) {
  34459. +        sum = do_filter_2400_u8(buf);
  34460. +        st->dcd_shreg <<= 1;
  34461. +        st->bit_pll += AFSK24_BITPLL_INC;
  34462. +        newsample = (sum > 0);
  34463. +        if (st->last_sample ^ newsample) {
  34464. +            st->last_sample = newsample;
  34465. +            st->dcd_shreg |= 1;
  34466. +            if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
  34467. +                st->bit_pll += AFSK24_BITPLL_INC/2;
  34468. +            else
  34469. +                st->bit_pll -= AFSK24_BITPLL_INC/2;
  34470. +            j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
  34471. +                - hweight16(st->dcd_shreg & 0x1e0);
  34472. +            st->dcd_sum0 += j;
  34473. +        }
  34474. +        hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
  34475. +        if ((--st->dcd_time) <= 0) {
  34476. +            hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 + 
  34477. +                           st->dcd_sum1 + 
  34478. +                           st->dcd_sum2) < 0);
  34479. +            st->dcd_sum2 = st->dcd_sum1;
  34480. +            st->dcd_sum1 = st->dcd_sum0;
  34481. +            st->dcd_sum0 = 2; /* slight bias */
  34482. +            st->dcd_time = 120;
  34483. +        }
  34484. +        if (st->bit_pll >= 0x10000) {
  34485. +            st->bit_pll &= 0xffff;
  34486. +            st->shreg >>= 1;
  34487. +            st->shreg |= (!(st->last_rxbit ^
  34488. +                    st->last_sample)) << 16;
  34489. +            st->last_rxbit = st->last_sample;
  34490. +            diag_trigger(sm);
  34491. +            if (st->shreg & 1) {
  34492. +                hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
  34493. +                st->shreg = 0x10000;
  34494. +            }
  34495. +        }
  34496. +        diag_add(sm, (((int)*buf)-0x80) << 8, sum);
  34497. +    }
  34498. +}
  34499. +
  34500. +/* --------------------------------------------------------------------- */
  34501. +
  34502. +static void demodulator_2400_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
  34503. +{
  34504. +    struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
  34505. +    int j;
  34506. +    int sum;
  34507. +    unsigned char newsample;
  34508. +
  34509. +    for (; buflen > 0; buflen--, buf++) {
  34510. +        sum = do_filter_2400_s16(buf);
  34511. +        st->dcd_shreg <<= 1;
  34512. +        st->bit_pll += AFSK24_BITPLL_INC;
  34513. +        newsample = (sum > 0);
  34514. +        if (st->last_sample ^ newsample) {
  34515. +            st->last_sample = newsample;
  34516. +            st->dcd_shreg |= 1;
  34517. +            if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
  34518. +                st->bit_pll += AFSK24_BITPLL_INC/2;
  34519. +            else
  34520. +                st->bit_pll -= AFSK24_BITPLL_INC/2;
  34521. +            j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
  34522. +                - hweight16(st->dcd_shreg & 0x1e0);
  34523. +            st->dcd_sum0 += j;
  34524. +        }
  34525. +        hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
  34526. +        if ((--st->dcd_time) <= 0) {
  34527. +            hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 + 
  34528. +                           st->dcd_sum1 + 
  34529. +                           st->dcd_sum2) < 0);
  34530. +            st->dcd_sum2 = st->dcd_sum1;
  34531. +            st->dcd_sum1 = st->dcd_sum0;
  34532. +            st->dcd_sum0 = 2; /* slight bias */
  34533. +            st->dcd_time = 120;
  34534. +        }
  34535. +        if (st->bit_pll >= 0x10000) {
  34536. +            st->bit_pll &= 0xffff;
  34537. +            st->shreg >>= 1;
  34538. +            st->shreg |= (!(st->last_rxbit ^
  34539. +                    st->last_sample)) << 16;
  34540. +            st->last_rxbit = st->last_sample;
  34541. +            diag_trigger(sm);
  34542. +            if (st->shreg & 1) {
  34543. +                hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
  34544. +                st->shreg = 0x10000;
  34545. +            }
  34546. +        }
  34547. +        diag_add(sm, *buf, sum);
  34548. +    }
  34549. +}
  34550. +
  34551. +/* --------------------------------------------------------------------- */
  34552. +
  34553. +static void demod_init_2400(struct sm_state *sm)
  34554. +{
  34555. +    struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
  34556. +
  34557. +           st->dcd_time = 120;
  34558. +    st->dcd_sum0 = 2;
  34559. +}
  34560. +
  34561. +/* --------------------------------------------------------------------- */
  34562. +
  34563. +const struct modem_tx_info sm_afsk2400_7_tx = {
  34564. +    "afsk2400_7", sizeof(struct mod_state_afsk24), AFSK24_SAMPLERATE, 2400, 
  34565. +    modulator_2400_u8, modulator_2400_s16, NULL
  34566. +};
  34567. +
  34568. +const struct modem_rx_info sm_afsk2400_7_rx = {
  34569. +    "afsk2400_7", sizeof(struct demod_state_afsk24), 
  34570. +    AFSK24_SAMPLERATE, 2400, 14, AFSK24_SAMPLERATE/2400, 
  34571. +    demodulator_2400_u8, demodulator_2400_s16, demod_init_2400
  34572. +};
  34573. +
  34574. +/* --------------------------------------------------------------------- */
  34575. diff -u --recursive --new-file v2.0.34/linux/drivers/net/soundmodem/sm_afsk2400_8.c linux/drivers/net/soundmodem/sm_afsk2400_8.c
  34576. --- v2.0.34/linux/drivers/net/soundmodem/sm_afsk2400_8.c    Wed Dec 31 16:00:00 1969
  34577. +++ linux/drivers/net/soundmodem/sm_afsk2400_8.c    Mon Jul 13 13:47:31 1998
  34578. @@ -0,0 +1,296 @@
  34579. +/*****************************************************************************/
  34580. +
  34581. +/*
  34582. + *    sm_afsk2400_8.c  -- soundcard radio modem driver, 2400 baud AFSK modem
  34583. + *
  34584. + *    Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
  34585. + *
  34586. + *    This program is free software; you can redistribute it and/or modify
  34587. + *    it under the terms of the GNU General Public License as published by
  34588. + *    the Free Software Foundation; either version 2 of the License, or
  34589. + *    (at your option) any later version.
  34590. + *
  34591. + *    This program is distributed in the hope that it will be useful,
  34592. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  34593. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  34594. + *    GNU General Public License for more details.
  34595. + *
  34596. + *    You should have received a copy of the GNU General Public License
  34597. + *    along with this program; if not, write to the Free Software
  34598. + *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  34599. + *
  34600. + *  Please note that the GPL allows you to use the driver, NOT the radio.
  34601. + *  In order to use the radio, you need a license from the communications
  34602. + *  authority of your country.
  34603. + *
  34604. + */
  34605. +
  34606. +/*
  34607. + * This driver is intended to be compatible with TCM3105 modems
  34608. + * overclocked to 8MHz. The mark and space frequencies therefore
  34609. + * lie at 3970 and 2165 Hz.
  34610. + * Note that I do _not_ recommend the building of such links, I provide
  34611. + * this only for the users who live in the coverage area of such
  34612. + * a "legacy" link.
  34613. + */
  34614. +
  34615. +#include "sm.h"
  34616. +#include "sm_tbl_afsk2400_8.h"
  34617. +
  34618. +/* --------------------------------------------------------------------- */
  34619. +
  34620. +struct demod_state_afsk24 {
  34621. +    unsigned int shreg;
  34622. +    unsigned int bit_pll;
  34623. +    unsigned char last_sample;
  34624. +    unsigned int dcd_shreg;
  34625. +    int dcd_sum0, dcd_sum1, dcd_sum2;
  34626. +    unsigned int dcd_time;
  34627. +    unsigned char last_rxbit;
  34628. +};
  34629. +
  34630. +struct mod_state_afsk24 {
  34631. +    unsigned int shreg;
  34632. +    unsigned char tx_bit;
  34633. +    unsigned int bit_pll;
  34634. +    unsigned int tx_seq;
  34635. +    unsigned int phinc;
  34636. +};
  34637. +
  34638. +/* --------------------------------------------------------------------- */
  34639. +
  34640. +static const int dds_inc[2] = { AFSK24_TX_FREQ_LO*0x10000/AFSK24_SAMPLERATE,
  34641. +                AFSK24_TX_FREQ_HI*0x10000/AFSK24_SAMPLERATE };
  34642. +
  34643. +static void modulator_2400_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
  34644. +{
  34645. +    struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
  34646. +
  34647. +    for (; buflen > 0; buflen--, buf++) {
  34648. +        if (st->tx_seq < 0x5555) {
  34649. +            if (st->shreg <= 1)
  34650. +                st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
  34651. +            st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
  34652. +            st->shreg >>= 1;
  34653. +            st->phinc = dds_inc[st->tx_bit & 1];
  34654. +        }
  34655. +        st->tx_seq += 0x5555;
  34656. +        st->tx_seq &= 0xffff;
  34657. +        *buf = OFFSCOS(st->bit_pll);
  34658. +        st->bit_pll += st->phinc;
  34659. +    }
  34660. +}
  34661. +
  34662. +/* --------------------------------------------------------------------- */
  34663. +
  34664. +static void modulator_2400_s16(struct sm_state *sm, short *buf, unsigned int buflen)
  34665. +{
  34666. +    struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
  34667. +
  34668. +    for (; buflen > 0; buflen--, buf++) {
  34669. +        if (st->tx_seq < 0x5555) {
  34670. +            if (st->shreg <= 1)
  34671. +                st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
  34672. +            st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
  34673. +            st->shreg >>= 1;
  34674. +            st->phinc = dds_inc[st->tx_bit & 1];
  34675. +        }
  34676. +        st->tx_seq += 0x5555;
  34677. +        st->tx_seq &= 0xffff;
  34678. +        *buf = COS(st->bit_pll);
  34679. +        st->bit_pll += st->phinc;
  34680. +    }
  34681. +}
  34682. +
  34683. +/* --------------------------------------------------------------------- */
  34684. +
  34685. +extern __inline__ int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
  34686. +{
  34687. +    int sum = -0x80 * csum;
  34688. +    
  34689. +    sum += (st[0] * coeff[0]);
  34690. +    sum += (st[-1] * coeff[1]);
  34691. +    sum += (st[-2] * coeff[2]);
  34692. +    sum += (st[-3] * coeff[3]);
  34693. +    sum += (st[-4] * coeff[4]);
  34694. +    sum += (st[-5] * coeff[5]);
  34695. +    sum += (st[-6] * coeff[6]);
  34696. +    sum += (st[-7] * coeff[7]);
  34697. +    sum += (st[-8] * coeff[8]);
  34698. +    sum += (st[-9] * coeff[9]);
  34699. +    sum += (st[-10] * coeff[10]);
  34700. +    sum += (st[-11] * coeff[11]);
  34701. +    sum += (st[-12] * coeff[12]);
  34702. +    sum += (st[-13] * coeff[13]);
  34703. +
  34704. +    sum >>= 7;
  34705. +    return sum * sum;
  34706. +}
  34707. +
  34708. +extern __inline__ int convolution14_s16(const short *st, const int *coeff, int csum)
  34709. +{
  34710. +    int sum = 0;
  34711. +    
  34712. +    sum += (st[0] * coeff[0]);
  34713. +    sum += (st[-1] * coeff[1]);
  34714. +    sum += (st[-2] * coeff[2]);
  34715. +    sum += (st[-3] * coeff[3]);
  34716. +    sum += (st[-4] * coeff[4]);
  34717. +    sum += (st[-5] * coeff[5]);
  34718. +    sum += (st[-6] * coeff[6]);
  34719. +    sum += (st[-7] * coeff[7]);
  34720. +    sum += (st[-8] * coeff[8]);
  34721. +    sum += (st[-9] * coef