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