^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * speedfax.c low level stuff for Sedlbauer Speedfax+ cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * based on the ISAR DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Thanks to Sedlbauer AG for informations and HW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author Karsten Keil <keil@isdn4linux.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mISDNhw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "ipac.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "isar.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define SPEEDFAX_REV "2.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define PCI_SUBVENDOR_SPEEDFAX_PYRAMID 0x51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define PCI_SUBVENDOR_SPEEDFAX_PCI 0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define PCI_SUB_ID_SEDLBAUER 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define SFAX_PCI_ADDR 0xc8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SFAX_PCI_ISAC 0xd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define SFAX_PCI_ISAR 0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* TIGER 100 Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define TIGER_RESET_ADDR 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define TIGER_EXTERN_RESET_ON 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define TIGER_EXTERN_RESET_OFF 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define TIGER_AUX_CTRL 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define TIGER_AUX_DATA 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define TIGER_AUX_IRQMASK 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define TIGER_AUX_STATUS 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* Tiger AUX BITs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define SFAX_AUX_IOMASK 0xdd /* 1 and 5 are inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SFAX_ISAR_RESET_BIT_OFF 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SFAX_ISAR_RESET_BIT_ON 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define SFAX_TIGER_IRQ_BIT 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SFAX_LED1_BIT 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define SFAX_LED2_BIT 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define SFAX_PCI_RESET_ON (SFAX_ISAR_RESET_BIT_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define SFAX_PCI_RESET_OFF (SFAX_LED1_BIT | SFAX_LED2_BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int sfax_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static u32 debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static u32 irqloops = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct sfax_hw {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) char name[MISDN_MAX_IDLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u32 irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u32 irqcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u32 cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct _ioport p_isac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct _ioport p_isar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) u8 aux_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) spinlock_t lock; /* HW access lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct isac_hw isac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct isar_hw isar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static LIST_HEAD(Cards);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static DEFINE_RWLOCK(card_lock); /* protect Cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) _set_debug(struct sfax_hw *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) card->isac.dch.debug = debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) card->isar.ch[0].bch.debug = debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) card->isar.ch[1].bch.debug = debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) set_debug(const char *val, const struct kernel_param *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct sfax_hw *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ret = param_set_uint(val, kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) read_lock(&card_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) list_for_each_entry(card, &Cards, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) _set_debug(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) read_unlock(&card_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) MODULE_AUTHOR("Karsten Keil");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) MODULE_VERSION(SPEEDFAX_REV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) MODULE_FIRMWARE("isdn/ISAR.BIN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) MODULE_PARM_DESC(debug, "Speedfax debug mask");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) module_param(irqloops, uint, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) IOFUNC_IND(ISAC, sfax_hw, p_isac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) IOFUNC_IND(ISAR, sfax_hw, p_isar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) speedfax_irq(int intno, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct sfax_hw *sf = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int cnt = irqloops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) spin_lock(&sf->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) val = inb(sf->cfg + TIGER_AUX_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (val & SFAX_TIGER_IRQ_BIT) { /* for us or shared ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) spin_unlock(&sf->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return IRQ_NONE; /* shared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) sf->irqcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) val = ReadISAR_IND(sf, ISAR_IRQBIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) Start_ISAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (val & ISAR_IRQSTA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) mISDNisar_irq(&sf->isar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) val = ReadISAC_IND(sf, ISAC_ISTA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) mISDNisac_irq(&sf->isac, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) val = ReadISAR_IND(sf, ISAR_IRQBIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if ((val & ISAR_IRQSTA) && cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) goto Start_ISAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (cnt < irqloops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) pr_debug("%s: %d irqloops cpu%d\n", sf->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) irqloops - cnt, smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (irqloops && !cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) irqloops, smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) spin_unlock(&sf->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) enable_hwirq(struct sfax_hw *sf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) WriteISAC_IND(sf, ISAC_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) WriteISAR_IND(sf, ISAR_IRQBIT, ISAR_IRQMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) outb(SFAX_TIGER_IRQ_BIT, sf->cfg + TIGER_AUX_IRQMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) disable_hwirq(struct sfax_hw *sf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) WriteISAC_IND(sf, ISAC_MASK, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) WriteISAR_IND(sf, ISAR_IRQBIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) outb(0, sf->cfg + TIGER_AUX_IRQMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) reset_speedfax(struct sfax_hw *sf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) pr_debug("%s: resetting card\n", sf->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) outb(TIGER_EXTERN_RESET_ON, sf->cfg + TIGER_RESET_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) outb(SFAX_PCI_RESET_ON, sf->cfg + TIGER_AUX_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) outb(TIGER_EXTERN_RESET_OFF, sf->cfg + TIGER_RESET_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) sf->aux_data = SFAX_PCI_RESET_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) sfax_ctrl(struct sfax_hw *sf, u32 cmd, u_long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case HW_RESET_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) reset_speedfax(sf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case HW_ACTIVATE_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (arg & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) sf->aux_data &= ~SFAX_LED1_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (arg & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) sf->aux_data &= ~SFAX_LED2_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case HW_DEACT_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (arg & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) sf->aux_data |= SFAX_LED1_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (arg & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) sf->aux_data |= SFAX_LED2_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) pr_info("%s: %s unknown command %x %lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) sf->name, __func__, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) channel_ctrl(struct sfax_hw *sf, struct mISDN_ctrl_req *cq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) switch (cq->op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case MISDN_CTRL_GETOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case MISDN_CTRL_LOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (cq->channel < 0 || cq->channel > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ret = sf->isac.ctrl(&sf->isac, HW_TESTLOOP, cq->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) case MISDN_CTRL_L1_TIMER3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = sf->isac.ctrl(&sf->isac, HW_TIMER3_VALUE, cq->p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) pr_info("%s: unknown Op %x\n", sf->name, cq->op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct dchannel *dch = container_of(dev, struct dchannel, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct sfax_hw *sf = dch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct channel_req *rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) pr_debug("%s: cmd:%x %p\n", sf->name, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case OPEN_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) rq = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (rq->protocol == ISDN_P_TE_S0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) err = sf->isac.open(&sf->isac, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) err = sf->isar.open(&sf->isar, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (!try_module_get(THIS_MODULE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) pr_info("%s: cannot get module\n", sf->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case CLOSE_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) pr_debug("%s: dev(%d) close from %p\n", sf->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dch->dev.id, __builtin_return_address(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case CONTROL_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) err = channel_ctrl(sf, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) pr_debug("%s: unknown command %x\n", sf->name, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) init_card(struct sfax_hw *sf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int ret, cnt = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ret = request_irq(sf->irq, speedfax_irq, IRQF_SHARED, sf->name, sf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) pr_info("%s: couldn't get interrupt %d\n", sf->name, sf->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) while (cnt--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) spin_lock_irqsave(&sf->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ret = sf->isac.init(&sf->isac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) spin_unlock_irqrestore(&sf->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) pr_info("%s: ISAC init failed with %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) sf->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) enable_hwirq(sf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* RESET Receiver and Transmitter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) WriteISAC_IND(sf, ISAC_CMDR, 0x41);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) spin_unlock_irqrestore(&sf->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) msleep_interruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (debug & DEBUG_HW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) pr_notice("%s: IRQ %d count %d\n", sf->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sf->irq, sf->irqcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!sf->irqcnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) pr_info("%s: IRQ(%d) got no requests during init %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) sf->name, sf->irq, 3 - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) free_irq(sf->irq, sf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) setup_speedfax(struct sfax_hw *sf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (!request_region(sf->cfg, 256, sf->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) pr_info("mISDN: %s config port %x-%x already in use\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) sf->name, sf->cfg, sf->cfg + 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) outb(0xff, sf->cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) outb(0, sf->cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) outb(0xdd, sf->cfg + TIGER_AUX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) outb(0, sf->cfg + TIGER_AUX_IRQMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) sf->isac.type = IPAC_TYPE_ISAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ASSIGN_FUNC(IND, ISAC, sf->isac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ASSIGN_FUNC(IND, ISAR, sf->isar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) spin_lock_irqsave(&sf->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) reset_speedfax(sf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) disable_hwirq(sf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) spin_unlock_irqrestore(&sf->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) release_card(struct sfax_hw *card) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) spin_lock_irqsave(&card->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) disable_hwirq(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) spin_unlock_irqrestore(&card->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) card->isac.release(&card->isac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) free_irq(card->irq, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) card->isar.release(&card->isar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) mISDN_unregister_device(&card->isac.dch.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) release_region(card->cfg, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) pci_disable_device(card->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) pci_set_drvdata(card->pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) write_lock_irqsave(&card_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) list_del(&card->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) write_unlock_irqrestore(&card_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) kfree(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) sfax_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) setup_instance(struct sfax_hw *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) const struct firmware *firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) write_lock_irqsave(&card_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) list_add_tail(&card->list, &Cards);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) write_unlock_irqrestore(&card_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) _set_debug(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) spin_lock_init(&card->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) card->isac.hwlock = &card->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) card->isar.hwlock = &card->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) card->isar.ctrl = (void *)&sfax_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) card->isac.name = card->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) card->isar.name = card->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) card->isar.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) pr_info("%s: firmware request failed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) card->name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) goto error_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (debug & DEBUG_HW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) pr_notice("%s: got firmware %zu bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) card->name, firmware->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) mISDNisac_init(&card->isac, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) card->isac.dch.dev.D.ctrl = sfax_dctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) card->isac.dch.dev.Bprotocols =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) mISDNisar_init(&card->isar, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) set_channelmap(i + 1, card->isac.dch.dev.channelmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) list_add(&card->isar.ch[i].bch.ch.list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) &card->isac.dch.dev.bchannels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) err = setup_speedfax(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) goto error_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) err = card->isar.init(&card->isar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) err = mISDN_register_device(&card->isac.dch.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) &card->pdev->dev, card->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) err = init_card(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto error_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) err = card->isar.firmware(&card->isar, firmware->data, firmware->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) sfax_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) pr_notice("SpeedFax %d cards installed\n", sfax_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) disable_hwirq(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) free_irq(card->irq, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) error_init:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) mISDN_unregister_device(&card->isac.dch.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) release_region(card->cfg, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) error_setup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) card->isac.release(&card->isac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) card->isar.release(&card->isar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) error_fw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) pci_disable_device(card->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) write_lock_irqsave(&card_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) list_del(&card->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) write_unlock_irqrestore(&card_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) kfree(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct sfax_hw *card = kzalloc(sizeof(struct sfax_hw), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (!card) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) pr_info("No memory for Speedfax+ PCI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) card->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) err = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) kfree(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) pr_notice("mISDN: Speedfax found adapter %s at %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) (char *)ent->driver_data, pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) card->cfg = pci_resource_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) card->irq = pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) pci_set_drvdata(pdev, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) err = setup_instance(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) pci_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) sfax_remove_pci(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct sfax_hw *card = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) release_card(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) pr_debug("%s: drvdata already removed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static struct pci_device_id sfaxpci_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 0, 0, (unsigned long) "Pyramid Speedfax + PCI"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) PCI_SUBVENDOR_SPEEDFAX_PCI, PCI_SUB_ID_SEDLBAUER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 0, 0, (unsigned long) "Sedlbauer Speedfax + PCI"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) MODULE_DEVICE_TABLE(pci, sfaxpci_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static struct pci_driver sfaxpci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .name = "speedfax+ pci",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .probe = sfaxpci_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .remove = sfax_remove_pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .id_table = sfaxpci_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) Speedfax_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) SPEEDFAX_REV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) err = pci_register_driver(&sfaxpci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static void __exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) Speedfax_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) pci_unregister_driver(&sfaxpci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) module_init(Speedfax_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) module_exit(Speedfax_cleanup);