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