pcmcia: move driver name to struct pcmcia_driver
[deliverable/linux.git] / drivers / isdn / hisax / avma1_cs.c
CommitLineData
1da177e4
LT
1/*
2 * PCMCIA client driver for AVM A1 / Fritz!PCMCIA
3 *
4 * Author Carsten Paeth
5 * Copyright 1998-2001 by Carsten Paeth <calle@calle.in-berlin.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/module.h>
13
14
15#include <linux/kernel.h>
16#include <linux/init.h>
1da177e4
LT
17#include <linux/ptrace.h>
18#include <linux/slab.h>
19#include <linux/string.h>
20#include <asm/io.h>
21#include <asm/system.h>
22
1da177e4
LT
23#include <pcmcia/cistpl.h>
24#include <pcmcia/ds.h>
25#include "hisax_cfg.h"
26
27MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for AVM A1/Fritz!PCMCIA cards");
28MODULE_AUTHOR("Carsten Paeth");
29MODULE_LICENSE("GPL");
30
1da177e4
LT
31
32/*====================================================================*/
33
34/* Parameters that can be set with 'insmod' */
35
36static int isdnprot = 2;
37
38module_param(isdnprot, int, 0);
39
40/*====================================================================*/
41
42/*
43 The event() function is this driver's Card Services event handler.
44 It will be called by Card Services when an appropriate card status
45 event is received. The config() and release() entry points are
46 used to configure or release a socket, in response to card insertion
47 and ejection events. They are invoked from the skeleton event
48 handler.
49*/
50
a465870a 51static int avma1cs_config(struct pcmcia_device *link) __devinit ;
fba395ee 52static void avma1cs_release(struct pcmcia_device *link);
1da177e4
LT
53
54/*
55 The attach() and detach() entry points are used to create and destroy
56 "instances" of the driver, where each instance represents everything
57 needed to manage one actual PCMCIA card.
58*/
59
a465870a 60static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ;
1da177e4 61
1da177e4 62
1da177e4
LT
63/*======================================================================
64
65 avma1cs_attach() creates an "instance" of the driver, allocating
66 local data structures for one device. The device is registered
67 with Card Services.
68
69 The dev_link structure is initialized, but we don't actually
70 configure the card at this point -- we wait until we receive a
71 card insertion event.
72
73======================================================================*/
74
a465870a 75static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
1da177e4 76{
e773cfe1 77 dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
1da177e4 78
1da177e4 79 /* General socket configuration */
00990e7c 80 p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
7feabb64
DB
81 p_dev->config_index = 1;
82 p_dev->config_regs = PRESENT_OPTION;
f8cfa618 83
15b99ac1 84 return avma1cs_config(p_dev);
1da177e4
LT
85} /* avma1cs_attach */
86
87/*======================================================================
88
89 This deletes a driver "instance". The device is de-registered
90 with Card Services. If it has been released, all local data
91 structures are freed. Otherwise, the structures will be freed
92 when the device is released.
93
94======================================================================*/
95
a465870a 96static void __devexit avma1cs_detach(struct pcmcia_device *link)
1da177e4 97{
e773cfe1 98 dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
e2d40963
DB
99 avma1cs_release(link);
100 kfree(link->priv);
1da177e4
LT
101} /* avma1cs_detach */
102
103/*======================================================================
104
105 avma1cs_config() is scheduled to run after a CARD_INSERTION event
106 is received, to configure the PCMCIA socket, and to make the
107 ethernet device available to the system.
108
109======================================================================*/
110
00990e7c 111static int avma1cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
1da177e4 112{
00990e7c
DB
113 p_dev->resource[0]->end = 16;
114 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
115 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
90abdc3b 116 p_dev->io_lines = 5;
00990e7c 117
90abdc3b 118 return pcmcia_request_io(p_dev);
1da177e4
LT
119}
120
1da177e4 121
a465870a 122static int __devinit avma1cs_config(struct pcmcia_device *link)
1da177e4 123{
eb14120f 124 int i = -1;
1da177e4
LT
125 char devname[128];
126 IsdnCard_t icard;
127 int busy = 0;
fba395ee 128
e773cfe1 129 dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
1da177e4 130
5fcd4da0
DB
131 devname[0] = 0;
132 if (link->prod_id[1])
133 strlcpy(devname, link->prod_id[1], sizeof(devname));
a9606fd3 134
5fcd4da0
DB
135 if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
136 return -ENODEV;
1da177e4 137
5fcd4da0 138 do {
1da177e4
LT
139 /*
140 * allocate an interrupt line
141 */
eb14120f 142 if (!link->irq) {
50db3fdb 143 /* undo */
fba395ee 144 pcmcia_disable_device(link);
1da177e4
LT
145 break;
146 }
50db3fdb 147
1da177e4
LT
148 /*
149 * configure the PCMCIA socket
150 */
1ac71e5a 151 i = pcmcia_enable_device(link);
4c89e88b 152 if (i != 0) {
fba395ee 153 pcmcia_disable_device(link);
1da177e4
LT
154 break;
155 }
156
157 } while (0);
158
1da177e4
LT
159 /* If any step failed, release any partially configured state */
160 if (i != 0) {
161 avma1cs_release(link);
15b99ac1 162 return -ENODEV;
1da177e4
LT
163 }
164
eb14120f 165 icard.para[0] = link->irq;
9a017a91 166 icard.para[1] = link->resource[0]->start;
1da177e4
LT
167 icard.protocol = isdnprot;
168 icard.typ = ISDN_CTYPE_A1_PCMCIA;
169
170 i = hisax_init_pcmcia(link, &busy, &icard);
171 if (i < 0) {
9a017a91
DB
172 printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 "
173 "PCMCIA %d at i/o %#x\n", i,
174 (unsigned int) link->resource[0]->start);
1da177e4 175 avma1cs_release(link);
15b99ac1 176 return -ENODEV;
1da177e4 177 }
b498ada6 178 link->priv = (void *) (unsigned long) i;
1da177e4 179
15b99ac1 180 return 0;
1da177e4
LT
181} /* avma1cs_config */
182
183/*======================================================================
184
185 After a card is removed, avma1cs_release() will unregister the net
186 device, and release the PCMCIA configuration. If the device is
187 still open, this will be postponed until it is closed.
188
189======================================================================*/
190
fba395ee 191static void avma1cs_release(struct pcmcia_device *link)
1da177e4 192{
b498ada6 193 unsigned long minor = (unsigned long) link->priv;
1da177e4 194
e773cfe1 195 dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link);
1da177e4 196
5f2a71fc 197 /* now unregister function with hisax */
b498ada6 198 HiSax_closecard(minor);
1da177e4 199
fba395ee 200 pcmcia_disable_device(link);
1da177e4
LT
201} /* avma1cs_release */
202
1da177e4 203
c594c12c
DB
204static struct pcmcia_device_id avma1cs_ids[] = {
205 PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
206 PCMCIA_DEVICE_PROD_ID12("ISDN", "CARD", 0x8d9761c8, 0x01c5aa7b),
207 PCMCIA_DEVICE_NULL
208};
209MODULE_DEVICE_TABLE(pcmcia, avma1cs_ids);
210
1da177e4
LT
211static struct pcmcia_driver avma1cs_driver = {
212 .owner = THIS_MODULE,
2e9b981a 213 .name = "avma1_cs",
15b99ac1 214 .probe = avma1cs_probe,
a465870a 215 .remove = __devexit_p(avma1cs_detach),
c594c12c 216 .id_table = avma1cs_ids,
1da177e4 217};
8661bb5b 218
1da177e4
LT
219/*====================================================================*/
220
221static int __init init_avma1_cs(void)
222{
223 return(pcmcia_register_driver(&avma1cs_driver));
224}
225
226static void __exit exit_avma1_cs(void)
227{
228 pcmcia_unregister_driver(&avma1cs_driver);
1da177e4
LT
229}
230
231module_init(init_avma1_cs);
232module_exit(exit_avma1_cs);
This page took 0.50959 seconds and 5 git commands to generate.