/* * Gemplus GPR400/GemPC400 PCMCIA smartcard reader driver. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * * CONTRIBUTORS: * 2000.12.01 Alain Macaire, Gemplus Research * Support for TLV commands * 2002.07.05 Chad Blomquist & Vlad Korolev * Portability fixes for iPaq ARM support * 2004.06.12 Henryk Plötz * Ported to kernel 2.6 * * (C) 2005-2006 Stefan Schmidt * 2005-11-24: * - Remove deprecated functions. * - Now compiles with 2.6.14 * - Check return values for copy_{to,from}_user * * 2005-11-25: * - Change license to only GPL. * */ #define GPR400_CARD_INSERTED(x) ((*((char *)(x) + 0xfba) & 0x80) == 0x80) #define GPR400_RST 0x01 #define GPR400_START 0x02 #define GPR400_IRQACK 0x04 /* * Commands to the GPR400 are TLV (Tag, Length, Value) coded and placed into * the I/O buffer starting at byte 2. If the length of a command exceeds 28 * bytes (32 - 2 - 2) the command is sent in pieces of maximum 28 bytes with * a handshake performed after each chunk. The tag of such a command is * OR'ed with 0x04 (except for the last chunk). The maximum length of data * that can be transmitted to or read from the GPR400 is 256 bytes. When * data is received from the GPR400 the data is tagged with the same tag * as the command sent to get the data with bit 2 set. */ #define GPR400_CLSE 0x10 /* Close session tag */ #define GPR400_OPN 0x20 /* Open session tag */ #define GPR400_APDU 0x30 /* APDU exchange tag */ #define GPR400_POWER 0x40 /* Power down/Standby */ #define GPR400_SLCT 0x50 /* Select card tag */ #define GPR400_STS 0xA0 /* Get reader status */ #define GPR400_RECV 0x02 /* Received data */ #define GPR400_CONT 0x04 /* Chain block */ #define PCMCIA_DEBUG 1 #define GPR_MAJOR 123 /* Experimental! */ #define GPR_BUFSZ 256 /* typical buffer size */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define FS_RELEASE_T int #include "gpr400_cs.h" /* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If you do not define PCMCIA_DEBUG at all, all the debug code will be left out. If you compile with PCMCIA_DEBUG=0, the debug code will be present but disabled -- but it can then be enabled for specific modules at load time with a 'pc_debug=#' option to insmod. */ #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = "Development version. Stefan Schmidt"; #else #define DEBUG(n, args...) #endif /*====================================================================*/ /* Parameters that can be set with 'insmod' */ /* Release IO ports after configuration? */ static int free_ports = 0; // Bit map of interrupts to choose from (default=0xdeb8) INT_MODULE_PARM(irq_mask, 0xdeb8); static int irq_list[4] = { -1 }; MODULE_PARM(irq_list, "1-4i"); MODULE_PARM(free_ports, "i"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Driver for the GemPC400 Smartcard reader"); MODULE_AUTHOR("Joseph L. Phillips "); /*====================================================================*/ /* The event() function is this driver's Card Services event handler. It will be called by Card Services when an appropriate card status event is received. The config() and release() entry points are used to configure or release a socket, in response to card insertion and ejection events. They are invoked from the gpr400 event handler. */ static void gpr400_config(dev_link_t *link); static void gpr400_release(u_long arg); static int gpr400_event(event_t event, int priority, event_callback_args_t *args); /* The attach() and detach() entry points are used to create and destroy "instances" of the driver, where each instance represents everything needed to manage one actual PCMCIA card. */ static dev_link_t *gpr400_attach(void); static void gpr400_detach(dev_link_t *); /* * Prototypes of card access functions */ static irqreturn_t gpr400_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int gpr400_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg); static int gpr400_open(struct inode *inode, struct file *file); static FS_RELEASE_T gpr400_close(struct inode *inode, struct file *file); static struct file_operations gpr400_chr_fops = { open: gpr400_open, ioctl: gpr400_ioctl, release: gpr400_close, owner: THIS_MODULE }; /* The dev_info variable is the "key" that is used to match up this device driver with appropriate cards, through the card configuration database. */ static dev_info_t dev_info = "gpr400_cs"; /* A linked list of "instances" of the gpr400 device. Each actual PCMCIA card corresponds to one device instance, and is described by one dev_link_t structure (defined in ds.h). You may not want to use a linked list for this -- for example, the memory card driver uses an array of dev_link_t pointers, where minor device numbers are used to derive the corresponding array index. */ static dev_link_t *dev_list = NULL; /* A dev_link_t structure has fields for most things that are needed to keep track of a socket, but there will usually be some device specific information that also needs to be kept track of. The 'priv' pointer in a dev_link_t structure can be used to point to a device-specific private data structure, like this. To simplify the data structure handling, we actually include the dev_link_t structure in the device's private data structure. A driver needs to provide a dev_node_t structure for each device on a card. In some cases, there is only one device per card (for example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept in a linked list starting at the 'dev' field of a dev_link_t structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. In this case, we also provide a flag to indicate if a device is "stopped" due to a power management event, or card ejection. The device IO routines can use a flag like this to throttle IO to a card that is not ready to accept it. The bus_operations pointer is used on platforms for which we need to use special socket-specific versions of normal IO primitives (inb, outb, readb, writeb, etc) for card IO. typedef struct local_info_t { dev_link_t link; dev_node_t node; int stop; struct bus_operations *bus; } local_info_t; */ /* * Private data for GPR400 reader. Need to provide a dev_node_t * structure for the device. * FIX: Possibly needs to be extended to support PRG encryption and/or * downloading of additional drivers to the GPR400. */ typedef struct gpr400_local_t { dev_link_t link; dev_node_t node; int stop; caddr_t am_base; /* Base of mapped attribute memory */ u_long io_base; /* Base of I/O port range */ int irq; /* irq assigned to this card reader */ struct timer_list release_timer; } gpr400_local_t; /* * cardReaderError -- decode card reader error message */ static char * cardReaderError(int v) { char *msg = "unknown reader status"; switch (v) { case 0x00: msg = "command executed sucessfully"; break; case 0x04: msg = "reader command not recognized"; break; case 0x05: msg = "smart card driver unknown"; break; case 0x10: msg = "card reset response error"; break; case 0x12: msg = "invalid (L)ength parameter"; break; case 0x14: msg = "card type unknown"; break; case 0x15: msg = "card turned off"; break; case 0x16: msg = "unsupportet V parameter"; break; case 0x19: msg = "no flash memory present"; break; case 0x1a: msg = "error in ISO command format"; break; case 0x1b: msg = "incorrect number of parameters"; break; case 0x1d: msg = "TCK byte in ATR incorrect"; break; case 0x1e: msg = "memory access is incorrect"; break; case 0x1f: msg = "cannot write flash memory"; break; case 0x20: msg = "bad TLV command type "; break; case 0xA0: msg = "smart card malfunction (TA1)"; break; case 0xA2: msg = "smart card malfunction"; break; case 0xA3: msg = "parity error"; break; case 0xE4: msg = "invalid procedure byte recvd"; break; case 0xE5: msg = "command with no data"; break; case 0xE7: msg = "SW1/SW2 not equal to 90 00"; break; case 0xF7: msg = "card removed during command"; break; case 0xF8: msg = "card in short circuit"; break; case 0xFB: msg = "card removed"; break; } return msg; } /*====================================================================== gpr400_attach() creates an "instance" of the driver, allocating local data structures for one device. The device is registered with Card Services. The dev_link structure is initialized, but we don't actually configure the card at this point -- we wait until we receive a card insertion event. ======================================================================*/ static dev_link_t *gpr400_attach(void) { gpr400_local_t *local; dev_link_t *link; client_reg_t client_reg; int ret, i; DEBUG(0, "gpr400_attach()\n"); /* Allocate space for private device-specific data */ local = kmalloc(sizeof(gpr400_local_t), GFP_KERNEL); if (!local) return NULL; memset(local, 0, sizeof(gpr400_local_t)); link = &local->link; link->priv = local; /* Initialize the release timer */ init_timer(&local->release_timer); local->release_timer.function = &gpr400_release; local->release_timer.data = (u_long)link; /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; if (irq_list[0] == -1) link->irq.IRQInfo2 = irq_mask; else for (i = 0; i < 4; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost everything. In most clients, many details (i.e., number, sizes, and attributes of IO windows) are fixed by the nature of the device, and can be hard-wired here. */ link->conf.Vcc = 50; link->conf.Vpp1 = link->conf.Vpp2 = 50; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; /* Register with Card Services */ link->next = dev_list; dev_list = link; client_reg.dev_info = &dev_info; client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; client_reg.event_handler = &gpr400_event; client_reg.Version = 0x0210; client_reg.event_callback_args.client_data = link; ret = pcmcia_register_client(&link->handle, &client_reg); if (ret != CS_SUCCESS) { cs_error(link->handle, RegisterClient, ret); gpr400_detach(link); return NULL; } return link; } /* gpr400_attach */ /*====================================================================== This deletes a driver "instance". The device is de-registered with Card Services. If it has been released, all local data structures are freed. Otherwise, the structures will be freed when the device is released. ======================================================================*/ static void gpr400_detach(dev_link_t *link) { dev_link_t **linkp; DEBUG(0, "gpr400_detach(0x%p)\n", link); /* Locate device structure */ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) if (*linkp == link) break; if (*linkp == NULL) return; /* If the device is currently configured and active, we won't actually delete it yet. Instead, it is marked so that when the release() function is called, that will trigger a proper detach(). */ if (link->state & DEV_CONFIG) { #ifdef PCMCIA_DEBUG printk(KERN_DEBUG "gpr400_cs: detach postponed, '%s' " "still locked\n", link->dev->dev_name); #endif link->state |= DEV_STALE_LINK; return; } /* Break the link with Card Services */ if (link->handle) pcmcia_deregister_client(link->handle); /* Unlink device structure, and free it */ *linkp = link->next; /* This points to the parent gpr400_local_t struct */ kfree(link->priv); } /* gpr400_detach */ /*====================================================================== gpr400_config() is scheduled to run after a CARD_INSERTION event is received, to configure the PCMCIA socket, and to make the device available to the system. ======================================================================*/ #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) #define CFG_CHECK(fn, ret) \ if(ret != 0) goto next_entry static void gpr400_config(dev_link_t *link) { client_handle_t handle = link->handle; gpr400_local_t *dev = link->priv; tuple_t tuple; cisparse_t parse; int last_fn, last_ret; u_char buf[64]; config_info_t conf; win_req_t req; memreq_t map; int manfid = 0, prodid = 0; DEBUG(0, "gpr400_config(0x%p)\n", link); /* This reads the card's CONFIG tuple to find its configuration registers. */ tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; DEBUG(0, "Got gpr400_cs CIS data\n" ); DEBUG(0,"Base:%x Version: %s SubTuples: %d \n" , (int)parse.config.base, parse.vers_2.str, (u_int) parse.config.subtuples ); DEBUG(0,"Version: %d %d \n" , (int)parse.version_1.major, (int)parse.version_1.minor ); DEBUG(0,"Version: %s \n" , parse.version_1.str ); DEBUG(0,"Manf ID: M: %x C: %x\n", (u_int)parse.manfid.manf, (u_int)parse.manfid.card ); printk (KERN_INFO "IRQ Stuff: %x %x\n", conf.IntType, conf.AssignedIRQ ); /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); link->conf.Vcc = conf.Vcc; DEBUG(0,"Config Attr: %x \n", conf.Attributes ); DEBUG(0,"Got Config Says: Vcc: %d Vpp %d Vpp2 %d \n", conf.Vcc, conf.Vpp1, conf.Vpp2 ); DEBUG(0,"IType: %x Pres %x IRQ %x IRQAttr %x \n", conf.IntType, conf.Present, conf.AssignedIRQ, conf.IRQAttributes ); tuple.DesiredTuple = CISTPL_MANFID; tuple.Attributes = TUPLE_RETURN_COMMON; if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) { manfid = le16_to_cpu(buf[0]); prodid = le16_to_cpu(buf[1]); } DEBUG(0,"Manufacturer Info: manfid=%x prodid=%x \n", manfid, prodid ); /* In this loop, we scan the CIS for configuration table entries, each of which describes a valid card configuration, including voltage, IO window, memory window, and interrupt settings. We make no assumptions about the card to be configured: we use just the information available in the CIS. In an ideal world, this would work for any PCMCIA card, but it requires a complete and accurate CIS. In practice, a driver usually "knows" most of these things without consulting the CIS, and most client drivers will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while ( last_ret == CS_SUCCESS ) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_io_t *io = &(parse.cftable_entry.io); DEBUG( 0, "Requesting Entry" ); CFG_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); CFG_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); DEBUG(0, "Card Says: Index: %d IRQ: %x - %x \n", (int)cfg->index, (int)cfg->irq.IRQInfo1, (int)cfg->irq.IRQInfo2 ); if (cfg->index == 0 || cfg->io.nwin == 0 ) goto next_entry; link->conf.ConfigIndex = cfg->index; /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ if (cfg->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000) goto next_entry; } if (cfg->vpp1.present & (1<conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; DEBUG( 0, "IO Win: %d [%x %x %x] \n", io->nwin, io->win[0].len, io->win[0].base, 0xA0A0 ); /* IO window settings */ link->io.NumPorts1 = link->io.NumPorts2 = 0; if ((cfg->io.nwin > 0) ) { cistpl_io_t *io = &cfg->io ; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; if (!(io->flags & CISTPL_IO_8BIT)) link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; if (!(io->flags & CISTPL_IO_16BIT)) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; link->io.BasePort1 = io->win[0].base; link->io.NumPorts1 = io->win[0].len; if (io->nwin > 1) { link->io.Attributes2 = link->io.Attributes1; link->io.BasePort2 = io->win[1].base; link->io.NumPorts2 = io->win[1].len; } } /* Now set up a common memory window, if needed. There is room in the dev_link_t structure for one memory window handle, but if the base addresses need to be saved, or if multiple windows are needed, the info should go in the private data structure for this device. Note that the memory window base is a physical address, and needs to be mapped to virtual space with ioremap() before it is used. GPR400: Allocate a 2K memory window for the attribute space. This contains four registers of interest. */ if ((cfg->mem.nwin > 0) ) { cistpl_mem_t *mem = &cfg->mem ; req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM; req.Attributes |= WIN_ENABLE; req.Base = mem->win[0].host_addr; req.Size = mem->win[0].len; if (req.Size < 0x1000) req.Size = 0x1000; req.AccessSpeed = 55; map.Page = 0; DEBUG ( 0, "Requesting Memory\n"); CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win)); map.CardOffset = mem->win[0].card_addr; CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &map)); } /* Do we need to allocate an interrupt? */ if (cfg->irq.IRQInfo1 ) { link->conf.Attributes |= CONF_ENABLE_IRQ; DEBUG(0, "Interrupt will be requested\n" ); } DEBUG ( 0, "Done With this Entry" ); /* If we got this far, we're cool! */ break; next_entry: CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } /* PCMCIA_CD0 Allocate an interrupt line. Note that this does not assign a handler to the interrupt, unless the 'Handler' member of the irq structure is initialized. */ DEBUG ( 0, "Requesting IRQ\n"); if (link->conf.Attributes & CONF_ENABLE_IRQ) CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); /* This reserves IO space but doesn't actually enable it */ DEBUG(0, "Requesting IO\n"); CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io)); /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); /* We can release the IO port allocations here, if some other driver for the card is going to loaded, and will expect the ports to be available. */ if (free_ports) { if (link->io.BasePort1) release_region(link->io.BasePort1, link->io.NumPorts1); if (link->io.BasePort2) release_region(link->io.BasePort2, link->io.NumPorts2); } /* At this point, the dev_node_t structure(s) need to be initialized and arranged in a linked list at link->dev. */ sprintf(dev->node.dev_name, "gpr400"); dev->node.major = GPR_MAJOR; dev->node.minor = 0; dev->am_base = (caddr_t)req.Base; dev->io_base = link->io.BasePort1; dev->irq = link->irq.AssignedIRQ; link->dev = &dev->node; printk ( KERN_DEBUG "Requesting actual IRQ %d\n", dev->irq ); request_irq(dev->irq, gpr400_interrupt, SA_SHIRQ, dev_info, dev); /* Finally, report what we've done */ printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", dev->node.dev_name, link->conf.ConfigIndex, link->conf.Vcc/10, link->conf.Vcc%10); if (link->conf.Vpp1) printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); if (link->io.NumPorts2) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); if (link->win) printk(", mem 0x%06lx-0x%06lx", req.Base, req.Base+req.Size-1); printk("\n"); link->state &= ~DEV_CONFIG_PENDING; return; cs_failed: cs_error(link->handle, last_fn, last_ret); gpr400_release((u_long)link); } /* gpr400_config */ /*====================================================================== After a card is removed, gpr400_release() will unregister the device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. ======================================================================*/ static void gpr400_release(u_long arg) { dev_link_t *link = (dev_link_t *)arg; gpr400_local_t *dev = link->priv; DEBUG(0, "gpr400_release(0x%p)\n", link); /* If the device is currently in use, we won't release until it is actually closed, because until then, we can't be sure that no one will try to access the device or its data structures. */ if (link->open) { DEBUG(1, "gpr400_cs: release postponed, '%s' still open\n", link->dev->dev_name); link->state |= DEV_STALE_CONFIG; return; } /* Unlink the device chain */ link->dev = NULL; /* In a normal driver, additional code may be needed to release other kernel data structures associated with this device. */ /* Don't bother checking to see if these succeed or not */ if (link->win) pcmcia_release_window(link->win); pcmcia_release_configuration(link->handle); if (link->io.NumPorts1) pcmcia_release_io(link->handle, &link->io); if (link->irq.AssignedIRQ) pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; printk ( KERN_DEBUG "Releasing IRQ: %d %p\n", link->irq.AssignedIRQ, dev ); free_irq(link->irq.AssignedIRQ, dev); if (link->state & DEV_STALE_LINK) gpr400_detach(link); } /* gpr400_release */ /*====================================================================== The card status event handler. Mostly, this schedules other stuff to run after an event is received. When a CARD_REMOVAL event is received, we immediately set a private flag to block future accesses to this device. All the functions that actually access the device should check this flag to make sure the card is still present. ======================================================================*/ static int gpr400_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; gpr400_local_t *dev = link->priv; DEBUG(1, "gpr400_event(0x%06x)\n", event); switch (event) { case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { ((gpr400_local_t *)link->priv)->stop = 1; mod_timer(&dev->release_timer, jiffies + HZ/20); } break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; // dev->bus = args->bus; gpr400_config(link); break; case CS_EVENT_PM_SUSPEND: link->state |= DEV_SUSPEND; /* Fall through... */ case CS_EVENT_RESET_PHYSICAL: /* Mark the device as stopped, to block IO until later */ dev->stop = 1; if (link->state & DEV_CONFIG) pcmcia_release_configuration(link->handle); break; case CS_EVENT_PM_RESUME: link->state &= ~DEV_SUSPEND; /* Fall through... */ case CS_EVENT_CARD_RESET: if (link->state & DEV_CONFIG) pcmcia_request_configuration(link->handle, &link->conf); dev->stop = 0; /* In a normal driver, additional code may go here to restore the device state and restart IO. */ break; } return 0; } /* gpr400_event */ /*====================================================================*/ static struct pcmcia_driver gpr400_cs_driver = { .owner = THIS_MODULE, .drv = { .name = "gpr400_cs", }, .attach = gpr400_attach, .detach = gpr400_detach, }; static int __init init_gpr400_cs(void) { /* * servinfo_t and CS_RELEASE_CODE are deprecated. See also: * http://lists.infradead.org/pipermail/linux-pcmcia/2005-July/002123.html */ /*servinfo_t serv;*/ DEBUG(0, "%s\n", version); /*pcmcia_get_card_services_info(&serv); */ /* if (serv.Revision != CS_RELEASE_CODE) { printk(KERN_NOTICE "gpr400_cs: Card Services release " "does not match!\n"); return -1; } */ pcmcia_register_driver(&gpr400_cs_driver); /* * Register new character device with kernel */ if (register_chrdev(GPR_MAJOR, "gpr400", &gpr400_chr_fops) != 0) { printk(KERN_NOTICE "gpr400_cs: unable to grab device #%d\n", GPR_MAJOR); pcmcia_unregister_driver(&gpr400_cs_driver); return -1; } return 0; } static void __exit exit_gpr400_cs(void) { DEBUG(0, "gpr400_cs: unloading\n"); unregister_chrdev(GPR_MAJOR, "gpr400"); pcmcia_unregister_driver(&gpr400_cs_driver); while (dev_list != NULL) { del_timer(&((gpr400_local_t*)dev_list->priv)->release_timer); if (dev_list->state & DEV_CONFIG) gpr400_release((u_long)dev_list); gpr400_detach(dev_list); } } module_init(init_gpr400_cs); module_exit(exit_gpr400_cs); /* * GPR400 specific I/O routines */ static wait_queue_head_t gpr400_wait; /* * tlv_send -- send a tlv string to the smart card reader * The function handles breaking up the string into pieces small enough * for the reader to swallow and performs the necessary handshake with * the reader after each chunk. Checks the reader status after each * chunk and aborts on errors. */ static int tlv_send(struct gpr400_local_t *dev, u_char t, int l, u_char *v) { int s; /* length sent */ int i; /* loop var */ u_char va; /* reader status */ #ifdef PCMCIA_DEBUG if (pc_debug) { printk(KERN_DEBUG "tlv_send(dev,t=0x%02x,l=0x%02x,v=0x", t, l); for (i = 0; i < l; ++i) printk("%02x", v[i]); printk(")\n"); } #endif /* * Send chunks. */ t |= GPR400_CONT; for (s = 0; l - s > 28; s += 28) { /* * Copy data to reader */ outb(t, dev->io_base + 2); outb(28, dev->io_base + 3); for (i = 0; i < 28; ++i) outb(*v++, dev->io_base + 4 + i); /* * Start processing and wait for it to finish */ outb(GPR400_START, dev->io_base); interruptible_sleep_on(&gpr400_wait); /* * Get status byte */ va = inb(dev->io_base + 4); if (va != 0x00) { printk(KERN_INFO "gpr400_cs: %s\n", cardReaderError(va)); return -EIO; } } /* * Send final chunk */ t &= ~GPR400_CONT; outb(t, dev->io_base + 2); outb(l - s, dev->io_base + 3); for (i = 0; i < l - s; ++i) outb(*v++, dev->io_base + 4 + i); s += i; /* * Start processing of final chunk */ outb(GPR400_START, dev->io_base); interruptible_sleep_on(&gpr400_wait); /* * The final status may mark an error return from the card * (i.e. sw1/sw2 != 0x90/00) which must be handled by higher * layers. This is not a reader error, so it is ignored here. */ va = inb(dev->io_base + 4); if (va != 0x00 && va != 0xe7) { printk(KERN_INFO "gpr400_cs: %s\n", cardReaderError(va)); return -EIO; } return s; } /* * tlv_recv -- receive a tlv string from the smart card reader. * This function handles reassembly of pieces of information returned * from the reader. Returns reader status byte. t, l and v contain the * response. */ static int tlv_recv(struct gpr400_local_t *dev, u_char *t, int *l, u_char *v) { u_char ta; /* tag of chunk */ int la; /* length of chunk */ u_char s; /* reader status */ int i; /* loop var */ int j; /* loop var */ u_char *vsave = v; /* saved pointer to start of data */ ta = *t = inb(dev->io_base + 2); la = *l = inb(dev->io_base + 3) & 0xFF; s = inb(dev->io_base + 4); #ifdef PCMCIA_DEBUG if (pc_debug) printk(KERN_DEBUG "tlv_recv(dev,0x%02x,0x%02x,?): %s\n", *t, *l, cardReaderError(s)); #endif /* * Command not successful is *not* a reader error */ if (s == 0xe7) s = 0x00; if (s != 0x00) { printk(KERN_INFO "gpr400_cs: %s", cardReaderError(s)); return s; } /* * Reader status byte doesn't count for length returned */ *l -= 1; *t &= ~GPR400_CONT; /* Clear continuation flag, if any */ for (i = 1; ta & GPR400_CONT; i = 0) { for (j = 0; j < la - i; ++j) *v++ = inb(dev->io_base + 4 + i + j); /* * Get next chunk */ outb(GPR400_START, dev->io_base); interruptible_sleep_on(&gpr400_wait); ta = inb(dev->io_base + 2); la = inb(dev->io_base + 3) & 0xFF; *l += la; } /* * Get last chunk of data */ for (j = 0; j < la - i; ++j) *v++ = inb(dev->io_base + 4 + i + j); #ifdef PCMCIA_DEBUG if (pc_debug) { printk(KERN_DEBUG "tlv_recv(%d) ->", *l); for (i = 0; i < *l; ++i) printk(" %02x", vsave[i]); printk("\n"); } #endif return s; } /* * interrupt handler */ static irqreturn_t gpr400_interrupt(int irq, void *dev_id, struct pt_regs *regs) { dev_link_t *link; gpr400_local_t *dev; u_char ack; #ifdef PCMCIA_DEBUG if (pc_debug) printk(KERN_DEBUG "gpr400_cs: interrupt\n"); #endif /* * Find device that caused the interrupt. */ for (link = dev_list; link; link = link->next) { dev = (gpr400_local_t *)link->priv; if (dev && dev->irq == irq) break; } if (!DEV_OK(link)) return IRQ_NONE; dev = (gpr400_local_t *)link->priv; /* * Acknowledge interrupt to reader. */ ack = inb(dev->io_base); ack &= ~GPR400_IRQACK; outb(ack, dev->io_base); /* * Wakeup upper half. */ wake_up_interruptible(&gpr400_wait); return IRQ_HANDLED; } /** * reset the gpr400 device */ void gpr400_reset( gpr400_local_t *dev ) { #ifdef PCMCIA_DEBUG if (pc_debug) printk(KERN_DEBUG "gpr400_reset\n"); #endif outb(GPR400_RST, dev->io_base); udelay(10); /* wait 5 us at least */ outb(0, dev->io_base); mdelay(20); /* wait 20 ms */ }/* gpr400_reset */ /* * open channel on GPR400 */ static int gpr400_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); dev_link_t *link; gpr400_local_t *dev; int s; /* status */ #ifdef PCMCIA_DEBUG if (pc_debug) printk(KERN_DEBUG "gpr400_open(%d)\n", minor); #endif for (link = dev_list; link; link = link->next) { if (link->dev && link->dev->minor == minor) break; } dev = (gpr400_local_t *)link->priv; if (!DEV_OK(link)) return -ENODEV; /* * Only one process may use the reader */ if (link->open) return -EBUSY; /* * Initialize the wait token */ init_waitqueue_head(&gpr400_wait); /* * reset the reader for good measure (clean slate) */ gpr400_reset(dev); /* Reconfigure PCMCIA interface */ if (link->state & DEV_CONFIG) pcmcia_request_configuration(link->handle, &link->conf); /* * Send select card command: * bit 4: =0: clock speed 3.68 MHz * =1: clock speed 7.36 MHz * bit 1,0: =00: downloaded driver 0 * =10: ISO7816-3 driver * all other values are RFU. */ if ((s = tlv_send(dev, GPR400_SLCT, 0x01, "\x02")) < 0) return s; ++link->open; return 0; }/* gpr400_open */ /* * close channel on GPR400 */ static FS_RELEASE_T gpr400_close(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); dev_link_t *link; gpr400_local_t *dev; #ifdef PCMCIA_DEBUG if (pc_debug) printk(KERN_DEBUG "gpr400_close(%d)\n", minor); #endif for (link = dev_list; link; link = link->next) { if (link->dev && link->dev->minor == minor) break; } if (!DEV_OK(link)) return (FS_RELEASE_T)0; dev = (gpr400_local_t *)link->priv; /* * Close session with card */ tlv_send(dev, GPR400_CLSE, 0x00, NULL); /* * Make device available again, regardless of errors during close. */ --link->open; /* * If card was removed clean up */ if (link->state & DEV_STALE_CONFIG) gpr400_release((u_long)link); return (FS_RELEASE_T)0; }/* gpr400_close */ /* * gpr400_ioctl -- perform reader operations * All of the card reader operations are currently performed through * ioctl's. This is because the semantics of read and write are not * easily mapped onto reading/writing a card through the ISO interface. * * The ioctl's that do not have the possibility to return values other * than a status return EIO for all possible problems. The ioctl's that * copy information back to the user fill the reader status bit and * succeed, even if the reader had an error. */ static int gpr400_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) { int minor = MINOR(inode->i_rdev); dev_link_t *link; gpr400_local_t *dev; u_char ta; /* reader answer tag */ int la; /* reader answer length */ int ret = 0; /* return value */ u_int size; /* size for data transfers */ struct gpr400_status status; /* reader status structure */ struct gpr400_cmd gpr400_cmd; /* reader command structure */ struct gpr400_atr atr; /* reader ATR structure */ struct gpr400_tlv tlv; /* TLV command buffer */ unsigned char rcv_status; /* status of TLV command */ u_char buf[GPR_BUFSZ]; #ifdef PCMCIA_DEBUG if (pc_debug) printk(KERN_DEBUG "gpr400_ioctl(%d, 0x%0x)\n", minor, cmd); #endif for (link = dev_list; link; link = link->next) { if (link->dev && link->dev->minor == minor) break; } if (!DEV_OK(link)) return -ENODEV; dev = (gpr400_local_t *)link->priv; size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; if (cmd & IOC_IN) /* Moved from verify_area to !access_ok * http://www.ussg.iu.edu/hypermail/linux/kernel/0508.3/1210.html */ if ((ret = !access_ok(VERIFY_READ, (char *)arg, size))) return ret; if (cmd & IOC_OUT) if ((ret = !access_ok(VERIFY_WRITE, (char *)arg, size))) return ret; switch (cmd) { case GPR400_RESET: /* reset the card reader */ gpr400_reset(dev); /* Reconfigure PCMCIA interface */ if (link->state & DEV_CONFIG) pcmcia_request_configuration(link->handle, &link->conf); /* Send select command */ if ((ret = tlv_send(dev, GPR400_SLCT, 0x01, "\x02")) < 0) return ret; break; case GPR400_PWROFF: /* poweroff the card reader */ case GPR400_STNDBY: /* put card reader in standby */ if ((ret = tlv_send(dev, GPR400_POWER, 0x01, "\x00")) >= 0) ret = 0; break; case GPR400_STATUS: /* fetch stati of card reader */ /* * The reader status returned is actually the status of * the first partial command! */ tlv_send(dev, GPR400_STS, 0x01, "\x00"); tlv_recv(dev, &ta, &la, buf); status.status = ret; status.os_version = buf[0]; status.flash_mem = buf[1]; status.manufacturer = buf[6]; tlv_send(dev, GPR400_STS, 0x01, "\x01"); tlv_recv(dev, &ta, &la, buf); status.rom_sum = buf[0]; status.ram_sum = buf[1]; status.flash_sum = ((la > 2) ? buf[2] : 0); tlv_send(dev, GPR400_STS, 0x01, "\x02"); tlv_recv(dev, &ta, &la, buf); status.reg1 = buf[0]; status.reg2 = buf[1]; status.info = buf[2]; status.card_inserted = ((buf[0] & 0x80) ? 1 : 0); if (copy_to_user((struct gpr400_status *)arg, &status, sizeof(struct gpr400_status))) return -EFAULT; break; case GPR400_RAM: /* Get image of reader ram */ if (copy_to_user((struct gpr400_ram *)arg, dev->am_base, sizeof(struct gpr400_ram))) return -EFAULT; break; case GPR400_CMD: /* Perform a command */ if (copy_from_user(&gpr400_cmd, (struct gpr400_cmd *)arg, sizeof(struct gpr400_cmd))) return -EFAULT; /* * Send command to reader. * Note: Assumes that there is no padding in * struct gpr400_cmd! */ size = 6; if (gpr400_cmd.dir == 0x00) size += gpr400_cmd.len; tlv_send(dev, GPR400_APDU, size, (u_char *)&gpr400_cmd); /* * Get status or status and command data from card */ gpr400_cmd.status = tlv_recv(dev, &ta, &la, buf); gpr400_cmd.sw1 = gpr400_cmd.sw2 = 0; if (la >= 2) { memcpy(gpr400_cmd.data, buf, la - 2); gpr400_cmd.sw1 = buf[la - 2]; gpr400_cmd.sw2 = buf[la - 1]; } if (copy_to_user((struct gpr400_cmd *)arg, &gpr400_cmd, sizeof(struct gpr400_cmd))) return -EFAULT; break; case GPR400_OPEN: /* open session command */ /* * Open session with card: * Powers up the smart card in accordance with ISO7816-3. * Response contains Reader status and ATR. Note that the * ATR is TS + a maximum of 32 bytes. */ tlv_send(dev, GPR400_OPN, 0x00, ""); la = 0; memset(&atr, 0, sizeof(struct gpr400_atr)); atr.status = tlv_recv(dev, &ta, &la, buf); atr.len = la; if (ret == 0x00) memcpy(atr.data, buf, la); if (copy_to_user((struct gpr400_atr *)arg, &atr, sizeof(struct gpr400_atr))) return -EFAULT; break; case GPR400_CLOSE: /* close session command */ if ((ret = tlv_send(dev, GPR400_CLSE, 0x00, NULL)) < 0) return ret; break; case GPR400_SELECT: /* select reader protocol */ /* * Send select card command: * bit 4: =0: clock speed 3.68 MHz * =1: clock speed 7.36 MHz * bit 1,0: =00: downloaded driver 0 * =10: ISO7816-3 driver * all other values are RFU. */ if ((ret = tlv_send(dev, GPR400_SLCT, 0x01, "\x02")) < 0) return ret; break; case GPR400_TLV: /* Do TLV Exchange with GPR400 */ if (copy_from_user(&tlv, (struct gpr400_tlv *)arg, sizeof(struct gpr400_tlv))) return -EFAULT; tlv_send(dev, tlv.tag, tlv.length, (u_char *)&tlv.value); rcv_status = tlv_recv(dev, &ta, &la, buf); tlv.tag = ta; if (rcv_status == 0) tlv.length = la + 1; else tlv.length = la; tlv.value[0] = rcv_status; memcpy(&(tlv.value[1]), buf, la); if (copy_to_user((struct gpr400_tlv *)arg, &tlv, sizeof(struct gpr400_tlv))) return -EFAULT; break; default: ret = -EINVAL; break; } return ret; }