diff options
Diffstat (limited to 'drivers/telephony/ixj_pcmcia.c')
-rw-r--r-- | drivers/telephony/ixj_pcmcia.c | 119 |
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 | ||
37 | static void ixj_detach(struct pcmcia_device *p_dev); | 37 | static void ixj_detach(struct pcmcia_device *p_dev); |
38 | static void ixj_config(dev_link_t * link); | 38 | static int ixj_config(struct pcmcia_device * link); |
39 | static void ixj_cs_release(dev_link_t * link); | 39 | static void ixj_cs_release(struct pcmcia_device * link); |
40 | 40 | ||
41 | static int ixj_attach(struct pcmcia_device *p_dev) | 41 | static 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 | ||
72 | static void ixj_detach(struct pcmcia_device *p_dev) | 58 | static 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) \ |
87 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 68 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
88 | 69 | ||
89 | static void ixj_get_serial(dev_link_t * link, IXJ * j) | 70 | static 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 | ||
152 | static void ixj_config(dev_link_t * link) | 131 | static 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 | ||
227 | static void ixj_cs_release(dev_link_t *link) | 201 | static 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 | |||
238 | static 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 | |||
249 | static 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 | ||
260 | static struct pcmcia_device_id ixj_ids[] = { | 209 | static 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 | ||
278 | static int __init ixj_pcmcia_init(void) | 225 | static int __init ixj_pcmcia_init(void) |