/* * Copyright (c) 2002 Bruce M. Simpson * All rights reserved. * * Based in part on the work of Wolf Geldmacher and Alain Macaire. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bruce M. Simpson. * 4. Neither the name of Bruce M. Simpson nor the names of co- * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bruce M. Simpson OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * gprsc.h */ #ifndef _DEV_SCARD_GPRSC_H_ #define _DEV_SCARD_GPRSC_H_ #include #ifdef _KERNEL #define GPRPRINTF(sc, fmt, args...) \ device_printf((sc)->sc_dev, fmt "\n", ##args) #define GPRPUTS(sc, msg) \ device_printf((sc)->sc_dev, msg "\n") #if defined(GPRSC_DEBUG) #define GPRDPRINTF(sc, fmt, args...) \ device_printf((sc)->sc_dev, "%s(%d) " fmt "\n", \ __FUNCTION__ , __LINE__ , ##args) #define GPRDPUTS(sc, msg) \ device_printf((sc)->sc_dev, msg "\n") #else #define GPRDPRINTF(sc, fmt, args...) #define GPRDPUTS(sc, msg) #endif /* All register and memory accesses are 8 bits wide. */ #define GPR_AM_RID 3 /* attribute memory RID */ #define GPR_MEM_SIZE 0x1000 /* attribute memory aperture size */ /* common memory map locations */ #define GPR_MEM_CIS 0x0000 /* card information services */ /* attribute memory map locations */ #define GPR_MEM_REG 0x0FA0 /* base of register file */ /* register file locations */ #define GPR_REG_CF (GPR_MEM_REG+0) /* configuration options */ #define GPR_REG_ST (GPR_MEM_REG+24) /* general setup */ #define GPR_REG_SC1 (GPR_MEM_REG+26) /* smart card register 1 */ #define GPR_REG_SC2 (GPR_MEM_REG+28) /* smart card register 2 */ #define GPR_REG_CLK (GPR_MEM_REG+30) /* clock/control register */ /* CF register bits */ #define GPR_CF_INIT 0x80 /* latch to high for 5usec to init card */ #define GPR_CF_CFG0 0x10 /* set io window to 0x200-0x21F */ #define GPR_CF_CFG1 0x11 /* set io window to 0x220-0x23F */ #define GPR_CF_CFG2 0x12 /* set io window to 0x240-0x25F */ #define GPR_CF_CFG3 0x18 /* set io window to 0x300-0x31F */ #define GPR_CF_CFG4 0x19 /* set io window to 0x320-0x33F */ #define GPR_CF_CFG5 0x1A /* set io window to 0x340-0x35F */ /* ST register bits */ #define GPR_ST_MEM_LK 0x08 /* Lock attribute memory and I/O buffer */ /* SC1 register bits */ #define GPR_SC1_PRESENT 0x80 /* 1 if smart card present */ #define GPR_SC1_EJECTED 0x08 /* 1 if smart card was ejected */ /* Convenience macros for accessing the inserted/ejected bits of GPR_SC1 */ #define GPR_SMARTCARD_PRESENT(sc) \ (((u_int8_t)bus_space_read_1((sc)->sc_mem_tag, (sc)->sc_mem_bsh, \ GPR_REG_SC1)) & GPR_SC1_PRESENT) #define GPR_SMARTCARD_EJECTED(sc) \ (((u_int8_t)bus_space_read_1((sc)->sc_mem_tag, (sc)->sc_mem_bsh, \ GPR_REG_SC1)) & GPR_SC1_EJECTED) /* * The 32-byte I/O buffer is mapped into io port space as specified by * the contents of the CF register detailed above. There are two control * registers at the base of this buffer. The remaining 30 bytes are used * when communicating with the card using the TLV protocol. * These two registers are used for communicating with the Pseudo-Random * number Generator (PRG) and for handshaking. * Setting GPR_PRGCTL_RESET to 1 for 5usec and waiting 20ms will * reset the reader and power it up. */ #define GPR_IO_SIZE 32 /* 32-byte aperture */ /* Offsets to PRG registers within I/O port address space */ #define GPR_IO_PRGCTL 0x00 /* handshaking and PRG control */ #define GPR_IO_PRGDAT 0x01 /* PRG data */ #define GPR_IO_TLVBASE 0x02 /* Base of the TLV buffer */ #define GPR_IO_TLV_TAG (GPR_IO_TLVBASE) /* tag */ #define GPR_IO_TLV_LEN (GPR_IO_TLVBASE+0x01) /* length */ #define GPR_IO_TLV_VAL_BASE (GPR_IO_TLVBASE+0x02) /* value buffer */ /* Bits for PRGCTL register */ #define GPR_PRGCTL_RESET 0x01 /* master reset */ #define GPR_PRGCTL_START 0x02 /* execute command */ #define GPR_PRGCTL_IRQACK 0x04 /* acknowledge interrupt */ /* Acknowledge a card interrupt */ #define GPR_CLEAR_INTR(sc) \ do { \ u_int8_t __prgctl = (u_int8_t) bus_space_read_1( \ (sc)->sc_io_tag, (sc)->sc_io_bsh, GPR_IO_PRGCTL); \ __prgctl &= ~(GPR_PRGCTL_IRQACK); \ bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_bsh, \ GPR_IO_PRGCTL, __prgctl); \ } while (0) /* Initiate execution of a command in the TLV buffer */ #define GPR_START_CMD(sc) \ bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_bsh, \ GPR_IO_PRGCTL, GPR_PRGCTL_START) /* Poll the GPR_PRGCTL_START bit for command completion */ #define GPR_POLL_CMD(sc) \ (((u_int8_t) bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_bsh, \ GPR_IO_PRGCTL)) & GPR_PRGCTL_START) /* * Reset the device. You must wait GPR_RESET_WAIT_DELAY ms after this * operation using some other timer mechanism (spinning would be unacceptable). */ #define GPR_RESET_HOLD_DELAY 6 /* 6 us delay to reset the reader */ #define GPR_RESET_TIMO (20*hz/1000) /* reset timeout */ #define GPR_CMD_TIMO (6*hz) /* command timeout */ #define GPR_RESET(sc) \ do { \ bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_bsh, \ GPR_IO_PRGCTL, GPR_PRGCTL_RESET); \ DELAY(GPR_RESET_HOLD_DELAY); \ bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_bsh, \ GPR_IO_PRGCTL, 0); \ } while (0) /* * TLV command tags. * * The GPR 400 accepts commands using the TLV (Tag, Length, Value) protocol. * These are written to the I/O buffer at GPR_IO_TLVBASE onwards. If a * command would exceed GPR_TLV_MAXLEN bytes in length, then each command * tag up to the final tag should be OR'd with GPR_TLV_CONT to indicate * a continuation. The maximum length of any command chained in this way * is 256 bytes. * When data is received from the device, each tag will be OR'd with the * mask GPR_TLV_RECV. */ #define GPR_TLV_MAX_CHUNK_LEN 28 #define GPR_TLV_MAX_CMD_LEN 256 #define GPR_TAG_CLOSE 0x10 /* Close Session tag */ #define GPR_TAG_OPEN 0x20 /* Open Session tag */ #define GPR_TAG_APDU 0x30 /* APDU exchange tag */ #define GPR_TAG_POWER 0x40 /* Power Down tag */ #define GPR_TAG_SELECT 0x50 /* Select Card tag */ #define GPR_TAG_STATUS 0xA0 /* Get Reader Status tag */ #define GPR_TLV_RECV 0x02 /* received data */ #define GPR_TLV_CONT 0x04 /* continuation */ /* bits for the GPR_TAG_SELECT command, which takes a single byte */ #define GPR_SELECT_ISO_7816_3 0x02 /* select the ISO7816-3 driver */ /* return codes found in the status byte */ #define GPR_STATUS_OK 0x00 /* Command execution OK */ #define GPR_STATUS_SW1_ERR 0xE7 /* SW1/SW2 not equal to 0x90 0x00 */ #define GPR_STATUS_LEN_ERR 0x12 /* Invalid command length */ #define GPR_STATUS_CARD_REMOVED 0xFB /* Card removed */ /* XXX: macros could have side-effects */ #define GPR_WRITE_TLV_TAG(sc, tag) \ bus_space_write_1(sc->sc_io_tag, sc->sc_io_bsh, GPR_IO_TLV_TAG, (tag)) #define GPR_WRITE_TLV_LEN(sc, len) \ bus_space_write_1(sc->sc_io_tag, sc->sc_io_bsh, GPR_IO_TLV_LEN, (len)) #define GPR_WRITE_TLV_VAL(sc, off, val) \ bus_space_write_1(sc->sc_io_tag, sc->sc_io_bsh, \ GPR_IO_TLV_VAL_BASE+(off), (val)) #define GPR_READ_TLV_TAG(sc) \ bus_space_read_1(sc->sc_io_tag, sc->sc_io_bsh, GPR_IO_TLV_TAG) #define GPR_READ_TLV_LEN(sc) \ bus_space_read_1(sc->sc_io_tag, sc->sc_io_bsh, GPR_IO_TLV_LEN) #define GPR_READ_TLV_VAL(sc, off) \ bus_space_read_1(sc->sc_io_tag, sc->sc_io_bsh, \ GPR_IO_TLV_VAL_BASE+(off)) #define GPR_READ_TLV_STATUS(sc) \ bus_space_read_1(sc->sc_io_tag, sc->sc_io_bsh, \ GPR_IO_TLV_VAL_BASE+2) #define GPR400_CMD_DIR_TOCARD 0 #define GPR400_CMD_DIR_FROMCARD 1 #define GPR400_MIN_CMD_SIZE 6 #endif /* _KERNEL */ /* * Structure used to fetch reader status information */ struct gpr400_status { unsigned char status; /* reader status */ unsigned char os_version; /* reader os version */ unsigned char flash_mem; /* flash memory present */ unsigned char manufacturer; /* Card manufacturer byte */ unsigned char rom_sum; /* ROM checksum */ unsigned char ram_sum; /* RAM checksum */ unsigned char flash_sum; /* Flash checksum */ unsigned char reg1; /* Smartcard register 1 */ unsigned char reg2; /* Smartcard register 2 */ unsigned char info; /* Clock & Control register */ unsigned char card_inserted; /* boolean for card inserted */ }; struct gpr400_cmd { unsigned char dir; /* 00 to card, 01 from card */ unsigned char cla; /* CLA byte */ unsigned char ins; /* INS byte */ unsigned char p1; /* P1 byte */ unsigned char p2; /* P2 byte */ unsigned char len; /* LEN byte */ unsigned char data[256]; /* data buffer */ unsigned char status; /* reader status */ unsigned char sw1; /* SW1 status byte */ unsigned char sw2; /* SW2 status byte */ }; struct gpr400_atr { unsigned char status; /* status of card reader */ unsigned char len; /* length of ATR */ unsigned char data[62]; /* buffer for ATR */ }; struct gpr400_ram { unsigned char ram[2016]; /* RAM area */ }; struct gpr400_tlv { /* GPR400 TLV command */ unsigned char tag; unsigned short length; unsigned char value[300]; }; /* * ioctl's for the GPR400 smart card reader */ #define GPR400_RESET _IO('g', 0x01) /* reset the reader */ #define GPR400_PWROFF _IO('g', 0x02) /* power down the reader */ #define GPR400_STNDBY _IO('g', 0x03) /* reader to standby mode */ #define GPR400_OPEN _IOR('g', 0x04, struct gpr400_atr) #define GPR400_CLOSE _IO('g', 0x05) /* close session */ #define GPR400_SELECT _IO('g', 0x06) /* select card protocol */ #define GPR400_STATUS _IOR('g', 0x07, struct gpr400_status) #define GPR400_RAM _IOR('g', 0x08, struct gpr400_ram) #define GPR400_CMD _IOWR('g', 0x09, struct gpr400_cmd) #define GPR400_TLV _IOWR('g', 0x0a, struct gpr400_tlv) #endif /* _DEV_SCARD_GPRSC_H_ */