diff options
Diffstat (limited to 'drivers/isdn/hardware/mISDN/hfcpci.c')
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfcpci.c | 100 |
1 files changed, 44 insertions, 56 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index cd5d26c9909f..8df12bf02af3 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c | |||
@@ -64,9 +64,6 @@ MODULE_LICENSE("GPL"); | |||
64 | module_param(debug, uint, 0); | 64 | module_param(debug, uint, 0); |
65 | module_param(poll, uint, S_IRUGO | S_IWUSR); | 65 | module_param(poll, uint, S_IRUGO | S_IWUSR); |
66 | 66 | ||
67 | static LIST_HEAD(HFClist); | ||
68 | static DEFINE_RWLOCK(HFClock); | ||
69 | |||
70 | enum { | 67 | enum { |
71 | HFC_CCD_2BD0, | 68 | HFC_CCD_2BD0, |
72 | HFC_CCD_B000, | 69 | HFC_CCD_B000, |
@@ -136,7 +133,6 @@ struct hfcPCI_hw { | |||
136 | 133 | ||
137 | 134 | ||
138 | struct hfc_pci { | 135 | struct hfc_pci { |
139 | struct list_head list; | ||
140 | u_char subtype; | 136 | u_char subtype; |
141 | u_char chanlimit; | 137 | u_char chanlimit; |
142 | u_char initdone; | 138 | u_char initdone; |
@@ -1227,41 +1223,6 @@ hfcpci_int(int intno, void *dev_id) | |||
1227 | return IRQ_HANDLED; | 1223 | return IRQ_HANDLED; |
1228 | } | 1224 | } |
1229 | 1225 | ||
1230 | static void | ||
1231 | hfcpci_softirq(void *arg) | ||
1232 | { | ||
1233 | u_long flags; | ||
1234 | struct bchannel *bch; | ||
1235 | struct hfc_pci *hc; | ||
1236 | |||
1237 | write_lock_irqsave(&HFClock, flags); | ||
1238 | list_for_each_entry(hc, &HFClist, list) { | ||
1239 | if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) { | ||
1240 | spin_lock(&hc->lock); | ||
1241 | bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); | ||
1242 | if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */ | ||
1243 | main_rec_hfcpci(bch); | ||
1244 | tx_birq(bch); | ||
1245 | } | ||
1246 | bch = Sel_BCS(hc, hc->hw.bswapped ? 1 : 2); | ||
1247 | if (bch && bch->state == ISDN_P_B_RAW) { /* B2 rx&tx */ | ||
1248 | main_rec_hfcpci(bch); | ||
1249 | tx_birq(bch); | ||
1250 | } | ||
1251 | spin_unlock(&hc->lock); | ||
1252 | } | ||
1253 | } | ||
1254 | write_unlock_irqrestore(&HFClock, flags); | ||
1255 | |||
1256 | /* if next event would be in the past ... */ | ||
1257 | if ((s32)(hfc_jiffies + tics - jiffies) <= 0) | ||
1258 | hfc_jiffies = jiffies + 1; | ||
1259 | else | ||
1260 | hfc_jiffies += tics; | ||
1261 | hfc_tl.expires = hfc_jiffies; | ||
1262 | add_timer(&hfc_tl); | ||
1263 | } | ||
1264 | |||
1265 | /* | 1226 | /* |
1266 | * timer callback for D-chan busy resolution. Currently no function | 1227 | * timer callback for D-chan busy resolution. Currently no function |
1267 | */ | 1228 | */ |
@@ -2131,7 +2092,6 @@ release_card(struct hfc_pci *hc) { | |||
2131 | mISDN_freebchannel(&hc->bch[1]); | 2092 | mISDN_freebchannel(&hc->bch[1]); |
2132 | mISDN_freebchannel(&hc->bch[0]); | 2093 | mISDN_freebchannel(&hc->bch[0]); |
2133 | mISDN_freedchannel(&hc->dch); | 2094 | mISDN_freedchannel(&hc->dch); |
2134 | list_del(&hc->list); | ||
2135 | pci_set_drvdata(hc->pdev, NULL); | 2095 | pci_set_drvdata(hc->pdev, NULL); |
2136 | kfree(hc); | 2096 | kfree(hc); |
2137 | } | 2097 | } |
@@ -2141,7 +2101,6 @@ setup_card(struct hfc_pci *card) | |||
2141 | { | 2101 | { |
2142 | int err = -EINVAL; | 2102 | int err = -EINVAL; |
2143 | u_int i; | 2103 | u_int i; |
2144 | u_long flags; | ||
2145 | char name[MISDN_MAX_IDLEN]; | 2104 | char name[MISDN_MAX_IDLEN]; |
2146 | 2105 | ||
2147 | card->dch.debug = debug; | 2106 | card->dch.debug = debug; |
@@ -2169,13 +2128,10 @@ setup_card(struct hfc_pci *card) | |||
2169 | if (err) | 2128 | if (err) |
2170 | goto error; | 2129 | goto error; |
2171 | snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-pci.%d", HFC_cnt + 1); | 2130 | snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-pci.%d", HFC_cnt + 1); |
2172 | err = mISDN_register_device(&card->dch.dev, name); | 2131 | err = mISDN_register_device(&card->dch.dev, &card->pdev->dev, name); |
2173 | if (err) | 2132 | if (err) |
2174 | goto error; | 2133 | goto error; |
2175 | HFC_cnt++; | 2134 | HFC_cnt++; |
2176 | write_lock_irqsave(&HFClock, flags); | ||
2177 | list_add_tail(&card->list, &HFClist); | ||
2178 | write_unlock_irqrestore(&HFClock, flags); | ||
2179 | printk(KERN_INFO "HFC %d cards installed\n", HFC_cnt); | 2135 | printk(KERN_INFO "HFC %d cards installed\n", HFC_cnt); |
2180 | return 0; | 2136 | return 0; |
2181 | error: | 2137 | error: |
@@ -2311,15 +2267,12 @@ static void __devexit | |||
2311 | hfc_remove_pci(struct pci_dev *pdev) | 2267 | hfc_remove_pci(struct pci_dev *pdev) |
2312 | { | 2268 | { |
2313 | struct hfc_pci *card = pci_get_drvdata(pdev); | 2269 | struct hfc_pci *card = pci_get_drvdata(pdev); |
2314 | u_long flags; | ||
2315 | 2270 | ||
2316 | if (card) { | 2271 | if (card) |
2317 | write_lock_irqsave(&HFClock, flags); | ||
2318 | release_card(card); | 2272 | release_card(card); |
2319 | write_unlock_irqrestore(&HFClock, flags); | 2273 | else |
2320 | } else | ||
2321 | if (debug) | 2274 | if (debug) |
2322 | printk(KERN_WARNING "%s: drvdata allready removed\n", | 2275 | printk(KERN_WARNING "%s: drvdata already removed\n", |
2323 | __func__); | 2276 | __func__); |
2324 | } | 2277 | } |
2325 | 2278 | ||
@@ -2331,6 +2284,46 @@ static struct pci_driver hfc_driver = { | |||
2331 | .id_table = hfc_ids, | 2284 | .id_table = hfc_ids, |
2332 | }; | 2285 | }; |
2333 | 2286 | ||
2287 | static int | ||
2288 | _hfcpci_softirq(struct device *dev, void *arg) | ||
2289 | { | ||
2290 | struct hfc_pci *hc = dev_get_drvdata(dev); | ||
2291 | struct bchannel *bch; | ||
2292 | if (hc == NULL) | ||
2293 | return 0; | ||
2294 | |||
2295 | if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) { | ||
2296 | spin_lock(&hc->lock); | ||
2297 | bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); | ||
2298 | if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */ | ||
2299 | main_rec_hfcpci(bch); | ||
2300 | tx_birq(bch); | ||
2301 | } | ||
2302 | bch = Sel_BCS(hc, hc->hw.bswapped ? 1 : 2); | ||
2303 | if (bch && bch->state == ISDN_P_B_RAW) { /* B2 rx&tx */ | ||
2304 | main_rec_hfcpci(bch); | ||
2305 | tx_birq(bch); | ||
2306 | } | ||
2307 | spin_unlock(&hc->lock); | ||
2308 | } | ||
2309 | return 0; | ||
2310 | } | ||
2311 | |||
2312 | static void | ||
2313 | hfcpci_softirq(void *arg) | ||
2314 | { | ||
2315 | (void) driver_for_each_device(&hfc_driver.driver, NULL, arg, | ||
2316 | _hfcpci_softirq); | ||
2317 | |||
2318 | /* if next event would be in the past ... */ | ||
2319 | if ((s32)(hfc_jiffies + tics - jiffies) <= 0) | ||
2320 | hfc_jiffies = jiffies + 1; | ||
2321 | else | ||
2322 | hfc_jiffies += tics; | ||
2323 | hfc_tl.expires = hfc_jiffies; | ||
2324 | add_timer(&hfc_tl); | ||
2325 | } | ||
2326 | |||
2334 | static int __init | 2327 | static int __init |
2335 | HFC_init(void) | 2328 | HFC_init(void) |
2336 | { | 2329 | { |
@@ -2375,14 +2368,9 @@ HFC_init(void) | |||
2375 | static void __exit | 2368 | static void __exit |
2376 | HFC_cleanup(void) | 2369 | HFC_cleanup(void) |
2377 | { | 2370 | { |
2378 | struct hfc_pci *card, *next; | ||
2379 | |||
2380 | if (timer_pending(&hfc_tl)) | 2371 | if (timer_pending(&hfc_tl)) |
2381 | del_timer(&hfc_tl); | 2372 | del_timer(&hfc_tl); |
2382 | 2373 | ||
2383 | list_for_each_entry_safe(card, next, &HFClist, list) { | ||
2384 | release_card(card); | ||
2385 | } | ||
2386 | pci_unregister_driver(&hfc_driver); | 2374 | pci_unregister_driver(&hfc_driver); |
2387 | } | 2375 | } |
2388 | 2376 | ||