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.16-rc6 291 lines 6.9 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 void ixj_config(dev_link_t * link); 39static void ixj_cs_release(dev_link_t * link); 40 41static int ixj_attach(struct pcmcia_device *p_dev) 42{ 43 dev_link_t *link; 44 45 DEBUG(0, "ixj_attach()\n"); 46 /* Create new ixj device */ 47 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 48 if (!link) 49 return -ENOMEM; 50 memset(link, 0, sizeof(struct dev_link_t)); 51 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 52 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; 53 link->io.IOAddrLines = 3; 54 link->conf.Vcc = 50; 55 link->conf.IntType = INT_MEMORY_AND_IO; 56 link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL); 57 if (!link->priv) { 58 kfree(link); 59 return -ENOMEM; 60 } 61 memset(link->priv, 0, sizeof(struct ixj_info_t)); 62 63 link->handle = p_dev; 64 p_dev->instance = link; 65 66 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 67 ixj_config(link); 68 69 return 0; 70} 71 72static void ixj_detach(struct pcmcia_device *p_dev) 73{ 74 dev_link_t *link = dev_to_instance(p_dev); 75 76 DEBUG(0, "ixj_detach(0x%p)\n", link); 77 78 link->state &= ~DEV_RELEASE_PENDING; 79 if (link->state & DEV_CONFIG) 80 ixj_cs_release(link); 81 82 kfree(link->priv); 83 kfree(link); 84} 85 86#define CS_CHECK(fn, ret) \ 87do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 88 89static void ixj_get_serial(dev_link_t * link, IXJ * j) 90{ 91 client_handle_t handle; 92 tuple_t tuple; 93 u_short buf[128]; 94 char *str; 95 int last_ret, last_fn, i, place; 96 handle = link->handle; 97 DEBUG(0, "ixj_get_serial(0x%p)\n", link); 98 tuple.TupleData = (cisdata_t *) buf; 99 tuple.TupleOffset = 0; 100 tuple.TupleDataMax = 80; 101 tuple.Attributes = 0; 102 tuple.DesiredTuple = CISTPL_VERS_1; 103 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 104 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 105 str = (char *) buf; 106 printk("PCMCIA Version %d.%d\n", str[0], str[1]); 107 str += 2; 108 printk("%s", str); 109 str = str + strlen(str) + 1; 110 printk(" %s", str); 111 str = str + strlen(str) + 1; 112 place = 1; 113 for (i = strlen(str) - 1; i >= 0; i--) { 114 switch (str[i]) { 115 case '0': 116 case '1': 117 case '2': 118 case '3': 119 case '4': 120 case '5': 121 case '6': 122 case '7': 123 case '8': 124 case '9': 125 j->serial += (str[i] - 48) * place; 126 break; 127 case 'A': 128 case 'B': 129 case 'C': 130 case 'D': 131 case 'E': 132 case 'F': 133 j->serial += (str[i] - 55) * place; 134 break; 135 case 'a': 136 case 'b': 137 case 'c': 138 case 'd': 139 case 'e': 140 case 'f': 141 j->serial += (str[i] - 87) * place; 142 break; 143 } 144 place = place * 0x10; 145 } 146 str = str + strlen(str) + 1; 147 printk(" version %s\n", str); 148 cs_failed: 149 return; 150} 151 152static void ixj_config(dev_link_t * link) 153{ 154 IXJ *j; 155 client_handle_t handle; 156 ixj_info_t *info; 157 tuple_t tuple; 158 u_short buf[128]; 159 cisparse_t parse; 160 config_info_t conf; 161 cistpl_cftable_entry_t *cfg = &parse.cftable_entry; 162 cistpl_cftable_entry_t dflt = 163 { 164 0 165 }; 166 int last_ret, last_fn; 167 handle = link->handle; 168 info = link->priv; 169 DEBUG(0, "ixj_config(0x%p)\n", link); 170 tuple.TupleData = (cisdata_t *) buf; 171 tuple.TupleOffset = 0; 172 tuple.TupleDataMax = 255; 173 tuple.Attributes = 0; 174 tuple.DesiredTuple = CISTPL_CONFIG; 175 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 176 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 177 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 178 link->conf.ConfigBase = parse.config.base; 179 link->conf.Present = parse.config.rmask[0]; 180 link->state |= DEV_CONFIG; 181 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); 182 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 183 tuple.Attributes = 0; 184 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 185 while (1) { 186 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 187 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 188 goto next_entry; 189 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 190 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; 191 link->conf.ConfigIndex = cfg->index; 192 link->io.BasePort1 = io->win[0].base; 193 link->io.NumPorts1 = io->win[0].len; 194 if (io->nwin == 2) { 195 link->io.BasePort2 = io->win[1].base; 196 link->io.NumPorts2 = io->win[1].len; 197 } 198 if (pcmcia_request_io(link->handle, &link->io) != 0) 199 goto next_entry; 200 /* If we've got this far, we're done */ 201 break; 202 } 203 next_entry: 204 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) 205 dflt = *cfg; 206 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); 207 } 208 209 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); 210 211 /* 212 * Register the card with the core. 213 */ 214 j=ixj_pcmcia_probe(link->io.BasePort1,link->io.BasePort1 + 0x10); 215 216 info->ndev = 1; 217 info->node.major = PHONE_MAJOR; 218 link->dev = &info->node; 219 ixj_get_serial(link, j); 220 link->state &= ~DEV_CONFIG_PENDING; 221 return; 222 cs_failed: 223 cs_error(link->handle, last_fn, last_ret); 224 ixj_cs_release(link); 225} 226 227static void ixj_cs_release(dev_link_t *link) 228{ 229 ixj_info_t *info = link->priv; 230 DEBUG(0, "ixj_cs_release(0x%p)\n", link); 231 info->ndev = 0; 232 link->dev = NULL; 233 pcmcia_release_configuration(link->handle); 234 pcmcia_release_io(link->handle, &link->io); 235 link->state &= ~DEV_CONFIG; 236} 237 238static int ixj_suspend(struct pcmcia_device *dev) 239{ 240 dev_link_t *link = dev_to_instance(dev); 241 242 link->state |= DEV_SUSPEND; 243 if (link->state & DEV_CONFIG) 244 pcmcia_release_configuration(link->handle); 245 246 return 0; 247} 248 249static int ixj_resume(struct pcmcia_device *dev) 250{ 251 dev_link_t *link = dev_to_instance(dev); 252 253 link->state &= ~DEV_SUSPEND; 254 if (DEV_OK(link)) 255 pcmcia_request_configuration(link->handle, &link->conf); 256 257 return 0; 258} 259 260static struct pcmcia_device_id ixj_ids[] = { 261 PCMCIA_DEVICE_MANF_CARD(0x0257, 0x0600), 262 PCMCIA_DEVICE_NULL 263}; 264MODULE_DEVICE_TABLE(pcmcia, ixj_ids); 265 266static struct pcmcia_driver ixj_driver = { 267 .owner = THIS_MODULE, 268 .drv = { 269 .name = "ixj_cs", 270 }, 271 .probe = ixj_attach, 272 .remove = ixj_detach, 273 .id_table = ixj_ids, 274 .suspend = ixj_suspend, 275 .resume = ixj_resume, 276}; 277 278static int __init ixj_pcmcia_init(void) 279{ 280 return pcmcia_register_driver(&ixj_driver); 281} 282 283static void ixj_pcmcia_exit(void) 284{ 285 pcmcia_unregister_driver(&ixj_driver); 286} 287 288module_init(ixj_pcmcia_init); 289module_exit(ixj_pcmcia_exit); 290 291MODULE_LICENSE("GPL");