1/* $Id: t1pci.c,v 1.1.1.1 2008/10/15 03:26:33 james26_jang Exp $ 2 * 3 * Module for AVM T1 PCI-card. 4 * 5 * Copyright 1999 by Carsten Paeth <calle@calle.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/config.h> 13#include <linux/module.h> 14#include <linux/kernel.h> 15#include <linux/skbuff.h> 16#include <linux/delay.h> 17#include <linux/mm.h> 18#include <linux/interrupt.h> 19#include <linux/ioport.h> 20#include <linux/pci.h> 21#include <linux/capi.h> 22#include <linux/init.h> 23#include <asm/io.h> 24#include "capicmd.h" 25#include "capiutil.h" 26#include "capilli.h" 27#include "avmcard.h" 28 29static char *revision = "$Revision: 1.1.1.1 $"; 30 31#undef CONFIG_T1PCI_DEBUG 32#undef CONFIG_T1PCI_POLLDEBUG 33 34/* ------------------------------------------------------------- */ 35 36static struct pci_device_id t1pci_pci_tbl[] __initdata = { 37 { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, PCI_ANY_ID, PCI_ANY_ID }, 38 { } /* Terminating entry */ 39}; 40 41MODULE_DEVICE_TABLE(pci, t1pci_pci_tbl); 42MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 PCI card"); 43MODULE_AUTHOR("Carsten Paeth"); 44MODULE_LICENSE("GPL"); 45 46/* ------------------------------------------------------------- */ 47 48static struct capi_driver_interface *di; 49 50/* ------------------------------------------------------------- */ 51 52static void t1pci_remove_ctr(struct capi_ctr *ctrl) 53{ 54 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 55 avmcard *card = cinfo->card; 56 57 b1dma_reset(card); 58 59 di->detach_ctr(ctrl); 60 free_irq(card->irq, card); 61 iounmap(card->mbase); 62 release_region(card->port, AVMB1_PORTLEN); 63 ctrl->driverdata = 0; 64 kfree(card->ctrlinfo); 65 kfree(card->dma); 66 kfree(card); 67 68 MOD_DEC_USE_COUNT; 69} 70 71/* ------------------------------------------------------------- */ 72 73static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p) 74{ 75 avmcard *card; 76 avmctrl_info *cinfo; 77 int retval; 78 79 MOD_INC_USE_COUNT; 80 81 card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); 82 83 if (!card) { 84 printk(KERN_WARNING "%s: no memory.\n", driver->name); 85 MOD_DEC_USE_COUNT; 86 return -ENOMEM; 87 } 88 memset(card, 0, sizeof(avmcard)); 89 card->dma = (avmcard_dmainfo *) kmalloc(sizeof(avmcard_dmainfo), GFP_ATOMIC); 90 if (!card->dma) { 91 printk(KERN_WARNING "%s: no memory.\n", driver->name); 92 kfree(card); 93 MOD_DEC_USE_COUNT; 94 return -ENOMEM; 95 } 96 memset(card->dma, 0, sizeof(avmcard_dmainfo)); 97 cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC); 98 if (!cinfo) { 99 printk(KERN_WARNING "%s: no memory.\n", driver->name); 100 kfree(card->dma); 101 kfree(card); 102 MOD_DEC_USE_COUNT; 103 return -ENOMEM; 104 } 105 memset(cinfo, 0, sizeof(avmctrl_info)); 106 card->ctrlinfo = cinfo; 107 cinfo->card = card; 108 sprintf(card->name, "t1pci-%x", p->port); 109 card->port = p->port; 110 card->irq = p->irq; 111 card->membase = p->membase; 112 card->cardtype = avm_t1pci; 113 114 if (check_region(card->port, AVMB1_PORTLEN)) { 115 printk(KERN_WARNING 116 "%s: ports 0x%03x-0x%03x in use.\n", 117 driver->name, card->port, card->port + AVMB1_PORTLEN); 118 kfree(card->ctrlinfo); 119 kfree(card->dma); 120 kfree(card); 121 MOD_DEC_USE_COUNT; 122 return -EBUSY; 123 } 124 125 card->mbase = ioremap_nocache(card->membase, 64); 126 if (!card->mbase) { 127 printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n", 128 driver->name, card->membase); 129 kfree(card->ctrlinfo); 130 kfree(card->dma); 131 kfree(card); 132 MOD_DEC_USE_COUNT; 133 return -EIO; 134 } 135 136 b1dma_reset(card); 137 138 if ((retval = t1pci_detect(card)) != 0) { 139 if (retval < 6) 140 printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n", 141 driver->name, card->port, retval); 142 else 143 printk(KERN_NOTICE "%s: card at 0x%x, but cabel not connected or T1 has no power (%d)\n", 144 driver->name, card->port, retval); 145 iounmap(card->mbase); 146 kfree(card->ctrlinfo); 147 kfree(card->dma); 148 kfree(card); 149 MOD_DEC_USE_COUNT; 150 return -EIO; 151 } 152 b1dma_reset(card); 153 154 request_region(p->port, AVMB1_PORTLEN, card->name); 155 156 retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card); 157 if (retval) { 158 printk(KERN_ERR "%s: unable to get IRQ %d.\n", 159 driver->name, card->irq); 160 iounmap(card->mbase); 161 release_region(card->port, AVMB1_PORTLEN); 162 kfree(card->ctrlinfo); 163 kfree(card->dma); 164 kfree(card); 165 MOD_DEC_USE_COUNT; 166 return -EBUSY; 167 } 168 169 cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); 170 if (!cinfo->capi_ctrl) { 171 printk(KERN_ERR "%s: attach controller failed.\n", driver->name); 172 iounmap(card->mbase); 173 free_irq(card->irq, card); 174 release_region(card->port, AVMB1_PORTLEN); 175 kfree(card->ctrlinfo); 176 kfree(card->dma); 177 kfree(card); 178 MOD_DEC_USE_COUNT; 179 return -EBUSY; 180 } 181 card->cardnr = cinfo->capi_ctrl->cnr; 182 183 skb_queue_head_init(&card->dma->send_queue); 184 185 printk(KERN_INFO 186 "%s: AVM T1 PCI at i/o %#x, irq %d, mem %#lx\n", 187 driver->name, card->port, card->irq, card->membase); 188 189 return 0; 190} 191 192/* ------------------------------------------------------------- */ 193 194static char *t1pci_procinfo(struct capi_ctr *ctrl) 195{ 196 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 197 198 if (!cinfo) 199 return ""; 200 sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx", 201 cinfo->cardname[0] ? cinfo->cardname : "-", 202 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", 203 cinfo->card ? cinfo->card->port : 0x0, 204 cinfo->card ? cinfo->card->irq : 0, 205 cinfo->card ? cinfo->card->membase : 0 206 ); 207 return cinfo->infobuf; 208} 209 210/* ------------------------------------------------------------- */ 211 212static struct capi_driver t1pci_driver = { 213 name: "t1pci", 214 revision: "0.0", 215 load_firmware: b1dma_load_firmware, 216 reset_ctr: b1dma_reset_ctr, 217 remove_ctr: t1pci_remove_ctr, 218 register_appl: b1dma_register_appl, 219 release_appl: b1dma_release_appl, 220 send_message: b1dma_send_message, 221 222 procinfo: t1pci_procinfo, 223 ctr_read_proc: b1dmactl_read_proc, 224 driver_read_proc: 0, /* use standard driver_read_proc */ 225 226 add_card: 0, /* no add_card function */ 227}; 228 229static int ncards = 0; 230 231static int __init t1pci_init(void) 232{ 233 struct capi_driver *driver = &t1pci_driver; 234 struct pci_dev *dev = NULL; 235 char *p; 236 int retval; 237 238 MOD_INC_USE_COUNT; 239 240 if ((p = strchr(revision, ':')) != 0 && p[1]) { 241 strncpy(driver->revision, p + 2, sizeof(driver->revision)); 242 driver->revision[sizeof(driver->revision)-1] = 0; 243 if ((p = strchr(driver->revision, '$')) != 0 && p > driver->revision) 244 *(p-1) = 0; 245 } 246 247 printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); 248 249 di = attach_capi_driver(driver); 250 if (!di) { 251 printk(KERN_ERR "%s: failed to attach capi_driver\n", 252 driver->name); 253 MOD_DEC_USE_COUNT; 254 return -EIO; 255 } 256 257 while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, dev))) { 258 struct capicardparams param; 259 260 if (pci_enable_device(dev) < 0) { 261 printk(KERN_ERR "%s: failed to enable AVM-T1-PCI\n", 262 driver->name); 263 continue; 264 } 265 pci_set_master(dev); 266 267 param.port = pci_resource_start(dev, 1); 268 param.irq = dev->irq; 269 param.membase = pci_resource_start(dev, 0); 270 271 printk(KERN_INFO 272 "%s: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n", 273 driver->name, param.port, param.irq, param.membase); 274 retval = t1pci_add_card(driver, ¶m); 275 if (retval != 0) { 276 printk(KERN_ERR 277 "%s: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n", 278 driver->name, param.port, param.irq, param.membase); 279 continue; 280 } 281 ncards++; 282 } 283 if (ncards) { 284 printk(KERN_INFO "%s: %d T1-PCI card(s) detected\n", 285 driver->name, ncards); 286 MOD_DEC_USE_COUNT; 287 return 0; 288 } 289 printk(KERN_ERR "%s: NO T1-PCI card detected\n", driver->name); 290 detach_capi_driver(&t1pci_driver); 291 MOD_DEC_USE_COUNT; 292 return -ENODEV; 293} 294 295static void __exit t1pci_exit(void) 296{ 297 detach_capi_driver(&t1pci_driver); 298} 299 300module_init(t1pci_init); 301module_exit(t1pci_exit); 302