162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * hvconsole.c 462306a36Sopenharmony_ci * Copyright (C) 2004 Hollis Blanchard, IBM Corporation 562306a36Sopenharmony_ci * Copyright (C) 2004 IBM Corporation 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Additional Author(s): 862306a36Sopenharmony_ci * Ryan S. Arnold <rsa@us.ibm.com> 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * LPAR console support. 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/kernel.h> 1462306a36Sopenharmony_ci#include <linux/export.h> 1562306a36Sopenharmony_ci#include <linux/errno.h> 1662306a36Sopenharmony_ci#include <asm/hvcall.h> 1762306a36Sopenharmony_ci#include <asm/hvconsole.h> 1862306a36Sopenharmony_ci#include <asm/plpar_wrappers.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/** 2162306a36Sopenharmony_ci * hvc_get_chars - retrieve characters from firmware for denoted vterm adapter 2262306a36Sopenharmony_ci * @vtermno: The vtermno or unit_address of the adapter from which to fetch the 2362306a36Sopenharmony_ci * data. 2462306a36Sopenharmony_ci * @buf: The character buffer into which to put the character data fetched from 2562306a36Sopenharmony_ci * firmware. 2662306a36Sopenharmony_ci * @count: not used? 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ciint hvc_get_chars(uint32_t vtermno, char *buf, int count) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci long ret; 3162306a36Sopenharmony_ci unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 3262306a36Sopenharmony_ci unsigned long *lbuf = (unsigned long *)buf; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci ret = plpar_hcall(H_GET_TERM_CHAR, retbuf, vtermno); 3562306a36Sopenharmony_ci lbuf[0] = be64_to_cpu(retbuf[1]); 3662306a36Sopenharmony_ci lbuf[1] = be64_to_cpu(retbuf[2]); 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci if (ret == H_SUCCESS) 3962306a36Sopenharmony_ci return retbuf[0]; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci return 0; 4262306a36Sopenharmony_ci} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ciEXPORT_SYMBOL(hvc_get_chars); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci/** 4862306a36Sopenharmony_ci * hvc_put_chars: send characters to firmware for denoted vterm adapter 4962306a36Sopenharmony_ci * @vtermno: The vtermno or unit_address of the adapter from which the data 5062306a36Sopenharmony_ci * originated. 5162306a36Sopenharmony_ci * @buf: The character buffer that contains the character data to send to 5262306a36Sopenharmony_ci * firmware. Must be at least 16 bytes, even if count is less than 16. 5362306a36Sopenharmony_ci * @count: Send this number of characters. 5462306a36Sopenharmony_ci */ 5562306a36Sopenharmony_ciint hvc_put_chars(uint32_t vtermno, const char *buf, int count) 5662306a36Sopenharmony_ci{ 5762306a36Sopenharmony_ci unsigned long *lbuf = (unsigned long *) buf; 5862306a36Sopenharmony_ci long ret; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci /* hcall will ret H_PARAMETER if 'count' exceeds firmware max.*/ 6262306a36Sopenharmony_ci if (count > MAX_VIO_PUT_CHARS) 6362306a36Sopenharmony_ci count = MAX_VIO_PUT_CHARS; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci ret = plpar_hcall_norets(H_PUT_TERM_CHAR, vtermno, count, 6662306a36Sopenharmony_ci cpu_to_be64(lbuf[0]), 6762306a36Sopenharmony_ci cpu_to_be64(lbuf[1])); 6862306a36Sopenharmony_ci if (ret == H_SUCCESS) 6962306a36Sopenharmony_ci return count; 7062306a36Sopenharmony_ci if (ret == H_BUSY) 7162306a36Sopenharmony_ci return -EAGAIN; 7262306a36Sopenharmony_ci return -EIO; 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ciEXPORT_SYMBOL(hvc_put_chars); 76