diff options
Diffstat (limited to 'drivers/char/ip2/i2ellis.c')
-rw-r--r-- | drivers/char/ip2/i2ellis.c | 1403 |
1 files changed, 0 insertions, 1403 deletions
diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c deleted file mode 100644 index 29db44de399f..000000000000 --- a/drivers/char/ip2/i2ellis.c +++ /dev/null | |||
@@ -1,1403 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * (c) 1998 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: Low-level interface code for the device driver | ||
12 | * (This is included source code, not a separate compilation | ||
13 | * module.) | ||
14 | * | ||
15 | *******************************************************************************/ | ||
16 | //--------------------------------------------- | ||
17 | // Function declarations private to this module | ||
18 | //--------------------------------------------- | ||
19 | // Functions called only indirectly through i2eBordStr entries. | ||
20 | |||
21 | static int iiWriteBuf16(i2eBordStrPtr, unsigned char *, int); | ||
22 | static int iiWriteBuf8(i2eBordStrPtr, unsigned char *, int); | ||
23 | static int iiReadBuf16(i2eBordStrPtr, unsigned char *, int); | ||
24 | static int iiReadBuf8(i2eBordStrPtr, unsigned char *, int); | ||
25 | |||
26 | static unsigned short iiReadWord16(i2eBordStrPtr); | ||
27 | static unsigned short iiReadWord8(i2eBordStrPtr); | ||
28 | static void iiWriteWord16(i2eBordStrPtr, unsigned short); | ||
29 | static void iiWriteWord8(i2eBordStrPtr, unsigned short); | ||
30 | |||
31 | static int iiWaitForTxEmptyII(i2eBordStrPtr, int); | ||
32 | static int iiWaitForTxEmptyIIEX(i2eBordStrPtr, int); | ||
33 | static int iiTxMailEmptyII(i2eBordStrPtr); | ||
34 | static int iiTxMailEmptyIIEX(i2eBordStrPtr); | ||
35 | static int iiTrySendMailII(i2eBordStrPtr, unsigned char); | ||
36 | static int iiTrySendMailIIEX(i2eBordStrPtr, unsigned char); | ||
37 | |||
38 | static unsigned short iiGetMailII(i2eBordStrPtr); | ||
39 | static unsigned short iiGetMailIIEX(i2eBordStrPtr); | ||
40 | |||
41 | static void iiEnableMailIrqII(i2eBordStrPtr); | ||
42 | static void iiEnableMailIrqIIEX(i2eBordStrPtr); | ||
43 | static void iiWriteMaskII(i2eBordStrPtr, unsigned char); | ||
44 | static void iiWriteMaskIIEX(i2eBordStrPtr, unsigned char); | ||
45 | |||
46 | static void ii2Nop(void); | ||
47 | |||
48 | //*************** | ||
49 | //* Static Data * | ||
50 | //*************** | ||
51 | |||
52 | static int ii2Safe; // Safe I/O address for delay routine | ||
53 | |||
54 | static int iiDelayed; // Set when the iiResetDelay function is | ||
55 | // called. Cleared when ANY board is reset. | ||
56 | static DEFINE_RWLOCK(Dl_spinlock); | ||
57 | |||
58 | //******** | ||
59 | //* Code * | ||
60 | //******** | ||
61 | |||
62 | //======================================================= | ||
63 | // Initialization Routines | ||
64 | // | ||
65 | // iiSetAddress | ||
66 | // iiReset | ||
67 | // iiResetDelay | ||
68 | // iiInitialize | ||
69 | //======================================================= | ||
70 | |||
71 | //****************************************************************************** | ||
72 | // Function: iiSetAddress(pB, address, delay) | ||
73 | // Parameters: pB - pointer to the board structure | ||
74 | // address - the purported I/O address of the board | ||
75 | // delay - pointer to the 1-ms delay function to use | ||
76 | // in this and any future operations to this board | ||
77 | // | ||
78 | // Returns: True if everything appears copacetic. | ||
79 | // False if there is any error: the pB->i2eError field has the error | ||
80 | // | ||
81 | // Description: | ||
82 | // | ||
83 | // This routine (roughly) checks for address validity, sets the i2eValid OK and | ||
84 | // sets the state to II_STATE_COLD which means that we haven't even sent a reset | ||
85 | // yet. | ||
86 | // | ||
87 | //****************************************************************************** | ||
88 | static int | ||
89 | iiSetAddress( i2eBordStrPtr pB, int address, delayFunc_t delay ) | ||
90 | { | ||
91 | // Should any failure occur before init is finished... | ||
92 | pB->i2eValid = I2E_INCOMPLETE; | ||
93 | |||
94 | // Cannot check upper limit except extremely: Might be microchannel | ||
95 | // Address must be on an 8-byte boundary | ||
96 | |||
97 | if ((unsigned int)address <= 0x100 | ||
98 | || (unsigned int)address >= 0xfff8 | ||
99 | || (address & 0x7) | ||
100 | ) | ||
101 | { | ||
102 | I2_COMPLETE(pB, I2EE_BADADDR); | ||
103 | } | ||
104 | |||
105 | // Initialize accelerators | ||
106 | pB->i2eBase = address; | ||
107 | pB->i2eData = address + FIFO_DATA; | ||
108 | pB->i2eStatus = address + FIFO_STATUS; | ||
109 | pB->i2ePointer = address + FIFO_PTR; | ||
110 | pB->i2eXMail = address + FIFO_MAIL; | ||
111 | pB->i2eXMask = address + FIFO_MASK; | ||
112 | |||
113 | // Initialize i/o address for ii2DelayIO | ||
114 | ii2Safe = address + FIFO_NOP; | ||
115 | |||
116 | // Initialize the delay routine | ||
117 | pB->i2eDelay = ((delay != (delayFunc_t)NULL) ? delay : (delayFunc_t)ii2Nop); | ||
118 | |||
119 | pB->i2eValid = I2E_MAGIC; | ||
120 | pB->i2eState = II_STATE_COLD; | ||
121 | |||
122 | I2_COMPLETE(pB, I2EE_GOOD); | ||
123 | } | ||
124 | |||
125 | //****************************************************************************** | ||
126 | // Function: iiReset(pB) | ||
127 | // Parameters: pB - pointer to the board structure | ||
128 | // | ||
129 | // Returns: True if everything appears copacetic. | ||
130 | // False if there is any error: the pB->i2eError field has the error | ||
131 | // | ||
132 | // Description: | ||
133 | // | ||
134 | // Attempts to reset the board (see also i2hw.h). Normally, we would use this to | ||
135 | // reset a board immediately after iiSetAddress(), but it is valid to reset a | ||
136 | // board from any state, say, in order to change or re-load loadware. (Under | ||
137 | // such circumstances, no reason to re-run iiSetAddress(), which is why it is a | ||
138 | // separate routine and not included in this routine. | ||
139 | // | ||
140 | //****************************************************************************** | ||
141 | static int | ||
142 | iiReset(i2eBordStrPtr pB) | ||
143 | { | ||
144 | // Magic number should be set, else even the address is suspect | ||
145 | if (pB->i2eValid != I2E_MAGIC) | ||
146 | { | ||
147 | I2_COMPLETE(pB, I2EE_BADMAGIC); | ||
148 | } | ||
149 | |||
150 | outb(0, pB->i2eBase + FIFO_RESET); /* Any data will do */ | ||
151 | iiDelay(pB, 50); // Pause between resets | ||
152 | outb(0, pB->i2eBase + FIFO_RESET); /* Second reset */ | ||
153 | |||
154 | // We must wait before even attempting to read anything from the FIFO: the | ||
155 | // board's P.O.S.T may actually attempt to read and write its end of the | ||
156 | // FIFO in order to check flags, loop back (where supported), etc. On | ||
157 | // completion of this testing it would reset the FIFO, and on completion | ||
158 | // of all // P.O.S.T., write the message. We must not mistake data which | ||
159 | // might have been sent for testing as part of the reset message. To | ||
160 | // better utilize time, say, when resetting several boards, we allow the | ||
161 | // delay to be performed externally; in this way the caller can reset | ||
162 | // several boards, delay a single time, then call the initialization | ||
163 | // routine for all. | ||
164 | |||
165 | pB->i2eState = II_STATE_RESET; | ||
166 | |||
167 | iiDelayed = 0; // i.e., the delay routine hasn't been called since the most | ||
168 | // recent reset. | ||
169 | |||
170 | // Ensure anything which would have been of use to standard loadware is | ||
171 | // blanked out, since board has now forgotten everything!. | ||
172 | |||
173 | pB->i2eUsingIrq = I2_IRQ_UNDEFINED; /* to not use an interrupt so far */ | ||
174 | pB->i2eWaitingForEmptyFifo = 0; | ||
175 | pB->i2eOutMailWaiting = 0; | ||
176 | pB->i2eChannelPtr = NULL; | ||
177 | pB->i2eChannelCnt = 0; | ||
178 | |||
179 | pB->i2eLeadoffWord[0] = 0; | ||
180 | pB->i2eFifoInInts = 0; | ||
181 | pB->i2eFifoOutInts = 0; | ||
182 | pB->i2eFatalTrap = NULL; | ||
183 | pB->i2eFatal = 0; | ||
184 | |||
185 | I2_COMPLETE(pB, I2EE_GOOD); | ||
186 | } | ||
187 | |||
188 | //****************************************************************************** | ||
189 | // Function: iiResetDelay(pB) | ||
190 | // Parameters: pB - pointer to the board structure | ||
191 | // | ||
192 | // Returns: True if everything appears copacetic. | ||
193 | // False if there is any error: the pB->i2eError field has the error | ||
194 | // | ||
195 | // Description: | ||
196 | // | ||
197 | // Using the delay defined in board structure, waits two seconds (for board to | ||
198 | // reset). | ||
199 | // | ||
200 | //****************************************************************************** | ||
201 | static int | ||
202 | iiResetDelay(i2eBordStrPtr pB) | ||
203 | { | ||
204 | if (pB->i2eValid != I2E_MAGIC) { | ||
205 | I2_COMPLETE(pB, I2EE_BADMAGIC); | ||
206 | } | ||
207 | if (pB->i2eState != II_STATE_RESET) { | ||
208 | I2_COMPLETE(pB, I2EE_BADSTATE); | ||
209 | } | ||
210 | iiDelay(pB,2000); /* Now we wait for two seconds. */ | ||
211 | iiDelayed = 1; /* Delay has been called: ok to initialize */ | ||
212 | I2_COMPLETE(pB, I2EE_GOOD); | ||
213 | } | ||
214 | |||
215 | //****************************************************************************** | ||
216 | // Function: iiInitialize(pB) | ||
217 | // Parameters: pB - pointer to the board structure | ||
218 | // | ||
219 | // Returns: True if everything appears copacetic. | ||
220 | // False if there is any error: the pB->i2eError field has the error | ||
221 | // | ||
222 | // Description: | ||
223 | // | ||
224 | // Attempts to read the Power-on reset message. Initializes any remaining fields | ||
225 | // in the pB structure. | ||
226 | // | ||
227 | // This should be called as the third step of a process beginning with | ||
228 | // iiReset(), then iiResetDelay(). This routine checks to see that the structure | ||
229 | // is "valid" and in the reset state, also confirms that the delay routine has | ||
230 | // been called since the latest reset (to any board! overly strong!). | ||
231 | // | ||
232 | //****************************************************************************** | ||
233 | static int | ||
234 | iiInitialize(i2eBordStrPtr pB) | ||
235 | { | ||
236 | int itemp; | ||
237 | unsigned char c; | ||
238 | unsigned short utemp; | ||
239 | unsigned int ilimit; | ||
240 | |||
241 | if (pB->i2eValid != I2E_MAGIC) | ||
242 | { | ||
243 | I2_COMPLETE(pB, I2EE_BADMAGIC); | ||
244 | } | ||
245 | |||
246 | if (pB->i2eState != II_STATE_RESET || !iiDelayed) | ||
247 | { | ||
248 | I2_COMPLETE(pB, I2EE_BADSTATE); | ||
249 | } | ||
250 | |||
251 | // In case there is a failure short of our completely reading the power-up | ||
252 | // message. | ||
253 | pB->i2eValid = I2E_INCOMPLETE; | ||
254 | |||
255 | |||
256 | // Now attempt to read the message. | ||
257 | |||
258 | for (itemp = 0; itemp < sizeof(porStr); itemp++) | ||
259 | { | ||
260 | // We expect the entire message is ready. | ||
261 | if (!I2_HAS_INPUT(pB)) { | ||
262 | pB->i2ePomSize = itemp; | ||
263 | I2_COMPLETE(pB, I2EE_PORM_SHORT); | ||
264 | } | ||
265 | |||
266 | pB->i2ePom.c[itemp] = c = inb(pB->i2eData); | ||
267 | |||
268 | // We check the magic numbers as soon as they are supposed to be read | ||
269 | // (rather than after) to minimize effect of reading something we | ||
270 | // already suspect can't be "us". | ||
271 | if ( (itemp == POR_1_INDEX && c != POR_MAGIC_1) || | ||
272 | (itemp == POR_2_INDEX && c != POR_MAGIC_2)) | ||
273 | { | ||
274 | pB->i2ePomSize = itemp+1; | ||
275 | I2_COMPLETE(pB, I2EE_BADMAGIC); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | pB->i2ePomSize = itemp; | ||
280 | |||
281 | // Ensure that this was all the data... | ||
282 | if (I2_HAS_INPUT(pB)) | ||
283 | I2_COMPLETE(pB, I2EE_PORM_LONG); | ||
284 | |||
285 | // For now, we'll fail to initialize if P.O.S.T reports bad chip mapper: | ||
286 | // Implying we will not be able to download any code either: That's ok: the | ||
287 | // condition is pretty explicit. | ||
288 | if (pB->i2ePom.e.porDiag1 & POR_BAD_MAPPER) | ||
289 | { | ||
290 | I2_COMPLETE(pB, I2EE_POSTERR); | ||
291 | } | ||
292 | |||
293 | // Determine anything which must be done differently depending on the family | ||
294 | // of boards! | ||
295 | switch (pB->i2ePom.e.porID & POR_ID_FAMILY) | ||
296 | { | ||
297 | case POR_ID_FII: // IntelliPort-II | ||
298 | |||
299 | pB->i2eFifoStyle = FIFO_II; | ||
300 | pB->i2eFifoSize = 512; // 512 bytes, always | ||
301 | pB->i2eDataWidth16 = false; | ||
302 | |||
303 | pB->i2eMaxIrq = 15; // Because board cannot tell us it is in an 8-bit | ||
304 | // slot, we do allow it to be done (documentation!) | ||
305 | |||
306 | pB->i2eGoodMap[1] = | ||
307 | pB->i2eGoodMap[2] = | ||
308 | pB->i2eGoodMap[3] = | ||
309 | pB->i2eChannelMap[1] = | ||
310 | pB->i2eChannelMap[2] = | ||
311 | pB->i2eChannelMap[3] = 0; | ||
312 | |||
313 | switch (pB->i2ePom.e.porID & POR_ID_SIZE) | ||
314 | { | ||
315 | case POR_ID_II_4: | ||
316 | pB->i2eGoodMap[0] = | ||
317 | pB->i2eChannelMap[0] = 0x0f; // four-port | ||
318 | |||
319 | // Since porPorts1 is based on the Hardware ID register, the numbers | ||
320 | // should always be consistent for IntelliPort-II. Ditto below... | ||
321 | if (pB->i2ePom.e.porPorts1 != 4) | ||
322 | { | ||
323 | I2_COMPLETE(pB, I2EE_INCONSIST); | ||
324 | } | ||
325 | break; | ||
326 | |||
327 | case POR_ID_II_8: | ||
328 | case POR_ID_II_8R: | ||
329 | pB->i2eGoodMap[0] = | ||
330 | pB->i2eChannelMap[0] = 0xff; // Eight port | ||
331 | if (pB->i2ePom.e.porPorts1 != 8) | ||
332 | { | ||
333 | I2_COMPLETE(pB, I2EE_INCONSIST); | ||
334 | } | ||
335 | break; | ||
336 | |||
337 | case POR_ID_II_6: | ||
338 | pB->i2eGoodMap[0] = | ||
339 | pB->i2eChannelMap[0] = 0x3f; // Six Port | ||
340 | if (pB->i2ePom.e.porPorts1 != 6) | ||
341 | { | ||
342 | I2_COMPLETE(pB, I2EE_INCONSIST); | ||
343 | } | ||
344 | break; | ||
345 | } | ||
346 | |||
347 | // Fix up the "good channel list based on any errors reported. | ||
348 | if (pB->i2ePom.e.porDiag1 & POR_BAD_UART1) | ||
349 | { | ||
350 | pB->i2eGoodMap[0] &= ~0x0f; | ||
351 | } | ||
352 | |||
353 | if (pB->i2ePom.e.porDiag1 & POR_BAD_UART2) | ||
354 | { | ||
355 | pB->i2eGoodMap[0] &= ~0xf0; | ||
356 | } | ||
357 | |||
358 | break; // POR_ID_FII case | ||
359 | |||
360 | case POR_ID_FIIEX: // IntelliPort-IIEX | ||
361 | |||
362 | pB->i2eFifoStyle = FIFO_IIEX; | ||
363 | |||
364 | itemp = pB->i2ePom.e.porFifoSize; | ||
365 | |||
366 | // Implicit assumption that fifo would not grow beyond 32k, | ||
367 | // nor would ever be less than 256. | ||
368 | |||
369 | if (itemp < 8 || itemp > 15) | ||
370 | { | ||
371 | I2_COMPLETE(pB, I2EE_INCONSIST); | ||
372 | } | ||
373 | pB->i2eFifoSize = (1 << itemp); | ||
374 | |||
375 | // These are based on what P.O.S.T thinks should be there, based on | ||
376 | // box ID registers | ||
377 | ilimit = pB->i2ePom.e.porNumBoxes; | ||
378 | if (ilimit > ABS_MAX_BOXES) | ||
379 | { | ||
380 | ilimit = ABS_MAX_BOXES; | ||
381 | } | ||
382 | |||
383 | // For as many boxes as EXIST, gives the type of box. | ||
384 | // Added 8/6/93: check for the ISA-4 (asic) which looks like an | ||
385 | // expandable but for whom "8 or 16?" is not the right question. | ||
386 | |||
387 | utemp = pB->i2ePom.e.porFlags; | ||
388 | if (utemp & POR_CEX4) | ||
389 | { | ||
390 | pB->i2eChannelMap[0] = 0x000f; | ||
391 | } else { | ||
392 | utemp &= POR_BOXES; | ||
393 | for (itemp = 0; itemp < ilimit; itemp++) | ||
394 | { | ||
395 | pB->i2eChannelMap[itemp] = | ||
396 | ((utemp & POR_BOX_16) ? 0xffff : 0x00ff); | ||
397 | utemp >>= 1; | ||
398 | } | ||
399 | } | ||
400 | |||
401 | // These are based on what P.O.S.T actually found. | ||
402 | |||
403 | utemp = (pB->i2ePom.e.porPorts2 << 8) + pB->i2ePom.e.porPorts1; | ||
404 | |||
405 | for (itemp = 0; itemp < ilimit; itemp++) | ||
406 | { | ||
407 | pB->i2eGoodMap[itemp] = 0; | ||
408 | if (utemp & 1) pB->i2eGoodMap[itemp] |= 0x000f; | ||
409 | if (utemp & 2) pB->i2eGoodMap[itemp] |= 0x00f0; | ||
410 | if (utemp & 4) pB->i2eGoodMap[itemp] |= 0x0f00; | ||
411 | if (utemp & 8) pB->i2eGoodMap[itemp] |= 0xf000; | ||
412 | utemp >>= 4; | ||
413 | } | ||
414 | |||
415 | // Now determine whether we should transfer in 8 or 16-bit mode. | ||
416 | switch (pB->i2ePom.e.porBus & (POR_BUS_SLOT16 | POR_BUS_DIP16) ) | ||
417 | { | ||
418 | case POR_BUS_SLOT16 | POR_BUS_DIP16: | ||
419 | pB->i2eDataWidth16 = true; | ||
420 | pB->i2eMaxIrq = 15; | ||
421 | break; | ||
422 | |||
423 | case POR_BUS_SLOT16: | ||
424 | pB->i2eDataWidth16 = false; | ||
425 | pB->i2eMaxIrq = 15; | ||
426 | break; | ||
427 | |||
428 | case 0: | ||
429 | case POR_BUS_DIP16: // In an 8-bit slot, DIP switch don't care. | ||
430 | default: | ||
431 | pB->i2eDataWidth16 = false; | ||
432 | pB->i2eMaxIrq = 7; | ||
433 | break; | ||
434 | } | ||
435 | break; // POR_ID_FIIEX case | ||
436 | |||
437 | default: // Unknown type of board | ||
438 | I2_COMPLETE(pB, I2EE_BAD_FAMILY); | ||
439 | break; | ||
440 | } // End the switch based on family | ||
441 | |||
442 | // Temporarily, claim there is no room in the outbound fifo. | ||
443 | // We will maintain this whenever we check for an empty outbound FIFO. | ||
444 | pB->i2eFifoRemains = 0; | ||
445 | |||
446 | // Now, based on the bus type, should we expect to be able to re-configure | ||
447 | // interrupts (say, for testing purposes). | ||
448 | switch (pB->i2ePom.e.porBus & POR_BUS_TYPE) | ||
449 | { | ||
450 | case POR_BUS_T_ISA: | ||
451 | case POR_BUS_T_UNK: // If the type of bus is undeclared, assume ok. | ||
452 | case POR_BUS_T_MCA: | ||
453 | case POR_BUS_T_EISA: | ||
454 | break; | ||
455 | default: | ||
456 | I2_COMPLETE(pB, I2EE_BADBUS); | ||
457 | } | ||
458 | |||
459 | if (pB->i2eDataWidth16) | ||
460 | { | ||
461 | pB->i2eWriteBuf = iiWriteBuf16; | ||
462 | pB->i2eReadBuf = iiReadBuf16; | ||
463 | pB->i2eWriteWord = iiWriteWord16; | ||
464 | pB->i2eReadWord = iiReadWord16; | ||
465 | } else { | ||
466 | pB->i2eWriteBuf = iiWriteBuf8; | ||
467 | pB->i2eReadBuf = iiReadBuf8; | ||
468 | pB->i2eWriteWord = iiWriteWord8; | ||
469 | pB->i2eReadWord = iiReadWord8; | ||
470 | } | ||
471 | |||
472 | switch(pB->i2eFifoStyle) | ||
473 | { | ||
474 | case FIFO_II: | ||
475 | pB->i2eWaitForTxEmpty = iiWaitForTxEmptyII; | ||
476 | pB->i2eTxMailEmpty = iiTxMailEmptyII; | ||
477 | pB->i2eTrySendMail = iiTrySendMailII; | ||
478 | pB->i2eGetMail = iiGetMailII; | ||
479 | pB->i2eEnableMailIrq = iiEnableMailIrqII; | ||
480 | pB->i2eWriteMask = iiWriteMaskII; | ||
481 | |||
482 | break; | ||
483 | |||
484 | case FIFO_IIEX: | ||
485 | pB->i2eWaitForTxEmpty = iiWaitForTxEmptyIIEX; | ||
486 | pB->i2eTxMailEmpty = iiTxMailEmptyIIEX; | ||
487 | pB->i2eTrySendMail = iiTrySendMailIIEX; | ||
488 | pB->i2eGetMail = iiGetMailIIEX; | ||
489 | pB->i2eEnableMailIrq = iiEnableMailIrqIIEX; | ||
490 | pB->i2eWriteMask = iiWriteMaskIIEX; | ||
491 | |||
492 | break; | ||
493 | |||
494 | default: | ||
495 | I2_COMPLETE(pB, I2EE_INCONSIST); | ||
496 | } | ||
497 | |||
498 | // Initialize state information. | ||
499 | pB->i2eState = II_STATE_READY; // Ready to load loadware. | ||
500 | |||
501 | // Some Final cleanup: | ||
502 | // For some boards, the bootstrap firmware may perform some sort of test | ||
503 | // resulting in a stray character pending in the incoming mailbox. If one is | ||
504 | // there, it should be read and discarded, especially since for the standard | ||
505 | // firmware, it's the mailbox that interrupts the host. | ||
506 | |||
507 | pB->i2eStartMail = iiGetMail(pB); | ||
508 | |||
509 | // Throw it away and clear the mailbox structure element | ||
510 | pB->i2eStartMail = NO_MAIL_HERE; | ||
511 | |||
512 | // Everything is ok now, return with good status/ | ||
513 | |||
514 | pB->i2eValid = I2E_MAGIC; | ||
515 | I2_COMPLETE(pB, I2EE_GOOD); | ||
516 | } | ||
517 | |||
518 | //****************************************************************************** | ||
519 | // Function: ii2DelayTimer(mseconds) | ||
520 | // Parameters: mseconds - number of milliseconds to delay | ||
521 | // | ||
522 | // Returns: Nothing | ||
523 | // | ||
524 | // Description: | ||
525 | // | ||
526 | // This routine delays for approximately mseconds milliseconds and is intended | ||
527 | // to be called indirectly through i2Delay field in i2eBordStr. It uses the | ||
528 | // Linux timer_list mechanism. | ||
529 | // | ||
530 | // The Linux timers use a unit called "jiffies" which are 10mS in the Intel | ||
531 | // architecture. This function rounds the delay period up to the next "jiffy". | ||
532 | // In the Alpha architecture the "jiffy" is 1mS, but this driver is not intended | ||
533 | // for Alpha platforms at this time. | ||
534 | // | ||
535 | //****************************************************************************** | ||
536 | static void | ||
537 | ii2DelayTimer(unsigned int mseconds) | ||
538 | { | ||
539 | msleep_interruptible(mseconds); | ||
540 | } | ||
541 | |||
542 | #if 0 | ||
543 | //static void ii2DelayIO(unsigned int); | ||
544 | //****************************************************************************** | ||
545 | // !!! Not Used, this is DOS crap, some of you young folks may be interested in | ||
546 | // in how things were done in the stone age of caculating machines !!! | ||
547 | // Function: ii2DelayIO(mseconds) | ||
548 | // Parameters: mseconds - number of milliseconds to delay | ||
549 | // | ||
550 | // Returns: Nothing | ||
551 | // | ||
552 | // Description: | ||
553 | // | ||
554 | // This routine delays for approximately mseconds milliseconds and is intended | ||
555 | // to be called indirectly through i2Delay field in i2eBordStr. It is intended | ||
556 | // for use where a clock-based function is impossible: for example, DOS drivers. | ||
557 | // | ||
558 | // This function uses the IN instruction to place bounds on the timing and | ||
559 | // assumes that ii2Safe has been set. This is because I/O instructions are not | ||
560 | // subject to caching and will therefore take a certain minimum time. To ensure | ||
561 | // the delay is at least long enough on fast machines, it is based on some | ||
562 | // fastest-case calculations. On slower machines this may cause VERY long | ||
563 | // delays. (3 x fastest case). In the fastest case, everything is cached except | ||
564 | // the I/O instruction itself. | ||
565 | // | ||
566 | // Timing calculations: | ||
567 | // The fastest bus speed for I/O operations is likely to be 10 MHz. The I/O | ||
568 | // operation in question is a byte operation to an odd address. For 8-bit | ||
569 | // operations, the architecture generally enforces two wait states. At 10 MHz, a | ||
570 | // single cycle time is 100nS. A read operation at two wait states takes 6 | ||
571 | // cycles for a total time of 600nS. Therefore approximately 1666 iterations | ||
572 | // would be required to generate a single millisecond delay. The worst | ||
573 | // (reasonable) case would be an 8MHz system with no cacheing. In this case, the | ||
574 | // I/O instruction would take 125nS x 6 cyles = 750 nS. More importantly, code | ||
575 | // fetch of other instructions in the loop would take time (zero wait states, | ||
576 | // however) and would be hard to estimate. This is minimized by using in-line | ||
577 | // assembler for the in inner loop of IN instructions. This consists of just a | ||
578 | // few bytes. So we'll guess about four code fetches per loop. Each code fetch | ||
579 | // should take four cycles, so we have 125nS * 8 = 1000nS. Worst case then is | ||
580 | // that what should have taken 1 mS takes instead 1666 * (1750) = 2.9 mS. | ||
581 | // | ||
582 | // So much for theoretical timings: results using 1666 value on some actual | ||
583 | // machines: | ||
584 | // IBM 286 6MHz 3.15 mS | ||
585 | // Zenith 386 33MHz 2.45 mS | ||
586 | // (brandX) 386 33MHz 1.90 mS (has cache) | ||
587 | // (brandY) 486 33MHz 2.35 mS | ||
588 | // NCR 486 ?? 1.65 mS (microchannel) | ||
589 | // | ||
590 | // For most machines, it is probably safe to scale this number back (remember, | ||
591 | // for robust operation use an actual timed delay if possible), so we are using | ||
592 | // a value of 1190. This yields 1.17 mS for the fastest machine in our sample, | ||
593 | // 1.75 mS for typical 386 machines, and 2.25 mS the absolute slowest machine. | ||
594 | // | ||
595 | // 1/29/93: | ||
596 | // The above timings are too slow. Actual cycle times might be faster. ISA cycle | ||
597 | // times could approach 500 nS, and ... | ||
598 | // The IBM model 77 being microchannel has no wait states for 8-bit reads and | ||
599 | // seems to be accessing the I/O at 440 nS per access (from start of one to | ||
600 | // start of next). This would imply we need 1000/.440 = 2272 iterations to | ||
601 | // guarantee we are fast enough. In actual testing, we see that 2 * 1190 are in | ||
602 | // fact enough. For diagnostics, we keep the level at 1190, but developers note | ||
603 | // this needs tuning. | ||
604 | // | ||
605 | // Safe assumption: 2270 i/o reads = 1 millisecond | ||
606 | // | ||
607 | //****************************************************************************** | ||
608 | |||
609 | |||
610 | static int ii2DelValue = 1190; // See timing calculations below | ||
611 | // 1666 for fastest theoretical machine | ||
612 | // 1190 safe for most fast 386 machines | ||
613 | // 1000 for fastest machine tested here | ||
614 | // 540 (sic) for AT286/6Mhz | ||
615 | static void | ||
616 | ii2DelayIO(unsigned int mseconds) | ||
617 | { | ||
618 | if (!ii2Safe) | ||
619 | return; /* Do nothing if this variable uninitialized */ | ||
620 | |||
621 | while(mseconds--) { | ||
622 | int i = ii2DelValue; | ||
623 | while ( i-- ) { | ||
624 | inb(ii2Safe); | ||
625 | } | ||
626 | } | ||
627 | } | ||
628 | #endif | ||
629 | |||
630 | //****************************************************************************** | ||
631 | // Function: ii2Nop() | ||
632 | // Parameters: None | ||
633 | // | ||
634 | // Returns: Nothing | ||
635 | // | ||
636 | // Description: | ||
637 | // | ||
638 | // iiInitialize will set i2eDelay to this if the delay parameter is NULL. This | ||
639 | // saves checking for a NULL pointer at every call. | ||
640 | //****************************************************************************** | ||
641 | static void | ||
642 | ii2Nop(void) | ||
643 | { | ||
644 | return; // no mystery here | ||
645 | } | ||
646 | |||
647 | //======================================================= | ||
648 | // Routines which are available in 8/16-bit versions, or | ||
649 | // in different fifo styles. These are ALL called | ||
650 | // indirectly through the board structure. | ||
651 | //======================================================= | ||
652 | |||
653 | //****************************************************************************** | ||
654 | // Function: iiWriteBuf16(pB, address, count) | ||
655 | // Parameters: pB - pointer to board structure | ||
656 | // address - address of data to write | ||
657 | // count - number of data bytes to write | ||
658 | // | ||
659 | // Returns: True if everything appears copacetic. | ||
660 | // False if there is any error: the pB->i2eError field has the error | ||
661 | // | ||
662 | // Description: | ||
663 | // | ||
664 | // Writes 'count' bytes from 'address' to the data fifo specified by the board | ||
665 | // structure pointer pB. Should count happen to be odd, an extra pad byte is | ||
666 | // sent (identity unknown...). Uses 16-bit (word) operations. Is called | ||
667 | // indirectly through pB->i2eWriteBuf. | ||
668 | // | ||
669 | //****************************************************************************** | ||
670 | static int | ||
671 | iiWriteBuf16(i2eBordStrPtr pB, unsigned char *address, int count) | ||
672 | { | ||
673 | // Rudimentary sanity checking here. | ||
674 | if (pB->i2eValid != I2E_MAGIC) | ||
675 | I2_COMPLETE(pB, I2EE_INVALID); | ||
676 | |||
677 | I2_OUTSW(pB->i2eData, address, count); | ||
678 | |||
679 | I2_COMPLETE(pB, I2EE_GOOD); | ||
680 | } | ||
681 | |||
682 | //****************************************************************************** | ||
683 | // Function: iiWriteBuf8(pB, address, count) | ||
684 | // Parameters: pB - pointer to board structure | ||
685 | // address - address of data to write | ||
686 | // count - number of data bytes to write | ||
687 | // | ||
688 | // Returns: True if everything appears copacetic. | ||
689 | // False if there is any error: the pB->i2eError field has the error | ||
690 | // | ||
691 | // Description: | ||
692 | // | ||
693 | // Writes 'count' bytes from 'address' to the data fifo specified by the board | ||
694 | // structure pointer pB. Should count happen to be odd, an extra pad byte is | ||
695 | // sent (identity unknown...). This is to be consistent with the 16-bit version. | ||
696 | // Uses 8-bit (byte) operations. Is called indirectly through pB->i2eWriteBuf. | ||
697 | // | ||
698 | //****************************************************************************** | ||
699 | static int | ||
700 | iiWriteBuf8(i2eBordStrPtr pB, unsigned char *address, int count) | ||
701 | { | ||
702 | /* Rudimentary sanity checking here */ | ||
703 | if (pB->i2eValid != I2E_MAGIC) | ||
704 | I2_COMPLETE(pB, I2EE_INVALID); | ||
705 | |||
706 | I2_OUTSB(pB->i2eData, address, count); | ||
707 | |||
708 | I2_COMPLETE(pB, I2EE_GOOD); | ||
709 | } | ||
710 | |||
711 | //****************************************************************************** | ||
712 | // Function: iiReadBuf16(pB, address, count) | ||
713 | // Parameters: pB - pointer to board structure | ||
714 | // address - address to put data read | ||
715 | // count - number of data bytes to read | ||
716 | // | ||
717 | // Returns: True if everything appears copacetic. | ||
718 | // False if there is any error: the pB->i2eError field has the error | ||
719 | // | ||
720 | // Description: | ||
721 | // | ||
722 | // Reads 'count' bytes into 'address' from the data fifo specified by the board | ||
723 | // structure pointer pB. Should count happen to be odd, an extra pad byte is | ||
724 | // received (identity unknown...). Uses 16-bit (word) operations. Is called | ||
725 | // indirectly through pB->i2eReadBuf. | ||
726 | // | ||
727 | //****************************************************************************** | ||
728 | static int | ||
729 | iiReadBuf16(i2eBordStrPtr pB, unsigned char *address, int count) | ||
730 | { | ||
731 | // Rudimentary sanity checking here. | ||
732 | if (pB->i2eValid != I2E_MAGIC) | ||
733 | I2_COMPLETE(pB, I2EE_INVALID); | ||
734 | |||
735 | I2_INSW(pB->i2eData, address, count); | ||
736 | |||
737 | I2_COMPLETE(pB, I2EE_GOOD); | ||
738 | } | ||
739 | |||
740 | //****************************************************************************** | ||
741 | // Function: iiReadBuf8(pB, address, count) | ||
742 | // Parameters: pB - pointer to board structure | ||
743 | // address - address to put data read | ||
744 | // count - number of data bytes to read | ||
745 | // | ||
746 | // Returns: True if everything appears copacetic. | ||
747 | // False if there is any error: the pB->i2eError field has the error | ||
748 | // | ||
749 | // Description: | ||
750 | // | ||
751 | // Reads 'count' bytes into 'address' from the data fifo specified by the board | ||
752 | // structure pointer pB. Should count happen to be odd, an extra pad byte is | ||
753 | // received (identity unknown...). This to match the 16-bit behaviour. Uses | ||
754 | // 8-bit (byte) operations. Is called indirectly through pB->i2eReadBuf. | ||
755 | // | ||
756 | //****************************************************************************** | ||
757 | static int | ||
758 | iiReadBuf8(i2eBordStrPtr pB, unsigned char *address, int count) | ||
759 | { | ||
760 | // Rudimentary sanity checking here. | ||
761 | if (pB->i2eValid != I2E_MAGIC) | ||
762 | I2_COMPLETE(pB, I2EE_INVALID); | ||
763 | |||
764 | I2_INSB(pB->i2eData, address, count); | ||
765 | |||
766 | I2_COMPLETE(pB, I2EE_GOOD); | ||
767 | } | ||
768 | |||
769 | //****************************************************************************** | ||
770 | // Function: iiReadWord16(pB) | ||
771 | // Parameters: pB - pointer to board structure | ||
772 | // | ||
773 | // Returns: True if everything appears copacetic. | ||
774 | // False if there is any error: the pB->i2eError field has the error | ||
775 | // | ||
776 | // Description: | ||
777 | // | ||
778 | // Returns the word read from the data fifo specified by the board-structure | ||
779 | // pointer pB. Uses a 16-bit operation. Is called indirectly through | ||
780 | // pB->i2eReadWord. | ||
781 | // | ||
782 | //****************************************************************************** | ||
783 | static unsigned short | ||
784 | iiReadWord16(i2eBordStrPtr pB) | ||
785 | { | ||
786 | return inw(pB->i2eData); | ||
787 | } | ||
788 | |||
789 | //****************************************************************************** | ||
790 | // Function: iiReadWord8(pB) | ||
791 | // Parameters: pB - pointer to board structure | ||
792 | // | ||
793 | // Returns: True if everything appears copacetic. | ||
794 | // False if there is any error: the pB->i2eError field has the error | ||
795 | // | ||
796 | // Description: | ||
797 | // | ||
798 | // Returns the word read from the data fifo specified by the board-structure | ||
799 | // pointer pB. Uses two 8-bit operations. Bytes are assumed to be LSB first. Is | ||
800 | // called indirectly through pB->i2eReadWord. | ||
801 | // | ||
802 | //****************************************************************************** | ||
803 | static unsigned short | ||
804 | iiReadWord8(i2eBordStrPtr pB) | ||
805 | { | ||
806 | unsigned short urs; | ||
807 | |||
808 | urs = inb(pB->i2eData); | ||
809 | |||
810 | return (inb(pB->i2eData) << 8) | urs; | ||
811 | } | ||
812 | |||
813 | //****************************************************************************** | ||
814 | // Function: iiWriteWord16(pB, value) | ||
815 | // Parameters: pB - pointer to board structure | ||
816 | // value - data to write | ||
817 | // | ||
818 | // Returns: True if everything appears copacetic. | ||
819 | // False if there is any error: the pB->i2eError field has the error | ||
820 | // | ||
821 | // Description: | ||
822 | // | ||
823 | // Writes the word 'value' to the data fifo specified by the board-structure | ||
824 | // pointer pB. Uses 16-bit operation. Is called indirectly through | ||
825 | // pB->i2eWriteWord. | ||
826 | // | ||
827 | //****************************************************************************** | ||
828 | static void | ||
829 | iiWriteWord16(i2eBordStrPtr pB, unsigned short value) | ||
830 | { | ||
831 | outw((int)value, pB->i2eData); | ||
832 | } | ||
833 | |||
834 | //****************************************************************************** | ||
835 | // Function: iiWriteWord8(pB, value) | ||
836 | // Parameters: pB - pointer to board structure | ||
837 | // value - data to write | ||
838 | // | ||
839 | // Returns: True if everything appears copacetic. | ||
840 | // False if there is any error: the pB->i2eError field has the error | ||
841 | // | ||
842 | // Description: | ||
843 | // | ||
844 | // Writes the word 'value' to the data fifo specified by the board-structure | ||
845 | // pointer pB. Uses two 8-bit operations (writes LSB first). Is called | ||
846 | // indirectly through pB->i2eWriteWord. | ||
847 | // | ||
848 | //****************************************************************************** | ||
849 | static void | ||
850 | iiWriteWord8(i2eBordStrPtr pB, unsigned short value) | ||
851 | { | ||
852 | outb((char)value, pB->i2eData); | ||
853 | outb((char)(value >> 8), pB->i2eData); | ||
854 | } | ||
855 | |||
856 | //****************************************************************************** | ||
857 | // Function: iiWaitForTxEmptyII(pB, mSdelay) | ||
858 | // Parameters: pB - pointer to board structure | ||
859 | // mSdelay - period to wait before returning | ||
860 | // | ||
861 | // Returns: True if the FIFO is empty. | ||
862 | // False if it not empty in the required time: the pB->i2eError | ||
863 | // field has the error. | ||
864 | // | ||
865 | // Description: | ||
866 | // | ||
867 | // Waits up to "mSdelay" milliseconds for the outgoing FIFO to become empty; if | ||
868 | // not empty by the required time, returns false and error in pB->i2eError, | ||
869 | // otherwise returns true. | ||
870 | // | ||
871 | // mSdelay == 0 is taken to mean must be empty on the first test. | ||
872 | // | ||
873 | // This version operates on IntelliPort-II - style FIFO's | ||
874 | // | ||
875 | // Note this routine is organized so that if status is ok there is no delay at | ||
876 | // all called either before or after the test. Is called indirectly through | ||
877 | // pB->i2eWaitForTxEmpty. | ||
878 | // | ||
879 | //****************************************************************************** | ||
880 | static int | ||
881 | iiWaitForTxEmptyII(i2eBordStrPtr pB, int mSdelay) | ||
882 | { | ||
883 | unsigned long flags; | ||
884 | int itemp; | ||
885 | |||
886 | for (;;) | ||
887 | { | ||
888 | // This routine hinges on being able to see the "other" status register | ||
889 | // (as seen by the local processor). His incoming fifo is our outgoing | ||
890 | // FIFO. | ||
891 | // | ||
892 | // By the nature of this routine, you would be using this as part of a | ||
893 | // larger atomic context: i.e., you would use this routine to ensure the | ||
894 | // fifo empty, then act on this information. Between these two halves, | ||
895 | // you will generally not want to service interrupts or in any way | ||
896 | // disrupt the assumptions implicit in the larger context. | ||
897 | // | ||
898 | // Even worse, however, this routine "shifts" the status register to | ||
899 | // point to the local status register which is not the usual situation. | ||
900 | // Therefore for extra safety, we force the critical section to be | ||
901 | // completely atomic, and pick up after ourselves before allowing any | ||
902 | // interrupts of any kind. | ||
903 | |||
904 | |||
905 | write_lock_irqsave(&Dl_spinlock, flags); | ||
906 | outb(SEL_COMMAND, pB->i2ePointer); | ||
907 | outb(SEL_CMD_SH, pB->i2ePointer); | ||
908 | |||
909 | itemp = inb(pB->i2eStatus); | ||
910 | |||
911 | outb(SEL_COMMAND, pB->i2ePointer); | ||
912 | outb(SEL_CMD_UNSH, pB->i2ePointer); | ||
913 | |||
914 | if (itemp & ST_IN_EMPTY) | ||
915 | { | ||
916 | I2_UPDATE_FIFO_ROOM(pB); | ||
917 | write_unlock_irqrestore(&Dl_spinlock, flags); | ||
918 | I2_COMPLETE(pB, I2EE_GOOD); | ||
919 | } | ||
920 | |||
921 | write_unlock_irqrestore(&Dl_spinlock, flags); | ||
922 | |||
923 | if (mSdelay-- == 0) | ||
924 | break; | ||
925 | |||
926 | iiDelay(pB, 1); /* 1 mS granularity on checking condition */ | ||
927 | } | ||
928 | I2_COMPLETE(pB, I2EE_TXE_TIME); | ||
929 | } | ||
930 | |||
931 | //****************************************************************************** | ||
932 | // Function: iiWaitForTxEmptyIIEX(pB, mSdelay) | ||
933 | // Parameters: pB - pointer to board structure | ||
934 | // mSdelay - period to wait before returning | ||
935 | // | ||
936 | // Returns: True if the FIFO is empty. | ||
937 | // False if it not empty in the required time: the pB->i2eError | ||
938 | // field has the error. | ||
939 | // | ||
940 | // Description: | ||
941 | // | ||
942 | // Waits up to "mSdelay" milliseconds for the outgoing FIFO to become empty; if | ||
943 | // not empty by the required time, returns false and error in pB->i2eError, | ||
944 | // otherwise returns true. | ||
945 | // | ||
946 | // mSdelay == 0 is taken to mean must be empty on the first test. | ||
947 | // | ||
948 | // This version operates on IntelliPort-IIEX - style FIFO's | ||
949 | // | ||
950 | // Note this routine is organized so that if status is ok there is no delay at | ||
951 | // all called either before or after the test. Is called indirectly through | ||
952 | // pB->i2eWaitForTxEmpty. | ||
953 | // | ||
954 | //****************************************************************************** | ||
955 | static int | ||
956 | iiWaitForTxEmptyIIEX(i2eBordStrPtr pB, int mSdelay) | ||
957 | { | ||
958 | unsigned long flags; | ||
959 | |||
960 | for (;;) | ||
961 | { | ||
962 | // By the nature of this routine, you would be using this as part of a | ||
963 | // larger atomic context: i.e., you would use this routine to ensure the | ||
964 | // fifo empty, then act on this information. Between these two halves, | ||
965 | // you will generally not want to service interrupts or in any way | ||
966 | // disrupt the assumptions implicit in the larger context. | ||
967 | |||
968 | write_lock_irqsave(&Dl_spinlock, flags); | ||
969 | |||
970 | if (inb(pB->i2eStatus) & STE_OUT_MT) { | ||
971 | I2_UPDATE_FIFO_ROOM(pB); | ||
972 | write_unlock_irqrestore(&Dl_spinlock, flags); | ||
973 | I2_COMPLETE(pB, I2EE_GOOD); | ||
974 | } | ||
975 | write_unlock_irqrestore(&Dl_spinlock, flags); | ||
976 | |||
977 | if (mSdelay-- == 0) | ||
978 | break; | ||
979 | |||
980 | iiDelay(pB, 1); // 1 mS granularity on checking condition | ||
981 | } | ||
982 | I2_COMPLETE(pB, I2EE_TXE_TIME); | ||
983 | } | ||
984 | |||
985 | //****************************************************************************** | ||
986 | // Function: iiTxMailEmptyII(pB) | ||
987 | // Parameters: pB - pointer to board structure | ||
988 | // | ||
989 | // Returns: True if the transmit mailbox is empty. | ||
990 | // False if it not empty. | ||
991 | // | ||
992 | // Description: | ||
993 | // | ||
994 | // Returns true or false according to whether the transmit mailbox is empty (and | ||
995 | // therefore able to accept more mail) | ||
996 | // | ||
997 | // This version operates on IntelliPort-II - style FIFO's | ||
998 | // | ||
999 | //****************************************************************************** | ||
1000 | static int | ||
1001 | iiTxMailEmptyII(i2eBordStrPtr pB) | ||
1002 | { | ||
1003 | int port = pB->i2ePointer; | ||
1004 | outb(SEL_OUTMAIL, port); | ||
1005 | return inb(port) == 0; | ||
1006 | } | ||
1007 | |||
1008 | //****************************************************************************** | ||
1009 | // Function: iiTxMailEmptyIIEX(pB) | ||
1010 | // Parameters: pB - pointer to board structure | ||
1011 | // | ||
1012 | // Returns: True if the transmit mailbox is empty. | ||
1013 | // False if it not empty. | ||
1014 | // | ||
1015 | // Description: | ||
1016 | // | ||
1017 | // Returns true or false according to whether the transmit mailbox is empty (and | ||
1018 | // therefore able to accept more mail) | ||
1019 | // | ||
1020 | // This version operates on IntelliPort-IIEX - style FIFO's | ||
1021 | // | ||
1022 | //****************************************************************************** | ||
1023 | static int | ||
1024 | iiTxMailEmptyIIEX(i2eBordStrPtr pB) | ||
1025 | { | ||
1026 | return !(inb(pB->i2eStatus) & STE_OUT_MAIL); | ||
1027 | } | ||
1028 | |||
1029 | //****************************************************************************** | ||
1030 | // Function: iiTrySendMailII(pB,mail) | ||
1031 | // Parameters: pB - pointer to board structure | ||
1032 | // mail - value to write to mailbox | ||
1033 | // | ||
1034 | // Returns: True if the transmit mailbox is empty, and mail is sent. | ||
1035 | // False if it not empty. | ||
1036 | // | ||
1037 | // Description: | ||
1038 | // | ||
1039 | // If outgoing mailbox is empty, sends mail and returns true. If outgoing | ||
1040 | // mailbox is not empty, returns false. | ||
1041 | // | ||
1042 | // This version operates on IntelliPort-II - style FIFO's | ||
1043 | // | ||
1044 | //****************************************************************************** | ||
1045 | static int | ||
1046 | iiTrySendMailII(i2eBordStrPtr pB, unsigned char mail) | ||
1047 | { | ||
1048 | int port = pB->i2ePointer; | ||
1049 | |||
1050 | outb(SEL_OUTMAIL, port); | ||
1051 | if (inb(port) == 0) { | ||
1052 | outb(SEL_OUTMAIL, port); | ||
1053 | outb(mail, port); | ||
1054 | return 1; | ||
1055 | } | ||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | //****************************************************************************** | ||
1060 | // Function: iiTrySendMailIIEX(pB,mail) | ||
1061 | // Parameters: pB - pointer to board structure | ||
1062 | // mail - value to write to mailbox | ||
1063 | // | ||
1064 | // Returns: True if the transmit mailbox is empty, and mail is sent. | ||
1065 | // False if it not empty. | ||
1066 | // | ||
1067 | // Description: | ||
1068 | // | ||
1069 | // If outgoing mailbox is empty, sends mail and returns true. If outgoing | ||
1070 | // mailbox is not empty, returns false. | ||
1071 | // | ||
1072 | // This version operates on IntelliPort-IIEX - style FIFO's | ||
1073 | // | ||
1074 | //****************************************************************************** | ||
1075 | static int | ||
1076 | iiTrySendMailIIEX(i2eBordStrPtr pB, unsigned char mail) | ||
1077 | { | ||
1078 | if (inb(pB->i2eStatus) & STE_OUT_MAIL) | ||
1079 | return 0; | ||
1080 | outb(mail, pB->i2eXMail); | ||
1081 | return 1; | ||
1082 | } | ||
1083 | |||
1084 | //****************************************************************************** | ||
1085 | // Function: iiGetMailII(pB,mail) | ||
1086 | // Parameters: pB - pointer to board structure | ||
1087 | // | ||
1088 | // Returns: Mailbox data or NO_MAIL_HERE. | ||
1089 | // | ||
1090 | // Description: | ||
1091 | // | ||
1092 | // If no mail available, returns NO_MAIL_HERE otherwise returns the data from | ||
1093 | // the mailbox, which is guaranteed != NO_MAIL_HERE. | ||
1094 | // | ||
1095 | // This version operates on IntelliPort-II - style FIFO's | ||
1096 | // | ||
1097 | //****************************************************************************** | ||
1098 | static unsigned short | ||
1099 | iiGetMailII(i2eBordStrPtr pB) | ||
1100 | { | ||
1101 | if (I2_HAS_MAIL(pB)) { | ||
1102 | outb(SEL_INMAIL, pB->i2ePointer); | ||
1103 | return inb(pB->i2ePointer); | ||
1104 | } else { | ||
1105 | return NO_MAIL_HERE; | ||
1106 | } | ||
1107 | } | ||
1108 | |||
1109 | //****************************************************************************** | ||
1110 | // Function: iiGetMailIIEX(pB,mail) | ||
1111 | // Parameters: pB - pointer to board structure | ||
1112 | // | ||
1113 | // Returns: Mailbox data or NO_MAIL_HERE. | ||
1114 | // | ||
1115 | // Description: | ||
1116 | // | ||
1117 | // If no mail available, returns NO_MAIL_HERE otherwise returns the data from | ||
1118 | // the mailbox, which is guaranteed != NO_MAIL_HERE. | ||
1119 | // | ||
1120 | // This version operates on IntelliPort-IIEX - style FIFO's | ||
1121 | // | ||
1122 | //****************************************************************************** | ||
1123 | static unsigned short | ||
1124 | iiGetMailIIEX(i2eBordStrPtr pB) | ||
1125 | { | ||
1126 | if (I2_HAS_MAIL(pB)) | ||
1127 | return inb(pB->i2eXMail); | ||
1128 | else | ||
1129 | return NO_MAIL_HERE; | ||
1130 | } | ||
1131 | |||
1132 | //****************************************************************************** | ||
1133 | // Function: iiEnableMailIrqII(pB) | ||
1134 | // Parameters: pB - pointer to board structure | ||
1135 | // | ||
1136 | // Returns: Nothing | ||
1137 | // | ||
1138 | // Description: | ||
1139 | // | ||
1140 | // Enables board to interrupt host (only) by writing to host's in-bound mailbox. | ||
1141 | // | ||
1142 | // This version operates on IntelliPort-II - style FIFO's | ||
1143 | // | ||
1144 | //****************************************************************************** | ||
1145 | static void | ||
1146 | iiEnableMailIrqII(i2eBordStrPtr pB) | ||
1147 | { | ||
1148 | outb(SEL_MASK, pB->i2ePointer); | ||
1149 | outb(ST_IN_MAIL, pB->i2ePointer); | ||
1150 | } | ||
1151 | |||
1152 | //****************************************************************************** | ||
1153 | // Function: iiEnableMailIrqIIEX(pB) | ||
1154 | // Parameters: pB - pointer to board structure | ||
1155 | // | ||
1156 | // Returns: Nothing | ||
1157 | // | ||
1158 | // Description: | ||
1159 | // | ||
1160 | // Enables board to interrupt host (only) by writing to host's in-bound mailbox. | ||
1161 | // | ||
1162 | // This version operates on IntelliPort-IIEX - style FIFO's | ||
1163 | // | ||
1164 | //****************************************************************************** | ||
1165 | static void | ||
1166 | iiEnableMailIrqIIEX(i2eBordStrPtr pB) | ||
1167 | { | ||
1168 | outb(MX_IN_MAIL, pB->i2eXMask); | ||
1169 | } | ||
1170 | |||
1171 | //****************************************************************************** | ||
1172 | // Function: iiWriteMaskII(pB) | ||
1173 | // Parameters: pB - pointer to board structure | ||
1174 | // | ||
1175 | // Returns: Nothing | ||
1176 | // | ||
1177 | // Description: | ||
1178 | // | ||
1179 | // Writes arbitrary value to the mask register. | ||
1180 | // | ||
1181 | // This version operates on IntelliPort-II - style FIFO's | ||
1182 | // | ||
1183 | //****************************************************************************** | ||
1184 | static void | ||
1185 | iiWriteMaskII(i2eBordStrPtr pB, unsigned char value) | ||
1186 | { | ||
1187 | outb(SEL_MASK, pB->i2ePointer); | ||
1188 | outb(value, pB->i2ePointer); | ||
1189 | } | ||
1190 | |||
1191 | //****************************************************************************** | ||
1192 | // Function: iiWriteMaskIIEX(pB) | ||
1193 | // Parameters: pB - pointer to board structure | ||
1194 | // | ||
1195 | // Returns: Nothing | ||
1196 | // | ||
1197 | // Description: | ||
1198 | // | ||
1199 | // Writes arbitrary value to the mask register. | ||
1200 | // | ||
1201 | // This version operates on IntelliPort-IIEX - style FIFO's | ||
1202 | // | ||
1203 | //****************************************************************************** | ||
1204 | static void | ||
1205 | iiWriteMaskIIEX(i2eBordStrPtr pB, unsigned char value) | ||
1206 | { | ||
1207 | outb(value, pB->i2eXMask); | ||
1208 | } | ||
1209 | |||
1210 | //****************************************************************************** | ||
1211 | // Function: iiDownloadBlock(pB, pSource, isStandard) | ||
1212 | // Parameters: pB - pointer to board structure | ||
1213 | // pSource - loadware block to download | ||
1214 | // isStandard - True if "standard" loadware, else false. | ||
1215 | // | ||
1216 | // Returns: Success or Failure | ||
1217 | // | ||
1218 | // Description: | ||
1219 | // | ||
1220 | // Downloads a single block (at pSource)to the board referenced by pB. Caller | ||
1221 | // sets isStandard to true/false according to whether the "standard" loadware is | ||
1222 | // what's being loaded. The normal process, then, is to perform an iiInitialize | ||
1223 | // to the board, then perform some number of iiDownloadBlocks using the returned | ||
1224 | // state to determine when download is complete. | ||
1225 | // | ||
1226 | // Possible return values: (see I2ELLIS.H) | ||
1227 | // II_DOWN_BADVALID | ||
1228 | // II_DOWN_BADFILE | ||
1229 | // II_DOWN_CONTINUING | ||
1230 | // II_DOWN_GOOD | ||
1231 | // II_DOWN_BAD | ||
1232 | // II_DOWN_BADSTATE | ||
1233 | // II_DOWN_TIMEOUT | ||
1234 | // | ||
1235 | // Uses the i2eState and i2eToLoad fields (initialized at iiInitialize) to | ||
1236 | // determine whether this is the first block, whether to check for magic | ||
1237 | // numbers, how many blocks there are to go... | ||
1238 | // | ||
1239 | //****************************************************************************** | ||
1240 | static int | ||
1241 | iiDownloadBlock ( i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard) | ||
1242 | { | ||
1243 | int itemp; | ||
1244 | int loadedFirst; | ||
1245 | |||
1246 | if (pB->i2eValid != I2E_MAGIC) return II_DOWN_BADVALID; | ||
1247 | |||
1248 | switch(pB->i2eState) | ||
1249 | { | ||
1250 | case II_STATE_READY: | ||
1251 | |||
1252 | // Loading the first block after reset. Must check the magic number of the | ||
1253 | // loadfile, store the number of blocks we expect to load. | ||
1254 | if (pSource->e.loadMagic != MAGIC_LOADFILE) | ||
1255 | { | ||
1256 | return II_DOWN_BADFILE; | ||
1257 | } | ||
1258 | |||
1259 | // Next we store the total number of blocks to load, including this one. | ||
1260 | pB->i2eToLoad = 1 + pSource->e.loadBlocksMore; | ||
1261 | |||
1262 | // Set the state, store the version numbers. ('Cause this may have come | ||
1263 | // from a file - we might want to report these versions and revisions in | ||
1264 | // case of an error! | ||
1265 | pB->i2eState = II_STATE_LOADING; | ||
1266 | pB->i2eLVersion = pSource->e.loadVersion; | ||
1267 | pB->i2eLRevision = pSource->e.loadRevision; | ||
1268 | pB->i2eLSub = pSource->e.loadSubRevision; | ||
1269 | |||
1270 | // The time and date of compilation is also available but don't bother | ||
1271 | // storing it for normal purposes. | ||
1272 | loadedFirst = 1; | ||
1273 | break; | ||
1274 | |||
1275 | case II_STATE_LOADING: | ||
1276 | loadedFirst = 0; | ||
1277 | break; | ||
1278 | |||
1279 | default: | ||
1280 | return II_DOWN_BADSTATE; | ||
1281 | } | ||
1282 | |||
1283 | // Now we must be in the II_STATE_LOADING state, and we assume i2eToLoad | ||
1284 | // must be positive still, because otherwise we would have cleaned up last | ||
1285 | // time and set the state to II_STATE_LOADED. | ||
1286 | if (!iiWaitForTxEmpty(pB, MAX_DLOAD_READ_TIME)) { | ||
1287 | return II_DOWN_TIMEOUT; | ||
1288 | } | ||
1289 | |||
1290 | if (!iiWriteBuf(pB, pSource->c, LOADWARE_BLOCK_SIZE)) { | ||
1291 | return II_DOWN_BADVALID; | ||
1292 | } | ||
1293 | |||
1294 | // If we just loaded the first block, wait for the fifo to empty an extra | ||
1295 | // long time to allow for any special startup code in the firmware, like | ||
1296 | // sending status messages to the LCD's. | ||
1297 | |||
1298 | if (loadedFirst) { | ||
1299 | if (!iiWaitForTxEmpty(pB, MAX_DLOAD_START_TIME)) { | ||
1300 | return II_DOWN_TIMEOUT; | ||
1301 | } | ||
1302 | } | ||
1303 | |||
1304 | // Determine whether this was our last block! | ||
1305 | if (--(pB->i2eToLoad)) { | ||
1306 | return II_DOWN_CONTINUING; // more to come... | ||
1307 | } | ||
1308 | |||
1309 | // It WAS our last block: Clean up operations... | ||
1310 | // ...Wait for last buffer to drain from the board... | ||
1311 | if (!iiWaitForTxEmpty(pB, MAX_DLOAD_READ_TIME)) { | ||
1312 | return II_DOWN_TIMEOUT; | ||
1313 | } | ||
1314 | // If there were only a single block written, this would come back | ||
1315 | // immediately and be harmless, though not strictly necessary. | ||
1316 | itemp = MAX_DLOAD_ACK_TIME/10; | ||
1317 | while (--itemp) { | ||
1318 | if (I2_HAS_INPUT(pB)) { | ||
1319 | switch (inb(pB->i2eData)) { | ||
1320 | case LOADWARE_OK: | ||
1321 | pB->i2eState = | ||
1322 | isStandard ? II_STATE_STDLOADED :II_STATE_LOADED; | ||
1323 | |||
1324 | // Some revisions of the bootstrap firmware (e.g. ISA-8 1.0.2) | ||
1325 | // will, // if there is a debug port attached, require some | ||
1326 | // time to send information to the debug port now. It will do | ||
1327 | // this before // executing any of the code we just downloaded. | ||
1328 | // It may take up to 700 milliseconds. | ||
1329 | if (pB->i2ePom.e.porDiag2 & POR_DEBUG_PORT) { | ||
1330 | iiDelay(pB, 700); | ||
1331 | } | ||
1332 | |||
1333 | return II_DOWN_GOOD; | ||
1334 | |||
1335 | case LOADWARE_BAD: | ||
1336 | default: | ||
1337 | return II_DOWN_BAD; | ||
1338 | } | ||
1339 | } | ||
1340 | |||
1341 | iiDelay(pB, 10); // 10 mS granularity on checking condition | ||
1342 | } | ||
1343 | |||
1344 | // Drop-through --> timed out waiting for firmware confirmation | ||
1345 | |||
1346 | pB->i2eState = II_STATE_BADLOAD; | ||
1347 | return II_DOWN_TIMEOUT; | ||
1348 | } | ||
1349 | |||
1350 | //****************************************************************************** | ||
1351 | // Function: iiDownloadAll(pB, pSource, isStandard, size) | ||
1352 | // Parameters: pB - pointer to board structure | ||
1353 | // pSource - loadware block to download | ||
1354 | // isStandard - True if "standard" loadware, else false. | ||
1355 | // size - size of data to download (in bytes) | ||
1356 | // | ||
1357 | // Returns: Success or Failure | ||
1358 | // | ||
1359 | // Description: | ||
1360 | // | ||
1361 | // Given a pointer to a board structure, a pointer to the beginning of some | ||
1362 | // loadware, whether it is considered the "standard loadware", and the size of | ||
1363 | // the array in bytes loads the entire array to the board as loadware. | ||
1364 | // | ||
1365 | // Assumes the board has been freshly reset and the power-up reset message read. | ||
1366 | // (i.e., in II_STATE_READY). Complains if state is bad, or if there seems to be | ||
1367 | // too much or too little data to load, or if iiDownloadBlock complains. | ||
1368 | //****************************************************************************** | ||
1369 | static int | ||
1370 | iiDownloadAll(i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard, int size) | ||
1371 | { | ||
1372 | int status; | ||
1373 | |||
1374 | // We know (from context) board should be ready for the first block of | ||
1375 | // download. Complain if not. | ||
1376 | if (pB->i2eState != II_STATE_READY) return II_DOWN_BADSTATE; | ||
1377 | |||
1378 | while (size > 0) { | ||
1379 | size -= LOADWARE_BLOCK_SIZE; // How much data should there be left to | ||
1380 | // load after the following operation ? | ||
1381 | |||
1382 | // Note we just bump pSource by "one", because its size is actually that | ||
1383 | // of an entire block, same as LOADWARE_BLOCK_SIZE. | ||
1384 | status = iiDownloadBlock(pB, pSource++, isStandard); | ||
1385 | |||
1386 | switch(status) | ||
1387 | { | ||
1388 | case II_DOWN_GOOD: | ||
1389 | return ( (size > 0) ? II_DOWN_OVER : II_DOWN_GOOD); | ||
1390 | |||
1391 | case II_DOWN_CONTINUING: | ||
1392 | break; | ||
1393 | |||
1394 | default: | ||
1395 | return status; | ||
1396 | } | ||
1397 | } | ||
1398 | |||
1399 | // We shouldn't drop out: it means "while" caught us with nothing left to | ||
1400 | // download, yet the previous DownloadBlock did not return complete. Ergo, | ||
1401 | // not enough data to match the size byte in the header. | ||
1402 | return II_DOWN_UNDER; | ||
1403 | } | ||