xref: /netbsd-src/sys/arch/shark/shark/scr.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: scr.c,v 1.29 2014/03/16 05:20:25 dholland Exp $	*/
2 
3 /*
4  * Copyright 1997
5  * Digital Equipment Corporation. All rights reserved.
6  *
7  * This software is furnished under license and may be used and
8  * copied only in accordance with the following terms and conditions.
9  * Subject to these conditions, you may download, copy, install,
10  * use, modify and distribute this software in source and/or binary
11  * form. No title or ownership is transferred hereby.
12  *
13  * 1) Any source code used, modified or distributed must reproduce
14  *    and retain this copyright notice and list of conditions as
15  *    they appear in the source file.
16  *
17  * 2) No right is granted to use any trade name, trademark, or logo of
18  *    Digital Equipment Corporation. Neither the "Digital Equipment
19  *    Corporation" name nor any trademark or logo of Digital Equipment
20  *    Corporation may be used to endorse or promote products derived
21  *    from this software without the prior written permission of
22  *    Digital Equipment Corporation.
23  *
24  * 3) This software is provided "AS-IS" and any express or implied
25  *    warranties, including but not limited to, any implied warranties
26  *    of merchantability, fitness for a particular purpose, or
27  *    non-infringement are disclaimed. In no event shall DIGITAL be
28  *    liable for any damages whatsoever, and in particular, DIGITAL
29  *    shall not be liable for special, indirect, consequential, or
30  *    incidental damages or damages for lost profits, loss of
31  *    revenue or loss of use, whether such damages arise in contract,
32  *    negligence, tort, under statute, in equity, at law or otherwise,
33  *    even if advised of the possibility of such damage.
34  */
35 
36 /*
37 **++
38 **
39 **  FACILITY:
40 **
41 **    Driver for smart card
42 **
43 **  ABSTRACT:
44 **
45 **    The driver provides access to a Smart Card for the DNARD.
46 **
47 **    There is no Smart Card silicon.  Several i/o pins
48 **    connect to the pads on the Smart Card, and the driver is
49 **    is responsible for driving the signals in accordance with
50 **    ISO 7816-3 (the Smart Card spec)
51 **
52 **    This driver puts a high load on the system due to the need
53 **    to interrupt at a high rate (up to 50 kHz) during bit detection.
54 **
55 **
56 **    The driver is dived into the standard top half ioctl, and bottom
57 **    half interrupt.  The interrupt is FIQ, which requires its own stack.
58 **    disable_interrupts and restore_interrupts must be used to protect from
59 **    a FIQ.  Since splxxx functions do not use this, the bottom half cannot
60 **    use any standard functions (ie like wakeup, timeout, etc.
61 **    Thus the communication from the bottom half
62 **    to the top half uses a "done" bit called masterDone.  This bit
63 **    is set by the master state machine when all bottom half work is
64 **    complete.  The top half checks/sleeps on this masterDone bit.
65 **
66 **    The FIQ is driven by Timer 2 (T2)in the sequoia.  All times are
67 **    referenced to T2 counts.
68 **
69 **    The bottom half is done as a several linked state machines.
70 **    The top level machine is the maserSM (ie master State Machine).  This
71 **    machine calls mid level protocol machines, ie ATRSM (Answer To Reset
72 **    State Machine), t0SendSM (T=0 Send State Machine), and t0RecvSM (T=0 Recv
73 **    State Machine).  These mid level protocol machines in turn call low level
74 **    bit-bashing machines, ie coldResetSM, t0SendByteSM, T0RecvByteSM.
75 **
76 **    Smart Cards are driven in a command/response mode.  Ie you issue a command
77 **    to the Smart Card and it responds.  This command/response mode is reflected
78 **    in the structure of the driver.  Ie the ioctl gets a command, it
79 **    gives it to the bottom half to execute and goes to sleep.  The bottom half
80 **    executes the command and gets the response to from the card and then
81 **    notifies the top half that it has completed.  Commands usually complete
82 **    in under a second.
83 **
84 **
85 **
86 **  AUTHORS:
87 **
88 **    E. J. Grohn
89 **    Digital Equipment Corporation.
90 **
91 **  CREATION DATE:
92 **
93 **    27-July-97
94 **
95 **--
96 */
97 
98 /*
99 **
100 **  INCLUDE FILES
101 **
102 */
103 
104 #include <sys/cdefs.h>
105 __KERNEL_RCSID(0, "$NetBSD: scr.c,v 1.29 2014/03/16 05:20:25 dholland Exp $");
106 
107 #include "opt_ddb.h"
108 
109 #include <sys/param.h>
110 #include <sys/systm.h>
111 #include <sys/ioctl.h>
112 /* #include <sys/select.h> */
113 /* #include <sys/tty.h> */
114 #include <sys/proc.h>
115 #include <sys/conf.h>
116 /* #include <sys/file.h> */
117 /* #include <sys/uio.h> */
118 #include <sys/kernel.h>
119 /* #include <sys/syslog.h> */
120 #include <sys/types.h>
121 #include <sys/device.h>
122 #include <dev/isa/isavar.h>
123 #include <arm/cpufunc.h>
124 
125 
126 /* SCR_DEBUG is the master switch for turning on debugging */
127 //#define SCR_DEBUG 1
128 #ifdef SCR_DEBUG
129     #define KERNEL_DEBUG
130     #ifdef DDB
131         #define DEBUGGER printf("file = %s, line = %d\n",__FILE__,__LINE__);Debugger()
132     #else
133         #define DEBUGGER panic("file = %s, line = %d",__FILE__,__LINE__);
134     #endif
135 #else
136     #define DEBUGGER
137 #endif
138 
139 
140 #include <machine/kerndebug.h>
141 //#include <machine/intr.h>
142 #include <dev/ic/i8253reg.h>
143 #include <shark/shark/hat.h>
144 #include <shark/shark/sequoia.h>
145 #include <machine/scrio.h>
146 
147 
148 
149 
150 /*
151 **
152 **  MACRO DEFINITIONS
153 **
154 */
155 
156 
157 #define scr_lcr scr_cfcr
158 
159 /*
160 ** Macro to extract the minor device number from the device Identifier
161 */
162 #define SCRUNIT(x)      (minor(x))
163 
164 /*
165 ** some macros to assist in debugging
166 */
167 #ifdef SCR_DEBUG
168     #define KERNEL_DEBUG
169     #define ASSERT(f)	        do { if (!(f)) { DEBUGGER;} }while(0)
170     #define TOGGLE_TEST_PIN()   scrToggleTestPin()
171     #define INVALID_STATE_CMD(sc,state,cmd)  invalidStateCmd(sc,state,cmd,__LINE__);
172 #else
173     #define ASSERT(f)
174     #define TOGGLE_TEST_PIN()
175     //#define INVALID_STATE_CMD(sc,state,cmd)  panic("scr: invalid state/cmd, sc = %X, state = %X, cmd = %X, line = %d",sc,state,cmd,__LINE__);
176     #define INVALID_STATE_CMD(sc,state,cmd)  sc->bigTrouble = true;
177 
178 #endif
179 
180 
181 /*
182 ** The first and last bytes of the debug control variables is reserved for
183 ** the standard KERN_DEBUG_xxx macros, so we can tailor the middle two bytes
184 */
185 #define SCRPROBE_DEBUG_INFO			0x00000100
186 #define SCRATTACH_DEBUG_INFO		0x00000200
187 #define SCROPEN_DEBUG_INFO			0x00000400
188 #define SCRCLOSE_DEBUG_INFO			0x00000800
189 #define SCRREAD_DEBUG_INFO			0x00001000
190 #define SCRWRITE_DEBUG_INFO			0x00002000
191 #define SCRIOCTL_DEBUG_INFO			0x00004000
192 #define MASTER_SM_DEBUG_INFO		0x00008000
193 #define COLD_RESET_SM_DEBUG_INFO	0x00010000
194 #define ATR_SM_DEBUG_INFO			0x00020000
195 #define T0_RECV_BYTE_SM_DEBUG_INFO	0x00040000
196 #define T0_SEND_BYTE_SM_DEBUG_INFO	0x00080000
197 #define T0_RECV_SM_DEBUG_INFO		0x00100000
198 #define T0_SEND_SM_DEBUG_INFO		0x00200000
199 
200 
201 int scrdebug =  //SCRPROBE_DEBUG_INFO	    |
202                 //SCRATTACH_DEBUG_INFO	|
203                 //SCROPEN_DEBUG_INFO		|
204                 //SCRCLOSE_DEBUG_INFO		|
205                 //SCRREAD_DEBUG_INFO		|
206                 //SCRWRITE_DEBUG_INFO		|
207                 //SCRIOCTL_DEBUG_INFO		|
208                 //MASTER_SM_DEBUG_INFO	|
209                 //COLD_RESET_SM_DEBUG_INFO|
210                 //ATR_SM_DEBUG_INFO		|
211                 //T0_RECV_BYTE_SM_DEBUG_INFO |
212                 //T0_SEND_BYTE_SM_DEBUG_INFO  |
213                 //T0_RECV_SM_DEBUG_INFO		|
214                 //T0_SEND_SM_DEBUG_INFO		|
215                 0;
216 
217 
218 
219 
220 
221 
222 /*
223 ** the bottom half of the driver is done as several linked state machines
224 ** below are all the states of the machines, and the commands that are
225 ** sent to each machine
226 */
227 
228 /* commands to Master State Machine from ioctl */
229 #define 	mcOn				0x0100		/* ioctl on */
230 #define		mcT0DataSend		0x0102		/* ioctl send */
231 #define		mcT0DataRecv		0x0103		/* ioctl recv */
232 
233 /* commands to Master State Machine from lower state machines */
234 #define		mcColdReset			0x0105		/* cold reset finished  */
235 #define		mcATR				0x0106		/* ATR has finished */
236 #define		mcT0Send			0x0108		/* T0 send finished */
237 #define		mcT0Recv			0x010a		/* T0 recv finished */
238 
239 /* states in Master state machine (ms = Master State) */
240 #define		msIdleOff		    0x0200      /* in idle state, card powered off */
241 #define		msColdReset		    0x0201      /* turning on power, clock, reset */
242 #define		msATR			    0x0202      /* getting ATR sequence from card */
243 #define		msIdleOn		    0x0203      /* idle, put card powered on */
244 #define		msT0Send		    0x0204      /* sending T0 data */
245 #define		msT0Recv		    0x0205      /* recving T0 data */
246 
247 
248 
249 
250 /* commands to T0 send state machine  */
251 #define 	t0scStart			0x0300      /* start  */
252 #define		t0scTWorkWaiting	0x0301      /* work waiting timeout */
253 
254 /* states in T0 send state machine */
255 #define 	t0ssIdle			0x0400      /* idle state */
256 #define		t0ssSendHeader		0x0401		/* send 5 header bytes */
257 #define		t0ssRecvProcedure	0x0402      /* wait for procedure byte */
258 #define		t0ssSendByte		0x0403      /* send 1 byte */
259 #define		t0ssSendData		0x0404      /* send all bytes */
260 #define		t0ssRecvSW1			0x0405      /* wait for sw1 */
261 #define		t0ssRecvSW2			0x0406      /* wait for sw2 */
262 
263 
264 
265 
266 
267 /* commands to T0 recv state machine */
268 #define 	t0rcStart			0x0500      /* start */
269 #define		t0rcTWorkWaiting	0x0501      /* work waiting timeout */
270 
271 /* states in T0 recv state machine */
272 #define 	t0rsIdle			0x0600      /* idle state */
273 #define		t0rsSendHeader		0x0601		/* send 5 header bytes */
274 #define		t0rsRecvProcedure	0x0602      /* wait for procedure byte */
275 #define		t0rsRecvByte		0x0603      /* recv 1 byte */
276 #define		t0rsRecvData		0x0604      /* recv all bytes */
277 #define		t0rsRecvSW1			0x0605      /* wait for sw1 */
278 #define		t0rsRecvSW2			0x0606      /* wait for sw2 */
279 
280 
281 
282 /* commands to Cold Reset state machine */
283 #define		crcStart		    0x0900      /* start */
284 #define		crcT2			    0x0902		/* timeout T2 ISO 7816-3, P6, Figure 2 */
285 
286 /* states in cold reset state machine */
287 #define		crsIdle			    0x0a00      /* idle */
288 #define		crsT2Wait		    0x0a01      /* wait for T2 ISO 7816-3.P6. Figure 2 */
289 
290 
291 
292 
293 
294 /* commands to Answer To Reset (ATR) state machine */
295 #define		atrcStart			0x0b00      /* start */
296 #define		atrcT3				0x0b04      /* got T3 timeout */
297 #define		atrcTWorkWaiting	0x0b05      /* work waiting timeout */
298 
299 /* states in Answer To Reset (ATR) state machine */
300 #define		atrsIdle		    0x0c00      /* idle */
301 #define		atrsTS			    0x0c01		/* looking for TS, (initial bytes)	*/
302 #define		atrsT0			    0x0c02		/* looking for T0, (format bytes)	*/
303 #define		atrsTABCD		    0x0c03		/* looking for TAx (interface bytes)*/
304 #define		atrsTK			    0x0c04		/* looking for TK  (history bytes)		*/
305 #define		atrsTCK			    0x0c05		/* looking for TCK (check bytes		*/
306 
307 
308 /* commands to T0 Recv Byte state machine */
309 #define		t0rbcStart			0x0d00      /* start */
310 #define		t0rbcAbort			0x0d01      /* abort */
311 #define		t0rbcTFindStartEdge	0x0d02		/* start bit edge search */
312 #define		t0rbcTFindStartMid	0x0d03		/* start bit mid search */
313 #define		t0rbcTClockData		0x0d04		/* data bit search */
314 #define		t0rbcTErrorStart	0x0d05		/* start to send error  */
315 #define		t0rbcTErrorStop		0x0d06		/* stop sending error	*/
316 
317 /* states in T0 Recv Byte state machine */
318 #define		t0rbsIdle			0x0e00      /* idle */
319 #define		t0rbsFindStartEdge  0x0e01		/* looking for start bit */
320 #define		t0rbsFindStartMid   0x0e02		/* looking for start bit */
321 #define		t0rbsClockData		0x0e03		/* looking for data bits */
322 #define		t0rbsSendError		0x0e04		/* output error bit */
323 
324 
325 
326 
327 /* commands to T0 Send Byte state machine */
328 #define		t0sbcStart			0x0f00      /* start the machine */
329 #define		t0sbcAbort			0x0f01      /* abort the machine */
330 #define		t0sbcTGuardTime		0x0f02		/* guard time finished */
331 #define		t0sbcTClockData		0x0f03		/* clock time finished     */
332 #define		t0sbcTError			0x0f04		/* start to send error  */
333 #define		t0sbcTResend		0x0f05		/* if parity error, then wait unfill we can re-send */
334 
335 
336 
337 /* states in T0 Send Byte state machine */
338 #define		t0sbsIdle			0x1000      /* idle */
339 #define		t0sbsWaitGuardTime	0x1001		/* wait for guard time to finish */
340 #define		t0sbsClockData		0x1002		/* clocking out data & parity */
341 #define		t0sbsWaitError		0x1003		/* waiting for error indicator */
342 #define		t0sbsWaitResend		0x1004		/* waiting to start re-send if error */
343 
344 
345 
346 
347 /*
348 ** generic middle level state machine commands
349 ** sent by T0 Send Byte & T0 recv Byte to T0 Send and T0 Recv
350 */
351 #define		gcT0RecvByte		0x1100      /* receive finished */
352 #define		gcT0RecvByteErr		0x1101      /* receive got error */
353 #define		gcT0SendByte		0x1102      /* send finished */
354 #define		gcT0SendByteErr		0x1103      /* send got error */
355 
356 
357 
358 
359 
360 
361 /*
362 **
363 ** below are definitions associated with Smart Card
364 **
365 */
366 
367 
368 /*
369 ** Frequency of clock sent to card
370 ** NCI's card is running at 1/2 freq, so in debug we can make
371 ** use of this to toggle more debug signals and still be within
372 ** interrupt time budget
373 */
374 #ifdef  SCR_DEBUG
375     #define CARD_FREQ_DEF			(3579000/2)
376 #else
377     #define CARD_FREQ_DEF			(3579000)
378 #endif
379 
380 
381 
382 /* byte logic level and msb/lsb coding */
383 #define CONVENTION_UNKNOWN		        0
384 #define CONVENTION_INVERSE		        1
385 #define CONVENTION_DIRECT		        2
386 #define CONVENIONT_INVERSE_ID			0x3f
387 #define CONVENTION_DIRECT_FIX			0x3b
388 #define CONVENTION_DIRECT_ID			0x23
389 
390 
391 /* macros that help us set the T2 count for bit bashing */
392 #define CLK_COUNT_START	        (((372   * TIMER_FREQ) / sc->cardFreq) /5)
393 #define CLK_COUNT_DATA	        (((372   * TIMER_FREQ) / sc->cardFreq)   )
394 #define START_2_DATA            5
395 
396 /* default settings to use if not specified in ATR */
397 #define N_DEFAULT			    0		/* guard time default */
398 #define Fi_DEFAULT			    372		/* clock rate conversion default */
399 #define Di_DEFAULT			    1		/* bit rate adjustment factor */
400 #define Wi_DEFAULT			    10		/* waiting time */
401 
402 
403 /* table for clock rate adjustment in ATR */
404 int FI2Fi[16] = {372, 372, 558, 744,1116,1488,1860,   0,
405                    0, 512, 768,1024,1536,2048,   0,   0};
406 
407 /* table for bit rate adjustment   in ATR*/
408 int DI2Di[16] = {  0,   1,   2,   4,   8,   16, 32,   0,
409                   12,  20,   0,   0,   0,    0,  0,   0};
410 
411 /* values of atrY in the ATR sequence*/
412 #define ATR_Y_TA	0x10
413 #define ATR_Y_TB	0x20
414 #define ATR_Y_TC	0x40
415 #define ATR_Y_TD	0x80
416 
417 /* T0,T1,etc  information in ATR sequence*/
418 #define PROTOCOL_T0 0x0001			/* bit 0 for T0 */
419 #define PROTOCOL_T1 0x0002			/* bit 1 for T1 */
420 #define PROTOCOL_T2 0x0004			/* bit 2 for T2*/
421 #define PROTOCOL_T3 0x0008			/* bit 3 for T3*/
422 /* etc  */
423 
424 
425 /* timeouts for various places - see ISO 7816-3 */
426 #define T_t2					((300   * TIMER_FREQ) / sc->cardFreq)
427 #define T_t3					((40000 * (TIMER_FREQ/1024)) / (sc->cardFreq/1024))
428 #define T_WORK_WAITING			(((960 * sc->Wi * sc->Fi ) / (sc->cardFreq/1024))  * (TIMER_FREQ/1024))
429 #define PARITY_ERROR_MAX 3		/* maximum parity errors on 1 byte before giving up  */
430 
431 /*
432 ** its possible for the HAT to wedge.  If that happens, all timing is sick, so
433 ** we use timeout below (driven of system sleeps) as a "watchdog"
434 */
435 #define MAX_FIQ_TIME     5      /* maximum time we are willing to run the FIQ */
436 
437 
438 /* used to decode T0 commands */
439 #define CMD_BUF_INS_OFF		    1	    /* offset to INS in header */
440 #define CMD_BUF_DATA_LEN_OFF    4	    /* offset to data length in header */
441 
442 
443 /*
444 **
445 ** DATA STRUCTURES
446 **
447 */
448 typedef unsigned char BYTE;
449 
450 /* our soft c structure */
451 struct scr_softc
452 {
453     int     open;
454 
455     /* configuration information */
456     int     status;                 /* status to be returned */
457     int     cardFreq;               /* freq supplied to card */
458     int     convention;             /* ie direct or inverse */
459     int     protocolType;           /* bit 0 indicates T0, bit 1 indicates T1,etc */
460     int     N;                      /* guard time  */
461     int     Fi;                     /* clock rate */
462     int     Di;                     /* bit rate adjustment */
463     int     Wi;                     /* work waiting time */
464     int     clkCountStartRecv;      /* count for clock start bits on recv */
465     int     clkCountDataRecv;       /* count for clock data  bits on recv*/
466     int     clkCountDataSend;       /* count for clock data  bits on send */
467 
468     /* state machines */
469     int     masterS ;
470     int     t0RecvS;
471     int     t0SendS;
472     int     coldResetS;
473     int     ATRS;
474     int     t0RecvByteS;
475     int     t0SendByteS;
476 
477     /* extra stuff kept for t0send state machine */
478     int     commandCount;           /* number of command bytes sent */
479     int     dataCount;              /* number of data bytes send/recv */
480     int     dataMax;                /* max number of data bytes to send/recv */
481 
482     /* extra stuff kept for t0RecvByteS, t0SendByteS machines */
483     void    (*t0ByteParent)(struct scr_softc *,int);  /* state machine that is controlling this SM */
484     int     shiftBits;              /* number of bits shifted	*/
485     BYTE    shiftByte;              /* intermediate value of bit being shifted */
486     BYTE    dataByte;               /* actual value of byte */
487     int     shiftParity;            /* value of parity */
488     int     shiftParityCount;       /* number of retries due to parity error */
489 
490     /* extra stuff kept for ATR machine */
491     int     atrY;       /* indicates if TA,TB,TC,TD is to follow */
492     int     atrK;       /* number of historical characters*/
493     int     atrKCount;  /* progressive could of historical characters*/
494     int     atrTABCDx;  /* the 'i' in TA(i), TB(i), TC(i) and TD(i) */
495     int     atrFi;      /* value of Fi */
496     int     atrDi;      /* value of Di */
497 
498     int masterDone; /* flag used by bottom half to tell top half its done */
499     int bigTrouble; /* david/jim, remove this when the dust settles  */
500 
501     /* pointers used by ioctl */
502     ScrOn * pIoctlOn;   /* pointer to on ioctl data */
503     ScrT0 * pIoctlT0;   /* pointer to T0 ioctl data */
504 };
505 
506 /* number of devices */
507 static int devices = 0;
508 
509 /* used as reference for tsleep */
510 static int tsleepIdent;
511 
512 
513 /*
514 ** only 1 device is using the hat at any one time
515 ** variable below must be acquired using splhigh before using the hat
516 */
517 static int hatLock = false;
518 
519 
520 
521 
522 /*
523 ** data structures associated with our timeout queue that we run for the
524 ** bottom half of the driver
525 */
526 
527 /* timeout callout structure */
528 typedef struct callout_t
529 {
530     struct callout_t *c_next;                       /* next callout in queue */
531     struct scr_softc *c_sc;                         /* soft c */
532     int     c_arg;                                  /* function argument */
533     void    (*c_func)(struct scr_softc*,int); /* function to call */
534     int     c_time;                                 /* ticks to the event */
535 }Callout;
536 
537 /* actual callout array */
538 #define  SCR_CLK_CALLOUT_COUNT 10
539 static Callout  scrClkCalloutArray[SCR_CLK_CALLOUT_COUNT];
540 
541 /* callout lists */
542 static Callout *scrClkCallFree;                     /* free queue */
543 static Callout  scrClkCallTodo;                     /* todo queue */
544 
545 /*
546 ** information kept for the clock/FIQ that drives our timeout queue
547 */
548 static int scrClkEnable = 0;                   /* true if clock enabled */
549 static void myHatWedge(int nFIQs);             /* callback that informs us if FIQ has wedged */
550 static int scrClkCount;                        /* number used to set t2 that drives FIQ */
551 
552 #define HATSTACKSIZE 1024                       /* size of stack used during a FIQ */
553 static unsigned char hatStack[HATSTACKSIZE];   /* actual stack used during a FIQ */
554 
555 
556 
557 
558 
559 
560 
561 
562 
563 
564 
565 
566 /*
567 **
568 **  FUNCTIONAL PROTOTYPES
569 **
570 */
571 
572 /*
573 **
574 ** functions in top half of driver
575 **
576 */
577 
578 /* configure routines */
579 int     scrprobe(device_t, cfdata_t, void *);
580 void    scrattach(device_t, device_t, void *);
581 
582 static void   initStates(struct scr_softc * sc);
583 
584 
585 
586 
587 /*
588 **
589 ** functions in bottom half of driver
590 **
591 */
592 
593 /* top level state machine */
594 static void   masterSM(struct scr_softc * sc,int cmd);
595 
596 /* mid level state machines, ie protocols  */
597 static void   t0SendSM(struct scr_softc * sc,int cnd);
598 static void   t0RecvSM(struct scr_softc * sc,int cnd);
599 static void   ATRSM(struct scr_softc * sc,int cnd);
600 
601 /* low level state machines, ie bash hardware bits */
602 static void   coldResetSM(struct scr_softc * sc,int cnd);
603 
604 static void   t0SendByteSM(struct scr_softc * sc,int cnd);
605 static void   t0RecvByteSM(struct scr_softc * sc,int cnd);
606 
607 static void   cardOff(struct scr_softc * sc);
608 
609 /*
610 ** functions used for our own timeout routines.
611 ** we cannot use system ones as we are running at a spl level
612 ** that can interrupt the system timeout routines
613 */
614 static void scrClkInit(void);
615 static void scrClkStart(struct scr_softc* sc,int countPerTick);
616 static void scrClkAdj(int count);
617 static void scrClkStop(void);
618 static void hatClkIrq(int count);
619 
620 static void scrTimeout(void (*func)(struct scr_softc*,int), struct scr_softc*, int arg, int count);
621 static void scrUntimeout(void (*func)(struct scr_softc*,int), struct scr_softc*, int arg);
622 
623 
624 /* debug functions */
625 #ifdef SCR_DEBUG
626     static void invalidStateCmd(struct scr_softc* sc,int state,int cmd, int line);
627     static char * getText(int x);
628 #endif
629 
630 
631 
632 
633 
634 CFATTACH_DECL_NEW(scr, sizeof(struct scr_softc),
635     scrprobe, scrattach, NULL, NULL);
636 
637 extern struct cfdriver scr_cd;
638 
639 dev_type_open(scropen);
640 dev_type_close(scrclose);
641 dev_type_ioctl(scrioctl);
642 
643 const struct cdevsw scr_cdevsw = {
644 	.d_open = scropen,
645 	.d_close = scrclose,
646 	.d_read = noread,
647 	.d_write = nowrite,
648 	.d_ioctl = scrioctl,
649 	.d_stop = nostop,
650 	.d_tty = notty,
651 	.d_poll = nopoll,
652 	.d_mmap = nommap,
653 	.d_kqfilter = nokqfilter,
654 	.d_flag = D_TTY
655 };
656 
657 /*
658 **++
659 **  FUNCTIONAL DESCRIPTION:
660 **
661 **      scrProbe
662 **
663 **     This is the probe routine for the Smart Card.  Because the
664 **     Smart Card is hard wired, there is no probing to peform.  The
665 **     function ensures that a succesfull problem occurs only once.
666 **
667 **  FORMAL PARAMETERS:
668 **
669 **     parent  - input  : pointer to the parent device
670 **     match   - not used
671 **     aux     - output : pointer to an isa_attach_args structure.
672 **
673 **  IMPLICIT INPUTS:
674 **
675 **     none.
676 **
677 **  IMPLICIT OUTPUTS:
678 **
679 **     none.
680 **
681 **  FUNCTION VALUE:
682 **
683 **     0 - Probe failed to find the requested device.
684 **     1 - Probe successfully talked to the device.
685 **
686 **  SIDE EFFECTS:
687 **
688 **     none.
689 **--
690 */
691 int
692 scrprobe(device_t parent, cfdata_t match, void *aux)
693 {
694     struct isa_attach_args  *ia = aux;
695     int                     rv = 0;
696 
697     KERN_DEBUG (scrdebug, SCRPROBE_DEBUG_INFO,("scrprobe: called, name = %s\n",
698                                                device_cfdata(parent)->cf_name));
699 
700     if (device_is_a(parent, "ofisascr") && devices == 0)
701     {
702         /* set "devices" to ensure that we respond only once */
703         devices++;
704 
705         /* tell the caller that we are not using any resource */
706 	ia->ia_nio = 0;
707 	ia->ia_niomem = 0;
708 	ia->ia_nirq = 0;
709 	ia->ia_ndrq = 0;
710         rv = 1;
711 
712 
713         KERN_DEBUG (scrdebug, SCRPROBE_DEBUG_INFO,("scrprobe: successful \n"));
714 
715     }
716 
717 
718     return (rv);
719 
720 } /* End scrprobe() */
721 
722 
723 /*
724 **++
725 **  FUNCTIONAL DESCRIPTION:
726 **
727 **      scrattach
728 **
729 **      Initialize the clock and state machines
730 **
731 **  FORMAL PARAMETERS:
732 **
733 **      parent - input  : pointer to my parents device structure.
734 **      self   - output : pointer to my softc with device structure at front.
735 **      aux    - input  : pointer to the isa_attach_args structure.
736 **
737 **  IMPLICIT INPUTS:
738 **
739 **      nill
740 **
741 **  IMPLICIT OUTPUTS:
742 **
743 **      scrconsinit - clock callout functions set
744 **                    state machines all at idle
745 **
746 **  FUNCTION VALUE:
747 **
748 **      none.
749 **
750 **  SIDE EFFECTS:
751 **
752 **      none.
753 **--
754 */
755 void
756 scrattach(device_t parent, device_t self, void *aux)
757 {
758     struct scr_softc       *sc = device_private(self);
759 
760     printf("\n");
761     if (device_is_a(parent, "ofisascr"))
762     {
763         KERN_DEBUG (scrdebug, SCRATTACH_DEBUG_INFO,("scrattach: called \n"));
764 
765         /* set initial state machine values */
766         scrClkInit();
767         initStates(sc);
768         sc->open = false;
769     }
770 
771     else
772     {
773         panic("scrattach: not on an ISA bus, attach impossible");
774     } /* End else we aren't on ISA and we can't handle it */
775 
776 
777     return;
778 } /* End scrattach() */
779 
780 
781 /*
782 **++
783 **  FUNCTIONAL DESCRIPTION:
784 **
785 **      initStates
786 **
787 **      sets the state of all machines to idle
788 **
789 **  FORMAL PARAMETERS:
790 **
791 **      sc    -  Pointer to the softc structure.
792 **
793 **  IMPLICIT INPUTS:
794 **
795 **      nill
796 **
797 **  IMPLICIT OUTPUTS:
798 **
799 **      nill
800 **
801 **  FUNCTION VALUE:
802 **
803 **      nill
804 **
805 **  SIDE EFFECTS:
806 **
807 **      nill
808 **--
809 */
810 static void initStates(struct scr_softc * sc)
811 {
812     sc->masterS         = msIdleOff;
813     sc->t0RecvS         = t0rsIdle;
814     sc->t0SendS         = t0ssIdle;
815     sc->coldResetS      = crsIdle;
816     sc->ATRS            = atrsIdle;
817     sc->t0RecvByteS     = t0rbsIdle;
818     sc->t0SendByteS     = t0sbsIdle;
819 }
820 
821 
822 
823 /*
824 **++
825 **  FUNCTIONAL DESCRIPTION:
826 **
827 **     scrOpen
828 **
829 **     Opens the driver.  We only let the device be opened
830 **     once for security reasons
831 **
832 **  FORMAL PARAMETERS:
833 **
834 **     dev  - input : Device identifier consisting of major and minor numbers.
835 **     flag - input : Indicates if this is a blocking I/O call.
836 **     mode - not used.
837 **     l    - input : Pointer to the lwp structure of the light weight process
838 **            performing the open.
839 **
840 **  IMPLICIT INPUTS:
841 **
842 **     none.
843 **
844 **  IMPLICIT OUTPUTS:
845 **
846 **     none.
847 **
848 **  FUNCTION VALUE:
849 **
850 **     ENXIO   - invalid device specified for open.
851 **     EBUSY   - The unit is already open
852 **
853 **  SIDE EFFECTS:
854 **
855 **     none.
856 **--
857 */
858 int scropen(dev_t dev, int flag, int mode, struct lwp *l)
859 {
860     struct scr_softc     *sc;
861 
862     KERN_DEBUG (scrdebug, SCROPEN_DEBUG_INFO,
863                 ("scropen: called with minor device %d and flag 0x%x\n",
864                  SCRUNIT(dev), flag));
865 
866     sc = device_lookup_private(&scr_cd, SCRUNIT(dev));
867     if (!sc)
868     {
869         KERN_DEBUG (scrdebug, SCROPEN_DEBUG_INFO,("\t scropen, return ENXIO\n"));
870         return (ENXIO);
871     }
872 
873 
874     // david,jim - remove ifdef this when NCI can cope with only 1 open
875 #if 0
876     if (sc->open)
877     {
878 
879         KERN_DEBUG (scrdebug, SCROPEN_DEBUG_INFO,("\t scropen, return EBUSY\n"));
880         return (EBUSY);
881     }
882 
883 
884     /* set all initial conditions */
885     sc->open = true;
886 #endif
887 
888     KERN_DEBUG (scrdebug, SCROPEN_DEBUG_INFO,("scropen: success \n"));
889     /* Now invoke the line discipline open routine
890     */
891 
892     return 0;
893 
894 } /* End scropen() */
895 
896 
897 /*
898 **++
899 **  FUNCTIONAL DESCRIPTION:
900 **
901 **     This function closed the driver
902 **
903 **  FORMAL PARAMETERS:
904 **
905 **     dev  - input : Device identifier consisting of major and minor numbers.
906 **     flag - Not used.
907 **     mode - Not used.
908 **     p    - Not used.
909 **
910 **  IMPLICIT INPUTS:
911 **
912 **     scr_cd  - used to locate the softc structure for the device unit
913 **               identified by dev.
914 **
915 **  IMPLICIT OUTPUTS:
916 **
917 **     The device is put into an idle state.
918 **
919 **  FUNCTION VALUE:
920 **
921 **     0 - Always returns success.
922 **
923 **  SIDE EFFECTS:
924 **
925 **     none.
926 **--
927 */
928 int scrclose(dev_t dev, int flag, int mode, struct lwp *l)
929 {
930 #if 0
931     struct scr_softc   *sc  = device_lookup_private(&scr_cd, SCRUNIT(dev));
932 #endif
933 
934     KERN_DEBUG (scrdebug, SCRCLOSE_DEBUG_INFO,
935                 ("scrclose: called for minor device %d flag 0x%x\n",
936                  SCRUNIT(dev), flag));
937 
938     // david,jim - remove ifdef this when NCI can cope with only 1 open
939 #if 0
940     /* Check we are open in the first place
941     */
942     if (sc->open)
943     {
944         /* put everything in the idle state */
945         scrClkInit();
946         initStates(sc);
947         sc->open = false;
948 
949     }
950 
951 
952     else
953     {
954         KERN_DEBUG (scrdebug, SCRCLOSE_DEBUG_INFO,("\t scrclose, device not open\n"));
955     }
956 #endif
957 
958     KERN_DEBUG (scrdebug, SCRCLOSE_DEBUG_INFO,("scrclose exiting\n"));
959     return(0);
960 }
961 
962 /*
963 **++
964 **  FUNCTIONAL DESCRIPTION:
965 **
966 **     This routine is responsible for performing I/O controls.
967 **
968 **      There are 4 commands.  Status, On, T0 and Off.
969 **
970 **      Status checks to see if the card is inserted.  This command
971 **      does not use the state machines
972 **
973 **      On turns the card on and gets the ATR sequence from the card.
974 **      This command does use the state machines
975 **
976 **      T0 is used to read and write the card.  This command does use
977 **      the state machines
978 **
979 **      Off turns the card off.  This command does not use the state
980 **      machines.
981 **
982 **
983 **  FORMAL PARAMETERS:
984 **
985 **     dev - input :  Device identifier consisting of major and minor numbers.
986 **     cmd - input : The requested IOCTL command to be performed.
987 **                   See scrio.h for details
988 **
989 **
990 **                   Bit Position      { 3322222222221111111111
991 **                                     { 10987654321098765432109876543210
992 **                   Meaning           | DDDLLLLLLLLLLLLLGGGGGGGGCCCCCCCC
993 **
994 **                   D - Command direction, in/out/both.
995 **                   L - Command argument length.
996 **                   G - Command group, 't' used for tty.
997 **                   C - Actual command enumeration.
998 **
999 **     data - input/output : Direction depends on the command.
1000 **     flag - input : Not used by us but passed to line discipline and ttioctl
1001 **     l    - input : pointer to lwp structure of user.
1002 **
1003 **  IMPLICIT INPUTS:
1004 **
1005 **     none.
1006 **
1007 **  IMPLICIT OUTPUTS:
1008 **
1009 **     sc->masterS      state of master state machine
1010 **
1011 **
1012 **  FUNCTION VALUE:
1013 **
1014 **      ENOTTY   if not correct ioctl
1015 **
1016 **
1017 **  SIDE EFFECTS:
1018 **
1019 **--
1020 */
1021 int
1022 scrioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
1023 {
1024     struct scr_softc*   sc = device_lookup_private(&scr_cd, SCRUNIT(dev));
1025 
1026     int                 error = 0;          /* error value returned */
1027     int                 masterDoneRetries= 0;         /* nuber of times we looked at masterDone */
1028     int                 done;               /* local copy of masterDone */
1029 
1030     ScrStatus *         pIoctlStatus;       /* pointer to status ioctl */
1031     ScrOff *            pIoctlOff;          /* pointer to off ioctl */
1032 
1033     u_int               savedInts;          /* saved interrupts */
1034     int                 s;                  /* saved spl value */
1035 
1036 
1037 
1038     KERN_DEBUG (scrdebug, SCRIOCTL_DEBUG_INFO,
1039                 ("scrioctl: called for device 0x%x, command 0x%lx, "
1040                  "flag 0x%x\n",
1041                  SCRUNIT(dev), cmd, flag));
1042 
1043 
1044 
1045     switch (cmd)
1046     {
1047         /*
1048         ** get the status of the card, ie is it in, in but off, in and on
1049         */
1050         case SCRIOSTATUS:
1051             pIoctlStatus = (ScrStatus*)data;
1052             if (scrGetDetect())
1053             {
1054                 savedInts = disable_interrupts(I32_bit | F32_bit);
1055                 if (sc->masterS == msIdleOn)
1056                 {
1057                     pIoctlStatus->status = CARD_ON;
1058                 }
1059                 else
1060                 {
1061                     ASSERT(sc->masterS == msIdleOff);
1062                     pIoctlStatus->status = CARD_INSERTED;
1063                 }
1064                 restore_interrupts(savedInts);
1065             }
1066 
1067             else
1068             {
1069                 pIoctlStatus->status = CARD_REMOVED;
1070             }
1071             break;
1072 
1073 
1074 
1075         /*
1076         ** turn the card on and get the ATR sequence
1077         */
1078         case SCRIOON:
1079             sc->pIoctlOn = (ScrOn*)data;
1080             // acquire the hat lock.
1081             while (1)
1082             {
1083                 s = splhigh();
1084                 if(!hatLock)
1085                 {
1086                     hatLock = true;
1087                     splx(s);
1088                     break;
1089                 }
1090                 splx(s);
1091 
1092                 tsleep(&tsleepIdent ,PZERO,"hat", 1);
1093             }
1094 
1095 
1096             // check to see if the card is in
1097             if(!scrGetDetect())
1098             {
1099                 initStates(sc);
1100                 cardOff(sc);
1101                 // do not  call scrClkInit() as it is idle already
1102                 sc->pIoctlOn->status = ERROR_CARD_REMOVED;
1103             }
1104 
1105 
1106             // check to see if we are already on
1107             else if(sc->masterS == msIdleOn)
1108             {
1109                 sc->pIoctlOn->status = ERROR_CARD_ON;
1110             }
1111 
1112             // card was in, card is off, so lets start it
1113             else
1114             {
1115                 // set up the top half
1116                 sc->masterDone = false;
1117                 sc->bigTrouble = false;    /* david/jim, remove this when the dust settles  */
1118 
1119 
1120 
1121                 // start bottom half
1122                 scrClkStart (sc,400);
1123                 savedInts = disable_interrupts(I32_bit | F32_bit);
1124                 masterSM(sc,mcOn);
1125                 restore_interrupts(savedInts);
1126 
1127 
1128 
1129                 // see if bottom half done
1130                 while (1)
1131                 {
1132                     // check that we have not looped too many times
1133                     if(masterDoneRetries >= MAX_FIQ_TIME * hz)
1134                     {
1135 //printf("MAX_FIQ_TIME reached \n");
1136                         // big problems, so reset bottom
1137                         savedInts = disable_interrupts(I32_bit | F32_bit);
1138                         scrClkInit();
1139                         initStates(sc);
1140                         cardOff(sc);
1141                         sc->status = ERROR_CARD_REMOVED;
1142                         sc->masterDone = true;
1143                         restore_interrupts(savedInts);
1144                         // dont stop clock, done at bottom of case
1145                     }
1146                     masterDoneRetries++;
1147 
1148                     // get done bit
1149                     savedInts = disable_interrupts(I32_bit | F32_bit);
1150                     done =  sc->masterDone;
1151                     restore_interrupts(savedInts);
1152 
1153                     // see if all done
1154                     if(done)
1155                     {
1156                         break;
1157                     }
1158 
1159 
1160                     // wait for a while
1161                     tsleep(&tsleepIdent ,PZERO,"hat", 1);
1162                 }
1163 
1164 
1165                 // stop bottom half
1166                 scrClkStop();
1167 
1168 
1169                 /* need to fix up count bits in non hat interrupt time, so */
1170                 if (sc->status == ERROR_OK)
1171                 {
1172                     sc->clkCountStartRecv = CLK_COUNT_START;
1173                     sc->clkCountDataRecv  = sc->clkCountStartRecv * START_2_DATA;
1174                     sc->clkCountDataSend  = CLK_COUNT_DATA;
1175                 }
1176 
1177 
1178 
1179                 /* takes while to turn off all lines, so keep out of hat */
1180                 if (sc->masterS != msIdleOn)
1181                 {
1182                     cardOff(sc);
1183                 }
1184                 // get the status back from the state machine
1185                 sc->pIoctlOn->status = sc->status;
1186 
1187 
1188             }
1189 
1190 
1191             // release  the hat lock.
1192             s = splhigh();
1193             ASSERT(hatlock);
1194             hatLock = false;
1195             splx(s);
1196 
1197             // david,jim hack to stop ioctl memcpy problem, to be removed when problem fixed ejg
1198             if (sc->pIoctlOn->status != ERROR_OK)
1199             {
1200                 sc->pIoctlOn->atrLen = 0;
1201             }
1202             break;
1203 
1204 
1205         /*
1206         ** turn the card off
1207         */
1208         case SCRIOOFF:
1209             pIoctlOff = (ScrOff*)data;
1210             // card off does not requires any  state processing, so do work here
1211             initStates(sc);
1212             cardOff(sc);
1213             // do not  call scrClkInit() as it is idle already
1214             pIoctlOff->status = ERROR_OK;
1215             break;
1216 
1217 
1218         /*
1219         ** do a T0 read or write
1220         */
1221         case SCRIOT0:
1222             sc->pIoctlT0 = (ScrT0*)data;
1223 
1224             // acquire the hat lock.
1225             while (1)
1226             {
1227                 s = splhigh();
1228                 if(!hatLock)
1229                 {
1230                     hatLock = true;
1231                     splx(s);
1232                     break;
1233                 }
1234                 splx(s);
1235 
1236                 tsleep(&tsleepIdent ,PZERO,"hat", 1);
1237             }
1238 
1239             // check to see if the card is in
1240             if(!scrGetDetect())
1241             {
1242                 initStates(sc);
1243                 cardOff(sc);
1244                 // do not  call scrClkInit() as it is idle already
1245                 sc->pIoctlT0->status = ERROR_CARD_REMOVED;
1246             }
1247 
1248 
1249             // check to see if card is off
1250             else if(sc->masterS == msIdleOff)
1251             {
1252                 sc->pIoctlT0->status = ERROR_CARD_OFF;
1253             }
1254 
1255             // card was in, card is on, lets do command
1256             else
1257 
1258             {
1259                 // set up the top half
1260                 sc->masterDone = false;
1261                 sc->bigTrouble = false;    /* david/jim, remove this when the dust settles  */
1262 
1263                 // start bottom half
1264                 scrClkStart (sc,sc->clkCountDataSend);
1265                 savedInts = disable_interrupts(I32_bit | F32_bit);
1266                 if (sc->pIoctlT0->writeBuffer)
1267                 {
1268                     masterSM(sc,mcT0DataSend);
1269                 }
1270                 else
1271                 {
1272                     masterSM(sc,mcT0DataRecv);
1273                 }
1274                 restore_interrupts(savedInts);
1275 
1276 
1277                // see if bottom half done
1278                while (1)
1279                {
1280                      // check that we have not looped too many times
1281                      if(masterDoneRetries >= MAX_FIQ_TIME * hz)
1282                      {
1283 //printf("MAX_FIQ_TIME reached \n");
1284                         // big problems, so reset bottom
1285                         savedInts = disable_interrupts(I32_bit | F32_bit);
1286                         scrClkInit();
1287                         initStates(sc);
1288                         cardOff(sc);
1289                         sc->status = ERROR_CARD_REMOVED;
1290                         sc->masterDone = true;
1291                         restore_interrupts(savedInts);
1292                      }
1293                      masterDoneRetries++;
1294 
1295 
1296                     // get done bit
1297                     savedInts = disable_interrupts(I32_bit | F32_bit);
1298                     done =  sc->masterDone;
1299                     restore_interrupts(savedInts);
1300 
1301 
1302                     // see if all done
1303                     if(done)
1304                     {
1305                         break;
1306                     }
1307 
1308 
1309                     // wait for a while
1310                     tsleep(&tsleepIdent ,PZERO,"hat", 1);
1311                 }
1312 
1313                 // stop bottom half
1314                 scrClkStop();
1315 
1316 
1317 
1318                 // get the status back from the state machine
1319                 sc->pIoctlT0->status = sc->status;
1320             }
1321 
1322 
1323             // release  the hat lock.
1324             s = splhigh();
1325             hatLock = false;
1326             splx(s);
1327 
1328 
1329 
1330             // david, jim hack to stop ioctl memcpy problem, to be removed when problem fixed ejg
1331             if (sc->pIoctlT0->status != ERROR_OK)
1332             {
1333                 sc->pIoctlT0->dataLen = 0;
1334             }
1335             break;
1336 
1337         default:
1338             KERN_DEBUG (scrdebug, SCRIOCTL_DEBUG_INFO,("\t scrioctl: unknown command, ENOTTY \n"));
1339             error = ENOTTY;
1340             break;
1341     }
1342 
1343 
1344 
1345     KERN_DEBUG (scrdebug, SCRIOCTL_DEBUG_INFO,
1346                 ("scrioctl: exiting with sc->status %d\n", error));
1347     return (error);
1348 } /* End scrioctl */
1349 
1350 
1351 
1352 
1353 
1354 
1355 /*
1356 **
1357 ** All functions below this point are the bottom half of the driver
1358 **
1359 ** All are called during a FIQ, except for some functions in masterSM which
1360 ** provides the interface between the bottom half and top half of
1361 ** the driver (nb masterDone() helps masterSM() out with this interface
1362 ** between top and bottom parts of the driver.
1363 **
1364 */
1365 
1366 
1367 /*
1368 **++
1369 **  FUNCTIONAL DESCRIPTION:
1370 **
1371 **      masterSM
1372 **
1373 **      This state machine implements the top level state control  It
1374 **      receives commands to turn the card on, and do T0 reads and T0 writes
1375 **      from the scrioctl.  It then calls mid level state machine to action
1376 **      these commands.
1377 **
1378 **      This machine is the only machine to keep state between scrioctl calls.
1379 **      Between calls, the state will be either msIdleOff, or msIdleOn.  msIdleOff
1380 **      indicates that no signals are applied to the card.  msidleOn indicates that
1381 **      power and clock are supplied to the card, and that the card has performed
1382 **      a successful ATR sequence.
1383 **
1384 **      This routine gets called during FIQ interrupts and from scrioctl.  It is a
1385 **      requirement that the scrioctl disables interrupts before calling this function.
1386 **
1387 **      NB:- there is no way for the machine to get from msIdleOn to msIdleOff.  Since
1388 **      this is just a mater of turning all signals off and resetting state machines,
1389 **      scrioctl takes a shortcut and resets everything itself.   Ie it hits everything
1390 **      with a big hammer!!
1391 **
1392 **  FORMAL PARAMETERS:
1393 **
1394 **      sc      -  Pointer to the softc structure.
1395 **      cmd     -  command to the state machine, can be from ioctl, or mid level SM
1396 **
1397 **  IMPLICIT INPUTS:
1398 **
1399 **      sc->masterS     state of this machine
1400 **      sc->pIoctlT0    pointer to T0 ioctl
1401 **
1402 **  IMPLICIT OUTPUTS:
1403 **
1404 **
1405 **  FUNCTION VALUE:
1406 **
1407 **      nill
1408 **
1409 **  SIDE EFFECTS:
1410 **
1411 **      power and clock applied to card if successful ATR
1412 **--
1413 */
1414 static void masterSM(struct scr_softc * sc,int cmd)
1415 {
1416 
1417     if (sc->bigTrouble) return;     // david,jim , remove this when dust settles
1418 
1419     switch (sc->masterS)
1420     {
1421         case msIdleOff:
1422             switch (cmd)
1423             {
1424                 case mcOn:
1425                     if (scrGetDetect())
1426                     {
1427                         /*
1428                         ** the card is off, and we want it on
1429                         */
1430 
1431                         /* set initial values */
1432                         sc->status          = 0;
1433                         sc->convention      = CONVENTION_UNKNOWN;
1434                         sc->protocolType    = 0;
1435                         sc->N               = N_DEFAULT;
1436                         sc->Fi              = Fi_DEFAULT;
1437                         sc->Di              = Di_DEFAULT;
1438                         sc->Wi              = Wi_DEFAULT;
1439                         sc->cardFreq        = CARD_FREQ_DEF;
1440                         sc->clkCountStartRecv = CLK_COUNT_START;
1441                         sc->clkCountDataRecv  = sc->clkCountStartRecv * START_2_DATA;
1442                         sc->clkCountDataSend  = CLK_COUNT_DATA;
1443 
1444                         /* get coldResetSM  to turn on power, clock, reset */
1445                         sc->masterS = msColdReset;
1446                         coldResetSM(sc,crcStart);
1447                     }
1448                     else
1449                     {
1450                         /* card not inserted, so just set status and give up */
1451                         sc->status = ERROR_CARD_REMOVED;
1452                         sc->masterDone = true;
1453                     }
1454                     break;
1455 
1456                 default:
1457                     INVALID_STATE_CMD(sc,sc->masterS,cmd);
1458                     break;
1459             }
1460             break;
1461 
1462         case msColdReset:
1463             switch (cmd)
1464             {
1465                 case mcColdReset:
1466                     /*
1467                     ** coldResetSM has turned on power, clock , reset
1468                     ** tell ATRSM to get the ATR sequence from the card
1469                     */
1470                     sc->masterS = msATR;
1471                     ATRSM(sc,atrcStart);
1472                     break;
1473 
1474                 default:
1475                     INVALID_STATE_CMD(sc,sc->masterS,cmd);
1476                     break;
1477             }
1478             break;
1479 
1480         case msATR:
1481             switch (cmd)
1482             {
1483                 case mcATR:
1484                     /*
1485                     ** ATRSM has tried to get ATR sequence, so give
1486                     ** back results to scrioctl.  ATR sequence data
1487                     ** was copied directly into ioctl data area, so
1488                     ** no need to copy data
1489                     */
1490                     if(sc->status == ERROR_OK)
1491                     {
1492                         sc->masterS = msIdleOn;
1493                     }
1494                     else
1495                     {
1496                         sc->masterS = msIdleOff;
1497                     }
1498                     sc->masterDone = true;
1499                     break;
1500 
1501 
1502                 default:
1503                     INVALID_STATE_CMD(sc,sc->masterS,cmd);
1504                     break;
1505             }
1506             break;
1507 
1508         case msIdleOn:
1509             switch (cmd)
1510             {
1511                 // nb there is no command to go to the IdleOff state.  This
1512                 // is a reset of the state machine, so is done in ioctl
1513 
1514                 case mcT0DataSend:
1515                     /*
1516                     ** card is on, and we want to T0 Send, so
1517                     ** as t0SendSM to do work
1518                     */
1519                     sc->status  = ERROR_OK;
1520                     sc->masterS = msT0Send;
1521                     t0SendSM(sc,t0scStart);
1522                     break;
1523 
1524                 case mcT0DataRecv:
1525                     /*
1526                     ** card is on, and we want to T0 Recv, so
1527                     ** as t0RecvSM to do work
1528                     */
1529                     sc->status  = ERROR_OK;
1530                     sc->masterS = msT0Recv;
1531                     t0RecvSM(sc,t0rcStart);
1532                     break;
1533 
1534                 default:
1535                     INVALID_STATE_CMD(sc,sc->masterS,cmd);
1536                     break;
1537             }
1538 
1539             break;
1540 
1541         case msT0Send:
1542             switch (cmd)
1543             {
1544                 case mcT0Send:
1545                     /*
1546                     ** t0SendSM has tried to send , so lets give back results
1547                     */
1548                     sc->masterS = msIdleOn;
1549                     sc->masterDone = true;
1550                     break;
1551 
1552                 default:
1553                     INVALID_STATE_CMD(sc,sc->masterS,cmd);
1554                     break;
1555             }
1556             break;
1557 
1558         case msT0Recv:
1559             switch (cmd)
1560             {
1561                 case mcT0Recv:
1562                     /*
1563                     ** t0RecvSM has tried to recv , so lets give back results
1564                     ** data was written directly into ioctl data area, so we
1565                     ** do not  need to copy any data
1566                     */
1567                     sc->pIoctlT0->dataLen = sc->dataCount;
1568                     sc->masterS = msIdleOn;
1569                     sc->masterDone = true;
1570                     break;
1571 
1572                 default:
1573                     INVALID_STATE_CMD(sc,sc->masterS,cmd);
1574                     break;
1575             }
1576             break;
1577 
1578         default:
1579             INVALID_STATE_CMD(sc,sc->masterS,cmd);
1580             break;
1581 
1582     }
1583 }
1584 
1585 
1586 
1587 
1588 /*
1589 **++
1590 **  FUNCTIONAL DESCRIPTION:
1591 **
1592 **      t0SendSM
1593 **
1594 **      This is the T=0 Send State Machine.  It is responsible
1595 **      for performing the send part of the ISO 7816-3 T=0
1596 **      protocol.  It is mid level protocol state machine.
1597 **
1598 **      Once started, this machine is driven entirely via the
1599 **      FIQ/timeout structure .
1600 **
1601 **
1602 **
1603 **  FORMAL PARAMETERS:
1604 **
1605 **      sc      -  Pointer to the softc structure.
1606 **      cmd     -  command to this machine
1607 **
1608 **  IMPLICIT INPUTS:
1609 **
1610 **      sc->t0SendS             state of this machine
1611 **      sc->pIoctlT0->command   command to send to card
1612 **      sc->pIoctlT0->data      data to send to card
1613 **
1614 **  IMPLICIT OUTPUTS:
1615 **
1616 **      sc->status              error status from this machine
1617 **      sc->pIoctlT0->sw1       command status from card
1618 **      sc->pIoctlT0->sw2       command status from card
1619 **      sc->status              error status from this machine
1620 **
1621 **  FUNCTION VALUE:
1622 **
1623 **      nill
1624 **
1625 **  SIDE EFFECTS:
1626 **
1627 **      nill
1628 **--
1629 */
1630 static void   t0SendSM         (struct scr_softc * sc, int cmd)
1631 {
1632     if (sc->bigTrouble) return;     // david,jim , remove this when dust settles
1633     /*
1634     ** check for major failures that are common to most states
1635     */
1636     if (cmd == t0scTWorkWaiting ||
1637         cmd == gcT0RecvByteErr  ||
1638         cmd == gcT0SendByteErr
1639         )
1640     {
1641         switch(cmd)
1642         {
1643             case t0scTWorkWaiting:
1644                 ASSERT(sc->t0SendS != t0ssIdle);
1645 
1646                 /* kill all lower machines */
1647                 t0SendByteSM(sc,t0sbcAbort);
1648                 t0RecvByteSM(sc,t0rbcAbort);
1649 
1650                 /* set status */
1651                 sc->status = ERROR_WORK_WAITING;
1652                 break;
1653 
1654             case gcT0RecvByteErr:   // fall through
1655             case gcT0SendByteErr:
1656                 scrUntimeout(t0SendSM, sc, t0scTWorkWaiting);
1657                 // done set status, already set in lower machine
1658                 break;
1659 
1660             default:
1661                 INVALID_STATE_CMD(sc, sc->t0SendS,cmd);
1662                 break;
1663         }
1664 
1665         /* change states */
1666         sc->t0SendS = t0ssIdle;
1667         masterSM(sc,mcT0Send);
1668         return;
1669     }
1670 
1671     switch (sc->t0SendS)
1672     {
1673         case t0ssIdle:
1674             switch (cmd)
1675             {
1676                 case t0scStart:
1677                     /* set initial values */
1678                     sc->t0SendS = t0ssSendHeader;
1679                     sc->t0ByteParent = t0SendSM;
1680                     sc->commandCount = 0;
1681                     sc->dataCount = 0;
1682                     sc->dataMax = sc->pIoctlT0->command[CMD_BUF_DATA_LEN_OFF];
1683                     sc->dataByte = sc->pIoctlT0->command[sc->commandCount];
1684 
1685                     // get a byte
1686                     t0SendByteSM(sc,t0sbcStart);
1687                     break;
1688 
1689                 default:
1690                     INVALID_STATE_CMD(sc, sc->t0SendS,cmd);
1691                     break;
1692             }
1693             break;
1694 
1695         case t0ssSendHeader:
1696             switch (cmd)
1697             {
1698                 case gcT0SendByte:
1699                     sc->commandCount++;
1700                     if (sc->commandCount < CMD_BUF_LEN)
1701                     {
1702                         sc->dataByte = sc->pIoctlT0->command[sc->commandCount];
1703                         t0SendByteSM(sc,t0sbcStart);
1704                     }
1705                     else
1706                     {
1707                         ASSERT(sc->commandCount == CMD_BUF_LEN);
1708 
1709                         sc->t0SendS = t0ssRecvProcedure;
1710                         scrTimeout(t0SendSM,sc,t0scTWorkWaiting,T_WORK_WAITING);
1711                         t0RecvByteSM(sc,t0rbcStart);
1712                     }
1713                     break;
1714 
1715                 default:
1716                     INVALID_STATE_CMD(sc, sc->t0SendS,cmd);
1717                     break;
1718             }
1719             break;
1720 
1721         case t0ssRecvProcedure:
1722             switch (cmd)
1723             {
1724                 case gcT0RecvByte:
1725                     scrUntimeout(t0SendSM, sc,t0scTWorkWaiting);
1726                     /* see if we should send all remaining bytes */
1727                     if ( (sc->dataByte == sc->pIoctlT0->command[CMD_BUF_INS_OFF])          ||
1728                          (sc->dataByte == (sc->pIoctlT0->command[CMD_BUF_INS_OFF] ^ 0x01))   )
1729                     {
1730                         ASSERT(sc->dataCount < sc->dataMax);
1731                         sc->t0SendS = t0ssSendData;
1732                         sc->dataByte = sc->pIoctlT0->data[sc->dataCount];
1733                         t0SendByteSM(sc,t0sbcStart);
1734                         sc->dataCount++;
1735                     }
1736 
1737                     /* see if we should send one data byte */
1738                     else if ((sc->dataByte == (sc->pIoctlT0->command[CMD_BUF_INS_OFF]  ^ 0xFF)) ||
1739                              (sc->dataByte == (sc->pIoctlT0->command[CMD_BUF_INS_OFF]  ^ 0xFE)) )
1740                     {
1741                         ASSERT(sc->dataCount < sc->dataMax);
1742                         sc->t0SendS = t0ssSendByte;
1743                         sc->dataByte = sc->pIoctlT0->data[ sc->dataCount];
1744                         t0SendByteSM(sc,t0sbcStart);
1745                         sc->dataCount++;
1746                     }
1747 
1748                     /* see if we should extend the work waiting period */
1749                     else if (sc->dataByte == 0x60)
1750                     {
1751                         t0RecvByteSM(sc,t0rbcStart);
1752                         scrTimeout(t0SendSM,sc,t0scTWorkWaiting,T_WORK_WAITING);
1753                     }
1754 
1755 #ifdef ORIGINAL_SW1_CODE /* XXX XXX XXX cgd */
1756                     /* see if we have a SW1 byte */
1757                     else if ( ((sc->dataByte & 0xf0)  == 0x60) || ((sc->dataByte & 0xf0)  == 0x90)
1758                               &&
1759                               sc->dataByte != 0x60)
1760 #else /* XXX XXX XXX cgd */
1761                     /* see if we have a SW1 byte */
1762                     else if ( ( ((sc->dataByte & 0xf0)  == 0x60) || ((sc->dataByte & 0xf0)  == 0x90) )
1763                               &&
1764                               sc->dataByte != 0x60)
1765 #endif /* XXX XXX XXX cgd */
1766                     {
1767                         sc->pIoctlT0->sw1 = sc->dataByte;
1768                         sc->t0SendS = t0ssRecvSW2;
1769                         t0RecvByteSM(sc,t0rbcStart);
1770                         scrTimeout(t0SendSM,sc,t0scTWorkWaiting,T_WORK_WAITING);
1771                     }
1772 
1773                     /* got bad data byte, log error and get out */
1774                     else
1775                     {
1776                         sc->status = ERROR_BAD_PROCEDURE_BYTE;
1777 
1778                         /* change state */
1779                         sc->t0SendS = t0ssIdle;
1780                         masterSM(sc,mcT0Send);
1781                     }
1782                     break;
1783 
1784                 default:
1785                     INVALID_STATE_CMD(sc, sc->t0SendS,cmd);
1786                     break;
1787             }
1788             break;
1789 
1790         case t0ssSendByte:
1791             switch (cmd)
1792             {
1793                 case gcT0SendByte:
1794                     if (sc->dataCount < sc->dataMax)
1795                     {
1796                         sc->t0SendS = t0ssRecvProcedure;
1797                     }
1798 
1799                     /* wait for sw1 byte */
1800                     else
1801                     {
1802                         ASSERT(sc->dataCount == sc->dataMax);
1803                         sc->t0SendS = t0ssRecvSW1;
1804                     }
1805 
1806                     // ask for another byte
1807                     t0RecvByteSM(sc,t0rbcStart);
1808                     scrTimeout(t0SendSM,sc,t0scTWorkWaiting,T_WORK_WAITING);
1809                     break;
1810 
1811                 default:
1812                     INVALID_STATE_CMD(sc, sc->t0SendS,cmd);
1813                     break;
1814             }
1815             break;
1816 
1817         case t0ssSendData:
1818             switch (cmd)
1819             {
1820                 case gcT0SendByte:
1821                     /* send data */
1822                     if (sc->dataCount < sc->dataMax)
1823                     {
1824                         sc->t0SendS = t0ssSendData;
1825                         sc->dataByte = sc->pIoctlT0->data[ sc->dataCount];
1826                         t0SendByteSM(sc,t0sbcStart);
1827                         sc->dataCount++;
1828                     }
1829 
1830                     /* wait for sw1 byte */
1831                     else
1832                     {
1833                         ASSERT(sc->dataCount == sc->dataMax);
1834                         sc->t0SendS = t0ssRecvSW1;
1835                         t0RecvByteSM(sc,t0rbcStart);
1836                         scrTimeout(t0SendSM,sc,t0scTWorkWaiting,T_WORK_WAITING);
1837                     }
1838                     break;
1839 
1840                 default:
1841                     INVALID_STATE_CMD(sc, sc->t0SendS,cmd);
1842                     break;
1843             }
1844             break;
1845 
1846         case t0ssRecvSW1:
1847             switch (cmd)
1848             {
1849                 case gcT0RecvByte:
1850                     scrUntimeout(t0SendSM, sc,t0scTWorkWaiting);
1851                     sc->pIoctlT0->sw1 = sc->dataByte;
1852                     sc->t0SendS = t0ssRecvSW2;
1853                     t0RecvByteSM(sc,t0rbcStart);
1854                     scrTimeout(t0SendSM,sc,t0scTWorkWaiting,T_WORK_WAITING);
1855                     break;
1856                 default:
1857                     INVALID_STATE_CMD(sc, sc->t0SendS,cmd);
1858                     break;
1859             }
1860             break;
1861 
1862         case t0ssRecvSW2:
1863             switch (cmd)
1864             {
1865                 case gcT0RecvByte:
1866                     scrUntimeout(t0SendSM, sc,t0scTWorkWaiting);
1867                     sc->pIoctlT0->sw2 = sc->dataByte;
1868                     sc->t0SendS = t0ssIdle;
1869                     masterSM(sc,mcT0Send);
1870                     break;
1871 
1872                 default:
1873                     INVALID_STATE_CMD(sc, sc->t0SendS,cmd);
1874                     break;
1875             }
1876             break;
1877 
1878         default:
1879             INVALID_STATE_CMD(sc, sc->t0SendS,cmd);
1880             break;
1881     }
1882 }
1883 
1884 
1885 
1886 /*
1887 **++
1888 **  FUNCTIONAL DESCRIPTION:
1889 **
1890 **      t0RecvSM
1891 **
1892 **      This is the T=0 Recv State Machine.  It is responsible
1893 **      for performing the recv part of the ISO 7816-3 T=0
1894 **      protocol.   It is mid level protocol state machine.
1895 **
1896 **      Once started, this machine is driven entirely via the
1897 **      FIQ/timeout structure .
1898 **
1899 **  FORMAL PARAMETERS:
1900 **
1901 **      sc      -  Pointer to the softc structure.
1902 **      cmd     -  command to this machine
1903 **
1904 **  IMPLICIT INPUTS:
1905 **
1906 **      sc->t0RecvS             state of this machine
1907 **      sc->pIoctlT0->command   command to send to card
1908 **
1909 **  IMPLICIT OUTPUTS:
1910 **
1911 **      sc->pIoctlT0->data      data from card
1912 **      sc->pIoctlT0->dataLen   size of data from card
1913 **      sc->pIoctlT0->sw1       command status from card
1914 **      sc->pIoctlT0->sw2       command status from card
1915 **      sc->status              error status from this machine
1916 **
1917 **  FUNCTION VALUE:
1918 **
1919 **      nill
1920 **
1921 **  SIDE EFFECTS:
1922 **
1923 **      nill
1924 **--
1925 */
1926 static void   t0RecvSM (struct scr_softc * sc,int cmd)
1927 {
1928     if (sc->bigTrouble) return;     // david,jim , remove this when dust settles
1929 
1930     /*
1931     ** check for major failures that are common to most states
1932     */
1933     if (cmd == t0rcTWorkWaiting ||
1934         cmd == gcT0RecvByteErr  ||
1935         cmd == gcT0SendByteErr  )
1936 
1937     {
1938         switch(cmd)
1939         {
1940 
1941             case t0rcTWorkWaiting:
1942                 ASSERT(sc->t0RecvS != t0rsIdle);
1943 
1944                 /* kill all lower level machines */
1945                 t0SendByteSM(sc,t0sbcAbort);
1946                 t0RecvByteSM(sc,t0rbcAbort);
1947 
1948                 /* set status */
1949                 sc->status = ERROR_WORK_WAITING;
1950                 break;
1951 
1952             case gcT0RecvByteErr:       // fall through
1953             case gcT0SendByteErr:
1954                 /* kill all the timers */
1955                 scrUntimeout(t0RecvSM, sc,t0rcTWorkWaiting);
1956                 break;
1957 
1958             default:
1959                 INVALID_STATE_CMD(sc, sc->t0RecvS,cmd);
1960                 break;
1961 
1962         }
1963 
1964 
1965 
1966         /* change state */
1967         sc->t0RecvS = t0rsIdle;
1968         masterSM(sc,mcT0Recv);
1969 
1970         /* all done */
1971         return;
1972     }
1973 
1974     switch (sc->t0RecvS)
1975     {
1976         case t0rsIdle:
1977             switch (cmd)
1978             {
1979                 case t0rcStart:
1980                     /* set initial values */
1981                     sc->t0RecvS = t0rsSendHeader;
1982                     sc->t0ByteParent = t0RecvSM;
1983                     sc->commandCount = 0;
1984                     sc->dataCount = 0;
1985                     sc->dataMax = sc->pIoctlT0->command[CMD_BUF_DATA_LEN_OFF];
1986                     if (sc->dataMax == 0)
1987                     {
1988                         sc->dataMax = 256;
1989                     }
1990                     sc->dataByte = sc->pIoctlT0->command[sc->commandCount];
1991                     t0SendByteSM(sc,t0sbcStart);
1992                     break;
1993 
1994                 default:
1995                     INVALID_STATE_CMD(sc, sc->t0RecvS,cmd);
1996                     break;
1997             }
1998             break;
1999 
2000         case t0rsSendHeader:
2001             switch (cmd)
2002             {
2003                 case gcT0SendByte:
2004                     sc->commandCount++;
2005                     if (sc->commandCount < CMD_BUF_LEN)
2006                     {
2007                         sc->dataByte = sc->pIoctlT0->command[sc->commandCount];
2008                         t0SendByteSM(sc,t0sbcStart);
2009                     }
2010                     else
2011                     {
2012                         ASSERT(sc->commandCount == CMD_BUF_LEN);
2013 
2014                         sc->t0RecvS = t0rsRecvProcedure;
2015                         scrTimeout(t0RecvSM,sc,t0rcTWorkWaiting,T_WORK_WAITING);
2016                         t0RecvByteSM(sc,t0rbcStart);
2017                     }
2018                     break;
2019 
2020                 default:
2021                     INVALID_STATE_CMD(sc, sc->t0RecvS,cmd);
2022                     break;
2023             }
2024             break;
2025 
2026         case t0rsRecvProcedure:
2027             switch (cmd)
2028             {
2029                 case gcT0RecvByte:
2030                     scrUntimeout(t0RecvSM, sc,t0rcTWorkWaiting);
2031 
2032                     /* see if we should recv all remaining bytes */
2033                     if ( (sc->dataByte == sc->pIoctlT0->command[CMD_BUF_INS_OFF])          ||
2034                          (sc->dataByte == (sc->pIoctlT0->command[CMD_BUF_INS_OFF] ^ 0x01))   )
2035                     {
2036                         ASSERT(sc->dataCount < sc->dataMax);
2037 
2038                         sc->t0RecvS = t0rsRecvData;
2039                         scrTimeout(t0RecvSM,sc,t0rcTWorkWaiting,T_WORK_WAITING);
2040                         t0RecvByteSM(sc,t0rbcStart);
2041                     }
2042 
2043                     /* see if we should send one data byte */
2044                     else if ((sc->dataByte == (sc->pIoctlT0->command[CMD_BUF_INS_OFF]  ^ 0xFF)) ||
2045                              (sc->dataByte == (sc->pIoctlT0->command[CMD_BUF_INS_OFF]  ^ 0xFE)) )
2046                     {
2047                         ASSERT(sc->dataCount < sc->dataMax);
2048                         sc->t0RecvS = t0rsRecvByte;
2049                         scrTimeout(t0RecvSM,sc,t0rcTWorkWaiting,T_WORK_WAITING);
2050                         t0RecvByteSM(sc,t0rbcStart);
2051                     }
2052 
2053                     /* see if we should extend the work waiting period */
2054                     else if (sc->dataByte == 0x60)
2055                     {
2056                         t0RecvByteSM(sc,t0rbcStart);
2057                         scrTimeout(t0RecvSM,sc,t0rcTWorkWaiting,T_WORK_WAITING);
2058                     }
2059 
2060 #ifdef ORIGINAL_SW1_CODE /* XXX XXX XXX cgd */
2061                     /* see if we have a SW1 byte */
2062                     else if ( ((sc->dataByte & 0xf0)  == 0x60) || ((sc->dataByte & 0xf0)  == 0x90)
2063                               &&
2064                               sc->dataByte != 0x60)
2065 #else /* XXX XXX XXX cgd */
2066                     /* see if we have a SW1 byte */
2067                     else if ( ( ((sc->dataByte & 0xf0)  == 0x60) || ((sc->dataByte & 0xf0)  == 0x90) )
2068                               &&
2069                               sc->dataByte != 0x60)
2070 #endif /* XXX XXX XXX cgd */
2071                     {
2072                         sc->pIoctlT0->sw1 = sc->dataByte;
2073                         sc->t0RecvS = t0rsRecvSW2;
2074                         t0RecvByteSM(sc,t0rbcStart);
2075                         scrTimeout(t0RecvSM,sc,t0rcTWorkWaiting,T_WORK_WAITING);
2076                     }
2077 
2078                     /* got bad data byte, log error and get out */
2079                     else
2080                     {
2081                         sc->status = ERROR_BAD_PROCEDURE_BYTE;
2082 
2083                         /* change state */
2084                         sc->t0RecvS = t0rsIdle;
2085                         masterSM(sc,mcT0Recv);
2086                     }
2087                     break;
2088 
2089                 default:
2090                     INVALID_STATE_CMD(sc, sc->t0RecvS,cmd);
2091                     break;
2092             }
2093             break;
2094 
2095         case t0rsRecvByte:
2096             switch (cmd)
2097             {
2098                 case gcT0RecvByte:
2099                     /* clock in byte */
2100                     scrUntimeout(t0RecvSM, sc,t0rcTWorkWaiting);
2101                     sc->pIoctlT0->data[sc->dataCount] = sc->dataByte;
2102                     sc->dataCount++;
2103 
2104 
2105                     if (sc->dataCount < sc->dataMax)
2106                     {
2107                         /* get procedure byte */
2108                         sc->t0RecvS = t0rsRecvProcedure;
2109                     }
2110 
2111                     else
2112                     {
2113                         ASSERT(sc->dataCount == sc->dataMax);
2114                         sc->t0RecvS = t0rsRecvSW1;
2115                     }
2116 
2117                     // ask for another byte
2118                     scrTimeout(t0RecvSM,sc,t0rcTWorkWaiting,T_WORK_WAITING);
2119                     t0RecvByteSM(sc,t0rbcStart);
2120                     break;
2121 
2122                 default:
2123                     INVALID_STATE_CMD(sc, sc->t0RecvS,cmd);
2124                     break;
2125             }
2126             break;
2127 
2128         case t0rsRecvData:
2129             switch (cmd)
2130             {
2131                 case gcT0RecvByte:
2132                     /* clock in data */
2133                     scrUntimeout(t0RecvSM, sc,t0rcTWorkWaiting);
2134                     sc->pIoctlT0->data[sc->dataCount] = sc->dataByte;
2135                     sc->dataCount++;
2136 
2137                     /* decide if we have all data */
2138                     if (sc->dataCount >= sc->dataMax)
2139                     {
2140                         KERN_DEBUG (scrdebug, T0_RECV_SM_DEBUG_INFO,("\t\tt0RecvSM: changing state to t0rsRecvSW1\n"));
2141                         ASSERT(sc->dataCount == sc->dataMax);
2142                         sc->t0RecvS = t0rsRecvSW1;
2143                     }
2144 
2145                     /* ask for another byte */
2146                     scrTimeout(t0RecvSM,sc,t0rcTWorkWaiting,T_WORK_WAITING);
2147                     t0RecvByteSM(sc,t0rbcStart);
2148                     break;
2149 
2150                 default:
2151                     INVALID_STATE_CMD(sc, sc->t0RecvS,cmd);
2152                     break;
2153             }
2154             break;
2155 
2156         case t0rsRecvSW1:
2157             switch (cmd)
2158             {
2159                 case gcT0RecvByte:
2160                     scrUntimeout(t0RecvSM, sc,t0rcTWorkWaiting);
2161                     sc->pIoctlT0->sw1 = sc->dataByte;
2162 
2163                     sc->t0RecvS = t0rsRecvSW2;
2164                     t0RecvByteSM(sc,t0rbcStart);
2165                     scrTimeout(t0RecvSM,sc,t0rcTWorkWaiting,T_WORK_WAITING);
2166                     break;
2167                 default:
2168                     INVALID_STATE_CMD(sc, sc->t0RecvS,cmd);
2169                     break;
2170             }
2171             break;
2172 
2173         case t0rsRecvSW2:
2174             switch (cmd)
2175             {
2176                 case gcT0RecvByte:
2177                     scrUntimeout(t0RecvSM, sc,t0rcTWorkWaiting);
2178                     sc->pIoctlT0->sw2 = sc->dataByte;
2179 
2180                     sc->t0RecvS = t0rsIdle;
2181                     masterSM(sc,mcT0Recv);
2182                     break;
2183 
2184                 default:
2185                     INVALID_STATE_CMD(sc, sc->t0RecvS,cmd);
2186                     break;
2187             }
2188             break;
2189 
2190         default:
2191             INVALID_STATE_CMD(sc, sc->t0RecvS,cmd);
2192             break;
2193     }
2194 }
2195 
2196 
2197 /*
2198 **++
2199 **  FUNCTIONAL DESCRIPTION:
2200 **
2201 **      coldResetSM
2202 **
2203 **      This state machine switches on the power, clock and reset pins
2204 **      in the correct order/timing.
2205 **      It is a low level bit-bashing state machine.
2206 **
2207 **
2208 **  FORMAL PARAMETERS:
2209 **
2210 **      sc      -  Pointer to the softc structure.
2211 **      cmd     -  command to this machine
2212 **
2213 **  IMPLICIT INPUTS:
2214 **
2215 **      sc->coldResetS     state of this machine
2216 **
2217 **  IMPLICIT OUTPUTS:
2218 **
2219 **      nill
2220 **
2221 **  FUNCTION VALUE:
2222 **
2223 **      nill
2224 **
2225 **  SIDE EFFECTS:
2226 **
2227 **      signals to card are on
2228 **--
2229 */
2230 static void   coldResetSM(struct scr_softc * sc,int cmd)
2231 {
2232     if (sc->bigTrouble) return;     // david,jim , remove this when dust settles
2233 
2234     switch (sc->coldResetS)
2235     {
2236         case    crsIdle:
2237             switch (cmd)
2238             {
2239                 case crcStart:
2240                     scrSetReset(true);
2241                     scrSetClock(true);
2242                     scrSetDataHighZ();
2243                     scrSetPower(true);
2244 
2245                     /* start a t2 timer */
2246                     scrTimeout(coldResetSM,sc,crcT2,T_t2);
2247                     sc->coldResetS = crsT2Wait;
2248                     break;
2249 
2250                 default:
2251                     INVALID_STATE_CMD(sc,sc->masterS,cmd);
2252                     break;
2253             }
2254             break;
2255 
2256         case    crsT2Wait:
2257             switch (cmd)
2258             {
2259                 case crcT2:
2260                     /* turn off rst */
2261                     scrSetReset(false);
2262 
2263                     /* tell master state machine that we are all done */
2264                     sc->coldResetS = crsIdle;
2265                     masterSM(sc,mcColdReset);
2266                     break;
2267 
2268                 default:
2269                     INVALID_STATE_CMD(sc,sc->masterS,cmd);
2270                     break;
2271             }
2272             break;
2273 
2274 
2275         default:
2276             INVALID_STATE_CMD(sc,sc->coldResetS,cmd);
2277             break;
2278     }
2279 }
2280 
2281 /*
2282 **++
2283 **  FUNCTIONAL DESCRIPTION:
2284 **
2285 **      ATRSM
2286 **
2287 **      This is the Answer To Reset State Machine.  It is responsible
2288 **      for performing the Answer To Reset as specified in ISO 7816-3.
2289 **      It is mid level protocol state machine.
2290 **
2291 **      Once started, this machine is driven entirely via the
2292 **      FIQ/timeout structure.
2293 **
2294 **
2295 **      During the first byte, we have to check if the card is operating
2296 **      at full speed or half speed.  The first couple of bits are
2297 **      checked to see if it is 1/2 speed, and if so, the clock is changed
2298 **      and the state adjustes
2299 **
2300 **      At the end of the first byte we have to determin the logic being
2301 **      used by the card, ie is it active high/low and msb/lsb.
2302 **
2303 **
2304 **  FORMAL PARAMETERS:
2305 **
2306 **      sc      -  Pointer to the softc structure.
2307 **      cmd     -  command to this machine
2308 **
2309 **  IMPLICIT INPUTS:
2310 **
2311 **      sc->pIoctlAtr->atr      data from card
2312 **      sc->pIoctlT0->sw1       command status from card
2313 **      sc->pIoctlT0->sw2       command status from card
2314 **      sc->status              error status from this machine
2315 **
2316 **  IMPLICIT OUTPUTS:
2317 **
2318 **      sc->pIoctlOn->atrBuf    data from ATR sequence
2319 **      sc->pIoctlOn->atrLen    size of data from ATR sequence
2320 **      sc->status              error status from this machine
2321 **
2322 **
2323 **  FUNCTION VALUE:
2324 **
2325 **      nill
2326 **
2327 **  SIDE EFFECTS:
2328 **
2329 **      nill
2330 **--
2331 */
2332 static void ATRSM (struct scr_softc * sc,int cmd)
2333 {
2334     int lc;
2335     int tck;
2336 
2337     if (sc->bigTrouble) return;     // david,jim , remove this when dust settles
2338 
2339     /*
2340     ** check for major failures that are common to most states
2341     */
2342     if (cmd == atrcT3            ||
2343         cmd == atrcTWorkWaiting  ||
2344         cmd == gcT0RecvByteErr
2345         )
2346     {
2347         switch(cmd)
2348         {
2349             case atrcT3:
2350                 scrUntimeout (ATRSM,sc,atrcTWorkWaiting);
2351                 sc->status = ERROR_ATR_T3;
2352                 t0RecvByteSM(sc,t0rbcAbort);
2353                 break;
2354 
2355             case atrcTWorkWaiting:
2356                 scrUntimeout (ATRSM,sc,atrcT3);
2357                 sc->status = ERROR_WORK_WAITING;
2358                 t0RecvByteSM(sc,t0rbcAbort);
2359                 break;
2360 
2361             case gcT0RecvByteErr:
2362                 scrUntimeout (ATRSM,sc,atrcT3);
2363                 scrUntimeout (ATRSM,sc,atrcTWorkWaiting);
2364                 /* done set status, its already set */
2365                 break;
2366 
2367             default:
2368                 INVALID_STATE_CMD(sc,sc->ATRS,cmd);
2369                 break;
2370         }
2371 
2372         /* change state */
2373         sc->ATRS = atrsIdle;
2374         masterSM(sc,mcATR);
2375         return;
2376     }
2377 
2378     switch (sc->ATRS)
2379     {
2380         case    atrsIdle:
2381             switch (cmd)
2382             {
2383                 case atrcStart:
2384                     /* lets start looking */
2385                     sc->ATRS = atrsTS;
2386                     sc->pIoctlOn->atrLen = 0;
2387                     sc->t0ByteParent = ATRSM;
2388                     scrTimeout(ATRSM,sc,atrcT3,T_t3 *2);  /* by 2 to accommodate 1/2 freq cards */
2389                     t0RecvByteSM(sc,t0rbcStart);
2390                     break;
2391 
2392                 default:
2393                     INVALID_STATE_CMD(sc,sc->ATRS,cmd);
2394                     break;
2395             }
2396             break;
2397 
2398         case atrsTS:
2399             switch (cmd)
2400             {
2401                 case gcT0RecvByte:
2402                     scrUntimeout(ATRSM,sc,atrcT3);
2403                     sc->pIoctlOn->atrBuf[sc->pIoctlOn->atrLen] = sc->dataByte;
2404                     sc->pIoctlOn->atrLen++;
2405                     if(sc->pIoctlOn->atrLen >= ATR_BUF_MAX)
2406                     {
2407                         #ifdef SCR_DEBUG
2408                             DEBUGGER;
2409                         #endif
2410                         sc->status = ERROR_ATR_TCK;
2411                         sc->ATRS = atrsIdle;
2412                         masterSM(sc,mcATR);
2413                     }
2414                     else
2415                     {
2416                         /* move onto recv T0 */
2417                         sc->ATRS = atrsT0;
2418                         scrTimeout(ATRSM,sc,atrcTWorkWaiting,T_WORK_WAITING);
2419                         t0RecvByteSM(sc,t0rbcStart);
2420                     }
2421                     break;
2422 
2423                 default:
2424                     INVALID_STATE_CMD(sc,sc->ATRS,cmd);
2425                     break;
2426             }
2427             break;
2428 
2429         case atrsT0:
2430             switch (cmd)
2431             {
2432                 case gcT0RecvByte:
2433                     scrUntimeout(ATRSM,sc,atrcTWorkWaiting);
2434                     sc->pIoctlOn->atrBuf[sc->pIoctlOn->atrLen] = sc->dataByte;
2435                     sc->pIoctlOn->atrLen++;
2436                     if(sc->pIoctlOn->atrLen >= ATR_BUF_MAX)
2437                     {
2438                         #ifdef SCR_DEBUG
2439                             printf("atrLen >= ATR_BUF_MAX\n");
2440                             DEBUGGER;
2441                         #endif
2442                         sc->status = ERROR_ATR_TCK;
2443                         sc->ATRS = atrsIdle;
2444                         masterSM(sc,mcATR);
2445                     }
2446                     else
2447                     {
2448                         /* store Y & K */
2449                         sc->atrY = sc->dataByte & 0xf0;
2450                         sc->atrK = sc->dataByte & 0x0f;
2451 
2452                         sc->atrTABCDx = 1;
2453                         sc->atrKCount = 1;
2454 
2455                         /* if there are no TDx following set T0 protocol */
2456                         if (!ISSET(sc->atrY,ATR_Y_TD))
2457                         {
2458                             sc->protocolType    = PROTOCOL_T0;
2459                         }
2460 
2461 
2462                         if (sc->atrY)
2463                         {
2464 
2465                             sc->ATRS = atrsTABCD;
2466                             scrTimeout(ATRSM,sc,atrcTWorkWaiting,T_WORK_WAITING);
2467                             t0RecvByteSM(sc,t0rbcStart);
2468                         }
2469 
2470                         else if (sc->atrK)
2471                         {
2472                             sc->ATRS = atrsTK;
2473                             scrTimeout(ATRSM,sc,atrcTWorkWaiting,T_WORK_WAITING);
2474                             t0RecvByteSM(sc,t0rbcStart);
2475                         }
2476 
2477                         else if (sc->protocolType != PROTOCOL_T0)
2478                         {
2479                             sc->ATRS = atrsTCK;
2480                             scrTimeout(ATRSM,sc,atrcTWorkWaiting,T_WORK_WAITING);
2481                             t0RecvByteSM(sc,t0rbcStart);
2482                         }
2483 
2484                         else /* got all of ATR */
2485                         {
2486                             sc->ATRS = atrsIdle;
2487                             masterSM(sc,mcATR);
2488                         }
2489                     }
2490                     break;
2491 
2492 
2493                 default:
2494                     INVALID_STATE_CMD(sc,sc->ATRS,cmd);
2495                     break;
2496             }
2497             break;
2498 
2499 
2500         case atrsTABCD:
2501             switch (cmd)
2502             {
2503                 case gcT0RecvByte:
2504                     scrUntimeout(ATRSM,sc,atrcTWorkWaiting);
2505                     sc->pIoctlOn->atrBuf[sc->pIoctlOn->atrLen] = sc->dataByte;
2506                     sc->pIoctlOn->atrLen++;
2507                     if(sc->pIoctlOn->atrLen >= ATR_BUF_MAX)
2508                     {
2509                         #ifdef SCR_DEBUG
2510                             printf("atrLen >= ATR_BUF_MAX\n");
2511                             DEBUGGER;
2512                         #endif
2513                         sc->status = ERROR_ATR_TCK;
2514                         sc->ATRS = atrsIdle;
2515                         masterSM(sc,mcATR);
2516                     }
2517                     else
2518                     {
2519                         if (sc->atrY & ATR_Y_TA)
2520                         {
2521                             sc->atrY &= ~ATR_Y_TA;
2522                             if (sc->atrTABCDx == 1)
2523                             {
2524                                 sc->Fi = FI2Fi[((sc->dataByte >> 4) & 0x0f)];
2525                                 if (sc->Fi == 0)
2526                                 {
2527                                     sc->status = ERROR_ATR_FI_INVALID;
2528                                     sc->Fi = Fi_DEFAULT;
2529                                 }
2530 
2531                                 sc->Di = DI2Di[(sc->dataByte & 0x0f)];
2532                                 if (sc->Di == 0)
2533                                 {
2534                                     sc->status = ERROR_ATR_DI_INVALID;
2535                                     sc->Di = Di_DEFAULT;
2536                                 }
2537 
2538                             }
2539                         }
2540 
2541                         else if (sc->atrY & ATR_Y_TB)
2542                         {
2543                             sc->atrY &= ~ATR_Y_TB;
2544                         }
2545 
2546                         else if (sc->atrY & ATR_Y_TC)
2547                         {
2548                             sc->atrY &= ~ATR_Y_TC;
2549                             if (sc->atrTABCDx == 1)
2550                             {
2551                                 sc->N = sc->dataByte;
2552                             }
2553 
2554                             if (sc->atrTABCDx == 2)
2555                             {
2556                                 sc->Wi = sc->dataByte;
2557                             }
2558                         }
2559 
2560                         else
2561                         {
2562                             ASSERT(sc->atrY & ATR_Y_TD);
2563                             sc->atrY &= ~ATR_Y_TD;
2564 
2565                             /* copy across the y section of TD */
2566                             sc->atrY    =    sc->dataByte;
2567                             sc->atrY &= 0xf0;
2568 
2569                             /* step to the next group of TABCD */
2570                             sc->atrTABCDx++;
2571 
2572                             /* store protocols */
2573                             sc->protocolType = (1 << (sc->dataByte &0x0f));
2574                         }
2575 
2576 
2577                         /* see what we should do next */
2578                         if (sc->atrY)
2579                         {
2580                             /* just stay in the same state */
2581                             scrTimeout(ATRSM,sc,atrcTWorkWaiting,T_WORK_WAITING);
2582                             t0RecvByteSM(sc,t0rbcStart);
2583                         }
2584 
2585                         else if (sc->atrK)
2586                         {
2587                             sc->ATRS = atrsTK;
2588                             scrTimeout(ATRSM,sc,atrcTWorkWaiting,T_WORK_WAITING);
2589                             t0RecvByteSM(sc,t0rbcStart);
2590                         }
2591 
2592                         else if (sc->protocolType != PROTOCOL_T0)
2593                         {
2594                             sc->ATRS = atrsTCK;
2595                             scrTimeout(ATRSM,sc,atrcTWorkWaiting,T_WORK_WAITING);
2596                             t0RecvByteSM(sc,t0rbcStart);
2597                         }
2598 
2599                         else /* got all of ATR */
2600                         {
2601                             sc->ATRS = atrsIdle;
2602                             masterSM(sc,mcATR);
2603                         }
2604                     }
2605 
2606                     break;
2607 
2608 
2609                 default:
2610                     INVALID_STATE_CMD(sc,sc->ATRS,cmd);
2611                     break;
2612             }
2613             break;
2614 
2615         case atrsTK:
2616             switch (cmd)
2617             {
2618                 case gcT0RecvByte:
2619                     scrUntimeout(ATRSM,sc,atrcTWorkWaiting);
2620                     sc->pIoctlOn->atrBuf[sc->pIoctlOn->atrLen] = sc->dataByte;
2621                     sc->pIoctlOn->atrLen++;
2622                     if(sc->pIoctlOn->atrLen >= ATR_BUF_MAX)
2623                     {
2624                         #ifdef SCR_DEBUG
2625                             printf("atrLen >= ATR_BUF_MAX\n");
2626                             DEBUGGER;
2627                         #endif
2628                         sc->status = ERROR_ATR_TCK;
2629                         sc->ATRS = atrsIdle;
2630                         masterSM(sc,mcATR);
2631                     }
2632                     else
2633                     {
2634 
2635                         if (sc->atrKCount < sc->atrK)
2636                         {
2637                             sc->atrKCount++;
2638                             scrTimeout(ATRSM,sc,atrcTWorkWaiting,T_WORK_WAITING);
2639                             t0RecvByteSM(sc,t0rbcStart);
2640                         }
2641 
2642 
2643                         else if (sc->protocolType != PROTOCOL_T0)
2644                         {
2645                             sc->ATRS = atrsTCK;
2646                             scrTimeout(ATRSM,sc,atrcTWorkWaiting,T_WORK_WAITING);
2647                             t0RecvByteSM(sc,t0rbcStart);
2648                         }
2649 
2650                         else /* got all of ATR */
2651                         {
2652                             sc->ATRS = atrsIdle;
2653                             masterSM(sc,mcATR);
2654                         }
2655                     }
2656                     break;
2657 
2658                 default:
2659                     INVALID_STATE_CMD(sc,sc->ATRS,cmd);
2660                     break;
2661             }
2662             break;
2663 
2664         case atrsTCK:
2665             switch (cmd)
2666             {
2667                 case gcT0RecvByte:
2668                     scrUntimeout(ATRSM,sc,atrcTWorkWaiting);
2669                     sc->pIoctlOn->atrBuf[sc->pIoctlOn->atrLen] = sc->dataByte;
2670                     sc->pIoctlOn->atrLen++;
2671                     if(sc->pIoctlOn->atrLen >= ATR_BUF_MAX)
2672                     {
2673                         #ifdef SCR_DEBUG
2674                             printf("atrLen >= ATR_BUF_MAX\n");
2675                             DEBUGGER;
2676                         #endif
2677                         sc->status = ERROR_ATR_TCK;
2678                         sc->ATRS = atrsIdle;
2679                         masterSM(sc,mcATR);
2680                     }
2681                     else
2682                     {
2683                         tck = 0;
2684                         for (lc = 1; lc < sc->pIoctlOn->atrLen-1; lc++)
2685                         {
2686                             tck ^= sc->pIoctlOn->atrBuf[lc];
2687                         }
2688 
2689                         if (tck == sc->pIoctlOn->atrBuf[sc->pIoctlOn->atrLen-1])
2690                         {
2691                             sc->ATRS = atrsIdle;
2692                             masterSM(sc,mcATR);
2693                         }
2694                         else
2695                         {
2696                             sc->status = ERROR_ATR_TCK;
2697                             sc->ATRS = atrsIdle;
2698                             masterSM(sc,mcATR);
2699                         }
2700                     }
2701                     break;
2702 
2703                 default:
2704                     INVALID_STATE_CMD(sc,sc->ATRS,cmd);
2705                     break;
2706             }
2707             break;
2708 
2709 
2710 
2711         default:
2712             INVALID_STATE_CMD(sc,sc->ATRS,cmd);
2713             break;
2714     }
2715 }
2716 
2717 
2718 
2719 /*
2720 **++
2721 **  FUNCTIONAL DESCRIPTION:
2722 **
2723 **      t0RecvByteSM
2724 **
2725 **      This state machine attempts to read 1 byte from a card.
2726 **      It is a low level bit-bashing state machine.
2727 **
2728 **      Data from the card is async, so the machine scans at
2729 **      5 times the data rate looking for a state bit.  Once
2730 **      a start bit has been found, it waits for the middle of
2731 **      the bit and starts sampling at the bit rate.
2732 **
2733 **      Several mid level machines can use this machine, so the value
2734 **      sc->t0ByteParent is used to point to back to the mid level machine
2735 **
2736 **
2737 **  FORMAL PARAMETERS:
2738 **
2739 **      sc      -  Pointer to the softc structure.
2740 **      cmd     -  command to this machine
2741 **
2742 **  IMPLICIT INPUTS:
2743 **
2744 **      sc->t0RecvByteS     state of this machine
2745 **      sc->t0ByteParent    mid level machine that started this machine
2746 **
2747 **  IMPLICIT OUTPUTS:
2748 **
2749 **      sc->shiftByte       byte read from the card
2750 **      sc->status          error value if could not read byte
2751 **
2752 **  FUNCTION VALUE:
2753 **
2754 **      nill
2755 **
2756 **  SIDE EFFECTS:
2757 **
2758 **      nill
2759 **--
2760 */
2761 static void   t0RecvByteSM(struct scr_softc* sc,int cmd)
2762 {
2763     if (sc->bigTrouble) return;     // david,jim , remove this when dust settles
2764 
2765     if (cmd == t0rbcAbort)
2766     {
2767         /* kill all the timers */
2768         scrUntimeout(t0RecvByteSM, sc,t0rbcTFindStartEdge);
2769         scrUntimeout(t0RecvByteSM, sc,t0rbcTFindStartMid);
2770         scrUntimeout(t0RecvByteSM, sc,t0rbcTClockData);
2771         scrUntimeout(t0RecvByteSM, sc,t0rbcTErrorStart);
2772         scrUntimeout(t0RecvByteSM, sc,t0rbcTErrorStop);
2773 
2774         scrSetDataHighZ();
2775         sc->t0RecvByteS = t0rbsIdle;
2776         return;
2777     }
2778 
2779 
2780     switch (sc->t0RecvByteS)
2781     {
2782         case t0rbsIdle:
2783             switch (cmd)
2784             {
2785                 case t0rbcStart:
2786                     /* set initial conditions */
2787                     sc->shiftBits   = 0;
2788                     sc->shiftByte   = 0;
2789                     sc->shiftParity = 0;
2790                     sc->shiftParityCount = 0;
2791                     scrClkAdj(sc->clkCountStartRecv); /* recv data clock running at 5 times */
2792 
2793                     /* check if start bit is already here */
2794                     //if (scrGetData())
2795                     if (1)
2796                     {
2797                         /* didn't find it, keep looking */
2798                         scrTimeout(t0RecvByteSM,sc,t0rbcTFindStartEdge,sc->clkCountStartRecv);
2799                         sc->t0RecvByteS = t0rbsFindStartEdge;
2800                     }
2801                     else
2802                     {
2803                         /* found start bit, look for mid bit */
2804                         scrTimeout(t0RecvByteSM,sc,t0rbcTFindStartMid,sc->clkCountStartRecv);
2805                         sc->t0RecvByteS = t0rbsFindStartMid;
2806                     }
2807                     break;
2808 
2809 
2810 
2811                 default:
2812                     INVALID_STATE_CMD(sc, sc->t0RecvByteS,cmd);
2813                     break;
2814             }
2815             break;
2816 
2817 
2818         case    t0rbsFindStartEdge:
2819             switch (cmd)
2820             {
2821                 case t0rbcTFindStartEdge:
2822                     if (scrGetData())
2823                     {
2824                         /* didn't find it, keep looking */
2825                         scrTimeout(t0RecvByteSM,sc,t0rbcTFindStartEdge,sc->clkCountStartRecv);
2826                     }
2827                     else
2828                     {
2829                         /* found start bit, look for mid bit */
2830                         scrTimeout(t0RecvByteSM,sc,t0rbcTFindStartMid,sc->clkCountStartRecv * 2);
2831                         sc->t0RecvByteS = t0rbsFindStartMid;
2832                     }
2833                     break;
2834 
2835 
2836                 default:
2837                     INVALID_STATE_CMD(sc, sc->t0RecvByteS,cmd);
2838                     break;
2839             }
2840             break;
2841 
2842         case    t0rbsFindStartMid:
2843             switch (cmd)
2844             {
2845                 case t0rbcTFindStartMid:
2846                     if (scrGetData())
2847                     {
2848                         /* found glitch, so just go back to hunting */
2849                         scrTimeout(t0RecvByteSM,sc,t0rbcTFindStartEdge,sc->clkCountStartRecv);
2850                         sc->t0RecvByteS = t0rbsFindStartEdge;
2851                     }
2852                     else
2853                     {
2854                         /* found start bit, start clocking in data */
2855                         TOGGLE_TEST_PIN();
2856                         scrTimeout(t0RecvByteSM,sc,t0rbcTClockData,sc->clkCountDataRecv);
2857                         sc->t0RecvByteS = t0rbsClockData;
2858                     }
2859                     break;
2860 
2861 
2862                 default:
2863                     INVALID_STATE_CMD(sc, sc->t0RecvByteS,cmd);
2864                     break;
2865             }
2866             break;
2867 
2868 
2869         case    t0rbsClockData:
2870             TOGGLE_TEST_PIN();
2871             switch (cmd)
2872             {
2873                 case t0rbcTClockData:
2874                     if (sc->shiftBits < 8)
2875                     {
2876                         if (sc->convention == CONVENTION_INVERSE ||
2877                             sc->convention == CONVENTION_UNKNOWN)
2878                         {
2879                             /* logic 1 is low, msb is first */
2880                             sc->shiftByte <<= 1;
2881                             sc->shiftByte &=  0xfe;
2882                             if (!scrGetData())
2883                             {
2884                                 sc->shiftByte |= 0x01;
2885                                 sc->shiftParity++;
2886                             }
2887                         }
2888                         else
2889                         {
2890                             ASSERT(sc->convention == CONVENTION_DIRECT);
2891                             /* logic 1 is high, lsb is first */
2892                             sc->shiftByte = sc->shiftByte >> 1;
2893                             sc->shiftByte &=  0x7f;
2894                             if (scrGetData())
2895                             {
2896                                 sc->shiftParity++;
2897                                 sc->shiftByte |= 0x80;
2898                             }
2899                         }
2900                         sc->shiftBits++;
2901 
2902 
2903                         /* in TS byte, check if we have a card that works at 1/2 freq */
2904                         if (sc->convention == CONVENTION_UNKNOWN  &&   /* in TS byte */
2905                             sc->shiftBits == 3 &&                     /* test at bit 3 in word */
2906                             sc->shiftByte == 4 &&                     /* check for 1/2 freq pattern */
2907                             sc->cardFreq  == CARD_FREQ_DEF)           /* only do this if at full freq */
2908                         {
2909                             /* adjust counts down to 1/2 freq */
2910                             sc->cardFreq        = CARD_FREQ_DEF / 2;
2911                             sc->clkCountStartRecv   = sc->clkCountStartRecv *2;
2912                             sc->clkCountDataRecv    = sc->clkCountDataRecv  *2;
2913                             sc->clkCountDataSend    = sc->clkCountDataSend  *2;
2914 
2915 
2916                             /* adjust this so that we have clocked in only fist bit of TS */
2917                             sc->shiftParity = 0;
2918                             sc->shiftByte   = 0;
2919                             sc->shiftBits   = 1;
2920 
2921                             scrTimeout(t0RecvByteSM,sc,t0rbcTClockData,(sc->clkCountDataRecv * 3) /4);
2922                         }
2923                         else
2924                         {
2925                             scrTimeout(t0RecvByteSM,sc,t0rbcTClockData,sc->clkCountDataRecv);
2926                         }
2927                     }
2928 
2929                     /* clock in parity bit  */
2930                     else if (sc->shiftBits == 8)
2931                     {
2932                         if (sc->convention == CONVENTION_INVERSE)
2933                         {
2934                             if (!scrGetData())
2935                             {
2936                                 sc->shiftParity++;
2937                             }
2938                         }
2939                         else if (sc->convention == CONVENTION_DIRECT)
2940                         {
2941                             if (scrGetData())
2942                             {
2943                                 sc->shiftParity++;
2944                             }
2945                         }
2946 
2947 
2948                         else
2949                         {
2950                             /* sc->convention not set so sort it out */
2951                             ASSERT(sc->convention == CONVENTION_UNKNOWN);
2952                             if (sc->shiftByte == CONVENIONT_INVERSE_ID && scrGetData())
2953                             {
2954                                 sc->convention = CONVENTION_INVERSE;
2955                                 sc->shiftParity = 0;    /* force good parity */
2956                             }
2957 
2958                             else if (sc->shiftByte == CONVENTION_DIRECT_ID && scrGetData())
2959                             {
2960                                 sc->shiftByte = CONVENTION_DIRECT_FIX;
2961                                 sc->convention = CONVENTION_DIRECT;
2962                                 sc->shiftParity = 0;    /* force good parity */
2963                             }
2964 
2965                             else
2966                             {
2967                                 sc->shiftParity = 1; /* force bad parity */
2968                             }
2969                         }
2970 
2971 
2972                         if ((sc->shiftParity & 01) == 0)
2973                         {
2974                             sc->shiftBits++;
2975                             scrTimeout(t0RecvByteSM,sc,t0rbcTClockData,sc->clkCountDataRecv);
2976                         }
2977                         else
2978                         {
2979                             /* got parity error */
2980                             if (sc->shiftParityCount < PARITY_ERROR_MAX)
2981                             {
2982                                 sc->shiftParityCount++;
2983                                 scrTimeout(t0RecvByteSM,sc,t0rbcTErrorStart,sc->clkCountDataRecv);
2984                                 sc->t0RecvByteS = t0rbsSendError;
2985                             }
2986                             else
2987 
2988                             {
2989                                 /* too many parity errors, just give up on this sc->dataByte */
2990                                 sc->status = ERROR_PARITY;
2991                                 sc->t0RecvByteS = t0rbsIdle;
2992                                 sc->t0ByteParent(sc,gcT0RecvByteErr);
2993                             }
2994                         }
2995                     }
2996 
2997                     else
2998                     {
2999                         sc->dataByte = sc->shiftByte;
3000                         sc->t0RecvByteS = t0rbsIdle;
3001                         sc->t0ByteParent(sc,gcT0RecvByte);
3002                     }
3003                     break;
3004 
3005                 default:
3006                     INVALID_STATE_CMD(sc, sc->t0RecvByteS,cmd);
3007                     break;
3008             }
3009             break;
3010 
3011 
3012         case    t0rbsSendError:
3013             TOGGLE_TEST_PIN();
3014             switch (cmd)
3015             {
3016                 case t0rbcTErrorStart:
3017                     /* start sending error bit */
3018                     scrSetData(false);
3019                     scrTimeout(t0RecvByteSM,sc,t0rbcTErrorStop,sc->clkCountDataRecv * 2);
3020                     break;
3021 
3022                 case t0rbcTErrorStop:
3023                     /* stop sending parity error & reset information*/
3024                     scrSetData(true);
3025                     sc->shiftBits   = 0;
3026                     sc->shiftByte   = 0;
3027                     sc->shiftParity = 0;
3028 
3029                     /* start looking for start bit */
3030                     scrTimeout(t0RecvByteSM,sc,t0rbcTFindStartEdge,1);
3031                     sc->t0RecvByteS = t0rbsFindStartEdge;
3032                     break;
3033 
3034                 default:
3035                     INVALID_STATE_CMD(sc, sc->t0RecvByteS,cmd);
3036                     break;
3037             }
3038             break;
3039 
3040 
3041         default:
3042             INVALID_STATE_CMD(sc, sc->t0RecvByteS,cmd);
3043             break;
3044     }
3045 }
3046 
3047 /*
3048 **++
3049 **  FUNCTIONAL DESCRIPTION:
3050 **
3051 **      t0SendByteSM
3052 **
3053 **      This state machine writes 1 byte to a card.
3054 **      It is a low level bit-bashing state machine.
3055 **
3056 **
3057 **      Several mid level machines can use this machine, so the value
3058 **      sc->t0ByteParent is used to point to back to the mid level machine
3059 **
3060 **  FORMAL PARAMETERS:
3061 **
3062 **      sc      -  Pointer to the softc structure.
3063 **      cmd     -  command to this machine
3064 **
3065 **  IMPLICIT INPUTS:
3066 **
3067 **      sc->t0SendByteS     state of this machine
3068 **      sc->shiftByte       byte to write to the card
3069 **
3070 **  IMPLICIT OUTPUTS:
3071 **
3072 **      sc->status          error value if could not read byte
3073 **
3074 **  FUNCTION VALUE:
3075 **
3076 **      nill
3077 **
3078 **  SIDE EFFECTS:
3079 **
3080 **      nill
3081 **--
3082 */
3083 //int bigTroubleTest = 0;
3084 static void t0SendByteSM (struct scr_softc * sc,int cmd)
3085 {
3086     //if(bigTroubleTest == 2000)
3087     //{
3088     //    INVALID_STATE_CMD(sc, sc->t0SendByteS,cmd);
3089     //    bigTroubleTest = 0;
3090     //}
3091     //
3092     //bigTroubleTest++;
3093 
3094     if (sc->bigTrouble) return;     // david,jim , remove this when dust settles
3095 
3096     if (cmd == t0sbcAbort)
3097     {
3098         /* kill all the timers */
3099         scrUntimeout(t0SendByteSM, sc, t0sbcTGuardTime);
3100         scrUntimeout(t0SendByteSM, sc, t0sbcTClockData);
3101         scrUntimeout(t0SendByteSM, sc, t0sbcTError);
3102 
3103         scrSetDataHighZ();
3104         return;
3105     }
3106 
3107 
3108     switch (sc->t0SendByteS)
3109     {
3110         case t0sbsIdle:
3111             switch (cmd)
3112             {
3113                 case t0sbcStart:
3114                     /* set initial conditions */
3115                     sc->shiftBits   = 0;
3116                     sc->shiftParity = 0;
3117                     sc->shiftParityCount = 0;
3118                     sc->shiftByte = sc->dataByte;
3119 
3120                     scrClkAdj(sc->clkCountDataSend); /* send data clock running at 1 ETU  */
3121 
3122                     /* check if we have to wait for guard time */
3123                     if (0) /* possible optimization here */
3124                     {
3125                         /* can send start bit now */
3126                         scrTimeout(t0SendByteSM,sc,t0sbcTClockData,sc->clkCountDataSend);
3127                         scrSetData(false);
3128                         sc->t0SendByteS = t0sbsClockData;
3129                     }
3130                     else
3131                     {
3132                         /* need to wait for guard time */
3133                         scrTimeout(t0SendByteSM,sc,t0sbcTGuardTime,sc->clkCountDataSend * (12 + sc->N));
3134                         sc->t0SendByteS = t0sbsWaitGuardTime;
3135 
3136                     }
3137                     break;
3138 
3139                 default:
3140                     INVALID_STATE_CMD(sc, sc->t0SendByteS,cmd);
3141                     break;
3142             }
3143             break;
3144 
3145 
3146         case t0sbsWaitGuardTime:
3147             switch (cmd)
3148             {
3149                 case t0sbcTGuardTime:
3150                     TOGGLE_TEST_PIN();
3151                     /*  set start bit */
3152                     scrTimeout(t0SendByteSM,sc,t0sbcTClockData,sc->clkCountDataSend);
3153                     scrSetData(false);
3154                     sc->t0SendByteS = t0sbsClockData;
3155                     break;
3156 
3157                 default:
3158                     INVALID_STATE_CMD(sc, sc->t0SendByteS,cmd);
3159                     break;
3160             }
3161             break;
3162 
3163 
3164         case t0sbsClockData:
3165             switch (cmd)
3166             {
3167                 case t0sbcTClockData:
3168                     TOGGLE_TEST_PIN();
3169                     /* clock out data bit */
3170                     if (sc->shiftBits < 8)
3171                     {
3172                         if (sc->convention == CONVENTION_INVERSE)
3173                         {
3174                             if (sc->shiftByte & 0x80)
3175                             {
3176                                 scrSetData(false);
3177                                 sc->shiftParity++;
3178                             }
3179                             else
3180                             {
3181                                 scrSetData(true);
3182                             }
3183                             sc->shiftByte = sc->shiftByte << 1;
3184                         }
3185                         else
3186                         {
3187                             ASSERT(sc->convention == CONVENTION_DIRECT);
3188                             if (sc->shiftByte & 0x01)
3189                             {
3190                                 scrSetData(true);
3191                                 sc->shiftParity++;
3192                             }
3193                             else
3194                             {
3195                                 scrSetData(false);
3196                             }
3197                             sc->shiftByte = sc->shiftByte >> 1;
3198                         }
3199                         sc->shiftBits++;
3200                         scrTimeout(t0SendByteSM,sc,t0sbcTClockData,sc->clkCountDataSend);
3201                     }
3202 
3203                     /* clock out parity bit */
3204                     else if (sc->shiftBits == 8)
3205                     {
3206                         if ( ((sc->shiftParity & 0x01) &&  (sc->convention == CONVENTION_INVERSE))  ||
3207                              (!(sc->shiftParity & 0x01) && (sc->convention == CONVENTION_DIRECT))     )
3208                         {
3209                             scrSetData(false);
3210                         }
3211                         else
3212                         {
3213                             scrSetData(true);
3214                         }
3215                         sc->shiftBits++;
3216                         scrTimeout(t0SendByteSM,sc,t0sbcTClockData,sc->clkCountDataSend);
3217                     }
3218 
3219                     /* all data shifted out, move onto next state */
3220                     else
3221                     {
3222                         ASSERT(sc->shiftBits > 8);
3223                         scrSetData(true);
3224                         scrTimeout(t0SendByteSM,sc,t0sbcTError,sc->clkCountDataSend);
3225                         sc->t0SendByteS = t0sbsWaitError;
3226                     }
3227                     break;
3228 
3229                 default:
3230                     INVALID_STATE_CMD(sc, sc->t0SendByteS,cmd);
3231                     break;
3232             }
3233             break;
3234 
3235         case t0sbsWaitError:
3236             switch (cmd)
3237             {
3238                 case t0sbcTError:
3239                     /* no error indicated*/
3240                     if (scrGetData())
3241                     {
3242                         sc->t0SendByteS = t0sbsIdle;
3243                         sc->t0ByteParent(sc,gcT0SendByte);
3244                     }
3245 
3246                     /* got error */
3247                     else
3248                     {
3249                         /* got parity error */
3250                         if (sc->shiftParityCount < PARITY_ERROR_MAX)
3251                         {
3252                             sc->shiftParityCount++;
3253                             scrTimeout(t0SendByteSM,sc,t0sbcTResend,sc->clkCountDataSend * 2);
3254                             sc->t0SendByteS = t0sbsWaitResend;
3255                         }
3256                         else
3257                         {
3258                             /* too many parity errors, just give up on this sc->dataByte */
3259                             sc->status = ERROR_PARITY;
3260                             sc->t0SendByteS = t0sbsIdle;
3261                             sc->t0ByteParent(sc,gcT0SendByteErr);
3262                         }
3263                     }
3264                     break;
3265 
3266                 default:
3267                     INVALID_STATE_CMD(sc, sc->t0SendByteS,cmd);
3268                     break;
3269             }
3270             break;
3271 
3272         case t0sbsWaitResend:
3273             switch (cmd)
3274             {
3275                 case t0sbcTResend:
3276                     sc->shiftBits   = 0;
3277                     sc->shiftParity = 0;
3278                     sc->shiftByte = sc->dataByte;
3279                     /*  set start bit */
3280 
3281                     scrTimeout(t0SendByteSM,sc,t0sbcTClockData,sc->clkCountDataSend);
3282                     scrSetData(false);
3283                     sc->t0SendByteS = t0sbsClockData;
3284                     break;
3285 
3286                 default:
3287                     INVALID_STATE_CMD(sc, sc->t0SendByteS,cmd);
3288                     break;
3289             }
3290             break;
3291 
3292 
3293         default:
3294             INVALID_STATE_CMD(sc, sc->t0SendByteS,cmd);
3295             break;
3296     }
3297 }
3298 
3299 
3300 
3301 
3302 
3303 
3304 
3305 
3306 
3307 
3308 
3309 /*
3310 **++
3311 **  FUNCTIONAL DESCRIPTION:
3312 **
3313 **      cardOff
3314 **
3315 **      Turn all signals to the card off
3316 **
3317 **  FORMAL PARAMETERS:
3318 **
3319 **      sc      -  Pointer to the softc structure.
3320 **
3321 **  IMPLICIT INPUTS:
3322 **
3323 **      nill
3324 **
3325 **  IMPLICIT OUTPUTS:
3326 **
3327 **      nill
3328 **
3329 **  FUNCTION VALUE:
3330 **
3331 **      nill
3332 **
3333 **  SIDE EFFECTS:
3334 **
3335 **      nill
3336 **--
3337 */
3338 static void   cardOff  (struct scr_softc * sc)
3339 {
3340     scrSetReset(true);
3341     scrSetDataHighZ();
3342     scrSetClock(false);
3343     scrSetPower(false);
3344 }
3345 
3346 
3347 
3348 
3349 /*
3350 **
3351 **
3352 **    **************** timer routines ***************
3353 **
3354 */
3355 
3356 /*
3357 **++
3358 **  FUNCTIONAL DESCRIPTION:
3359 **
3360 **      scrClkInit
3361 **
3362 **      Init the callout queues.  The callout queues are used
3363 **      by the timeout/untimeout queues
3364 **
3365 **  FORMAL PARAMETERS:
3366 **
3367 **      nill
3368 **
3369 **  IMPLICIT INPUTS:
3370 **
3371 **      nill
3372 **
3373 **  IMPLICIT OUTPUTS:
3374 **
3375 **      nill
3376 **
3377 **  FUNCTION VALUE:
3378 **
3379 **      nill
3380 **
3381 **  SIDE EFFECTS:
3382 **
3383 **      nill
3384 **--
3385 */
3386 static void scrClkInit(void)
3387 {
3388 
3389     int lc;
3390     Callout *c;
3391     Callout *new;
3392 
3393     scrClkCallTodo.c_next = NULL;
3394     scrClkCallFree = &scrClkCalloutArray[0];
3395     c = scrClkCallFree;
3396 
3397     for (lc = 1; lc < SCR_CLK_CALLOUT_COUNT; lc++)
3398     {
3399         new = &scrClkCalloutArray[lc];
3400         c->c_next = new;
3401         c = new;
3402     }
3403 
3404     c->c_next = NULL;
3405 }
3406 
3407 
3408 /*
3409 **++
3410 **  FUNCTIONAL DESCRIPTION:
3411 **
3412 **      scrClkStart
3413 **
3414 **      This function starts the clock running.  The clock is reall the
3415 **      HAT clock (High Available Timer) that is using a FIQ (fast interrupt
3416 **      request).
3417 **
3418 **  FORMAL PARAMETERS:
3419 **
3420 **      sc              -  Pointer to the softc structure.
3421 **      countPerTick    -  value for T2 timer  that drives FIQ
3422 **
3423 **  IMPLICIT INPUTS:
3424 **
3425 **      nill
3426 **
3427 **  IMPLICIT OUTPUTS:
3428 **
3429 **      nill
3430 **
3431 **  FUNCTION VALUE:
3432 **
3433 **      nill
3434 **
3435 **  SIDE EFFECTS:
3436 **
3437 **      nill
3438 **--
3439 */
3440 static void scrClkStart(struct scr_softc * sc,int countPerTick)
3441 {
3442     u_int savedInts;
3443 
3444     savedInts = disable_interrupts(I32_bit | F32_bit);
3445 
3446 
3447 
3448     ASSERT(scrClkCallTodo.c_next == NULL);
3449     ASSERT(!scrClkEnable);
3450     scrClkEnable = 1;
3451     scrClkCount = countPerTick;
3452 
3453     hatClkOn(countPerTick,
3454              hatClkIrq,
3455              0xdeadbeef,
3456              hatStack + HATSTACKSIZE - sizeof(unsigned),
3457              myHatWedge);
3458 
3459     restore_interrupts(savedInts);
3460 }
3461 
3462 /*
3463 **++
3464 **  FUNCTIONAL DESCRIPTION:
3465 **
3466 **      scrClkAdj
3467 **
3468 **      Adjusts the frequence of the clock
3469 **
3470 **  FORMAL PARAMETERS:
3471 **
3472 **      count   -  new value for T2 timer that drives FIQ
3473 **
3474 **  IMPLICIT INPUTS:
3475 **
3476 **      nill
3477 **
3478 **  IMPLICIT OUTPUTS:
3479 **
3480 **      nill
3481 **
3482 **  FUNCTION VALUE:
3483 **
3484 **      nill
3485 **
3486 **  SIDE EFFECTS:
3487 **
3488 **      nill
3489 **--
3490 */
3491 static void scrClkAdj (int count)
3492 {
3493     u_int savedInts;
3494 
3495     if (count != scrClkCount)
3496     {
3497         savedInts = disable_interrupts(I32_bit | F32_bit);
3498 
3499         ASSERT(scrClkEnable);
3500 
3501         scrClkCount = count;
3502         hatClkAdjust(count);
3503 
3504         restore_interrupts(savedInts);
3505     }
3506 }
3507 
3508 /*
3509 **++
3510 **  FUNCTIONAL DESCRIPTION:
3511 **
3512 **      scrClkStop
3513 **
3514 **      Stops the clock
3515 **
3516 **  FORMAL PARAMETERS:
3517 **
3518 **      nill
3519 **
3520 **
3521 **  IMPLICIT INPUTS:
3522 **
3523 **      nill
3524 **
3525 **  IMPLICIT OUTPUTS:
3526 **
3527 **      nill
3528 **
3529 **  FUNCTION VALUE:
3530 **
3531 **      nill
3532 **
3533 **  SIDE EFFECTS:
3534 **
3535 **      nill
3536 **--
3537 */
3538 static void scrClkStop(void)
3539 {
3540     u_int savedInts;
3541     savedInts = disable_interrupts(I32_bit | F32_bit);
3542 
3543     ASSERT(scrClkEnable);
3544     scrClkEnable = 0;
3545     ASSERT(scrClkCallTodo.c_next == NULL);
3546     hatClkOff();
3547 
3548     restore_interrupts(savedInts);
3549 }
3550 
3551 
3552 
3553 /*
3554 **++
3555 **  FUNCTIONAL DESCRIPTION:
3556 **
3557 **      hatClkIrq
3558 **
3559 **      This is what the HAT clock calls.   This call drives
3560 **      the timeout queues, which in turn drive the state machines
3561 **
3562 **      Be very carefully when calling a timeout as the function
3563 **      that is called may in turn do timeout/untimeout calls
3564 **      before returning
3565 **
3566 **  FORMAL PARAMETERS:
3567 **
3568 **      int x       - not used
3569 **
3570 **  IMPLICIT INPUTS:
3571 **
3572 **      nill
3573 **
3574 **  IMPLICIT OUTPUTS:
3575 **
3576 **      nill
3577 **
3578 **  FUNCTION VALUE:
3579 **
3580 **      nill
3581 **
3582 **  SIDE EFFECTS:
3583 **
3584 **      a timeout may be called if it is due
3585 **--
3586 */
3587 static void hatClkIrq(int  x)
3588 {
3589     register Callout *p1;
3590     register int needsoft =0;
3591     register Callout *c;
3592     register int arg;
3593     register void (*func)(struct scr_softc*,int);
3594     struct scr_softc * sc;
3595 
3596     ASSERT(scrClkEnable);
3597     for (p1 = scrClkCallTodo.c_next; p1 != NULL; p1 = p1->c_next)
3598     {
3599         p1->c_time -= scrClkCount;
3600 
3601         if (p1->c_time > 0)
3602         {
3603             break;
3604         }
3605         needsoft = 1;
3606         if (p1->c_time == 0)
3607         {
3608             break;
3609         }
3610     }
3611 
3612 
3613     if (needsoft)
3614     {
3615         while ((c = scrClkCallTodo.c_next) != NULL && c->c_time <= 0)
3616         {
3617             func = c->c_func;
3618             sc = c->c_sc;
3619             arg = c->c_arg;
3620             scrClkCallTodo.c_next = c->c_next;
3621             c->c_next = scrClkCallFree;
3622             scrClkCallFree = c;
3623             (*func)(sc,arg);
3624         }
3625     }
3626 }
3627 
3628 /*
3629 **++
3630 **  FUNCTIONAL DESCRIPTION:
3631 **
3632 **      myHatWedge
3633 **
3634 **      Called if the HAT timer becomes clogged/wedged.  Not
3635 **      used by this driver, we let upper layers recover
3636 **      from this condition
3637 **
3638 **  FORMAL PARAMETERS:
3639 **
3640 **      int nFIQs - not used
3641 **
3642 **  IMPLICIT INPUTS:
3643 **
3644 **      nill
3645 **
3646 **  IMPLICIT OUTPUTS:
3647 **
3648 **      nill
3649 **
3650 **  FUNCTION VALUE:
3651 **
3652 **      nill
3653 **
3654 **  SIDE EFFECTS:
3655 **
3656 **      nill
3657 **--
3658 */
3659 static void myHatWedge(int nFIQs)
3660 {
3661     #ifdef DEBUG
3662         printf("myHatWedge: nFIQ = %d\n",nFIQs);
3663     #endif
3664 }
3665 
3666 
3667 
3668 /*
3669 **++
3670 **  FUNCTIONAL DESCRIPTION:
3671 **
3672 **      scrTimeout
3673 **
3674 **	    Execute a function after a specified length of time.
3675 **
3676 **
3677 **  FORMAL PARAMETERS:
3678 **
3679 **      ftn     -   function to execute
3680 **      sc      -   pointer to soft c
3681 **      arg     -   argument passed to function
3682 **      count   -   number of T2 counts for timeout
3683 **
3684 **  IMPLICIT INPUTS:
3685 **
3686 **      nill
3687 **
3688 **  IMPLICIT OUTPUTS:
3689 **
3690 **      nill
3691 **
3692 **  FUNCTION VALUE:
3693 **
3694 **      nill
3695 **
3696 **  SIDE EFFECTS:
3697 **
3698 **      nill
3699 **--
3700 */
3701 
3702 static void
3703 scrTimeout(
3704     void (*ftn)(struct scr_softc*,int),
3705     struct scr_softc* sc,
3706     int arg,
3707     int count)
3708 {
3709 
3710     register Callout *new, *p, *t;
3711     ASSERT(scrClkEnable);
3712 
3713 
3714     if (count <= 0)
3715     {
3716         count = 1;
3717     }
3718 
3719 
3720     /* Fill in the next free fcallout structure. */
3721     if (scrClkCallFree == NULL)
3722     {
3723         panic("timeout table full");
3724     }
3725 
3726     new = scrClkCallFree;
3727     scrClkCallFree = new->c_next;
3728     new->c_sc  = sc;
3729     new->c_arg = arg;
3730     new->c_func = ftn;
3731 
3732     /*
3733      * The time for each event is stored as a difference from the time
3734      * of the previous event on the queue.  Walk the queue, correcting
3735      * the counts argument for queue entries passed.  Correct the counts
3736      * value for the queue entry immediately after the insertion point
3737      * as well.  Watch out for negative c_time values; these represent
3738      * overdue events.
3739      */
3740     for (p = &scrClkCallTodo; (t = p->c_next) != NULL && count > t->c_time; p = t)
3741     {
3742         if (t->c_time > 0)
3743         {
3744             count -= t->c_time;
3745         }
3746     }
3747 
3748 
3749     new->c_time = count;
3750     if (t != NULL)
3751     {
3752         t->c_time -= count;
3753     }
3754 
3755     /* Insert the new entry into the queue. */
3756     p->c_next = new;
3757     new->c_next = t;
3758 }
3759 
3760 /*
3761 **++
3762 **  FUNCTIONAL DESCRIPTION:
3763 **
3764 **      scrUntimeout
3765 **
3766 **	    Cancel previous timeout function call.
3767 **
3768 **  FORMAL PARAMETERS:
3769 **
3770 **      ftn     - function of timeout to cancel
3771 **      sc      - sc  of timeout to cancel
3772 **      arg     - arg of timeout to cancel
3773 **
3774 **  IMPLICIT INPUTS:
3775 **
3776 **      nill
3777 **
3778 **  IMPLICIT OUTPUTS:
3779 **
3780 **      nill
3781 **
3782 **  FUNCTION VALUE:
3783 **
3784 **      nill
3785 **
3786 **  SIDE EFFECTS:
3787 **
3788 **      nill
3789 **--
3790 */
3791 static void
3792 scrUntimeout(
3793     void (*ftn)(struct scr_softc*, int),
3794     struct scr_softc* sc,
3795     int arg)
3796 {
3797     register Callout *p, *t;
3798     ASSERT(scrClkEnable);
3799 
3800     for (p = &scrClkCallTodo; (t = p->c_next) != NULL; p = t)
3801     {
3802         if (t->c_func == ftn && t->c_sc == sc && t->c_arg == arg)
3803         {
3804             /* Increment next entry's count. */
3805             if (t->c_next && t->c_time > 0)
3806             {
3807                 t->c_next->c_time += t->c_time;
3808             }
3809 
3810             /* Move entry from fcallout queue to scrClkCallFree queue. */
3811             p->c_next = t->c_next;
3812             t->c_next = scrClkCallFree;
3813             scrClkCallFree = t;
3814             break;
3815         }
3816     }
3817 }
3818 
3819 
3820 
3821 
3822 
3823 
3824 
3825 
3826 
3827 
3828 
3829 
3830 
3831 
3832 
3833 /******************* routines used only during debugging */
3834 #ifdef SCR_DEBUG
3835 
3836 /*
3837 **++
3838 **  FUNCTIONAL DESCRIPTION:
3839 **
3840 **      invalidStateCmd
3841 **
3842 **      Debugging function.  Printout information about problem
3843 **      and then kick in the debugger or panic
3844 **
3845 **  FORMAL PARAMETERS:
3846 **
3847 **      sc      - pointer to soft c
3848 **      state   - state of machine
3849 **      cmd     - command of machine
3850 **      line    - line that problem was detected
3851 **
3852 **
3853 **  IMPLICIT INPUTS:
3854 **
3855 **      nill
3856 **
3857 **  IMPLICIT OUTPUTS:
3858 **
3859 **      nill
3860 **
3861 **  FUNCTION VALUE:
3862 **
3863 **      nill
3864 **
3865 **  SIDE EFFECTS:
3866 **
3867 **      nill
3868 **--
3869 */
3870 void invalidStateCmd (struct scr_softc* sc,int state,int cmd,int line)
3871 {
3872     printf("INVALID_STATE_CMD: sc = %X, state = %X, cmd = %X, line = %d\n",sc,state,cmd,line);
3873     DEBUGGER;
3874 }
3875 
3876 /*
3877 **++
3878 **  FUNCTIONAL DESCRIPTION:
3879 **
3880 **      getText
3881 **
3882 **      Get text representation of state or command
3883 **
3884 **  FORMAL PARAMETERS:
3885 **
3886 **      x   - state or command
3887 **
3888 **  IMPLICIT INPUTS:
3889 **
3890 **      nill
3891 **
3892 **  IMPLICIT OUTPUTS:
3893 **
3894 **      nill
3895 **
3896 **  FUNCTION VALUE:
3897 **
3898 **      nill
3899 **
3900 **  SIDE EFFECTS:
3901 **
3902 **      nill
3903 **--
3904 */
3905 char * getText(int x)
3906 {
3907     switch (x)
3908     {
3909             /* commands to Master State Machine (mc = Master Command )*/
3910         case    mcOn:               return "mcOn";
3911         case    mcT0DataSend:       return "mcT0DataSend";
3912         case    mcT0DataRecv:       return "mcT0DataRecv";
3913         case    mcColdReset:        return "mcColdReset";
3914         case    mcATR:              return "mcATR";
3915         case    mcT0Send:           return "mcT0Send";
3916         case    mcT0Recv:           return "mcT0Recv";
3917 
3918             /* states in Master state machine (ms = Master State) */
3919         case    msIdleOff:          return "msIdleOff";
3920         case    msColdReset:        return "msColdReset";
3921         case    msATR:              return "msATR";
3922         case    msIdleOn:           return "msIdleOn";
3923         case    msT0Send:           return "msT0Send";
3924         case    msT0Recv:           return "msT0Recv";
3925 
3926 
3927 
3928             /* commands to T0 send state machine */
3929         case    t0scStart:          return "t0scStart";
3930         case    t0scTWorkWaiting:   return "t0scTWorkWaiting";
3931 
3932 
3933             /* states in T0 send state machine */
3934         case    t0ssIdle:           return "t0ssIdle";
3935         case    t0ssSendHeader:     return "t0ssSendHeader";
3936         case    t0ssRecvProcedure:  return "t0ssRecvProcedu";
3937         case    t0ssSendByte:       return "t0ssSendByte";
3938         case    t0ssSendData:       return "t0ssSendData";
3939         case    t0ssRecvSW1:        return "t0ssRecvSW1";
3940         case    t0ssRecvSW2:        return "t0ssRecvSW2";
3941 
3942 
3943             /* commands to T0 recv state machine */
3944         case t0rcStart:             return "t0rcStart";
3945         case t0rcTWorkWaiting:      return "t0rcTWorkWaiting";
3946 
3947             /* states in T0 recv state machine */
3948         case t0rsIdle:              return "t0rsIdle";
3949         case t0rsSendHeader:        return "t0rsSendHeader";
3950         case t0rsRecvProcedure:     return "t0rsRecvProcedure";
3951         case t0rsRecvByte:          return "t0rsRecvByte";
3952         case t0rsRecvData:          return "t0rsRecvData";
3953         case t0rsRecvSW1:           return "t0rsRecvSW1";
3954         case t0rsRecvSW2:           return "t0rsRecvSW2";
3955 
3956 
3957 
3958 
3959 
3960             /* commands to Answer To Reset (ATR) state machine */
3961         case    atrcStart:      return "atrcStart";
3962         case    atrcT3:         return "0x0b04";
3963         case    atrcTWorkWaiting: return "atrcTWorkWaiting";
3964 
3965 
3966             /* states in in Anser To Reset (ATR) state machine */
3967         case    atrsIdle:        return "atrsIdle";
3968         case    atrsTS:          return "atrsTS";
3969         case    atrsT0:          return "atrsT0";
3970         case    atrsTABCD:       return "atrsTABCD";
3971         case    atrsTK:          return "atrsTK";
3972         case    atrsTCK:         return "atrsTCK";
3973 
3974 
3975 
3976             /* commands to T0 Recv Byte state machine */
3977         case    t0rbcStart:         return "t0rbcStart";
3978         case    t0rbcAbort:         return "t0rbcAbort";
3979 
3980         case    t0rbcTFindStartEdge:return "t0rbcTFindStartEdge";
3981         case    t0rbcTFindStartMid: return "t0rbcTFindStartMid";
3982         case    t0rbcTClockData:    return "t0rbcTClockData";
3983         case    t0rbcTErrorStart:   return "t0rbcTErrorStart";
3984         case    t0rbcTErrorStop:    return "t0rbcTErrorStop";
3985 
3986             /* states in in TO Recv Byte state machine */
3987         case    t0rbsIdle:          return "t0rbsIdle";
3988         case    t0rbsFindStartEdge: return "t0rbcFindStartEdge";
3989         case    t0rbsFindStartMid:  return "t0rbcFindStartMid";
3990         case    t0rbsClockData:     return "t0rbcClockData";
3991         case    t0rbsSendError:     return "t0rbcSendError";
3992 
3993 
3994             /* commands to T0 Send Byte  state machine */
3995         case    t0sbcStart:         return "t0sbcStart";
3996         case    t0sbcAbort:         return "t0sbcAbort";
3997         case    t0sbcTGuardTime:    return "t0sbcTGuardTime";
3998         case    t0sbcTClockData:    return "t0sbcTClockData";
3999         case    t0sbcTError:        return "t0sbcTError";
4000         case    t0sbcTResend:       return "t0sbcTResend";
4001 
4002             /* states in in T0 Send Byte state machine */
4003         case    t0sbsIdle:          return "t0sbsIdle";
4004         case    t0sbsClockData:     return "t0sbsClockData";
4005         case    t0sbsWaitError:     return "t0sbsWaitError";
4006         case    t0sbsWaitResend:    return "t0sbsWaitResend";
4007         case    t0sbsWaitGuardTime: return "t0sbsWaitGuardTime";
4008 
4009 
4010         case    gcT0RecvByte:       return     "gcT0RecvByte";
4011         case gcT0RecvByteErr:       return "gcT0RecvByteErr";
4012         case gcT0SendByte:          return "gcT0SendByte";
4013         case gcT0SendByteErr:       return "gcT0SendByteErr";
4014 
4015 
4016         case crcStart:              return "crcStart";
4017         case crcT2:                 return "crcT2";
4018 
4019 
4020         default:
4021             printf("unknown case, %x\n",x);
4022             break;
4023     }
4024     return "???";
4025 }
4026 
4027 #endif /*  SCR_DEBUG */
4028