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+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *  usbatm.c - Generic USB xDSL driver core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *  Copyright (C) 2001, Alcatel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *  Copyright (C) 2003, Duncan Sands, SolNegro, Josep Comas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *  Copyright (C) 2004, David Woodhouse, Roman Kagan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *  Written by Johan Verrept, Duncan Sands (duncan.sands@free.fr) and David Woodhouse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *  1.7+:	- See the check-in logs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *  1.6:	- No longer opens a connection if the firmware is not loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *  		- Added support for the speedtouch 330
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *  		- Removed the limit on the number of devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *  		- Module now autoloads on device plugin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  *  		- Merged relevant parts of sarlib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *  		- Replaced the kernel thread with a tasklet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  *  		- New packet transmission code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  *  		- Changed proc file contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  *  		- Fixed all known SMP races
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  *  		- Many fixes and cleanups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  *  		- Various fixes by Oliver Neukum (oliver@neukum.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  *  1.5A:	- Version for inclusion in 2.5 series kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  *		- Modifications by Richard Purdie (rpurdie@rpsys.net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  *		- made compatible with kernel 2.5.6 onwards by changing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  *		usbatm_usb_send_data_context->urb to a pointer and adding code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  *		to alloc and free it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  *		- remove_wait_queue() added to usbatm_atm_processqueue_thread()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  *  1.5:	- fixed memory leak when atmsar_decode_aal5 returned NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  *		(reported by stephen.robinson@zen.co.uk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  *  1.4:	- changed the spin_lock() under interrupt to spin_lock_irqsave()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  *		- unlink all active send urbs of a vcc that is being closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  *  1.3.1:	- added the version number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  *  1.3:	- Added multiple send urb support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  *		- fixed memory leak and vcc->tx_inuse starvation bug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44)  *		  when not enough memory left in vcc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46)  *  1.2:	- Fixed race condition in usbatm_usb_send_data()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  *  1.1:	- Turned off packet debugging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  *
^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) #include "usbatm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #ifdef VERBOSE_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) static int usbatm_print_packet(struct usbatm_data *instance, const unsigned char *data, int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define PACKETDEBUG(arg...)	usbatm_print_packet(arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define vdbg(arg...)		dev_dbg(arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define PACKETDEBUG(arg...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define vdbg(arg...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define DRIVER_AUTHOR	"Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define DRIVER_DESC	"Generic USB ATM/DSL I/O"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) static const char usbatm_driver_name[] = "usbatm";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define UDSL_MAX_RCV_URBS		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define UDSL_MAX_SND_URBS		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #define UDSL_MAX_BUF_SIZE		65536
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define UDSL_DEFAULT_RCV_URBS		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define UDSL_DEFAULT_SND_URBS		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define UDSL_DEFAULT_RCV_BUF_SIZE	3392	/* 64 * ATM_CELL_SIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define UDSL_DEFAULT_SND_BUF_SIZE	3392	/* 64 * ATM_CELL_SIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define ATM_CELL_HEADER			(ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define THROTTLE_MSECS			100	/* delay to recover processing after urb submission fails */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) static unsigned int rcv_buf_bytes = UDSL_DEFAULT_RCV_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) static unsigned int snd_buf_bytes = UDSL_DEFAULT_SND_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) module_param(num_rcv_urbs, uint, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) MODULE_PARM_DESC(num_rcv_urbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		 "Number of urbs used for reception (range: 0-"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		 __MODULE_STRING(UDSL_MAX_RCV_URBS) ", default: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		 __MODULE_STRING(UDSL_DEFAULT_RCV_URBS) ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) module_param(num_snd_urbs, uint, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) MODULE_PARM_DESC(num_snd_urbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 		 "Number of urbs used for transmission (range: 0-"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 		 __MODULE_STRING(UDSL_MAX_SND_URBS) ", default: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		 __MODULE_STRING(UDSL_DEFAULT_SND_URBS) ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) module_param(rcv_buf_bytes, uint, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) MODULE_PARM_DESC(rcv_buf_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		 "Size of the buffers used for reception, in bytes (range: 1-"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		 __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		 __MODULE_STRING(UDSL_DEFAULT_RCV_BUF_SIZE) ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) module_param(snd_buf_bytes, uint, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) MODULE_PARM_DESC(snd_buf_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		 "Size of the buffers used for transmission, in bytes (range: 1-"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 		 __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 		 __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) /* receive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) struct usbatm_vcc_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	/* vpi/vci lookup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	short vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	int vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	struct atm_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	/* raw cell reassembly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	struct sk_buff *sarb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) };
^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) /* send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) struct usbatm_control {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	struct atm_skb_data atm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	u32 crc;
^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) #define UDSL_SKB(x)		((struct usbatm_control *)(x)->cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) /* ATM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) static void usbatm_atm_dev_close(struct atm_dev *atm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) static int usbatm_atm_open(struct atm_vcc *vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) static void usbatm_atm_close(struct atm_vcc *vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __user *arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t *pos, char *page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) static const struct atmdev_ops usbatm_atm_devops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	.dev_close	= usbatm_atm_dev_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	.open		= usbatm_atm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	.close		= usbatm_atm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	.ioctl		= usbatm_atm_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	.send		= usbatm_atm_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	.proc_read	= usbatm_atm_proc_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	.owner		= THIS_MODULE,
^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) /***********
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) **  misc  **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) ***********/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) static inline unsigned int usbatm_pdu_length(unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	length += ATM_CELL_PAYLOAD - 1 + ATM_AAL5_TRAILER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	return length - length % ATM_CELL_PAYLOAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) static inline void usbatm_pop(struct atm_vcc *vcc, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	if (vcc->pop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		vcc->pop(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) /***********
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) **  urbs  **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) ************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) static struct urb *usbatm_pop_urb(struct usbatm_channel *channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	spin_lock_irq(&channel->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	if (list_empty(&channel->list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		spin_unlock_irq(&channel->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	urb = list_entry(channel->list.next, struct urb, urb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	list_del(&urb->urb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	spin_unlock_irq(&channel->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	return urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) static int usbatm_submit_urb(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	struct usbatm_channel *channel = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	/* vdbg("%s: submitting urb 0x%p, size %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	     __func__, urb, urb->transfer_buffer_length); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	ret = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		if (printk_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 			atm_warn(channel->usbatm, "%s: urb 0x%p submission failed (%d)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 				__func__, urb, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		/* consider all errors transient and return the buffer back to the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		urb->status = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		spin_lock_irq(&channel->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		/* must add to the front when sending; doesn't matter when receiving */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		list_add(&urb->urb_list, &channel->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		spin_unlock_irq(&channel->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		/* make sure the channel doesn't stall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) static void usbatm_complete(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	struct usbatm_channel *channel = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	/* vdbg("%s: urb 0x%p, status %d, actual_length %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	     __func__, urb, status, urb->actual_length); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	/* usually in_interrupt(), but not always */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	spin_lock_irqsave(&channel->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	/* must add to the back when receiving; doesn't matter when sending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	list_add_tail(&urb->urb_list, &channel->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	spin_unlock_irqrestore(&channel->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	if (unlikely(status) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 			(!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 			 status != -EILSEQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		if (status == -ESHUTDOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		if (printk_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 			atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 				__func__, urb, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		/* throttle processing in case of an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		tasklet_schedule(&channel->tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) }
^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) **  decode  **
^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 inline struct usbatm_vcc_data *usbatm_find_vcc(struct usbatm_data *instance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 						  short vpi, int vci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	struct usbatm_vcc_data *vcc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	list_for_each_entry(vcc_data, &instance->vcc_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 		if ((vcc_data->vci == vci) && (vcc_data->vpi == vpi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 			return vcc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char *source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	struct atm_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	struct sk_buff *sarb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	short vpi = ((source[0] & 0x0f) << 4)  | (source[1] >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	int vci = ((source[1] & 0x0f) << 12) | (source[2] << 4) | (source[3] >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	u8 pti = ((source[3] & 0xe) >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	if ((vci != instance->cached_vci) || (vpi != instance->cached_vpi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		instance->cached_vpi = vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		instance->cached_vci = vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		instance->cached_vcc = usbatm_find_vcc(instance, vpi, vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		if (!instance->cached_vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 			atm_rldbg(instance, "%s: unknown vpi/vci (%hd/%d)!\n", __func__, vpi, vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	if (!instance->cached_vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	vcc = instance->cached_vcc->vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	/* OAM F5 end-to-end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	if (pti == ATM_PTI_E2EF5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		if (printk_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 			atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 				__func__, vpi, vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		atomic_inc(&vcc->stats->rx_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	sarb = instance->cached_vcc->sarb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		atm_rldbg(instance, "%s: buffer overrun (sarb->len %u, vcc: 0x%p)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 				__func__, sarb->len, vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		/* discard cells already received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		skb_trim(sarb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	memcpy(skb_tail_pointer(sarb), source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	__skb_put(sarb, ATM_CELL_PAYLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	if (pti & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		unsigned int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		unsigned int pdu_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		length = (source[ATM_CELL_SIZE - 6] << 8) + source[ATM_CELL_SIZE - 5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		/* guard against overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		if (length > ATM_MAX_AAL5_PDU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 			atm_rldbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 				  __func__, length, vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 			atomic_inc(&vcc->stats->rx_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		pdu_length = usbatm_pdu_length(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		if (sarb->len < pdu_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 			atm_rldbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 				  __func__, pdu_length, sarb->len, vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 			atomic_inc(&vcc->stats->rx_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 			goto out;
^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) 		if (crc32_be(~0, skb_tail_pointer(sarb) - pdu_length, pdu_length) != 0xc704dd7b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 			atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 				  __func__, vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 			atomic_inc(&vcc->stats->rx_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		vdbg(&instance->usb_intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		     "%s: got packet (length: %u, pdu_length: %u, vcc: 0x%p)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		     __func__, length, pdu_length, vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		skb = dev_alloc_skb(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 			if (printk_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 				atm_err(instance, "%s: no memory for skb (length: %u)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 					__func__, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 			atomic_inc(&vcc->stats->rx_drop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		vdbg(&instance->usb_intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		     "%s: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		     __func__, skb, skb->truesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		if (!atm_charge(vcc, skb->truesize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 			atm_rldbg(instance, "%s: failed atm_charge (skb->truesize: %u)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 				  __func__, skb->truesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 			dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 			goto out;	/* atm_charge increments rx_drop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		skb_copy_to_linear_data(skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 					skb_tail_pointer(sarb) - pdu_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 					length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		__skb_put(skb, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		vdbg(&instance->usb_intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		     "%s: sending skb 0x%p, skb->len %u, skb->truesize %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		     __func__, skb, skb->len, skb->truesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		PACKETDEBUG(instance, skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		vcc->push(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		atomic_inc(&vcc->stats->rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		skb_trim(sarb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) static void usbatm_extract_cells(struct usbatm_data *instance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		unsigned char *source, unsigned int avail_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	unsigned int stride = instance->rx_channel.stride;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	unsigned int buf_usage = instance->buf_usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	/* extract cells from incoming data, taking into account that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	 * the length of avail data may not be a multiple of stride */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	if (buf_usage > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		/* we have a partially received atm cell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		unsigned char *cell_buf = instance->cell_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		unsigned int space_left = stride - buf_usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		if (avail_data >= space_left) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 			/* add new data and process cell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 			memcpy(cell_buf + buf_usage, source, space_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			source += space_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 			avail_data -= space_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 			usbatm_extract_one_cell(instance, cell_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 			instance->buf_usage = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 			/* not enough data to fill the cell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 			memcpy(cell_buf + buf_usage, source, avail_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 			instance->buf_usage = buf_usage + avail_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	for (; avail_data >= stride; avail_data -= stride, source += stride)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		usbatm_extract_one_cell(instance, source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	if (avail_data > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		/* length was not a multiple of stride -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		 * save remaining data for next call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		memcpy(instance->cell_buf, source, avail_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		instance->buf_usage = avail_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) /*************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) **  encode  **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) *************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) static unsigned int usbatm_write_cells(struct usbatm_data *instance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 				       struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 				       u8 *target, unsigned int avail_space)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	struct usbatm_control *ctrl = UDSL_SKB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	struct atm_vcc *vcc = ctrl->atm.vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	unsigned int bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	unsigned int stride = instance->tx_channel.stride;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	for (bytes_written = 0; bytes_written < avail_space && ctrl->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	     bytes_written += stride, target += stride) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		unsigned int data_len = min_t(unsigned int, skb->len, ATM_CELL_PAYLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		unsigned int left = ATM_CELL_PAYLOAD - data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		u8 *ptr = target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		ptr[0] = vcc->vpi >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		ptr[1] = (vcc->vpi << 4) | (vcc->vci >> 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		ptr[2] = vcc->vci >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		ptr[3] = vcc->vci << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		ptr[4] = 0xec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		ptr += ATM_CELL_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		skb_copy_from_linear_data(skb, ptr, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		ptr += data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		__skb_pull(skb, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		if (!left)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		memset(ptr, 0, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		if (left >= ATM_AAL5_TRAILER) {	/* trailer will go in this cell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 			u8 *trailer = target + ATM_CELL_SIZE - ATM_AAL5_TRAILER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			/* trailer[0] = 0;		UU = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 			/* trailer[1] = 0;		CPI = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			trailer[2] = ctrl->len >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			trailer[3] = ctrl->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 			ctrl->crc = ~crc32_be(ctrl->crc, ptr, left - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 			trailer[4] = ctrl->crc >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 			trailer[5] = ctrl->crc >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 			trailer[6] = ctrl->crc >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 			trailer[7] = ctrl->crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 			target[3] |= 0x2;	/* adjust PTI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			ctrl->len = 0;		/* tag this skb finished */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 			ctrl->crc = crc32_be(ctrl->crc, ptr, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	return bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) /**************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) **  receive  **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) **************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) static void usbatm_rx_process(struct tasklet_struct *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	struct usbatm_data *instance = from_tasklet(instance, t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 						    rx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	while ((urb = usbatm_pop_urb(&instance->rx_channel))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		vdbg(&instance->usb_intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		     "%s: processing urb 0x%p", __func__, urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		if (usb_pipeisoc(urb->pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 			unsigned char *merge_start = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 			unsigned int merge_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 			const unsigned int packet_size = instance->rx_channel.packet_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 			int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 			for (i = 0; i < urb->number_of_packets; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 				if (!urb->iso_frame_desc[i].status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 					unsigned int actual_length = urb->iso_frame_desc[i].actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 					if (!merge_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 						merge_start = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 					merge_length += actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 					if (merge_length && (actual_length < packet_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 						usbatm_extract_cells(instance, merge_start, merge_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 						merge_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 					atm_rldbg(instance, "%s: status %d in frame %d!\n", __func__, urb->status, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 					if (merge_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 						usbatm_extract_cells(instance, merge_start, merge_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 					merge_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 					instance->buf_usage = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 			if (merge_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 				usbatm_extract_cells(instance, merge_start, merge_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 			if (!urb->status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 				usbatm_extract_cells(instance, urb->transfer_buffer, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 				instance->buf_usage = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		if (usbatm_submit_urb(urb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) /***********
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) **  send  **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) ***********/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) static void usbatm_tx_process(struct tasklet_struct *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	struct usbatm_data *instance = from_tasklet(instance, t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 						    tx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	struct sk_buff *skb = instance->current_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	struct urb *urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	const unsigned int buf_size = instance->tx_channel.buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	unsigned int bytes_written = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	u8 *buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		skb = skb_dequeue(&instance->sndqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	while (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		if (!urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 			urb = usbatm_pop_urb(&instance->tx_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 			if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 				break;		/* no more senders */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 			buffer = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 			bytes_written = (urb->status == -EAGAIN) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 				urb->transfer_buffer_length : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		bytes_written += usbatm_write_cells(instance, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 						  buffer + bytes_written,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 						  buf_size - bytes_written);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		vdbg(&instance->usb_intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		     "%s: wrote %u bytes from skb 0x%p to urb 0x%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		     __func__, bytes_written, skb, urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		if (!UDSL_SKB(skb)->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 			struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 			usbatm_pop(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 			atomic_inc(&vcc->stats->tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 			skb = skb_dequeue(&instance->sndqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		if (bytes_written == buf_size || (!skb && bytes_written)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 			urb->transfer_buffer_length = bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 			if (usbatm_submit_urb(urb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 			urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	instance->current_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) static void usbatm_cancel_send(struct usbatm_data *instance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 			       struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	struct sk_buff *skb, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	spin_lock_irq(&instance->sndqueue.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	skb_queue_walk_safe(&instance->sndqueue, skb, n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		if (UDSL_SKB(skb)->atm.vcc == vcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 			atm_dbg(instance, "%s: popping skb 0x%p\n", __func__, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 			__skb_unlink(skb, &instance->sndqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 			usbatm_pop(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	spin_unlock_irq(&instance->sndqueue.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	tasklet_disable(&instance->tx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	if ((skb = instance->current_skb) && (UDSL_SKB(skb)->atm.vcc == vcc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		atm_dbg(instance, "%s: popping current skb (0x%p)\n", __func__, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		instance->current_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		usbatm_pop(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	tasklet_enable(&instance->tx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	struct usbatm_data *instance = vcc->dev->dev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	struct usbatm_control *ctrl = UDSL_SKB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	/* racy disconnection check - fine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	if (!instance || instance->disconnected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) #ifdef VERBOSE_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		printk_ratelimited(KERN_DEBUG "%s: %s!\n", __func__, instance ? "disconnected" : "NULL instance");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	if (vcc->qos.aal != ATM_AAL5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		atm_rldbg(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	if (skb->len > ATM_MAX_AAL5_PDU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		atm_rldbg(instance, "%s: packet too long (%d vs %d)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 				__func__, skb->len, ATM_MAX_AAL5_PDU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	PACKETDEBUG(instance, skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	/* initialize the control block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	ctrl->atm.vcc = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	ctrl->len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	ctrl->crc = crc32_be(~0, skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	skb_queue_tail(&instance->sndqueue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	tasklet_schedule(&instance->tx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684)  fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	usbatm_pop(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) /********************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) **  bean counting  **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) ********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) static void usbatm_destroy_instance(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	struct usbatm_data *instance = container_of(kref, struct usbatm_data, refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	tasklet_kill(&instance->rx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	tasklet_kill(&instance->tx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	usb_put_dev(instance->usb_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	kfree(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) static void usbatm_get_instance(struct usbatm_data *instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	kref_get(&instance->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) static void usbatm_put_instance(struct usbatm_data *instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	kref_put(&instance->refcount, usbatm_destroy_instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) /**********
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) **  ATM  **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) **********/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) static void usbatm_atm_dev_close(struct atm_dev *atm_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	struct usbatm_data *instance = atm_dev->dev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	if (!instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	atm_dev->dev_data = NULL; /* catch bugs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	usbatm_put_instance(instance);	/* taken in usbatm_atm_init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t *pos, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	struct usbatm_data *instance = atm_dev->dev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	int left = *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	if (!instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		return sprintf(page, "%s\n", instance->description);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		return sprintf(page, "MAC: %pM\n", atm_dev->esi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		return sprintf(page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			       "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 			       atomic_read(&atm_dev->stats.aal5.tx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 			       atomic_read(&atm_dev->stats.aal5.tx_err),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 			       atomic_read(&atm_dev->stats.aal5.rx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			       atomic_read(&atm_dev->stats.aal5.rx_err),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 			       atomic_read(&atm_dev->stats.aal5.rx_drop));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	if (!left--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		if (instance->disconnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 			return sprintf(page, "Disconnected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 			switch (atm_dev->signal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 			case ATM_PHY_SIG_FOUND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 				return sprintf(page, "Line up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 			case ATM_PHY_SIG_LOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 				return sprintf(page, "Line down\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 				return sprintf(page, "Line state unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) static int usbatm_atm_open(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	struct usbatm_data *instance = vcc->dev->dev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	struct usbatm_vcc_data *new = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	int vci = vcc->vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	short vpi = vcc->vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	if (!instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	/* only support AAL5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	if ((vcc->qos.aal != ATM_AAL5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		atm_warn(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	/* sanity checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	if ((vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		atm_dbg(instance, "%s: max_sdu %d out of range!\n", __func__, vcc->qos.rxtp.max_sdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	mutex_lock(&instance->serialize);	/* vs self, usbatm_atm_close, usbatm_usb_disconnect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	if (instance->disconnected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		atm_dbg(instance, "%s: disconnected!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	if (usbatm_find_vcc(instance, vpi, vci)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		atm_dbg(instance, "%s: %hd/%d already in use!\n", __func__, vpi, vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		ret = -EADDRINUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	if (!new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	new->vcc = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	new->vpi = vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	new->vci = vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	new->sarb = alloc_skb(usbatm_pdu_length(vcc->qos.rxtp.max_sdu), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	if (!new->sarb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		atm_err(instance, "%s: no memory for SAR buffer!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	vcc->dev_data = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	tasklet_disable(&instance->rx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	instance->cached_vcc = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	instance->cached_vpi = vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	instance->cached_vci = vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	list_add(&new->list, &instance->vcc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	tasklet_enable(&instance->rx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	set_bit(ATM_VF_ADDR, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	set_bit(ATM_VF_PARTIAL, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	set_bit(ATM_VF_READY, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	mutex_unlock(&instance->serialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	atm_dbg(instance, "%s: allocated vcc data 0x%p\n", __func__, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	kfree(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	mutex_unlock(&instance->serialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) static void usbatm_atm_close(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	struct usbatm_data *instance = vcc->dev->dev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	struct usbatm_vcc_data *vcc_data = vcc->dev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	if (!instance || !vcc_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	usbatm_cancel_send(instance, vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	mutex_lock(&instance->serialize);	/* vs self, usbatm_atm_open, usbatm_usb_disconnect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	tasklet_disable(&instance->rx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	if (instance->cached_vcc == vcc_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		instance->cached_vcc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		instance->cached_vpi = ATM_VPI_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		instance->cached_vci = ATM_VCI_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	list_del(&vcc_data->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	tasklet_enable(&instance->rx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	kfree_skb(vcc_data->sarb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	vcc_data->sarb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	kfree(vcc_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	vcc->dev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	vcc->vpi = ATM_VPI_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	vcc->vci = ATM_VCI_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	clear_bit(ATM_VF_READY, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	clear_bit(ATM_VF_PARTIAL, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	clear_bit(ATM_VF_ADDR, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	mutex_unlock(&instance->serialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 			  void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	struct usbatm_data *instance = atm_dev->dev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	if (!instance || instance->disconnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	case ATM_QUERYLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		return put_user(ATM_LM_NONE, (int __user *)arg) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) static int usbatm_atm_init(struct usbatm_data *instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	struct atm_dev *atm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	/* ATM init.  The ATM initialization scheme suffers from an intrinsic race
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	 * condition: callbacks we register can be executed at once, before we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	 * initialized the struct atm_dev.  To protect against this, all callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	 * abort if atm_dev->dev_data is NULL. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	atm_dev = atm_dev_register(instance->driver_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 				   &instance->usb_intf->dev, &usbatm_atm_devops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 				   -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	if (!atm_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		usb_err(instance, "%s: failed to register ATM device!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	instance->atm_dev = atm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	atm_dev->ci_range.vci_bits = ATM_CI_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	/* temp init ATM device, set to 128kbit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	atm_dev->link_rate = 128 * 1000 / 424;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	usbatm_get_instance(instance);	/* dropped in usbatm_atm_dev_close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	/* ready for ATM callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	atm_dev->dev_data = instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	/* submit all rx URBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	for (i = 0; i < num_rcv_urbs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		usbatm_submit_urb(instance->urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944)  fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	instance->atm_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) /**********
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) **  USB  **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) **********/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) static int usbatm_do_heavy_init(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	struct usbatm_data *instance = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	allow_signal(SIGTERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	complete(&instance->thread_started);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	ret = instance->driver->heavy_init(instance, instance->usb_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		ret = usbatm_atm_init(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	mutex_lock(&instance->serialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	instance->thread = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	mutex_unlock(&instance->serialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	complete_and_exit(&instance->thread_exited, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) static int usbatm_heavy_init(struct usbatm_data *instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	struct task_struct *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	t = kthread_create(usbatm_do_heavy_init, instance, "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 			instance->driver->driver_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	if (IS_ERR(t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		usb_err(instance, "%s: failed to create kernel_thread (%ld)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 				__func__, PTR_ERR(t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		return PTR_ERR(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	instance->thread = t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	wake_up_process(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	wait_for_completion(&instance->thread_started);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) static void usbatm_tasklet_schedule(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	struct usbatm_channel *channel = from_timer(channel, t, delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	tasklet_schedule(&channel->tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static void usbatm_init_channel(struct usbatm_channel *channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	spin_lock_init(&channel->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	INIT_LIST_HEAD(&channel->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	timer_setup(&channel->delay, usbatm_tasklet_schedule, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		     struct usbatm_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	struct device *dev = &intf->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	struct usb_device *usb_dev = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	struct usbatm_data *instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	int error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	int i, length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	unsigned int maxpacket, num_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	/* instance init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	instance = kzalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	if (!instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	/* public fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	instance->driver = driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	strlcpy(instance->driver_name, driver->driver_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		sizeof(instance->driver_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	instance->usb_dev = usb_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	instance->usb_intf = intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	buf = instance->description;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	length = sizeof(instance->description);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	if ((i = usb_string(usb_dev, usb_dev->descriptor.iProduct, buf, length)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		goto bind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	buf += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	length -= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	i = scnprintf(buf, length, " (");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	buf += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	length -= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	if (length <= 0 || (i = usb_make_path(usb_dev, buf, length)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		goto bind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	buf += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	length -= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	snprintf(buf, length, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)  bind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	if (driver->bind && (error = driver->bind(instance, intf, id)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 			dev_err(dev, "%s: bind failed: %d!\n", __func__, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			goto fail_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	/* private fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	kref_init(&instance->refcount);		/* dropped in usbatm_usb_disconnect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	mutex_init(&instance->serialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	instance->thread = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	init_completion(&instance->thread_started);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	init_completion(&instance->thread_exited);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	INIT_LIST_HEAD(&instance->vcc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	skb_queue_head_init(&instance->sndqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	usbatm_init_channel(&instance->rx_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	usbatm_init_channel(&instance->tx_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	tasklet_setup(&instance->rx_channel.tasklet, usbatm_rx_process);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	tasklet_setup(&instance->tx_channel.tasklet, usbatm_tx_process);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	if ((instance->flags & UDSL_USE_ISOC) && driver->isoc_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		instance->rx_channel.endpoint = usb_rcvisocpipe(usb_dev, driver->isoc_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->bulk_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->bulk_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	/* tx buffer size must be a positive multiple of the stride */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	instance->tx_channel.buf_size = max(instance->tx_channel.stride,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 			snd_buf_bytes - (snd_buf_bytes % instance->tx_channel.stride));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	/* rx buffer size must be a positive multiple of the endpoint maxpacket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	maxpacket = usb_maxpacket(usb_dev, instance->rx_channel.endpoint, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	if ((maxpacket < 1) || (maxpacket > UDSL_MAX_BUF_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		dev_err(dev, "%s: invalid endpoint %02x!\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 				usb_pipeendpoint(instance->rx_channel.endpoint));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		goto fail_unbind;
^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) 	num_packets = max(1U, (rcv_buf_bytes + maxpacket / 2) / maxpacket); /* round */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	if (num_packets * maxpacket > UDSL_MAX_BUF_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 		num_packets--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	instance->rx_channel.buf_size = num_packets * maxpacket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	instance->rx_channel.packet_size = maxpacket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		struct usbatm_channel *channel = i ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 			&instance->tx_channel : &instance->rx_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		dev_dbg(dev, "%s: using %d byte buffer for %s channel 0x%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			__func__, channel->buf_size, i ? "tx" : "rx", channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	/* initialize urbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		u8 *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		struct usbatm_channel *channel = i < num_rcv_urbs ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 			&instance->rx_channel : &instance->tx_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		unsigned int iso_packets = usb_pipeisoc(channel->endpoint) ? channel->buf_size / channel->packet_size : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		urb = usb_alloc_urb(iso_packets, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		if (!urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 			goto fail_unbind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		instance->urbs[i] = urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		/* zero the tx padding to avoid leaking information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		buffer = kzalloc(channel->buf_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		if (!buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 			error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 			goto fail_unbind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		usb_fill_bulk_urb(urb, instance->usb_dev, channel->endpoint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 				  buffer, channel->buf_size, usbatm_complete, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		if (iso_packets) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 			int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 			urb->interval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			urb->transfer_flags = URB_ISO_ASAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 			urb->number_of_packets = iso_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 			for (j = 0; j < iso_packets; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 				urb->iso_frame_desc[j].offset = channel->packet_size * j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 				urb->iso_frame_desc[j].length = channel->packet_size;
^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) 		/* put all tx URBs on the list of spares */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 		if (i >= num_rcv_urbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 			list_add_tail(&urb->urb_list, &channel->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		vdbg(&intf->dev, "%s: alloced buffer 0x%p buf size %u urb 0x%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		     __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	instance->cached_vpi = ATM_VPI_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	instance->cached_vci = ATM_VCI_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	instance->cell_buf = kmalloc(instance->rx_channel.stride, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	if (!instance->cell_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		goto fail_unbind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	if (!(instance->flags & UDSL_SKIP_HEAVY_INIT) && driver->heavy_init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		error = usbatm_heavy_init(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		complete(&instance->thread_exited);	/* pretend that heavy_init was run */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		error = usbatm_atm_init(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 		goto fail_unbind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	usb_get_dev(usb_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	usb_set_intfdata(intf, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)  fail_unbind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	if (instance->driver->unbind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		instance->driver->unbind(instance, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)  fail_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	kfree(instance->cell_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		if (instance->urbs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			kfree(instance->urbs[i]->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		usb_free_urb(instance->urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	kfree(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) EXPORT_SYMBOL_GPL(usbatm_usb_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) void usbatm_usb_disconnect(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	struct device *dev = &intf->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	struct usbatm_data *instance = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	struct usbatm_vcc_data *vcc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	if (!instance) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		dev_dbg(dev, "%s: NULL instance!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	usb_set_intfdata(intf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	mutex_lock(&instance->serialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	instance->disconnected = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	if (instance->thread != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		send_sig(SIGTERM, instance->thread, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	mutex_unlock(&instance->serialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	wait_for_completion(&instance->thread_exited);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	mutex_lock(&instance->serialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	list_for_each_entry(vcc_data, &instance->vcc_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		vcc_release_async(vcc_data->vcc, -EPIPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	mutex_unlock(&instance->serialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	tasklet_disable(&instance->rx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	tasklet_disable(&instance->tx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		usb_kill_urb(instance->urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	del_timer_sync(&instance->rx_channel.delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	del_timer_sync(&instance->tx_channel.delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	/* turn usbatm_[rt]x_process into something close to a no-op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	/* no need to take the spinlock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	INIT_LIST_HEAD(&instance->rx_channel.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	INIT_LIST_HEAD(&instance->tx_channel.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	tasklet_enable(&instance->rx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	tasklet_enable(&instance->tx_channel.tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	if (instance->atm_dev && instance->driver->atm_stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		instance->driver->atm_stop(instance, instance->atm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	if (instance->driver->unbind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		instance->driver->unbind(instance, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	instance->driver_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		kfree(instance->urbs[i]->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		usb_free_urb(instance->urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	kfree(instance->cell_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	/* ATM finalize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	if (instance->atm_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 		atm_dev_deregister(instance->atm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		instance->atm_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	usbatm_put_instance(instance);	/* taken in usbatm_usb_probe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) EXPORT_SYMBOL_GPL(usbatm_usb_disconnect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /***********
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) **  init  **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) ***********/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) static int __init usbatm_usb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	if (sizeof(struct usbatm_control) > sizeof_field(struct sk_buff, cb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		printk(KERN_ERR "%s unusable with this kernel!\n", usbatm_driver_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	if ((num_rcv_urbs > UDSL_MAX_RCV_URBS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	    || (num_snd_urbs > UDSL_MAX_SND_URBS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	    || (rcv_buf_bytes < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	    || (rcv_buf_bytes > UDSL_MAX_BUF_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	    || (snd_buf_bytes < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	    || (snd_buf_bytes > UDSL_MAX_BUF_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) module_init(usbatm_usb_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static void __exit usbatm_usb_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) module_exit(usbatm_usb_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) **  debug  **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) ************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) #ifdef VERBOSE_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) static int usbatm_print_packet(struct usbatm_data *instance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 			       const unsigned char *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	unsigned char buffer[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	int i = 0, j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	for (i = 0; i < len;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 		buffer[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		sprintf(buffer, "%.3d :", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 		for (j = 0; (j < 16) && (i < len); j++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 			sprintf(buffer, "%s %2.2x", buffer, data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 		dev_dbg(&instance->usb_intf->dev, "%s", buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) #endif