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