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