Version:  2.0.40 2.2.26 2.4.37 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8

Linux/drivers/net/arcnet/com20020_cs.c

  1 /*
  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 
 35 #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
 36 
 37 #include <linux/kernel.h>
 38 #include <linux/ptrace.h>
 39 #include <linux/slab.h>
 40 #include <linux/string.h>
 41 #include <linux/timer.h>
 42 #include <linux/delay.h>
 43 #include <linux/module.h>
 44 #include <linux/netdevice.h>
 45 #include <linux/io.h>
 46 #include <pcmcia/cistpl.h>
 47 #include <pcmcia/ds.h>
 48 
 49 #include "arcdevice.h"
 50 #include "com20020.h"
 51 
 52 static void regdump(struct net_device *dev)
 53 {
 54 #ifdef DEBUG
 55         int ioaddr = dev->base_addr;
 56         int count;
 57 
 58         netdev_dbg(dev, "register dump:\n");
 59         for (count = 0; count < 16; count++) {
 60                 if (!(count % 16))
 61                         pr_cont("%04X:", ioaddr + count);
 62                 pr_cont(" %02X", arcnet_inb(ioaddr, count));
 63         }
 64         pr_cont("\n");
 65 
 66         netdev_dbg(dev, "buffer0 dump:\n");
 67         /* set up the address register */
 68         count = 0;
 69         arcnet_outb((count >> 8) | RDDATAflag | AUTOINCflag,
 70                     ioaddr, com20020_REG_W_ADDR_HI);
 71         arcnet_outb(count & 0xff, ioaddr, COM20020_REG_W_ADDR_LO);
 72 
 73         for (count = 0; count < 256 + 32; count++) {
 74                 if (!(count % 16))
 75                         pr_cont("%04X:", count);
 76 
 77                 /* copy the data */
 78                 pr_cont(" %02X", arcnet_inb(ioaddr, COM20020_REG_RW_MEMDATA));
 79         }
 80         pr_cont("\n");
 81 #endif
 82 }
 83 
 84 /*====================================================================*/
 85 
 86 /* Parameters that can be set with 'insmod' */
 87 
 88 static int node;
 89 static int timeout = 3;
 90 static int backplane;
 91 static int clockp;
 92 static int clockm;
 93 
 94 module_param(node, int, 0);
 95 module_param(timeout, int, 0);
 96 module_param(backplane, int, 0);
 97 module_param(clockp, int, 0);
 98 module_param(clockm, int, 0);
 99 
100 MODULE_LICENSE("GPL");
101 
102 /*====================================================================*/
103 
104 static int com20020_config(struct pcmcia_device *link);
105 static void com20020_release(struct pcmcia_device *link);
106 
107 static void com20020_detach(struct pcmcia_device *p_dev);
108 
109 /*====================================================================*/
110 
111 static int com20020_probe(struct pcmcia_device *p_dev)
112 {
113         struct com20020_dev *info;
114         struct net_device *dev;
115         struct arcnet_local *lp;
116 
117         dev_dbg(&p_dev->dev, "com20020_attach()\n");
118 
119         /* Create new network device */
120         info = kzalloc(sizeof(*info), GFP_KERNEL);
121         if (!info)
122                 goto fail_alloc_info;
123 
124         dev = alloc_arcdev("");
125         if (!dev)
126                 goto fail_alloc_dev;
127 
128         lp = netdev_priv(dev);
129         lp->timeout = timeout;
130         lp->backplane = backplane;
131         lp->clockp = clockp;
132         lp->clockm = clockm & 3;
133         lp->hw.owner = THIS_MODULE;
134 
135         /* fill in our module parameters as defaults */
136         dev->dev_addr[0] = node;
137 
138         p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
139         p_dev->resource[0]->end = 16;
140         p_dev->config_flags |= CONF_ENABLE_IRQ;
141 
142         info->dev = dev;
143         p_dev->priv = info;
144 
145         return com20020_config(p_dev);
146 
147 fail_alloc_dev:
148         kfree(info);
149 fail_alloc_info:
150         return -ENOMEM;
151 } /* com20020_attach */
152 
153 static void com20020_detach(struct pcmcia_device *link)
154 {
155         struct com20020_dev *info = link->priv;
156         struct net_device *dev = info->dev;
157 
158         dev_dbg(&link->dev, "detach...\n");
159 
160         dev_dbg(&link->dev, "com20020_detach\n");
161 
162         dev_dbg(&link->dev, "unregister...\n");
163 
164         unregister_netdev(dev);
165 
166         /* this is necessary because we register our IRQ separately
167          * from card services.
168          */
169         if (dev->irq)
170                 free_irq(dev->irq, dev);
171 
172         com20020_release(link);
173 
174         /* Unlink device structure, free bits */
175         dev_dbg(&link->dev, "unlinking...\n");
176         if (link->priv) {
177                 dev = info->dev;
178                 if (dev) {
179                         dev_dbg(&link->dev, "kfree...\n");
180                         free_netdev(dev);
181                 }
182                 dev_dbg(&link->dev, "kfree2...\n");
183                 kfree(info);
184         }
185 
186 } /* com20020_detach */
187 
188 static int com20020_config(struct pcmcia_device *link)
189 {
190         struct arcnet_local *lp;
191         struct com20020_dev *info;
192         struct net_device *dev;
193         int i, ret;
194         int ioaddr;
195 
196         info = link->priv;
197         dev = info->dev;
198 
199         dev_dbg(&link->dev, "config...\n");
200 
201         dev_dbg(&link->dev, "com20020_config\n");
202 
203         dev_dbg(&link->dev, "baseport1 is %Xh\n",
204                 (unsigned int)link->resource[0]->start);
205 
206         i = -ENODEV;
207         link->io_lines = 16;
208 
209         if (!link->resource[0]->start) {
210                 for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10) {
211                         link->resource[0]->start = ioaddr;
212                         i = pcmcia_request_io(link);
213                         if (i == 0)
214                                 break;
215                 }
216         } else {
217                 i = pcmcia_request_io(link);
218         }
219 
220         if (i != 0) {
221                 dev_dbg(&link->dev, "requestIO failed totally!\n");
222                 goto failed;
223         }
224 
225         ioaddr = dev->base_addr = link->resource[0]->start;
226         dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
227 
228         dev_dbg(&link->dev, "request IRQ %d\n",
229                 link->irq);
230         if (!link->irq) {
231                 dev_dbg(&link->dev, "requestIRQ failed totally!\n");
232                 goto failed;
233         }
234 
235         dev->irq = link->irq;
236 
237         ret = pcmcia_enable_device(link);
238         if (ret)
239                 goto failed;
240 
241         if (com20020_check(dev)) {
242                 regdump(dev);
243                 goto failed;
244         }
245 
246         lp = netdev_priv(dev);
247         lp->card_name = "PCMCIA COM20020";
248         lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
249 
250         SET_NETDEV_DEV(dev, &link->dev);
251 
252         i = com20020_found(dev, 0);     /* calls register_netdev */
253 
254         if (i != 0) {
255                 dev_notice(&link->dev,
256                            "com20020_found() failed\n");
257                 goto failed;
258         }
259 
260         netdev_dbg(dev, "port %#3lx, irq %d\n",
261                    dev->base_addr, dev->irq);
262         return 0;
263 
264 failed:
265         dev_dbg(&link->dev, "com20020_config failed...\n");
266         com20020_release(link);
267         return -ENODEV;
268 } /* com20020_config */
269 
270 static void com20020_release(struct pcmcia_device *link)
271 {
272         dev_dbg(&link->dev, "com20020_release\n");
273         pcmcia_disable_device(link);
274 }
275 
276 static int com20020_suspend(struct pcmcia_device *link)
277 {
278         struct com20020_dev *info = link->priv;
279         struct net_device *dev = info->dev;
280 
281         if (link->open)
282                 netif_device_detach(dev);
283 
284         return 0;
285 }
286 
287 static int com20020_resume(struct pcmcia_device *link)
288 {
289         struct com20020_dev *info = link->priv;
290         struct net_device *dev = info->dev;
291 
292         if (link->open) {
293                 int ioaddr = dev->base_addr;
294                 struct arcnet_local *lp = netdev_priv(dev);
295 
296                 arcnet_outb(lp->config | 0x80, ioaddr, COM20020_REG_W_CONFIG);
297                 udelay(5);
298                 arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
299         }
300 
301         return 0;
302 }
303 
304 static const struct pcmcia_device_id com20020_ids[] = {
305         PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.",
306                                 "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
307         PCMCIA_DEVICE_PROD_ID12("SoHard AG",
308                                 "SH ARC PCMCIA", 0xf8991729, 0x69dff0c7),
309         PCMCIA_DEVICE_NULL
310 };
311 MODULE_DEVICE_TABLE(pcmcia, com20020_ids);
312 
313 static struct pcmcia_driver com20020_cs_driver = {
314         .owner          = THIS_MODULE,
315         .name           = "com20020_cs",
316         .probe          = com20020_probe,
317         .remove         = com20020_detach,
318         .id_table       = com20020_ids,
319         .suspend        = com20020_suspend,
320         .resume         = com20020_resume,
321 };
322 module_pcmcia_driver(com20020_cs_driver);
323 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us