i2lib.c 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217
  1. /*******************************************************************************
  2. *
  3. * (c) 1999 by Computone Corporation
  4. *
  5. ********************************************************************************
  6. *
  7. *
  8. * PACKAGE: Linux tty Device Driver for IntelliPort family of multiport
  9. * serial I/O controllers.
  10. *
  11. * DESCRIPTION: High-level interface code for the device driver. Uses the
  12. * Extremely Low Level Interface Support (i2ellis.c). Provides an
  13. * interface to the standard loadware, to support drivers or
  14. * application code. (This is included source code, not a separate
  15. * compilation module.)
  16. *
  17. *******************************************************************************/
  18. //------------------------------------------------------------------------------
  19. // Note on Strategy:
  20. // Once the board has been initialized, it will interrupt us when:
  21. // 1) It has something in the fifo for us to read (incoming data, flow control
  22. // packets, or whatever).
  23. // 2) It has stripped whatever we have sent last time in the FIFO (and
  24. // consequently is ready for more).
  25. //
  26. // Note also that the buffer sizes declared in i2lib.h are VERY SMALL. This
  27. // worsens performance considerably, but is done so that a great many channels
  28. // might use only a little memory.
  29. //------------------------------------------------------------------------------
  30. //------------------------------------------------------------------------------
  31. // Revision History:
  32. //
  33. // 0.00 - 4/16/91 --- First Draft
  34. // 0.01 - 4/29/91 --- 1st beta release
  35. // 0.02 - 6/14/91 --- Changes to allow small model compilation
  36. // 0.03 - 6/17/91 MAG Break reporting protected from interrupts routines with
  37. // in-line asm added for moving data to/from ring buffers,
  38. // replacing a variety of methods used previously.
  39. // 0.04 - 6/21/91 MAG Initial flow-control packets not queued until
  40. // i2_enable_interrupts time. Former versions would enqueue
  41. // them at i2_init_channel time, before we knew how many
  42. // channels were supposed to exist!
  43. // 0.05 - 10/12/91 MAG Major changes: works through the ellis.c routines now;
  44. // supports new 16-bit protocol and expandable boards.
  45. // - 10/24/91 MAG Most changes in place and stable.
  46. // 0.06 - 2/20/92 MAG Format of CMD_HOTACK corrected: the command takes no
  47. // argument.
  48. // 0.07 -- 3/11/92 MAG Support added to store special packet types at interrupt
  49. // level (mostly responses to specific commands.)
  50. // 0.08 -- 3/30/92 MAG Support added for STAT_MODEM packet
  51. // 0.09 -- 6/24/93 MAG i2Link... needed to update number of boards BEFORE
  52. // turning on the interrupt.
  53. // 0.10 -- 6/25/93 MAG To avoid gruesome death from a bad board, we sanity check
  54. // some incoming.
  55. //
  56. // 1.1 - 12/25/96 AKM Linux version.
  57. // - 10/09/98 DMC Revised Linux version.
  58. //------------------------------------------------------------------------------
  59. //************
  60. //* Includes *
  61. //************
  62. #include <linux/sched.h>
  63. #include "i2lib.h"
  64. //***********************
  65. //* Function Prototypes *
  66. //***********************
  67. static void i2QueueNeeds(i2eBordStrPtr, i2ChanStrPtr, int);
  68. static i2ChanStrPtr i2DeQueueNeeds(i2eBordStrPtr, int );
  69. static void i2StripFifo(i2eBordStrPtr);
  70. static void i2StuffFifoBypass(i2eBordStrPtr);
  71. static void i2StuffFifoFlow(i2eBordStrPtr);
  72. static void i2StuffFifoInline(i2eBordStrPtr);
  73. static int i2RetryFlushOutput(i2ChanStrPtr);
  74. // Not a documented part of the library routines (careful...) but the Diagnostic
  75. // i2diag.c finds them useful to help the throughput in certain limited
  76. // single-threaded operations.
  77. static void iiSendPendingMail(i2eBordStrPtr);
  78. static void serviceOutgoingFifo(i2eBordStrPtr);
  79. // Functions defined in ip2.c as part of interrupt handling
  80. static void do_input(void *);
  81. static void do_status(void *);
  82. //***************
  83. //* Debug Data *
  84. //***************
  85. #ifdef DEBUG_FIFO
  86. unsigned char DBGBuf[0x4000];
  87. unsigned short I = 0;
  88. static void
  89. WriteDBGBuf(char *s, unsigned char *src, unsigned short n )
  90. {
  91. char *p = src;
  92. // XXX: We need a spin lock here if we ever use this again
  93. while (*s) { // copy label
  94. DBGBuf[I] = *s++;
  95. I = I++ & 0x3fff;
  96. }
  97. while (n--) { // copy data
  98. DBGBuf[I] = *p++;
  99. I = I++ & 0x3fff;
  100. }
  101. }
  102. static void
  103. fatality(i2eBordStrPtr pB )
  104. {
  105. int i;
  106. for (i=0;i<sizeof(DBGBuf);i++) {
  107. if ((i%16) == 0)
  108. printk("\n%4x:",i);
  109. printk("%02x ",DBGBuf[i]);
  110. }
  111. printk("\n");
  112. for (i=0;i<sizeof(DBGBuf);i++) {
  113. if ((i%16) == 0)
  114. printk("\n%4x:",i);
  115. if (DBGBuf[i] >= ' ' && DBGBuf[i] <= '~') {
  116. printk(" %c ",DBGBuf[i]);
  117. } else {
  118. printk(" . ");
  119. }
  120. }
  121. printk("\n");
  122. printk("Last index %x\n",I);
  123. }
  124. #endif /* DEBUG_FIFO */
  125. //********
  126. //* Code *
  127. //********
  128. static inline int
  129. i2Validate ( i2ChanStrPtr pCh )
  130. {
  131. //ip2trace(pCh->port_index, ITRC_VERIFY,ITRC_ENTER,2,pCh->validity,
  132. // (CHANNEL_MAGIC | CHANNEL_SUPPORT));
  133. return ((pCh->validity & (CHANNEL_MAGIC_BITS | CHANNEL_SUPPORT))
  134. == (CHANNEL_MAGIC | CHANNEL_SUPPORT));
  135. }
  136. //******************************************************************************
  137. // Function: iiSendPendingMail(pB)
  138. // Parameters: Pointer to a board structure
  139. // Returns: Nothing
  140. //
  141. // Description:
  142. // If any outgoing mail bits are set and there is outgoing mailbox is empty,
  143. // send the mail and clear the bits.
  144. //******************************************************************************
  145. static inline void
  146. iiSendPendingMail(i2eBordStrPtr pB)
  147. {
  148. if (pB->i2eOutMailWaiting && (!pB->i2eWaitingForEmptyFifo) )
  149. {
  150. if (iiTrySendMail(pB, pB->i2eOutMailWaiting))
  151. {
  152. /* If we were already waiting for fifo to empty,
  153. * or just sent MB_OUT_STUFFED, then we are
  154. * still waiting for it to empty, until we should
  155. * receive an MB_IN_STRIPPED from the board.
  156. */
  157. pB->i2eWaitingForEmptyFifo |=
  158. (pB->i2eOutMailWaiting & MB_OUT_STUFFED);
  159. pB->i2eOutMailWaiting = 0;
  160. pB->SendPendingRetry = 0;
  161. } else {
  162. /* The only time we hit this area is when "iiTrySendMail" has
  163. failed. That only occurs when the outbound mailbox is
  164. still busy with the last message. We take a short breather
  165. to let the board catch up with itself and then try again.
  166. 16 Retries is the limit - then we got a borked board.
  167. /\/\|=mhw=|\/\/ */
  168. if( ++pB->SendPendingRetry < 16 ) {
  169. init_timer( &(pB->SendPendingTimer) );
  170. pB->SendPendingTimer.expires = jiffies + 1;
  171. pB->SendPendingTimer.function = (void*)(unsigned long)iiSendPendingMail;
  172. pB->SendPendingTimer.data = (unsigned long)pB;
  173. add_timer( &(pB->SendPendingTimer) );
  174. } else {
  175. printk( KERN_ERR "IP2: iiSendPendingMail unable to queue outbound mail\n" );
  176. }
  177. }
  178. }
  179. }
  180. //******************************************************************************
  181. // Function: i2InitChannels(pB, nChannels, pCh)
  182. // Parameters: Pointer to Ellis Board structure
  183. // Number of channels to initialize
  184. // Pointer to first element in an array of channel structures
  185. // Returns: Success or failure
  186. //
  187. // Description:
  188. //
  189. // This function patches pointers, back-pointers, and initializes all the
  190. // elements in the channel structure array.
  191. //
  192. // This should be run after the board structure is initialized, through having
  193. // loaded the standard loadware (otherwise it complains).
  194. //
  195. // In any case, it must be done before any serious work begins initializing the
  196. // irq's or sending commands...
  197. //
  198. //******************************************************************************
  199. static int
  200. i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh)
  201. {
  202. int index, stuffIndex;
  203. i2ChanStrPtr *ppCh;
  204. if (pB->i2eValid != I2E_MAGIC) {
  205. COMPLETE(pB, I2EE_BADMAGIC);
  206. }
  207. if (pB->i2eState != II_STATE_STDLOADED) {
  208. COMPLETE(pB, I2EE_BADSTATE);
  209. }
  210. LOCK_INIT(&pB->read_fifo_spinlock);
  211. LOCK_INIT(&pB->write_fifo_spinlock);
  212. LOCK_INIT(&pB->Dbuf_spinlock);
  213. LOCK_INIT(&pB->Bbuf_spinlock);
  214. LOCK_INIT(&pB->Fbuf_spinlock);
  215. // NO LOCK needed yet - this is init
  216. pB->i2eChannelPtr = pCh;
  217. pB->i2eChannelCnt = nChannels;
  218. pB->i2Fbuf_strip = pB->i2Fbuf_stuff = 0;
  219. pB->i2Dbuf_strip = pB->i2Dbuf_stuff = 0;
  220. pB->i2Bbuf_strip = pB->i2Bbuf_stuff = 0;
  221. pB->SendPendingRetry = 0;
  222. memset ( pCh, 0, sizeof (i2ChanStr) * nChannels );
  223. for (index = stuffIndex = 0, ppCh = (i2ChanStrPtr *)(pB->i2Fbuf);
  224. nChannels && index < ABS_MOST_PORTS;
  225. index++)
  226. {
  227. if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) {
  228. continue;
  229. }
  230. LOCK_INIT(&pCh->Ibuf_spinlock);
  231. LOCK_INIT(&pCh->Obuf_spinlock);
  232. LOCK_INIT(&pCh->Cbuf_spinlock);
  233. LOCK_INIT(&pCh->Pbuf_spinlock);
  234. // NO LOCK needed yet - this is init
  235. // Set up validity flag according to support level
  236. if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) {
  237. pCh->validity = CHANNEL_MAGIC | CHANNEL_SUPPORT;
  238. } else {
  239. pCh->validity = CHANNEL_MAGIC;
  240. }
  241. pCh->pMyBord = pB; /* Back-pointer */
  242. // Prepare an outgoing flow-control packet to send as soon as the chance
  243. // occurs.
  244. if ( pCh->validity & CHANNEL_SUPPORT ) {
  245. pCh->infl.hd.i2sChannel = index;
  246. pCh->infl.hd.i2sCount = 5;
  247. pCh->infl.hd.i2sType = PTYPE_BYPASS;
  248. pCh->infl.fcmd = 37;
  249. pCh->infl.asof = 0;
  250. pCh->infl.room = IBUF_SIZE - 1;
  251. pCh->whenSendFlow = (IBUF_SIZE/5)*4; // when 80% full
  252. // The following is similar to calling i2QueueNeeds, except that this
  253. // is done in longhand, since we are setting up initial conditions on
  254. // many channels at once.
  255. pCh->channelNeeds = NEED_FLOW; // Since starting from scratch
  256. pCh->sinceLastFlow = 0; // No bytes received since last flow
  257. // control packet was queued
  258. stuffIndex++;
  259. *ppCh++ = pCh; // List this channel as needing
  260. // initial flow control packet sent
  261. }
  262. // Don't allow anything to be sent until the status packets come in from
  263. // the board.
  264. pCh->outfl.asof = 0;
  265. pCh->outfl.room = 0;
  266. // Initialize all the ring buffers
  267. pCh->Ibuf_stuff = pCh->Ibuf_strip = 0;
  268. pCh->Obuf_stuff = pCh->Obuf_strip = 0;
  269. pCh->Cbuf_stuff = pCh->Cbuf_strip = 0;
  270. memset( &pCh->icount, 0, sizeof (struct async_icount) );
  271. pCh->hotKeyIn = HOT_CLEAR;
  272. pCh->channelOptions = 0;
  273. pCh->bookMarks = 0;
  274. init_waitqueue_head(&pCh->pBookmarkWait);
  275. init_waitqueue_head(&pCh->open_wait);
  276. init_waitqueue_head(&pCh->close_wait);
  277. init_waitqueue_head(&pCh->delta_msr_wait);
  278. // Set base and divisor so default custom rate is 9600
  279. pCh->BaudBase = 921600; // MAX for ST654, changed after we get
  280. pCh->BaudDivisor = 96; // the boxids (UART types) later
  281. pCh->dataSetIn = 0;
  282. pCh->dataSetOut = 0;
  283. pCh->wopen = 0;
  284. pCh->throttled = 0;
  285. pCh->speed = CBR_9600;
  286. pCh->flags = 0;
  287. pCh->ClosingDelay = 5*HZ/10;
  288. pCh->ClosingWaitTime = 30*HZ;
  289. // Initialize task queue objects
  290. INIT_WORK(&pCh->tqueue_input, do_input, pCh);
  291. INIT_WORK(&pCh->tqueue_status, do_status, pCh);
  292. #ifdef IP2DEBUG_TRACE
  293. pCh->trace = ip2trace;
  294. #endif
  295. ++pCh;
  296. --nChannels;
  297. }
  298. // No need to check for wrap here; this is initialization.
  299. pB->i2Fbuf_stuff = stuffIndex;
  300. COMPLETE(pB, I2EE_GOOD);
  301. }
  302. //******************************************************************************
  303. // Function: i2DeQueueNeeds(pB, type)
  304. // Parameters: Pointer to a board structure
  305. // type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW
  306. // Returns:
  307. // Pointer to a channel structure
  308. //
  309. // Description: Returns pointer struct of next channel that needs service of
  310. // the type specified. Otherwise returns a NULL reference.
  311. //
  312. //******************************************************************************
  313. static i2ChanStrPtr
  314. i2DeQueueNeeds(i2eBordStrPtr pB, int type)
  315. {
  316. unsigned short queueIndex;
  317. unsigned long flags;
  318. i2ChanStrPtr pCh = NULL;
  319. switch(type) {
  320. case NEED_INLINE:
  321. WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags);
  322. if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip)
  323. {
  324. queueIndex = pB->i2Dbuf_strip;
  325. pCh = pB->i2Dbuf[queueIndex];
  326. queueIndex++;
  327. if (queueIndex >= CH_QUEUE_SIZE) {
  328. queueIndex = 0;
  329. }
  330. pB->i2Dbuf_strip = queueIndex;
  331. pCh->channelNeeds &= ~NEED_INLINE;
  332. }
  333. WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags);
  334. break;
  335. case NEED_BYPASS:
  336. WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags);
  337. if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip)
  338. {
  339. queueIndex = pB->i2Bbuf_strip;
  340. pCh = pB->i2Bbuf[queueIndex];
  341. queueIndex++;
  342. if (queueIndex >= CH_QUEUE_SIZE) {
  343. queueIndex = 0;
  344. }
  345. pB->i2Bbuf_strip = queueIndex;
  346. pCh->channelNeeds &= ~NEED_BYPASS;
  347. }
  348. WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags);
  349. break;
  350. case NEED_FLOW:
  351. WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags);
  352. if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip)
  353. {
  354. queueIndex = pB->i2Fbuf_strip;
  355. pCh = pB->i2Fbuf[queueIndex];
  356. queueIndex++;
  357. if (queueIndex >= CH_QUEUE_SIZE) {
  358. queueIndex = 0;
  359. }
  360. pB->i2Fbuf_strip = queueIndex;
  361. pCh->channelNeeds &= ~NEED_FLOW;
  362. }
  363. WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags);
  364. break;
  365. default:
  366. printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type);
  367. break;
  368. }
  369. return pCh;
  370. }
  371. //******************************************************************************
  372. // Function: i2QueueNeeds(pB, pCh, type)
  373. // Parameters: Pointer to a board structure
  374. // Pointer to a channel structure
  375. // type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW
  376. // Returns: Nothing
  377. //
  378. // Description:
  379. // For each type of need selected, if the given channel is not already in the
  380. // queue, adds it, and sets the flag indicating it is in the queue.
  381. //******************************************************************************
  382. static void
  383. i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type)
  384. {
  385. unsigned short queueIndex;
  386. unsigned long flags;
  387. // We turn off all the interrupts during this brief process, since the
  388. // interrupt-level code might want to put things on the queue as well.
  389. switch (type) {
  390. case NEED_INLINE:
  391. WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags);
  392. if ( !(pCh->channelNeeds & NEED_INLINE) )
  393. {
  394. pCh->channelNeeds |= NEED_INLINE;
  395. queueIndex = pB->i2Dbuf_stuff;
  396. pB->i2Dbuf[queueIndex++] = pCh;
  397. if (queueIndex >= CH_QUEUE_SIZE)
  398. queueIndex = 0;
  399. pB->i2Dbuf_stuff = queueIndex;
  400. }
  401. WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags);
  402. break;
  403. case NEED_BYPASS:
  404. WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags);
  405. if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS))
  406. {
  407. pCh->channelNeeds |= NEED_BYPASS;
  408. queueIndex = pB->i2Bbuf_stuff;
  409. pB->i2Bbuf[queueIndex++] = pCh;
  410. if (queueIndex >= CH_QUEUE_SIZE)
  411. queueIndex = 0;
  412. pB->i2Bbuf_stuff = queueIndex;
  413. }
  414. WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags);
  415. break;
  416. case NEED_FLOW:
  417. WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags);
  418. if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW))
  419. {
  420. pCh->channelNeeds |= NEED_FLOW;
  421. queueIndex = pB->i2Fbuf_stuff;
  422. pB->i2Fbuf[queueIndex++] = pCh;
  423. if (queueIndex >= CH_QUEUE_SIZE)
  424. queueIndex = 0;
  425. pB->i2Fbuf_stuff = queueIndex;
  426. }
  427. WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags);
  428. break;
  429. case NEED_CREDIT:
  430. pCh->channelNeeds |= NEED_CREDIT;
  431. break;
  432. default:
  433. printk(KERN_ERR "i2QueueNeeds called with bad type:%x\n",type);
  434. break;
  435. }
  436. return;
  437. }
  438. //******************************************************************************
  439. // Function: i2QueueCommands(type, pCh, timeout, nCommands, pCs,...)
  440. // Parameters: type - PTYPE_BYPASS or PTYPE_INLINE
  441. // pointer to the channel structure
  442. // maximum period to wait
  443. // number of commands (n)
  444. // n commands
  445. // Returns: Number of commands sent, or -1 for error
  446. //
  447. // get board lock before calling
  448. //
  449. // Description:
  450. // Queues up some commands to be sent to a channel. To send possibly several
  451. // bypass or inline commands to the given channel. The timeout parameter
  452. // indicates how many HUNDREDTHS OF SECONDS to wait until there is room:
  453. // 0 = return immediately if no room, -ive = wait forever, +ive = number of
  454. // 1/100 seconds to wait. Return values:
  455. // -1 Some kind of nasty error: bad channel structure or invalid arguments.
  456. // 0 No room to send all the commands
  457. // (+) Number of commands sent
  458. //******************************************************************************
  459. static int
  460. i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
  461. cmdSyntaxPtr pCs0,...)
  462. {
  463. int totalsize = 0;
  464. int blocksize;
  465. int lastended;
  466. cmdSyntaxPtr *ppCs;
  467. cmdSyntaxPtr pCs;
  468. int count;
  469. int flag;
  470. i2eBordStrPtr pB;
  471. unsigned short maxBlock;
  472. unsigned short maxBuff;
  473. short bufroom;
  474. unsigned short stuffIndex;
  475. unsigned char *pBuf;
  476. unsigned char *pInsert;
  477. unsigned char *pDest, *pSource;
  478. unsigned short channel;
  479. int cnt;
  480. unsigned long flags = 0;
  481. rwlock_t *lock_var_p = NULL;
  482. // Make sure the channel exists, otherwise do nothing
  483. if ( !i2Validate ( pCh ) ) {
  484. return -1;
  485. }
  486. ip2trace (CHANN, ITRC_QUEUE, ITRC_ENTER, 0 );
  487. pB = pCh->pMyBord;
  488. // Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT
  489. if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == IRQ_UNDEFINED) {
  490. return -2;
  491. }
  492. // If the board has gone fatal, return bad, and also hit the trap routine if
  493. // it exists.
  494. if (pB->i2eFatal) {
  495. if ( pB->i2eFatalTrap ) {
  496. (*(pB)->i2eFatalTrap)(pB);
  497. }
  498. return -3;
  499. }
  500. // Set up some variables, Which buffers are we using? How big are they?
  501. switch(type)
  502. {
  503. case PTYPE_INLINE:
  504. flag = INL;
  505. maxBlock = MAX_OBUF_BLOCK;
  506. maxBuff = OBUF_SIZE;
  507. pBuf = pCh->Obuf;
  508. break;
  509. case PTYPE_BYPASS:
  510. flag = BYP;
  511. maxBlock = MAX_CBUF_BLOCK;
  512. maxBuff = CBUF_SIZE;
  513. pBuf = pCh->Cbuf;
  514. break;
  515. default:
  516. return -4;
  517. }
  518. // Determine the total size required for all the commands
  519. totalsize = blocksize = sizeof(i2CmdHeader);
  520. lastended = 0;
  521. ppCs = &pCs0;
  522. for ( count = nCommands; count; count--, ppCs++)
  523. {
  524. pCs = *ppCs;
  525. cnt = pCs->length;
  526. // Will a new block be needed for this one?
  527. // Two possible reasons: too
  528. // big or previous command has to be at the end of a packet.
  529. if ((blocksize + cnt > maxBlock) || lastended) {
  530. blocksize = sizeof(i2CmdHeader);
  531. totalsize += sizeof(i2CmdHeader);
  532. }
  533. totalsize += cnt;
  534. blocksize += cnt;
  535. // If this command had to end a block, then we will make sure to
  536. // account for it should there be any more blocks.
  537. lastended = pCs->flags & END;
  538. }
  539. for (;;) {
  540. // Make sure any pending flush commands go out before we add more data.
  541. if ( !( pCh->flush_flags && i2RetryFlushOutput( pCh ) ) ) {
  542. // How much room (this time through) ?
  543. switch(type) {
  544. case PTYPE_INLINE:
  545. lock_var_p = &pCh->Obuf_spinlock;
  546. WRITE_LOCK_IRQSAVE(lock_var_p,flags);
  547. stuffIndex = pCh->Obuf_stuff;
  548. bufroom = pCh->Obuf_strip - stuffIndex;
  549. break;
  550. case PTYPE_BYPASS:
  551. lock_var_p = &pCh->Cbuf_spinlock;
  552. WRITE_LOCK_IRQSAVE(lock_var_p,flags);
  553. stuffIndex = pCh->Cbuf_stuff;
  554. bufroom = pCh->Cbuf_strip - stuffIndex;
  555. break;
  556. default:
  557. return -5;
  558. }
  559. if (--bufroom < 0) {
  560. bufroom += maxBuff;
  561. }
  562. ip2trace (CHANN, ITRC_QUEUE, 2, 1, bufroom );
  563. // Check for overflow
  564. if (totalsize <= bufroom) {
  565. // Normal Expected path - We still hold LOCK
  566. break; /* from for()- Enough room: goto proceed */
  567. }
  568. }
  569. ip2trace (CHANN, ITRC_QUEUE, 3, 1, totalsize );
  570. // Prepare to wait for buffers to empty
  571. WRITE_UNLOCK_IRQRESTORE(lock_var_p,flags);
  572. serviceOutgoingFifo(pB); // Dump what we got
  573. if (timeout == 0) {
  574. return 0; // Tired of waiting
  575. }
  576. if (timeout > 0)
  577. timeout--; // So negative values == forever
  578. if (!in_interrupt()) {
  579. schedule_timeout_interruptible(1); // short nap
  580. } else {
  581. // we cannot sched/sleep in interrrupt silly
  582. return 0;
  583. }
  584. if (signal_pending(current)) {
  585. return 0; // Wake up! Time to die!!!
  586. }
  587. ip2trace (CHANN, ITRC_QUEUE, 4, 0 );
  588. } // end of for(;;)
  589. // At this point we have room and the lock - stick them in.
  590. channel = pCh->infl.hd.i2sChannel;
  591. pInsert = &pBuf[stuffIndex]; // Pointer to start of packet
  592. pDest = CMD_OF(pInsert); // Pointer to start of command
  593. // When we start counting, the block is the size of the header
  594. for (blocksize = sizeof(i2CmdHeader), count = nCommands,
  595. lastended = 0, ppCs = &pCs0;
  596. count;
  597. count--, ppCs++)
  598. {
  599. pCs = *ppCs; // Points to command protocol structure
  600. // If this is a bookmark request command, post the fact that a bookmark
  601. // request is pending. NOTE THIS TRICK ONLY WORKS BECAUSE CMD_BMARK_REQ
  602. // has no parameters! The more general solution would be to reference
  603. // pCs->cmd[0].
  604. if (pCs == CMD_BMARK_REQ) {
  605. pCh->bookMarks++;
  606. ip2trace (CHANN, ITRC_DRAIN, 30, 1, pCh->bookMarks );
  607. }
  608. cnt = pCs->length;
  609. // If this command would put us over the maximum block size or
  610. // if the last command had to be at the end of a block, we end
  611. // the existing block here and start a new one.
  612. if ((blocksize + cnt > maxBlock) || lastended) {
  613. ip2trace (CHANN, ITRC_QUEUE, 5, 0 );
  614. PTYPE_OF(pInsert) = type;
  615. CHANNEL_OF(pInsert) = channel;
  616. // count here does not include the header
  617. CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader);
  618. stuffIndex += blocksize;
  619. if(stuffIndex >= maxBuff) {
  620. stuffIndex = 0;
  621. pInsert = pBuf;
  622. }
  623. pInsert = &pBuf[stuffIndex]; // Pointer to start of next pkt
  624. pDest = CMD_OF(pInsert);
  625. blocksize = sizeof(i2CmdHeader);
  626. }
  627. // Now we know there is room for this one in the current block
  628. blocksize += cnt; // Total bytes in this command
  629. pSource = pCs->cmd; // Copy the command into the buffer
  630. while (cnt--) {
  631. *pDest++ = *pSource++;
  632. }
  633. // If this command had to end a block, then we will make sure to account
  634. // for it should there be any more blocks.
  635. lastended = pCs->flags & END;
  636. } // end for
  637. // Clean up the final block by writing header, etc
  638. PTYPE_OF(pInsert) = type;
  639. CHANNEL_OF(pInsert) = channel;
  640. // count here does not include the header
  641. CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader);
  642. stuffIndex += blocksize;
  643. if(stuffIndex >= maxBuff) {
  644. stuffIndex = 0;
  645. pInsert = pBuf;
  646. }
  647. // Updates the index, and post the need for service. When adding these to
  648. // the queue of channels, we turn off the interrupt while doing so,
  649. // because at interrupt level we might want to push a channel back to the
  650. // end of the queue.
  651. switch(type)
  652. {
  653. case PTYPE_INLINE:
  654. pCh->Obuf_stuff = stuffIndex; // Store buffer pointer
  655. WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
  656. pB->debugInlineQueued++;
  657. // Add the channel pointer to list of channels needing service (first
  658. // come...), if it's not already there.
  659. i2QueueNeeds(pB, pCh, NEED_INLINE);
  660. break;
  661. case PTYPE_BYPASS:
  662. pCh->Cbuf_stuff = stuffIndex; // Store buffer pointer
  663. WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags);
  664. pB->debugBypassQueued++;
  665. // Add the channel pointer to list of channels needing service (first
  666. // come...), if it's not already there.
  667. i2QueueNeeds(pB, pCh, NEED_BYPASS);
  668. break;
  669. }
  670. ip2trace (CHANN, ITRC_QUEUE, ITRC_RETURN, 1, nCommands );
  671. return nCommands; // Good status: number of commands sent
  672. }
  673. //******************************************************************************
  674. // Function: i2GetStatus(pCh,resetBits)
  675. // Parameters: Pointer to a channel structure
  676. // Bit map of status bits to clear
  677. // Returns: Bit map of current status bits
  678. //
  679. // Description:
  680. // Returns the state of data set signals, and whether a break has been received,
  681. // (see i2lib.h for bit-mapped result). resetBits is a bit-map of any status
  682. // bits to be cleared: I2_BRK, I2_PAR, I2_FRA, I2_OVR,... These are cleared
  683. // AFTER the condition is passed. If pCh does not point to a valid channel,
  684. // returns -1 (which would be impossible otherwise.
  685. //******************************************************************************
  686. static int
  687. i2GetStatus(i2ChanStrPtr pCh, int resetBits)
  688. {
  689. unsigned short status;
  690. i2eBordStrPtr pB;
  691. ip2trace (CHANN, ITRC_STATUS, ITRC_ENTER, 2, pCh->dataSetIn, resetBits );
  692. // Make sure the channel exists, otherwise do nothing */
  693. if ( !i2Validate ( pCh ) )
  694. return -1;
  695. pB = pCh->pMyBord;
  696. status = pCh->dataSetIn;
  697. // Clear any specified error bits: but note that only actual error bits can
  698. // be cleared, regardless of the value passed.
  699. if (resetBits)
  700. {
  701. pCh->dataSetIn &= ~(resetBits & (I2_BRK | I2_PAR | I2_FRA | I2_OVR));
  702. pCh->dataSetIn &= ~(I2_DDCD | I2_DCTS | I2_DDSR | I2_DRI);
  703. }
  704. ip2trace (CHANN, ITRC_STATUS, ITRC_RETURN, 1, pCh->dataSetIn );
  705. return status;
  706. }
  707. //******************************************************************************
  708. // Function: i2Input(pChpDest,count)
  709. // Parameters: Pointer to a channel structure
  710. // Pointer to data buffer
  711. // Number of bytes to read
  712. // Returns: Number of bytes read, or -1 for error
  713. //
  714. // Description:
  715. // Strips data from the input buffer and writes it to pDest. If there is a
  716. // collosal blunder, (invalid structure pointers or the like), returns -1.
  717. // Otherwise, returns the number of bytes read.
  718. //******************************************************************************
  719. static int
  720. i2Input(i2ChanStrPtr pCh)
  721. {
  722. int amountToMove;
  723. unsigned short stripIndex;
  724. int count;
  725. unsigned long flags = 0;
  726. ip2trace (CHANN, ITRC_INPUT, ITRC_ENTER, 0);
  727. // Ensure channel structure seems real
  728. if ( !i2Validate( pCh ) ) {
  729. count = -1;
  730. goto i2Input_exit;
  731. }
  732. WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
  733. // initialize some accelerators and private copies
  734. stripIndex = pCh->Ibuf_strip;
  735. count = pCh->Ibuf_stuff - stripIndex;
  736. // If buffer is empty or requested data count was 0, (trivial case) return
  737. // without any further thought.
  738. if ( count == 0 ) {
  739. WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
  740. goto i2Input_exit;
  741. }
  742. // Adjust for buffer wrap
  743. if ( count < 0 ) {
  744. count += IBUF_SIZE;
  745. }
  746. // Don't give more than can be taken by the line discipline
  747. amountToMove = pCh->pTTY->ldisc.receive_room( pCh->pTTY );
  748. if (count > amountToMove) {
  749. count = amountToMove;
  750. }
  751. // How much could we copy without a wrap?
  752. amountToMove = IBUF_SIZE - stripIndex;
  753. if (amountToMove > count) {
  754. amountToMove = count;
  755. }
  756. // Move the first block
  757. pCh->pTTY->ldisc.receive_buf( pCh->pTTY,
  758. &(pCh->Ibuf[stripIndex]), NULL, amountToMove );
  759. // If we needed to wrap, do the second data move
  760. if (count > amountToMove) {
  761. pCh->pTTY->ldisc.receive_buf( pCh->pTTY,
  762. pCh->Ibuf, NULL, count - amountToMove );
  763. }
  764. // Bump and wrap the stripIndex all at once by the amount of data read. This
  765. // method is good regardless of whether the data was in one or two pieces.
  766. stripIndex += count;
  767. if (stripIndex >= IBUF_SIZE) {
  768. stripIndex -= IBUF_SIZE;
  769. }
  770. pCh->Ibuf_strip = stripIndex;
  771. // Update our flow control information and possibly queue ourselves to send
  772. // it, depending on how much data has been stripped since the last time a
  773. // packet was sent.
  774. pCh->infl.asof += count;
  775. if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) {
  776. pCh->sinceLastFlow -= pCh->whenSendFlow;
  777. WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
  778. i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW);
  779. } else {
  780. WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
  781. }
  782. i2Input_exit:
  783. ip2trace (CHANN, ITRC_INPUT, ITRC_RETURN, 1, count);
  784. return count;
  785. }
  786. //******************************************************************************
  787. // Function: i2InputFlush(pCh)
  788. // Parameters: Pointer to a channel structure
  789. // Returns: Number of bytes stripped, or -1 for error
  790. //
  791. // Description:
  792. // Strips any data from the input buffer. If there is a collosal blunder,
  793. // (invalid structure pointers or the like), returns -1. Otherwise, returns the
  794. // number of bytes stripped.
  795. //******************************************************************************
  796. static int
  797. i2InputFlush(i2ChanStrPtr pCh)
  798. {
  799. int count;
  800. unsigned long flags;
  801. // Ensure channel structure seems real
  802. if ( !i2Validate ( pCh ) )
  803. return -1;
  804. ip2trace (CHANN, ITRC_INPUT, 10, 0);
  805. WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
  806. count = pCh->Ibuf_stuff - pCh->Ibuf_strip;
  807. // Adjust for buffer wrap
  808. if (count < 0) {
  809. count += IBUF_SIZE;
  810. }
  811. // Expedient way to zero out the buffer
  812. pCh->Ibuf_strip = pCh->Ibuf_stuff;
  813. // Update our flow control information and possibly queue ourselves to send
  814. // it, depending on how much data has been stripped since the last time a
  815. // packet was sent.
  816. pCh->infl.asof += count;
  817. if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow )
  818. {
  819. pCh->sinceLastFlow -= pCh->whenSendFlow;
  820. WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
  821. i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW);
  822. } else {
  823. WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
  824. }
  825. ip2trace (CHANN, ITRC_INPUT, 19, 1, count);
  826. return count;
  827. }
  828. //******************************************************************************
  829. // Function: i2InputAvailable(pCh)
  830. // Parameters: Pointer to a channel structure
  831. // Returns: Number of bytes available, or -1 for error
  832. //
  833. // Description:
  834. // If there is a collosal blunder, (invalid structure pointers or the like),
  835. // returns -1. Otherwise, returns the number of bytes stripped. Otherwise,
  836. // returns the number of bytes available in the buffer.
  837. //******************************************************************************
  838. #if 0
  839. static int
  840. i2InputAvailable(i2ChanStrPtr pCh)
  841. {
  842. int count;
  843. // Ensure channel structure seems real
  844. if ( !i2Validate ( pCh ) ) return -1;
  845. // initialize some accelerators and private copies
  846. READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
  847. count = pCh->Ibuf_stuff - pCh->Ibuf_strip;
  848. READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
  849. // Adjust for buffer wrap
  850. if (count < 0)
  851. {
  852. count += IBUF_SIZE;
  853. }
  854. return count;
  855. }
  856. #endif
  857. //******************************************************************************
  858. // Function: i2Output(pCh, pSource, count)
  859. // Parameters: Pointer to channel structure
  860. // Pointer to source data
  861. // Number of bytes to send
  862. // Returns: Number of bytes sent, or -1 for error
  863. //
  864. // Description:
  865. // Queues the data at pSource to be sent as data packets to the board. If there
  866. // is a collosal blunder, (invalid structure pointers or the like), returns -1.
  867. // Otherwise, returns the number of bytes written. What if there is not enough
  868. // room for all the data? If pCh->channelOptions & CO_NBLOCK_WRITE is set, then
  869. // we transfer as many characters as we can now, then return. If this bit is
  870. // clear (default), routine will spin along until all the data is buffered.
  871. // Should this occur, the 1-ms delay routine is called while waiting to avoid
  872. // applications that one cannot break out of.
  873. //******************************************************************************
  874. static int
  875. i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
  876. {
  877. i2eBordStrPtr pB;
  878. unsigned char *pInsert;
  879. int amountToMove;
  880. int countOriginal = count;
  881. unsigned short channel;
  882. unsigned short stuffIndex;
  883. unsigned long flags;
  884. int rc = 0;
  885. int bailout = 10;
  886. ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, user );
  887. // Ensure channel structure seems real
  888. if ( !i2Validate ( pCh ) )
  889. return -1;
  890. // initialize some accelerators and private copies
  891. pB = pCh->pMyBord;
  892. channel = pCh->infl.hd.i2sChannel;
  893. // If the board has gone fatal, return bad, and also hit the trap routine if
  894. // it exists.
  895. if (pB->i2eFatal) {
  896. if (pB->i2eFatalTrap) {
  897. (*(pB)->i2eFatalTrap)(pB);
  898. }
  899. return -1;
  900. }
  901. // Proceed as though we would do everything
  902. while ( count > 0 ) {
  903. // How much room in output buffer is there?
  904. READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
  905. amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;
  906. READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
  907. if (amountToMove < 0) {
  908. amountToMove += OBUF_SIZE;
  909. }
  910. // Subtract off the headers size and see how much room there is for real
  911. // data. If this is negative, we will discover later.
  912. amountToMove -= sizeof (i2DataHeader);
  913. // Don't move more (now) than can go in a single packet
  914. if ( amountToMove > (int)(MAX_OBUF_BLOCK - sizeof(i2DataHeader)) ) {
  915. amountToMove = MAX_OBUF_BLOCK - sizeof(i2DataHeader);
  916. }
  917. // Don't move more than the count we were given
  918. if (amountToMove > count) {
  919. amountToMove = count;
  920. }
  921. // Now we know how much we must move: NB because the ring buffers have
  922. // an overflow area at the end, we needn't worry about wrapping in the
  923. // middle of a packet.
  924. // Small WINDOW here with no LOCK but I can't call Flush with LOCK
  925. // We would be flushing (or ending flush) anyway
  926. ip2trace (CHANN, ITRC_OUTPUT, 10, 1, amountToMove );
  927. if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) )
  928. && amountToMove > 0 )
  929. {
  930. WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
  931. stuffIndex = pCh->Obuf_stuff;
  932. // Had room to move some data: don't know whether the block size,
  933. // buffer space, or what was the limiting factor...
  934. pInsert = &(pCh->Obuf[stuffIndex]);
  935. // Set up the header
  936. CHANNEL_OF(pInsert) = channel;
  937. PTYPE_OF(pInsert) = PTYPE_DATA;
  938. TAG_OF(pInsert) = 0;
  939. ID_OF(pInsert) = ID_ORDINARY_DATA;
  940. DATA_COUNT_OF(pInsert) = amountToMove;
  941. // Move the data
  942. if ( user ) {
  943. rc = copy_from_user((char*)(DATA_OF(pInsert)), pSource,
  944. amountToMove );
  945. } else {
  946. memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove );
  947. }
  948. // Adjust pointers and indices
  949. pSource += amountToMove;
  950. pCh->Obuf_char_count += amountToMove;
  951. stuffIndex += amountToMove + sizeof(i2DataHeader);
  952. count -= amountToMove;
  953. if (stuffIndex >= OBUF_SIZE) {
  954. stuffIndex = 0;
  955. }
  956. pCh->Obuf_stuff = stuffIndex;
  957. WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
  958. ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex );
  959. } else {
  960. // Cannot move data
  961. // becuz we need to stuff a flush
  962. // or amount to move is <= 0
  963. ip2trace(CHANN, ITRC_OUTPUT, 14, 3,
  964. amountToMove, pB->i2eFifoRemains,
  965. pB->i2eWaitingForEmptyFifo );
  966. // Put this channel back on queue
  967. // this ultimatly gets more data or wakes write output
  968. i2QueueNeeds(pB, pCh, NEED_INLINE);
  969. if ( pB->i2eWaitingForEmptyFifo ) {
  970. ip2trace (CHANN, ITRC_OUTPUT, 16, 0 );
  971. // or schedule
  972. if (!in_interrupt()) {
  973. ip2trace (CHANN, ITRC_OUTPUT, 61, 0 );
  974. schedule_timeout_interruptible(2);
  975. if (signal_pending(current)) {
  976. break;
  977. }
  978. continue;
  979. } else {
  980. ip2trace (CHANN, ITRC_OUTPUT, 62, 0 );
  981. // let interrupt in = WAS restore_flags()
  982. // We hold no lock nor is irq off anymore???
  983. break;
  984. }
  985. break; // from while(count)
  986. }
  987. else if ( pB->i2eFifoRemains < 32 && !pB->i2eTxMailEmpty ( pB ) )
  988. {
  989. ip2trace (CHANN, ITRC_OUTPUT, 19, 2,
  990. pB->i2eFifoRemains,
  991. pB->i2eTxMailEmpty );
  992. break; // from while(count)
  993. } else if ( pCh->channelNeeds & NEED_CREDIT ) {
  994. ip2trace (CHANN, ITRC_OUTPUT, 22, 0 );
  995. break; // from while(count)
  996. } else if ( --bailout) {
  997. // Try to throw more things (maybe not us) in the fifo if we're
  998. // not already waiting for it.
  999. ip2trace (CHANN, ITRC_OUTPUT, 20, 0 );
  1000. serviceOutgoingFifo(pB);
  1001. //break; CONTINUE;
  1002. } else {
  1003. ip2trace (CHANN, ITRC_OUTPUT, 21, 3,
  1004. pB->i2eFifoRemains,
  1005. pB->i2eOutMailWaiting,
  1006. pB->i2eWaitingForEmptyFifo );
  1007. break; // from while(count)
  1008. }
  1009. }
  1010. } // End of while(count)
  1011. i2QueueNeeds(pB, pCh, NEED_INLINE);
  1012. // We drop through either when the count expires, or when there is some
  1013. // count left, but there was a non-blocking write.
  1014. if (countOriginal > count) {
  1015. ip2trace (CHANN, ITRC_OUTPUT, 17, 2, countOriginal, count );
  1016. serviceOutgoingFifo( pB );
  1017. }
  1018. ip2trace (CHANN, ITRC_OUTPUT, ITRC_RETURN, 2, countOriginal, count );
  1019. return countOriginal - count;
  1020. }
  1021. //******************************************************************************
  1022. // Function: i2FlushOutput(pCh)
  1023. // Parameters: Pointer to a channel structure
  1024. // Returns: Nothing
  1025. //
  1026. // Description:
  1027. // Sends bypass command to start flushing (waiting possibly forever until there
  1028. // is room), then sends inline command to stop flushing output, (again waiting
  1029. // possibly forever).
  1030. //******************************************************************************
  1031. static inline void
  1032. i2FlushOutput(i2ChanStrPtr pCh)
  1033. {
  1034. ip2trace (CHANN, ITRC_FLUSH, 1, 1, pCh->flush_flags );
  1035. if (pCh->flush_flags)
  1036. return;
  1037. if ( 1 != i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) {
  1038. pCh->flush_flags = STARTFL_FLAG; // Failed - flag for later
  1039. ip2trace (CHANN, ITRC_FLUSH, 2, 0 );
  1040. } else if ( 1 != i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL) ) {
  1041. pCh->flush_flags = STOPFL_FLAG; // Failed - flag for later
  1042. ip2trace (CHANN, ITRC_FLUSH, 3, 0 );
  1043. }
  1044. }
  1045. static int
  1046. i2RetryFlushOutput(i2ChanStrPtr pCh)
  1047. {
  1048. int old_flags = pCh->flush_flags;
  1049. ip2trace (CHANN, ITRC_FLUSH, 14, 1, old_flags );
  1050. pCh->flush_flags = 0; // Clear flag so we can avoid recursion
  1051. // and queue the commands
  1052. if ( old_flags & STARTFL_FLAG ) {
  1053. if ( 1 == i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) {
  1054. old_flags = STOPFL_FLAG; //Success - send stop flush
  1055. } else {
  1056. old_flags = STARTFL_FLAG; //Failure - Flag for retry later
  1057. }
  1058. ip2trace (CHANN, ITRC_FLUSH, 15, 1, old_flags );
  1059. }
  1060. if ( old_flags & STOPFL_FLAG ) {
  1061. if (1 == i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL)) {
  1062. old_flags = 0; // Success - clear flags
  1063. }
  1064. ip2trace (CHANN, ITRC_FLUSH, 16, 1, old_flags );
  1065. }
  1066. pCh->flush_flags = old_flags;
  1067. ip2trace (CHANN, ITRC_FLUSH, 17, 1, old_flags );
  1068. return old_flags;
  1069. }
  1070. //******************************************************************************
  1071. // Function: i2DrainOutput(pCh,timeout)
  1072. // Parameters: Pointer to a channel structure
  1073. // Maximum period to wait
  1074. // Returns: ?
  1075. //
  1076. // Description:
  1077. // Uses the bookmark request command to ask the board to send a bookmark back as
  1078. // soon as all the data is completely sent.
  1079. //******************************************************************************
  1080. static void
  1081. i2DrainWakeup(i2ChanStrPtr pCh)
  1082. {
  1083. ip2trace (CHANN, ITRC_DRAIN, 10, 1, pCh->BookmarkTimer.expires );
  1084. pCh->BookmarkTimer.expires = 0;
  1085. wake_up_interruptible( &pCh->pBookmarkWait );
  1086. }
  1087. static void
  1088. i2DrainOutput(i2ChanStrPtr pCh, int timeout)
  1089. {
  1090. wait_queue_t wait;
  1091. i2eBordStrPtr pB;
  1092. ip2trace (CHANN, ITRC_DRAIN, ITRC_ENTER, 1, pCh->BookmarkTimer.expires);
  1093. pB = pCh->pMyBord;
  1094. // If the board has gone fatal, return bad,
  1095. // and also hit the trap routine if it exists.
  1096. if (pB->i2eFatal) {
  1097. if (pB->i2eFatalTrap) {
  1098. (*(pB)->i2eFatalTrap)(pB);
  1099. }
  1100. return;
  1101. }
  1102. if ((timeout > 0) && (pCh->BookmarkTimer.expires == 0 )) {
  1103. // One per customer (channel)
  1104. init_timer( &(pCh->BookmarkTimer) );
  1105. pCh->BookmarkTimer.expires = jiffies + timeout;
  1106. pCh->BookmarkTimer.function = (void*)(unsigned long)i2DrainWakeup;
  1107. pCh->BookmarkTimer.data = (unsigned long)pCh;
  1108. ip2trace (CHANN, ITRC_DRAIN, 1, 1, pCh->BookmarkTimer.expires );
  1109. add_timer( &(pCh->BookmarkTimer) );
  1110. }
  1111. i2QueueCommands( PTYPE_INLINE, pCh, -1, 1, CMD_BMARK_REQ );
  1112. init_waitqueue_entry(&wait, current);
  1113. add_wait_queue(&(pCh->pBookmarkWait), &wait);
  1114. set_current_state( TASK_INTERRUPTIBLE );
  1115. serviceOutgoingFifo( pB );
  1116. schedule(); // Now we take our interruptible sleep on
  1117. // Clean up the queue
  1118. set_current_state( TASK_RUNNING );
  1119. remove_wait_queue(&(pCh->pBookmarkWait), &wait);
  1120. // if expires == 0 then timer poped, then do not need to del_timer
  1121. if ((timeout > 0) && pCh->BookmarkTimer.expires &&
  1122. time_before(jiffies, pCh->BookmarkTimer.expires)) {
  1123. del_timer( &(pCh->BookmarkTimer) );
  1124. pCh->BookmarkTimer.expires = 0;
  1125. ip2trace (CHANN, ITRC_DRAIN, 3, 1, pCh->BookmarkTimer.expires );
  1126. }
  1127. ip2trace (CHANN, ITRC_DRAIN, ITRC_RETURN, 1, pCh->BookmarkTimer.expires );
  1128. return;
  1129. }
  1130. //******************************************************************************
  1131. // Function: i2OutputFree(pCh)
  1132. // Parameters: Pointer to a channel structure
  1133. // Returns: Space in output buffer
  1134. //
  1135. // Description:
  1136. // Returns -1 if very gross error. Otherwise returns the amount of bytes still
  1137. // free in the output buffer.
  1138. //******************************************************************************
  1139. static int
  1140. i2OutputFree(i2ChanStrPtr pCh)
  1141. {
  1142. int amountToMove;
  1143. unsigned long flags;
  1144. // Ensure channel structure seems real
  1145. if ( !i2Validate ( pCh ) ) {
  1146. return -1;
  1147. }
  1148. READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
  1149. amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;
  1150. READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
  1151. if (amountToMove < 0) {
  1152. amountToMove += OBUF_SIZE;
  1153. }
  1154. // If this is negative, we will discover later
  1155. amountToMove -= sizeof(i2DataHeader);
  1156. return (amountToMove < 0) ? 0 : amountToMove;
  1157. }
  1158. static void
  1159. ip2_owake( PTTY tp)
  1160. {
  1161. i2ChanStrPtr pCh;
  1162. if (tp == NULL) return;
  1163. pCh = tp->driver_data;
  1164. ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags,
  1165. (1 << TTY_DO_WRITE_WAKEUP) );
  1166. wake_up_interruptible ( &tp->write_wait );
  1167. if ( ( tp->flags & (1 << TTY_DO_WRITE_WAKEUP) )
  1168. && tp->ldisc.write_wakeup )
  1169. {
  1170. (tp->ldisc.write_wakeup) ( tp );
  1171. ip2trace (CHANN, ITRC_SICMD, 11, 0 );
  1172. }
  1173. }
  1174. static inline void
  1175. set_baud_params(i2eBordStrPtr pB)
  1176. {
  1177. int i,j;
  1178. i2ChanStrPtr *pCh;
  1179. pCh = (i2ChanStrPtr *) pB->i2eChannelPtr;
  1180. for (i = 0; i < ABS_MAX_BOXES; i++) {
  1181. if (pB->channelBtypes.bid_value[i]) {
  1182. if (BID_HAS_654(pB->channelBtypes.bid_value[i])) {
  1183. for (j = 0; j < ABS_BIGGEST_BOX; j++) {
  1184. if (pCh[i*16+j] == NULL)
  1185. break;
  1186. (pCh[i*16+j])->BaudBase = 921600; // MAX for ST654
  1187. (pCh[i*16+j])->BaudDivisor = 96;
  1188. }
  1189. } else { // has cirrus cd1400
  1190. for (j = 0; j < ABS_BIGGEST_BOX; j++) {
  1191. if (pCh[i*16+j] == NULL)
  1192. break;
  1193. (pCh[i*16+j])->BaudBase = 115200; // MAX for CD1400
  1194. (pCh[i*16+j])->BaudDivisor = 12;
  1195. }
  1196. }
  1197. }
  1198. }
  1199. }
  1200. //******************************************************************************
  1201. // Function: i2StripFifo(pB)
  1202. // Parameters: Pointer to a board structure
  1203. // Returns: ?
  1204. //
  1205. // Description:
  1206. // Strips all the available data from the incoming FIFO, identifies the type of
  1207. // packet, and either buffers the data or does what needs to be done.
  1208. //
  1209. // Note there is no overflow checking here: if the board sends more data than it
  1210. // ought to, we will not detect it here, but blindly overflow...
  1211. //******************************************************************************
  1212. // A buffer for reading in blocks for unknown channels
  1213. static unsigned char junkBuffer[IBUF_SIZE];
  1214. // A buffer to read in a status packet. Because of the size of the count field
  1215. // for these things, the maximum packet size must be less than MAX_CMD_PACK_SIZE
  1216. static unsigned char cmdBuffer[MAX_CMD_PACK_SIZE + 4];
  1217. // This table changes the bit order from MSR order given by STAT_MODEM packet to
  1218. // status bits used in our library.
  1219. static char xlatDss[16] = {
  1220. 0 | 0 | 0 | 0 ,
  1221. 0 | 0 | 0 | I2_CTS ,
  1222. 0 | 0 | I2_DSR | 0 ,
  1223. 0 | 0 | I2_DSR | I2_CTS ,
  1224. 0 | I2_RI | 0 | 0 ,
  1225. 0 | I2_RI | 0 | I2_CTS ,
  1226. 0 | I2_RI | I2_DSR | 0 ,
  1227. 0 | I2_RI | I2_DSR | I2_CTS ,
  1228. I2_DCD | 0 | 0 | 0 ,
  1229. I2_DCD | 0 | 0 | I2_CTS ,
  1230. I2_DCD | 0 | I2_DSR | 0 ,
  1231. I2_DCD | 0 | I2_DSR | I2_CTS ,
  1232. I2_DCD | I2_RI | 0 | 0 ,
  1233. I2_DCD | I2_RI | 0 | I2_CTS ,
  1234. I2_DCD | I2_RI | I2_DSR | 0 ,
  1235. I2_DCD | I2_RI | I2_DSR | I2_CTS };
  1236. static inline void
  1237. i2StripFifo(i2eBordStrPtr pB)
  1238. {
  1239. i2ChanStrPtr pCh;
  1240. int channel;
  1241. int count;
  1242. unsigned short stuffIndex;
  1243. int amountToRead;
  1244. unsigned char *pc, *pcLimit;
  1245. unsigned char uc;
  1246. unsigned char dss_change;
  1247. unsigned long bflags,cflags;
  1248. // ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 );
  1249. while (HAS_INPUT(pB)) {
  1250. // ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 );
  1251. // Process packet from fifo a one atomic unit
  1252. WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock,bflags);
  1253. // The first word (or two bytes) will have channel number and type of
  1254. // packet, possibly other information
  1255. pB->i2eLeadoffWord[0] = iiReadWord(pB);
  1256. switch(PTYPE_OF(pB->i2eLeadoffWord))
  1257. {
  1258. case PTYPE_DATA:
  1259. pB->got_input = 1;
  1260. // ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 3, 0 );
  1261. channel = CHANNEL_OF(pB->i2eLeadoffWord); /* Store channel */
  1262. count = iiReadWord(pB); /* Count is in the next word */
  1263. // NEW: Check the count for sanity! Should the hardware fail, our death
  1264. // is more pleasant. While an oversize channel is acceptable (just more
  1265. // than the driver supports), an over-length count clearly means we are
  1266. // sick!
  1267. if ( ((unsigned int)count) > IBUF_SIZE ) {
  1268. pB->i2eFatal = 2;
  1269. WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
  1270. return; /* Bail out ASAP */
  1271. }
  1272. // Channel is illegally big ?
  1273. if ((channel >= pB->i2eChannelCnt) ||
  1274. (NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])))
  1275. {
  1276. iiReadBuf(pB, junkBuffer, count);
  1277. WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
  1278. break; /* From switch: ready for next packet */
  1279. }
  1280. // Channel should be valid, then
  1281. // If this is a hot-key, merely post its receipt for now. These are
  1282. // always supposed to be 1-byte packets, so we won't even check the
  1283. // count. Also we will post an acknowledgement to the board so that
  1284. // more data can be forthcoming. Note that we are not trying to use
  1285. // these sequences in this driver, merely to robustly ignore them.
  1286. if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY)
  1287. {
  1288. pCh->hotKeyIn = iiReadWord(pB) & 0xff;
  1289. WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
  1290. i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK);
  1291. break; /* From the switch: ready for next packet */
  1292. }
  1293. // Normal data! We crudely assume there is room for the data in our
  1294. // buffer because the board wouldn't have exceeded his credit limit.
  1295. WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,cflags);
  1296. // We have 2 locks now
  1297. stuffIndex = pCh->Ibuf_stuff;
  1298. amountToRead = IBUF_SIZE - stuffIndex;
  1299. if (amountToRead > count)
  1300. amountToRead = count;
  1301. // stuffIndex would have been already adjusted so there would
  1302. // always be room for at least one, and count is always at least
  1303. // one.
  1304. iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead);
  1305. pCh->icount.rx += amountToRead;
  1306. // Update the stuffIndex by the amount of data moved. Note we could
  1307. // never ask for more data than would just fit. However, we might
  1308. // have read in one more byte than we wanted because the read
  1309. // rounds up to even bytes. If this byte is on the end of the
  1310. // packet, and is padding, we ignore it. If the byte is part of
  1311. // the actual data, we need to move it.
  1312. stuffIndex += amountToRead;
  1313. if (stuffIndex >= IBUF_SIZE) {
  1314. if ((amountToRead & 1) && (count > amountToRead)) {
  1315. pCh->Ibuf[0] = pCh->Ibuf[IBUF_SIZE];
  1316. amountToRead++;
  1317. stuffIndex = 1;
  1318. } else {
  1319. stuffIndex = 0;
  1320. }
  1321. }
  1322. // If there is anything left over, read it as well
  1323. if (count > amountToRead) {
  1324. amountToRead = count - amountToRead;
  1325. iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead);
  1326. pCh->icount.rx += amountToRead;
  1327. stuffIndex += amountToRead;
  1328. }
  1329. // Update stuff index
  1330. pCh->Ibuf_stuff = stuffIndex;
  1331. WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,cflags);
  1332. WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
  1333. #ifdef USE_IQ
  1334. schedule_work(&pCh->tqueue_input);
  1335. #else
  1336. do_input(pCh);
  1337. #endif
  1338. // Note we do not need to maintain any flow-control credits at this
  1339. // time: if we were to increment .asof and decrement .room, there
  1340. // would be no net effect. Instead, when we strip data, we will
  1341. // increment .asof and leave .room unchanged.
  1342. break; // From switch: ready for next packet
  1343. case PTYPE_STATUS:
  1344. ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 4, 0 );
  1345. count = CMD_COUNT_OF(pB->i2eLeadoffWord);
  1346. iiReadBuf(pB, cmdBuffer, count);
  1347. // We can release early with buffer grab
  1348. WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
  1349. pc = cmdBuffer;
  1350. pcLimit = &(cmdBuffer[count]);
  1351. while (pc < pcLimit) {
  1352. channel = *pc++;
  1353. ip2trace (channel, ITRC_SFIFO, 7, 2, channel, *pc );
  1354. /* check for valid channel */
  1355. if (channel < pB->i2eChannelCnt
  1356. &&
  1357. (pCh = (((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])) != NULL
  1358. )
  1359. {
  1360. dss_change = 0;
  1361. switch (uc = *pc++)
  1362. {
  1363. /* Breaks and modem signals are easy: just update status */
  1364. case STAT_CTS_UP:
  1365. if ( !(pCh->dataSetIn & I2_CTS) )
  1366. {
  1367. pCh->dataSetIn |= I2_DCTS;
  1368. pCh->icount.cts++;
  1369. dss_change = 1;
  1370. }
  1371. pCh->dataSetIn |= I2_CTS;
  1372. break;
  1373. case STAT_CTS_DN:
  1374. if ( pCh->dataSetIn & I2_CTS )
  1375. {
  1376. pCh->dataSetIn |= I2_DCTS;
  1377. pCh->icount.cts++;
  1378. dss_change = 1;
  1379. }
  1380. pCh->dataSetIn &= ~I2_CTS;
  1381. break;
  1382. case STAT_DCD_UP:
  1383. ip2trace (channel, ITRC_MODEM, 1, 1, pCh->dataSetIn );
  1384. if ( !(pCh->dataSetIn & I2_DCD) )
  1385. {
  1386. ip2trace (CHANN, ITRC_MODEM, 2, 0 );
  1387. pCh->dataSetIn |= I2_DDCD;
  1388. pCh->icount.dcd++;
  1389. dss_change = 1;
  1390. }
  1391. pCh->dataSetIn |= I2_DCD;
  1392. ip2trace (channel, ITRC_MODEM, 3, 1, pCh->dataSetIn );
  1393. break;
  1394. case STAT_DCD_DN:
  1395. ip2trace (channel, ITRC_MODEM, 4, 1, pCh->dataSetIn );
  1396. if ( pCh->dataSetIn & I2_DCD )
  1397. {
  1398. ip2trace (channel, ITRC_MODEM, 5, 0 );
  1399. pCh->dataSetIn |= I2_DDCD;
  1400. pCh->icount.dcd++;
  1401. dss_change = 1;
  1402. }
  1403. pCh->dataSetIn &= ~I2_DCD;
  1404. ip2trace (channel, ITRC_MODEM, 6, 1, pCh->dataSetIn );
  1405. break;
  1406. case STAT_DSR_UP:
  1407. if ( !(pCh->dataSetIn & I2_DSR) )
  1408. {
  1409. pCh->dataSetIn |= I2_DDSR;
  1410. pCh->icount.dsr++;
  1411. dss_change = 1;
  1412. }
  1413. pCh->dataSetIn |= I2_DSR;
  1414. break;
  1415. case STAT_DSR_DN:
  1416. if ( pCh->dataSetIn & I2_DSR )
  1417. {
  1418. pCh->dataSetIn |= I2_DDSR;
  1419. pCh->icount.dsr++;
  1420. dss_change = 1;
  1421. }
  1422. pCh->dataSetIn &= ~I2_DSR;
  1423. break;
  1424. case STAT_RI_UP:
  1425. if ( !(pCh->dataSetIn & I2_RI) )
  1426. {
  1427. pCh->dataSetIn |= I2_DRI;
  1428. pCh->icount.rng++;
  1429. dss_change = 1;
  1430. }
  1431. pCh->dataSetIn |= I2_RI ;
  1432. break;
  1433. case STAT_RI_DN:
  1434. // to be compat with serial.c
  1435. //if ( pCh->dataSetIn & I2_RI )
  1436. //{
  1437. // pCh->dataSetIn |= I2_DRI;
  1438. // pCh->icount.rng++;
  1439. // dss_change = 1;
  1440. //}
  1441. pCh->dataSetIn &= ~I2_RI ;
  1442. break;
  1443. case STAT_BRK_DET:
  1444. pCh->dataSetIn |= I2_BRK;
  1445. pCh->icount.brk++;
  1446. dss_change = 1;
  1447. break;
  1448. // Bookmarks? one less request we're waiting for
  1449. case STAT_BMARK:
  1450. pCh->bookMarks--;
  1451. if (pCh->bookMarks <= 0 ) {
  1452. pCh->bookMarks = 0;
  1453. wake_up_interruptible( &pCh->pBookmarkWait );
  1454. ip2trace (channel, ITRC_DRAIN, 20, 1, pCh->BookmarkTimer.expires );
  1455. }
  1456. break;
  1457. // Flow control packets? Update the new credits, and if
  1458. // someone was waiting for output, queue him up again.
  1459. case STAT_FLOW:
  1460. pCh->outfl.room =
  1461. ((flowStatPtr)pc)->room -
  1462. (pCh->outfl.asof - ((flowStatPtr)pc)->asof);
  1463. ip2trace (channel, ITRC_STFLW, 1, 1, pCh->outfl.room );
  1464. if (pCh->channelNeeds & NEED_CREDIT)
  1465. {
  1466. ip2trace (channel, ITRC_STFLW, 2, 1, pCh->channelNeeds);
  1467. pCh->channelNeeds &= ~NEED_CREDIT;
  1468. i2QueueNeeds(pB, pCh, NEED_INLINE);
  1469. if ( pCh->pTTY )
  1470. ip2_owake(pCh->pTTY);
  1471. }
  1472. ip2trace (channel, ITRC_STFLW, 3, 1, pCh->channelNeeds);
  1473. pc += sizeof(flowStat);
  1474. break;
  1475. /* Special packets: */
  1476. /* Just copy the information into the channel structure */
  1477. case STAT_STATUS:
  1478. pCh->channelStatus = *((debugStatPtr)pc);
  1479. pc += sizeof(debugStat);
  1480. break;
  1481. case STAT_TXCNT:
  1482. pCh->channelTcount = *((cntStatPtr)pc);
  1483. pc += sizeof(cntStat);
  1484. break;
  1485. case STAT_RXCNT:
  1486. pCh->channelRcount = *((cntStatPtr)pc);
  1487. pc += sizeof(cntStat);
  1488. break;
  1489. case STAT_BOXIDS:
  1490. pB->channelBtypes = *((bidStatPtr)pc);
  1491. pc += sizeof(bidStat);
  1492. set_baud_params(pB);
  1493. break;
  1494. case STAT_HWFAIL:
  1495. i2QueueCommands (PTYPE_INLINE, pCh, 0, 1, CMD_HW_TEST);
  1496. pCh->channelFail = *((failStatPtr)pc);
  1497. pc += sizeof(failStat);
  1498. break;
  1499. /* No explicit match? then
  1500. * Might be an error packet...
  1501. */
  1502. default:
  1503. switch (uc & STAT_MOD_ERROR)
  1504. {
  1505. case STAT_ERROR:
  1506. if (uc & STAT_E_PARITY) {
  1507. pCh->dataSetIn |= I2_PAR;
  1508. pCh->icount.parity++;
  1509. }
  1510. if (uc & STAT_E_FRAMING){
  1511. pCh->dataSetIn |= I2_FRA;
  1512. pCh->icount.frame++;
  1513. }
  1514. if (uc & STAT_E_OVERRUN){
  1515. pCh->dataSetIn |= I2_OVR;
  1516. pCh->icount.overrun++;
  1517. }
  1518. break;
  1519. case STAT_MODEM:
  1520. // the answer to DSS_NOW request (not change)
  1521. pCh->dataSetIn = (pCh->dataSetIn
  1522. & ~(I2_RI | I2_CTS | I2_DCD | I2_DSR) )
  1523. | xlatDss[uc & 0xf];
  1524. wake_up_interruptible ( &pCh->dss_now_wait );
  1525. default:
  1526. break;
  1527. }
  1528. } /* End of switch on status type */
  1529. if (dss_change) {
  1530. #ifdef USE_IQ
  1531. schedule_work(&pCh->tqueue_status);
  1532. #else
  1533. do_status(pCh);
  1534. #endif
  1535. }
  1536. }
  1537. else /* Or else, channel is invalid */
  1538. {
  1539. // Even though the channel is invalid, we must test the
  1540. // status to see how much additional data it has (to be
  1541. // skipped)
  1542. switch (*pc++)
  1543. {
  1544. case STAT_FLOW:
  1545. pc += 4; /* Skip the data */
  1546. break;
  1547. default:
  1548. break;
  1549. }
  1550. }
  1551. } // End of while (there is still some status packet left)
  1552. break;
  1553. default: // Neither packet? should be impossible
  1554. ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1,
  1555. PTYPE_OF(pB->i2eLeadoffWord) );
  1556. break;
  1557. } // End of switch on type of packets
  1558. } //while(board HAS_INPUT)
  1559. ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_RETURN, 0 );
  1560. // Send acknowledgement to the board even if there was no data!
  1561. pB->i2eOutMailWaiting |= MB_IN_STRIPPED;
  1562. return;
  1563. }
  1564. //******************************************************************************
  1565. // Function: i2Write2Fifo(pB,address,count)
  1566. // Parameters: Pointer to a board structure, source address, byte count
  1567. // Returns: bytes written
  1568. //
  1569. // Description:
  1570. // Writes count bytes to board io address(implied) from source
  1571. // Adjusts count, leaves reserve for next time around bypass cmds
  1572. //******************************************************************************
  1573. static int
  1574. i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve)
  1575. {
  1576. int rc = 0;
  1577. unsigned long flags;
  1578. WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
  1579. if (!pB->i2eWaitingForEmptyFifo) {
  1580. if (pB->i2eFifoRemains > (count+reserve)) {
  1581. pB->i2eFifoRemains -= count;
  1582. iiWriteBuf(pB, source, count);
  1583. pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
  1584. rc = count;
  1585. }
  1586. }
  1587. WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
  1588. return rc;
  1589. }
  1590. //******************************************************************************
  1591. // Function: i2StuffFifoBypass(pB)
  1592. // Parameters: Pointer to a board structure
  1593. // Returns: Nothing
  1594. //
  1595. // Description:
  1596. // Stuffs as many bypass commands into the fifo as possible. This is simpler
  1597. // than stuffing data or inline commands to fifo, since we do not have
  1598. // flow-control to deal with.
  1599. //******************************************************************************
  1600. static inline void
  1601. i2StuffFifoBypass(i2eBordStrPtr pB)
  1602. {
  1603. i2ChanStrPtr pCh;
  1604. unsigned char *pRemove;
  1605. unsigned short stripIndex;
  1606. unsigned short packetSize;
  1607. unsigned short paddedSize;
  1608. unsigned short notClogged = 1;
  1609. unsigned long flags;
  1610. int bailout = 1000;
  1611. // Continue processing so long as there are entries, or there is room in the
  1612. // fifo. Each entry represents a channel with something to do.
  1613. while ( --bailout && notClogged &&
  1614. (NULL != (pCh = i2DeQueueNeeds(pB,NEED_BYPASS))))
  1615. {
  1616. WRITE_LOCK_IRQSAVE(&pCh->Cbuf_spinlock,flags);
  1617. stripIndex = pCh->Cbuf_strip;
  1618. // as long as there are packets for this channel...
  1619. while (stripIndex != pCh->Cbuf_stuff) {
  1620. pRemove = &(pCh->Cbuf[stripIndex]);
  1621. packetSize = CMD_COUNT_OF(pRemove) + sizeof(i2CmdHeader);
  1622. paddedSize = ROUNDUP(packetSize);
  1623. if (paddedSize > 0) {
  1624. if ( 0 == i2Write2Fifo(pB, pRemove, paddedSize,0)) {
  1625. notClogged = 0; /* fifo full */
  1626. i2QueueNeeds(pB, pCh, NEED_BYPASS); // Put back on queue
  1627. break; // Break from the channel
  1628. }
  1629. }
  1630. #ifdef DEBUG_FIFO
  1631. WriteDBGBuf("BYPS", pRemove, paddedSize);
  1632. #endif /* DEBUG_FIFO */
  1633. pB->debugBypassCount++;
  1634. pRemove += packetSize;
  1635. stripIndex += packetSize;
  1636. if (stripIndex >= CBUF_SIZE) {
  1637. stripIndex = 0;
  1638. pRemove = pCh->Cbuf;
  1639. }
  1640. }
  1641. // Done with this channel. Move to next, removing this one from
  1642. // the queue of channels if we cleaned it out (i.e., didn't get clogged.
  1643. pCh->Cbuf_strip = stripIndex;
  1644. WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags);
  1645. } // Either clogged or finished all the work
  1646. #ifdef IP2DEBUG_TRACE
  1647. if ( !bailout ) {
  1648. ip2trace (ITRC_NO_PORT, ITRC_ERROR, 1, 0 );
  1649. }
  1650. #endif
  1651. }
  1652. //******************************************************************************
  1653. // Function: i2StuffFifoFlow(pB)
  1654. // Parameters: Pointer to a board structure
  1655. // Returns: Nothing
  1656. //
  1657. // Description:
  1658. // Stuffs as many flow control packets into the fifo as possible. This is easier
  1659. // even than doing normal bypass commands, because there is always at most one
  1660. // packet, already assembled, for each channel.
  1661. //******************************************************************************
  1662. static inline void
  1663. i2StuffFifoFlow(i2eBordStrPtr pB)
  1664. {
  1665. i2ChanStrPtr pCh;
  1666. unsigned short paddedSize = ROUNDUP(sizeof(flowIn));
  1667. ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_ENTER, 2,
  1668. pB->i2eFifoRemains, paddedSize );
  1669. // Continue processing so long as there are entries, or there is room in the
  1670. // fifo. Each entry represents a channel with something to do.
  1671. while ( (NULL != (pCh = i2DeQueueNeeds(pB,NEED_FLOW)))) {
  1672. pB->debugFlowCount++;
  1673. // NO Chan LOCK needed ???
  1674. if ( 0 == i2Write2Fifo(pB,(unsigned char *)&(pCh->infl),paddedSize,0)) {
  1675. break;
  1676. }
  1677. #ifdef DEBUG_FIFO
  1678. WriteDBGBuf("FLOW",(unsigned char *) &(pCh->infl), paddedSize);
  1679. #endif /* DEBUG_FIFO */
  1680. } // Either clogged or finished all the work
  1681. ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_RETURN, 0 );
  1682. }
  1683. //******************************************************************************
  1684. // Function: i2StuffFifoInline(pB)
  1685. // Parameters: Pointer to a board structure
  1686. // Returns: Nothing
  1687. //
  1688. // Description:
  1689. // Stuffs as much data and inline commands into the fifo as possible. This is
  1690. // the most complex fifo-stuffing operation, since there if now the channel
  1691. // flow-control issue to deal with.
  1692. //******************************************************************************
  1693. static inline void
  1694. i2StuffFifoInline(i2eBordStrPtr pB)
  1695. {
  1696. i2ChanStrPtr pCh;
  1697. unsigned char *pRemove;
  1698. unsigned short stripIndex;
  1699. unsigned short packetSize;
  1700. unsigned short paddedSize;
  1701. unsigned short notClogged = 1;
  1702. unsigned short flowsize;
  1703. unsigned long flags;
  1704. int bailout = 1000;
  1705. int bailout2;
  1706. ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_ENTER, 3, pB->i2eFifoRemains,
  1707. pB->i2Dbuf_strip, pB->i2Dbuf_stuff );
  1708. // Continue processing so long as there are entries, or there is room in the
  1709. // fifo. Each entry represents a channel with something to do.
  1710. while ( --bailout && notClogged &&
  1711. (NULL != (pCh = i2DeQueueNeeds(pB,NEED_INLINE))) )
  1712. {
  1713. WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
  1714. stripIndex = pCh->Obuf_strip;
  1715. ip2trace (CHANN, ITRC_SICMD, 3, 2, stripIndex, pCh->Obuf_stuff );
  1716. // as long as there are packets for this channel...
  1717. bailout2 = 1000;
  1718. while ( --bailout2 && stripIndex != pCh->Obuf_stuff) {
  1719. pRemove = &(pCh->Obuf[stripIndex]);
  1720. // Must determine whether this be a data or command packet to
  1721. // calculate correctly the header size and the amount of
  1722. // flow-control credit this type of packet will use.
  1723. if (PTYPE_OF(pRemove) == PTYPE_DATA) {
  1724. flowsize = DATA_COUNT_OF(pRemove);
  1725. packetSize = flowsize + sizeof(i2DataHeader);
  1726. } else {
  1727. flowsize = CMD_COUNT_OF(pRemove);
  1728. packetSize = flowsize + sizeof(i2CmdHeader);
  1729. }
  1730. flowsize = CREDIT_USAGE(flowsize);
  1731. paddedSize = ROUNDUP(packetSize);
  1732. ip2trace (CHANN, ITRC_SICMD, 4, 2, pB->i2eFifoRemains, paddedSize );
  1733. // If we don't have enough credits from the board to send the data,
  1734. // flag the channel that we are waiting for flow control credit, and
  1735. // break out. This will clean up this channel and remove us from the
  1736. // queue of hot things to do.
  1737. ip2trace (CHANN, ITRC_SICMD, 5, 2, pCh->outfl.room, flowsize );
  1738. if (pCh->outfl.room <= flowsize) {
  1739. // Do Not have the credits to send this packet.
  1740. i2QueueNeeds(pB, pCh, NEED_CREDIT);
  1741. notClogged = 0;
  1742. break; // So to do next channel
  1743. }
  1744. if ( (paddedSize > 0)
  1745. && ( 0 == i2Write2Fifo(pB, pRemove, paddedSize, 128))) {
  1746. // Do Not have room in fifo to send this packet.
  1747. notClogged = 0;
  1748. i2QueueNeeds(pB, pCh, NEED_INLINE);
  1749. break; // Break from the channel
  1750. }
  1751. #ifdef DEBUG_FIFO
  1752. WriteDBGBuf("DATA", pRemove, paddedSize);
  1753. #endif /* DEBUG_FIFO */
  1754. pB->debugInlineCount++;
  1755. pCh->icount.tx += flowsize;
  1756. // Update current credits
  1757. pCh->outfl.room -= flowsize;
  1758. pCh->outfl.asof += flowsize;
  1759. if (PTYPE_OF(pRemove) == PTYPE_DATA) {
  1760. pCh->Obuf_char_count -= DATA_COUNT_OF(pRemove);
  1761. }
  1762. pRemove += packetSize;
  1763. stripIndex += packetSize;
  1764. ip2trace (CHANN, ITRC_SICMD, 6, 2, stripIndex, pCh->Obuf_strip);
  1765. if (stripIndex >= OBUF_SIZE) {
  1766. stripIndex = 0;
  1767. pRemove = pCh->Obuf;
  1768. ip2trace (CHANN, ITRC_SICMD, 7, 1, stripIndex );
  1769. }
  1770. } /* while */
  1771. if ( !bailout2 ) {
  1772. ip2trace (CHANN, ITRC_ERROR, 3, 0 );
  1773. }
  1774. // Done with this channel. Move to next, removing this one from the
  1775. // queue of channels if we cleaned it out (i.e., didn't get clogged.
  1776. pCh->Obuf_strip = stripIndex;
  1777. WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
  1778. if ( notClogged )
  1779. {
  1780. ip2trace (CHANN, ITRC_SICMD, 8, 0 );
  1781. if ( pCh->pTTY ) {
  1782. ip2_owake(pCh->pTTY);
  1783. }
  1784. }
  1785. } // Either clogged or finished all the work
  1786. if ( !bailout ) {
  1787. ip2trace (ITRC_NO_PORT, ITRC_ERROR, 4, 0 );
  1788. }
  1789. ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_RETURN, 1,pB->i2Dbuf_strip);
  1790. }
  1791. //******************************************************************************
  1792. // Function: serviceOutgoingFifo(pB)
  1793. // Parameters: Pointer to a board structure
  1794. // Returns: Nothing
  1795. //
  1796. // Description:
  1797. // Helper routine to put data in the outgoing fifo, if we aren't already waiting
  1798. // for something to be there. If the fifo has only room for a very little data,
  1799. // go head and hit the board with a mailbox hit immediately. Otherwise, it will
  1800. // have to happen later in the interrupt processing. Since this routine may be
  1801. // called both at interrupt and foreground time, we must turn off interrupts
  1802. // during the entire process.
  1803. //******************************************************************************
  1804. static void
  1805. serviceOutgoingFifo(i2eBordStrPtr pB)
  1806. {
  1807. // If we aren't currently waiting for the board to empty our fifo, service
  1808. // everything that is pending, in priority order (especially, Bypass before
  1809. // Inline).
  1810. if ( ! pB->i2eWaitingForEmptyFifo )
  1811. {
  1812. i2StuffFifoFlow(pB);
  1813. i2StuffFifoBypass(pB);
  1814. i2StuffFifoInline(pB);
  1815. iiSendPendingMail(pB);
  1816. }
  1817. }
  1818. //******************************************************************************
  1819. // Function: i2ServiceBoard(pB)
  1820. // Parameters: Pointer to a board structure
  1821. // Returns: Nothing
  1822. //
  1823. // Description:
  1824. // Normally this is called from interrupt level, but there is deliberately
  1825. // nothing in here specific to being called from interrupt level. All the
  1826. // hardware-specific, interrupt-specific things happen at the outer levels.
  1827. //
  1828. // For example, a timer interrupt could drive this routine for some sort of
  1829. // polled operation. The only requirement is that the programmer deal with any
  1830. // atomiticity/concurrency issues that result.
  1831. //
  1832. // This routine responds to the board's having sent mailbox information to the
  1833. // host (which would normally cause an interrupt). This routine reads the
  1834. // incoming mailbox. If there is no data in it, this board did not create the
  1835. // interrupt and/or has nothing to be done to it. (Except, if we have been
  1836. // waiting to write mailbox data to it, we may do so.
  1837. //
  1838. // Based on the value in the mailbox, we may take various actions.
  1839. //
  1840. // No checking here of pB validity: after all, it shouldn't have been called by
  1841. // the handler unless pB were on the list.
  1842. //******************************************************************************
  1843. static inline int
  1844. i2ServiceBoard ( i2eBordStrPtr pB )
  1845. {
  1846. unsigned inmail;
  1847. unsigned long flags;
  1848. /* This should be atomic because of the way we are called... */
  1849. if (NO_MAIL_HERE == ( inmail = pB->i2eStartMail ) ) {
  1850. inmail = iiGetMail(pB);
  1851. }
  1852. pB->i2eStartMail = NO_MAIL_HERE;
  1853. ip2trace (ITRC_NO_PORT, ITRC_INTR, 2, 1, inmail );
  1854. if (inmail != NO_MAIL_HERE) {
  1855. // If the board has gone fatal, nothing to do but hit a bit that will
  1856. // alert foreground tasks to protest!
  1857. if ( inmail & MB_FATAL_ERROR ) {
  1858. pB->i2eFatal = 1;
  1859. goto exit_i2ServiceBoard;
  1860. }
  1861. /* Assuming no fatal condition, we proceed to do work */
  1862. if ( inmail & MB_IN_STUFFED ) {
  1863. pB->i2eFifoInInts++;
  1864. i2StripFifo(pB); /* There might be incoming packets */
  1865. }
  1866. if (inmail & MB_OUT_STRIPPED) {
  1867. pB->i2eFifoOutInts++;
  1868. WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
  1869. pB->i2eFifoRemains = pB->i2eFifoSize;
  1870. pB->i2eWaitingForEmptyFifo = 0;
  1871. WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
  1872. ip2trace (ITRC_NO_PORT, ITRC_INTR, 30, 1, pB->i2eFifoRemains );
  1873. }
  1874. serviceOutgoingFifo(pB);
  1875. }
  1876. ip2trace (ITRC_NO_PORT, ITRC_INTR, 8, 0 );
  1877. exit_i2ServiceBoard:
  1878. return 0;
  1879. }