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