^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * A driver for the PCMCIA Smartcard Reader "Omnikey CardMan Mobile 4000"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * cm4000_cs.c support.linux@omnikey.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Tue Oct 23 11:32:43 GMT 2001 herp - cleaned up header files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Sun Jan 20 10:11:15 MET 2002 herp - added modversion header files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Thu Nov 14 16:34:11 GMT 2002 mh - added PPS functionality
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Tue Nov 19 16:36:27 GMT 2002 mh - added SUSPEND/RESUME functionailty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Wed Jul 28 12:55:01 CEST 2004 mh - kernel 2.6 adjustments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * current version: 2.4.0gm4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * (C) 2000,2001,2002,2003,2004 Omnikey AG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * (C) 2005-2006 Harald Welte <laforge@gnumonks.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * - Adhere to Kernel process/coding-style.rst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * - Port to 2.6.13 "new" style PCMCIA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * - Check for copy_{from,to}_user return values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * - Use nonseekable_open()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * - add class interface for udev device creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * All rights reserved. Licensed under dual BSD/GPL license.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/bitrev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <pcmcia/cistpl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <pcmcia/cisreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <pcmcia/ciscode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <pcmcia/ds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/cm4000_cs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* #define ATR_CSUM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define reader_to_dev(x) (&x->p_dev->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* n (debug level) is ignored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* additional debug output may be enabled by re-compiling with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * CM4000_DEBUG set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* #define CM4000_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define DEBUGP(n, rdr, x, args...) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) dev_dbg(reader_to_dev(rdr), "%s:" x, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) __func__ , ## args); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static DEFINE_MUTEX(cmm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define T_1SEC (HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define T_10MSEC msecs_to_jiffies(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define T_20MSEC msecs_to_jiffies(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define T_40MSEC msecs_to_jiffies(40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define T_50MSEC msecs_to_jiffies(50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define T_100MSEC msecs_to_jiffies(100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define T_500MSEC msecs_to_jiffies(500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static void cm4000_release(struct pcmcia_device *link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static int major; /* major number we get from the kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* note: the first state has to have number 0 always */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define M_FETCH_ATR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define M_TIMEOUT_WAIT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define M_READ_ATR_LEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define M_READ_ATR 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define M_ATR_PRESENT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define M_BAD_CARD 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define M_CARDOFF 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define LOCK_IO 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define LOCK_MONITOR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define IS_AUTOPPS_ACT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define IS_PROCBYTE_PRESENT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define IS_INVREV 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define IS_ANY_T0 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define IS_ANY_T1 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define IS_ATR_PRESENT 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define IS_ATR_VALID 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define IS_CMM_ABSENT 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define IS_BAD_LENGTH 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define IS_BAD_CSUM 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define IS_BAD_CARD 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define REG_FLAGS0(x) (x + 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define REG_FLAGS1(x) (x + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define REG_NUM_BYTES(x) (x + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define REG_BUF_ADDR(x) (x + 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define REG_BUF_DATA(x) (x + 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define REG_NUM_SEND(x) (x + 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define REG_BAUDRATE(x) (x + 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define REG_STOPBITS(x) (x + 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct cm4000_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct pcmcia_device *p_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned char atr[MAX_ATR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned char rbuf[512];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned char sbuf[512];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) wait_queue_head_t devq; /* when removing cardman must not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) zeroed! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) wait_queue_head_t ioq; /* if IO is locked, wait on this Q */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) wait_queue_head_t atrq; /* wait for ATR valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) wait_queue_head_t readq; /* used by write to wake blk.read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* warning: do not move this fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * initialising to zero depends on it - see ZERO_DEV below. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned char atr_csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned char atr_len_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned short atr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned short rlen; /* bytes avail. after write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned short rpos; /* latest read pos. write zeroes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned char procbyte; /* T=0 procedure byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned char mstate; /* state of card monitor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned char cwarn; /* slow down warning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned char flags0; /* cardman IO-flags 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unsigned char flags1; /* cardman IO-flags 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned int mdelay; /* variable monitor speeds, in jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned int baudv; /* baud value for speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned char ta1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned char proto; /* T=0, T=1, ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) unsigned long flags; /* lock+flags (MONITOR,IO,ATR) * for concurrent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) unsigned char pts[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct timer_list timer; /* used to keep monitor running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int monitor_running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define ZERO_DEV(dev) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) memset(&dev->atr_csum,0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) sizeof(struct cm4000_dev) - \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) offsetof(struct cm4000_dev, atr_csum))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static struct pcmcia_device *dev_table[CM4000_MAX_DEV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static struct class *cmm_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* This table doesn't use spaces after the comma between fields and thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * violates process/coding-style.rst. However, I don't really think wrapping it around will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * make it any clearer to read -HW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static unsigned char fi_di_table[10][14] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /*FI 00 01 02 03 04 05 06 07 08 09 10 11 12 13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /*DI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* 0 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* 1 */ {0x01,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x91,0x11,0x11,0x11,0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* 2 */ {0x02,0x12,0x22,0x32,0x11,0x11,0x11,0x11,0x11,0x92,0xA2,0xB2,0x11,0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* 3 */ {0x03,0x13,0x23,0x33,0x43,0x53,0x63,0x11,0x11,0x93,0xA3,0xB3,0xC3,0xD3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* 4 */ {0x04,0x14,0x24,0x34,0x44,0x54,0x64,0x11,0x11,0x94,0xA4,0xB4,0xC4,0xD4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* 5 */ {0x00,0x15,0x25,0x35,0x45,0x55,0x65,0x11,0x11,0x95,0xA5,0xB5,0xC5,0xD5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* 6 */ {0x06,0x16,0x26,0x36,0x46,0x56,0x66,0x11,0x11,0x96,0xA6,0xB6,0xC6,0xD6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* 7 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* 8 */ {0x08,0x11,0x28,0x38,0x48,0x58,0x68,0x11,0x11,0x98,0xA8,0xB8,0xC8,0xD8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #ifndef CM4000_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define xoutb outb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define xinb inb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static inline void xoutb(unsigned char val, unsigned short port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) outb(val, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static inline unsigned char xinb(unsigned short port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) val = inb(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) pr_debug("%.2x=inb(%.4x)\n", val, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static inline unsigned char invert_revert(unsigned char ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return bitrev8(~ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static void str_invert_revert(unsigned char *b, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) b[i] = invert_revert(b[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define ATRLENCK(dev,pos) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (pos>=dev->atr_len || pos>=MAX_ATR) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) goto return_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static unsigned int calc_baudv(unsigned char fidi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned int wcrcf, wbrcf, fi_rfu, di_rfu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) fi_rfu = 372;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) di_rfu = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* FI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) switch ((fidi >> 4) & 0x0F) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) wcrcf = 372;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case 0x01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) wcrcf = 372;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case 0x02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) wcrcf = 558;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case 0x03:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) wcrcf = 744;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case 0x04:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) wcrcf = 1116;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) case 0x05:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) wcrcf = 1488;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case 0x06:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) wcrcf = 1860;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) case 0x07:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) wcrcf = fi_rfu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case 0x08:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) wcrcf = fi_rfu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case 0x09:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) wcrcf = 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case 0x0A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) wcrcf = 768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case 0x0B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) wcrcf = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case 0x0C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) wcrcf = 1536;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case 0x0D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) wcrcf = 2048;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) wcrcf = fi_rfu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* DI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) switch (fidi & 0x0F) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) wbrcf = di_rfu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case 0x01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) wbrcf = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) case 0x02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) wbrcf = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case 0x03:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) wbrcf = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case 0x04:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) wbrcf = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case 0x05:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) wbrcf = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case 0x06:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) wbrcf = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case 0x07:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) wbrcf = di_rfu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case 0x08:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) wbrcf = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) case 0x09:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) wbrcf = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) wbrcf = di_rfu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return (wcrcf / wbrcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static unsigned short io_read_num_rec_bytes(unsigned int iobase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) unsigned short *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned short tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) tmp = *s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) *s = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) tmp = inb(REG_NUM_BYTES(iobase)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) (inb(REG_FLAGS0(iobase)) & 4 ? 0x100 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) } while (tmp != *s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static int parse_atr(struct cm4000_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) unsigned char any_t1, any_t0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) unsigned char ch, ifno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int ix, done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) DEBUGP(3, dev, "-> parse_atr: dev->atr_len = %i\n", dev->atr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (dev->atr_len < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) DEBUGP(5, dev, "parse_atr: atr_len < 3\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (dev->atr[0] == 0x3f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) set_bit(IS_INVREV, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) clear_bit(IS_INVREV, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ix = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ifno = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ch = dev->atr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) dev->proto = 0; /* XXX PROTO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) any_t1 = any_t0 = done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) dev->ta1 = 0x11; /* defaults to 9600 baud */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (ifno == 1 && (ch & 0x10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* read first interface byte and TA1 is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dev->ta1 = dev->atr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) DEBUGP(5, dev, "Card says FiDi is 0x%.2x\n", dev->ta1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ifno++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) } else if ((ifno == 2) && (ch & 0x10)) { /* TA(2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) dev->ta1 = 0x11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ifno++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) DEBUGP(5, dev, "Yi=%.2x\n", ch & 0xf0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ix += ((ch & 0x10) >> 4) /* no of int.face chars */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) +((ch & 0x20) >> 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) + ((ch & 0x40) >> 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) + ((ch & 0x80) >> 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* ATRLENCK(dev,ix); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (ch & 0x80) { /* TDi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ch = dev->atr[ix];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if ((ch & 0x0f)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) any_t1 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) DEBUGP(5, dev, "card is capable of T=1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) any_t0 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) DEBUGP(5, dev, "card is capable of T=0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) } while (!done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) DEBUGP(5, dev, "ix=%d noHist=%d any_t1=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ix, dev->atr[1] & 15, any_t1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (ix + 1 + (dev->atr[1] & 0x0f) + any_t1 != dev->atr_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) DEBUGP(5, dev, "length error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (any_t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) set_bit(IS_ANY_T0, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (any_t1) { /* compute csum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) dev->atr_csum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #ifdef ATR_CSUM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) for (i = 1; i < dev->atr_len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dev->atr_csum ^= dev->atr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (dev->atr_csum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) set_bit(IS_BAD_CSUM, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) DEBUGP(5, dev, "bad checksum\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) goto return_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (any_t0 == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) dev->proto = 1; /* XXX PROTO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) set_bit(IS_ANY_T1, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct card_fixup {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) char atr[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) u_int8_t atr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) u_int8_t stopbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static struct card_fixup card_fixups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) { /* ACOS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .atr = { 0x3b, 0xb3, 0x11, 0x00, 0x00, 0x41, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .atr_len = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .stopbits = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) { /* Motorola */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .atr = {0x3b, 0x76, 0x13, 0x00, 0x00, 0x80, 0x62, 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 0x41, 0x81, 0x81 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .atr_len = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .stopbits = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static void set_cardparameter(struct cm4000_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) unsigned int iobase = dev->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) u_int8_t stopbits = 0x02; /* ISO default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) DEBUGP(3, dev, "-> set_cardparameter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dev->flags1 = dev->flags1 | (((dev->baudv - 1) & 0x0100) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) xoutb(dev->flags1, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) DEBUGP(5, dev, "flags1 = 0x%02x\n", dev->flags1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* set baudrate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) xoutb((unsigned char)((dev->baudv - 1) & 0xFF), REG_BAUDRATE(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) DEBUGP(5, dev, "baudv = %i -> write 0x%02x\n", dev->baudv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ((dev->baudv - 1) & 0xFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* set stopbits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) for (i = 0; i < ARRAY_SIZE(card_fixups); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (!memcmp(dev->atr, card_fixups[i].atr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) card_fixups[i].atr_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) stopbits = card_fixups[i].stopbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) xoutb(stopbits, REG_STOPBITS(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) DEBUGP(3, dev, "<- set_cardparameter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) unsigned long tmp, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) unsigned short num_bytes_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) unsigned char pts_reply[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) unsigned int iobase = dev->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) DEBUGP(3, dev, "-> set_protocol\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) DEBUGP(5, dev, "ptsreq->Protocol = 0x%.8x, ptsreq->Flags=0x%.8x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) "ptsreq->pts1=0x%.2x, ptsreq->pts2=0x%.2x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) "ptsreq->pts3=0x%.2x\n", (unsigned int)ptsreq->protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) (unsigned int)ptsreq->flags, ptsreq->pts1, ptsreq->pts2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ptsreq->pts3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* Fill PTS structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) dev->pts[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) dev->pts[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) tmp = ptsreq->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) while ((tmp = (tmp >> 1)) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) dev->pts[1]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) dev->proto = dev->pts[1]; /* Set new protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) dev->pts[1] = (0x01 << 4) | (dev->pts[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* Correct Fi/Di according to CM4000 Fi/Di table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) DEBUGP(5, dev, "Ta(1) from ATR is 0x%.2x\n", dev->ta1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* set Fi/Di according to ATR TA(1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) dev->pts[2] = fi_di_table[dev->ta1 & 0x0F][(dev->ta1 >> 4) & 0x0F];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* Calculate PCK character */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) dev->pts[3] = dev->pts[0] ^ dev->pts[1] ^ dev->pts[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) DEBUGP(5, dev, "pts0=%.2x, pts1=%.2x, pts2=%.2x, pts3=%.2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) dev->pts[0], dev->pts[1], dev->pts[2], dev->pts[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /* check card convention */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (test_bit(IS_INVREV, &dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) str_invert_revert(dev->pts, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* reset SM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) xoutb(0x80, REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /* Enable access to the message buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) DEBUGP(5, dev, "Enable access to the messages buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) dev->flags1 = 0x20 /* T_Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) | (test_bit(IS_INVREV, &dev->flags) ? 0x02 : 0x00) /* inv parity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) | ((dev->baudv >> 8) & 0x01); /* MSB-baud */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) xoutb(dev->flags1, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) DEBUGP(5, dev, "Enable message buffer -> flags1 = 0x%.2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) dev->flags1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* write challenge to the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) DEBUGP(5, dev, "Write challenge to buffer: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) xoutb(i, REG_BUF_ADDR(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #ifdef CM4000_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) pr_debug("0x%.2x ", dev->pts[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) pr_debug("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* set number of bytes to write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) DEBUGP(5, dev, "Set number of bytes to write\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) xoutb(0x04, REG_NUM_SEND(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* Trigger CARDMAN CONTROLLER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) xoutb(0x50, REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* Monitor progress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* wait for xmit done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) DEBUGP(5, dev, "Waiting for NumRecBytes getting valid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) for (i = 0; i < 100; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (inb(REG_FLAGS0(iobase)) & 0x08) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) DEBUGP(5, dev, "NumRecBytes is valid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) usleep_range(10000, 11000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (i == 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) DEBUGP(5, dev, "Timeout waiting for NumRecBytes getting "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) "valid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) goto exit_setprotocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) DEBUGP(5, dev, "Reading NumRecBytes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) for (i = 0; i < 100; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) io_read_num_rec_bytes(iobase, &num_bytes_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (num_bytes_read >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (num_bytes_read > 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) goto exit_setprotocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) usleep_range(10000, 11000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* check whether it is a short PTS reply? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (num_bytes_read == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (i == 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) DEBUGP(5, dev, "Timeout reading num_bytes_read\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) goto exit_setprotocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) DEBUGP(5, dev, "Reset the CARDMAN CONTROLLER\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) xoutb(0x80, REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* Read PPS reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) DEBUGP(5, dev, "Read PPS reply\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) for (i = 0; i < num_bytes_read; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) xoutb(i, REG_BUF_ADDR(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) pts_reply[i] = inb(REG_BUF_DATA(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) #ifdef CM4000_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) DEBUGP(2, dev, "PTSreply: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) for (i = 0; i < num_bytes_read; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) pr_debug("0x%.2x ", pts_reply[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) pr_debug("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) #endif /* CM4000_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) DEBUGP(5, dev, "Clear Tactive in Flags1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) xoutb(0x20, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /* Compare ptsreq and ptsreply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if ((dev->pts[0] == pts_reply[0]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) (dev->pts[1] == pts_reply[1]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) (dev->pts[2] == pts_reply[2]) && (dev->pts[3] == pts_reply[3])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* setcardparameter according to PPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) dev->baudv = calc_baudv(dev->pts[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) set_cardparameter(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) } else if ((dev->pts[0] == pts_reply[0]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) ((dev->pts[1] & 0xef) == pts_reply[1]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ((pts_reply[0] ^ pts_reply[1]) == pts_reply[2])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* short PTS reply, set card parameter to default values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dev->baudv = calc_baudv(0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) set_cardparameter(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) exit_setprotocol:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) DEBUGP(3, dev, "<- set_protocol\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static int io_detect_cm4000(unsigned int iobase, struct cm4000_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* note: statemachine is assumed to be reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (inb(REG_FLAGS0(iobase)) & 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) clear_bit(IS_ATR_VALID, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) set_bit(IS_CMM_ABSENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return 0; /* detect CMM = 1 -> failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* xoutb(0x40, REG_FLAGS1(iobase)); detectCMM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) xoutb(dev->flags1 | 0x40, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if ((inb(REG_FLAGS0(iobase)) & 8) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) clear_bit(IS_ATR_VALID, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) set_bit(IS_CMM_ABSENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return 0; /* detect CMM=0 -> failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /* clear detectCMM again by restoring original flags1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) xoutb(dev->flags1, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static void terminate_monitor(struct cm4000_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /* tell the monitor to stop and wait until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * it terminates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) DEBUGP(3, dev, "-> terminate_monitor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) wait_event_interruptible(dev->devq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) test_and_set_bit(LOCK_MONITOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) (void *)&dev->flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* now, LOCK_MONITOR has been set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * allow a last cycle in the monitor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * the monitor will indicate that it has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * finished by clearing this bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) DEBUGP(5, dev, "Now allow last cycle of monitor!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) while (test_bit(LOCK_MONITOR, (void *)&dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) msleep(25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) DEBUGP(5, dev, "Delete timer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) del_timer_sync(&dev->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) #ifdef CM4000_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) dev->monitor_running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) DEBUGP(3, dev, "<- terminate_monitor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * monitor the card every 50msec. as a side-effect, retrieve the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * atr once a card is inserted. another side-effect of retrieving the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * atr is that the card will be powered on, so there is no need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * power on the card explicitly from the application: the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * is already doing that for you.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static void monitor_card(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct cm4000_dev *dev = from_timer(dev, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) unsigned int iobase = dev->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) unsigned short s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct ptsreq ptsreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int i, atrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) DEBUGP(7, dev, "-> monitor_card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* if someone has set the lock for us: we're done! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (test_and_set_bit(LOCK_MONITOR, &dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) DEBUGP(4, dev, "About to stop monitor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /* no */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) dev->rlen =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) dev->rpos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) dev->mstate = M_FETCH_ATR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) clear_bit(LOCK_MONITOR, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /* close et al. are sleeping on devq, so wake it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) wake_up_interruptible(&dev->devq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) DEBUGP(2, dev, "<- monitor_card (we are done now)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* try to lock io: if it is already locked, just add another timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (test_and_set_bit(LOCK_IO, (void *)&dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) DEBUGP(4, dev, "Couldn't get IO lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) goto return_with_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /* is a card/a reader inserted at all ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) dev->flags0 = xinb(REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) DEBUGP(7, dev, "dev->flags0 = 0x%2x\n", dev->flags0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) DEBUGP(7, dev, "smartcard present: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) dev->flags0 & 1 ? "yes" : "no");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) DEBUGP(7, dev, "cardman present: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) dev->flags0 == 0xff ? "no" : "yes");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if ((dev->flags0 & 1) == 0 /* no smartcard inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) || dev->flags0 == 0xff) { /* no cardman inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) /* no */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dev->rlen =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) dev->rpos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dev->mstate = M_FETCH_ATR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dev->flags &= 0x000000ff; /* only keep IO and MONITOR locks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (dev->flags0 == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) DEBUGP(4, dev, "set IS_CMM_ABSENT bit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) set_bit(IS_CMM_ABSENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) } else if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) DEBUGP(4, dev, "clear IS_CMM_ABSENT bit "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) "(card is removed)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) clear_bit(IS_CMM_ABSENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) goto release_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) } else if ((dev->flags0 & 1) && test_bit(IS_CMM_ABSENT, &dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* cardman and card present but cardman was absent before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * (after suspend with inserted card) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) DEBUGP(4, dev, "clear IS_CMM_ABSENT bit (card is inserted)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) clear_bit(IS_CMM_ABSENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (test_bit(IS_ATR_VALID, &dev->flags) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) DEBUGP(7, dev, "believe ATR is already valid (do nothing)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) goto release_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) switch (dev->mstate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) case M_CARDOFF: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) unsigned char flags0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) DEBUGP(4, dev, "M_CARDOFF\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) flags0 = inb(REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (flags0 & 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /* wait until Flags0 indicate power is off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) dev->mdelay = T_10MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* Flags0 indicate power off and no card inserted now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * Reset CARDMAN CONTROLLER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) xoutb(0x80, REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* prepare for fetching ATR again: after card off ATR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * is read again automatically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) dev->rlen =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) dev->rpos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) dev->atr_csum =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) dev->atr_len_retry = dev->cwarn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) dev->mstate = M_FETCH_ATR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) /* minimal gap between CARDOFF and read ATR is 50msec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) dev->mdelay = T_50MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case M_FETCH_ATR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) DEBUGP(4, dev, "M_FETCH_ATR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) xoutb(0x80, REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) DEBUGP(4, dev, "Reset BAUDV to 9600\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) dev->baudv = 0x173; /* 9600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) xoutb(0x02, REG_STOPBITS(iobase)); /* stopbits=2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) xoutb(0x73, REG_BAUDRATE(iobase)); /* baud value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) xoutb(0x21, REG_FLAGS1(iobase)); /* T_Active=1, baud
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /* warm start vs. power on: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) xoutb(dev->flags0 & 2 ? 0x46 : 0x44, REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) dev->mdelay = T_40MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) dev->mstate = M_TIMEOUT_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) case M_TIMEOUT_WAIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) DEBUGP(4, dev, "M_TIMEOUT_WAIT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* numRecBytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) io_read_num_rec_bytes(iobase, &dev->atr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) dev->mdelay = T_10MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) dev->mstate = M_READ_ATR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) case M_READ_ATR_LEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) DEBUGP(4, dev, "M_READ_ATR_LEN\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /* infinite loop possible, since there is no timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) #define MAX_ATR_LEN_RETRY 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (dev->atr_len == io_read_num_rec_bytes(iobase, &s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (dev->atr_len_retry++ >= MAX_ATR_LEN_RETRY) { /* + XX msec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) dev->mdelay = T_10MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) dev->mstate = M_READ_ATR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) dev->atr_len = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) dev->atr_len_retry = 0; /* set new timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) DEBUGP(4, dev, "Current ATR_LEN = %i\n", dev->atr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) case M_READ_ATR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) DEBUGP(4, dev, "M_READ_ATR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) for (i = 0; i < dev->atr_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) xoutb(i, REG_BUF_ADDR(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) dev->atr[i] = inb(REG_BUF_DATA(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* Deactivate T_Active flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) DEBUGP(4, dev, "Deactivate T_Active flags\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) dev->flags1 = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) xoutb(dev->flags1, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* atr is present (which doesn't mean it's valid) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) set_bit(IS_ATR_PRESENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (dev->atr[0] == 0x03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) str_invert_revert(dev->atr, dev->atr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) atrc = parse_atr(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (atrc == 0) { /* atr invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) dev->mdelay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) dev->mstate = M_BAD_CARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) dev->mdelay = T_50MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) dev->mstate = M_ATR_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) set_bit(IS_ATR_VALID, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (test_bit(IS_ATR_VALID, &dev->flags) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) DEBUGP(4, dev, "monitor_card: ATR valid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* if ta1 == 0x11, no PPS necessary (default values) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) /* do not do PPS with multi protocol cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if ((test_bit(IS_AUTOPPS_ACT, &dev->flags) == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) (dev->ta1 != 0x11) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) !(test_bit(IS_ANY_T0, &dev->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) test_bit(IS_ANY_T1, &dev->flags))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) DEBUGP(4, dev, "Perform AUTOPPS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) set_bit(IS_AUTOPPS_ACT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) ptsreq.protocol = (0x01 << dev->proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) ptsreq.flags = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) ptsreq.pts1 = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ptsreq.pts2 = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) ptsreq.pts3 = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (set_protocol(dev, &ptsreq) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) DEBUGP(4, dev, "AUTOPPS ret SUCC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) clear_bit(IS_AUTOPPS_ACT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) wake_up_interruptible(&dev->atrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) DEBUGP(4, dev, "AUTOPPS failed: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) "repower using defaults\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /* prepare for repowering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) clear_bit(IS_ATR_PRESENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) clear_bit(IS_ATR_VALID, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) dev->rlen =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) dev->rpos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) dev->atr_csum =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) dev->atr_len_retry = dev->cwarn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) dev->mstate = M_FETCH_ATR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) dev->mdelay = T_50MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /* for cards which use slightly different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * params (extra guard time) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) set_cardparameter(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (test_bit(IS_AUTOPPS_ACT, &dev->flags) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) DEBUGP(4, dev, "AUTOPPS already active "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) "2nd try:use default values\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (dev->ta1 == 0x11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) DEBUGP(4, dev, "No AUTOPPS necessary "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) "TA(1)==0x11\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (test_bit(IS_ANY_T0, &dev->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) && test_bit(IS_ANY_T1, &dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) DEBUGP(4, dev, "Do NOT perform AUTOPPS "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) "with multiprotocol cards\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) clear_bit(IS_AUTOPPS_ACT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) wake_up_interruptible(&dev->atrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) DEBUGP(4, dev, "ATR invalid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) wake_up_interruptible(&dev->atrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) case M_BAD_CARD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) DEBUGP(4, dev, "M_BAD_CARD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* slow down warning, but prompt immediately after insertion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (dev->cwarn == 0 || dev->cwarn == 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) set_bit(IS_BAD_CARD, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) dev_warn(&dev->p_dev->dev, MODULE_NAME ": ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (test_bit(IS_BAD_CSUM, &dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) "be zero) failed\n", dev->atr_csum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) #ifdef CM4000_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) DEBUGP(4, dev, "ATR length error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) DEBUGP(4, dev, "card damaged or wrong way "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) "inserted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) dev->cwarn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) wake_up_interruptible(&dev->atrq); /* wake open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) dev->cwarn++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) dev->mdelay = T_100MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) dev->mstate = M_FETCH_ATR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) DEBUGP(7, dev, "Unknown action\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) break; /* nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) release_io:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) DEBUGP(7, dev, "release_io\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) clear_bit(LOCK_IO, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) wake_up_interruptible(&dev->ioq); /* whoever needs IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return_with_timer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) DEBUGP(7, dev, "<- monitor_card (returns with timer)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) mod_timer(&dev->timer, jiffies + dev->mdelay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) clear_bit(LOCK_MONITOR, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /* Interface to userland (file_operations) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct cm4000_dev *dev = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) unsigned int iobase = dev->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int i, j, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) DEBUGP(2, dev, "-> cmm_read(%s,%d)\n", current->comm, current->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (count == 0) /* according to manpage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (!pcmcia_dev_present(dev->p_dev) || /* device removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) test_bit(IS_CMM_ABSENT, &dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (test_bit(IS_BAD_CSUM, &dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /* also see the note about this in cmm_write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (wait_event_interruptible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) (dev->atrq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ((filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (test_bit(IS_ATR_VALID, &dev->flags) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /* this one implements blocking IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (wait_event_interruptible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) (dev->readq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ((filp->f_flags & O_NONBLOCK) || (dev->rpos < dev->rlen)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) /* lock io */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (wait_event_interruptible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) (dev->ioq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) ((filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) dev->flags0 = inb(REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if ((dev->flags0 & 1) == 0 /* no smartcard inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) || dev->flags0 == 0xff) { /* no cardman inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) clear_bit(IS_ATR_VALID, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (dev->flags0 & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) set_bit(IS_CMM_ABSENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) goto release_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) DEBUGP(4, dev, "begin read answer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) j = min(count, (size_t)(dev->rlen - dev->rpos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) k = dev->rpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (k + j > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) j = 256 - k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) DEBUGP(4, dev, "read1 j=%d\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) for (i = 0; i < j; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) xoutb(k++, REG_BUF_ADDR(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) dev->rbuf[i] = xinb(REG_BUF_DATA(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) j = min(count, (size_t)(dev->rlen - dev->rpos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (k + j > 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) DEBUGP(4, dev, "read2 j=%d\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) dev->flags1 |= 0x10; /* MSB buf addr set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) xoutb(dev->flags1, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) for (; i < j; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) xoutb(k++, REG_BUF_ADDR(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) dev->rbuf[i] = xinb(REG_BUF_DATA(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (dev->proto == 0 && count > dev->rlen - dev->rpos && i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) DEBUGP(4, dev, "T=0 and count > buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) dev->rbuf[i] = dev->rbuf[i - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) dev->rbuf[i - 1] = dev->procbyte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) count = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) dev->rpos = dev->rlen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /* Clear T1Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) DEBUGP(4, dev, "Clear T1Active\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) dev->flags1 &= 0xdf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) xoutb(dev->flags1, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* last check before exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (!io_detect_cm4000(iobase, dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) goto release_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (test_bit(IS_INVREV, &dev->flags) && count > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) str_invert_revert(dev->rbuf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (copy_to_user(buf, dev->rbuf, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) release_io:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) clear_bit(LOCK_IO, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) wake_up_interruptible(&dev->ioq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) DEBUGP(2, dev, "<- cmm_read returns: rc = %zi\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) (rc < 0 ? rc : count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return rc < 0 ? rc : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static ssize_t cmm_write(struct file *filp, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) struct cm4000_dev *dev = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) unsigned int iobase = dev->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) unsigned short s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) unsigned char tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) unsigned char infolen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) unsigned char sendT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) unsigned short nsend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) unsigned short nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) DEBUGP(2, dev, "-> cmm_write(%s,%d)\n", current->comm, current->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (count == 0) /* according to manpage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (dev->proto == 0 && count < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) /* T0 must have at least 4 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) DEBUGP(4, dev, "T0 short write\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) nr = count & 0x1ff; /* max bytes to write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (!pcmcia_dev_present(dev->p_dev) || /* device removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) test_bit(IS_CMM_ABSENT, &dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (test_bit(IS_BAD_CSUM, &dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) DEBUGP(4, dev, "bad csum\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * wait for atr to become valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * note: it is important to lock this code. if we dont, the monitor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * could be run between test_bit and the call to sleep on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * atr-queue. if *then* the monitor detects atr valid, it will wake up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * any process on the atr-queue, *but* since we have been interrupted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * we do not yet sleep on this queue. this would result in a missed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * wake_up and the calling process would sleep forever (until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * interrupted). also, do *not* restore_flags before sleep_on, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * this could result in the same situation!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (wait_event_interruptible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) (dev->atrq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) ((filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (test_bit(IS_ATR_VALID, &dev->flags) == 0) { /* invalid atr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) DEBUGP(4, dev, "invalid ATR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) /* lock io */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (wait_event_interruptible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) (dev->ioq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) ((filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (copy_from_user(dev->sbuf, buf, ((count > 512) ? 512 : count)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) dev->flags0 = inb(REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if ((dev->flags0 & 1) == 0 /* no smartcard inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) || dev->flags0 == 0xff) { /* no cardman inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) clear_bit(IS_ATR_VALID, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (dev->flags0 & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) set_bit(IS_CMM_ABSENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) DEBUGP(4, dev, "IO error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) goto release_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (!io_detect_cm4000(iobase, dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) goto release_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) /* reflect T=0 send/read mode in flags1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) dev->flags1 |= (sendT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) set_cardparameter(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /* dummy read, reset flag procedure received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) tmp = inb(REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) dev->flags1 = 0x20 /* T_Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) | (sendT0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) | (test_bit(IS_INVREV, &dev->flags) ? 2 : 0)/* inverse parity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) | (((dev->baudv - 1) & 0x0100) >> 8); /* MSB-Baud */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) DEBUGP(1, dev, "set dev->flags1 = 0x%.2x\n", dev->flags1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) xoutb(dev->flags1, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /* xmit data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) DEBUGP(4, dev, "Xmit data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) for (i = 0; i < nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (i >= 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) dev->flags1 = 0x20 /* T_Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) | (sendT0) /* SendT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /* inverse parity: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) | (test_bit(IS_INVREV, &dev->flags) ? 2 : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) | (((dev->baudv - 1) & 0x0100) >> 8) /* MSB-Baud */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) | 0x10; /* set address high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) DEBUGP(4, dev, "dev->flags = 0x%.2x - set address "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) "high\n", dev->flags1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) xoutb(dev->flags1, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (test_bit(IS_INVREV, &dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) DEBUGP(4, dev, "Apply inverse convention for 0x%.2x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) "-> 0x%.2x\n", (unsigned char)dev->sbuf[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) invert_revert(dev->sbuf[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) xoutb(i, REG_BUF_ADDR(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) xoutb(invert_revert(dev->sbuf[i]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) REG_BUF_DATA(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) xoutb(i, REG_BUF_ADDR(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) xoutb(dev->sbuf[i], REG_BUF_DATA(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) DEBUGP(4, dev, "Xmit done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (dev->proto == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* T=0 proto: 0 byte reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (nr == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) DEBUGP(4, dev, "T=0 assumes 0 byte reply\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) xoutb(i, REG_BUF_ADDR(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (test_bit(IS_INVREV, &dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) xoutb(0xff, REG_BUF_DATA(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) xoutb(0x00, REG_BUF_DATA(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) /* numSendBytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (sendT0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) nsend = nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (nr == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) nsend = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) nsend = 5 + (unsigned char)dev->sbuf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (dev->sbuf[4] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) nsend += 0x100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) nsend = nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /* T0: output procedure byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (test_bit(IS_INVREV, &dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) DEBUGP(4, dev, "T=0 set Procedure byte (inverse-reverse) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) "0x%.2x\n", invert_revert(dev->sbuf[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) xoutb(invert_revert(dev->sbuf[1]), REG_NUM_BYTES(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) DEBUGP(4, dev, "T=0 set Procedure byte 0x%.2x\n", dev->sbuf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) xoutb(dev->sbuf[1], REG_NUM_BYTES(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) DEBUGP(1, dev, "set NumSendBytes = 0x%.2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) (unsigned char)(nsend & 0xff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) xoutb((unsigned char)(nsend & 0xff), REG_NUM_SEND(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) DEBUGP(1, dev, "Trigger CARDMAN CONTROLLER (0x%.2x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 0x40 /* SM_Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) | (dev->flags0 & 2 ? 0 : 4) /* power on if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) |(dev->proto ? 0x10 : 0x08) /* T=1/T=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) |(nsend & 0x100) >> 8 /* MSB numSendBytes */ );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) xoutb(0x40 /* SM_Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) | (dev->flags0 & 2 ? 0 : 4) /* power on if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) |(dev->proto ? 0x10 : 0x08) /* T=1/T=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) |(nsend & 0x100) >> 8, /* MSB numSendBytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) /* wait for xmit done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if (dev->proto == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) DEBUGP(4, dev, "Wait for xmit done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) for (i = 0; i < 1000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (inb(REG_FLAGS0(iobase)) & 0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) msleep_interruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (i == 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) DEBUGP(4, dev, "timeout waiting for xmit done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) goto release_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) /* T=1: wait for infoLen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) infolen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (dev->proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) /* wait until infoLen is valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) for (i = 0; i < 6000; i++) { /* max waiting time of 1 min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) io_read_num_rec_bytes(iobase, &s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (s >= 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) infolen = inb(REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) DEBUGP(4, dev, "infolen=%d\n", infolen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) msleep_interruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (i == 6000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) DEBUGP(4, dev, "timeout waiting for infoLen\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) goto release_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) clear_bit(IS_PROCBYTE_PRESENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) /* numRecBytes | bit9 of numRecytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) io_read_num_rec_bytes(iobase, &dev->rlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) for (i = 0; i < 600; i++) { /* max waiting time of 2 sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (dev->proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) if (dev->rlen >= infolen + 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) msleep_interruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) /* numRecBytes | bit9 of numRecytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) io_read_num_rec_bytes(iobase, &s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (s > dev->rlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) DEBUGP(1, dev, "NumRecBytes inc (reset timeout)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) i = 0; /* reset timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) dev->rlen = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) /* T=0: we are done when numRecBytes doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * increment any more and NoProcedureByte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * is set and numRecBytes == bytes sent + 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) * (header bytes + data + 1 for sw2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * except when the card replies an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) * which means, no data will be sent back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) else if (dev->proto == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if ((inb(REG_BUF_ADDR(iobase)) & 0x80)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) /* no procedure byte received since last read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) DEBUGP(1, dev, "NoProcedure byte set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /* i=0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) /* procedure byte received since last read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) DEBUGP(1, dev, "NoProcedure byte unset "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) "(reset timeout)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) dev->procbyte = inb(REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) DEBUGP(1, dev, "Read procedure byte 0x%.2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) dev->procbyte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) i = 0; /* resettimeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (inb(REG_FLAGS0(iobase)) & 0x08) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) DEBUGP(1, dev, "T0Done flag (read reply)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) if (dev->proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) infolen = inb(REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (i == 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) DEBUGP(1, dev, "timeout waiting for numRecBytes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) goto release_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (dev->proto == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) DEBUGP(1, dev, "Wait for T0Done bit to be set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) for (i = 0; i < 1000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (inb(REG_FLAGS0(iobase)) & 0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) msleep_interruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) if (i == 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) DEBUGP(1, dev, "timeout waiting for T0Done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) goto release_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) dev->procbyte = inb(REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) DEBUGP(4, dev, "Read procedure byte 0x%.2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) dev->procbyte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) io_read_num_rec_bytes(iobase, &dev->rlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) DEBUGP(4, dev, "Read NumRecBytes = %i\n", dev->rlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) /* T=1: read offset=zero, T=0: read offset=after challenge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) dev->rpos = dev->proto ? 0 : nr == 4 ? 5 : nr > dev->rlen ? 5 : nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) DEBUGP(4, dev, "dev->rlen = %i, dev->rpos = %i, nr = %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) dev->rlen, dev->rpos, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) release_io:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) DEBUGP(4, dev, "Reset SM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) DEBUGP(4, dev, "Write failed but clear T_Active\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) dev->flags1 &= 0xdf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) xoutb(dev->flags1, REG_FLAGS1(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) clear_bit(LOCK_IO, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) wake_up_interruptible(&dev->ioq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) wake_up_interruptible(&dev->readq); /* tell read we have data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) /* ITSEC E2: clear write buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) memset((char *)dev->sbuf, 0, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) /* return error or actually written bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) DEBUGP(2, dev, "<- cmm_write\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) return rc < 0 ? rc : nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) static void start_monitor(struct cm4000_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) DEBUGP(3, dev, "-> start_monitor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (!dev->monitor_running) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) DEBUGP(5, dev, "create, init and add timer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) timer_setup(&dev->timer, monitor_card, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) dev->monitor_running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) mod_timer(&dev->timer, jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) DEBUGP(5, dev, "monitor already running\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) DEBUGP(3, dev, "<- start_monitor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) static void stop_monitor(struct cm4000_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) DEBUGP(3, dev, "-> stop_monitor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (dev->monitor_running) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) DEBUGP(5, dev, "stopping monitor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) terminate_monitor(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) /* reset monitor SM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) clear_bit(IS_ATR_VALID, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) clear_bit(IS_ATR_PRESENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) DEBUGP(5, dev, "monitor already stopped\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) DEBUGP(3, dev, "<- stop_monitor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct cm4000_dev *dev = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) unsigned int iobase = dev->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) struct pcmcia_device *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) #ifdef CM4000_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) char *ioctl_names[CM_IOC_MAXNR + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) [_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) [_IOC_NR(CM_IOCGATR)] "CM_IOCGATR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) [_IOC_NR(CM_IOCARDOFF)] "CM_IOCARDOFF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) [_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) [_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) iminor(inode), ioctl_names[_IOC_NR(cmd)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) mutex_lock(&cmm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) link = dev_table[iminor(inode)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (!pcmcia_dev_present(link)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) DEBUGP(4, dev, "DEV_OK false\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) DEBUGP(4, dev, "CMM_ABSENT flag set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) DEBUGP(4, dev, "ioctype mismatch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (_IOC_NR(cmd) > CM_IOC_MAXNR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) DEBUGP(4, dev, "iocnr mismatch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) case CM_IOCGSTATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) DEBUGP(4, dev, " ... in CM_IOCGSTATUS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) /* clear other bits, but leave inserted & powered as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * they are */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) status = dev->flags0 & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if (test_bit(IS_ATR_PRESENT, &dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) status |= CM_ATR_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (test_bit(IS_ATR_VALID, &dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) status |= CM_ATR_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (test_bit(IS_CMM_ABSENT, &dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) status |= CM_NO_READER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) if (test_bit(IS_BAD_CARD, &dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) status |= CM_BAD_CARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (copy_to_user(argp, &status, sizeof(int)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) case CM_IOCGATR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) DEBUGP(4, dev, "... in CM_IOCGATR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) struct atreq __user *atreq = argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) /* allow nonblocking io and being interrupted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (wait_event_interruptible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) (dev->atrq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) ((filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) != 0)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (test_bit(IS_ATR_VALID, &dev->flags) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) tmp = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (copy_to_user(&(atreq->atr_len), &tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) sizeof(int)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (copy_to_user(atreq->atr, dev->atr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) dev->atr_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) tmp = dev->atr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) case CM_IOCARDOFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) #ifdef CM4000_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) DEBUGP(4, dev, "... in CM_IOCARDOFF\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (dev->flags0 & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) DEBUGP(4, dev, " Card inserted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) DEBUGP(2, dev, " No card inserted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) if (dev->flags0 & 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) DEBUGP(4, dev, " Card powered\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) DEBUGP(2, dev, " Card not powered\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) /* is a card inserted and powered? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if ((dev->flags0 & 0x01) && (dev->flags0 & 0x02)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) /* get IO lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) if (wait_event_interruptible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) (dev->ioq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) ((filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) || (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) == 0)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) if (filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) /* Set Flags0 = 0x42 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) DEBUGP(4, dev, "Set Flags0=0x42 \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) xoutb(0x42, REG_FLAGS0(iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) clear_bit(IS_ATR_PRESENT, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) clear_bit(IS_ATR_VALID, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) dev->mstate = M_CARDOFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) clear_bit(LOCK_IO, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (wait_event_interruptible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) (dev->atrq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) ((filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) || (test_bit(IS_ATR_VALID, (void *)&dev->flags) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 0)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) if (filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) /* release lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) clear_bit(LOCK_IO, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) wake_up_interruptible(&dev->ioq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) case CM_IOCSPTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) struct ptsreq krnptsreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (copy_from_user(&krnptsreq, argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) sizeof(struct ptsreq))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) DEBUGP(4, dev, "... in CM_IOCSPTS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /* wait for ATR to get valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) if (wait_event_interruptible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) (dev->atrq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) ((filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) != 0)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) if (filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) /* get IO lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (wait_event_interruptible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) (dev->ioq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) ((filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) || (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) == 0)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (filp->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if ((rc = set_protocol(dev, &krnptsreq)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) /* auto power_on again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) dev->mstate = M_FETCH_ATR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) clear_bit(IS_ATR_VALID, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) /* release lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) clear_bit(LOCK_IO, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) wake_up_interruptible(&dev->ioq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) #ifdef CM4000_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) case CM_IOSDBGLVL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) rc = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) DEBUGP(4, dev, "... in default (unknown IOCTL code)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) rc = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) mutex_unlock(&cmm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) static int cmm_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) struct cm4000_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) struct pcmcia_device *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) int minor = iminor(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (minor >= CM4000_MAX_DEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) mutex_lock(&cmm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) link = dev_table[minor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) if (link == NULL || !pcmcia_dev_present(link)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (link->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) dev = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) filp->private_data = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) DEBUGP(2, dev, "-> cmm_open(device=%d.%d process=%s,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) imajor(inode), minor, current->comm, current->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) /* init device variables, they may be "polluted" after close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) * or, the device may never have been closed (i.e. open failed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) ZERO_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) /* opening will always block since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) * monitor will be started by open, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) * means we have to wait for ATR becoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) * valid = block until valid (or card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) * inserted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) if (filp->f_flags & O_NONBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) dev->mdelay = T_50MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) /* start monitoring the cardstatus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) start_monitor(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) link->open = 1; /* only one open per device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) DEBUGP(2, dev, "<- cmm_open\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) ret = stream_open(inode, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) mutex_unlock(&cmm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) static int cmm_close(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) struct cm4000_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) struct pcmcia_device *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) int minor = iminor(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) if (minor >= CM4000_MAX_DEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) link = dev_table[minor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if (link == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) dev = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) DEBUGP(2, dev, "-> cmm_close(maj/min=%d.%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) imajor(inode), minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) stop_monitor(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) ZERO_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) link->open = 0; /* only one open per device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) wake_up(&dev->devq); /* socket removed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) DEBUGP(2, dev, "cmm_close\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) static void cmm_cm4000_release(struct pcmcia_device * link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) struct cm4000_dev *dev = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) /* dont terminate the monitor, rather rely on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) * close doing that for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) DEBUGP(3, dev, "-> cmm_cm4000_release\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) while (link->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) printk(KERN_INFO MODULE_NAME ": delaying release until "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) "process has terminated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) /* note: don't interrupt us:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) * close the applications which own
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) * the devices _first_ !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) wait_event(dev->devq, (link->open == 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) /* dev->devq=NULL; this cannot be zeroed earlier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) DEBUGP(3, dev, "<- cmm_cm4000_release\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) /*==== Interface to PCMCIA Layer =======================================*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) static int cm4000_config_check(struct pcmcia_device *p_dev, void *priv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) return pcmcia_request_io(p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) static int cm4000_config(struct pcmcia_device * link, int devno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) link->config_flags |= CONF_AUTO_SET_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) /* read the config-tuples */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) if (pcmcia_loop_config(link, cm4000_config_check, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) goto cs_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) if (pcmcia_enable_device(link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) goto cs_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) cs_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) cm4000_release(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) static int cm4000_suspend(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) struct cm4000_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) dev = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) stop_monitor(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) static int cm4000_resume(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) struct cm4000_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) dev = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) if (link->open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) start_monitor(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) static void cm4000_release(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) cmm_cm4000_release(link); /* delay release until device closed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) pcmcia_disable_device(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) static int cm4000_probe(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) struct cm4000_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) for (i = 0; i < CM4000_MAX_DEV; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) if (dev_table[i] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if (i == CM4000_MAX_DEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) printk(KERN_NOTICE MODULE_NAME ": all devices in use\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) /* create a new cm4000_cs device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) if (dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) dev->p_dev = link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) link->priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) dev_table[i] = link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) init_waitqueue_head(&dev->devq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) init_waitqueue_head(&dev->ioq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) init_waitqueue_head(&dev->atrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) init_waitqueue_head(&dev->readq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) ret = cm4000_config(link, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) dev_table[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) device_create(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) static void cm4000_detach(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) struct cm4000_dev *dev = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) int devno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) /* find device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) for (devno = 0; devno < CM4000_MAX_DEV; devno++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) if (dev_table[devno] == link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if (devno == CM4000_MAX_DEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) stop_monitor(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) cm4000_release(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) dev_table[devno] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) device_destroy(cmm_class, MKDEV(major, devno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) static const struct file_operations cm4000_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) .read = cmm_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) .write = cmm_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) .unlocked_ioctl = cmm_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) .open = cmm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) .release= cmm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) .llseek = no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) static const struct pcmcia_device_id cm4000_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0002),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) PCMCIA_DEVICE_PROD_ID12("CardMan", "4000", 0x2FB368CA, 0xA2BD8C39),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) PCMCIA_DEVICE_NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) MODULE_DEVICE_TABLE(pcmcia, cm4000_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) static struct pcmcia_driver cm4000_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) .name = "cm4000_cs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) .probe = cm4000_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) .remove = cm4000_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) .suspend = cm4000_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) .resume = cm4000_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) .id_table = cm4000_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) static int __init cmm_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) cmm_class = class_create(THIS_MODULE, "cardman_4000");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if (IS_ERR(cmm_class))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) return PTR_ERR(cmm_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) major = register_chrdev(0, DEVICE_NAME, &cm4000_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) if (major < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) printk(KERN_WARNING MODULE_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) ": could not get major number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) class_destroy(cmm_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) return major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) rc = pcmcia_register_driver(&cm4000_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) unregister_chrdev(major, DEVICE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) class_destroy(cmm_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) static void __exit cmm_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) pcmcia_unregister_driver(&cm4000_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) unregister_chrdev(major, DEVICE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) class_destroy(cmm_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) module_init(cmm_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) module_exit(cmm_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) MODULE_LICENSE("Dual BSD/GPL");