Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) /* drivers/atm/zatm.c - ZeitNet ZN122x device driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4) /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/atm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/atmdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/sonet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/atm_zatm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <asm/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include "uPD98401.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include "uPD98402.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include "zeprom.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include "zatm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  * TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  * Minor features
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44)  *  - support 64 kB SDUs (will have to use multibuffer batches then :-( )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  *  - proper use of CDV, credit = max(1,CDVT*PCR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46)  *  - AAL0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  *  - better receive timestamps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  *  - OAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define ZATM_COPPER	1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define DPRINTK(format,args...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #ifndef CONFIG_ATM_ZATM_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define NULLCHECK(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define EVENT(s,a,b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) static void event_dump(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) }
^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) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) /* 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  * NULL pointer checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define NULLCHECK(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)   if ((unsigned long) (x) < 0x30) printk(KERN_CRIT #x "==0x%x\n", (int) (x))
^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)  * Very extensive activity logging. Greatly improves bug detection speed but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * costs a few Mbps if enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define EV 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) static const char *ev[EV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) static unsigned long ev_a[EV],ev_b[EV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) static int ec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) static void EVENT(const char *s,unsigned long a,unsigned long b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	ev[ec] = s; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	ev_a[ec] = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	ev_b[ec] = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	ec = (ec+1) % EV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) static void event_dump(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	int n,i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	printk(KERN_NOTICE "----- event dump follows -----\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	for (n = 0; n < EV; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		i = (ec+n) % EV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		printk(KERN_NOTICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 		printk(ev[i] ? ev[i] : "(null)",ev_a[i],ev_b[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	printk(KERN_NOTICE "----- event dump ends here -----\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #endif /* CONFIG_ATM_ZATM_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) #define RING_BUSY	1	/* indication from do_tx that PDU has to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 				   backlogged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) static struct atm_dev *zatm_boards = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) static unsigned long dummy[2] = {0,0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) #define zin_n(r) inl(zatm_dev->base+r*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) #define zin(r) inl(zatm_dev->base+uPD98401_##r*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) #define zout(v,r) outl(v,zatm_dev->base+uPD98401_##r*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) #define zwait() do {} while (zin(CMR) & uPD98401_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) /* RX0, RX1, TX0, TX1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) static const int mbx_entries[NR_MBX] = { 1024,1024,1024,1024 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) static const int mbx_esize[NR_MBX] = { 16,16,4,4 }; /* entry size in bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) #define MBX_SIZE(i) (mbx_entries[i]*mbx_esize[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) /*-------------------------------- utilities --------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) static void zpokel(struct zatm_dev *zatm_dev,u32 value,u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	zout(value,CER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	zout(uPD98401_IND_ACC | uPD98401_IA_BALL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	    (uPD98401_IA_TGT_CM << uPD98401_IA_TGT_SHIFT) | addr,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static u32 zpeekl(struct zatm_dev *zatm_dev,u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	zout(uPD98401_IND_ACC | uPD98401_IA_BALL | uPD98401_IA_RW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	  (uPD98401_IA_TGT_CM << uPD98401_IA_TGT_SHIFT) | addr,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	return zin(CER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) }
^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) /*------------------------------- free lists --------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^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)  * Free buffer head structure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166)  *   [0] pointer to buffer (for SAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  *   [1] buffer descr link pointer (for SAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  *   [2] back pointer to skb (for poll_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  *   [3] data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  *   ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) struct rx_buffer_head {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	u32		buffer;	/* pointer to buffer (for SAR) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	u32		link;	/* buffer descriptor link pointer (for SAR) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	struct sk_buff	*skb;	/* back pointer to skb (for poll_rx) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) static void refill_pool(struct atm_dev *dev,int pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	struct rx_buffer_head *first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	int align,offset,free,count,size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	EVENT("refill_pool\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	size = (64 << (pool <= ZATM_AAL5_POOL_BASE ? 0 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	    pool-ZATM_AAL5_POOL_BASE))+sizeof(struct rx_buffer_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	if (size < PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		align = 32; /* for 32 byte alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		offset = sizeof(struct rx_buffer_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		align = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		offset = zatm_dev->pool_info[pool].offset+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		    sizeof(struct rx_buffer_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	size += align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	free = zpeekl(zatm_dev,zatm_dev->pool_base+2*pool) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	    uPD98401_RXFP_REMAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	if (free >= zatm_dev->pool_info[pool].low_water) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	EVENT("starting ... POOL: 0x%x, 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	    zpeekl(zatm_dev,zatm_dev->pool_base+2*pool),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	    zpeekl(zatm_dev,zatm_dev->pool_base+2*pool+1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	EVENT("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	first = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	while (free < zatm_dev->pool_info[pool].high_water) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		struct rx_buffer_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		skb = alloc_skb(size,GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 			printk(KERN_WARNING DEV_LABEL "(Itf %d): got no new "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 			    "skb (%d) with %d free\n",dev->number,size,free);
^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) 		skb_reserve(skb,(unsigned char *) ((((unsigned long) skb->data+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		    align+offset-1) & ~(unsigned long) (align-1))-offset)-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 		    skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		head = (struct rx_buffer_head *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 		skb_reserve(skb,sizeof(struct rx_buffer_head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		if (!first) first = head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		head->buffer = virt_to_bus(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		head->link = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		head->skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		EVENT("enq skb 0x%08lx/0x%08lx\n",(unsigned long) skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		    (unsigned long) head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		if (zatm_dev->last_free[pool])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 			((struct rx_buffer_head *) (zatm_dev->last_free[pool]->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 			    data))[-1].link = virt_to_bus(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		zatm_dev->last_free[pool] = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		skb_queue_tail(&zatm_dev->pool[pool],skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		free++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	if (first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		zout(virt_to_bus(first),CER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		zout(uPD98401_ADD_BAT | (pool << uPD98401_POOL_SHIFT) | count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		    CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		EVENT ("POOL: 0x%x, 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		    zpeekl(zatm_dev,zatm_dev->pool_base+2*pool),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		    zpeekl(zatm_dev,zatm_dev->pool_base+2*pool+1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		EVENT("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) static void drain_free(struct atm_dev *dev,int pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	skb_queue_purge(&ZATM_DEV(dev)->pool[pool]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) static int pool_index(int max_pdu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	if (max_pdu % ATM_CELL_PAYLOAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		printk(KERN_ERR DEV_LABEL ": driver error in pool_index: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		    "max_pdu is %d\n",max_pdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	if (max_pdu > 65536) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	for (i = 0; (64 << i) < max_pdu; i++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	return i+ZATM_AAL5_POOL_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) /* use_pool isn't reentrant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) static void use_pool(struct atm_dev *dev,int pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	if (!(zatm_dev->pool_info[pool].ref_count++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		skb_queue_head_init(&zatm_dev->pool[pool]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		size = pool-ZATM_AAL5_POOL_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		if (size < 0) size = 0; /* 64B... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		else if (size > 10) size = 10; /* ... 64kB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		zpokel(zatm_dev,((zatm_dev->pool_info[pool].low_water/4) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		    uPD98401_RXFP_ALERT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		    (1 << uPD98401_RXFP_BTSZ_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		    (size << uPD98401_RXFP_BFSZ_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		    zatm_dev->pool_base+pool*2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		zpokel(zatm_dev,(unsigned long) dummy,zatm_dev->pool_base+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		    pool*2+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		zatm_dev->last_free[pool] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		refill_pool(dev,pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	DPRINTK("pool %d: %d\n",pool,zatm_dev->pool_info[pool].ref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) static void unuse_pool(struct atm_dev *dev,int pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	if (!(--ZATM_DEV(dev)->pool_info[pool].ref_count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		drain_free(dev,pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) /*----------------------------------- RX ------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) static void exception(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320)    static int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321)    struct zatm_dev *zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322)    struct zatm_vcc *zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323)    unsigned long *qrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324)    int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326)    if (count++ > 2) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327)    for (i = 0; i < 8; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	printk("TX%d: 0x%08lx\n",i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	  zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330)    for (i = 0; i < 5; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	printk("SH%d: 0x%08lx\n",i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	  zpeekl(zatm_dev,uPD98401_IM(zatm_vcc->shaper)+16*i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333)    qrp = (unsigned long *) zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334)      uPD98401_TXVC_QRP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335)    printk("qrp=0x%08lx\n",(unsigned long) qrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336)    for (i = 0; i < 4; i++) printk("QRP[%d]: 0x%08lx",i,qrp[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) static const char *err_txt[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	"No error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	"RX buf underflow",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	"RX FIFO overrun",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	"Maximum len violation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	"CRC error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	"User abort",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	"Length violation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	"T1 error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	"Deactivated",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	"???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	"???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	"???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	"???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	"???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	"???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	"???"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) };
^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 void poll_rx(struct atm_dev *dev,int mbx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	unsigned long pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	u32 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	EVENT("poll_rx\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	pos = (zatm_dev->mbx_start[mbx] & ~0xffffUL) | zin(MTA(mbx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	while (x = zin(MWA(mbx)), (pos & 0xffff) != x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		u32 *here;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		struct atm_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		int cells,size,chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		EVENT("MBX: host 0x%lx, nic 0x%x\n",pos,x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		here = (u32 *) pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		if (((pos += 16) & 0xffff) == zatm_dev->mbx_end[mbx])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 			pos = zatm_dev->mbx_start[mbx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		cells = here[0] & uPD98401_AAL5_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) printk("RX IND: 0x%x, 0x%x, 0x%x, 0x%x\n",here[0],here[1],here[2],here[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) unsigned long *x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		printk("POOL: 0x%08x, 0x%08x\n",zpeekl(zatm_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		      zatm_dev->pool_base),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		      zpeekl(zatm_dev,zatm_dev->pool_base+1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		x = (unsigned long *) here[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		printk("[0..3] = 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		    x[0],x[1],x[2],x[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		if (here[3] & uPD98401_AAL5_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 			error = (here[3] & uPD98401_AAL5_ES) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 			    uPD98401_AAL5_ES_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			if (error == uPD98401_AAL5_ES_DEACT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 			    error == uPD98401_AAL5_ES_FREE) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) EVENT("error code 0x%x/0x%x\n",(here[3] & uPD98401_AAL5_ES) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402)   uPD98401_AAL5_ES_SHIFT,error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		skb = ((struct rx_buffer_head *) bus_to_virt(here[2]))->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		__net_timestamp(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) printk("[-3..0] 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",((unsigned *) skb->data)[-3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407)   ((unsigned *) skb->data)[-2],((unsigned *) skb->data)[-1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408)   ((unsigned *) skb->data)[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		EVENT("skb 0x%lx, here 0x%lx\n",(unsigned long) skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		    (unsigned long) here);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) printk("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		size = error ? 0 : ntohs(((__be16 *) skb->data)[cells*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		    ATM_CELL_PAYLOAD/sizeof(u16)-3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		EVENT("got skb 0x%lx, size %d\n",(unsigned long) skb,size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		chan = (here[3] & uPD98401_AAL5_CHAN) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		    uPD98401_AAL5_CHAN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		if (chan < zatm_dev->chans && zatm_dev->rx_map[chan]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 			int pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 			vcc = zatm_dev->rx_map[chan];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 			pos = ZATM_VCC(vcc)->pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 			if (skb == zatm_dev->last_free[pos])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 				zatm_dev->last_free[pos] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			skb_unlink(skb, zatm_dev->pool + pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 			printk(KERN_ERR DEV_LABEL "(itf %d): RX indication "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 			    "for non-existing channel\n",dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 			size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 			vcc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 			event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 			static unsigned long silence = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			static int last_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 			if (error != last_error ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 			    time_after(jiffies, silence)  || silence == 0){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 				printk(KERN_WARNING DEV_LABEL "(itf %d): "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 				    "chan %d error %s\n",dev->number,chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 				    err_txt[error]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 				last_error = error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 				silence = (jiffies+2*HZ)|1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 			size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		if (size && (size > cells*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		    size <= (cells-1)*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 			printk(KERN_ERR DEV_LABEL "(itf %d): size %d with %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			    "cells\n",dev->number,size,cells);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 			size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 			event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		if (size > ATM_MAX_AAL5_PDU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 			printk(KERN_ERR DEV_LABEL "(itf %d): size too big "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			    "(%d)\n",dev->number,size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 			size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 			event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		if (!size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 			dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 			if (vcc) atomic_inc(&vcc->stats->rx_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		if (!atm_charge(vcc,skb->truesize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 			dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		skb->len = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		ATM_SKB(skb)->vcc = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		vcc->push(vcc,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		atomic_inc(&vcc->stats->rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	zout(pos & 0xffff,MTA(mbx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) #if 0 /* probably a stupid idea */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	refill_pool(dev,zatm_vcc->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		/* maybe this saves us a few interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) static int open_rx_first(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	unsigned short chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	int cells;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	DPRINTK("open_rx_first (0x%x)\n",inb_p(0xc053));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	zatm_vcc->rx_chan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	if (vcc->qos.aal == ATM_AAL5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		if (vcc->qos.rxtp.max_sdu > 65464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 			vcc->qos.rxtp.max_sdu = 65464;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 			/* fix this - we may want to receive 64kB SDUs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			   later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		cells = DIV_ROUND_UP(vcc->qos.rxtp.max_sdu + ATM_AAL5_TRAILER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 				ATM_CELL_PAYLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		zatm_vcc->pool = pool_index(cells*ATM_CELL_PAYLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		cells = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		zatm_vcc->pool = ZATM_AAL0_POOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	if (zatm_vcc->pool < 0) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	zout(uPD98401_OPEN_CHAN,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	DPRINTK("chan is %d\n",chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	if (!chan) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	use_pool(vcc->dev,zatm_vcc->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	DPRINTK("pool %d\n",zatm_vcc->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	/* set up VC descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	zpokel(zatm_dev,zatm_vcc->pool << uPD98401_RXVC_POOL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	    chan*VC_SIZE/4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	zpokel(zatm_dev,uPD98401_RXVC_OD | (vcc->qos.aal == ATM_AAL5 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	    uPD98401_RXVC_AR : 0) | cells,chan*VC_SIZE/4+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	zpokel(zatm_dev,0,chan*VC_SIZE/4+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	zatm_vcc->rx_chan = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	zatm_dev->rx_map[chan] = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) static int open_rx_second(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	int pos,shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	DPRINTK("open_rx_second (0x%x)\n",inb_p(0xc053));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	if (!zatm_vcc->rx_chan) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	/* should also handle VPI @@@ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	pos = vcc->vci >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	shift = (1-(vcc->vci & 1)) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	zpokel(zatm_dev,(zpeekl(zatm_dev,pos) & ~(0xffff << shift)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	    ((zatm_vcc->rx_chan | uPD98401_RXLT_ENBL) << shift),pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) static void close_rx(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	int pos,shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	if (!zatm_vcc->rx_chan) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	DPRINTK("close_rx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	/* disable receiver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	if (vcc->vpi != ATM_VPI_UNSPEC && vcc->vci != ATM_VCI_UNSPEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		pos = vcc->vci >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		shift = (1-(vcc->vci & 1)) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		zpokel(zatm_dev,zpeekl(zatm_dev,pos) & ~(0xffff << shift),pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		zout(uPD98401_NOP,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		zout(uPD98401_NOP,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	zout(uPD98401_DEACT_CHAN | uPD98401_CHAN_RT | (zatm_vcc->rx_chan <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	    uPD98401_CHAN_ADDR_SHIFT),CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	udelay(10); /* why oh why ... ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	zout(uPD98401_CLOSE_CHAN | uPD98401_CHAN_RT | (zatm_vcc->rx_chan <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	    uPD98401_CHAN_ADDR_SHIFT),CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	if (!(zin(CMR) & uPD98401_CHAN_ADDR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		printk(KERN_CRIT DEV_LABEL "(itf %d): can't close RX channel "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		    "%d\n",vcc->dev->number,zatm_vcc->rx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	zatm_dev->rx_map[zatm_vcc->rx_chan] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	zatm_vcc->rx_chan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	unuse_pool(vcc->dev,zatm_vcc->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) static int start_rx(struct atm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	DPRINTK("start_rx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	zatm_dev->rx_map = kcalloc(zatm_dev->chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 				   sizeof(*zatm_dev->rx_map),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 				   GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	if (!zatm_dev->rx_map) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	/* set VPI/VCI split (use all VCIs and give what's left to VPIs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	zpokel(zatm_dev,(1 << dev->ci_range.vci_bits)-1,uPD98401_VRR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	/* prepare free buffer pools */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	for (i = 0; i <= ZATM_LAST_POOL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		zatm_dev->pool_info[i].ref_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		zatm_dev->pool_info[i].rqa_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		zatm_dev->pool_info[i].rqu_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		zatm_dev->pool_info[i].low_water = LOW_MARK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		zatm_dev->pool_info[i].high_water = HIGH_MARK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		zatm_dev->pool_info[i].offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		zatm_dev->pool_info[i].next_off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		zatm_dev->pool_info[i].next_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		zatm_dev->pool_info[i].next_thres = OFF_CNG_THRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) /*----------------------------------- TX ------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) static int do_tx(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	struct atm_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	u32 *dsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	EVENT("do_tx\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	DPRINTK("sending skb %p\n",skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	vcc = ATM_SKB(skb)->vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	EVENT("iovcnt=%d\n",skb_shinfo(skb)->nr_frags,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	if (!skb_shinfo(skb)->nr_frags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		if (zatm_vcc->txing == RING_ENTRIES-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 			spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			return RING_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		zatm_vcc->txing++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		dsc = zatm_vcc->ring+zatm_vcc->ring_curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		zatm_vcc->ring_curr = (zatm_vcc->ring_curr+RING_WORDS) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		    (RING_ENTRIES*RING_WORDS-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		dsc[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		dsc[2] = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		dsc[3] = virt_to_bus(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		dsc[0] = uPD98401_TXPD_V | uPD98401_TXPD_DP | uPD98401_TXPD_SM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		    | (vcc->qos.aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : 0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		    (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		    uPD98401_CLPM_1 : uPD98401_CLPM_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		EVENT("dsc (0x%lx)\n",(unsigned long) dsc,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) printk("NONONONOO!!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		dsc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		u32 *put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		dsc = kmalloc(uPD98401_TXPD_SIZE * 2 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			uPD98401_TXBD_SIZE * ATM_SKB(skb)->iovcnt, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		if (!dsc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			if (vcc->pop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 				vcc->pop(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 				dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		/* @@@ should check alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		put = dsc+8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		dsc[0] = uPD98401_TXPD_V | uPD98401_TXPD_DP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		    (vcc->aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : 0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		    (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		    uPD98401_CLPM_1 : uPD98401_CLPM_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		dsc[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		dsc[2] = ATM_SKB(skb)->iovcnt * uPD98401_TXBD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		dsc[3] = virt_to_bus(put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		for (i = 0; i < ATM_SKB(skb)->iovcnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 			*put++ = ((struct iovec *) skb->data)[i].iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			*put++ = virt_to_bus(((struct iovec *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			    skb->data)[i].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		put[-2] |= uPD98401_TXBD_LAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	ZATM_PRV_DSC(skb) = dsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	skb_queue_tail(&zatm_vcc->tx_queue,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	DPRINTK("QRP=0x%08lx\n",zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	  uPD98401_TXVC_QRP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	zout(uPD98401_TX_READY | (zatm_vcc->tx_chan <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	    uPD98401_CHAN_ADDR_SHIFT),CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	EVENT("done\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) static inline void dequeue_tx(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	EVENT("dequeue_tx\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	skb = skb_dequeue(&zatm_vcc->tx_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		printk(KERN_CRIT DEV_LABEL "(itf %d): dequeue_tx but not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		    "txing\n",vcc->dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) #if 0 /* @@@ would fail on CLP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD_V | uPD98401_TXPD_DP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727)   uPD98401_TXPD_SM | uPD98401_TXPD_AAL5)) printk("@#*$!!!!  (%08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728)   *ZATM_PRV_DSC(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	*ZATM_PRV_DSC(skb) = 0; /* mark as invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	zatm_vcc->txing--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	if (vcc->pop) vcc->pop(vcc,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	else dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	while ((skb = skb_dequeue(&zatm_vcc->backlog)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		if (do_tx(skb) == RING_BUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			skb_queue_head(&zatm_vcc->backlog,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	atomic_inc(&vcc->stats->tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	wake_up(&zatm_vcc->tx_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) static void poll_tx(struct atm_dev *dev,int mbx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	unsigned long pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	u32 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	EVENT("poll_tx\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	pos = (zatm_dev->mbx_start[mbx] & ~0xffffUL) | zin(MTA(mbx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	while (x = zin(MWA(mbx)), (pos & 0xffff) != x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		int chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		u32 data,*addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		EVENT("MBX: host 0x%lx, nic 0x%x\n",pos,x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		addr = (u32 *) pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		data = *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		chan = (data & uPD98401_TXI_CONN) >> uPD98401_TXI_CONN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		EVENT("addr = 0x%lx, data = 0x%08x,",(unsigned long) addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		    data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		EVENT("chan = %d\n",chan,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) NO !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		chan = (zatm_dev->mbx_start[mbx][pos >> 2] & uPD98401_TXI_CONN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		>> uPD98401_TXI_CONN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		if (chan < zatm_dev->chans && zatm_dev->tx_map[chan])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 			dequeue_tx(zatm_dev->tx_map[chan]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			printk(KERN_CRIT DEV_LABEL "(itf %d): TX indication "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			    "for non-existing channel %d\n",dev->number,chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		if (((pos += 4) & 0xffff) == zatm_dev->mbx_end[mbx])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 			pos = zatm_dev->mbx_start[mbx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	zout(pos & 0xffff,MTA(mbx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786)  * BUG BUG BUG: Doesn't handle "new-style" rate specification yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	unsigned long i,m,c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	int shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	DPRINTK("alloc_shaper (min = %d, max = %d)\n",min,max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	if (!zatm_dev->free_shapers) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	for (shaper = 0; !((zatm_dev->free_shapers >> shaper) & 1); shaper++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	zatm_dev->free_shapers &= ~1 << shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	if (ubr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		c = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		i = m = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		zatm_dev->ubr_ref_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		zatm_dev->ubr = shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		*pcr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		if (min) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 			if (min <= 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 				i = min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 				m = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 				i = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 				m = ATM_OC3_PCR*255/min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			if (max > zatm_dev->tx_bw) max = zatm_dev->tx_bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 			if (max <= 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 				i = max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 				m = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 				i = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 				m = DIV_ROUND_UP(ATM_OC3_PCR*255, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		if (i > m) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 			printk(KERN_CRIT DEV_LABEL "shaper algorithm botched "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			    "[%d,%d] -> i=%ld,m=%ld\n",min,max,i,m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 			m = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		*pcr = i*ATM_OC3_PCR/m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		c = 20; /* @@@ should use max_cdv ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		if ((min && *pcr < min) || (max && *pcr > max)) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		if (zatm_dev->tx_bw < *pcr) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		zatm_dev->tx_bw -= *pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	DPRINTK("i = %d, m = %d, PCR = %d\n",i,m,*pcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	zpokel(zatm_dev,(i << uPD98401_IM_I_SHIFT) | m,uPD98401_IM(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	zpokel(zatm_dev,c << uPD98401_PC_C_SHIFT,uPD98401_PC(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	zpokel(zatm_dev,0,uPD98401_X(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	zpokel(zatm_dev,0,uPD98401_Y(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	zpokel(zatm_dev,uPD98401_PS_E,uPD98401_PS(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	return shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) static void dealloc_shaper(struct atm_dev *dev,int shaper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	if (shaper == zatm_dev->ubr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		if (--zatm_dev->ubr_ref_cnt) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		zatm_dev->ubr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	zpokel(zatm_dev,zpeekl(zatm_dev,uPD98401_PS(shaper)) & ~uPD98401_PS_E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	    uPD98401_PS(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	zatm_dev->free_shapers |= 1 << shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) static void close_tx(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	int chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	chan = zatm_vcc->tx_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	if (!chan) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	DPRINTK("close_tx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	if (skb_peek(&zatm_vcc->backlog)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		printk("waiting for backlog to drain ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		wait_event(zatm_vcc->tx_wait, !skb_peek(&zatm_vcc->backlog));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	if (skb_peek(&zatm_vcc->tx_queue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		printk("waiting for TX queue to drain ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		wait_event(zatm_vcc->tx_wait, !skb_peek(&zatm_vcc->tx_queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	zout(uPD98401_DEACT_CHAN | (chan << uPD98401_CHAN_ADDR_SHIFT),CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	zout(uPD98401_CLOSE_CHAN | (chan << uPD98401_CHAN_ADDR_SHIFT),CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	if (!(zin(CMR) & uPD98401_CHAN_ADDR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		printk(KERN_CRIT DEV_LABEL "(itf %d): can't close TX channel "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		    "%d\n",vcc->dev->number,chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	zatm_vcc->tx_chan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	zatm_dev->tx_map[chan] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	if (zatm_vcc->shaper != zatm_dev->ubr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		zatm_dev->tx_bw += vcc->qos.txtp.min_pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		dealloc_shaper(vcc->dev,zatm_vcc->shaper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	kfree(zatm_vcc->ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) static int open_tx_first(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	u32 *loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	unsigned short chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	int unlimited;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	DPRINTK("open_tx_first\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	zatm_vcc->tx_chan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	zout(uPD98401_OPEN_CHAN,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	DPRINTK("chan is %d\n",chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	if (!chan) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	unlimited = vcc->qos.txtp.traffic_class == ATM_UBR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	    (!vcc->qos.txtp.max_pcr || vcc->qos.txtp.max_pcr == ATM_MAX_PCR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	    vcc->qos.txtp.max_pcr >= ATM_OC3_PCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	if (unlimited && zatm_dev->ubr != -1) zatm_vcc->shaper = zatm_dev->ubr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		int pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		if (unlimited) vcc->qos.txtp.max_sdu = ATM_MAX_AAL5_PDU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		if ((zatm_vcc->shaper = alloc_shaper(vcc->dev,&pcr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		    vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,unlimited))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		    < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 			close_tx(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 			return zatm_vcc->shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		if (pcr > ATM_OC3_PCR) pcr = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		vcc->qos.txtp.min_pcr = vcc->qos.txtp.max_pcr = pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	zatm_vcc->tx_chan = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	skb_queue_head_init(&zatm_vcc->tx_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	init_waitqueue_head(&zatm_vcc->tx_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	/* initialize ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	zatm_vcc->ring = kzalloc(RING_SIZE,GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	if (!zatm_vcc->ring) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	loop = zatm_vcc->ring+RING_ENTRIES*RING_WORDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	loop[0] = uPD98401_TXPD_V;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	loop[1] = loop[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	loop[3] = virt_to_bus(zatm_vcc->ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	zatm_vcc->ring_curr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	zatm_vcc->txing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	skb_queue_head_init(&zatm_vcc->backlog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	zpokel(zatm_dev,virt_to_bus(zatm_vcc->ring),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	    chan*VC_SIZE/4+uPD98401_TXVC_QRP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) static int open_tx_second(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	DPRINTK("open_tx_second\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	if (!zatm_vcc->tx_chan) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	/* set up VC descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	zpokel(zatm_dev,uPD98401_TXVC_L | (zatm_vcc->shaper <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	    uPD98401_TXVC_SHP_SHIFT) | (vcc->vpi << uPD98401_TXVC_VPI_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	    vcc->vci,zatm_vcc->tx_chan*VC_SIZE/4+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	zatm_dev->tx_map[zatm_vcc->tx_chan] = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) static int start_tx(struct atm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	DPRINTK("start_tx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	zatm_dev->tx_map = kmalloc_array(zatm_dev->chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 					 sizeof(*zatm_dev->tx_map),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 					 GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	if (!zatm_dev->tx_map) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	zatm_dev->tx_bw = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	zatm_dev->free_shapers = (1 << NR_SHAPERS)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	zatm_dev->ubr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	zatm_dev->ubr_ref_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	/* initialize shapers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	for (i = 0; i < NR_SHAPERS; i++) zpokel(zatm_dev,0,uPD98401_PS(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /*------------------------------- interrupts --------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) static irqreturn_t zatm_int(int irq,void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	struct atm_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	u32 reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	while ((reason = zin(GSR))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		EVENT("reason 0x%x\n",reason,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		if (reason & uPD98401_INT_PI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 			EVENT("PHY int\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 			dev->phy->interrupt(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		if (reason & uPD98401_INT_RQA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 			unsigned long pools;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 			int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 			pools = zin(RQA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 			EVENT("RQA (0x%08x)\n",pools,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 			for (i = 0; pools; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 				if (pools & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 					refill_pool(dev,i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 					zatm_dev->pool_info[i].rqa_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 				pools >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		if (reason & uPD98401_INT_RQU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 			unsigned long pools;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 			int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 			pools = zin(RQU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 			printk(KERN_WARNING DEV_LABEL "(itf %d): RQU 0x%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 			    dev->number,pools);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 			for (i = 0; pools; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 				if (pools & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 					refill_pool(dev,i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 					zatm_dev->pool_info[i].rqu_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 				pools >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		/* don't handle RD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		if (reason & uPD98401_INT_SPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			printk(KERN_ALERT DEV_LABEL "(itf %d): system parity "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 			    "error at 0x%08x\n",dev->number,zin(ADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		if (reason & uPD98401_INT_CPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			printk(KERN_ALERT DEV_LABEL "(itf %d): control memory "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			    "parity error at 0x%08x\n",dev->number,zin(ADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		if (reason & uPD98401_INT_SBE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			printk(KERN_ALERT DEV_LABEL "(itf %d): system bus "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			    "error at 0x%08x\n",dev->number,zin(ADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		/* don't handle IND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		if (reason & uPD98401_INT_MF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			printk(KERN_CRIT DEV_LABEL "(itf %d): mailbox full "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			    "(0x%x)\n",dev->number,(reason & uPD98401_INT_MF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 			    >> uPD98401_INT_MF_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 			    /* @@@ should try to recover */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		if (reason & uPD98401_INT_MM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 			if (reason & 1) poll_rx(dev,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 			if (reason & 2) poll_rx(dev,1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 			if (reason & 4) poll_tx(dev,2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 			if (reason & 8) poll_tx(dev,3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		/* @@@ handle RCRn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /*----------------------------- (E)EPROM access -----------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static void eprom_set(struct zatm_dev *zatm_dev, unsigned long value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		      unsigned short cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	if ((error = pci_write_config_dword(zatm_dev->pci_dev,cmd,value)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		printk(KERN_ERR DEV_LABEL ": PCI write failed (0x%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		    error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static unsigned long eprom_get(struct zatm_dev *zatm_dev, unsigned short cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	if ((error = pci_read_config_dword(zatm_dev->pci_dev,cmd,&value)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		printk(KERN_ERR DEV_LABEL ": PCI read failed (0x%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		    error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) static void eprom_put_bits(struct zatm_dev *zatm_dev, unsigned long data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 			   int bits, unsigned short cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	for (i = bits-1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		value = ZEPROM_CS | (((data >> i) & 1) ? ZEPROM_DI : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		eprom_set(zatm_dev,value,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		eprom_set(zatm_dev,value | ZEPROM_SK,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		eprom_set(zatm_dev,value,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) static void eprom_get_byte(struct zatm_dev *zatm_dev, unsigned char *byte,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 			   unsigned short cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	*byte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	for (i = 8; i; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 		eprom_set(zatm_dev,ZEPROM_CS,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		eprom_set(zatm_dev,ZEPROM_CS | ZEPROM_SK,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		*byte <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		if (eprom_get(zatm_dev,cmd) & ZEPROM_DO) *byte |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		eprom_set(zatm_dev,ZEPROM_CS,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static int eprom_try_esi(struct atm_dev *dev, unsigned short cmd, int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 			 int swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	unsigned char buf[ZEPROM_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	for (i = 0; i < ZEPROM_SIZE; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		eprom_set(zatm_dev,ZEPROM_CS,cmd); /* select EPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		eprom_put_bits(zatm_dev,ZEPROM_CMD_READ,ZEPROM_CMD_LEN,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 		eprom_put_bits(zatm_dev,i >> 1,ZEPROM_ADDR_LEN,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		eprom_get_byte(zatm_dev,buf+i+swap,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		eprom_get_byte(zatm_dev,buf+i+1-swap,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		eprom_set(zatm_dev,0,cmd); /* deselect EPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	memcpy(dev->esi,buf+offset,ESI_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	return memcmp(dev->esi,"\0\0\0\0\0",ESI_LEN); /* assumes ESI_LEN == 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) static void eprom_get_esi(struct atm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	if (eprom_try_esi(dev,ZEPROM_V1_REG,ZEPROM_V1_ESI_OFF,1)) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	(void) eprom_try_esi(dev,ZEPROM_V2_REG,ZEPROM_V2_ESI_OFF,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) /*--------------------------------- entries ---------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static int zatm_init(struct atm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	struct pci_dev *pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	unsigned short command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	int error,i,last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	unsigned long t0,t1,t2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	DPRINTK(">zatm_init\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	spin_lock_init(&zatm_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	pci_dev = zatm_dev->pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	zatm_dev->base = pci_resource_start(pci_dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	zatm_dev->irq = pci_dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	if ((error = pci_read_config_word(pci_dev,PCI_COMMAND,&command))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 		printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		    dev->number,error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	if ((error = pci_write_config_word(pci_dev,PCI_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	    command | PCI_COMMAND_IO | PCI_COMMAND_MASTER))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable IO (0x%02x)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		    "\n",dev->number,error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	eprom_get_esi(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%x,irq=%d,",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	    dev->number,pci_dev->revision,zatm_dev->base,zatm_dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	/* reset uPD98401 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	zout(0,SWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	while (!(zin(GSR) & uPD98401_INT_IND));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	zout(uPD98401_GMR_ONE /*uPD98401_BURST4*/,GMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	last = MAX_CRAM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	for (i = last-RAM_INCREMENT; i >= 0; i -= RAM_INCREMENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		zpokel(zatm_dev,0x55555555,i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		if (zpeekl(zatm_dev,i) != 0x55555555) last = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 			zpokel(zatm_dev,0xAAAAAAAA,i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 			if (zpeekl(zatm_dev,i) != 0xAAAAAAAA) last = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 			else zpokel(zatm_dev,i,i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	for (i = 0; i < last; i += RAM_INCREMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		if (zpeekl(zatm_dev,i) != i) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	zatm_dev->mem = i << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	while (i) zpokel(zatm_dev,0,--i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	/* reset again to rebuild memory pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	zout(0,SWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	while (!(zin(GSR) & uPD98401_INT_IND));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	zout(uPD98401_GMR_ONE | uPD98401_BURST8 | uPD98401_BURST4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	    uPD98401_BURST2 | uPD98401_GMR_PM | uPD98401_GMR_DR,GMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	/* TODO: should shrink allocation now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	printk("mem=%dkB,%s (",zatm_dev->mem >> 10,zatm_dev->copper ? "UTP" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	    "MMF");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	for (i = 0; i < ESI_LEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		printk("%02X%s",dev->esi[i],i == ESI_LEN-1 ? ")\n" : "-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 		spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		t0 = zpeekl(zatm_dev,uPD98401_TSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		t1 = zpeekl(zatm_dev,uPD98401_TSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		udelay(1010);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 		t2 = zpeekl(zatm_dev,uPD98401_TSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	while (t0 > t1 || t1 > t2); /* loop if wrapping ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	zatm_dev->khz = t2-2*t1+t0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	printk(KERN_NOTICE DEV_LABEL "(itf %d): uPD98401 %d.%d at %d.%03d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	    "MHz\n",dev->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	    (zin(VER) & uPD98401_MAJOR) >> uPD98401_MAJOR_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)             zin(VER) & uPD98401_MINOR,zatm_dev->khz/1000,zatm_dev->khz % 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	return uPD98402_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) static int zatm_start(struct atm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	struct zatm_dev *zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	struct pci_dev *pdev = zatm_dev->pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	unsigned long curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	int pools,vccs,rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	int error, i, ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	DPRINTK("zatm_start\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	zatm_dev->rx_map = zatm_dev->tx_map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)  	for (i = 0; i < NR_MBX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)  		zatm_dev->mbx_start[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)  	error = request_irq(zatm_dev->irq, zatm_int, IRQF_SHARED, DEV_LABEL, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)  		printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)  		    dev->number,zatm_dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	/* define memory regions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	pools = NR_POOLS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	if (NR_SHAPERS*SHAPER_SIZE > pools*POOL_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 		pools = NR_SHAPERS*SHAPER_SIZE/POOL_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	vccs = (zatm_dev->mem-NR_SHAPERS*SHAPER_SIZE-pools*POOL_SIZE)/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	    (2*VC_SIZE+RX_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	ld = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	for (rx = 1; rx < vccs; rx <<= 1) ld++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	dev->ci_range.vpi_bits = 0; /* @@@ no VPI for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	dev->ci_range.vci_bits = ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	dev->link_rate = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	zatm_dev->chans = vccs; /* ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	curr = rx*RX_SIZE/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	DPRINTK("RX pool 0x%08lx\n",curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	zpokel(zatm_dev,curr,uPD98401_PMA); /* receive pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	zatm_dev->pool_base = curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	curr += pools*POOL_SIZE/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	DPRINTK("Shapers 0x%08lx\n",curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	zpokel(zatm_dev,curr,uPD98401_SMA); /* shapers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	curr += NR_SHAPERS*SHAPER_SIZE/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	DPRINTK("Free    0x%08lx\n",curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	zpokel(zatm_dev,curr,uPD98401_TOS); /* free pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	printk(KERN_INFO DEV_LABEL "(itf %d): %d shapers, %d pools, %d RX, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	    "%ld VCs\n",dev->number,NR_SHAPERS,pools,rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	    (zatm_dev->mem-curr*4)/VC_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	/* create mailboxes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	for (i = 0; i < NR_MBX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		void *mbx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		dma_addr_t mbx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 		if (!mbx_entries[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		mbx = dma_alloc_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 					 2 * MBX_SIZE(i), &mbx_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		if (!mbx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 			error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 		 * Alignment provided by dma_alloc_coherent() isn't enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		 * for this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 		if (((unsigned long)mbx ^ mbx_dma) & 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 			printk(KERN_ERR DEV_LABEL "(itf %d): system "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 			       "bus incompatible with driver\n", dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 			dma_free_coherent(&pdev->dev, 2*MBX_SIZE(i), mbx, mbx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 			error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		DPRINTK("mbx@0x%08lx-0x%08lx\n", mbx, mbx + MBX_SIZE(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		zatm_dev->mbx_start[i] = (unsigned long)mbx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		zatm_dev->mbx_dma[i] = mbx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 		zatm_dev->mbx_end[i] = (zatm_dev->mbx_start[i] + MBX_SIZE(i)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 					0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		zout(mbx_dma >> 16, MSH(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 		zout(mbx_dma, MSL(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		zout(zatm_dev->mbx_end[i], MBA(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 		zout((unsigned long)mbx & 0xffff, MTA(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		zout((unsigned long)mbx & 0xffff, MWA(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	error = start_tx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	error = start_rx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 		goto out_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	error = dev->phy->start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 		goto out_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	zout(0xffffffff,IMR); /* enable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	/* enable TX & RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	zout(zin(GMR) | uPD98401_GMR_SE | uPD98401_GMR_RE,GMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) out_rx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	kfree(zatm_dev->rx_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) out_tx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	kfree(zatm_dev->tx_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	while (i-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		dma_free_coherent(&pdev->dev, 2 * MBX_SIZE(i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 				  (void *)zatm_dev->mbx_start[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 				  zatm_dev->mbx_dma[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	free_irq(zatm_dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) static void zatm_close(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)         DPRINTK(">zatm_close\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)         if (!ZATM_VCC(vcc)) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	clear_bit(ATM_VF_READY,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)         close_rx(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	EVENT("close_tx\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)         close_tx(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)         DPRINTK("zatm_close: done waiting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)         /* deallocate memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)         kfree(ZATM_VCC(vcc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	vcc->dev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	clear_bit(ATM_VF_ADDR,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static int zatm_open(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	short vpi = vcc->vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	int vci = vcc->vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	DPRINTK(">zatm_open\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		vcc->dev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		set_bit(ATM_VF_ADDR,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	if (vcc->qos.aal != ATM_AAL5) return -EINVAL; /* @@@ AAL0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n",vcc->dev->number,vcc->vpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	    vcc->vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		zatm_vcc = kmalloc(sizeof(*zatm_vcc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		if (!zatm_vcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 			clear_bit(ATM_VF_ADDR,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 		vcc->dev_data = zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 		ZATM_VCC(vcc)->tx_chan = 0; /* for zatm_close after open_rx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 		if ((error = open_rx_first(vcc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	                zatm_close(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	                return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	        }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 		if ((error = open_tx_first(vcc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 			zatm_close(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	        }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	if (vci == ATM_VPI_UNSPEC || vpi == ATM_VCI_UNSPEC) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	if ((error = open_rx_second(vcc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 		zatm_close(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	if ((error = open_tx_second(vcc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		zatm_close(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	set_bit(ATM_VF_READY,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) static int zatm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	printk("Not yet implemented\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	/* @@@ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 		case ZATM_GETPOOLZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 			if (!capable(CAP_NET_ADMIN)) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		case ZATM_GETPOOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 				struct zatm_pool_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 				int pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 				if (get_user(pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 				    &((struct zatm_pool_req __user *) arg)->pool_num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 					return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 				if (pool < 0 || pool > ZATM_LAST_POOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 				pool = array_index_nospec(pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 							  ZATM_LAST_POOL + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 				spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 				info = zatm_dev->pool_info[pool];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 				if (cmd == ZATM_GETPOOLZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 					zatm_dev->pool_info[pool].rqa_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 					zatm_dev->pool_info[pool].rqu_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 				spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 				return copy_to_user(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 				    &((struct zatm_pool_req __user *) arg)->info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 				    &info,sizeof(info)) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 		case ZATM_SETPOOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 				struct zatm_pool_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 				int pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 				if (!capable(CAP_NET_ADMIN)) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 				if (get_user(pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 				    &((struct zatm_pool_req __user *) arg)->pool_num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 					return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 				if (pool < 0 || pool > ZATM_LAST_POOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 				pool = array_index_nospec(pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 							  ZATM_LAST_POOL + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 				if (copy_from_user(&info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 				    &((struct zatm_pool_req __user *) arg)->info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 				    sizeof(info))) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 				if (!info.low_water)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 					info.low_water = zatm_dev->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 					    pool_info[pool].low_water;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 				if (!info.high_water)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 					info.high_water = zatm_dev->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 					    pool_info[pool].high_water;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 				if (!info.next_thres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 					info.next_thres = zatm_dev->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 					    pool_info[pool].next_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 				if (info.low_water >= info.high_water ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 				    info.low_water < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 				spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 				zatm_dev->pool_info[pool].low_water =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 				    info.low_water;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 				zatm_dev->pool_info[pool].high_water =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 				    info.high_water;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 				zatm_dev->pool_info[pool].next_thres =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 				    info.next_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 				spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)         		if (!dev->phy->ioctl) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		        return dev->phy->ioctl(dev,cmd,arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) static int zatm_send(struct atm_vcc *vcc,struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	EVENT(">zatm_send 0x%lx\n",(unsigned long) skb,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	if (!ZATM_VCC(vcc)->tx_chan || !test_bit(ATM_VF_READY,&vcc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 		if (vcc->pop) vcc->pop(vcc,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 		else dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 		printk(KERN_CRIT "!skb in zatm_send ?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 		if (vcc->pop) vcc->pop(vcc,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	ATM_SKB(skb)->vcc = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	error = do_tx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	if (error != RING_BUSY) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	skb_queue_tail(&ZATM_VCC(vcc)->backlog,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) static void zatm_phy_put(struct atm_dev *dev,unsigned char value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)     unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	zout(value,CER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	zout(uPD98401_IND_ACC | uPD98401_IA_B0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	    (uPD98401_IA_TGT_PHY << uPD98401_IA_TGT_SHIFT) | addr,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static unsigned char zatm_phy_get(struct atm_dev *dev,unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	zout(uPD98401_IND_ACC | uPD98401_IA_B0 | uPD98401_IA_RW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	  (uPD98401_IA_TGT_PHY << uPD98401_IA_TGT_SHIFT) | addr,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	return zin(CER) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) static const struct atmdev_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	.open		= zatm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	.close		= zatm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	.ioctl		= zatm_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	.send		= zatm_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	.phy_put	= zatm_phy_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	.phy_get	= zatm_phy_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	.change_qos	= zatm_change_qos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static int zatm_init_one(struct pci_dev *pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 			 const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	struct atm_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	zatm_dev = kmalloc(sizeof(*zatm_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	if (!zatm_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		printk(KERN_EMERG "%s: memory shortage\n", DEV_LABEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	ret = pci_enable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 		goto out_deregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	ret = pci_request_regions(pci_dev, DEV_LABEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		goto out_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	ret = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 		goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	zatm_dev->pci_dev = pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	dev->dev_data = zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	zatm_dev->copper = (int)ent->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	if ((ret = zatm_init(dev)) || (ret = zatm_start(dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 		goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	pci_set_drvdata(pci_dev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	zatm_dev->more = zatm_boards;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	zatm_boards = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) out_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	pci_release_regions(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) out_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	pci_disable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) out_deregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	atm_dev_deregister(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	kfree(zatm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) static const struct pci_device_id zatm_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	{ PCI_VDEVICE(ZEITNET, PCI_DEVICE_ID_ZEITNET_1221), ZATM_COPPER },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	{ PCI_VDEVICE(ZEITNET, PCI_DEVICE_ID_ZEITNET_1225), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	{ 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) MODULE_DEVICE_TABLE(pci, zatm_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) static struct pci_driver zatm_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	.name =		DEV_LABEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	.id_table =	zatm_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	.probe =	zatm_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) static int __init zatm_init_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	return pci_register_driver(&zatm_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) module_init(zatm_init_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) /* module_exit not defined so not unloadable */