pcmcia: remove the "Finally, report what we've done" message
[deliverable/linux.git] / drivers / isdn / hisax / elsa_cs.c
CommitLineData
1da177e4
LT
1/*======================================================================
2
3 An elsa_cs PCMCIA client driver
4
5 This driver is for the Elsa PCM ISDN Cards, i.e. the MicroLink
6
7
8 The contents of this file are subject to the Mozilla Public
9 License Version 1.1 (the "License"); you may not use this file
10 except in compliance with the License. You may obtain a copy of
11 the License at http://www.mozilla.org/MPL/
12
13 Software distributed under the License is distributed on an "AS
14 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
15 implied. See the License for the specific language governing
16 rights and limitations under the License.
17
18 The initial developer of the original code is David A. Hinds
19 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
20 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
21
22 Modifications from dummy_cs.c are Copyright (C) 1999-2001 Klaus
23 Lichtenwalder <Lichtenwalder@ACM.org>. All Rights Reserved.
24
25 Alternatively, the contents of this file may be used under the
26 terms of the GNU General Public License version 2 (the "GPL"), in
27 which case the provisions of the GPL are applicable instead of the
28 above. If you wish to allow the use of your version of this file
29 only under the terms of the GPL and not to allow others to use
30 your version of this file under the MPL, indicate your decision
31 by deleting the provisions above and replace them with the notice
32 and other provisions required by the GPL. If you do not delete
33 the provisions above, a recipient may use your version of this
34 file under either the MPL or the GPL.
35
36======================================================================*/
37
38#include <linux/module.h>
39#include <linux/kernel.h>
40#include <linux/init.h>
1da177e4
LT
41#include <linux/ptrace.h>
42#include <linux/slab.h>
43#include <linux/string.h>
44#include <linux/timer.h>
45#include <linux/ioport.h>
46#include <asm/io.h>
47#include <asm/system.h>
48
1da177e4
LT
49#include <pcmcia/cistpl.h>
50#include <pcmcia/cisreg.h>
51#include <pcmcia/ds.h>
52#include "hisax_cfg.h"
53
54MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards");
55MODULE_AUTHOR("Klaus Lichtenwalder");
56MODULE_LICENSE("Dual MPL/GPL");
57
1da177e4
LT
58
59/*====================================================================*/
60
61/* Parameters that can be set with 'insmod' */
62
63static int protocol = 2; /* EURO-ISDN Default */
64module_param(protocol, int, 0);
65
66/*====================================================================*/
67
68/*
69 The event() function is this driver's Card Services event handler.
70 It will be called by Card Services when an appropriate card status
71 event is received. The config() and release() entry points are
72 used to configure or release a socket, in response to card insertion
73 and ejection events. They are invoked from the elsa_cs event
74 handler.
75*/
76
f61bb62e 77static int elsa_cs_config(struct pcmcia_device *link) __devinit ;
fba395ee 78static void elsa_cs_release(struct pcmcia_device *link);
1da177e4
LT
79
80/*
81 The attach() and detach() entry points are used to create and destroy
82 "instances" of the driver, where each instance represents everything
83 needed to manage one actual PCMCIA card.
84*/
85
f61bb62e 86static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit;
1da177e4 87
1da177e4 88typedef struct local_info_t {
fd238232 89 struct pcmcia_device *p_dev;
1da177e4
LT
90 int busy;
91 int cardnr;
92} local_info_t;
93
94/*======================================================================
95
96 elsa_cs_attach() creates an "instance" of the driver, allocatingx
97 local data structures for one device. The device is registered
98 with Card Services.
99
100 The dev_link structure is initialized, but we don't actually
101 configure the card at this point -- we wait until we receive a
102 card insertion event.
103
104======================================================================*/
105
f61bb62e 106static int __devinit elsa_cs_probe(struct pcmcia_device *link)
1da177e4 107{
1da177e4 108 local_info_t *local;
1da177e4 109
e773cfe1 110 dev_dbg(&link->dev, "elsa_cs_attach()\n");
1da177e4
LT
111
112 /* Allocate space for private device-specific data */
41f96935 113 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
f8cfa618 114 if (!local) return -ENOMEM;
fd238232 115
fba395ee 116 local->p_dev = link;
fd238232
DB
117 link->priv = local;
118
1da177e4 119 local->cardnr = -1;
1da177e4 120
15b99ac1 121 return elsa_cs_config(link);
1da177e4
LT
122} /* elsa_cs_attach */
123
124/*======================================================================
125
126 This deletes a driver "instance". The device is de-registered
127 with Card Services. If it has been released, all local data
128 structures are freed. Otherwise, the structures will be freed
129 when the device is released.
130
131======================================================================*/
132
f61bb62e 133static void __devexit elsa_cs_detach(struct pcmcia_device *link)
1da177e4 134{
e2d40963 135 local_info_t *info = link->priv;
1da177e4 136
e773cfe1 137 dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link);
1da177e4 138
e2d40963
DB
139 info->busy = 1;
140 elsa_cs_release(link);
1da177e4 141
e2d40963 142 kfree(info);
1da177e4
LT
143} /* elsa_cs_detach */
144
145/*======================================================================
146
147 elsa_cs_config() is scheduled to run after a CARD_INSERTION event
148 is received, to configure the PCMCIA socket, and to make the
149 device available to the system.
150
151======================================================================*/
1da177e4 152
00990e7c 153static int elsa_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
1da177e4 154{
5fcd4da0
DB
155 int j;
156
90abdc3b 157 p_dev->io_lines = 3;
00990e7c
DB
158 p_dev->resource[0]->end = 8;
159 p_dev->resource[0]->flags &= IO_DATA_PATH_WIDTH;
160 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
90abdc3b 161
00990e7c 162 if ((p_dev->resource[0]->end) && p_dev->resource[0]->start) {
5fcd4da0 163 printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
90abdc3b 164 if (!pcmcia_request_io(p_dev))
5fcd4da0
DB
165 return 0;
166 } else {
167 printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
5fcd4da0 168 for (j = 0x2f0; j > 0x100; j -= 0x10) {
90abdc3b
DB
169 p_dev->resource[0]->start = j;
170 if (!pcmcia_request_io(p_dev))
5fcd4da0
DB
171 return 0;
172 }
173 }
174 return -ENODEV;
1da177e4
LT
175}
176
f61bb62e 177static int __devinit elsa_cs_config(struct pcmcia_device *link)
1da177e4 178{
1da177e4 179 local_info_t *dev;
e773cfe1 180 int i;
1da177e4
LT
181 IsdnCard_t icard;
182
e773cfe1 183 dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
1da177e4
LT
184 dev = link->priv;
185
00990e7c
DB
186 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
187
5fcd4da0 188 i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
e773cfe1
DB
189 if (i != 0)
190 goto failed;
1da177e4 191
eb14120f 192 if (!link->irq)
e773cfe1 193 goto failed;
1da177e4 194
1ac71e5a 195 i = pcmcia_enable_device(link);
e773cfe1
DB
196 if (i != 0)
197 goto failed;
1da177e4 198
eb14120f 199 icard.para[0] = link->irq;
9a017a91 200 icard.para[1] = link->resource[0]->start;
1da177e4
LT
201 icard.protocol = protocol;
202 icard.typ = ISDN_CTYPE_ELSA_PCMCIA;
203
204 i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard);
205 if (i < 0) {
9a017a91
DB
206 printk(KERN_ERR "elsa_cs: failed to initialize Elsa "
207 "PCMCIA %d with %pR\n", i, link->resource[0]);
1da177e4
LT
208 elsa_cs_release(link);
209 } else
210 ((local_info_t*)link->priv)->cardnr = i;
211
15b99ac1 212 return 0;
e773cfe1 213failed:
1da177e4 214 elsa_cs_release(link);
15b99ac1 215 return -ENODEV;
1da177e4
LT
216} /* elsa_cs_config */
217
218/*======================================================================
219
220 After a card is removed, elsa_cs_release() will unregister the net
221 device, and release the PCMCIA configuration. If the device is
222 still open, this will be postponed until it is closed.
223
224======================================================================*/
225
fba395ee 226static void elsa_cs_release(struct pcmcia_device *link)
1da177e4
LT
227{
228 local_info_t *local = link->priv;
229
e773cfe1 230 dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link);
1da177e4
LT
231
232 if (local) {
233 if (local->cardnr >= 0) {
234 /* no unregister function with hisax */
235 HiSax_closecard(local->cardnr);
236 }
237 }
5f2a71fc 238
fba395ee 239 pcmcia_disable_device(link);
1da177e4
LT
240} /* elsa_cs_release */
241
fba395ee 242static int elsa_suspend(struct pcmcia_device *link)
98e4c28b 243{
98e4c28b
DB
244 local_info_t *dev = link->priv;
245
98e4c28b 246 dev->busy = 1;
98e4c28b
DB
247
248 return 0;
249}
250
fba395ee 251static int elsa_resume(struct pcmcia_device *link)
98e4c28b 252{
98e4c28b
DB
253 local_info_t *dev = link->priv;
254
98e4c28b
DB
255 dev->busy = 0;
256
257 return 0;
258}
259
02ae38cf
DB
260static struct pcmcia_device_id elsa_ids[] = {
261 PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257),
262 PCMCIA_DEVICE_PROD_ID12("ELSA GmbH, Aachen", "MicroLink ISDN/MC ", 0x639e5718, 0x333ba257),
263 PCMCIA_DEVICE_NULL
264};
265MODULE_DEVICE_TABLE(pcmcia, elsa_ids);
266
1da177e4
LT
267static struct pcmcia_driver elsa_cs_driver = {
268 .owner = THIS_MODULE,
269 .drv = {
270 .name = "elsa_cs",
271 },
15b99ac1 272 .probe = elsa_cs_probe,
f61bb62e 273 .remove = __devexit_p(elsa_cs_detach),
02ae38cf 274 .id_table = elsa_ids,
98e4c28b
DB
275 .suspend = elsa_suspend,
276 .resume = elsa_resume,
1da177e4
LT
277};
278
279static int __init init_elsa_cs(void)
280{
281 return pcmcia_register_driver(&elsa_cs_driver);
282}
283
284static void __exit exit_elsa_cs(void)
285{
286 pcmcia_unregister_driver(&elsa_cs_driver);
1da177e4
LT
287}
288
289module_init(init_elsa_cs);
290module_exit(exit_elsa_cs);
This page took 0.529677 seconds and 5 git commands to generate.