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