Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.20-rc1 229 lines 5.0 kB view raw
1#include "ixj-ver.h" 2 3#include <linux/module.h> 4 5#include <linux/init.h> 6#include <linux/sched.h> 7#include <linux/kernel.h> /* printk() */ 8#include <linux/fs.h> /* everything... */ 9#include <linux/errno.h> /* error codes */ 10#include <linux/slab.h> 11 12#include <pcmcia/cs_types.h> 13#include <pcmcia/cs.h> 14#include <pcmcia/cistpl.h> 15#include <pcmcia/ds.h> 16 17#include "ixj.h" 18 19/* 20 * PCMCIA service support for Quicknet cards 21 */ 22 23#ifdef PCMCIA_DEBUG 24static int pc_debug = PCMCIA_DEBUG; 25module_param(pc_debug, int, 0644); 26#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) 27#else 28#define DEBUG(n, args...) 29#endif 30 31typedef struct ixj_info_t { 32 int ndev; 33 dev_node_t node; 34 struct ixj *port; 35} ixj_info_t; 36 37static void ixj_detach(struct pcmcia_device *p_dev); 38static int ixj_config(struct pcmcia_device * link); 39static void ixj_cs_release(struct pcmcia_device * link); 40 41static int ixj_probe(struct pcmcia_device *p_dev) 42{ 43 DEBUG(0, "ixj_attach()\n"); 44 /* Create new ixj device */ 45 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 46 p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; 47 p_dev->io.IOAddrLines = 3; 48 p_dev->conf.IntType = INT_MEMORY_AND_IO; 49 p_dev->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL); 50 if (!p_dev->priv) { 51 return -ENOMEM; 52 } 53 memset(p_dev->priv, 0, sizeof(struct ixj_info_t)); 54 55 return ixj_config(p_dev); 56} 57 58static void ixj_detach(struct pcmcia_device *link) 59{ 60 DEBUG(0, "ixj_detach(0x%p)\n", link); 61 62 ixj_cs_release(link); 63 64 kfree(link->priv); 65} 66 67#define CS_CHECK(fn, ret) \ 68do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 69 70static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) 71{ 72 char *str; 73 int i, place; 74 DEBUG(0, "ixj_get_serial(0x%p)\n", link); 75 76 str = link->prod_id[0]; 77 if (!str) 78 goto cs_failed; 79 printk("%s", str); 80 str = link->prod_id[1]; 81 if (!str) 82 goto cs_failed; 83 printk(" %s", str); 84 str = link->prod_id[2]; 85 if (!str) 86 goto cs_failed; 87 place = 1; 88 for (i = strlen(str) - 1; i >= 0; i--) { 89 switch (str[i]) { 90 case '0': 91 case '1': 92 case '2': 93 case '3': 94 case '4': 95 case '5': 96 case '6': 97 case '7': 98 case '8': 99 case '9': 100 j->serial += (str[i] - 48) * place; 101 break; 102 case 'A': 103 case 'B': 104 case 'C': 105 case 'D': 106 case 'E': 107 case 'F': 108 j->serial += (str[i] - 55) * place; 109 break; 110 case 'a': 111 case 'b': 112 case 'c': 113 case 'd': 114 case 'e': 115 case 'f': 116 j->serial += (str[i] - 87) * place; 117 break; 118 } 119 place = place * 0x10; 120 } 121 str = link->prod_id[3]; 122 if (!str) 123 goto cs_failed; 124 printk(" version %s\n", str); 125 cs_failed: 126 return; 127} 128 129static int ixj_config(struct pcmcia_device * link) 130{ 131 IXJ *j; 132 ixj_info_t *info; 133 tuple_t tuple; 134 u_short buf[128]; 135 cisparse_t parse; 136 cistpl_cftable_entry_t *cfg = &parse.cftable_entry; 137 cistpl_cftable_entry_t dflt = 138 { 139 0 140 }; 141 int last_ret, last_fn; 142 info = link->priv; 143 DEBUG(0, "ixj_config(0x%p)\n", link); 144 tuple.TupleData = (cisdata_t *) buf; 145 tuple.TupleOffset = 0; 146 tuple.TupleDataMax = 255; 147 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 148 tuple.Attributes = 0; 149 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 150 while (1) { 151 if (pcmcia_get_tuple_data(link, &tuple) != 0 || 152 pcmcia_parse_tuple(link, &tuple, &parse) != 0) 153 goto next_entry; 154 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 155 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; 156 link->conf.ConfigIndex = cfg->index; 157 link->io.BasePort1 = io->win[0].base; 158 link->io.NumPorts1 = io->win[0].len; 159 if (io->nwin == 2) { 160 link->io.BasePort2 = io->win[1].base; 161 link->io.NumPorts2 = io->win[1].len; 162 } 163 if (pcmcia_request_io(link, &link->io) != 0) 164 goto next_entry; 165 /* If we've got this far, we're done */ 166 break; 167 } 168 next_entry: 169 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) 170 dflt = *cfg; 171 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); 172 } 173 174 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 175 176 /* 177 * Register the card with the core. 178 */ 179 j=ixj_pcmcia_probe(link->io.BasePort1,link->io.BasePort1 + 0x10); 180 181 info->ndev = 1; 182 info->node.major = PHONE_MAJOR; 183 link->dev_node = &info->node; 184 ixj_get_serial(link, j); 185 return 0; 186 cs_failed: 187 cs_error(link, last_fn, last_ret); 188 ixj_cs_release(link); 189 return -ENODEV; 190} 191 192static void ixj_cs_release(struct pcmcia_device *link) 193{ 194 ixj_info_t *info = link->priv; 195 DEBUG(0, "ixj_cs_release(0x%p)\n", link); 196 info->ndev = 0; 197 pcmcia_disable_device(link); 198} 199 200static struct pcmcia_device_id ixj_ids[] = { 201 PCMCIA_DEVICE_MANF_CARD(0x0257, 0x0600), 202 PCMCIA_DEVICE_NULL 203}; 204MODULE_DEVICE_TABLE(pcmcia, ixj_ids); 205 206static struct pcmcia_driver ixj_driver = { 207 .owner = THIS_MODULE, 208 .drv = { 209 .name = "ixj_cs", 210 }, 211 .probe = ixj_probe, 212 .remove = ixj_detach, 213 .id_table = ixj_ids, 214}; 215 216static int __init ixj_pcmcia_init(void) 217{ 218 return pcmcia_register_driver(&ixj_driver); 219} 220 221static void ixj_pcmcia_exit(void) 222{ 223 pcmcia_unregister_driver(&ixj_driver); 224} 225 226module_init(ixj_pcmcia_init); 227module_exit(ixj_pcmcia_exit); 228 229MODULE_LICENSE("GPL");