Version:  2.6.34 2.6.35 2.6.36 2.6.37 2.6.38 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14

Linux/drivers/staging/sbe-2t3e3/module.c

  1 /*
  2  * SBE 2T3E3 synchronous serial card driver for Linux
  3  *
  4  * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
  5  *
  6  * This program is free software; you can redistribute it and/or modify it
  7  * under the terms of version 2 of the GNU General Public License
  8  * as published by the Free Software Foundation.
  9  *
 10  * This code is based on a driver written by SBE Inc.
 11  */
 12 
 13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 14 
 15 #include <linux/module.h>
 16 #include <linux/slab.h>
 17 #include <linux/delay.h>
 18 #include <linux/netdevice.h>
 19 #include <linux/pci.h>
 20 #include <linux/hdlc.h>
 21 #include <linux/if_arp.h>
 22 #include <linux/interrupt.h>
 23 #include "2t3e3.h"
 24 
 25 static void check_leds(unsigned long arg)
 26 {
 27         struct card *card = (struct card *)arg;
 28         struct channel *channel0 = &card->channels[0];
 29         static int blinker;
 30 
 31         update_led(channel0, ++blinker);
 32         if (has_two_ports(channel0->pdev))
 33                 update_led(&card->channels[1], blinker);
 34 
 35         card->timer.expires = jiffies + HZ / 10;
 36         add_timer(&card->timer);
 37 }
 38 
 39 static void t3e3_remove_channel(struct channel *channel)
 40 {
 41         struct pci_dev *pdev = channel->pdev;
 42         struct net_device *dev = channel->dev;
 43 
 44         /* system hangs if board asserts irq while module is unloaded */
 45         cpld_stop_intr(channel);
 46         free_irq(dev->irq, dev);
 47         dc_drop_descriptor_list(channel);
 48         unregister_hdlc_device(dev);
 49         free_netdev(dev);
 50         pci_release_regions(pdev);
 51         pci_disable_device(pdev);
 52         pci_set_drvdata(pdev, NULL);
 53 }
 54 
 55 static int t3e3_init_channel(struct channel *channel, struct pci_dev *pdev, struct card *card)
 56 {
 57         struct net_device *dev;
 58         unsigned int val;
 59         int err;
 60 
 61         err = pci_enable_device(pdev);
 62         if (err)
 63                 return err;
 64 
 65         err = pci_request_regions(pdev, "SBE 2T3E3");
 66         if (err)
 67                 goto disable;
 68 
 69         dev = alloc_hdlcdev(channel);
 70         if (!dev) {
 71                 pr_err("Out of memory\n");
 72                 err = -ENOMEM;
 73                 goto free_regions;
 74         }
 75 
 76         t3e3_sc_init(channel);
 77         dev_to_priv(dev) = channel;
 78 
 79         channel->pdev = pdev;
 80         channel->dev = dev;
 81         channel->card = card;
 82         channel->addr = pci_resource_start(pdev, 0);
 83         if (pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P1)
 84                 channel->h.slot = 1;
 85         else
 86                 channel->h.slot = 0;
 87 
 88         err = setup_device(dev, channel);
 89         if (err)
 90                 goto free_dev;
 91 
 92         pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */
 93         pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFFFFFF);
 94 
 95         pci_read_config_byte(channel->pdev, PCI_CACHE_LINE_SIZE, &channel->h.cache_size);
 96         pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command);
 97         t3e3_init(channel);
 98 
 99         err = request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev);
100         if (err) {
101                 netdev_warn(channel->dev, "%s: could not get irq: %d\n",
102                             dev->name, dev->irq);
103                 goto unregister_dev;
104         }
105 
106         pci_set_drvdata(pdev, channel);
107         return 0;
108 
109 unregister_dev:
110         unregister_hdlc_device(dev);
111 free_dev:
112         free_netdev(dev);
113 free_regions:
114         pci_release_regions(pdev);
115 disable:
116         pci_disable_device(pdev);
117         return err;
118 }
119 
120 static void t3e3_remove_card(struct pci_dev *pdev)
121 {
122         struct channel *channel0 = pci_get_drvdata(pdev);
123         struct card *card = channel0->card;
124 
125         del_timer(&card->timer);
126         if (has_two_ports(channel0->pdev)) {
127                 t3e3_remove_channel(&card->channels[1]);
128                 pci_dev_put(card->channels[1].pdev);
129         }
130         t3e3_remove_channel(channel0);
131         kfree(card);
132 }
133 
134 static int t3e3_init_card(struct pci_dev *pdev, const struct pci_device_id *ent)
135 {
136         /* pdev points to channel #0 */
137         struct pci_dev *pdev1 = NULL;
138         struct card *card;
139         int channels = 1, err;
140 
141         if (has_two_ports(pdev)) {
142                 while ((pdev1 = pci_get_subsys(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
143                                                PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P1,
144                                                pdev1)))
145                         if (pdev1->bus == pdev->bus &&
146                             pdev1->devfn == pdev->devfn + 8 /* next device on the same bus */)
147                                 break; /* found the second channel */
148 
149                 if (!pdev1) {
150                         dev_err(&pdev->dev, "Can't find the second channel\n");
151                         return -EFAULT;
152                 }
153                 channels = 2;
154                 /* holds the reference for pdev1 */
155         }
156 
157         card = kzalloc(sizeof(struct card) + channels * sizeof(struct channel),
158                        GFP_KERNEL);
159         if (!card)
160                 return -ENOBUFS;
161 
162         spin_lock_init(&card->bootrom_lock);
163         card->bootrom_addr = pci_resource_start(pdev, 0);
164 
165         err = t3e3_init_channel(&card->channels[0], pdev, card);
166         if (err)
167                 goto free_card;
168 
169         if (channels == 2) {
170                 err = t3e3_init_channel(&card->channels[1], pdev1, card);
171                 if (err) {
172                         t3e3_remove_channel(&card->channels[0]);
173                         goto free_card;
174                 }
175         }
176 
177         /* start LED timer */
178         init_timer(&card->timer);
179         card->timer.function = check_leds;
180         card->timer.expires = jiffies + HZ / 10;
181         card->timer.data = (unsigned long)card;
182         add_timer(&card->timer);
183         return 0;
184 
185 free_card:
186         kfree(card);
187         return err;
188 }
189 
190 static struct pci_device_id t3e3_pci_tbl[] = {
191         { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
192           PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_T3E3, 0, 0, 0 },
193         { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
194           PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P0, 0, 0, 0 },
195         /* channel 1 will be initialized after channel 0 */
196         { 0, }
197 };
198 
199 static struct pci_driver t3e3_pci_driver = {
200         .name     = "SBE T3E3",
201         .id_table = t3e3_pci_tbl,
202         .probe    = t3e3_init_card,
203         .remove   = t3e3_remove_card,
204 };
205 
206 module_pci_driver(t3e3_pci_driver);
207 MODULE_LICENSE("GPL");
208 MODULE_DEVICE_TABLE(pci, t3e3_pci_tbl);
209 

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