aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/telephony/ixj_pcmcia.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/telephony/ixj_pcmcia.c')
-rw-r--r--drivers/telephony/ixj_pcmcia.c119
1 files changed, 33 insertions, 86 deletions
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index d3a7b0c3d38b..dda0ca45d904 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -35,73 +35,52 @@ typedef struct ixj_info_t {
35} ixj_info_t; 35} ixj_info_t;
36 36
37static void ixj_detach(struct pcmcia_device *p_dev); 37static void ixj_detach(struct pcmcia_device *p_dev);
38static void ixj_config(dev_link_t * link); 38static int ixj_config(struct pcmcia_device * link);
39static void ixj_cs_release(dev_link_t * link); 39static void ixj_cs_release(struct pcmcia_device * link);
40 40
41static int ixj_attach(struct pcmcia_device *p_dev) 41static int ixj_probe(struct pcmcia_device *p_dev)
42{ 42{
43 dev_link_t *link;
44
45 DEBUG(0, "ixj_attach()\n"); 43 DEBUG(0, "ixj_attach()\n");
46 /* Create new ixj device */ 44 /* Create new ixj device */
47 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 45 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
48 if (!link) 46 p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
49 return -ENOMEM; 47 p_dev->io.IOAddrLines = 3;
50 memset(link, 0, sizeof(struct dev_link_t)); 48 p_dev->conf.IntType = INT_MEMORY_AND_IO;
51 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 49 p_dev->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
52 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; 50 if (!p_dev->priv) {
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; 51 return -ENOMEM;
60 } 52 }
61 memset(link->priv, 0, sizeof(struct ixj_info_t)); 53 memset(p_dev->priv, 0, sizeof(struct ixj_info_t));
62
63 link->handle = p_dev;
64 p_dev->instance = link;
65 54
66 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 55 return ixj_config(p_dev);
67 ixj_config(link);
68
69 return 0;
70} 56}
71 57
72static void ixj_detach(struct pcmcia_device *p_dev) 58static void ixj_detach(struct pcmcia_device *link)
73{ 59{
74 dev_link_t *link = dev_to_instance(p_dev);
75
76 DEBUG(0, "ixj_detach(0x%p)\n", link); 60 DEBUG(0, "ixj_detach(0x%p)\n", link);
77 61
78 link->state &= ~DEV_RELEASE_PENDING; 62 ixj_cs_release(link);
79 if (link->state & DEV_CONFIG)
80 ixj_cs_release(link);
81 63
82 kfree(link->priv); 64 kfree(link->priv);
83 kfree(link);
84} 65}
85 66
86#define CS_CHECK(fn, ret) \ 67#define CS_CHECK(fn, ret) \
87do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 68do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
88 69
89static void ixj_get_serial(dev_link_t * link, IXJ * j) 70static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
90{ 71{
91 client_handle_t handle;
92 tuple_t tuple; 72 tuple_t tuple;
93 u_short buf[128]; 73 u_short buf[128];
94 char *str; 74 char *str;
95 int last_ret, last_fn, i, place; 75 int last_ret, last_fn, i, place;
96 handle = link->handle;
97 DEBUG(0, "ixj_get_serial(0x%p)\n", link); 76 DEBUG(0, "ixj_get_serial(0x%p)\n", link);
98 tuple.TupleData = (cisdata_t *) buf; 77 tuple.TupleData = (cisdata_t *) buf;
99 tuple.TupleOffset = 0; 78 tuple.TupleOffset = 0;
100 tuple.TupleDataMax = 80; 79 tuple.TupleDataMax = 80;
101 tuple.Attributes = 0; 80 tuple.Attributes = 0;
102 tuple.DesiredTuple = CISTPL_VERS_1; 81 tuple.DesiredTuple = CISTPL_VERS_1;
103 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 82 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
104 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 83 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
105 str = (char *) buf; 84 str = (char *) buf;
106 printk("PCMCIA Version %d.%d\n", str[0], str[1]); 85 printk("PCMCIA Version %d.%d\n", str[0], str[1]);
107 str += 2; 86 str += 2;
@@ -149,22 +128,19 @@ static void ixj_get_serial(dev_link_t * link, IXJ * j)
149 return; 128 return;
150} 129}
151 130
152static void ixj_config(dev_link_t * link) 131static int ixj_config(struct pcmcia_device * link)
153{ 132{
154 IXJ *j; 133 IXJ *j;
155 client_handle_t handle;
156 ixj_info_t *info; 134 ixj_info_t *info;
157 tuple_t tuple; 135 tuple_t tuple;
158 u_short buf[128]; 136 u_short buf[128];
159 cisparse_t parse; 137 cisparse_t parse;
160 config_info_t conf;
161 cistpl_cftable_entry_t *cfg = &parse.cftable_entry; 138 cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
162 cistpl_cftable_entry_t dflt = 139 cistpl_cftable_entry_t dflt =
163 { 140 {
164 0 141 0
165 }; 142 };
166 int last_ret, last_fn; 143 int last_ret, last_fn;
167 handle = link->handle;
168 info = link->priv; 144 info = link->priv;
169 DEBUG(0, "ixj_config(0x%p)\n", link); 145 DEBUG(0, "ixj_config(0x%p)\n", link);
170 tuple.TupleData = (cisdata_t *) buf; 146 tuple.TupleData = (cisdata_t *) buf;
@@ -172,19 +148,17 @@ static void ixj_config(dev_link_t * link)
172 tuple.TupleDataMax = 255; 148 tuple.TupleDataMax = 255;
173 tuple.Attributes = 0; 149 tuple.Attributes = 0;
174 tuple.DesiredTuple = CISTPL_CONFIG; 150 tuple.DesiredTuple = CISTPL_CONFIG;
175 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 151 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
176 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 152 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
177 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 153 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
178 link->conf.ConfigBase = parse.config.base; 154 link->conf.ConfigBase = parse.config.base;
179 link->conf.Present = parse.config.rmask[0]; 155 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; 156 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
183 tuple.Attributes = 0; 157 tuple.Attributes = 0;
184 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 158 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
185 while (1) { 159 while (1) {
186 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 160 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
187 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 161 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
188 goto next_entry; 162 goto next_entry;
189 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 163 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
190 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; 164 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
@@ -195,7 +169,7 @@ static void ixj_config(dev_link_t * link)
195 link->io.BasePort2 = io->win[1].base; 169 link->io.BasePort2 = io->win[1].base;
196 link->io.NumPorts2 = io->win[1].len; 170 link->io.NumPorts2 = io->win[1].len;
197 } 171 }
198 if (pcmcia_request_io(link->handle, &link->io) != 0) 172 if (pcmcia_request_io(link, &link->io) != 0)
199 goto next_entry; 173 goto next_entry;
200 /* If we've got this far, we're done */ 174 /* If we've got this far, we're done */
201 break; 175 break;
@@ -203,10 +177,10 @@ static void ixj_config(dev_link_t * link)
203 next_entry: 177 next_entry:
204 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) 178 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
205 dflt = *cfg; 179 dflt = *cfg;
206 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); 180 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
207 } 181 }
208 182
209 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); 183 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
210 184
211 /* 185 /*
212 * Register the card with the core. 186 * Register the card with the core.
@@ -215,46 +189,21 @@ static void ixj_config(dev_link_t * link)
215 189
216 info->ndev = 1; 190 info->ndev = 1;
217 info->node.major = PHONE_MAJOR; 191 info->node.major = PHONE_MAJOR;
218 link->dev = &info->node; 192 link->dev_node = &info->node;
219 ixj_get_serial(link, j); 193 ixj_get_serial(link, j);
220 link->state &= ~DEV_CONFIG_PENDING; 194 return 0;
221 return;
222 cs_failed: 195 cs_failed:
223 cs_error(link->handle, last_fn, last_ret); 196 cs_error(link, last_fn, last_ret);
224 ixj_cs_release(link); 197 ixj_cs_release(link);
198 return -ENODEV;
225} 199}
226 200
227static void ixj_cs_release(dev_link_t *link) 201static void ixj_cs_release(struct pcmcia_device *link)
228{ 202{
229 ixj_info_t *info = link->priv; 203 ixj_info_t *info = link->priv;
230 DEBUG(0, "ixj_cs_release(0x%p)\n", link); 204 DEBUG(0, "ixj_cs_release(0x%p)\n", link);
231 info->ndev = 0; 205 info->ndev = 0;
232 link->dev = NULL; 206 pcmcia_disable_device(link);
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} 207}
259 208
260static struct pcmcia_device_id ixj_ids[] = { 209static struct pcmcia_device_id ixj_ids[] = {
@@ -268,11 +217,9 @@ static struct pcmcia_driver ixj_driver = {
268 .drv = { 217 .drv = {
269 .name = "ixj_cs", 218 .name = "ixj_cs",
270 }, 219 },
271 .probe = ixj_attach, 220 .probe = ixj_probe,
272 .remove = ixj_detach, 221 .remove = ixj_detach,
273 .id_table = ixj_ids, 222 .id_table = ixj_ids,
274 .suspend = ixj_suspend,
275 .resume = ixj_resume,
276}; 223};
277 224
278static int __init ixj_pcmcia_init(void) 225static int __init ixj_pcmcia_init(void)