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)  * mos7720.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *   Controls the Moschip 7720 usb to dual port serial converter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright 2006 Moschip Semiconductor Tech. Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Developed by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * 	Vijaya Kumar <vijaykumar.gn@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *	Ajay Kumar <naanuajay@yahoo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *	Gurudeva <ngurudeva@yahoo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * Cleaned up from the original by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *	Greg Kroah-Hartman <gregkh@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * Originally based on drivers/usb/serial/io_edgeport.c which is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *	Copyright (C) 2000 Inside Out Networks, All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *	Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/tty_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/serial_reg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/usb/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/parport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define DRIVER_AUTHOR "Aspire Communications pvt Ltd."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define DRIVER_DESC "Moschip USB Serial Driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) /* default urb timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define MOS_WDR_TIMEOUT	5000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define MOS_MAX_PORT	0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define MOS_WRITE	0x0E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define MOS_READ	0x0D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) /* Interrupt Routines Defines	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define SERIAL_IIR_RLS	0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define SERIAL_IIR_RDA	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define SERIAL_IIR_CTI	0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define SERIAL_IIR_THR	0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define SERIAL_IIR_MS	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define NUM_URBS			16	/* URB Count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define URB_TRANSFER_BUFFER_SIZE	32	/* URB Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) /* This structure holds all of the local serial port information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) struct moschip_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	__u8	shadowLCR;		/* last LCR value received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	__u8	shadowMCR;		/* last MCR value received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	__u8	shadowMSR;		/* last MSR value received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	char			open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	struct usb_serial_port	*port;	/* loop back to the owner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	struct urb		*write_urb_pool[NUM_URBS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define USB_VENDOR_ID_MOSCHIP		0x9710
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define MOSCHIP_DEVICE_ID_7720		0x7720
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define MOSCHIP_DEVICE_ID_7715		0x7715
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) static const struct usb_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	{ USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	{ USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7715) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	{ } /* terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) MODULE_DEVICE_TABLE(usb, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) /* initial values for parport regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define DCR_INIT_VAL       0x0c	/* SLCTIN, nINIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define ECR_INIT_VAL       0x00	/* SPP mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) struct urbtracker {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	struct mos7715_parport  *mos_parport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	struct list_head        urblist_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	struct kref             ref_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	struct urb              *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	struct usb_ctrlrequest	*setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) enum mos7715_pp_modes {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	SPP = 0<<5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	PS2 = 1<<5,      /* moschip calls this 'NIBBLE' mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	PPF = 2<<5,	 /* moschip calls this 'CB-FIFO mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) struct mos7715_parport {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	struct parport          *pp;	       /* back to containing struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	struct kref             ref_count;     /* to instance of this struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	struct list_head        deferred_urbs; /* list deferred async urbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	struct list_head        active_urbs;   /* list async urbs in flight */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	spinlock_t              listlock;      /* protects list access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	bool                    msg_pending;   /* usb sync call pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	struct completion       syncmsg_compl; /* usb sync call completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	struct tasklet_struct   urb_tasklet;   /* for sending deferred urbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	struct usb_serial       *serial;       /* back to containing struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	__u8	                shadowECR;     /* parallel port regs... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	__u8	                shadowDCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	atomic_t                shadowDSR;     /* updated in int-in callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) /* lock guards against dereferencing NULL ptr in parport ops callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) static DEFINE_SPINLOCK(release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #endif	/* CONFIG_USB_SERIAL_MOS7715_PARPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) static const unsigned int dummy; /* for clarity in register access fns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) enum mos_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	MOS7720_THR,		  /* serial port regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	MOS7720_RHR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	MOS7720_IER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	MOS7720_FCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	MOS7720_ISR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	MOS7720_LCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	MOS7720_MCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	MOS7720_LSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	MOS7720_MSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	MOS7720_SPR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	MOS7720_DLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	MOS7720_DLM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	MOS7720_DPR,		  /* parallel port regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	MOS7720_DSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	MOS7720_DCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	MOS7720_ECR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	MOS7720_SP1_REG,	  /* device control regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	MOS7720_SP2_REG,	  /* serial port 2 (7720 only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	MOS7720_PP_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	MOS7720_SP_CONTROL_REG,
^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)  * Return the correct value for the Windex field of the setup packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143)  * for a control endpoint message.  See the 7715 datasheet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) static inline __u16 get_reg_index(enum mos_regs reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	static const __u16 mos7715_index_lookup_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		0x00,		/* MOS7720_THR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		0x00,		/* MOS7720_RHR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 		0x01,		/* MOS7720_IER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		0x02,		/* MOS7720_FCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 		0x02,		/* MOS7720_ISR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 		0x03,		/* MOS7720_LCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		0x04,		/* MOS7720_MCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		0x05,		/* MOS7720_LSR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 		0x06,		/* MOS7720_MSR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 		0x07,		/* MOS7720_SPR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 		0x00,		/* MOS7720_DLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		0x01,		/* MOS7720_DLM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		0x00,		/* MOS7720_DPR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		0x01,		/* MOS7720_DSR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		0x02,		/* MOS7720_DCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		0x0a,		/* MOS7720_ECR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		0x01,		/* MOS7720_SP1_REG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		0x02,		/* MOS7720_SP2_REG (7720 only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		0x04,		/* MOS7720_PP_REG (7715 only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		0x08,		/* MOS7720_SP_CONTROL_REG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	return mos7715_index_lookup_table[reg];
^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)  * Return the correct value for the upper byte of the Wvalue field of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174)  * the setup packet for a control endpoint message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) static inline __u16 get_reg_value(enum mos_regs reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 				  unsigned int serial_portnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	if (reg >= MOS7720_SP1_REG)	/* control reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		return 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	else if (reg >= MOS7720_DPR)	/* parallel port reg (7715 only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		return 0x0100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	else			      /* serial port reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		return (serial_portnum + 2) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)  * Write data byte to the specified device register.  The data is embedded in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191)  * the value field of the setup packet. serial_portnum is ignored for registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192)  * not specific to a particular serial port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) static int write_mos_reg(struct usb_serial *serial, unsigned int serial_portnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 			 enum mos_regs reg, __u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	struct usb_device *usbdev = serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	unsigned int pipe = usb_sndctrlpipe(usbdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	__u8 request = (__u8)0x0e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	__u8 requesttype = (__u8)0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	__u16 index = get_reg_index(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	__u16 value = get_reg_value(reg, serial_portnum) + data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	int status = usb_control_msg(usbdev, pipe, request, requesttype, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 				     index, NULL, 0, MOS_WDR_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		dev_err(&usbdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 			"mos7720: usb_control_msg() failed: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212)  * Read data byte from the specified device register.  The data returned by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213)  * device is embedded in the value field of the setup packet.  serial_portnum is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214)  * ignored for registers that are not specific to a particular serial port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 			enum mos_regs reg, __u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	struct usb_device *usbdev = serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	unsigned int pipe = usb_rcvctrlpipe(usbdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	__u8 request = (__u8)0x0d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	__u8 requesttype = (__u8)0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	__u16 index = get_reg_index(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	__u16 value = get_reg_value(reg, serial_portnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	buf = kmalloc(1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		*data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	status = usb_control_msg(usbdev, pipe, request, requesttype, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 				     index, buf, 1, MOS_WDR_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	if (status == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		*data = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		dev_err(&usbdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 			"mos7720: usb_control_msg() failed: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		if (status >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 			status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		*data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) static inline int mos7715_change_mode(struct mos7715_parport *mos_parport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 				      enum mos7715_pp_modes mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	mos_parport->shadowECR = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	write_mos_reg(mos_parport->serial, dummy, MOS7720_ECR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		      mos_parport->shadowECR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) static void destroy_mos_parport(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	struct mos7715_parport *mos_parport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		container_of(kref, struct mos7715_parport, ref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	kfree(mos_parport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) static void destroy_urbtracker(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	struct urbtracker *urbtrack =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 		container_of(kref, struct urbtracker, ref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	struct mos7715_parport *mos_parport = urbtrack->mos_parport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	usb_free_urb(urbtrack->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	kfree(urbtrack->setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	kfree(urbtrack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	kref_put(&mos_parport->ref_count, destroy_mos_parport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283)  * This runs as a tasklet when sending an urb in a non-blocking parallel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284)  * port callback had to be deferred because the disconnect mutex could not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285)  * obtained at the time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) static void send_deferred_urbs(struct tasklet_struct *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	struct mos7715_parport *mos_parport = from_tasklet(mos_parport, t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 							   urb_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	struct urbtracker *urbtrack, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	struct list_head *cursor, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	/* if release function ran, game over */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	if (unlikely(mos_parport->serial == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	dev = &mos_parport->serial->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	/* try again to get the mutex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	if (!mutex_trylock(&mos_parport->serial->disc_mutex)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		dev_dbg(dev, "%s: rescheduling tasklet\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		tasklet_schedule(&mos_parport->urb_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	/* if device disconnected, game over */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	if (unlikely(mos_parport->serial->disconnected)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		mutex_unlock(&mos_parport->serial->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	spin_lock_irqsave(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	if (list_empty(&mos_parport->deferred_urbs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		spin_unlock_irqrestore(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		mutex_unlock(&mos_parport->serial->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		dev_dbg(dev, "%s: deferred_urbs list empty\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	/* move contents of deferred_urbs list to active_urbs list and submit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	list_for_each_safe(cursor, next, &mos_parport->deferred_urbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		list_move_tail(cursor, &mos_parport->active_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	list_for_each_entry_safe(urbtrack, tmp, &mos_parport->active_urbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 			    urblist_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		ret_val = usb_submit_urb(urbtrack->urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		dev_dbg(dev, "%s: urb submitted\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		if (ret_val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 			dev_err(dev, "usb_submit_urb() failed: %d\n", ret_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			list_del(&urbtrack->urblist_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			kref_put(&urbtrack->ref_count, destroy_urbtracker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	spin_unlock_irqrestore(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	mutex_unlock(&mos_parport->serial->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) /* callback for parallel port control urbs submitted asynchronously */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) static void async_complete(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	struct urbtracker *urbtrack = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	if (unlikely(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		dev_dbg(&urb->dev->dev, "%s - nonzero urb status received: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	/* remove the urbtracker from the active_urbs list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	spin_lock_irqsave(&urbtrack->mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	list_del(&urbtrack->urblist_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	spin_unlock_irqrestore(&urbtrack->mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	kref_put(&urbtrack->ref_count, destroy_urbtracker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 				      enum mos_regs reg, __u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	struct urbtracker *urbtrack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	struct usb_serial *serial = mos_parport->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	struct usb_device *usbdev = serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	/* create and initialize the control urb and containing urbtracker */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	urbtrack = kmalloc(sizeof(struct urbtracker), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	if (!urbtrack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	urbtrack->urb = usb_alloc_urb(0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	if (!urbtrack->urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		kfree(urbtrack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	if (!urbtrack->setup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		usb_free_urb(urbtrack->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		kfree(urbtrack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	urbtrack->setup->bRequestType = (__u8)0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	urbtrack->setup->bRequest = (__u8)0x0e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	urbtrack->setup->wValue = cpu_to_le16(get_reg_value(reg, dummy));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	urbtrack->setup->wIndex = cpu_to_le16(get_reg_index(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	urbtrack->setup->wLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	usb_fill_control_urb(urbtrack->urb, usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 			     usb_sndctrlpipe(usbdev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 			     (unsigned char *)urbtrack->setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 			     NULL, 0, async_complete, urbtrack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	kref_get(&mos_parport->ref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	urbtrack->mos_parport = mos_parport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	kref_init(&urbtrack->ref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	INIT_LIST_HEAD(&urbtrack->urblist_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	 * get the disconnect mutex, or add tracker to the deferred_urbs list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	 * and schedule a tasklet to try again later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	if (!mutex_trylock(&serial->disc_mutex)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 		spin_lock_irqsave(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		list_add_tail(&urbtrack->urblist_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 			      &mos_parport->deferred_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		spin_unlock_irqrestore(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		tasklet_schedule(&mos_parport->urb_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		dev_dbg(&usbdev->dev, "tasklet scheduled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	/* bail if device disconnected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	if (serial->disconnected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		kref_put(&urbtrack->ref_count, destroy_urbtracker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		mutex_unlock(&serial->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	/* add the tracker to the active_urbs list and submit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	spin_lock_irqsave(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	list_add_tail(&urbtrack->urblist_entry, &mos_parport->active_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	spin_unlock_irqrestore(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	ret_val = usb_submit_urb(urbtrack->urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	mutex_unlock(&serial->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	if (ret_val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		dev_err(&usbdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			"%s: submit_urb() failed: %d\n", __func__, ret_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		spin_lock_irqsave(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		list_del(&urbtrack->urblist_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 		spin_unlock_irqrestore(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		kref_put(&urbtrack->ref_count, destroy_urbtracker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) }
^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)  * This is the the common top part of all parallel port callback operations that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438)  * send synchronous messages to the device.  This implements convoluted locking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439)  * that avoids two scenarios: (1) a port operation is called after usbserial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440)  * has called our release function, at which point struct mos7715_parport has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441)  * been destroyed, and (2) the device has been disconnected, but usbserial has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442)  * not called the release function yet because someone has a serial port open.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443)  * The shared release_lock prevents the first, and the mutex and disconnected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444)  * flag maintained by usbserial covers the second.  We also use the msg_pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445)  * flag to ensure that all synchronous usb message calls have completed before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446)  * our release function can return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) static int parport_prologue(struct parport *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	struct mos7715_parport *mos_parport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	spin_lock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	if (unlikely(mos_parport == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		/* release fn called, port struct destroyed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	mos_parport->msg_pending = true;   /* synch usb call pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	reinit_completion(&mos_parport->syncmsg_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	mutex_lock(&mos_parport->serial->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	if (mos_parport->serial->disconnected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		/* device disconnected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		mutex_unlock(&mos_parport->serial->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		mos_parport->msg_pending = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		complete(&mos_parport->syncmsg_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)  * This is the common bottom part of all parallel port functions that send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477)  * synchronous messages to the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) static inline void parport_epilogue(struct parport *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	struct mos7715_parport *mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	mutex_unlock(&mos_parport->serial->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	mos_parport->msg_pending = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	complete(&mos_parport->syncmsg_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) static void parport_mos7715_write_data(struct parport *pp, unsigned char d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	struct mos7715_parport *mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	if (parport_prologue(pp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	mos7715_change_mode(mos_parport, SPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	write_mos_reg(mos_parport->serial, dummy, MOS7720_DPR, (__u8)d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	parport_epilogue(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) static unsigned char parport_mos7715_read_data(struct parport *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	struct mos7715_parport *mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	unsigned char d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	if (parport_prologue(pp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	read_mos_reg(mos_parport->serial, dummy, MOS7720_DPR, &d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	parport_epilogue(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	return d;
^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) static void parport_mos7715_write_control(struct parport *pp, unsigned char d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	struct mos7715_parport *mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	__u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	if (parport_prologue(pp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	data = ((__u8)d & 0x0f) | (mos_parport->shadowDCR & 0xf0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	mos_parport->shadowDCR = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	parport_epilogue(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) static unsigned char parport_mos7715_read_control(struct parport *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	struct mos7715_parport *mos_parport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	__u8 dcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	spin_lock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	if (unlikely(mos_parport == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	dcr = mos_parport->shadowDCR & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	return dcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) static unsigned char parport_mos7715_frob_control(struct parport *pp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 						  unsigned char mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 						  unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	struct mos7715_parport *mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	__u8 dcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	mask &= 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	val &= 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	if (parport_prologue(pp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	mos_parport->shadowDCR = (mos_parport->shadowDCR & (~mask)) ^ val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		      mos_parport->shadowDCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	dcr = mos_parport->shadowDCR & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	parport_epilogue(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	return dcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) static unsigned char parport_mos7715_read_status(struct parport *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	struct mos7715_parport *mos_parport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	spin_lock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	if (unlikely(mos_parport == NULL)) {	/* release called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	status = atomic_read(&mos_parport->shadowDSR) & 0xf8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) static void parport_mos7715_enable_irq(struct parport *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) static void parport_mos7715_disable_irq(struct parport *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) static void parport_mos7715_data_forward(struct parport *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	struct mos7715_parport *mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	if (parport_prologue(pp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	mos7715_change_mode(mos_parport, PS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	mos_parport->shadowDCR &=  ~0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		      mos_parport->shadowDCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	parport_epilogue(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) static void parport_mos7715_data_reverse(struct parport *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	struct mos7715_parport *mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	if (parport_prologue(pp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	mos7715_change_mode(mos_parport, PS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	mos_parport->shadowDCR |= 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		      mos_parport->shadowDCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	parport_epilogue(pp);
^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) static void parport_mos7715_init_state(struct pardevice *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 				       struct parport_state *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	s->u.pc.ctr = DCR_INIT_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	s->u.pc.ecr = ECR_INIT_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) /* N.B. Parport core code requires that this function not block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) static void parport_mos7715_save_state(struct parport *pp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 				       struct parport_state *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	struct mos7715_parport *mos_parport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	spin_lock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	if (unlikely(mos_parport == NULL)) {	/* release called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	s->u.pc.ctr = mos_parport->shadowDCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	s->u.pc.ecr = mos_parport->shadowECR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) /* N.B. Parport core code requires that this function not block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) static void parport_mos7715_restore_state(struct parport *pp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 					  struct parport_state *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	struct mos7715_parport *mos_parport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	spin_lock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	if (unlikely(mos_parport == NULL)) {	/* release called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	mos_parport->shadowDCR = s->u.pc.ctr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	mos_parport->shadowECR = s->u.pc.ecr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	write_parport_reg_nonblock(mos_parport, MOS7720_DCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 				   mos_parport->shadowDCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	write_parport_reg_nonblock(mos_parport, MOS7720_ECR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 				   mos_parport->shadowECR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) static size_t parport_mos7715_write_compat(struct parport *pp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 					   const void *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 					   size_t len, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	struct mos7715_parport *mos_parport = pp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	int actual_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	if (parport_prologue(pp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	mos7715_change_mode(mos_parport, PPF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	retval = usb_bulk_msg(mos_parport->serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 			      usb_sndbulkpipe(mos_parport->serial->dev, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			      (void *)buffer, len, &actual_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			      MOS_WDR_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	parport_epilogue(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		dev_err(&mos_parport->serial->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			"mos7720: usb_bulk_msg() failed: %d\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	return actual_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) static struct parport_operations parport_mos7715_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	.owner =		THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	.write_data =		parport_mos7715_write_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	.read_data =		parport_mos7715_read_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	.write_control =	parport_mos7715_write_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	.read_control =		parport_mos7715_read_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	.frob_control =		parport_mos7715_frob_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	.read_status =		parport_mos7715_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	.enable_irq =		parport_mos7715_enable_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	.disable_irq =		parport_mos7715_disable_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	.data_forward =		parport_mos7715_data_forward,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	.data_reverse =		parport_mos7715_data_reverse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	.init_state =		parport_mos7715_init_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	.save_state =		parport_mos7715_save_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	.restore_state =	parport_mos7715_restore_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	.compat_write_data =	parport_mos7715_write_compat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	.nibble_read_data =	parport_ieee1284_read_nibble,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	.byte_read_data =	parport_ieee1284_read_byte,
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705)  * Allocate and initialize parallel port control struct, initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706)  * the parallel port hardware device, and register with the parport subsystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) static int mos7715_parport_init(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	struct mos7715_parport *mos_parport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	/* allocate and initialize parallel port control struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	mos_parport = kzalloc(sizeof(struct mos7715_parport), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	if (!mos_parport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	mos_parport->msg_pending = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	kref_init(&mos_parport->ref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	spin_lock_init(&mos_parport->listlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	INIT_LIST_HEAD(&mos_parport->active_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	INIT_LIST_HEAD(&mos_parport->deferred_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	usb_set_serial_data(serial, mos_parport); /* hijack private pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	mos_parport->serial = serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	tasklet_setup(&mos_parport->urb_tasklet, send_deferred_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	init_completion(&mos_parport->syncmsg_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	/* cycle parallel port reset bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	write_mos_reg(mos_parport->serial, dummy, MOS7720_PP_REG, (__u8)0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	write_mos_reg(mos_parport->serial, dummy, MOS7720_PP_REG, (__u8)0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	/* initialize device registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	mos_parport->shadowDCR = DCR_INIT_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		      mos_parport->shadowDCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	mos_parport->shadowECR = ECR_INIT_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	write_mos_reg(mos_parport->serial, dummy, MOS7720_ECR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		      mos_parport->shadowECR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	/* register with parport core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	mos_parport->pp = parport_register_port(0, PARPORT_IRQ_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 						PARPORT_DMA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 						&parport_mos7715_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	if (mos_parport->pp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		dev_err(&serial->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 			"Could not register parport\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		kref_put(&mos_parport->ref_count, destroy_mos_parport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	mos_parport->pp->private_data = mos_parport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	mos_parport->pp->modes = PARPORT_MODE_COMPAT | PARPORT_MODE_PCSPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	mos_parport->pp->dev = &serial->interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	parport_announce_port(mos_parport->pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) #endif	/* CONFIG_USB_SERIAL_MOS7715_PARPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759)  * mos7720_interrupt_callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760)  *	this is the callback function for when we have received data on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761)  *	interrupt endpoint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) static void mos7720_interrupt_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	struct device *dev = &urb->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	__u8 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	__u8 sp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	__u8 sp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		/* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		/* this urb is terminated, clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		dev_dbg(dev, "%s - urb shutting down with status: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	length = urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	/* Moschip get 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	 * Byte 1 IIR Port 1 (port.number is 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	 * Byte 2 IIR Port 2 (port.number is 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	 * Byte 3 --------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	 * Byte 4 FIFO status for both */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	/* the above description is inverted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	 * 	oneukum 2007-03-14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	if (unlikely(length != 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		dev_dbg(dev, "Wrong data !!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	sp1 = data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	sp2 = data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	if ((sp1 | sp2) & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		/* No Interrupt Pending in both the ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		dev_dbg(dev, "No Interrupt !!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		switch (sp1 & 0x0f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		case SERIAL_IIR_RLS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			dev_dbg(dev, "Serial Port 1: Receiver status error or address bit detected in 9-bit mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		case SERIAL_IIR_CTI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 			dev_dbg(dev, "Serial Port 1: Receiver time out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		case SERIAL_IIR_MS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			/* dev_dbg(dev, "Serial Port 1: Modem status change\n"); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 			break;
^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) 		switch (sp2 & 0x0f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		case SERIAL_IIR_RLS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 			dev_dbg(dev, "Serial Port 2: Receiver status error or address bit detected in 9-bit mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		case SERIAL_IIR_CTI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 			dev_dbg(dev, "Serial Port 2: Receiver time out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		case SERIAL_IIR_MS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			/* dev_dbg(dev, "Serial Port 2: Modem status change\n"); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	result = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		dev_err(dev, "%s - Error %d submitting control urb\n", __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844)  * mos7715_interrupt_callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845)  *	this is the 7715's callback function for when we have received data on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846)  *	the interrupt endpoint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) static void mos7715_interrupt_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	struct device *dev = &urb->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	__u8 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	__u8 iir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		/* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	case -ENODEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		/* this urb is terminated, clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		dev_dbg(dev, "%s - urb shutting down with status: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	length = urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	/* Structure of data from 7715 device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	 * Byte 1: IIR serial Port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	 * Byte 2: unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	 * Byte 2: DSR parallel port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	 * Byte 4: FIFO status for both */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	if (unlikely(length != 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		dev_dbg(dev, "Wrong data !!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	iir = data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	if (!(iir & 0x01)) {	/* serial port interrupt pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		switch (iir & 0x0f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		case SERIAL_IIR_RLS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			dev_dbg(dev, "Serial Port: Receiver status error or address bit detected in 9-bit mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		case SERIAL_IIR_CTI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 			dev_dbg(dev, "Serial Port: Receiver time out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		case SERIAL_IIR_MS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 			/* dev_dbg(dev, "Serial Port: Modem status change\n"); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 			break;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	{       /* update local copy of DSR reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		struct mos7715_parport *mos_parport = port->serial->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		if (unlikely(mos_parport == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		atomic_set(&mos_parport->shadowDSR, data[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	result = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		dev_err(dev, "%s - Error %d submitting control urb\n", __func__, result);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919)  * mos7720_bulk_in_callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920)  *	this is the callback function for when we have received data on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921)  *	bulk in endpoint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) static void mos7720_bulk_in_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	unsigned char *data ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		dev_dbg(&urb->dev->dev, "nonzero read bulk status received: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	dev_dbg(&port->dev, "Entering...%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	if (urb->actual_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		tty_insert_flip_string(&port->port, data, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		tty_flip_buffer_push(&port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	if (port->read_urb->status != -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 			dev_dbg(&port->dev, "usb_submit_urb(read bulk) failed, retval = %d\n", retval);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954)  * mos7720_bulk_out_data_callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955)  *	this is the callback function for when we have finished sending serial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956)  *	data on the bulk out endpoint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) static void mos7720_bulk_out_data_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		dev_dbg(&urb->dev->dev, "nonzero write bulk status received:%d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	mos7720_port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	if (!mos7720_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		dev_dbg(&urb->dev->dev, "NULL mos7720_port pointer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		return ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	if (mos7720_port->open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		tty_port_tty_wakeup(&mos7720_port->port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) static int mos77xx_calc_num_ports(struct usb_serial *serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 					struct usb_serial_endpoints *epds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	if (product == MOSCHIP_DEVICE_ID_7715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		 * The 7715 uses the first bulk in/out endpoint pair for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		 * parallel port, and the second for the serial port. We swap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		 * the endpoint descriptors here so that the the first and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		 * only registered port structure uses the serial-port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		 * endpoints.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		swap(epds->bulk_in[0], epds->bulk_in[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		swap(epds->bulk_out[0], epds->bulk_out[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	struct usb_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	int response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	int port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	__u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	int allocated_urbs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	usb_clear_halt(serial->dev, port->write_urb->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	usb_clear_halt(serial->dev, port->read_urb->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	/* Initialising the write urb pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	for (j = 0; j < NUM_URBS; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		mos7720_port->write_urb_pool[j] = urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 					       GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		if (!urb->transfer_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 			usb_free_urb(mos7720_port->write_urb_pool[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 			mos7720_port->write_urb_pool[j] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		allocated_urbs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	if (!allocated_urbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	 /* Initialize MCS7720 -- Write Init values to corresponding Registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	  * Register Index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	  * 0 : MOS7720_THR/MOS7720_RHR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	  * 1 : MOS7720_IER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	  * 2 : MOS7720_FCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	  * 3 : MOS7720_LCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	  * 4 : MOS7720_MCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	  * 5 : MOS7720_LSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	  * 6 : MOS7720_MSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	  * 7 : MOS7720_SPR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	  * 0x08 : SP1/2 Control Reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	port_number = port->port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	read_mos_reg(serial, port_number, MOS7720_LSR, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	dev_dbg(&port->dev, "SS::%p LSR:%x\n", mos7720_port, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	write_mos_reg(serial, dummy, MOS7720_SP1_REG, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	write_mos_reg(serial, dummy, MOS7720_SP2_REG, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	write_mos_reg(serial, port_number, MOS7720_IER, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	write_mos_reg(serial, port_number, MOS7720_FCR, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	write_mos_reg(serial, port_number, MOS7720_FCR, 0xcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	mos7720_port->shadowLCR = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	write_mos_reg(serial, port_number, MOS7720_LCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		      mos7720_port->shadowLCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	mos7720_port->shadowMCR = 0x0b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	write_mos_reg(serial, port_number, MOS7720_MCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		      mos7720_port->shadowMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	write_mos_reg(serial, port_number, MOS7720_SP_CONTROL_REG, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	read_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	data = data | (port->port_number + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	mos7720_port->shadowLCR = 0x83;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	write_mos_reg(serial, port_number, MOS7720_LCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		      mos7720_port->shadowLCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	write_mos_reg(serial, port_number, MOS7720_THR, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	write_mos_reg(serial, port_number, MOS7720_IER, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	mos7720_port->shadowLCR = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	write_mos_reg(serial, port_number, MOS7720_LCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		      mos7720_port->shadowLCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	write_mos_reg(serial, port_number, MOS7720_IER, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	response = usb_submit_urb(port->read_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	if (response)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		dev_err(&port->dev, "%s - Error %d submitting read urb\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 							__func__, response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	/* initialize our port settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	mos7720_port->shadowMCR = UART_MCR_OUT2; /* Must set to enable ints! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	/* send a open port command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	mos7720_port->open = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	return 0;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)  * mos7720_chars_in_buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)  *	this function is called by the tty driver when it wants to know how many
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)  *	bytes of data we currently have outstanding in the port (data that has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)  *	been written, but hasn't made it out the port yet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)  *	If successful, we return the number of bytes left to be written in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)  *	system,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)  *	Otherwise we return a negative error number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) static int mos7720_chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	int chars = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	for (i = 0; i < NUM_URBS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		if (mos7720_port->write_urb_pool[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		    mos7720_port->write_urb_pool[i]->status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			chars += URB_TRANSFER_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	return chars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static void mos7720_close(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	struct usb_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	for (j = 0; j < NUM_URBS; ++j)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		usb_kill_urb(mos7720_port->write_urb_pool[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	/* Freeing Write URBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	for (j = 0; j < NUM_URBS; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		if (mos7720_port->write_urb_pool[j]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 			kfree(mos7720_port->write_urb_pool[j]->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 			usb_free_urb(mos7720_port->write_urb_pool[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		}
^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) 	/* While closing port, shutdown all bulk read, write  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	 * and interrupt read if they exists, otherwise nop   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	usb_kill_urb(port->write_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	usb_kill_urb(port->read_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	write_mos_reg(serial, port->port_number, MOS7720_MCR, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	write_mos_reg(serial, port->port_number, MOS7720_IER, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	mos7720_port->open = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) static void mos7720_break(struct tty_struct *tty, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	unsigned char data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	struct usb_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	if (break_state == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		data = mos7720_port->shadowLCR | UART_LCR_SBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		data = mos7720_port->shadowLCR & ~UART_LCR_SBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	mos7720_port->shadowLCR  = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	write_mos_reg(serial, port->port_number, MOS7720_LCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		      mos7720_port->shadowLCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)  * mos7720_write_room
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)  *	this function is called by the tty driver when it wants to know how many
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)  *	bytes of data we can accept for a specific port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)  *	If successful, we return the amount of room that we have for this port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)  *	Otherwise we return a negative error number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static int mos7720_write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	int room = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	/* FIXME: Locking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	for (i = 0; i < NUM_URBS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		if (mos7720_port->write_urb_pool[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		    mos7720_port->write_urb_pool[i]->status != -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			room += URB_TRANSFER_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	dev_dbg(&port->dev, "%s - returns %d\n", __func__, room);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	return room;
^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) static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 				 const unsigned char *data, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	int bytes_sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	int transfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	struct usb_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	struct urb    *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	const unsigned char *current_position = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	/* try to find a free urb in the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	for (i = 0; i < NUM_URBS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		if (mos7720_port->write_urb_pool[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		    mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 			urb = mos7720_port->write_urb_pool[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 			dev_dbg(&port->dev, "URB:%d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	if (urb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		dev_dbg(&port->dev, "%s - no more free urbs\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	if (urb->transfer_buffer == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 		urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 					       GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		if (!urb->transfer_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 			bytes_sent = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	memcpy(urb->transfer_buffer, current_position, transfer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	usb_serial_debug_data(&port->dev, __func__, transfer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 			      urb->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	/* fill urb with data and submit  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	usb_fill_bulk_urb(urb, serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 			  usb_sndbulkpipe(serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 					port->bulk_out_endpointAddress),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 			  urb->transfer_buffer, transfer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 			  mos7720_bulk_out_data_callback, mos7720_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	/* send it down the pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	status = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		dev_err_console(port, "%s - usb_submit_urb(write bulk) failed "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 			"with status = %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 		bytes_sent = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	bytes_sent = transfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	return bytes_sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static void mos7720_throttle(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	if (!mos7720_port->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 		dev_dbg(&port->dev, "%s - port not opened\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	/* if we are implementing XON/XOFF, send the stop character */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	if (I_IXOFF(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		unsigned char stop_char = STOP_CHAR(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		status = mos7720_write(tty, port, &stop_char, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 		if (status <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	/* if we are implementing RTS/CTS, toggle that line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	if (C_CRTSCTS(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		mos7720_port->shadowMCR &= ~UART_MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		write_mos_reg(port->serial, port->port_number, MOS7720_MCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 			      mos7720_port->shadowMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) static void mos7720_unthrottle(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	if (!mos7720_port->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 		dev_dbg(&port->dev, "%s - port not opened\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	/* if we are implementing XON/XOFF, send the start character */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	if (I_IXOFF(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		unsigned char start_char = START_CHAR(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 		status = mos7720_write(tty, port, &start_char, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		if (status <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	/* if we are implementing RTS/CTS, toggle that line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	if (C_CRTSCTS(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		mos7720_port->shadowMCR |= UART_MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		write_mos_reg(port->serial, port->port_number, MOS7720_MCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 			      mos7720_port->shadowMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) /* FIXME: this function does not work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) static int set_higher_rates(struct moschip_port *mos7720_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 			    unsigned int baud)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	struct usb_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	int port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	enum mos_regs sp_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	port = mos7720_port->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	 /***********************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	 *      Init Sequence for higher rates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	 ***********************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	dev_dbg(&port->dev, "Sending Setting Commands ..........\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	port_number = port->port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	write_mos_reg(serial, port_number, MOS7720_IER, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	write_mos_reg(serial, port_number, MOS7720_FCR, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	write_mos_reg(serial, port_number, MOS7720_FCR, 0xcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	mos7720_port->shadowMCR = 0x0b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	write_mos_reg(serial, port_number, MOS7720_MCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		      mos7720_port->shadowMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	/***********************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	 *              Set for higher rates           *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	 ***********************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	/* writing baud rate verbatum into uart clock field clearly not right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	if (port_number == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		sp_reg = MOS7720_SP1_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		sp_reg = MOS7720_SP2_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	write_mos_reg(serial, dummy, sp_reg, baud * 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	mos7720_port->shadowMCR = 0x2b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	write_mos_reg(serial, port_number, MOS7720_MCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		      mos7720_port->shadowMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	/***********************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	 *              Set DLL/DLM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	 ***********************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	write_mos_reg(serial, port_number, MOS7720_LCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		      mos7720_port->shadowLCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	write_mos_reg(serial, port_number, MOS7720_DLL, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	write_mos_reg(serial, port_number, MOS7720_DLM, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	write_mos_reg(serial, port_number, MOS7720_LCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		      mos7720_port->shadowLCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /* baud rate information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct divisor_table_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	__u32  baudrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	__u16  divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) /* Define table of divisors for moschip 7720 hardware	   *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)  * These assume a 3.6864MHz crystal, the standard /16, and *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)  * MCR.7 = 0.						   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static const struct divisor_table_entry divisor_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	{   50,		2304},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	{   110,	1047},	/* 2094.545455 => 230450   => .0217 % over */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	{   134,	857},	/* 1713.011152 => 230398.5 => .00065% under */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	{   150,	768},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	{   300,	384},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	{   600,	192},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	{   1200,	96},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	{   1800,	64},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	{   2400,	48},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	{   4800,	24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	{   7200,	16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	{   9600,	12},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	{   19200,	6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	{   38400,	3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	{   57600,	2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	{   115200,	1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)  * calc_baud_rate_divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)  *	this function calculates the proper baud rate divisor for the specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)  *	baud rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)  *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) static int calc_baud_rate_divisor(struct usb_serial_port *port, int baudrate, int *divisor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	__u16 custom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	__u16 round1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	__u16 round;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	dev_dbg(&port->dev, "%s - %d\n", __func__, baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	for (i = 0; i < ARRAY_SIZE(divisor_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 		if (divisor_table[i].baudrate == baudrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 			*divisor = divisor_table[i].divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	/* After trying for all the standard baud rates    *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	 * Try calculating the divisor for this baud rate  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	if (baudrate > 75 &&  baudrate < 230400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 		/* get the divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 		custom = (__u16)(230400L  / baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		/* Check for round off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		round1 = (__u16)(2304000L / baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 		round = (__u16)(round1 - (custom * 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		if (round > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 			custom++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		*divisor = custom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		dev_dbg(&port->dev, "Baud %d = %d\n", baudrate, custom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	dev_dbg(&port->dev, "Baud calculation Failed...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)  * send_cmd_write_baud_rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)  *	this function sends the proper command to change the baud rate of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)  *	specified port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 				    int baudrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	struct usb_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	int divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	unsigned char number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	port = mos7720_port->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	number = port->port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	dev_dbg(&port->dev, "%s - baud = %d\n", __func__, baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	/* Calculate the Divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	status = calc_baud_rate_divisor(port, baudrate, &divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		dev_err(&port->dev, "%s - bad baud rate\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	/* Enable access to divisor latch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	write_mos_reg(serial, number, MOS7720_LCR, mos7720_port->shadowLCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	/* Write the divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	write_mos_reg(serial, number, MOS7720_DLL, (__u8)(divisor & 0xff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	write_mos_reg(serial, number, MOS7720_DLM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		      (__u8)((divisor & 0xff00) >> 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	/* Disable access to divisor latch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	write_mos_reg(serial, number, MOS7720_LCR, mos7720_port->shadowLCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)  * change_port_settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)  *	This routine is called to set the UART on the device to match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)  *      the specified new settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) static void change_port_settings(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 				 struct moschip_port *mos7720_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 				 struct ktermios *old_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	struct usb_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	int baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	unsigned cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	__u8 lData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	__u8 lParity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	__u8 lStop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	int port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 		return ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	port = mos7720_port->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	port_number = port->port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	if (!mos7720_port->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 		dev_dbg(&port->dev, "%s - port not opened\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	lData = UART_LCR_WLEN8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	lStop = 0x00;	/* 1 stop bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	lParity = 0x00;	/* No parity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	cflag = tty->termios.c_cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	/* Change the number of bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	switch (cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 		lData = UART_LCR_WLEN5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 		lData = UART_LCR_WLEN6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		lData = UART_LCR_WLEN7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		lData = UART_LCR_WLEN8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	/* Change the Parity bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	if (cflag & PARENB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 		if (cflag & PARODD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 			lParity = UART_LCR_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 			dev_dbg(&port->dev, "%s - parity = odd\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 			lParity = (UART_LCR_EPAR | UART_LCR_PARITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 			dev_dbg(&port->dev, "%s - parity = even\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		dev_dbg(&port->dev, "%s - parity = none\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	if (cflag & CMSPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		lParity = lParity | 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	/* Change the Stop bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	if (cflag & CSTOPB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 		lStop = UART_LCR_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 		dev_dbg(&port->dev, "%s - stop bits = 2\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 		lStop = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 		dev_dbg(&port->dev, "%s - stop bits = 1\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) #define LCR_BITS_MASK		0x03	/* Mask for bits/char field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) #define LCR_STOP_MASK		0x04	/* Mask for stop bits field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) #define LCR_PAR_MASK		0x38	/* Mask for parity field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	/* Update the LCR with the correct value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	mos7720_port->shadowLCR &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 		~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	mos7720_port->shadowLCR |= (lData | lParity | lStop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	/* Disable Interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	write_mos_reg(serial, port_number, MOS7720_IER, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	write_mos_reg(serial, port_number, MOS7720_FCR, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	write_mos_reg(serial, port_number, MOS7720_FCR, 0xcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	/* Send the updated LCR value to the mos7720 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	write_mos_reg(serial, port_number, MOS7720_LCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 		      mos7720_port->shadowLCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	mos7720_port->shadowMCR = 0x0b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	write_mos_reg(serial, port_number, MOS7720_MCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 		      mos7720_port->shadowMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	/* set up the MCR register and send it to the mos7720 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	mos7720_port->shadowMCR = UART_MCR_OUT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	if (cflag & CBAUD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		mos7720_port->shadowMCR |= (UART_MCR_DTR | UART_MCR_RTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	if (cflag & CRTSCTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 		mos7720_port->shadowMCR |= (UART_MCR_XONANY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		/* To set hardware flow control to the specified *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		 * serial port, in SP1/2_CONTROL_REG             */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		if (port_number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 			write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 				      0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 			write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 				      0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 		mos7720_port->shadowMCR &= ~(UART_MCR_XONANY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	write_mos_reg(serial, port_number, MOS7720_MCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		      mos7720_port->shadowMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	/* Determine divisor based on baud rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	baud = tty_get_baud_rate(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	if (!baud) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		/* pick a default, any default... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 		dev_dbg(&port->dev, "Picked default baud...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 		baud = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	if (baud >= 230400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 		set_higher_rates(mos7720_port, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 		/* Enable Interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 		write_mos_reg(serial, port_number, MOS7720_IER, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	dev_dbg(&port->dev, "%s - baud rate = %d\n", __func__, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	status = send_cmd_write_baud_rate(mos7720_port, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	/* FIXME: needs to write actual resulting baud back not just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	   blindly do so */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	if (cflag & CBAUD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 		tty_encode_baud_rate(tty, baud, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	/* Enable Interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	write_mos_reg(serial, port_number, MOS7720_IER, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	if (port->read_urb->status != -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 		status = usb_submit_urb(port->read_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 			dev_dbg(&port->dev, "usb_submit_urb(read bulk) failed, status = %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)  * mos7720_set_termios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)  *	this function is called by the tty driver when it wants to change the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)  *	termios structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) static void mos7720_set_termios(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 		struct usb_serial_port *port, struct ktermios *old_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	if (!mos7720_port->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 		dev_dbg(&port->dev, "%s - port not opened\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	/* change the port settings to the new ones specified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	change_port_settings(tty, mos7720_port, old_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	if (port->read_urb->status != -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 		status = usb_submit_urb(port->read_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 			dev_dbg(&port->dev, "usb_submit_urb(read bulk) failed, status = %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)  * get_lsr_info - get line status register info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)  * Purpose: Let user call ioctl() to get info when the UART physically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)  * 	    is emptied.  On bus types like RS485, the transmitter must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)  * 	    release the bus after transmitting. This must be done when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)  * 	    the transmit shift register is empty, not be done when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)  * 	    transmit holding register is empty.  This functionality
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)  * 	    allows an RS485 driver to be written in user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) static int get_lsr_info(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 		struct moschip_port *mos7720_port, unsigned int __user *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	unsigned int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	unsigned char data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	int port_number = port->port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	count = mos7720_chars_in_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	if (count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		read_mos_reg(port->serial, port_number, MOS7720_LSR, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		if ((data & (UART_LSR_TEMT | UART_LSR_THRE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 					== (UART_LSR_TEMT | UART_LSR_THRE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 			dev_dbg(&port->dev, "%s -- Empty\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 			result = TIOCSER_TEMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	if (copy_to_user(value, &result, sizeof(int)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) static int mos7720_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	unsigned int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	unsigned int mcr ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	unsigned int msr ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	mcr = mos7720_port->shadowMCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	msr = mos7720_port->shadowMSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	result = ((mcr & UART_MCR_DTR)  ? TIOCM_DTR : 0)   /* 0x002 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	  | ((mcr & UART_MCR_RTS)   ? TIOCM_RTS : 0)   /* 0x004 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	  | ((msr & UART_MSR_CTS)   ? TIOCM_CTS : 0)   /* 0x020 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	  | ((msr & UART_MSR_DCD)   ? TIOCM_CAR : 0)   /* 0x040 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	  | ((msr & UART_MSR_RI)    ? TIOCM_RI :  0)   /* 0x080 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	  | ((msr & UART_MSR_DSR)   ? TIOCM_DSR : 0);  /* 0x100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) static int mos7720_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 			    unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	unsigned int mcr ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	mcr = mos7720_port->shadowMCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	if (set & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 		mcr |= UART_MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	if (set & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		mcr |= UART_MCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	if (set & TIOCM_LOOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		mcr |= UART_MCR_LOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	if (clear & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 		mcr &= ~UART_MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	if (clear & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 		mcr &= ~UART_MCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	if (clear & TIOCM_LOOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 		mcr &= ~UART_MCR_LOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	mos7720_port->shadowMCR = mcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	write_mos_reg(port->serial, port->port_number, MOS7720_MCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 		      mos7720_port->shadowMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) static int get_serial_info(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 			   struct serial_struct *ss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	ss->type		= PORT_16550A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	ss->line		= mos7720_port->port->minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	ss->port		= mos7720_port->port->port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	ss->irq			= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	ss->xmit_fifo_size	= NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	ss->baud_base		= 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	ss->close_delay		= 5*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	ss->closing_wait	= 30*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) static int mos7720_ioctl(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 			 unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	if (mos7720_port == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	case TIOCSERGETLSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 		dev_dbg(&port->dev, "%s TIOCSERGETLSR\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 		return get_lsr_info(tty, mos7720_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 					(unsigned int __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) static int mos7720_startup(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	struct usb_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	char data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 	u16 product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 	int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 	product = le16_to_cpu(serial->dev->descriptor.idProduct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	dev = serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	if (product == MOSCHIP_DEVICE_ID_7715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 		struct urb *urb = serial->port[0]->interrupt_in_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 		urb->complete = mos7715_interrupt_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 		ret_val = mos7715_parport_init(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 		if (ret_val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 			return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 	/* start the interrupt urb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 	if (ret_val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 		dev_err(&dev->dev, "failed to submit interrupt urb: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 			ret_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	/* LSR For Port 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	read_mos_reg(serial, 0, MOS7720_LSR, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	dev_dbg(&dev->dev, "LSR:%x\n", data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) static void mos7720_release(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 	usb_kill_urb(serial->port[0]->interrupt_in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 	/* close the parallel port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	if (le16_to_cpu(serial->dev->descriptor.idProduct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	    == MOSCHIP_DEVICE_ID_7715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 		struct urbtracker *urbtrack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 		unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 		struct mos7715_parport *mos_parport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 			usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 		/* prevent NULL ptr dereference in port callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 		spin_lock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 		mos_parport->pp->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 		spin_unlock(&release_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 		/* wait for synchronous usb calls to return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 		if (mos_parport->msg_pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 			wait_for_completion_timeout(&mos_parport->syncmsg_compl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 					    msecs_to_jiffies(MOS_WDR_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 		parport_remove_port(mos_parport->pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 		usb_set_serial_data(serial, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 		mos_parport->serial = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 		/* if tasklet currently scheduled, wait for it to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 		tasklet_kill(&mos_parport->urb_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 		/* unlink any urbs sent by the tasklet  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 		spin_lock_irqsave(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		list_for_each_entry(urbtrack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 				    &mos_parport->active_urbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 				    urblist_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 			usb_unlink_urb(urbtrack->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 		spin_unlock_irqrestore(&mos_parport->listlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 		parport_del_port(mos_parport->pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 		kref_put(&mos_parport->ref_count, destroy_mos_parport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) static int mos7720_port_probe(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	mos7720_port = kzalloc(sizeof(*mos7720_port), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	if (!mos7720_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	mos7720_port->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	usb_set_serial_port_data(port, mos7720_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) static int mos7720_port_remove(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	struct moschip_port *mos7720_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	mos7720_port = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	kfree(mos7720_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) static struct usb_serial_driver moschip7720_2port_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 		.owner =	THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 		.name =		"moschip7720",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	.description		= "Moschip 2 port adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	.id_table		= id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	.num_bulk_in		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	.num_bulk_out		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	.num_interrupt_in	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	.calc_num_ports		= mos77xx_calc_num_ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	.open			= mos7720_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	.close			= mos7720_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	.throttle		= mos7720_throttle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	.unthrottle		= mos7720_unthrottle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 	.attach			= mos7720_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	.release		= mos7720_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	.port_probe		= mos7720_port_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	.port_remove		= mos7720_port_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	.ioctl			= mos7720_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	.tiocmget		= mos7720_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	.tiocmset		= mos7720_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	.get_serial		= get_serial_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	.set_termios		= mos7720_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	.write			= mos7720_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	.write_room		= mos7720_write_room,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	.chars_in_buffer	= mos7720_chars_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	.break_ctl		= mos7720_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	.read_bulk_callback	= mos7720_bulk_in_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	.read_int_callback	= mos7720_interrupt_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) static struct usb_serial_driver * const serial_drivers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	&moschip7720_2port_driver, NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) module_usb_serial_driver(serial_drivers, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) MODULE_LICENSE("GPL v2");