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)  * Copyright (C) 2004 Hollis Blanchard <hollisb@us.ibm.com>, IBM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) /* Host Virtual Serial Interface (HVSI) is a protocol between the hosted OS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * and the service processor on IBM pSeries servers. On these servers, there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * are no serial ports under the OS's control, and sometimes there is no other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * console available either. However, the service processor has two standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * serial ports, so this over-complicated protocol allows the OS to control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * those ports by proxy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * Besides data, the procotol supports the reading/writing of the serial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * port's DTR line, and the reading of the CD line. This is to allow the OS to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * control a modem attached to the service processor's serial port. Note that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * the OS cannot change the speed of the port through this protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #undef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/interrupt.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/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/sysrq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <asm/hvcall.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <asm/hvconsole.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <asm/vio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <asm/param.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <asm/hvsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define HVSI_MAJOR	229
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define HVSI_MINOR	128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define MAX_NR_HVSI_CONSOLES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define HVSI_TIMEOUT (5*HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define HVSI_VERSION 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define HVSI_MAX_PACKET 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define HVSI_MAX_READ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define HVSI_MAX_OUTGOING_DATA 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define N_OUTBUF 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53)  * we pass data via two 8-byte registers, so we would like our char arrays
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54)  * properly aligned for those loads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define __ALIGNED__	__attribute__((__aligned__(sizeof(long))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) struct hvsi_struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	struct tty_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	struct delayed_work writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	struct work_struct handshaker;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	wait_queue_head_t emptyq; /* woken when outbuf is emptied */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	wait_queue_head_t stateq; /* woken when HVSI state changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	uint8_t throttle_buf[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	uint8_t outbuf[N_OUTBUF]; /* to implement write_room and chars_in_buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	/* inbuf is for packet reassembly. leave a little room for leftovers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	uint8_t inbuf[HVSI_MAX_PACKET + HVSI_MAX_READ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	uint8_t *inbuf_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	int n_throttle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	int n_outbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	uint32_t vtermno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	uint32_t virq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	atomic_t seqno; /* HVSI packet sequence number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	uint16_t mctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	uint8_t state;  /* HVSI protocol state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	uint8_t flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #ifdef CONFIG_MAGIC_SYSRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	uint8_t sysrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #endif /* CONFIG_MAGIC_SYSRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) static struct hvsi_struct hvsi_ports[MAX_NR_HVSI_CONSOLES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) static struct tty_driver *hvsi_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) static int hvsi_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) static int (*hvsi_wait)(struct hvsi_struct *hp, int state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) enum HVSI_PROTOCOL_STATE {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	HVSI_CLOSED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	HVSI_WAIT_FOR_VER_RESPONSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	HVSI_WAIT_FOR_VER_QUERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	HVSI_OPEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	HVSI_WAIT_FOR_MCTRL_RESPONSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	HVSI_FSP_DIED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define HVSI_CONSOLE 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) static inline int is_console(struct hvsi_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	return hp->flags & HVSI_CONSOLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) static inline int is_open(struct hvsi_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	/* if we're waiting for an mctrl then we're already open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	return (hp->state == HVSI_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 			|| (hp->state == HVSI_WAIT_FOR_MCTRL_RESPONSE);
^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) static inline void print_state(struct hvsi_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	static const char *state_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 		"HVSI_CLOSED",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 		"HVSI_WAIT_FOR_VER_RESPONSE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		"HVSI_WAIT_FOR_VER_QUERY",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		"HVSI_OPEN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		"HVSI_WAIT_FOR_MCTRL_RESPONSE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 		"HVSI_FSP_DIED",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	const char *name = (hp->state < ARRAY_SIZE(state_names))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		? state_names[hp->state] : "UNKNOWN";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	pr_debug("hvsi%i: state = %s\n", hp->index, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #endif /* DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) static inline void __set_state(struct hvsi_struct *hp, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	hp->state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	print_state(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	wake_up_all(&hp->stateq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) static inline void set_state(struct hvsi_struct *hp, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	__set_state(hp, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) static inline int len_packet(const uint8_t *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	return (int)((struct hvsi_header *)packet)->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) static inline int is_header(const uint8_t *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	struct hvsi_header *header = (struct hvsi_header *)packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	return header->type >= VS_QUERY_RESPONSE_PACKET_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) static inline int got_packet(const struct hvsi_struct *hp, uint8_t *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	if (hp->inbuf_end < packet + sizeof(struct hvsi_header))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		return 0; /* don't even have the packet header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	if (hp->inbuf_end < (packet + len_packet(packet)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		return 0; /* don't have the rest of the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) /* shift remaining bytes in packetbuf down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) static void compact_inbuf(struct hvsi_struct *hp, uint8_t *read_to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	int remaining = (int)(hp->inbuf_end - read_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	pr_debug("%s: %i chars remain\n", __func__, remaining);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	if (read_to != hp->inbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 		memmove(hp->inbuf, read_to, remaining);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	hp->inbuf_end = hp->inbuf + remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) #define dbg_dump_packet(packet) dump_packet(packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) #define dbg_dump_hex(data, len) dump_hex(data, len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) #define dbg_dump_packet(packet) do { } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) #define dbg_dump_hex(data, len) do { } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) static void dump_hex(const uint8_t *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	printk("    ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	for (i=0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		printk("%.2x", data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	printk("\n    ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	for (i=0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		if (isprint(data[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 			printk("%c", data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 			printk(".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) static void dump_packet(uint8_t *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	struct hvsi_header *header = (struct hvsi_header *)packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	printk("type 0x%x, len %i, seqno %i:\n", header->type, header->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 			header->seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	dump_hex(packet, header->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) static int hvsi_read(struct hvsi_struct *hp, char *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	unsigned long got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	got = hvc_get_chars(hp->vtermno, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	return got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	struct tty_struct *tty, struct hvsi_struct **to_handshake)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	struct hvsi_control *header = (struct hvsi_control *)packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	switch (be16_to_cpu(header->verb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		case VSV_MODEM_CTL_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 			if ((be32_to_cpu(header->word) & HVSI_TSCD) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 				/* CD went away; no more connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 				pr_debug("hvsi%i: CD dropped\n", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 				hp->mctrl &= TIOCM_CD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 				if (tty && !C_CLOCAL(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 					tty_hangup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		case VSV_CLOSE_PROTOCOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 			pr_debug("hvsi%i: service processor came back\n", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 			if (hp->state != HVSI_CLOSED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 				*to_handshake = hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 			printk(KERN_WARNING "hvsi%i: unknown HVSI control packet: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 				hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 			dump_packet(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) static void hvsi_recv_response(struct hvsi_struct *hp, uint8_t *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	struct hvsi_query_response *resp = (struct hvsi_query_response *)packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	uint32_t mctrl_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	switch (hp->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		case HVSI_WAIT_FOR_VER_RESPONSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 			__set_state(hp, HVSI_WAIT_FOR_VER_QUERY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		case HVSI_WAIT_FOR_MCTRL_RESPONSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 			hp->mctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 			mctrl_word = be32_to_cpu(resp->u.mctrl_word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 			if (mctrl_word & HVSI_TSDTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 				hp->mctrl |= TIOCM_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 			if (mctrl_word & HVSI_TSCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 				hp->mctrl |= TIOCM_CD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 			__set_state(hp, HVSI_OPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			printk(KERN_ERR "hvsi%i: unexpected query response: ", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 			dump_packet(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) /* respond to service processor's version query */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) static int hvsi_version_respond(struct hvsi_struct *hp, uint16_t query_seqno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	struct hvsi_query_response packet __ALIGNED__;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	int wrote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	packet.hdr.type = VS_QUERY_RESPONSE_PACKET_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	packet.hdr.len = sizeof(struct hvsi_query_response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	packet.verb = cpu_to_be16(VSV_SEND_VERSION_NUMBER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	packet.u.version = HVSI_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	packet.query_seqno = cpu_to_be16(query_seqno+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	pr_debug("%s: sending %i bytes\n", __func__, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	dbg_dump_hex((uint8_t*)&packet, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	if (wrote != packet.hdr.len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		printk(KERN_ERR "hvsi%i: couldn't send query response!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 			hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	struct hvsi_query *query = (struct hvsi_query *)packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	switch (hp->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		case HVSI_WAIT_FOR_VER_QUERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 			hvsi_version_respond(hp, be16_to_cpu(query->hdr.seqno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 			__set_state(hp, HVSI_OPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 			printk(KERN_ERR "hvsi%i: unexpected query: ", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 			dump_packet(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	for (i=0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		char c = buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) #ifdef CONFIG_MAGIC_SYSRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		if (c == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 			hp->sysrq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		} else if (hp->sysrq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 			handle_sysrq(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			hp->sysrq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) #endif /* CONFIG_MAGIC_SYSRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		tty_insert_flip_char(&hp->port, c, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342)  * We could get 252 bytes of data at once here. But the tty layer only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343)  * throttles us at TTY_THRESHOLD_THROTTLE (128) bytes, so we could overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344)  * it. Accordingly we won't send more than 128 bytes at a time to the flip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345)  * buffer, which will give the tty buffer a chance to throttle us. Should the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346)  * value of TTY_THRESHOLD_THROTTLE change in n_tty.c, this code should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347)  * revisited.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) #define TTY_THRESHOLD_THROTTLE 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) static bool hvsi_recv_data(struct hvsi_struct *hp, const uint8_t *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	const struct hvsi_header *header = (const struct hvsi_header *)packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	const uint8_t *data = packet + sizeof(struct hvsi_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	int datalen = header->len - sizeof(struct hvsi_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	int overflow = datalen - TTY_THRESHOLD_THROTTLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	pr_debug("queueing %i chars '%.*s'\n", datalen, datalen, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	if (datalen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	if (overflow > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		pr_debug("%s: got >TTY_THRESHOLD_THROTTLE bytes\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		datalen = TTY_THRESHOLD_THROTTLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	hvsi_insert_chars(hp, data, datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	if (overflow > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		 * we still have more data to deliver, so we need to save off the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		 * overflow and send it later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		pr_debug("%s: deferring overflow\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		memcpy(hp->throttle_buf, data + TTY_THRESHOLD_THROTTLE, overflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		hp->n_throttle = overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  * Returns true/false indicating data successfully read from hypervisor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384)  * Used both to get packets for tty connections and to advance the state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385)  * machine during console handshaking (in which case tty = NULL and we ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386)  * incoming data).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		struct hvsi_struct **handshake)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	uint8_t *packet = hp->inbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	int chunklen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	bool flip = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	*handshake = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	if (chunklen == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		pr_debug("%s: 0-length read\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	pr_debug("%s: got %i bytes\n", __func__, chunklen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	dbg_dump_hex(hp->inbuf_end, chunklen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	hp->inbuf_end += chunklen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	/* handle all completed packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	while ((packet < hp->inbuf_end) && got_packet(hp, packet)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		struct hvsi_header *header = (struct hvsi_header *)packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		if (!is_header(packet)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 			printk(KERN_ERR "hvsi%i: got malformed packet\n", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 			/* skip bytes until we find a header or run out of data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 			while ((packet < hp->inbuf_end) && (!is_header(packet)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 				packet++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		pr_debug("%s: handling %i-byte packet\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 				len_packet(packet));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		dbg_dump_packet(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		switch (header->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 			case VS_DATA_PACKET_HEADER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 				if (!is_open(hp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 				flip = hvsi_recv_data(hp, packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 			case VS_CONTROL_PACKET_HEADER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 				hvsi_recv_control(hp, packet, tty, handshake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 			case VS_QUERY_RESPONSE_PACKET_HEADER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 				hvsi_recv_response(hp, packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 			case VS_QUERY_PACKET_HEADER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 				hvsi_recv_query(hp, packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 				printk(KERN_ERR "hvsi%i: unknown HVSI packet type 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 						hp->index, header->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 				dump_packet(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		packet += len_packet(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		if (*handshake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 			pr_debug("%s: handshake\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	compact_inbuf(hp, packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	if (flip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		tty_flip_buffer_push(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) static void hvsi_send_overflow(struct hvsi_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	pr_debug("%s: delivering %i bytes overflow\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 			hp->n_throttle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	hp->n_throttle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) }
^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)  * must get all pending data because we only get an irq on empty->non-empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473)  * transition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) static irqreturn_t hvsi_interrupt(int irq, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	struct hvsi_struct *hp = (struct hvsi_struct *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	struct hvsi_struct *handshake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	int again = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	tty = tty_port_tty_get(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	while (again) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		again = hvsi_load_chunk(hp, tty, &handshake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		if (handshake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 			pr_debug("hvsi%i: attempting re-handshake\n", handshake->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 			schedule_work(&handshake->handshaker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		}
^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) 	spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	if (tty && hp->n_throttle && !tty_throttled(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		/* we weren't hung up and we weren't throttled, so we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 		 * deliver the rest now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		hvsi_send_overflow(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		tty_flip_buffer_push(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) /* for boot console, before the irq handler is running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) static int __init poll_for_state(struct hvsi_struct *hp, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	unsigned long end_jiffies = jiffies + HVSI_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		hvsi_interrupt(hp->virq, (void *)hp); /* get pending data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		if (hp->state == state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		mdelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		if (time_after(jiffies, end_jiffies))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 			return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) /* wait for irq handler to change our state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) static int wait_for_state(struct hvsi_struct *hp, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	if (!wait_event_timeout(hp->stateq, (hp->state == state), HVSI_TIMEOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) static int hvsi_query(struct hvsi_struct *hp, uint16_t verb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	struct hvsi_query packet __ALIGNED__;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	int wrote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	packet.hdr.type = VS_QUERY_PACKET_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	packet.hdr.len = sizeof(struct hvsi_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	packet.verb = cpu_to_be16(verb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	pr_debug("%s: sending %i bytes\n", __func__, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	dbg_dump_hex((uint8_t*)&packet, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	if (wrote != packet.hdr.len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		printk(KERN_ERR "hvsi%i: couldn't send query (%i)!\n", hp->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 			wrote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) static int hvsi_get_mctrl(struct hvsi_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	set_state(hp, HVSI_WAIT_FOR_MCTRL_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	hvsi_query(hp, VSV_SEND_MODEM_CTL_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	ret = hvsi_wait(hp, HVSI_OPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		printk(KERN_ERR "hvsi%i: didn't get modem flags\n", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		set_state(hp, HVSI_OPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		return ret;
^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) 	pr_debug("%s: mctrl 0x%x\n", __func__, hp->mctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	return 0;
^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) /* note that we can only set DTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) static int hvsi_set_mctrl(struct hvsi_struct *hp, uint16_t mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	struct hvsi_control packet __ALIGNED__;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	int wrote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	packet.hdr.type = VS_CONTROL_PACKET_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	packet.hdr.len = sizeof(struct hvsi_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	packet.verb = cpu_to_be16(VSV_SET_MODEM_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	packet.mask = cpu_to_be32(HVSI_TSDTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	if (mctrl & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		packet.word = cpu_to_be32(HVSI_TSDTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	pr_debug("%s: sending %i bytes\n", __func__, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	dbg_dump_hex((uint8_t*)&packet, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	if (wrote != packet.hdr.len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		printk(KERN_ERR "hvsi%i: couldn't set DTR!\n", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) static void hvsi_drain_input(struct hvsi_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	uint8_t buf[HVSI_MAX_READ] __ALIGNED__;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	unsigned long end_jiffies = jiffies + HVSI_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	while (time_before(end_jiffies, jiffies))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		if (0 == hvsi_read(hp, buf, HVSI_MAX_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) static int hvsi_handshake(struct hvsi_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	 * We could have a CLOSE or other data waiting for us before we even try
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	 * to open; try to throw it all away so we don't get confused. (CLOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	 * is the first message sent up the pipe when the FSP comes online. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	 * need to distinguish between "it came up a while ago and we're the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	 * user" and "it was just reset before it saw our handshake packet".)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	hvsi_drain_input(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	set_state(hp, HVSI_WAIT_FOR_VER_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	ret = hvsi_query(hp, VSV_SEND_VERSION_NUMBER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		printk(KERN_ERR "hvsi%i: couldn't send version query\n", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	ret = hvsi_wait(hp, HVSI_OPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) static void hvsi_handshaker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	struct hvsi_struct *hp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		container_of(work, struct hvsi_struct, handshaker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	if (hvsi_handshake(hp) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	printk(KERN_ERR "hvsi%i: re-handshaking failed\n", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	if (is_console(hp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		 * ttys will re-attempt the handshake via hvsi_open, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		 * the console will not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		printk(KERN_ERR "hvsi%i: lost console!\n", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) static int hvsi_put_chars(struct hvsi_struct *hp, const char *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	struct hvsi_data packet __ALIGNED__;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	BUG_ON(count > HVSI_MAX_OUTGOING_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	packet.hdr.type = VS_DATA_PACKET_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	packet.hdr.len = count + sizeof(struct hvsi_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	memcpy(&packet.data, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	ret = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	if (ret == packet.hdr.len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		/* return the number of chars written, not the packet length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	return ret; /* return any errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) static void hvsi_close_protocol(struct hvsi_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	struct hvsi_control packet __ALIGNED__;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	packet.hdr.type = VS_CONTROL_PACKET_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	packet.hdr.len = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	packet.verb = cpu_to_be16(VSV_CLOSE_PROTOCOL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	pr_debug("%s: sending %i bytes\n", __func__, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	dbg_dump_hex((uint8_t*)&packet, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) static int hvsi_open(struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	struct hvsi_struct *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	hp = &hvsi_ports[tty->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	tty->driver_data = hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	if (hp->state == HVSI_FSP_DIED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	tty_port_tty_set(&hp->port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	hp->port.count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	atomic_set(&hp->seqno, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	if (is_console(hp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		return 0; /* this has already been handshaked as the console */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	ret = hvsi_handshake(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		printk(KERN_ERR "%s: HVSI handshaking failed\n", tty->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	ret = hvsi_get_mctrl(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		printk(KERN_ERR "%s: couldn't get initial modem flags\n", tty->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	ret = hvsi_set_mctrl(hp, hp->mctrl | TIOCM_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		printk(KERN_ERR "%s: couldn't set DTR\n", tty->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) /* wait for hvsi_write_worker to empty hp->outbuf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) static void hvsi_flush_output(struct hvsi_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	wait_event_timeout(hp->emptyq, (hp->n_outbuf <= 0), HVSI_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	/* 'writer' could still be pending if it didn't see n_outbuf = 0 yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	cancel_delayed_work_sync(&hp->writer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	flush_work(&hp->handshaker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	 * it's also possible that our timeout expired and hvsi_write_worker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	 * didn't manage to push outbuf. poof.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	hp->n_outbuf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) static void hvsi_close(struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	struct hvsi_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	if (tty_hung_up_p(filp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	if (--hp->port.count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		tty_port_tty_set(&hp->port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		hp->inbuf_end = hp->inbuf; /* discard remaining partial packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		/* only close down connection if it is not the console */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		if (!is_console(hp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); /* no more irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			__set_state(hp, HVSI_CLOSED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 			 * any data delivered to the tty layer after this will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			 * discarded (except for XON/XOFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 			tty->closing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 			spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			/* let any existing irq handlers finish. no more will start. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			synchronize_irq(hp->virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			/* hvsi_write_worker will re-schedule until outbuf is empty. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			hvsi_flush_output(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			/* tell FSP to stop sending data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 			hvsi_close_protocol(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 			 * drain anything FSP is still in the middle of sending, and let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 			 * hvsi_handshake drain the rest on the next open.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 			hvsi_drain_input(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 			spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	} else if (hp->port.count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		printk(KERN_ERR "hvsi_close %lu: oops, count is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		       hp - hvsi_ports, hp->port.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) static void hvsi_hangup(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	struct hvsi_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	tty_port_tty_set(&hp->port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	hp->port.count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	hp->n_outbuf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) /* called with hp->lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) static void hvsi_push(struct hvsi_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	if (hp->n_outbuf <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	n = hvsi_put_chars(hp, hp->outbuf, hp->n_outbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	if (n > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		/* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		pr_debug("%s: wrote %i chars\n", __func__, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		hp->n_outbuf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	} else if (n == -EIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		__set_state(hp, HVSI_FSP_DIED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		printk(KERN_ERR "hvsi%i: service processor died\n", hp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) /* hvsi_write_worker will keep rescheduling itself until outbuf is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) static void hvsi_write_worker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	struct hvsi_struct *hp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		container_of(work, struct hvsi_struct, writer.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	static long start_j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	if (start_j == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		start_j = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) #endif /* DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	if (!is_open(hp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		 * We could have a non-open connection if the service processor died
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		 * while we were busily scheduling ourselves. In that case, it could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		 * be minutes before the service processor comes back, so only try
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		 * again once a second.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		schedule_delayed_work(&hp->writer, HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	hvsi_push(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	if (hp->n_outbuf > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		schedule_delayed_work(&hp->writer, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		pr_debug("%s: outbuf emptied after %li jiffies\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 				jiffies - start_j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		start_j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) #endif /* DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		wake_up_all(&hp->emptyq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		tty_port_tty_wakeup(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) static int hvsi_write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	struct hvsi_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	return N_OUTBUF - hp->n_outbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) static int hvsi_chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	struct hvsi_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	return hp->n_outbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) static int hvsi_write(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		     const unsigned char *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	struct hvsi_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	const char *source = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	int total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	int origcount = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	if (!is_open(hp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		/* we're either closing or not yet open; don't accept data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		pr_debug("%s: not open\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	 * when the hypervisor buffer (16K) fills, data will stay in hp->outbuf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	 * and hvsi_write_worker will be scheduled. subsequent hvsi_write() calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	 * will see there is no room in outbuf and return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	while ((count > 0) && (hvsi_write_room(tty) > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		int chunksize = min(count, hvsi_write_room(tty));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		BUG_ON(hp->n_outbuf < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		memcpy(hp->outbuf + hp->n_outbuf, source, chunksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		hp->n_outbuf += chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		total += chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		source += chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		count -= chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		hvsi_push(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	if (hp->n_outbuf > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		 * we weren't able to write it all to the hypervisor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		 * schedule another push attempt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		schedule_delayed_work(&hp->writer, 10);
^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) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	if (total != origcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		pr_debug("%s: wanted %i, only wrote %i\n", __func__, origcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 			total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	return total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963)  * I have never seen throttle or unthrottle called, so this little throttle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964)  * buffering scheme may or may not work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) static void hvsi_throttle(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	struct hvsi_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) static void hvsi_unthrottle(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	struct hvsi_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	if (hp->n_throttle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		hvsi_send_overflow(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		tty_flip_buffer_push(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) static int hvsi_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	struct hvsi_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	hvsi_get_mctrl(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	return hp->mctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static int hvsi_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 				unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	struct hvsi_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	uint16_t new_mctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	/* we can only alter DTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	clear &= TIOCM_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	set &= TIOCM_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	new_mctrl = (hp->mctrl & ~clear) | set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	if (hp->mctrl != new_mctrl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		hvsi_set_mctrl(hp, new_mctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		hp->mctrl = new_mctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static const struct tty_operations hvsi_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	.open = hvsi_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	.close = hvsi_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	.write = hvsi_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	.hangup = hvsi_hangup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	.write_room = hvsi_write_room,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	.chars_in_buffer = hvsi_chars_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	.throttle = hvsi_throttle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	.unthrottle = hvsi_unthrottle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	.tiocmget = hvsi_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	.tiocmset = hvsi_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static int __init hvsi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	hvsi_driver = alloc_tty_driver(hvsi_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	if (!hvsi_driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	hvsi_driver->driver_name = "hvsi";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	hvsi_driver->name = "hvsi";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	hvsi_driver->major = HVSI_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	hvsi_driver->minor_start = HVSI_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	hvsi_driver->init_termios = tty_std_termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	hvsi_driver->init_termios.c_ispeed = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	hvsi_driver->init_termios.c_ospeed = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	hvsi_driver->flags = TTY_DRIVER_REAL_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	tty_set_operations(hvsi_driver, &hvsi_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	for (i=0; i < hvsi_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		struct hvsi_struct *hp = &hvsi_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		int ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		tty_port_link_device(&hp->port, hvsi_driver, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 			printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 				hp->virq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	hvsi_wait = wait_for_state; /* irqs active now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	ret = tty_register_driver(hvsi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		pr_err("Couldn't register hvsi console driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		goto err_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) err_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	hvsi_wait = poll_for_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	for (i = 0; i < hvsi_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		struct hvsi_struct *hp = &hvsi_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		free_irq(hp->virq, hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	tty_driver_kref_put(hvsi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) device_initcall(hvsi_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) /***** console (not tty) code: *****/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static void hvsi_console_print(struct console *console, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	struct hvsi_struct *hp = &hvsi_ports[console->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	char c[HVSI_MAX_OUTGOING_DATA] __ALIGNED__;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	unsigned int i = 0, n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	int ret, donecr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	if (!is_open(hp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	 * ugh, we have to translate LF -> CRLF ourselves, in place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	 * copied from hvc_console.c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	while (count > 0 || i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		if (count > 0 && i < sizeof(c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			if (buf[n] == '\n' && !donecr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 				c[i++] = '\r';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 				donecr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 				c[i++] = buf[n++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 				donecr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 				--count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 			ret = hvsi_put_chars(hp, c, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 				i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 			i -= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		}
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static struct tty_driver *hvsi_console_device(struct console *console,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	int *index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	*index = console->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	return hvsi_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static int __init hvsi_console_setup(struct console *console, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	struct hvsi_struct *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	if (console->index < 0 || console->index >= hvsi_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	hp = &hvsi_ports[console->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	/* give the FSP a chance to change the baud rate when we re-open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	hvsi_close_protocol(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	ret = hvsi_handshake(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	ret = hvsi_get_mctrl(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	ret = hvsi_set_mctrl(hp, hp->mctrl | TIOCM_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	hp->flags |= HVSI_CONSOLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) static struct console hvsi_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	.name		= "hvsi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	.write		= hvsi_console_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	.device		= hvsi_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	.setup		= hvsi_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	.flags		= CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	.index		= -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) static int __init hvsi_console_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	struct device_node *vty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	hvsi_wait = poll_for_state; /* no irqs yet; must poll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	/* search device tree for vty nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	for_each_compatible_node(vty, "serial", "hvterm-protocol") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		struct hvsi_struct *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		const __be32 *vtermno, *irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 		vtermno = of_get_property(vty, "reg", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		irq = of_get_property(vty, "interrupts", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		if (!vtermno || !irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		if (hvsi_count >= MAX_NR_HVSI_CONSOLES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 			of_node_put(vty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 		hp = &hvsi_ports[hvsi_count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		INIT_DELAYED_WORK(&hp->writer, hvsi_write_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		INIT_WORK(&hp->handshaker, hvsi_handshaker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		init_waitqueue_head(&hp->emptyq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 		init_waitqueue_head(&hp->stateq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		spin_lock_init(&hp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		tty_port_init(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		hp->index = hvsi_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		hp->inbuf_end = hp->inbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		hp->state = HVSI_CLOSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		hp->vtermno = be32_to_cpup(vtermno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		hp->virq = irq_create_mapping(NULL, be32_to_cpup(irq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		if (hp->virq == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 			printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 			       __func__, be32_to_cpup(irq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 			tty_port_destroy(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 			continue;
^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) 		hvsi_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	if (hvsi_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		register_console(&hvsi_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) console_initcall(hvsi_console_init);