OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [pcmcia/] [com20020_cs.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * Linux ARCnet driver - COM20020 PCMCIA support
3
 *
4
 * Written 1994-1999 by Avery Pennarun,
5
 *    based on an ISA version by David Woodhouse.
6
 * Derived from ibmtr_cs.c by Steve Kipisz (pcmcia-cs 3.1.4)
7
 *    which was derived from pcnet_cs.c by David Hinds.
8
 * Some additional portions derived from skeleton.c by Donald Becker.
9
 *
10
 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
11
 *  for sponsoring the further development of this driver.
12
 *
13
 * **********************
14
 *
15
 * The original copyright of skeleton.c was as follows:
16
 *
17
 * skeleton.c Written 1993 by Donald Becker.
18
 * Copyright 1993 United States Government as represented by the
19
 * Director, National Security Agency.  This software may only be used
20
 * and distributed according to the terms of the GNU General Public License as
21
 * modified by SRC, incorporated herein by reference.
22
 *
23
 * **********************
24
 * Changes:
25
 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000
26
 * - reorganize kmallocs in com20020_attach, checking all for failure
27
 *   and releasing the previous allocations if one fails
28
 * **********************
29
 *
30
 * For more details, see drivers/net/arcnet.c
31
 *
32
 * **********************
33
 */
34
#include <linux/kernel.h>
35
#include <linux/init.h>
36
#include <linux/ptrace.h>
37
#include <linux/slab.h>
38
#include <linux/string.h>
39
#include <linux/timer.h>
40
#include <linux/delay.h>
41
#include <linux/module.h>
42
#include <linux/netdevice.h>
43
#include <linux/arcdevice.h>
44
#include <linux/com20020.h>
45
 
46
#include <pcmcia/cs_types.h>
47
#include <pcmcia/cs.h>
48
#include <pcmcia/cistpl.h>
49
#include <pcmcia/ds.h>
50
 
51
#include <asm/io.h>
52
#include <asm/system.h>
53
 
54
#define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
55
 
56
#ifdef PCMCIA_DEBUG
57
 
58
static int pc_debug = PCMCIA_DEBUG;
59
module_param(pc_debug, int, 0);
60
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
61
 
62
static void regdump(struct net_device *dev)
63
{
64
    int ioaddr = dev->base_addr;
65
    int count;
66
 
67
    printk("com20020 register dump:\n");
68
    for (count = ioaddr; count < ioaddr + 16; count++)
69
    {
70
        if (!(count % 16))
71
            printk("\n%04X: ", count);
72
        printk("%02X ", inb(count));
73
    }
74
    printk("\n");
75
 
76
    printk("buffer0 dump:\n");
77
        /* set up the address register */
78
        count = 0;
79
        outb((count >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
80
        outb(count & 0xff, _ADDR_LO);
81
 
82
    for (count = 0; count < 256+32; count++)
83
    {
84
        if (!(count % 16))
85
            printk("\n%04X: ", count);
86
 
87
        /* copy the data */
88
        printk("%02X ", inb(_MEMDATA));
89
    }
90
    printk("\n");
91
}
92
 
93
#else
94
 
95
#define DEBUG(n, args...) do { } while (0)
96
static inline void regdump(struct net_device *dev) { }
97
 
98
#endif
99
 
100
 
101
/*====================================================================*/
102
 
103
/* Parameters that can be set with 'insmod' */
104
 
105
static int node;
106
static int timeout = 3;
107
static int backplane;
108
static int clockp;
109
static int clockm;
110
 
111
module_param(node, int, 0);
112
module_param(timeout, int, 0);
113
module_param(backplane, int, 0);
114
module_param(clockp, int, 0);
115
module_param(clockm, int, 0);
116
 
117
MODULE_LICENSE("GPL");
118
 
119
/*====================================================================*/
120
 
121
static int com20020_config(struct pcmcia_device *link);
122
static void com20020_release(struct pcmcia_device *link);
123
 
124
static void com20020_detach(struct pcmcia_device *p_dev);
125
 
126
/*====================================================================*/
127
 
128
typedef struct com20020_dev_t {
129
    struct net_device       *dev;
130
    dev_node_t          node;
131
} com20020_dev_t;
132
 
133
/*======================================================================
134
 
135
    com20020_attach() creates an "instance" of the driver, allocating
136
    local data structures for one device.  The device is registered
137
    with Card Services.
138
 
139
======================================================================*/
140
 
141
static int com20020_probe(struct pcmcia_device *p_dev)
142
{
143
    com20020_dev_t *info;
144
    struct net_device *dev;
145
    struct arcnet_local *lp;
146
 
147
    DEBUG(0, "com20020_attach()\n");
148
 
149
    /* Create new network device */
150
    info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
151
    if (!info)
152
        goto fail_alloc_info;
153
 
154
    dev = alloc_arcdev("");
155
    if (!dev)
156
        goto fail_alloc_dev;
157
 
158
    lp = dev->priv;
159
    lp->timeout = timeout;
160
    lp->backplane = backplane;
161
    lp->clockp = clockp;
162
    lp->clockm = clockm & 3;
163
    lp->hw.owner = THIS_MODULE;
164
 
165
    /* fill in our module parameters as defaults */
166
    dev->dev_addr[0] = node;
167
 
168
    p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
169
    p_dev->io.NumPorts1 = 16;
170
    p_dev->io.IOAddrLines = 16;
171
    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
172
    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
173
    p_dev->conf.Attributes = CONF_ENABLE_IRQ;
174
    p_dev->conf.IntType = INT_MEMORY_AND_IO;
175
 
176
    p_dev->irq.Instance = info->dev = dev;
177
    p_dev->priv = info;
178
 
179
    return com20020_config(p_dev);
180
 
181
fail_alloc_dev:
182
    kfree(info);
183
fail_alloc_info:
184
    return -ENOMEM;
185
} /* com20020_attach */
186
 
187
/*======================================================================
188
 
189
    This deletes a driver "instance".  The device is de-registered
190
    with Card Services.  If it has been released, all local data
191
    structures are freed.  Otherwise, the structures will be freed
192
    when the device is released.
193
 
194
======================================================================*/
195
 
196
static void com20020_detach(struct pcmcia_device *link)
197
{
198
    struct com20020_dev_t *info = link->priv;
199
    struct net_device *dev = info->dev;
200
 
201
    DEBUG(1,"detach...\n");
202
 
203
    DEBUG(0, "com20020_detach(0x%p)\n", link);
204
 
205
    if (link->dev_node) {
206
        DEBUG(1,"unregister...\n");
207
 
208
        unregister_netdev(dev);
209
 
210
        /*
211
         * this is necessary because we register our IRQ separately
212
         * from card services.
213
         */
214
        if (dev->irq)
215
            free_irq(dev->irq, dev);
216
    }
217
 
218
    com20020_release(link);
219
 
220
    /* Unlink device structure, free bits */
221
    DEBUG(1,"unlinking...\n");
222
    if (link->priv)
223
    {
224
        dev = info->dev;
225
        if (dev)
226
        {
227
            DEBUG(1,"kfree...\n");
228
            free_netdev(dev);
229
        }
230
        DEBUG(1,"kfree2...\n");
231
        kfree(info);
232
    }
233
 
234
} /* com20020_detach */
235
 
236
/*======================================================================
237
 
238
    com20020_config() is scheduled to run after a CARD_INSERTION event
239
    is received, to configure the PCMCIA socket, and to make the
240
    device available to the system.
241
 
242
======================================================================*/
243
 
244
#define CS_CHECK(fn, ret) \
245
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
246
 
247
static int com20020_config(struct pcmcia_device *link)
248
{
249
    struct arcnet_local *lp;
250
    com20020_dev_t *info;
251
    struct net_device *dev;
252
    int i, last_ret, last_fn;
253
    int ioaddr;
254
 
255
    info = link->priv;
256
    dev = info->dev;
257
 
258
    DEBUG(1,"config...\n");
259
 
260
    DEBUG(0, "com20020_config(0x%p)\n", link);
261
 
262
    DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
263
    i = !CS_SUCCESS;
264
    if (!link->io.BasePort1)
265
    {
266
        for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
267
        {
268
            link->io.BasePort1 = ioaddr;
269
            i = pcmcia_request_io(link, &link->io);
270
            if (i == CS_SUCCESS)
271
                break;
272
        }
273
    }
274
    else
275
        i = pcmcia_request_io(link, &link->io);
276
 
277
    if (i != CS_SUCCESS)
278
    {
279
        DEBUG(1,"arcnet: requestIO failed totally!\n");
280
        goto failed;
281
    }
282
 
283
    ioaddr = dev->base_addr = link->io.BasePort1;
284
    DEBUG(1,"arcnet: got ioaddr %Xh\n", ioaddr);
285
 
286
    DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n",
287
           link->irq.AssignedIRQ,
288
           link->irq.IRQInfo1, link->irq.IRQInfo2);
289
    i = pcmcia_request_irq(link, &link->irq);
290
    if (i != CS_SUCCESS)
291
    {
292
        DEBUG(1,"arcnet: requestIRQ failed totally!\n");
293
        goto failed;
294
    }
295
 
296
    dev->irq = link->irq.AssignedIRQ;
297
 
298
    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
299
 
300
    if (com20020_check(dev))
301
    {
302
        regdump(dev);
303
        goto failed;
304
    }
305
 
306
    lp = dev->priv;
307
    lp->card_name = "PCMCIA COM20020";
308
    lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
309
 
310
    link->dev_node = &info->node;
311
    SET_NETDEV_DEV(dev, &handle_to_dev(link));
312
 
313
    i = com20020_found(dev, 0);  /* calls register_netdev */
314
 
315
    if (i != 0) {
316
        DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
317
        link->dev_node = NULL;
318
        goto failed;
319
    }
320
 
321
    strcpy(info->node.dev_name, dev->name);
322
 
323
    DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n",
324
           dev->name, dev->base_addr, dev->irq);
325
    return 0;
326
 
327
cs_failed:
328
    cs_error(link, last_fn, last_ret);
329
failed:
330
    DEBUG(1,"com20020_config failed...\n");
331
    com20020_release(link);
332
    return -ENODEV;
333
} /* com20020_config */
334
 
335
/*======================================================================
336
 
337
    After a card is removed, com20020_release() will unregister the net
338
    device, and release the PCMCIA configuration.  If the device is
339
    still open, this will be postponed until it is closed.
340
 
341
======================================================================*/
342
 
343
static void com20020_release(struct pcmcia_device *link)
344
{
345
        DEBUG(0, "com20020_release(0x%p)\n", link);
346
        pcmcia_disable_device(link);
347
}
348
 
349
static int com20020_suspend(struct pcmcia_device *link)
350
{
351
        com20020_dev_t *info = link->priv;
352
        struct net_device *dev = info->dev;
353
 
354
        if (link->open)
355
                netif_device_detach(dev);
356
 
357
        return 0;
358
}
359
 
360
static int com20020_resume(struct pcmcia_device *link)
361
{
362
        com20020_dev_t *info = link->priv;
363
        struct net_device *dev = info->dev;
364
 
365
        if (link->open) {
366
                int ioaddr = dev->base_addr;
367
                struct arcnet_local *lp = dev->priv;
368
                ARCRESET;
369
        }
370
 
371
        return 0;
372
}
373
 
374
static struct pcmcia_device_id com20020_ids[] = {
375
        PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.",
376
                        "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
377
        PCMCIA_DEVICE_PROD_ID12("SoHard AG",
378
                        "SH ARC PCMCIA", 0xf8991729, 0x69dff0c7),
379
        PCMCIA_DEVICE_NULL
380
};
381
MODULE_DEVICE_TABLE(pcmcia, com20020_ids);
382
 
383
static struct pcmcia_driver com20020_cs_driver = {
384
        .owner          = THIS_MODULE,
385
        .drv            = {
386
                .name   = "com20020_cs",
387
        },
388
        .probe          = com20020_probe,
389
        .remove         = com20020_detach,
390
        .id_table       = com20020_ids,
391
        .suspend        = com20020_suspend,
392
        .resume         = com20020_resume,
393
};
394
 
395
static int __init init_com20020_cs(void)
396
{
397
        return pcmcia_register_driver(&com20020_cs_driver);
398
}
399
 
400
static void __exit exit_com20020_cs(void)
401
{
402
        pcmcia_unregister_driver(&com20020_cs_driver);
403
}
404
 
405
module_init(init_com20020_cs);
406
module_exit(exit_com20020_cs);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.