TTY/Serial patches for 5.10-rc1
Here is the big set of tty and serial driver patches for 5.10-rc1. Lots of little things in here, including: - tasklet_setup api conversions - sysrq support for capital letters - vt and vc cleanups and unwinding the mess some more - serial driver updates and minor tweaks - new device ids - rs485 support for some drivers - serial binding documentation updates - lots of small serial driver changes for reported issues All have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCX4c5vA8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ykVRACfWQRqsz/IIs6MZsDY9dkj4+QVUWAAn0mN2uHR mBox8w4TdTfG96jFXSfF =WYKP -----END PGP SIGNATURE----- Merge tag 'tty-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty Pull tty/serial updates from Greg KH: "Here is the big set of tty and serial driver patches for 5.10-rc1. Lots of little things in here, including: - tasklet_setup api conversions - sysrq support for capital letters - vt and vc cleanups and unwinding the mess some more - serial driver updates and minor tweaks - new device ids - rs485 support for some drivers - serial binding documentation updates - lots of small serial driver changes for reported issues All have been in linux-next for a while with no reported issues" * tag 'tty-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (79 commits) serial: mcf: add sysrq capability serial: fsl_lpuart: add sysrq support when using dma fbcon: remove no-op fbcon_set_origin() tty/sysrq: Extend the sysrq_key_table to cover capital letters serial: max310x: rework RX interrupt handling serial: 8250_dw: Fix clk-notifier/port suspend deadlock serial: 8250: Skip uninitialized TTY port baud rate update serial: 8250: Discard RTS/DTS setting from clock update method tty: serial: imx: disable TXDC IRQ in imx_uart_shutdown() to avoid IRQ storm serial: 8250_fsl: Fix TX interrupt handling condition serial: pl011: Fix lockdep splat when handling magic-sysrq interrupt tty: serial: fsl_lpuart: fix lpuart32_poll_get_char tty: serial: lpuart: fix lpuart32_write usage serial: qcom_geni_serial: To correct QUP Version detection logic serial: mvebu-uart: fix unused variable warning vt_ioctl: make VT_RESIZEX behave like VT_RESIZE serial: mvebu-uart: simplify the return expression of mvebu_uart_probe() tty: serial: imx: fix link error with CONFIG_SERIAL_CORE_CONSOLE=n tty: hvc: fix link error with CONFIG_SERIAL_CORE_CONSOLE=n pch_uart: drop double zeroing ...
This commit is contained in:
Коммит
5d6c413c92
|
@ -79,6 +79,8 @@ On all
|
|||
|
||||
echo t > /proc/sysrq-trigger
|
||||
|
||||
The :kbd:`<command key>` is case sensitive.
|
||||
|
||||
What are the 'command' keys?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ Required properties:
|
|||
* "mediatek,mt8135-uart" for MT8135 compatible UARTS
|
||||
* "mediatek,mt8173-uart" for MT8173 compatible UARTS
|
||||
* "mediatek,mt8183-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS
|
||||
* "mediatek,mt8192-uart", "mediatek,mt6577-uart" for MT8192 compatible UARTS
|
||||
* "mediatek,mt8516-uart" for MT8516 compatible UARTS
|
||||
* "mediatek,mt6577-uart" for MT6577 and all of the above
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ properties:
|
|||
- renesas,hscif-r8a774a1 # RZ/G2M
|
||||
- renesas,hscif-r8a774b1 # RZ/G2N
|
||||
- renesas,hscif-r8a774c0 # RZ/G2E
|
||||
- renesas,hscif-r8a774e1 # RZ/G2H
|
||||
- renesas,hscif-r8a7795 # R-Car H3
|
||||
- renesas,hscif-r8a7796 # R-Car M3-W
|
||||
- renesas,hscif-r8a77961 # R-Car M3-W+
|
||||
|
|
|
@ -51,6 +51,7 @@ properties:
|
|||
- renesas,scif-r8a774a1 # RZ/G2M
|
||||
- renesas,scif-r8a774b1 # RZ/G2N
|
||||
- renesas,scif-r8a774c0 # RZ/G2E
|
||||
- renesas,scif-r8a774e1 # RZ/G2H
|
||||
- renesas,scif-r8a7795 # R-Car H3
|
||||
- renesas,scif-r8a7796 # R-Car M3-W
|
||||
- renesas,scif-r8a77961 # R-Car M3-W+
|
||||
|
|
|
@ -22,6 +22,7 @@ Required properties:
|
|||
|
||||
For those SoCs that use SYST
|
||||
* "mediatek,mt8183-timer" for MT8183 compatible timers (SYST)
|
||||
* "mediatek,mt8192-timer" for MT8192 compatible timers (SYST)
|
||||
* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
|
||||
* "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
|
||||
|
||||
|
|
|
@ -257,7 +257,7 @@ static struct notifier_block vt_notifier_block = {
|
|||
|
||||
static unsigned char get_attributes(struct vc_data *vc, u16 *pos)
|
||||
{
|
||||
pos = screen_pos(vc, pos - (u16 *)vc->vc_origin, 1);
|
||||
pos = screen_pos(vc, pos - (u16 *)vc->vc_origin, true);
|
||||
return (scr_readw(pos) & ~vc->vc_hi_font_mask) >> 8;
|
||||
}
|
||||
|
||||
|
@ -465,7 +465,7 @@ static u16 get_char(struct vc_data *vc, u16 *pos, u_char *attribs)
|
|||
u16 w;
|
||||
u16 c;
|
||||
|
||||
pos = screen_pos(vc, pos - (u16 *)vc->vc_origin, 1);
|
||||
pos = screen_pos(vc, pos - (u16 *)vc->vc_origin, true);
|
||||
w = scr_readw(pos);
|
||||
c = w & 0xff;
|
||||
|
||||
|
|
|
@ -325,7 +325,7 @@ static void drm_fb_helper_sysrq(int dummy1)
|
|||
|
||||
static const struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
|
||||
.handler = drm_fb_helper_sysrq,
|
||||
.help_msg = "force-fb(V)",
|
||||
.help_msg = "force-fb(v)",
|
||||
.action_msg = "Restore framebuffer console",
|
||||
};
|
||||
#else
|
||||
|
|
|
@ -81,6 +81,7 @@ config HVC_DCC
|
|||
bool "ARM JTAG DCC console"
|
||||
depends on ARM || ARM64
|
||||
select HVC_DRIVER
|
||||
select SERIAL_CORE_CONSOLE
|
||||
help
|
||||
This console uses the JTAG DCC on ARM to create a console under the HVC
|
||||
driver. This console is used through a JTAG only on ARM. If you don't have
|
||||
|
|
|
@ -1216,13 +1216,6 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
|
|||
|
||||
tty_wait_until_sent(tty, HVCS_CLOSE_WAIT);
|
||||
|
||||
/*
|
||||
* This line is important because it tells hvcs_open that this
|
||||
* device needs to be re-configured the next time hvcs_open is
|
||||
* called.
|
||||
*/
|
||||
tty->driver_data = NULL;
|
||||
|
||||
free_irq(irq, hvcsd);
|
||||
return;
|
||||
} else if (hvcsd->port.count < 0) {
|
||||
|
@ -1237,6 +1230,13 @@ static void hvcs_cleanup(struct tty_struct * tty)
|
|||
{
|
||||
struct hvcs_struct *hvcsd = tty->driver_data;
|
||||
|
||||
/*
|
||||
* This line is important because it tells hvcs_open that this
|
||||
* device needs to be re-configured the next time hvcs_open is
|
||||
* called.
|
||||
*/
|
||||
tty->driver_data = NULL;
|
||||
|
||||
tty_port_put(&hvcsd->port);
|
||||
}
|
||||
|
||||
|
|
|
@ -1006,9 +1006,9 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
|
|||
/*
|
||||
* Send and receive all queued packets.
|
||||
*/
|
||||
static void ipwireless_do_tasklet(unsigned long hw_)
|
||||
static void ipwireless_do_tasklet(struct tasklet_struct *t)
|
||||
{
|
||||
struct ipw_hardware *hw = (struct ipw_hardware *) hw_;
|
||||
struct ipw_hardware *hw = from_tasklet(hw, t, tasklet);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&hw->lock, flags);
|
||||
|
@ -1635,7 +1635,7 @@ struct ipw_hardware *ipwireless_hardware_create(void)
|
|||
INIT_LIST_HEAD(&hw->rx_queue);
|
||||
INIT_LIST_HEAD(&hw->rx_pool);
|
||||
spin_lock_init(&hw->lock);
|
||||
tasklet_init(&hw->tasklet, ipwireless_do_tasklet, (unsigned long) hw);
|
||||
tasklet_setup(&hw->tasklet, ipwireless_do_tasklet);
|
||||
INIT_WORK(&hw->work_rx, ipw_receive_data_work);
|
||||
timer_setup(&hw->setup_timer, ipwireless_setup_timer, 0);
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel,
|
|||
skb->len,
|
||||
notify_packet_sent,
|
||||
network);
|
||||
if (ret == -1) {
|
||||
if (ret < 0) {
|
||||
skb_pull(skb, 2);
|
||||
return 0;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel,
|
|||
notify_packet_sent,
|
||||
network);
|
||||
kfree(buf);
|
||||
if (ret == -1)
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
|
|
@ -218,7 +218,7 @@ static int ipw_write(struct tty_struct *linux_tty,
|
|||
ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS,
|
||||
buf, count,
|
||||
ipw_write_packet_sent_callback, tty);
|
||||
if (ret == -1) {
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&tty->ipw_tty_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -76,10 +76,9 @@ module_param(debug, int, 0600);
|
|||
|
||||
/**
|
||||
* struct gsm_mux_net - network interface
|
||||
* @struct gsm_dlci* dlci
|
||||
*
|
||||
* Created when net interface is initialized.
|
||||
**/
|
||||
*/
|
||||
struct gsm_mux_net {
|
||||
struct kref ref;
|
||||
struct gsm_dlci *dlci;
|
||||
|
@ -222,11 +221,8 @@ struct gsm_mux {
|
|||
u8 received_fcs;
|
||||
u8 *txframe; /* TX framing buffer */
|
||||
|
||||
/* Methods for the receiver side */
|
||||
/* Method for the receiver side */
|
||||
void (*receive)(struct gsm_mux *gsm, u8 ch);
|
||||
void (*error)(struct gsm_mux *gsm, u8 ch, u8 flag);
|
||||
/* And transmit side */
|
||||
int (*output)(struct gsm_mux *mux, u8 *data, int len);
|
||||
|
||||
/* Link Layer */
|
||||
unsigned int mru;
|
||||
|
@ -366,6 +362,8 @@ static const u8 gsm_fcs8[256] = {
|
|||
#define INIT_FCS 0xFF
|
||||
#define GOOD_FCS 0xCF
|
||||
|
||||
static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len);
|
||||
|
||||
/**
|
||||
* gsm_fcs_add - update FCS
|
||||
* @fcs: Current FCS
|
||||
|
@ -400,7 +398,7 @@ static inline u8 gsm_fcs_add_block(u8 fcs, u8 *c, int len)
|
|||
/**
|
||||
* gsm_read_ea - read a byte into an EA
|
||||
* @val: variable holding value
|
||||
* c: byte going into the EA
|
||||
* @c: byte going into the EA
|
||||
*
|
||||
* Processes one byte of an EA. Updates the passed variable
|
||||
* and returns 1 if the EA is now completely read
|
||||
|
@ -514,8 +512,8 @@ static void gsm_print_packet(const char *hdr, int addr, int cr,
|
|||
|
||||
/**
|
||||
* gsm_stuff_packet - bytestuff a packet
|
||||
* @ibuf: input
|
||||
* @obuf: output
|
||||
* @input: input buffer
|
||||
* @output: output buffer
|
||||
* @len: length of input
|
||||
*
|
||||
* Expand a buffer by bytestuffing it. The worst case size change
|
||||
|
@ -587,7 +585,7 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
|
|||
WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
gsm->output(gsm, cbuf, len);
|
||||
gsmld_output(gsm, cbuf, len);
|
||||
gsm_print_packet("-->", addr, cr, control, NULL, 0);
|
||||
}
|
||||
|
||||
|
@ -687,7 +685,7 @@ static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci)
|
|||
print_hex_dump_bytes("gsm_data_kick: ",
|
||||
DUMP_PREFIX_OFFSET,
|
||||
gsm->txframe, len);
|
||||
if (gsm->output(gsm, gsm->txframe, len) < 0)
|
||||
if (gsmld_output(gsm, gsm->txframe, len) < 0)
|
||||
break;
|
||||
/* FIXME: Can eliminate one SOF in many more cases */
|
||||
gsm->tx_bytes -= msg->len;
|
||||
|
@ -1305,7 +1303,7 @@ static void gsm_control_transmit(struct gsm_mux *gsm, struct gsm_control *ctrl)
|
|||
|
||||
/**
|
||||
* gsm_control_retransmit - retransmit a control frame
|
||||
* @data: pointer to our gsm object
|
||||
* @t: timer contained in our gsm object
|
||||
*
|
||||
* Called off the T2 timer expiry in order to retransmit control frames
|
||||
* that have been lost in the system somewhere. The control_lock protects
|
||||
|
@ -1342,7 +1340,7 @@ static void gsm_control_retransmit(struct timer_list *t)
|
|||
* @gsm: the GSM channel
|
||||
* @command: command to send including CR bit
|
||||
* @data: bytes of data (must be kmalloced)
|
||||
* @len: length of the block to send
|
||||
* @clen: length of the block to send
|
||||
*
|
||||
* Queue and dispatch a control command. Only one command can be
|
||||
* active at a time. In theory more can be outstanding but the matching
|
||||
|
@ -1454,7 +1452,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
|
|||
|
||||
/**
|
||||
* gsm_dlci_t1 - T1 timer expiry
|
||||
* @dlci: DLCI that opened
|
||||
* @t: timer contained in the DLCI that opened
|
||||
*
|
||||
* The T1 timer handles retransmits of control frames (essentially of
|
||||
* SABM and DISC). We resend the command until the retry count runs out
|
||||
|
@ -1550,7 +1548,7 @@ static void gsm_dlci_begin_close(struct gsm_dlci *dlci)
|
|||
* gsm_dlci_data - data arrived
|
||||
* @dlci: channel
|
||||
* @data: block of bytes received
|
||||
* @len: length of received block
|
||||
* @clen: length of received block
|
||||
*
|
||||
* A UI or UIH frame has arrived which contains data for a channel
|
||||
* other than the control channel. If the relevant virtual tty is
|
||||
|
@ -1672,7 +1670,7 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
|
|||
|
||||
/**
|
||||
* gsm_dlci_free - free DLCI
|
||||
* @dlci: DLCI to free
|
||||
* @port: tty port for DLCI to free
|
||||
*
|
||||
* Free up a DLCI.
|
||||
*
|
||||
|
@ -2128,7 +2126,6 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
|
|||
gsm->receive = gsm0_receive;
|
||||
else
|
||||
gsm->receive = gsm1_receive;
|
||||
gsm->error = gsm_error;
|
||||
|
||||
spin_lock(&gsm_mux_lock);
|
||||
for (i = 0; i < MAX_MUX; i++) {
|
||||
|
@ -2151,7 +2148,7 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
|
|||
|
||||
/**
|
||||
* gsm_free_mux - free up a mux
|
||||
* @mux: mux to free
|
||||
* @gsm: mux to free
|
||||
*
|
||||
* Dispose of allocated resources for a dead mux
|
||||
*/
|
||||
|
@ -2164,7 +2161,7 @@ static void gsm_free_mux(struct gsm_mux *gsm)
|
|||
|
||||
/**
|
||||
* gsm_free_muxr - free up a mux
|
||||
* @mux: mux to free
|
||||
* @ref: kreference to the mux to free
|
||||
*
|
||||
* Dispose of allocated resources for a dead mux
|
||||
*/
|
||||
|
@ -2378,7 +2375,6 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
|
|||
int ret, i;
|
||||
|
||||
gsm->tty = tty_kref_get(tty);
|
||||
gsm->output = gsmld_output;
|
||||
ret = gsm_activate_mux(gsm);
|
||||
if (ret != 0)
|
||||
tty_kref_put(gsm->tty);
|
||||
|
@ -2438,7 +2434,7 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
case TTY_BREAK:
|
||||
case TTY_PARITY:
|
||||
case TTY_FRAME:
|
||||
gsm->error(gsm, *dp, flags);
|
||||
gsm_error(gsm, *dp, flags);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "%s: unknown flag %d\n",
|
||||
|
|
|
@ -123,13 +123,13 @@ struct n_hdlc_buf_list {
|
|||
|
||||
/**
|
||||
* struct n_hdlc - per device instance data structure
|
||||
* @magic - magic value for structure
|
||||
* @tbusy - reentrancy flag for tx wakeup code
|
||||
* @woke_up - tx wakeup needs to be run again as it was called while @tbusy
|
||||
* @tx_buf_list - list of pending transmit frame buffers
|
||||
* @rx_buf_list - list of received frame buffers
|
||||
* @tx_free_buf_list - list unused transmit frame buffers
|
||||
* @rx_free_buf_list - list unused received frame buffers
|
||||
* @magic: magic value for structure
|
||||
* @tbusy: reentrancy flag for tx wakeup code
|
||||
* @woke_up: tx wakeup needs to be run again as it was called while @tbusy
|
||||
* @tx_buf_list: list of pending transmit frame buffers
|
||||
* @rx_buf_list: list of received frame buffers
|
||||
* @tx_free_buf_list: list unused transmit frame buffers
|
||||
* @rx_free_buf_list: list unused received frame buffers
|
||||
*/
|
||||
struct n_hdlc {
|
||||
int magic;
|
||||
|
@ -187,7 +187,7 @@ static void n_hdlc_free_buf_list(struct n_hdlc_buf_list *list)
|
|||
|
||||
/**
|
||||
* n_hdlc_tty_close - line discipline close
|
||||
* @tty - pointer to tty info structure
|
||||
* @tty: pointer to tty info structure
|
||||
*
|
||||
* Called when the line discipline is changed to something
|
||||
* else, the tty is closed, or the tty detects a hangup.
|
||||
|
@ -218,7 +218,7 @@ static void n_hdlc_tty_close(struct tty_struct *tty)
|
|||
|
||||
/**
|
||||
* n_hdlc_tty_open - called when line discipline changed to n_hdlc
|
||||
* @tty - pointer to tty info structure
|
||||
* @tty: pointer to tty info structure
|
||||
*
|
||||
* Returns 0 if success, otherwise error code
|
||||
*/
|
||||
|
@ -255,8 +255,8 @@ static int n_hdlc_tty_open(struct tty_struct *tty)
|
|||
|
||||
/**
|
||||
* n_hdlc_send_frames - send frames on pending send buffer list
|
||||
* @n_hdlc - pointer to ldisc instance data
|
||||
* @tty - pointer to tty instance data
|
||||
* @n_hdlc: pointer to ldisc instance data
|
||||
* @tty: pointer to tty instance data
|
||||
*
|
||||
* Send frames on pending send buffer list until the driver does not accept a
|
||||
* frame (busy) this function is called after adding a frame to the send buffer
|
||||
|
@ -335,7 +335,7 @@ check_again:
|
|||
|
||||
/**
|
||||
* n_hdlc_tty_wakeup - Callback for transmit wakeup
|
||||
* @tty - pointer to associated tty instance data
|
||||
* @tty: pointer to associated tty instance data
|
||||
*
|
||||
* Called when low level device driver can accept more send data.
|
||||
*/
|
||||
|
@ -348,10 +348,10 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty)
|
|||
|
||||
/**
|
||||
* n_hdlc_tty_receive - Called by tty driver when receive data is available
|
||||
* @tty - pointer to tty instance data
|
||||
* @data - pointer to received data
|
||||
* @flags - pointer to flags for data
|
||||
* @count - count of received data in bytes
|
||||
* @tty: pointer to tty instance data
|
||||
* @data: pointer to received data
|
||||
* @flags: pointer to flags for data
|
||||
* @count: count of received data in bytes
|
||||
*
|
||||
* Called by tty low level driver when receive data is available. Data is
|
||||
* interpreted as one HDLC frame.
|
||||
|
@ -408,10 +408,10 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
|
|||
|
||||
/**
|
||||
* n_hdlc_tty_read - Called to retrieve one frame of data (if available)
|
||||
* @tty - pointer to tty instance data
|
||||
* @file - pointer to open file object
|
||||
* @buf - pointer to returned data buffer
|
||||
* @nr - size of returned data buffer
|
||||
* @tty: pointer to tty instance data
|
||||
* @file: pointer to open file object
|
||||
* @buf: pointer to returned data buffer
|
||||
* @nr: size of returned data buffer
|
||||
*
|
||||
* Returns the number of bytes returned or error code.
|
||||
*/
|
||||
|
@ -479,10 +479,10 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
|
|||
|
||||
/**
|
||||
* n_hdlc_tty_write - write a single frame of data to device
|
||||
* @tty - pointer to associated tty device instance data
|
||||
* @file - pointer to file object data
|
||||
* @data - pointer to transmit data (one frame)
|
||||
* @count - size of transmit frame in bytes
|
||||
* @tty: pointer to associated tty device instance data
|
||||
* @file: pointer to file object data
|
||||
* @data: pointer to transmit data (one frame)
|
||||
* @count: size of transmit frame in bytes
|
||||
*
|
||||
* Returns the number of bytes written (or error code).
|
||||
*/
|
||||
|
@ -546,10 +546,10 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
|
|||
|
||||
/**
|
||||
* n_hdlc_tty_ioctl - process IOCTL system call for the tty device.
|
||||
* @tty - pointer to tty instance data
|
||||
* @file - pointer to open file object for device
|
||||
* @cmd - IOCTL command code
|
||||
* @arg - argument for IOCTL call (cmd dependent)
|
||||
* @tty: pointer to tty instance data
|
||||
* @file: pointer to open file object for device
|
||||
* @cmd: IOCTL command code
|
||||
* @arg: argument for IOCTL call (cmd dependent)
|
||||
*
|
||||
* Returns command dependent result.
|
||||
*/
|
||||
|
@ -614,9 +614,9 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
|
|||
|
||||
/**
|
||||
* n_hdlc_tty_poll - TTY callback for poll system call
|
||||
* @tty - pointer to tty instance data
|
||||
* @filp - pointer to open file object for device
|
||||
* @poll_table - wait queue for operations
|
||||
* @tty: pointer to tty instance data
|
||||
* @filp: pointer to open file object for device
|
||||
* @wait: wait queue for operations
|
||||
*
|
||||
* Determine which operations (read/write) will not block and return info
|
||||
* to caller.
|
||||
|
@ -703,8 +703,8 @@ static struct n_hdlc *n_hdlc_alloc(void)
|
|||
|
||||
/**
|
||||
* n_hdlc_buf_return - put the HDLC buffer after the head of the specified list
|
||||
* @buf_list - pointer to the buffer list
|
||||
* @buf - pointer to the buffer
|
||||
* @buf_list: pointer to the buffer list
|
||||
* @buf: pointer to the buffer
|
||||
*/
|
||||
static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list,
|
||||
struct n_hdlc_buf *buf)
|
||||
|
@ -721,8 +721,8 @@ static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list,
|
|||
|
||||
/**
|
||||
* n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
|
||||
* @buf_list - pointer to buffer list
|
||||
* @buf - pointer to buffer
|
||||
* @buf_list: pointer to buffer list
|
||||
* @buf: pointer to buffer
|
||||
*/
|
||||
static void n_hdlc_buf_put(struct n_hdlc_buf_list *buf_list,
|
||||
struct n_hdlc_buf *buf)
|
||||
|
@ -739,7 +739,7 @@ static void n_hdlc_buf_put(struct n_hdlc_buf_list *buf_list,
|
|||
|
||||
/**
|
||||
* n_hdlc_buf_get - remove and return an HDLC buffer from list
|
||||
* @buf_list - pointer to HDLC buffer list
|
||||
* @buf_list: pointer to HDLC buffer list
|
||||
*
|
||||
* Remove and return an HDLC buffer from the head of the specified HDLC buffer
|
||||
* list.
|
||||
|
|
|
@ -322,7 +322,7 @@ static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
|
|||
|
||||
/**
|
||||
* reset_buffer_flags - reset buffer state
|
||||
* @tty: terminal to reset
|
||||
* @ldata: line disc data to reset
|
||||
*
|
||||
* Reset the read buffer counters and clear the flags.
|
||||
* Called from n_tty_open() and n_tty_flush_buffer().
|
||||
|
@ -906,7 +906,7 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab,
|
|||
/**
|
||||
* echo_char_raw - echo a character raw
|
||||
* @c: unicode byte to echo
|
||||
* @tty: terminal device
|
||||
* @ldata: line disc data
|
||||
*
|
||||
* Echo user input back onto the screen. This must be called only when
|
||||
* L_ECHO(tty) is true. Called from the driver receive_buf path.
|
||||
|
|
|
@ -100,7 +100,7 @@ static void pty_unthrottle(struct tty_struct *tty)
|
|||
* pty_write - write to a pty
|
||||
* @tty: the tty we write from
|
||||
* @buf: kernel buffer of data
|
||||
* @count: bytes to write
|
||||
* @c: bytes to write
|
||||
*
|
||||
* Our "hardware" write method. Data is coming from the ldisc which
|
||||
* may be in a non sleeping state. We simply throw this at the other
|
||||
|
@ -120,10 +120,10 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
|
|||
spin_lock_irqsave(&to->port->lock, flags);
|
||||
/* Stuff the data into the input queue of the other end */
|
||||
c = tty_insert_flip_string(to->port, buf, c);
|
||||
spin_unlock_irqrestore(&to->port->lock, flags);
|
||||
/* And shovel */
|
||||
if (c)
|
||||
tty_flip_buffer_push(to->port);
|
||||
spin_unlock_irqrestore(&to->port->lock, flags);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
|
|
@ -110,12 +110,8 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev)
|
|||
|
||||
/* get the clock - this also enables the HW */
|
||||
data->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
ret = PTR_ERR_OR_ZERO(data->clk);
|
||||
if (ret) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "could not get clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (IS_ERR(data->clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(data->clk), "could not get clk\n");
|
||||
|
||||
/* get the interrupt */
|
||||
ret = platform_get_irq(pdev, 0);
|
||||
|
@ -155,9 +151,7 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev)
|
|||
/* register the port */
|
||||
ret = serial8250_register_8250_port(&up);
|
||||
if (ret < 0) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev,
|
||||
"unable to register 8250 port - %d\n", ret);
|
||||
dev_err_probe(&pdev->dev, ret, "unable to register 8250 port\n");
|
||||
goto dis_clk;
|
||||
}
|
||||
data->line = ret;
|
||||
|
|
|
@ -373,39 +373,6 @@ static void dw8250_set_ldisc(struct uart_port *p, struct ktermios *termios)
|
|||
serial8250_do_set_ldisc(p, termios);
|
||||
}
|
||||
|
||||
static int dw8250_startup(struct uart_port *p)
|
||||
{
|
||||
struct dw8250_data *d = to_dw8250_data(p->private_data);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Some platforms may provide a reference clock shared between several
|
||||
* devices. In this case before using the serial port first we have to
|
||||
* make sure that any clock state change is known to the UART port at
|
||||
* least post factum.
|
||||
*/
|
||||
if (d->clk) {
|
||||
ret = clk_notifier_register(d->clk, &d->clk_notifier);
|
||||
if (ret)
|
||||
dev_warn(p->dev, "Failed to set the clock notifier\n");
|
||||
}
|
||||
|
||||
return serial8250_do_startup(p);
|
||||
}
|
||||
|
||||
static void dw8250_shutdown(struct uart_port *p)
|
||||
{
|
||||
struct dw8250_data *d = to_dw8250_data(p->private_data);
|
||||
|
||||
serial8250_do_shutdown(p);
|
||||
|
||||
if (d->clk) {
|
||||
clk_notifier_unregister(d->clk, &d->clk_notifier);
|
||||
|
||||
flush_work(&d->clk_work);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dw8250_fallback_dma_filter will prevent the UART from getting just any free
|
||||
* channel on platforms that have DMA engines, but don't have any channels
|
||||
|
@ -501,8 +468,6 @@ static int dw8250_probe(struct platform_device *pdev)
|
|||
p->serial_out = dw8250_serial_out;
|
||||
p->set_ldisc = dw8250_set_ldisc;
|
||||
p->set_termios = dw8250_set_termios;
|
||||
p->startup = dw8250_startup;
|
||||
p->shutdown = dw8250_shutdown;
|
||||
|
||||
p->membase = devm_ioremap(dev, regs->start, resource_size(regs));
|
||||
if (!p->membase)
|
||||
|
@ -622,6 +587,19 @@ static int dw8250_probe(struct platform_device *pdev)
|
|||
goto err_reset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some platforms may provide a reference clock shared between several
|
||||
* devices. In this case any clock state change must be known to the
|
||||
* UART port at least post factum.
|
||||
*/
|
||||
if (data->clk) {
|
||||
err = clk_notifier_register(data->clk, &data->clk_notifier);
|
||||
if (err)
|
||||
dev_warn(p->dev, "Failed to set the clock notifier\n");
|
||||
else
|
||||
queue_work(system_unbound_wq, &data->clk_work);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
|
@ -648,6 +626,12 @@ static int dw8250_remove(struct platform_device *pdev)
|
|||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
if (data->clk) {
|
||||
clk_notifier_unregister(data->clk, &data->clk_notifier);
|
||||
|
||||
flush_work(&data->clk_work);
|
||||
}
|
||||
|
||||
serial8250_unregister_port(data->data.line);
|
||||
|
||||
reset_control_assert(data->rst);
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/serial_8250.h>
|
||||
|
||||
#include "8250.h"
|
||||
|
||||
/*
|
||||
* Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker.
|
||||
* Copyright 2020 NXP
|
||||
* Copyright 2020 Puresoftware Ltd.
|
||||
*
|
||||
* This isn't a full driver; it just provides an alternate IRQ
|
||||
* handler to deal with an errata. Everything else is just
|
||||
* using the bog standard 8250 support.
|
||||
* handler to deal with an errata and provide ACPI wrapper.
|
||||
* Everything else is just using the bog standard 8250 support.
|
||||
*
|
||||
* We follow code flow of serial8250_default_handle_irq() but add
|
||||
* a check for a break and insert a dummy read on the Rx for the
|
||||
|
@ -20,6 +17,16 @@
|
|||
* IRQ event to the next one.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/serial_8250.h>
|
||||
|
||||
#include "8250.h"
|
||||
|
||||
struct fsl8250_data {
|
||||
int line;
|
||||
};
|
||||
|
||||
int fsl8250_handle_irq(struct uart_port *port)
|
||||
{
|
||||
unsigned char lsr, orig_lsr;
|
||||
|
@ -71,7 +78,7 @@ int fsl8250_handle_irq(struct uart_port *port)
|
|||
|
||||
serial8250_modem_status(up);
|
||||
|
||||
if (lsr & UART_LSR_THRE)
|
||||
if ((lsr & UART_LSR_THRE) && (up->ier & UART_IER_THRI))
|
||||
serial8250_tx_chars(up);
|
||||
|
||||
up->lsr_saved_flags = orig_lsr;
|
||||
|
@ -79,3 +86,90 @@ int fsl8250_handle_irq(struct uart_port *port)
|
|||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsl8250_handle_irq);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static int fsl8250_acpi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct fsl8250_data *data;
|
||||
struct uart_8250_port port8250;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *regs;
|
||||
|
||||
int ret, irq;
|
||||
|
||||
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!regs) {
|
||||
dev_err(dev, "no registers defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
if (irq != -EPROBE_DEFER)
|
||||
dev_err(dev, "cannot get irq\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
memset(&port8250, 0, sizeof(port8250));
|
||||
|
||||
ret = device_property_read_u32(dev, "clock-frequency",
|
||||
&port8250.port.uartclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spin_lock_init(&port8250.port.lock);
|
||||
|
||||
port8250.port.mapbase = regs->start;
|
||||
port8250.port.irq = irq;
|
||||
port8250.port.handle_irq = fsl8250_handle_irq;
|
||||
port8250.port.type = PORT_16550A;
|
||||
port8250.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
|
||||
| UPF_FIXED_PORT | UPF_IOREMAP
|
||||
| UPF_FIXED_TYPE;
|
||||
port8250.port.dev = dev;
|
||||
port8250.port.mapsize = resource_size(regs);
|
||||
port8250.port.iotype = UPIO_MEM;
|
||||
port8250.port.irqflags = IRQF_SHARED;
|
||||
|
||||
port8250.port.membase = devm_ioremap(dev, port8250.port.mapbase,
|
||||
port8250.port.mapsize);
|
||||
if (!port8250.port.membase)
|
||||
return -ENOMEM;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->line = serial8250_register_8250_port(&port8250);
|
||||
if (data->line < 0)
|
||||
return data->line;
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsl8250_acpi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct fsl8250_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
serial8250_unregister_port(data->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id fsl_8250_acpi_id[] = {
|
||||
{ "NXP0018", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, fsl_8250_acpi_id);
|
||||
|
||||
static struct platform_driver fsl8250_platform_driver = {
|
||||
.driver = {
|
||||
.name = "fsl-16550-uart",
|
||||
.acpi_match_table = ACPI_PTR(fsl_8250_acpi_id),
|
||||
},
|
||||
.probe = fsl8250_acpi_probe,
|
||||
.remove = fsl8250_acpi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(fsl8250_platform_driver);
|
||||
#endif
|
||||
|
|
|
@ -259,22 +259,14 @@ static int ingenic_uart_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
|
||||
data->clk_module = devm_clk_get(&pdev->dev, "module");
|
||||
if (IS_ERR(data->clk_module)) {
|
||||
err = PTR_ERR(data->clk_module);
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev,
|
||||
"unable to get module clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
if (IS_ERR(data->clk_module))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(data->clk_module),
|
||||
"unable to get module clock\n");
|
||||
|
||||
data->clk_baud = devm_clk_get(&pdev->dev, "baud");
|
||||
if (IS_ERR(data->clk_baud)) {
|
||||
err = PTR_ERR(data->clk_baud);
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev,
|
||||
"unable to get baud clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
if (IS_ERR(data->clk_baud))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(data->clk_baud),
|
||||
"unable to get baud clock\n");
|
||||
|
||||
err = clk_prepare_enable(data->clk_module);
|
||||
if (err) {
|
||||
|
|
|
@ -669,6 +669,7 @@ static int __init early_mtk8250_setup(struct earlycon_device *device,
|
|||
return -ENODEV;
|
||||
|
||||
device->port.iotype = UPIO_MEM32;
|
||||
device->port.regshift = 2;
|
||||
|
||||
return early_serial8250_setup(device, NULL);
|
||||
}
|
||||
|
|
|
@ -1776,6 +1776,39 @@ pci_wch_ch38x_setup(struct serial_private *priv,
|
|||
return pci_default_setup(priv, board, port, idx);
|
||||
}
|
||||
|
||||
|
||||
#define CH384_XINT_ENABLE_REG 0xEB
|
||||
#define CH384_XINT_ENABLE_BIT 0x02
|
||||
|
||||
static int pci_wch_ch38x_init(struct pci_dev *dev)
|
||||
{
|
||||
int max_port;
|
||||
unsigned long iobase;
|
||||
|
||||
|
||||
switch (dev->device) {
|
||||
case 0x3853: /* 8 ports */
|
||||
max_port = 8;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
iobase = pci_resource_start(dev, 0);
|
||||
outb(CH384_XINT_ENABLE_BIT, iobase + CH384_XINT_ENABLE_REG);
|
||||
|
||||
return max_port;
|
||||
}
|
||||
|
||||
static void pci_wch_ch38x_exit(struct pci_dev *dev)
|
||||
{
|
||||
unsigned long iobase;
|
||||
|
||||
iobase = pci_resource_start(dev, 0);
|
||||
outb(0x0, iobase + CH384_XINT_ENABLE_REG);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pci_sunix_setup(struct serial_private *priv,
|
||||
const struct pciserial_board *board,
|
||||
|
@ -1867,6 +1900,7 @@ pci_moxa_setup(struct serial_private *priv,
|
|||
#define PCIE_VENDOR_ID_WCH 0x1c00
|
||||
#define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250
|
||||
#define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470
|
||||
#define PCIE_DEVICE_ID_WCH_CH384_8S 0x3853
|
||||
#define PCIE_DEVICE_ID_WCH_CH382_2S 0x3253
|
||||
|
||||
#define PCI_VENDOR_ID_ACCESIO 0x494f
|
||||
|
@ -2642,6 +2676,16 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
|||
.subdevice = PCI_ANY_ID,
|
||||
.setup = pci_wch_ch38x_setup,
|
||||
},
|
||||
/* WCH CH384 8S card (16850 clone) */
|
||||
{
|
||||
.vendor = PCIE_VENDOR_ID_WCH,
|
||||
.device = PCIE_DEVICE_ID_WCH_CH384_8S,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.init = pci_wch_ch38x_init,
|
||||
.exit = pci_wch_ch38x_exit,
|
||||
.setup = pci_wch_ch38x_setup,
|
||||
},
|
||||
/*
|
||||
* ASIX devices with FIFO bug
|
||||
*/
|
||||
|
@ -2751,15 +2795,6 @@ static struct pci_serial_quirk *find_quirk(struct pci_dev *dev)
|
|||
return quirk;
|
||||
}
|
||||
|
||||
static inline int get_pci_irq(struct pci_dev *dev,
|
||||
const struct pciserial_board *board)
|
||||
{
|
||||
if (board->flags & FL_NOIRQ)
|
||||
return 0;
|
||||
else
|
||||
return dev->irq;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the configuration table for all of the PCI serial boards
|
||||
* which we support. It is directly indexed by the pci_board_num_t enum
|
||||
|
@ -2913,6 +2948,7 @@ enum pci_board_num_t {
|
|||
pbn_fintek_F81512A,
|
||||
pbn_wch382_2,
|
||||
pbn_wch384_4,
|
||||
pbn_wch384_8,
|
||||
pbn_pericom_PI7C9X7951,
|
||||
pbn_pericom_PI7C9X7952,
|
||||
pbn_pericom_PI7C9X7954,
|
||||
|
@ -3650,6 +3686,13 @@ static struct pciserial_board pci_boards[] = {
|
|||
.uart_offset = 8,
|
||||
.first_offset = 0xC0,
|
||||
},
|
||||
[pbn_wch384_8] = {
|
||||
.flags = FL_BASE0,
|
||||
.num_ports = 8,
|
||||
.base_baud = 115200,
|
||||
.uart_offset = 8,
|
||||
.first_offset = 0x00,
|
||||
},
|
||||
/*
|
||||
* Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART
|
||||
*/
|
||||
|
@ -5566,6 +5609,9 @@ static const struct pci_device_id serial_pci_tbl[] = {
|
|||
PCI_ANY_ID, PCI_ANY_ID,
|
||||
0, 0, pbn_wch384_4 },
|
||||
|
||||
{ PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_8S,
|
||||
PCI_ANY_ID, PCI_ANY_ID,
|
||||
0, 0, pbn_wch384_8 },
|
||||
/*
|
||||
* Realtek RealManage
|
||||
*/
|
||||
|
|
|
@ -2653,6 +2653,10 @@ void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk)
|
|||
goto out_lock;
|
||||
|
||||
port->uartclk = uartclk;
|
||||
|
||||
if (!tty_port_initialized(&port->state->port))
|
||||
goto out_lock;
|
||||
|
||||
termios = &port->state->port.tty->termios;
|
||||
|
||||
baud = serial8250_get_baud_rate(port, termios, NULL);
|
||||
|
@ -2665,7 +2669,6 @@ void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk)
|
|||
|
||||
serial8250_set_divisor(port, baud, quot, frac);
|
||||
serial_port_out(port, UART_LCR, up->lcr);
|
||||
serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
|
||||
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
serial8250_rpm_put(up);
|
||||
|
|
|
@ -8,6 +8,7 @@ menu "Serial drivers"
|
|||
|
||||
config SERIAL_EARLYCON
|
||||
bool
|
||||
depends on SERIAL_CORE
|
||||
help
|
||||
Support for early consoles with the earlycon parameter. This enables
|
||||
the console before standard serial driver is probed. The console is
|
||||
|
@ -520,6 +521,7 @@ config SERIAL_IMX_EARLYCON
|
|||
depends on ARCH_MXC || COMPILE_TEST
|
||||
depends on OF
|
||||
select SERIAL_EARLYCON
|
||||
select SERIAL_CORE_CONSOLE
|
||||
help
|
||||
If you have enabled the earlycon on the Freescale IMX
|
||||
CPU you can make it the earlycon by answering Y to this option.
|
||||
|
|
|
@ -308,8 +308,9 @@ static void pl011_write(unsigned int val, const struct uart_amba_port *uap,
|
|||
*/
|
||||
static int pl011_fifo_to_tty(struct uart_amba_port *uap)
|
||||
{
|
||||
u16 status;
|
||||
unsigned int ch, flag, fifotaken;
|
||||
int sysrq;
|
||||
u16 status;
|
||||
|
||||
for (fifotaken = 0; fifotaken != 256; fifotaken++) {
|
||||
status = pl011_read(uap, REG_FR);
|
||||
|
@ -344,10 +345,12 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap)
|
|||
flag = TTY_FRAME;
|
||||
}
|
||||
|
||||
if (uart_handle_sysrq_char(&uap->port, ch & 255))
|
||||
continue;
|
||||
spin_unlock(&uap->port.lock);
|
||||
sysrq = uart_handle_sysrq_char(&uap->port, ch & 255);
|
||||
spin_lock(&uap->port.lock);
|
||||
|
||||
uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
|
||||
if (!sysrq)
|
||||
uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
|
||||
}
|
||||
|
||||
return fifotaken;
|
||||
|
|
|
@ -1722,10 +1722,11 @@ static int atmel_prepare_rx_pdc(struct uart_port *port)
|
|||
/*
|
||||
* tasklet handling tty stuff outside the interrupt handler.
|
||||
*/
|
||||
static void atmel_tasklet_rx_func(unsigned long data)
|
||||
static void atmel_tasklet_rx_func(struct tasklet_struct *t)
|
||||
{
|
||||
struct uart_port *port = (struct uart_port *)data;
|
||||
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
|
||||
struct atmel_uart_port *atmel_port = from_tasklet(atmel_port, t,
|
||||
tasklet_rx);
|
||||
struct uart_port *port = &atmel_port->uart;
|
||||
|
||||
/* The interrupt handler does not take the lock */
|
||||
spin_lock(&port->lock);
|
||||
|
@ -1733,10 +1734,11 @@ static void atmel_tasklet_rx_func(unsigned long data)
|
|||
spin_unlock(&port->lock);
|
||||
}
|
||||
|
||||
static void atmel_tasklet_tx_func(unsigned long data)
|
||||
static void atmel_tasklet_tx_func(struct tasklet_struct *t)
|
||||
{
|
||||
struct uart_port *port = (struct uart_port *)data;
|
||||
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
|
||||
struct atmel_uart_port *atmel_port = from_tasklet(atmel_port, t,
|
||||
tasklet_tx);
|
||||
struct uart_port *port = &atmel_port->uart;
|
||||
|
||||
/* The interrupt handler does not take the lock */
|
||||
spin_lock(&port->lock);
|
||||
|
@ -1911,10 +1913,8 @@ static int atmel_startup(struct uart_port *port)
|
|||
}
|
||||
|
||||
atomic_set(&atmel_port->tasklet_shutdown, 0);
|
||||
tasklet_init(&atmel_port->tasklet_rx, atmel_tasklet_rx_func,
|
||||
(unsigned long)port);
|
||||
tasklet_init(&atmel_port->tasklet_tx, atmel_tasklet_tx_func,
|
||||
(unsigned long)port);
|
||||
tasklet_setup(&atmel_port->tasklet_rx, atmel_tasklet_rx_func);
|
||||
tasklet_setup(&atmel_port->tasklet_tx, atmel_tasklet_tx_func);
|
||||
|
||||
/*
|
||||
* Initialize DMA (if necessary)
|
||||
|
|
|
@ -56,7 +56,6 @@ static void __init earlycon_init(struct earlycon_device *device,
|
|||
const char *name)
|
||||
{
|
||||
struct console *earlycon = device->con;
|
||||
struct uart_port *port = &device->port;
|
||||
const char *s;
|
||||
size_t len;
|
||||
|
||||
|
@ -70,6 +69,12 @@ static void __init earlycon_init(struct earlycon_device *device,
|
|||
len = s - name;
|
||||
strlcpy(earlycon->name, name, min(len + 1, sizeof(earlycon->name)));
|
||||
earlycon->data = &early_console_dev;
|
||||
}
|
||||
|
||||
static void __init earlycon_print_info(struct earlycon_device *device)
|
||||
{
|
||||
struct console *earlycon = device->con;
|
||||
struct uart_port *port = &device->port;
|
||||
|
||||
if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM16 ||
|
||||
port->iotype == UPIO_MEM32 || port->iotype == UPIO_MEM32BE)
|
||||
|
@ -140,6 +145,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match)
|
|||
|
||||
earlycon_init(&early_console_dev, match->name);
|
||||
err = match->setup(&early_console_dev, buf);
|
||||
earlycon_print_info(&early_console_dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (!early_console_dev.con->write)
|
||||
|
@ -302,6 +308,7 @@ int __init of_setup_earlycon(const struct earlycon_id *match,
|
|||
}
|
||||
earlycon_init(&early_console_dev, match->name);
|
||||
err = match->setup(&early_console_dev, options);
|
||||
earlycon_print_info(&early_console_dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (!early_console_dev.con->write)
|
||||
|
|
|
@ -649,26 +649,24 @@ static int lpuart32_poll_init(struct uart_port *port)
|
|||
spin_lock_irqsave(&sport->port.lock, flags);
|
||||
|
||||
/* Disable Rx & Tx */
|
||||
lpuart32_write(&sport->port, UARTCTRL, 0);
|
||||
lpuart32_write(&sport->port, 0, UARTCTRL);
|
||||
|
||||
temp = lpuart32_read(&sport->port, UARTFIFO);
|
||||
|
||||
/* Enable Rx and Tx FIFO */
|
||||
lpuart32_write(&sport->port, UARTFIFO,
|
||||
temp | UARTFIFO_RXFE | UARTFIFO_TXFE);
|
||||
lpuart32_write(&sport->port, temp | UARTFIFO_RXFE | UARTFIFO_TXFE, UARTFIFO);
|
||||
|
||||
/* flush Tx and Rx FIFO */
|
||||
lpuart32_write(&sport->port, UARTFIFO,
|
||||
UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH);
|
||||
lpuart32_write(&sport->port, UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, UARTFIFO);
|
||||
|
||||
/* explicitly clear RDRF */
|
||||
if (lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_RDRF) {
|
||||
lpuart32_read(&sport->port, UARTDATA);
|
||||
lpuart32_write(&sport->port, UARTFIFO, UARTFIFO_RXUF);
|
||||
lpuart32_write(&sport->port, UARTFIFO_RXUF, UARTFIFO);
|
||||
}
|
||||
|
||||
/* Enable Rx and Tx */
|
||||
lpuart32_write(&sport->port, UARTCTRL, UARTCTRL_RE | UARTCTRL_TE);
|
||||
lpuart32_write(&sport->port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL);
|
||||
spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
|
||||
return 0;
|
||||
|
@ -677,12 +675,12 @@ static int lpuart32_poll_init(struct uart_port *port)
|
|||
static void lpuart32_poll_put_char(struct uart_port *port, unsigned char c)
|
||||
{
|
||||
lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TDRE);
|
||||
lpuart32_write(port, UARTDATA, c);
|
||||
lpuart32_write(port, c, UARTDATA);
|
||||
}
|
||||
|
||||
static int lpuart32_poll_get_char(struct uart_port *port)
|
||||
{
|
||||
if (!(lpuart32_read(port, UARTSTAT) & UARTSTAT_RDRF))
|
||||
if (!(lpuart32_read(port, UARTWATER) >> UARTWATER_RXCNT_OFF))
|
||||
return NO_POLL_CHAR;
|
||||
|
||||
return lpuart32_read(port, UARTDATA);
|
||||
|
@ -978,6 +976,15 @@ static irqreturn_t lpuart_int(int irq, void *dev_id)
|
|||
|
||||
sts = readb(sport->port.membase + UARTSR1);
|
||||
|
||||
/* SysRq, using dma, check for linebreak by framing err. */
|
||||
if (sts & UARTSR1_FE && sport->lpuart_dma_rx_use) {
|
||||
readb(sport->port.membase + UARTDR);
|
||||
uart_handle_break(&sport->port);
|
||||
/* linebreak produces some garbage, removing it */
|
||||
writeb(UARTCFIFO_RXFLUSH, sport->port.membase + UARTCFIFO);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (sts & UARTSR1_RDRF && !sport->lpuart_dma_rx_use)
|
||||
lpuart_rxint(sport);
|
||||
|
||||
|
@ -1006,6 +1013,37 @@ static irqreturn_t lpuart32_int(int irq, void *dev_id)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
static inline void lpuart_handle_sysrq_chars(struct uart_port *port,
|
||||
unsigned char *p, int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*p && uart_handle_sysrq_char(port, *p))
|
||||
return;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
static void lpuart_handle_sysrq(struct lpuart_port *sport)
|
||||
{
|
||||
struct circ_buf *ring = &sport->rx_ring;
|
||||
int count;
|
||||
|
||||
if (ring->head < ring->tail) {
|
||||
count = sport->rx_sgl.length - ring->tail;
|
||||
lpuart_handle_sysrq_chars(&sport->port,
|
||||
ring->buf + ring->tail, count);
|
||||
ring->tail = 0;
|
||||
}
|
||||
|
||||
if (ring->head > ring->tail) {
|
||||
count = ring->head - ring->tail;
|
||||
lpuart_handle_sysrq_chars(&sport->port,
|
||||
ring->buf + ring->tail, count);
|
||||
ring->tail = ring->head;
|
||||
}
|
||||
}
|
||||
|
||||
static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
|
||||
{
|
||||
struct tty_port *port = &sport->port.state->port;
|
||||
|
@ -1092,6 +1130,15 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
|
|||
*/
|
||||
ring->head = sport->rx_sgl.length - state.residue;
|
||||
BUG_ON(ring->head > sport->rx_sgl.length);
|
||||
|
||||
/*
|
||||
* Silent handling of keys pressed in the sysrq timeframe
|
||||
*/
|
||||
if (sport->port.sysrq) {
|
||||
lpuart_handle_sysrq(sport);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point ring->head may point to the first byte right after the
|
||||
* last byte of the dma buffer:
|
||||
|
@ -1123,6 +1170,7 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
|
|||
sport->port.icount.rx += count;
|
||||
}
|
||||
|
||||
exit:
|
||||
dma_sync_sg_for_device(chan->device->dev, &sport->rx_sgl, 1,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
|
@ -1260,7 +1308,7 @@ static int lpuart_config_rs485(struct uart_port *port,
|
|||
modem |= UARTMODEM_TXRTSE;
|
||||
|
||||
/*
|
||||
* RTS needs to be logic HIGH either during transer _or_ after
|
||||
* RTS needs to be logic HIGH either during transfer _or_ after
|
||||
* transfer, other variants are not supported by the hardware.
|
||||
*/
|
||||
|
||||
|
@ -1311,7 +1359,7 @@ static int lpuart32_config_rs485(struct uart_port *port,
|
|||
modem |= UARTMODEM_TXRTSE;
|
||||
|
||||
/*
|
||||
* RTS needs to be logic HIGH either during transer _or_ after
|
||||
* RTS needs to be logic HIGH either during transfer _or_ after
|
||||
* transfer, other variants are not supported by the hardware.
|
||||
*/
|
||||
|
||||
|
@ -1559,6 +1607,7 @@ err:
|
|||
static void lpuart_rx_dma_startup(struct lpuart_port *sport)
|
||||
{
|
||||
int ret;
|
||||
unsigned char cr3;
|
||||
|
||||
if (!sport->dma_rx_chan)
|
||||
goto err;
|
||||
|
@ -1575,6 +1624,12 @@ static void lpuart_rx_dma_startup(struct lpuart_port *sport)
|
|||
sport->lpuart_dma_rx_use = true;
|
||||
rx_dma_timer_init(sport);
|
||||
|
||||
if (sport->port.has_sysrq) {
|
||||
cr3 = readb(sport->port.membase + UARTCR3);
|
||||
cr3 |= UARTCR3_FEIE;
|
||||
writeb(cr3, sport->port.membase + UARTCR3);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
|
|
|
@ -138,24 +138,24 @@ static void free_port_memory(struct icom_port *icom_port)
|
|||
|
||||
trace(icom_port, "RET_PORT_MEM", 0);
|
||||
if (icom_port->recv_buf) {
|
||||
pci_free_consistent(dev, 4096, icom_port->recv_buf,
|
||||
icom_port->recv_buf_pci);
|
||||
dma_free_coherent(&dev->dev, 4096, icom_port->recv_buf,
|
||||
icom_port->recv_buf_pci);
|
||||
icom_port->recv_buf = NULL;
|
||||
}
|
||||
if (icom_port->xmit_buf) {
|
||||
pci_free_consistent(dev, 4096, icom_port->xmit_buf,
|
||||
icom_port->xmit_buf_pci);
|
||||
dma_free_coherent(&dev->dev, 4096, icom_port->xmit_buf,
|
||||
icom_port->xmit_buf_pci);
|
||||
icom_port->xmit_buf = NULL;
|
||||
}
|
||||
if (icom_port->statStg) {
|
||||
pci_free_consistent(dev, 4096, icom_port->statStg,
|
||||
icom_port->statStg_pci);
|
||||
dma_free_coherent(&dev->dev, 4096, icom_port->statStg,
|
||||
icom_port->statStg_pci);
|
||||
icom_port->statStg = NULL;
|
||||
}
|
||||
|
||||
if (icom_port->xmitRestart) {
|
||||
pci_free_consistent(dev, 4096, icom_port->xmitRestart,
|
||||
icom_port->xmitRestart_pci);
|
||||
dma_free_coherent(&dev->dev, 4096, icom_port->xmitRestart,
|
||||
icom_port->xmitRestart_pci);
|
||||
icom_port->xmitRestart = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +169,8 @@ static int get_port_memory(struct icom_port *icom_port)
|
|||
struct pci_dev *dev = icom_port->adapter->pci_dev;
|
||||
|
||||
icom_port->xmit_buf =
|
||||
pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
|
||||
dma_alloc_coherent(&dev->dev, 4096, &icom_port->xmit_buf_pci,
|
||||
GFP_KERNEL);
|
||||
if (!icom_port->xmit_buf) {
|
||||
dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
|
||||
return -ENOMEM;
|
||||
|
@ -179,7 +180,8 @@ static int get_port_memory(struct icom_port *icom_port)
|
|||
(unsigned long) icom_port->xmit_buf);
|
||||
|
||||
icom_port->recv_buf =
|
||||
pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
|
||||
dma_alloc_coherent(&dev->dev, 4096, &icom_port->recv_buf_pci,
|
||||
GFP_KERNEL);
|
||||
if (!icom_port->recv_buf) {
|
||||
dev_err(&dev->dev, "Can not allocate Receive buffer\n");
|
||||
free_port_memory(icom_port);
|
||||
|
@ -189,7 +191,8 @@ static int get_port_memory(struct icom_port *icom_port)
|
|||
(unsigned long) icom_port->recv_buf);
|
||||
|
||||
icom_port->statStg =
|
||||
pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
|
||||
dma_alloc_coherent(&dev->dev, 4096, &icom_port->statStg_pci,
|
||||
GFP_KERNEL);
|
||||
if (!icom_port->statStg) {
|
||||
dev_err(&dev->dev, "Can not allocate Status buffer\n");
|
||||
free_port_memory(icom_port);
|
||||
|
@ -199,7 +202,8 @@ static int get_port_memory(struct icom_port *icom_port)
|
|||
(unsigned long) icom_port->statStg);
|
||||
|
||||
icom_port->xmitRestart =
|
||||
pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
|
||||
dma_alloc_coherent(&dev->dev, 4096, &icom_port->xmitRestart_pci,
|
||||
GFP_KERNEL);
|
||||
if (!icom_port->xmitRestart) {
|
||||
dev_err(&dev->dev,
|
||||
"Can not allocate xmit Restart buffer\n");
|
||||
|
@ -414,7 +418,7 @@ static void load_code(struct icom_port *icom_port)
|
|||
/*Set up data in icom DRAM to indicate where personality
|
||||
*code is located and its length.
|
||||
*/
|
||||
new_page = pci_alloc_consistent(dev, 4096, &temp_pci);
|
||||
new_page = dma_alloc_coherent(&dev->dev, 4096, &temp_pci, GFP_KERNEL);
|
||||
|
||||
if (!new_page) {
|
||||
dev_err(&dev->dev, "Can not allocate DMA buffer\n");
|
||||
|
@ -494,7 +498,7 @@ static void load_code(struct icom_port *icom_port)
|
|||
}
|
||||
|
||||
if (new_page != NULL)
|
||||
pci_free_consistent(dev, 4096, new_page, temp_pci);
|
||||
dma_free_coherent(&dev->dev, 4096, new_page, temp_pci);
|
||||
}
|
||||
|
||||
static int startup(struct icom_port *icom_port)
|
||||
|
|
|
@ -257,7 +257,7 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev)
|
|||
|
||||
/**
|
||||
* ifx_spi_timeout - SPI timeout
|
||||
* @arg: our SPI device
|
||||
* @t: timer in our SPI device
|
||||
*
|
||||
* The SPI has timed out: hang up the tty. Users will then see a hangup
|
||||
* and error events.
|
||||
|
@ -277,7 +277,6 @@ static void ifx_spi_timeout(struct timer_list *t)
|
|||
/**
|
||||
* ifx_spi_tiocmget - get modem lines
|
||||
* @tty: our tty device
|
||||
* @filp: file handle issuing the request
|
||||
*
|
||||
* Map the signal state into Linux modem flags and report the value
|
||||
* in Linux terms
|
||||
|
@ -531,7 +530,7 @@ static int ifx_spi_chars_in_buffer(struct tty_struct *tty)
|
|||
|
||||
/**
|
||||
* ifx_port_hangup
|
||||
* @port: our tty port
|
||||
* @tty: our tty
|
||||
*
|
||||
* tty port hang up. Called when tty_hangup processing is invoked either
|
||||
* by loss of carrier, or by software (eg vhangup). Serialized against
|
||||
|
@ -611,7 +610,7 @@ static const struct tty_operations ifx_spi_serial_ops = {
|
|||
|
||||
/**
|
||||
* ifx_spi_insert_fip_string - queue received data
|
||||
* @ifx_ser: our SPI device
|
||||
* @ifx_dev: our SPI device
|
||||
* @chars: buffer we have received
|
||||
* @size: number of chars reeived
|
||||
*
|
||||
|
@ -725,10 +724,11 @@ complete_exit:
|
|||
* Queue data for transmission if possible and then kick off the
|
||||
* transfer.
|
||||
*/
|
||||
static void ifx_spi_io(unsigned long data)
|
||||
static void ifx_spi_io(struct tasklet_struct *t)
|
||||
{
|
||||
int retval;
|
||||
struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data;
|
||||
struct ifx_spi_device *ifx_dev = from_tasklet(ifx_dev, t,
|
||||
io_work_tasklet);
|
||||
|
||||
if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags) &&
|
||||
test_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags)) {
|
||||
|
@ -1067,8 +1067,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi)
|
|||
init_waitqueue_head(&ifx_dev->mdm_reset_wait);
|
||||
|
||||
spi_set_drvdata(spi, ifx_dev);
|
||||
tasklet_init(&ifx_dev->io_work_tasklet, ifx_spi_io,
|
||||
(unsigned long)ifx_dev);
|
||||
tasklet_setup(&ifx_dev->io_work_tasklet, ifx_spi_io);
|
||||
|
||||
set_bit(IFX_SPI_STATE_PRESENT, &ifx_dev->flags);
|
||||
|
||||
|
|
|
@ -1552,10 +1552,6 @@ static void imx_uart_shutdown(struct uart_port *port)
|
|||
ucr2 = imx_uart_readl(sport, UCR2);
|
||||
ucr2 &= ~(UCR2_TXEN | UCR2_ATEN);
|
||||
imx_uart_writel(sport, ucr2, UCR2);
|
||||
|
||||
ucr4 = imx_uart_readl(sport, UCR4);
|
||||
ucr4 &= ~UCR4_OREN;
|
||||
imx_uart_writel(sport, ucr4, UCR4);
|
||||
spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
|
||||
/*
|
||||
|
@ -1568,10 +1564,15 @@ static void imx_uart_shutdown(struct uart_port *port)
|
|||
*/
|
||||
|
||||
spin_lock_irqsave(&sport->port.lock, flags);
|
||||
|
||||
ucr1 = imx_uart_readl(sport, UCR1);
|
||||
ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN | UCR1_RXDMAEN | UCR1_ATDMAEN);
|
||||
|
||||
imx_uart_writel(sport, ucr1, UCR1);
|
||||
|
||||
ucr4 = imx_uart_readl(sport, UCR4);
|
||||
ucr4 &= ~(UCR4_OREN | UCR4_TCEN);
|
||||
imx_uart_writel(sport, ucr4, UCR4);
|
||||
|
||||
spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
|
||||
clk_disable_unprepare(sport->clk_per);
|
||||
|
@ -2389,8 +2390,7 @@ static int imx_uart_probe(struct platform_device *pdev)
|
|||
|
||||
/* Disable interrupts before requesting them */
|
||||
ucr1 = imx_uart_readl(sport, UCR1);
|
||||
ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN |
|
||||
UCR1_TRDYEN | UCR1_RTSDEN);
|
||||
ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN | UCR1_RTSDEN);
|
||||
imx_uart_writel(sport, ucr1, UCR1);
|
||||
|
||||
if (!imx_uart_is_imx1(sport) && sport->dte_mode) {
|
||||
|
|
|
@ -1056,9 +1056,9 @@ static int max310x_startup(struct uart_port *port)
|
|||
max310x_port_update(port, MAX310X_MODE1_REG,
|
||||
MAX310X_MODE1_TRNSCVCTRL_BIT, 0);
|
||||
|
||||
/* Configure MODE2 register & Reset FIFOs*/
|
||||
val = MAX310X_MODE2_RXEMPTINV_BIT | MAX310X_MODE2_FIFORST_BIT;
|
||||
max310x_port_write(port, MAX310X_MODE2_REG, val);
|
||||
/* Reset FIFOs */
|
||||
max310x_port_write(port, MAX310X_MODE2_REG,
|
||||
MAX310X_MODE2_FIFORST_BIT);
|
||||
max310x_port_update(port, MAX310X_MODE2_REG,
|
||||
MAX310X_MODE2_FIFORST_BIT, 0);
|
||||
|
||||
|
@ -1086,8 +1086,27 @@ static int max310x_startup(struct uart_port *port)
|
|||
/* Clear IRQ status register */
|
||||
max310x_port_read(port, MAX310X_IRQSTS_REG);
|
||||
|
||||
/* Enable RX, TX, CTS change interrupts */
|
||||
val = MAX310X_IRQ_RXEMPTY_BIT | MAX310X_IRQ_TXEMPTY_BIT;
|
||||
/*
|
||||
* Let's ask for an interrupt after a timeout equivalent to
|
||||
* the receiving time of 4 characters after the last character
|
||||
* has been received.
|
||||
*/
|
||||
max310x_port_write(port, MAX310X_RXTO_REG, 4);
|
||||
|
||||
/*
|
||||
* Make sure we also get RX interrupts when the RX FIFO is
|
||||
* filling up quickly, so get an interrupt when half of the RX
|
||||
* FIFO has been filled in.
|
||||
*/
|
||||
max310x_port_write(port, MAX310X_FIFOTRIGLVL_REG,
|
||||
MAX310X_FIFOTRIGLVL_RX(MAX310X_FIFO_SIZE / 2));
|
||||
|
||||
/* Enable RX timeout interrupt in LSR */
|
||||
max310x_port_write(port, MAX310X_LSR_IRQEN_REG,
|
||||
MAX310X_LSR_RXTO_BIT);
|
||||
|
||||
/* Enable LSR, RX FIFO trigger, CTS change interrupts */
|
||||
val = MAX310X_IRQ_LSR_BIT | MAX310X_IRQ_RXFIFO_BIT | MAX310X_IRQ_TXEMPTY_BIT;
|
||||
max310x_port_write(port, MAX310X_IRQEN_REG, val | MAX310X_IRQ_CTS_BIT);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -632,6 +632,7 @@ static int mcf_probe(struct platform_device *pdev)
|
|||
port->ops = &mcf_uart_ops;
|
||||
port->flags = UPF_BOOT_AUTOCONF;
|
||||
port->rs485_config = mcf_config_rs485;
|
||||
port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MCF_CONSOLE);
|
||||
|
||||
uart_add_one_port(&mcf_driver, port);
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ static void men_z135_reg_clr(struct men_z135_port *uart,
|
|||
|
||||
/**
|
||||
* men_z135_handle_modem_status() - Handle change of modem status
|
||||
* @port: The UART port
|
||||
* @uart: The UART port
|
||||
*
|
||||
* Handle change of modem status register. This is done by reading the "delta"
|
||||
* versions of DCD (Data Carrier Detect) and CTS (Clear To Send).
|
||||
|
@ -236,7 +236,7 @@ static u16 get_rx_fifo_content(struct men_z135_port *uart)
|
|||
|
||||
/**
|
||||
* men_z135_handle_rx() - RX tasklet routine
|
||||
* @arg: Pointer to struct men_z135_port
|
||||
* @uart: Pointer to struct men_z135_port
|
||||
*
|
||||
* Copy from RX FIFO and acknowledge number of bytes copied.
|
||||
*/
|
||||
|
@ -287,7 +287,7 @@ static void men_z135_handle_rx(struct men_z135_port *uart)
|
|||
|
||||
/**
|
||||
* men_z135_handle_tx() - TX tasklet routine
|
||||
* @arg: Pointer to struct men_z135_port
|
||||
* @uart: Pointer to struct men_z135_port
|
||||
*
|
||||
*/
|
||||
static void men_z135_handle_tx(struct men_z135_port *uart)
|
||||
|
@ -596,7 +596,7 @@ static void men_z135_stop_rx(struct uart_port *port)
|
|||
|
||||
/**
|
||||
* men_z135_enable_ms() - Enable Modem Status
|
||||
* port:
|
||||
* @port: the port
|
||||
*
|
||||
* Enable Modem Status IRQ.
|
||||
*/
|
||||
|
|
|
@ -803,7 +803,7 @@ static int mvebu_uart_probe(struct platform_device *pdev)
|
|||
&pdev->dev);
|
||||
struct uart_port *port;
|
||||
struct mvebu_uart *mvuart;
|
||||
int ret, id, irq;
|
||||
int id, irq;
|
||||
|
||||
if (!reg) {
|
||||
dev_err(&pdev->dev, "no registers defined\n");
|
||||
|
@ -912,10 +912,7 @@ static int mvebu_uart_probe(struct platform_device *pdev)
|
|||
udelay(1);
|
||||
writel(0, port->membase + UART_CTRL(port));
|
||||
|
||||
ret = uart_add_one_port(&mvebu_uart_driver, port);
|
||||
if (ret)
|
||||
return ret;
|
||||
return 0;
|
||||
return uart_add_one_port(&mvebu_uart_driver, port);
|
||||
}
|
||||
|
||||
static struct mvebu_uart_driver_data uart_std_driver_data = {
|
||||
|
|
|
@ -981,7 +981,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv)
|
|||
|
||||
priv->tx_dma_use = 1;
|
||||
|
||||
priv->sg_tx_p = kcalloc(num, sizeof(struct scatterlist), GFP_ATOMIC);
|
||||
priv->sg_tx_p = kmalloc_array(num, sizeof(struct scatterlist), GFP_ATOMIC);
|
||||
if (!priv->sg_tx_p) {
|
||||
dev_err(priv->port.dev, "%s:kzalloc Failed\n", __func__);
|
||||
return 0;
|
||||
|
|
|
@ -1644,7 +1644,7 @@ static int __init pmz_probe(void)
|
|||
* TODO: Add routines with proper locking to do that...
|
||||
*/
|
||||
node_a = node_b = NULL;
|
||||
for (np = NULL; (np = of_get_next_child(node_p, np)) != NULL;) {
|
||||
for_each_child_of_node(node_p, np) {
|
||||
if (of_node_name_prefix(np, "ch-a"))
|
||||
node_a = of_node_get(np);
|
||||
else if (of_node_name_prefix(np, "ch-b"))
|
||||
|
|
|
@ -242,7 +242,7 @@ static void qcom_geni_serial_set_mctrl(struct uart_port *uport,
|
|||
if (mctrl & TIOCM_LOOP)
|
||||
port->loopback = RX_TX_CTS_RTS_SORTED;
|
||||
|
||||
if (!(mctrl & TIOCM_RTS))
|
||||
if (!(mctrl & TIOCM_RTS) && !uport->suspended)
|
||||
uart_manual_rfr = UART_MANUAL_RFR_EN | UART_RFR_NOT_READY;
|
||||
writel(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR);
|
||||
}
|
||||
|
@ -1000,7 +1000,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
|
|||
sampling_rate = UART_OVERSAMPLING;
|
||||
/* Sampling rate is halved for IP versions >= 2.5 */
|
||||
ver = geni_se_get_qup_hw_version(&port->se);
|
||||
if (GENI_SE_VERSION_MAJOR(ver) >= 2 && GENI_SE_VERSION_MINOR(ver) >= 5)
|
||||
if (ver >= QUP_SE_VERSION_2_5)
|
||||
sampling_rate /= 2;
|
||||
|
||||
clk_rate = get_clk_div_rate(baud, sampling_rate, &clk_div);
|
||||
|
@ -1107,7 +1107,7 @@ static int qcom_geni_console_setup(struct console *co, char *options)
|
|||
{
|
||||
struct uart_port *uport;
|
||||
struct qcom_geni_serial_port *port;
|
||||
int baud = 9600;
|
||||
int baud = 115200;
|
||||
int bits = 8;
|
||||
int parity = 'n';
|
||||
int flow = 'n';
|
||||
|
@ -1438,11 +1438,9 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
|
|||
return PTR_ERR(port->se.opp_table);
|
||||
/* OPP table is optional */
|
||||
ret = dev_pm_opp_of_add_table(&pdev->dev);
|
||||
if (!ret) {
|
||||
port->se.has_opp_table = true;
|
||||
} else if (ret != -ENODEV) {
|
||||
if (ret && ret != -ENODEV) {
|
||||
dev_err(&pdev->dev, "invalid OPP table in device tree\n");
|
||||
return ret;
|
||||
goto put_clkname;
|
||||
}
|
||||
|
||||
port->private_data.drv = drv;
|
||||
|
@ -1483,8 +1481,8 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
|
|||
|
||||
return 0;
|
||||
err:
|
||||
if (port->se.has_opp_table)
|
||||
dev_pm_opp_of_remove_table(&pdev->dev);
|
||||
dev_pm_opp_of_remove_table(&pdev->dev);
|
||||
put_clkname:
|
||||
dev_pm_opp_put_clkname(port->se.opp_table);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1494,8 +1492,7 @@ static int qcom_geni_serial_remove(struct platform_device *pdev)
|
|||
struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
|
||||
struct uart_driver *drv = port->private_data.drv;
|
||||
|
||||
if (port->se.has_opp_table)
|
||||
dev_pm_opp_of_remove_table(&pdev->dev);
|
||||
dev_pm_opp_of_remove_table(&pdev->dev);
|
||||
dev_pm_opp_put_clkname(port->se.opp_table);
|
||||
dev_pm_clear_wake_irq(&pdev->dev);
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
|
|
|
@ -879,22 +879,20 @@ static int sa1100_serial_add_one_port(struct sa1100_port *sport, struct platform
|
|||
|
||||
static int sa1100_serial_probe(struct platform_device *dev)
|
||||
{
|
||||
struct resource *res = dev->resource;
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dev->num_resources; i++, res++)
|
||||
if (res->flags & IORESOURCE_MEM)
|
||||
break;
|
||||
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
if (i < dev->num_resources) {
|
||||
for (i = 0; i < NR_PORTS; i++) {
|
||||
if (sa1100_ports[i].port.mapbase != res->start)
|
||||
continue;
|
||||
|
||||
sa1100_serial_add_one_port(&sa1100_ports[i], dev);
|
||||
for (i = 0; i < NR_PORTS; i++)
|
||||
if (sa1100_ports[i].port.mapbase == res->start)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == NR_PORTS)
|
||||
return -ENODEV;
|
||||
|
||||
sa1100_serial_add_one_port(&sa1100_ports[i], dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1271,6 +1271,7 @@ static int sc16is7xx_probe(struct device *dev,
|
|||
s->p[i].port.type = PORT_SC16IS7XX;
|
||||
s->p[i].port.fifosize = SC16IS7XX_FIFO_SIZE;
|
||||
s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY;
|
||||
s->p[i].port.iobase = i;
|
||||
s->p[i].port.iotype = UPIO_PORT;
|
||||
s->p[i].port.uartclk = freq;
|
||||
s->p[i].port.rs485_config = sc16is7xx_config_rs485;
|
||||
|
|
|
@ -2626,7 +2626,7 @@ static ssize_t uartclk_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.baud_base * 16);
|
||||
return sprintf(buf, "%d\n", tmp.baud_base * 16);
|
||||
}
|
||||
|
||||
static ssize_t type_show(struct device *dev,
|
||||
|
@ -2636,7 +2636,7 @@ static ssize_t type_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.type);
|
||||
return sprintf(buf, "%d\n", tmp.type);
|
||||
}
|
||||
|
||||
static ssize_t line_show(struct device *dev,
|
||||
|
@ -2646,7 +2646,7 @@ static ssize_t line_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.line);
|
||||
return sprintf(buf, "%d\n", tmp.line);
|
||||
}
|
||||
|
||||
static ssize_t port_show(struct device *dev,
|
||||
|
@ -2660,7 +2660,7 @@ static ssize_t port_show(struct device *dev,
|
|||
ioaddr = tmp.port;
|
||||
if (HIGH_BITS_OFFSET)
|
||||
ioaddr |= (unsigned long)tmp.port_high << HIGH_BITS_OFFSET;
|
||||
return snprintf(buf, PAGE_SIZE, "0x%lX\n", ioaddr);
|
||||
return sprintf(buf, "0x%lX\n", ioaddr);
|
||||
}
|
||||
|
||||
static ssize_t irq_show(struct device *dev,
|
||||
|
@ -2670,7 +2670,7 @@ static ssize_t irq_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.irq);
|
||||
return sprintf(buf, "%d\n", tmp.irq);
|
||||
}
|
||||
|
||||
static ssize_t flags_show(struct device *dev,
|
||||
|
@ -2680,7 +2680,7 @@ static ssize_t flags_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "0x%X\n", tmp.flags);
|
||||
return sprintf(buf, "0x%X\n", tmp.flags);
|
||||
}
|
||||
|
||||
static ssize_t xmit_fifo_size_show(struct device *dev,
|
||||
|
@ -2690,7 +2690,7 @@ static ssize_t xmit_fifo_size_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.xmit_fifo_size);
|
||||
return sprintf(buf, "%d\n", tmp.xmit_fifo_size);
|
||||
}
|
||||
|
||||
static ssize_t close_delay_show(struct device *dev,
|
||||
|
@ -2700,7 +2700,7 @@ static ssize_t close_delay_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.close_delay);
|
||||
return sprintf(buf, "%d\n", tmp.close_delay);
|
||||
}
|
||||
|
||||
static ssize_t closing_wait_show(struct device *dev,
|
||||
|
@ -2710,7 +2710,7 @@ static ssize_t closing_wait_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.closing_wait);
|
||||
return sprintf(buf, "%d\n", tmp.closing_wait);
|
||||
}
|
||||
|
||||
static ssize_t custom_divisor_show(struct device *dev,
|
||||
|
@ -2720,7 +2720,7 @@ static ssize_t custom_divisor_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.custom_divisor);
|
||||
return sprintf(buf, "%d\n", tmp.custom_divisor);
|
||||
}
|
||||
|
||||
static ssize_t io_type_show(struct device *dev,
|
||||
|
@ -2730,7 +2730,7 @@ static ssize_t io_type_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.io_type);
|
||||
return sprintf(buf, "%d\n", tmp.io_type);
|
||||
}
|
||||
|
||||
static ssize_t iomem_base_show(struct device *dev,
|
||||
|
@ -2740,7 +2740,7 @@ static ssize_t iomem_base_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)tmp.iomem_base);
|
||||
return sprintf(buf, "0x%lX\n", (unsigned long)tmp.iomem_base);
|
||||
}
|
||||
|
||||
static ssize_t iomem_reg_shift_show(struct device *dev,
|
||||
|
@ -2750,7 +2750,7 @@ static ssize_t iomem_reg_shift_show(struct device *dev,
|
|||
struct tty_port *port = dev_get_drvdata(dev);
|
||||
|
||||
uart_get_info(port, &tmp);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift);
|
||||
return sprintf(buf, "%d\n", tmp.iomem_reg_shift);
|
||||
}
|
||||
|
||||
static ssize_t console_show(struct device *dev,
|
||||
|
@ -3260,9 +3260,7 @@ int uart_get_rs485_mode(struct uart_port *port)
|
|||
if (IS_ERR(port->rs485_term_gpio)) {
|
||||
ret = PTR_ERR(port->rs485_term_gpio);
|
||||
port->rs485_term_gpio = NULL;
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "Cannot get rs485-term-gpios\n");
|
||||
return ret;
|
||||
return dev_err_probe(dev, ret, "Cannot get rs485-term-gpios\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -129,13 +129,9 @@ static int stm32_config_rs485(struct uart_port *port,
|
|||
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
|
||||
cr3 &= ~USART_CR3_DEP;
|
||||
rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl & ~TIOCM_RTS);
|
||||
} else {
|
||||
cr3 |= USART_CR3_DEP;
|
||||
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl | TIOCM_RTS);
|
||||
}
|
||||
|
||||
writel_relaxed(cr3, port->membase + ofs->cr3);
|
||||
|
@ -541,17 +537,42 @@ static void stm32_disable_ms(struct uart_port *port)
|
|||
/* Transmit stop */
|
||||
static void stm32_stop_tx(struct uart_port *port)
|
||||
{
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
struct serial_rs485 *rs485conf = &port->rs485;
|
||||
|
||||
stm32_tx_interrupt_disable(port);
|
||||
|
||||
if (rs485conf->flags & SER_RS485_ENABLED) {
|
||||
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl & ~TIOCM_RTS);
|
||||
} else {
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl | TIOCM_RTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* There are probably characters waiting to be transmitted. */
|
||||
static void stm32_start_tx(struct uart_port *port)
|
||||
{
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
struct serial_rs485 *rs485conf = &port->rs485;
|
||||
struct circ_buf *xmit = &port->state->xmit;
|
||||
|
||||
if (uart_circ_empty(xmit))
|
||||
return;
|
||||
|
||||
if (rs485conf->flags & SER_RS485_ENABLED) {
|
||||
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl | TIOCM_RTS);
|
||||
} else {
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl & ~TIOCM_RTS);
|
||||
}
|
||||
}
|
||||
|
||||
stm32_transmit_chars(port);
|
||||
}
|
||||
|
||||
|
@ -851,13 +872,9 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
|
||||
cr3 &= ~USART_CR3_DEP;
|
||||
rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl & ~TIOCM_RTS);
|
||||
} else {
|
||||
cr3 |= USART_CR3_DEP;
|
||||
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl | TIOCM_RTS);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -172,9 +172,9 @@ static void timbuart_handle_rx_port(struct uart_port *port, u32 isr, u32 *ier)
|
|||
dev_dbg(port->dev, "%s - leaving\n", __func__);
|
||||
}
|
||||
|
||||
static void timbuart_tasklet(unsigned long arg)
|
||||
static void timbuart_tasklet(struct tasklet_struct *t)
|
||||
{
|
||||
struct timbuart_port *uart = (struct timbuart_port *)arg;
|
||||
struct timbuart_port *uart = from_tasklet(uart, t, tasklet);
|
||||
u32 isr, ier = 0;
|
||||
|
||||
spin_lock(&uart->port.lock);
|
||||
|
@ -451,7 +451,7 @@ static int timbuart_probe(struct platform_device *dev)
|
|||
}
|
||||
uart->port.irq = irq;
|
||||
|
||||
tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart);
|
||||
tasklet_setup(&uart->tasklet, timbuart_tasklet);
|
||||
|
||||
err = uart_register_driver(&timbuart_driver);
|
||||
if (err)
|
||||
|
|
|
@ -283,7 +283,7 @@ static unsigned int qe_uart_tx_empty(struct uart_port *port)
|
|||
* don't need that support. This function must exist, however, otherwise
|
||||
* the kernel will panic.
|
||||
*/
|
||||
void qe_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||
static void qe_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -942,7 +942,7 @@ static inline int mgsl_paranoia_check(struct mgsl_struct *info,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* line discipline callback wrappers
|
||||
*
|
||||
* The wrappers maintain line discipline references
|
||||
|
@ -7419,14 +7419,14 @@ static int usc_loopmode_active( struct mgsl_struct * info)
|
|||
#if SYNCLINK_GENERIC_HDLC
|
||||
|
||||
/**
|
||||
* called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
|
||||
* set encoding and frame check sequence (FCS) options
|
||||
* hdlcdev_attach - called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
|
||||
* @dev: pointer to network device structure
|
||||
* @encoding: serial encoding setting
|
||||
* @parity: FCS setting
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* encoding serial encoding setting
|
||||
* parity FCS setting
|
||||
* Set encoding and frame check sequence (FCS) options.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
|
||||
unsigned short parity)
|
||||
|
@ -7468,10 +7468,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
|
|||
}
|
||||
|
||||
/**
|
||||
* called by generic HDLC layer to send frame
|
||||
*
|
||||
* skb socket buffer containing HDLC frame
|
||||
* dev pointer to network device structure
|
||||
* hdlcdev_xmit - called by generic HDLC layer to send a frame
|
||||
* @skb: socket buffer containing HDLC frame
|
||||
* @dev: pointer to network device structure
|
||||
*/
|
||||
static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
|
@ -7509,12 +7508,12 @@ static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer when interface enabled
|
||||
* claim resources and initialize hardware
|
||||
* hdlcdev_open - called by network layer when interface enabled
|
||||
* @dev: pointer to network device structure
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* Claim resources and initialize hardware.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_open(struct net_device *dev)
|
||||
{
|
||||
|
@ -7568,12 +7567,12 @@ static int hdlcdev_open(struct net_device *dev)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer when interface is disabled
|
||||
* shutdown hardware and release resources
|
||||
* hdlcdev_close - called by network layer when interface is disabled
|
||||
* @dev: pointer to network device structure
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* Shutdown hardware and release resources.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_close(struct net_device *dev)
|
||||
{
|
||||
|
@ -7598,13 +7597,12 @@ static int hdlcdev_close(struct net_device *dev)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer to process IOCTL call to network device
|
||||
* hdlcdev_ioctl - called by network layer to process IOCTL call to network device
|
||||
* @dev: pointer to network device structure
|
||||
* @ifr: pointer to network interface request structure
|
||||
* @cmd: IOCTL command code
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* ifr pointer to network interface request structure
|
||||
* cmd IOCTL command code
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
|
@ -7702,9 +7700,9 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer when transmit timeout is detected
|
||||
* hdlcdev_tx_timeout - called by network layer when transmit timeout is detected
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* @dev: pointer to network device structure
|
||||
*/
|
||||
static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
||||
{
|
||||
|
@ -7725,10 +7723,10 @@ static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by device driver when transmit completes
|
||||
* reenable network layer transmit if stopped
|
||||
* hdlcdev_tx_done - called by device driver when transmit completes
|
||||
* @info: pointer to device instance information
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* Reenable network layer transmit if stopped.
|
||||
*/
|
||||
static void hdlcdev_tx_done(struct mgsl_struct *info)
|
||||
{
|
||||
|
@ -7737,12 +7735,12 @@ static void hdlcdev_tx_done(struct mgsl_struct *info)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by device driver when frame received
|
||||
* pass frame to network layer
|
||||
* hdlcdev_rx - called by device driver when frame received
|
||||
* @info: pointer to device instance information
|
||||
* @buf: pointer to buffer contianing frame data
|
||||
* @size: count of data bytes in buf
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* buf pointer to buffer contianing frame data
|
||||
* size count of data bytes in buf
|
||||
* Pass frame to network layer.
|
||||
*/
|
||||
static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size)
|
||||
{
|
||||
|
@ -7778,12 +7776,12 @@ static const struct net_device_ops hdlcdev_ops = {
|
|||
};
|
||||
|
||||
/**
|
||||
* called by device driver when adding device instance
|
||||
* do generic HDLC initialization
|
||||
* hdlcdev_init - called by device driver when adding device instance
|
||||
* @info: pointer to device instance information
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* Do generic HDLC initialization.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_init(struct mgsl_struct *info)
|
||||
{
|
||||
|
@ -7827,10 +7825,10 @@ static int hdlcdev_init(struct mgsl_struct *info)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by device driver when removing device instance
|
||||
* do generic HDLC cleanup
|
||||
* hdlcdev_exit - called by device driver when removing device instance
|
||||
* @info: pointer to device instance information
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* Do generic HDLC cleanup.
|
||||
*/
|
||||
static void hdlcdev_exit(struct mgsl_struct *info)
|
||||
{
|
||||
|
|
|
@ -1395,14 +1395,14 @@ static int set_break(struct tty_struct *tty, int break_state)
|
|||
#if SYNCLINK_GENERIC_HDLC
|
||||
|
||||
/**
|
||||
* called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
|
||||
* set encoding and frame check sequence (FCS) options
|
||||
* hdlcdev_attach - called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
|
||||
* @dev: pointer to network device structure
|
||||
* @encoding: serial encoding setting
|
||||
* @parity: FCS setting
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* encoding serial encoding setting
|
||||
* parity FCS setting
|
||||
* Set encoding and frame check sequence (FCS) options.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
|
||||
unsigned short parity)
|
||||
|
@ -1446,10 +1446,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
|
|||
}
|
||||
|
||||
/**
|
||||
* called by generic HDLC layer to send frame
|
||||
*
|
||||
* skb socket buffer containing HDLC frame
|
||||
* dev pointer to network device structure
|
||||
* hdlcdev_xmit - called by generic HDLC layer to send a frame
|
||||
* @skb: socket buffer containing HDLC frame
|
||||
* @dev: pointer to network device structure
|
||||
*/
|
||||
static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
|
@ -1483,12 +1482,12 @@ static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer when interface enabled
|
||||
* claim resources and initialize hardware
|
||||
* hdlcdev_open - called by network layer when interface enabled
|
||||
* @dev: pointer to network device structure
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* Claim resources and initialize hardware.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_open(struct net_device *dev)
|
||||
{
|
||||
|
@ -1544,12 +1543,12 @@ static int hdlcdev_open(struct net_device *dev)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer when interface is disabled
|
||||
* shutdown hardware and release resources
|
||||
* hdlcdev_close - called by network layer when interface is disabled
|
||||
* @dev: pointer to network device structure
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* Shutdown hardware and release resources.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_close(struct net_device *dev)
|
||||
{
|
||||
|
@ -1574,13 +1573,12 @@ static int hdlcdev_close(struct net_device *dev)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer to process IOCTL call to network device
|
||||
* hdlcdev_ioctl - called by network layer to process IOCTL call to network device
|
||||
* @dev: pointer to network device structure
|
||||
* @ifr: pointer to network interface request structure
|
||||
* @cmd: IOCTL command code
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* ifr pointer to network interface request structure
|
||||
* cmd IOCTL command code
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
|
@ -1678,9 +1676,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer when transmit timeout is detected
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* hdlcdev_tx_timeout - called by network layer when transmit timeout is detected
|
||||
* @dev: pointer to network device structure
|
||||
*/
|
||||
static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
||||
{
|
||||
|
@ -1700,10 +1697,10 @@ static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by device driver when transmit completes
|
||||
* reenable network layer transmit if stopped
|
||||
* hdlcdev_tx_done - called by device driver when transmit completes
|
||||
* @info: pointer to device instance information
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* Reenable network layer transmit if stopped.
|
||||
*/
|
||||
static void hdlcdev_tx_done(struct slgt_info *info)
|
||||
{
|
||||
|
@ -1712,12 +1709,12 @@ static void hdlcdev_tx_done(struct slgt_info *info)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by device driver when frame received
|
||||
* pass frame to network layer
|
||||
* hdlcdev_rx - called by device driver when frame received
|
||||
* @info: pointer to device instance information
|
||||
* @buf: pointer to buffer contianing frame data
|
||||
* @size: count of data bytes in buf
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* buf pointer to buffer contianing frame data
|
||||
* size count of data bytes in buf
|
||||
* Pass frame to network layer.
|
||||
*/
|
||||
static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
|
||||
{
|
||||
|
@ -1751,12 +1748,12 @@ static const struct net_device_ops hdlcdev_ops = {
|
|||
};
|
||||
|
||||
/**
|
||||
* called by device driver when adding device instance
|
||||
* do generic HDLC initialization
|
||||
* hdlcdev_init - called by device driver when adding device instance
|
||||
* @info: pointer to device instance information
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* Do generic HDLC initialization.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_init(struct slgt_info *info)
|
||||
{
|
||||
|
@ -1800,10 +1797,10 @@ static int hdlcdev_init(struct slgt_info *info)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by device driver when removing device instance
|
||||
* do generic HDLC cleanup
|
||||
* hdlcdev_exit - called by device driver when removing device instance
|
||||
* @info: pointer to device instance information
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* Do generic HDLC cleanup.
|
||||
*/
|
||||
static void hdlcdev_exit(struct slgt_info *info)
|
||||
{
|
||||
|
@ -3341,8 +3338,8 @@ static int alloc_desc(struct slgt_info *info)
|
|||
unsigned int pbufs;
|
||||
|
||||
/* allocate memory to hold descriptor lists */
|
||||
info->bufs = pci_zalloc_consistent(info->pdev, DESC_LIST_SIZE,
|
||||
&info->bufs_dma_addr);
|
||||
info->bufs = dma_alloc_coherent(&info->pdev->dev, DESC_LIST_SIZE,
|
||||
&info->bufs_dma_addr, GFP_KERNEL);
|
||||
if (info->bufs == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -3384,7 +3381,8 @@ static int alloc_desc(struct slgt_info *info)
|
|||
static void free_desc(struct slgt_info *info)
|
||||
{
|
||||
if (info->bufs != NULL) {
|
||||
pci_free_consistent(info->pdev, DESC_LIST_SIZE, info->bufs, info->bufs_dma_addr);
|
||||
dma_free_coherent(&info->pdev->dev, DESC_LIST_SIZE,
|
||||
info->bufs, info->bufs_dma_addr);
|
||||
info->bufs = NULL;
|
||||
info->rbufs = NULL;
|
||||
info->tbufs = NULL;
|
||||
|
@ -3395,7 +3393,9 @@ static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count)
|
|||
{
|
||||
int i;
|
||||
for (i=0; i < count; i++) {
|
||||
if ((bufs[i].buf = pci_alloc_consistent(info->pdev, DMABUFSIZE, &bufs[i].buf_dma_addr)) == NULL)
|
||||
bufs[i].buf = dma_alloc_coherent(&info->pdev->dev, DMABUFSIZE,
|
||||
&bufs[i].buf_dma_addr, GFP_KERNEL);
|
||||
if (!bufs[i].buf)
|
||||
return -ENOMEM;
|
||||
bufs[i].pbuf = cpu_to_le32((unsigned int)bufs[i].buf_dma_addr);
|
||||
}
|
||||
|
@ -3408,7 +3408,8 @@ static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count)
|
|||
for (i=0; i < count; i++) {
|
||||
if (bufs[i].buf == NULL)
|
||||
continue;
|
||||
pci_free_consistent(info->pdev, DMABUFSIZE, bufs[i].buf, bufs[i].buf_dma_addr);
|
||||
dma_free_coherent(&info->pdev->dev, DMABUFSIZE, bufs[i].buf,
|
||||
bufs[i].buf_dma_addr);
|
||||
bufs[i].buf = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -685,7 +685,7 @@ static inline int sanity_check(SLMP_INFO *info,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* line discipline callback wrappers
|
||||
*
|
||||
* The wrappers maintain line discipline references
|
||||
|
@ -1520,14 +1520,14 @@ static int set_break(struct tty_struct *tty, int break_state)
|
|||
#if SYNCLINK_GENERIC_HDLC
|
||||
|
||||
/**
|
||||
* called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
|
||||
* set encoding and frame check sequence (FCS) options
|
||||
* hdlcdev_attach - called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
|
||||
* @dev: pointer to network device structure
|
||||
* @encoding: serial encoding setting
|
||||
* @parity: FCS setting
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* encoding serial encoding setting
|
||||
* parity FCS setting
|
||||
* Set encoding and frame check sequence (FCS) options.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
|
||||
unsigned short parity)
|
||||
|
@ -1569,10 +1569,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
|
|||
}
|
||||
|
||||
/**
|
||||
* called by generic HDLC layer to send frame
|
||||
*
|
||||
* skb socket buffer containing HDLC frame
|
||||
* dev pointer to network device structure
|
||||
* hdlcdev_xmit - called by generic HDLC layer to send frame
|
||||
* @skb: socket buffer containing HDLC frame
|
||||
* @dev: pointer to network device structure
|
||||
*/
|
||||
static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
|
@ -1610,12 +1609,12 @@ static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer when interface enabled
|
||||
* claim resources and initialize hardware
|
||||
* hdlcdev_open - called by network layer when interface enabled
|
||||
* @dev: pointer to network device structure
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* Claim resources and initialize hardware.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_open(struct net_device *dev)
|
||||
{
|
||||
|
@ -1669,12 +1668,12 @@ static int hdlcdev_open(struct net_device *dev)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer when interface is disabled
|
||||
* shutdown hardware and release resources
|
||||
* hdlcdev_close - called by network layer when interface is disabled
|
||||
* @dev: pointer to network device structure
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* Shutdown hardware and release resources.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_close(struct net_device *dev)
|
||||
{
|
||||
|
@ -1699,13 +1698,12 @@ static int hdlcdev_close(struct net_device *dev)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer to process IOCTL call to network device
|
||||
* hdlcdev_ioctl - called by network layer to process IOCTL call to network device
|
||||
* @dev: pointer to network device structure
|
||||
* @ifr: pointer to network interface request structure
|
||||
* @cmd: IOCTL command code
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* ifr pointer to network interface request structure
|
||||
* cmd IOCTL command code
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
|
@ -1803,9 +1801,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by network layer when transmit timeout is detected
|
||||
*
|
||||
* dev pointer to network device structure
|
||||
* hdlcdev_tx_timeout - called by network layer when transmit timeout is detected
|
||||
* @dev: pointer to network device structure
|
||||
*/
|
||||
static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
||||
{
|
||||
|
@ -1826,10 +1823,10 @@ static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by device driver when transmit completes
|
||||
* reenable network layer transmit if stopped
|
||||
* hdlcdev_tx_done - called by device driver when transmit completes
|
||||
* @info: pointer to device instance information
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* Reenable network layer transmit if stopped.
|
||||
*/
|
||||
static void hdlcdev_tx_done(SLMP_INFO *info)
|
||||
{
|
||||
|
@ -1838,12 +1835,12 @@ static void hdlcdev_tx_done(SLMP_INFO *info)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by device driver when frame received
|
||||
* pass frame to network layer
|
||||
* hdlcdev_rx - called by device driver when frame received
|
||||
* @info: pointer to device instance information
|
||||
* @buf: pointer to buffer contianing frame data
|
||||
* @size: count of data bytes in buf
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* buf pointer to buffer contianing frame data
|
||||
* size count of data bytes in buf
|
||||
* Pass frame to network layer.
|
||||
*/
|
||||
static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
|
||||
{
|
||||
|
@ -1879,12 +1876,12 @@ static const struct net_device_ops hdlcdev_ops = {
|
|||
};
|
||||
|
||||
/**
|
||||
* called by device driver when adding device instance
|
||||
* do generic HDLC initialization
|
||||
* hdlcdev_init - called by device driver when adding device instance
|
||||
* @info: pointer to device instance information
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* Do generic HDLC initialization.
|
||||
*
|
||||
* returns 0 if success, otherwise error code
|
||||
* Return: 0 if success, otherwise error code
|
||||
*/
|
||||
static int hdlcdev_init(SLMP_INFO *info)
|
||||
{
|
||||
|
@ -1928,10 +1925,10 @@ static int hdlcdev_init(SLMP_INFO *info)
|
|||
}
|
||||
|
||||
/**
|
||||
* called by device driver when removing device instance
|
||||
* do generic HDLC cleanup
|
||||
* hdlcdev_exit - called by device driver when removing device instance
|
||||
* @info: pointer to device instance information
|
||||
*
|
||||
* info pointer to device instance information
|
||||
* Do generic HDLC cleanup.
|
||||
*/
|
||||
static void hdlcdev_exit(SLMP_INFO *info)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/sched/rt.h>
|
||||
#include <linux/sched/debug.h>
|
||||
#include <linux/sched/task.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/fs.h>
|
||||
|
@ -440,7 +441,7 @@ static const struct sysrq_key_op sysrq_unrt_op = {
|
|||
/* Key Operations table and lock */
|
||||
static DEFINE_SPINLOCK(sysrq_key_table_lock);
|
||||
|
||||
static const struct sysrq_key_op *sysrq_key_table[36] = {
|
||||
static const struct sysrq_key_op *sysrq_key_table[62] = {
|
||||
&sysrq_loglevel_op, /* 0 */
|
||||
&sysrq_loglevel_op, /* 1 */
|
||||
&sysrq_loglevel_op, /* 2 */
|
||||
|
@ -497,6 +498,32 @@ static const struct sysrq_key_op *sysrq_key_table[36] = {
|
|||
/* y: May be registered on sparc64 for global register dump */
|
||||
NULL, /* y */
|
||||
&sysrq_ftrace_dump_op, /* z */
|
||||
NULL, /* A */
|
||||
NULL, /* B */
|
||||
NULL, /* C */
|
||||
NULL, /* D */
|
||||
NULL, /* E */
|
||||
NULL, /* F */
|
||||
NULL, /* G */
|
||||
NULL, /* H */
|
||||
NULL, /* I */
|
||||
NULL, /* J */
|
||||
NULL, /* K */
|
||||
NULL, /* L */
|
||||
NULL, /* M */
|
||||
NULL, /* N */
|
||||
NULL, /* O */
|
||||
NULL, /* P */
|
||||
NULL, /* Q */
|
||||
NULL, /* R */
|
||||
NULL, /* S */
|
||||
NULL, /* T */
|
||||
NULL, /* U */
|
||||
NULL, /* V */
|
||||
NULL, /* W */
|
||||
NULL, /* X */
|
||||
NULL, /* Y */
|
||||
NULL, /* Z */
|
||||
};
|
||||
|
||||
/* key2index calculation, -1 on invalid index */
|
||||
|
@ -508,6 +535,8 @@ static int sysrq_key_table_key2index(int key)
|
|||
retval = key - '0';
|
||||
else if ((key >= 'a') && (key <= 'z'))
|
||||
retval = key + 10 - 'a';
|
||||
else if ((key >= 'A') && (key <= 'Z'))
|
||||
retval = key + 36 - 'A';
|
||||
else
|
||||
retval = -1;
|
||||
return retval;
|
||||
|
@ -621,6 +650,8 @@ struct sysrq_state {
|
|||
unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];
|
||||
unsigned int alt;
|
||||
unsigned int alt_use;
|
||||
unsigned int shift;
|
||||
unsigned int shift_use;
|
||||
bool active;
|
||||
bool need_reinject;
|
||||
bool reinjecting;
|
||||
|
@ -805,10 +836,20 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq,
|
|||
}
|
||||
break;
|
||||
|
||||
case KEY_LEFTSHIFT:
|
||||
case KEY_RIGHTSHIFT:
|
||||
if (!value)
|
||||
sysrq->shift = KEY_RESERVED;
|
||||
else if (value != 2)
|
||||
sysrq->shift = code;
|
||||
break;
|
||||
|
||||
case KEY_SYSRQ:
|
||||
if (value == 1 && sysrq->alt != KEY_RESERVED) {
|
||||
sysrq->active = true;
|
||||
sysrq->alt_use = sysrq->alt;
|
||||
/* either RESERVED (for released) or actual code */
|
||||
sysrq->shift_use = sysrq->shift;
|
||||
/*
|
||||
* If nothing else will be pressed we'll need
|
||||
* to re-inject Alt-SysRq keysroke.
|
||||
|
@ -831,8 +872,12 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq,
|
|||
|
||||
default:
|
||||
if (sysrq->active && value && value != 2) {
|
||||
unsigned char c = sysrq_xlate[code];
|
||||
|
||||
sysrq->need_reinject = false;
|
||||
__handle_sysrq(sysrq_xlate[code], true);
|
||||
if (sysrq->shift_use != KEY_RESERVED)
|
||||
c = toupper(c);
|
||||
__handle_sysrq(c, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -119,8 +119,8 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate);
|
|||
/**
|
||||
* tty_termios_encode_baud_rate
|
||||
* @termios: ktermios structure holding user requested state
|
||||
* @ispeed: input speed
|
||||
* @ospeed: output speed
|
||||
* @ibaud: input speed
|
||||
* @obaud: output speed
|
||||
*
|
||||
* Encode the speeds set into the passed termios structure. This is
|
||||
* used as a library helper for drivers so that they can report back
|
||||
|
@ -223,7 +223,7 @@ EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
|
|||
/**
|
||||
* tty_encode_baud_rate - set baud rate of the tty
|
||||
* @ibaud: input baud rate
|
||||
* @obad: output baud rate
|
||||
* @obaud: output baud rate
|
||||
*
|
||||
* Update the current termios data for the tty with the new speed
|
||||
* settings. The caller must hold the termios_rwsem for the tty in
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
* tty_buffer_lock_exclusive - gain exclusive access to buffer
|
||||
* tty_buffer_unlock_exclusive - release exclusive access
|
||||
*
|
||||
* @port - tty_port owning the flip buffer
|
||||
* @port: tty port owning the flip buffer
|
||||
*
|
||||
* Guarantees safe use of the line discipline's receive_buf() method by
|
||||
* excluding the buffer work and any pending flush from using the flip
|
||||
|
@ -78,7 +78,7 @@ EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive);
|
|||
|
||||
/**
|
||||
* tty_buffer_space_avail - return unused buffer space
|
||||
* @port - tty_port owning the flip buffer
|
||||
* @port: tty port owning the flip buffer
|
||||
*
|
||||
* Returns the # of bytes which can be written by the driver without
|
||||
* reaching the buffer limit.
|
||||
|
@ -107,7 +107,7 @@ static void tty_buffer_reset(struct tty_buffer *p, size_t size)
|
|||
|
||||
/**
|
||||
* tty_buffer_free_all - free buffers used by a tty
|
||||
* @tty: tty to free from
|
||||
* @port: tty port to free from
|
||||
*
|
||||
* Remove all the buffers pending on a tty whether queued with data
|
||||
* or in the free ring. Must be called when the tty is no longer in use
|
||||
|
@ -142,7 +142,7 @@ void tty_buffer_free_all(struct tty_port *port)
|
|||
|
||||
/**
|
||||
* tty_buffer_alloc - allocate a tty buffer
|
||||
* @tty: tty device
|
||||
* @port: tty port
|
||||
* @size: desired size (characters)
|
||||
*
|
||||
* Allocate a new tty buffer to hold the desired number of characters.
|
||||
|
@ -184,7 +184,7 @@ found:
|
|||
|
||||
/**
|
||||
* tty_buffer_free - free a tty buffer
|
||||
* @tty: tty owning the buffer
|
||||
* @port: tty port owning the buffer
|
||||
* @b: the buffer to free
|
||||
*
|
||||
* Free a tty buffer, or add it to the free list according to our
|
||||
|
@ -243,7 +243,7 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld)
|
|||
|
||||
/**
|
||||
* tty_buffer_request_room - grow tty buffer if needed
|
||||
* @tty: tty structure
|
||||
* @port: tty port
|
||||
* @size: size desired
|
||||
* @flags: buffer flags if new buffer allocated (default = 0)
|
||||
*
|
||||
|
@ -559,7 +559,7 @@ EXPORT_SYMBOL(tty_flip_buffer_push);
|
|||
|
||||
/**
|
||||
* tty_buffer_init - prepare a tty buffer structure
|
||||
* @tty: tty to initialise
|
||||
* @port: tty port to initialise
|
||||
*
|
||||
* Set up the initial state of the buffer management for a tty device.
|
||||
* Must be called before the other tty buffer functions are used.
|
||||
|
|
|
@ -307,7 +307,7 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
|
|||
|
||||
/**
|
||||
* get_tty_driver - find device of a tty
|
||||
* @dev_t: device identifier
|
||||
* @device: device identifier
|
||||
* @index: returns the index of the tty
|
||||
*
|
||||
* This routine returns a tty driver structure, given a device number
|
||||
|
@ -544,7 +544,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup);
|
|||
|
||||
/**
|
||||
* __tty_hangup - actual handler for hangup events
|
||||
* @work: tty device
|
||||
* @tty: tty device
|
||||
*
|
||||
* This can be called by a "kworker" kernel thread. That is process
|
||||
* synchronous but doesn't hold any locks, so we need to make sure we
|
||||
|
@ -1232,7 +1232,7 @@ static int tty_driver_install_tty(struct tty_driver *driver,
|
|||
/**
|
||||
* tty_driver_remove_tty() - remove a tty from the driver tables
|
||||
* @driver: the driver for the tty
|
||||
* @idx: the minor number
|
||||
* @tty: tty to remove
|
||||
*
|
||||
* Remvoe a tty object from the driver tables. The tty->index field
|
||||
* will be set by the time this is called.
|
||||
|
@ -1247,9 +1247,9 @@ static void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *
|
|||
driver->ttys[tty->index] = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* tty_reopen() - fast re-open of an open tty
|
||||
* @tty - the tty to open
|
||||
/**
|
||||
* tty_reopen() - fast re-open of an open tty
|
||||
* @tty: the tty to open
|
||||
*
|
||||
* Return 0 on success, -errno on error.
|
||||
* Re-opens on master ptys are not allowed and return -EIO.
|
||||
|
@ -1295,7 +1295,6 @@ static int tty_reopen(struct tty_struct *tty)
|
|||
* tty_init_dev - initialise a tty device
|
||||
* @driver: tty driver we are opening a device on
|
||||
* @idx: device index
|
||||
* @ret_tty: returned tty structure
|
||||
*
|
||||
* Prepare a tty device. This may not be a "new" clean device but
|
||||
* could also be an active device. The pty drivers require special
|
||||
|
@ -1313,6 +1312,8 @@ static int tty_reopen(struct tty_struct *tty)
|
|||
* failed open. The new code protects the open with a mutex, so it's
|
||||
* really quite straightforward. The mutex locking can probably be
|
||||
* relaxed for the (most common) case of reopening a tty.
|
||||
*
|
||||
* Return: returned tty structure
|
||||
*/
|
||||
|
||||
struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
|
||||
|
@ -1432,7 +1433,7 @@ static void tty_flush_works(struct tty_struct *tty)
|
|||
|
||||
/**
|
||||
* release_one_tty - release tty structure memory
|
||||
* @kref: kref of tty we are obliterating
|
||||
* @work: work of tty we are obliterating
|
||||
*
|
||||
* Releases memory associated with a tty structure, and clears out the
|
||||
* driver table slots. This function is called when a device is no longer
|
||||
|
@ -1528,7 +1529,6 @@ static void release_tty(struct tty_struct *tty, int idx)
|
|||
/**
|
||||
* tty_release_checks - check a tty before real release
|
||||
* @tty: tty to check
|
||||
* @o_tty: link of @tty (if any)
|
||||
* @idx: index of the tty
|
||||
*
|
||||
* Performs some paranoid checking before true release of the @tty.
|
||||
|
@ -2200,7 +2200,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
|
|||
|
||||
/**
|
||||
* tiocgwinsz - implement window query ioctl
|
||||
* @tty; tty
|
||||
* @tty: tty
|
||||
* @arg: user buffer for result
|
||||
*
|
||||
* Copies the kernel idea of the window size into the user buffer.
|
||||
|
@ -2223,8 +2223,7 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
|
|||
/**
|
||||
* tty_do_resize - resize event
|
||||
* @tty: tty being resized
|
||||
* @rows: rows (character)
|
||||
* @cols: cols (character)
|
||||
* @ws: new dimensions
|
||||
*
|
||||
* Update the termios variables and send the necessary signals to
|
||||
* peform a terminal resize correctly
|
||||
|
@ -2254,7 +2253,7 @@ EXPORT_SYMBOL(tty_do_resize);
|
|||
|
||||
/**
|
||||
* tiocswinsz - implement window size set ioctl
|
||||
* @tty; tty side of tty
|
||||
* @tty: tty side of tty
|
||||
* @arg: user buffer for result
|
||||
*
|
||||
* Copies the user idea of the window size to the kernel. Traditionally
|
||||
|
@ -2402,7 +2401,6 @@ out:
|
|||
/**
|
||||
* tty_tiocmget - get modem status
|
||||
* @tty: tty device
|
||||
* @file: user file pointer
|
||||
* @p: pointer to result
|
||||
*
|
||||
* Obtain the modem status bits from the tty driver if the feature
|
||||
|
|
|
@ -178,8 +178,8 @@ void session_clear_tty(struct pid *session)
|
|||
|
||||
/**
|
||||
* tty_signal_session_leader - sends SIGHUP to session leader
|
||||
* @tty controlling tty
|
||||
* @exit_session if non-zero, signal all foreground group processes
|
||||
* @tty: controlling tty
|
||||
* @exit_session: if non-zero, signal all foreground group processes
|
||||
*
|
||||
* Send SIGHUP and SIGCONT to the session leader and its process group.
|
||||
* Optionally, signal all processes in the foreground process group.
|
||||
|
|
|
@ -79,7 +79,6 @@ EXPORT_SYMBOL(tty_register_ldisc);
|
|||
/**
|
||||
* tty_unregister_ldisc - unload a line discipline
|
||||
* @disc: ldisc number
|
||||
* @new_ldisc: pointer to the ldisc object
|
||||
*
|
||||
* Remove a line discipline from the kernel providing it is not
|
||||
* currently in use.
|
||||
|
@ -542,7 +541,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
|
|||
/**
|
||||
* tty_set_ldisc - set line discipline
|
||||
* @tty: the terminal to set
|
||||
* @ldisc: the line discipline
|
||||
* @disc: the line discipline number
|
||||
*
|
||||
* Set the discipline of a tty line. Must be called from a process
|
||||
* context. The ldisc change logic has to protect itself against any
|
||||
|
|
|
@ -268,7 +268,7 @@ unsigned short *set_translate(int m, struct vc_data *vc)
|
|||
* was active.
|
||||
* Still, it is now possible to a certain extent to cut and paste non-ASCII.
|
||||
*/
|
||||
u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode)
|
||||
u16 inverse_translate(const struct vc_data *conp, int glyph, int use_unicode)
|
||||
{
|
||||
struct uni_pagedir *p;
|
||||
int m;
|
||||
|
@ -708,7 +708,7 @@ EXPORT_SYMBOL(con_set_default_unimap);
|
|||
/**
|
||||
* con_copy_unimap - copy unimap between two vts
|
||||
* @dst_vc: target
|
||||
* @src_vt: source
|
||||
* @src_vc: source
|
||||
*
|
||||
* The caller must hold the console lock when invoking this method
|
||||
*/
|
||||
|
|
|
@ -54,7 +54,7 @@ static struct vc_selection {
|
|||
/* set reverse video on characters s-e of console with selection. */
|
||||
static inline void highlight(const int s, const int e)
|
||||
{
|
||||
invert_screen(vc_sel.cons, s, e-s+2, 1);
|
||||
invert_screen(vc_sel.cons, s, e-s+2, true);
|
||||
}
|
||||
|
||||
/* use complementary color to show the pointer */
|
||||
|
|
|
@ -50,11 +50,7 @@
|
|||
#include <asm/byteorder.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#undef attr
|
||||
#undef org
|
||||
#undef addr
|
||||
#define HEADER_SIZE 4
|
||||
|
||||
#define HEADER_SIZE 4u
|
||||
#define CON_BUF_SIZE (CONFIG_BASE_SMALL ? 256 : PAGE_SIZE)
|
||||
|
||||
/*
|
||||
|
@ -177,12 +173,14 @@ vcs_poll_data_get(struct file *file)
|
|||
return poll;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns VC for inode.
|
||||
/**
|
||||
* vcs_vc -- return VC for @inode
|
||||
* @inode: inode for which to return a VC
|
||||
* @viewed: returns whether this console is currently foreground (viewed)
|
||||
*
|
||||
* Must be called with console_lock.
|
||||
*/
|
||||
static struct vc_data*
|
||||
vcs_vc(struct inode *inode, int *viewed)
|
||||
static struct vc_data *vcs_vc(struct inode *inode, bool *viewed)
|
||||
{
|
||||
unsigned int currcons = console(inode);
|
||||
|
||||
|
@ -191,54 +189,177 @@ vcs_vc(struct inode *inode, int *viewed)
|
|||
if (currcons == 0) {
|
||||
currcons = fg_console;
|
||||
if (viewed)
|
||||
*viewed = 1;
|
||||
*viewed = true;
|
||||
} else {
|
||||
currcons--;
|
||||
if (viewed)
|
||||
*viewed = 0;
|
||||
*viewed = false;
|
||||
}
|
||||
return vc_cons[currcons].d;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns size for VC carried by inode.
|
||||
/**
|
||||
* vcs_size -- return size for a VC in @vc
|
||||
* @vc: which VC
|
||||
* @attr: does it use attributes?
|
||||
* @unicode: is it unicode?
|
||||
*
|
||||
* Must be called with console_lock.
|
||||
*/
|
||||
static int
|
||||
vcs_size(struct inode *inode)
|
||||
static int vcs_size(const struct vc_data *vc, bool attr, bool unicode)
|
||||
{
|
||||
int size;
|
||||
struct vc_data *vc;
|
||||
|
||||
WARN_CONSOLE_UNLOCKED();
|
||||
|
||||
vc = vcs_vc(inode, NULL);
|
||||
if (!vc)
|
||||
return -ENXIO;
|
||||
|
||||
size = vc->vc_rows * vc->vc_cols;
|
||||
|
||||
if (use_attributes(inode)) {
|
||||
if (use_unicode(inode))
|
||||
if (attr) {
|
||||
if (unicode)
|
||||
return -EOPNOTSUPP;
|
||||
size = 2*size + HEADER_SIZE;
|
||||
} else if (use_unicode(inode))
|
||||
|
||||
size = 2 * size + HEADER_SIZE;
|
||||
} else if (unicode)
|
||||
size *= 4;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
|
||||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
struct vc_data *vc;
|
||||
int size;
|
||||
|
||||
console_lock();
|
||||
size = vcs_size(file_inode(file));
|
||||
vc = vcs_vc(inode, NULL);
|
||||
if (!vc) {
|
||||
console_unlock();
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
size = vcs_size(vc, use_attributes(inode), use_unicode(inode));
|
||||
console_unlock();
|
||||
if (size < 0)
|
||||
return size;
|
||||
return fixed_size_llseek(file, offset, orig, size);
|
||||
}
|
||||
|
||||
static int vcs_read_buf_uni(struct vc_data *vc, char *con_buf,
|
||||
unsigned int pos, unsigned int count, bool viewed)
|
||||
{
|
||||
unsigned int nr, row, col, maxcol = vc->vc_cols;
|
||||
int ret;
|
||||
|
||||
ret = vc_uniscr_check(vc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pos /= 4;
|
||||
row = pos / maxcol;
|
||||
col = pos % maxcol;
|
||||
nr = maxcol - col;
|
||||
do {
|
||||
if (nr > count / 4)
|
||||
nr = count / 4;
|
||||
vc_uniscr_copy_line(vc, con_buf, viewed, row, col, nr);
|
||||
con_buf += nr * 4;
|
||||
count -= nr * 4;
|
||||
row++;
|
||||
col = 0;
|
||||
nr = maxcol;
|
||||
} while (count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vcs_read_buf_noattr(const struct vc_data *vc, char *con_buf,
|
||||
unsigned int pos, unsigned int count, bool viewed)
|
||||
{
|
||||
u16 *org;
|
||||
unsigned int col, maxcol = vc->vc_cols;
|
||||
|
||||
org = screen_pos(vc, pos, viewed);
|
||||
col = pos % maxcol;
|
||||
pos += maxcol - col;
|
||||
|
||||
while (count-- > 0) {
|
||||
*con_buf++ = (vcs_scr_readw(vc, org++) & 0xff);
|
||||
if (++col == maxcol) {
|
||||
org = screen_pos(vc, pos, viewed);
|
||||
col = 0;
|
||||
pos += maxcol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int vcs_read_buf(const struct vc_data *vc, char *con_buf,
|
||||
unsigned int pos, unsigned int count, bool viewed,
|
||||
unsigned int *skip)
|
||||
{
|
||||
u16 *org, *con_buf16;
|
||||
unsigned int col, maxcol = vc->vc_cols;
|
||||
unsigned int filled = count;
|
||||
|
||||
if (pos < HEADER_SIZE) {
|
||||
/* clamp header values if they don't fit */
|
||||
con_buf[0] = min(vc->vc_rows, 0xFFu);
|
||||
con_buf[1] = min(vc->vc_cols, 0xFFu);
|
||||
getconsxy(vc, con_buf + 2);
|
||||
|
||||
*skip += pos;
|
||||
count += pos;
|
||||
if (count > CON_BUF_SIZE) {
|
||||
count = CON_BUF_SIZE;
|
||||
filled = count - pos;
|
||||
}
|
||||
|
||||
/* Advance state pointers and move on. */
|
||||
count -= min(HEADER_SIZE, count);
|
||||
pos = HEADER_SIZE;
|
||||
con_buf += HEADER_SIZE;
|
||||
/* If count >= 0, then pos is even... */
|
||||
} else if (pos & 1) {
|
||||
/*
|
||||
* Skip first byte for output if start address is odd. Update
|
||||
* region sizes up/down depending on free space in buffer.
|
||||
*/
|
||||
(*skip)++;
|
||||
if (count < CON_BUF_SIZE)
|
||||
count++;
|
||||
else
|
||||
filled--;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return filled;
|
||||
|
||||
pos -= HEADER_SIZE;
|
||||
pos /= 2;
|
||||
col = pos % maxcol;
|
||||
|
||||
org = screen_pos(vc, pos, viewed);
|
||||
pos += maxcol - col;
|
||||
|
||||
/*
|
||||
* Buffer has even length, so we can always copy character + attribute.
|
||||
* We do not copy last byte to userspace if count is odd.
|
||||
*/
|
||||
count = (count + 1) / 2;
|
||||
con_buf16 = (u16 *)con_buf;
|
||||
|
||||
while (count) {
|
||||
*con_buf16++ = vcs_scr_readw(vc, org++);
|
||||
count--;
|
||||
if (++col == maxcol) {
|
||||
org = screen_pos(vc, pos, viewed);
|
||||
col = 0;
|
||||
pos += maxcol;
|
||||
}
|
||||
}
|
||||
|
||||
return filled;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
||||
|
@ -246,11 +367,11 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|||
struct inode *inode = file_inode(file);
|
||||
struct vc_data *vc;
|
||||
struct vcs_poll_data *poll;
|
||||
long pos, read;
|
||||
int attr, uni_mode, row, col, maxcol, viewed;
|
||||
unsigned short *org = NULL;
|
||||
unsigned int read;
|
||||
ssize_t ret;
|
||||
char *con_buf;
|
||||
loff_t pos;
|
||||
bool viewed, attr, uni_mode;
|
||||
|
||||
con_buf = (char *) __get_free_page(GFP_KERNEL);
|
||||
if (!con_buf)
|
||||
|
@ -283,16 +404,14 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|||
read = 0;
|
||||
ret = 0;
|
||||
while (count) {
|
||||
char *con_buf0, *con_buf_start;
|
||||
long this_round, size;
|
||||
ssize_t orig_count;
|
||||
long p = pos;
|
||||
unsigned int this_round, skip = 0;
|
||||
int size;
|
||||
|
||||
/* Check whether we are above size each round,
|
||||
* as copy_to_user at the end of this loop
|
||||
* could sleep.
|
||||
*/
|
||||
size = vcs_size(inode);
|
||||
size = vcs_size(vc, attr, uni_mode);
|
||||
if (size < 0) {
|
||||
if (read)
|
||||
break;
|
||||
|
@ -313,104 +432,17 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|||
* attempt to move it to userspace.
|
||||
*/
|
||||
|
||||
con_buf_start = con_buf0 = con_buf;
|
||||
orig_count = this_round;
|
||||
maxcol = vc->vc_cols;
|
||||
if (uni_mode) {
|
||||
unsigned int nr;
|
||||
|
||||
ret = vc_uniscr_check(vc);
|
||||
ret = vcs_read_buf_uni(vc, con_buf, pos, this_round,
|
||||
viewed);
|
||||
if (ret)
|
||||
break;
|
||||
p /= 4;
|
||||
row = p / vc->vc_cols;
|
||||
col = p % maxcol;
|
||||
nr = maxcol - col;
|
||||
do {
|
||||
if (nr > this_round/4)
|
||||
nr = this_round/4;
|
||||
vc_uniscr_copy_line(vc, con_buf0, viewed,
|
||||
row, col, nr);
|
||||
con_buf0 += nr * 4;
|
||||
this_round -= nr * 4;
|
||||
row++;
|
||||
col = 0;
|
||||
nr = maxcol;
|
||||
} while (this_round);
|
||||
} else if (!attr) {
|
||||
org = screen_pos(vc, p, viewed);
|
||||
col = p % maxcol;
|
||||
p += maxcol - col;
|
||||
while (this_round-- > 0) {
|
||||
*con_buf0++ = (vcs_scr_readw(vc, org++) & 0xff);
|
||||
if (++col == maxcol) {
|
||||
org = screen_pos(vc, p, viewed);
|
||||
col = 0;
|
||||
p += maxcol;
|
||||
}
|
||||
}
|
||||
vcs_read_buf_noattr(vc, con_buf, pos, this_round,
|
||||
viewed);
|
||||
} else {
|
||||
if (p < HEADER_SIZE) {
|
||||
size_t tmp_count;
|
||||
|
||||
/* clamp header values if they don't fit */
|
||||
con_buf0[0] = min(vc->vc_rows, 0xFFu);
|
||||
con_buf0[1] = min(vc->vc_cols, 0xFFu);
|
||||
getconsxy(vc, con_buf0 + 2);
|
||||
|
||||
con_buf_start += p;
|
||||
this_round += p;
|
||||
if (this_round > CON_BUF_SIZE) {
|
||||
this_round = CON_BUF_SIZE;
|
||||
orig_count = this_round - p;
|
||||
}
|
||||
|
||||
tmp_count = HEADER_SIZE;
|
||||
if (tmp_count > this_round)
|
||||
tmp_count = this_round;
|
||||
|
||||
/* Advance state pointers and move on. */
|
||||
this_round -= tmp_count;
|
||||
p = HEADER_SIZE;
|
||||
con_buf0 = con_buf + HEADER_SIZE;
|
||||
/* If this_round >= 0, then p is even... */
|
||||
} else if (p & 1) {
|
||||
/* Skip first byte for output if start address is odd
|
||||
* Update region sizes up/down depending on free
|
||||
* space in buffer.
|
||||
*/
|
||||
con_buf_start++;
|
||||
if (this_round < CON_BUF_SIZE)
|
||||
this_round++;
|
||||
else
|
||||
orig_count--;
|
||||
}
|
||||
if (this_round > 0) {
|
||||
unsigned short *tmp_buf = (unsigned short *)con_buf0;
|
||||
|
||||
p -= HEADER_SIZE;
|
||||
p /= 2;
|
||||
col = p % maxcol;
|
||||
|
||||
org = screen_pos(vc, p, viewed);
|
||||
p += maxcol - col;
|
||||
|
||||
/* Buffer has even length, so we can always copy
|
||||
* character + attribute. We do not copy last byte
|
||||
* to userspace if this_round is odd.
|
||||
*/
|
||||
this_round = (this_round + 1) >> 1;
|
||||
|
||||
while (this_round) {
|
||||
*tmp_buf++ = vcs_scr_readw(vc, org++);
|
||||
this_round --;
|
||||
if (++col == maxcol) {
|
||||
org = screen_pos(vc, p, viewed);
|
||||
col = 0;
|
||||
p += maxcol;
|
||||
}
|
||||
}
|
||||
}
|
||||
this_round = vcs_read_buf(vc, con_buf, pos, this_round,
|
||||
viewed, &skip);
|
||||
}
|
||||
|
||||
/* Finally, release the console semaphore while we push
|
||||
|
@ -421,18 +453,18 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|||
*/
|
||||
|
||||
console_unlock();
|
||||
ret = copy_to_user(buf, con_buf_start, orig_count);
|
||||
ret = copy_to_user(buf, con_buf + skip, this_round);
|
||||
console_lock();
|
||||
|
||||
if (ret) {
|
||||
read += (orig_count - ret);
|
||||
read += this_round - ret;
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
buf += orig_count;
|
||||
pos += orig_count;
|
||||
read += orig_count;
|
||||
count -= orig_count;
|
||||
buf += this_round;
|
||||
pos += this_round;
|
||||
read += this_round;
|
||||
count -= this_round;
|
||||
}
|
||||
*ppos += read;
|
||||
if (read)
|
||||
|
@ -443,18 +475,129 @@ unlock_out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static u16 *vcs_write_buf_noattr(struct vc_data *vc, const char *con_buf,
|
||||
unsigned int pos, unsigned int count, bool viewed, u16 **org0)
|
||||
{
|
||||
u16 *org;
|
||||
unsigned int col, maxcol = vc->vc_cols;
|
||||
|
||||
*org0 = org = screen_pos(vc, pos, viewed);
|
||||
col = pos % maxcol;
|
||||
pos += maxcol - col;
|
||||
|
||||
while (count > 0) {
|
||||
unsigned char c = *con_buf++;
|
||||
|
||||
count--;
|
||||
vcs_scr_writew(vc,
|
||||
(vcs_scr_readw(vc, org) & 0xff00) | c, org);
|
||||
org++;
|
||||
if (++col == maxcol) {
|
||||
org = screen_pos(vc, pos, viewed);
|
||||
col = 0;
|
||||
pos += maxcol;
|
||||
}
|
||||
}
|
||||
|
||||
return org;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compilers (gcc 10) are unable to optimize the swap in cpu_to_le16. So do it
|
||||
* the poor man way.
|
||||
*/
|
||||
static inline u16 vc_compile_le16(u8 hi, u8 lo)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN
|
||||
return (lo << 8u) | hi;
|
||||
#else
|
||||
return (hi << 8u) | lo;
|
||||
#endif
|
||||
}
|
||||
|
||||
static u16 *vcs_write_buf(struct vc_data *vc, const char *con_buf,
|
||||
unsigned int pos, unsigned int count, bool viewed, u16 **org0)
|
||||
{
|
||||
u16 *org;
|
||||
unsigned int col, maxcol = vc->vc_cols;
|
||||
unsigned char c;
|
||||
|
||||
/* header */
|
||||
if (pos < HEADER_SIZE) {
|
||||
char header[HEADER_SIZE];
|
||||
|
||||
getconsxy(vc, header + 2);
|
||||
while (pos < HEADER_SIZE && count > 0) {
|
||||
count--;
|
||||
header[pos++] = *con_buf++;
|
||||
}
|
||||
if (!viewed)
|
||||
putconsxy(vc, header + 2);
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return NULL;
|
||||
|
||||
pos -= HEADER_SIZE;
|
||||
col = (pos/2) % maxcol;
|
||||
|
||||
*org0 = org = screen_pos(vc, pos/2, viewed);
|
||||
|
||||
/* odd pos -- the first single character */
|
||||
if (pos & 1) {
|
||||
count--;
|
||||
c = *con_buf++;
|
||||
vcs_scr_writew(vc, vc_compile_le16(c, vcs_scr_readw(vc, org)),
|
||||
org);
|
||||
org++;
|
||||
pos++;
|
||||
if (++col == maxcol) {
|
||||
org = screen_pos(vc, pos/2, viewed);
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pos /= 2;
|
||||
pos += maxcol - col;
|
||||
|
||||
/* even pos -- handle attr+character pairs */
|
||||
while (count > 1) {
|
||||
unsigned short w;
|
||||
|
||||
w = get_unaligned(((unsigned short *)con_buf));
|
||||
vcs_scr_writew(vc, w, org++);
|
||||
con_buf += 2;
|
||||
count -= 2;
|
||||
if (++col == maxcol) {
|
||||
org = screen_pos(vc, pos, viewed);
|
||||
col = 0;
|
||||
pos += maxcol;
|
||||
}
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return org;
|
||||
|
||||
/* odd pos -- the remaining character */
|
||||
c = *con_buf++;
|
||||
vcs_scr_writew(vc, vc_compile_le16(vcs_scr_readw(vc, org) >> 8, c),
|
||||
org);
|
||||
|
||||
return org;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
struct vc_data *vc;
|
||||
long pos;
|
||||
long attr, size, written;
|
||||
char *con_buf0;
|
||||
int col, maxcol, viewed;
|
||||
u16 *org0 = NULL, *org = NULL;
|
||||
size_t ret;
|
||||
char *con_buf;
|
||||
u16 *org0, *org;
|
||||
unsigned int written;
|
||||
int size;
|
||||
ssize_t ret;
|
||||
loff_t pos;
|
||||
bool viewed, attr;
|
||||
|
||||
if (use_unicode(inode))
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -476,7 +619,11 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
if (!vc)
|
||||
goto unlock_out;
|
||||
|
||||
size = vcs_size(inode);
|
||||
size = vcs_size(vc, attr, false);
|
||||
if (size < 0) {
|
||||
ret = size;
|
||||
goto unlock_out;
|
||||
}
|
||||
ret = -EINVAL;
|
||||
if (pos < 0 || pos > size)
|
||||
goto unlock_out;
|
||||
|
@ -484,9 +631,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
count = size - pos;
|
||||
written = 0;
|
||||
while (count) {
|
||||
long this_round = count;
|
||||
size_t orig_count;
|
||||
long p;
|
||||
unsigned int this_round = count;
|
||||
|
||||
if (this_round > CON_BUF_SIZE)
|
||||
this_round = CON_BUF_SIZE;
|
||||
|
@ -515,7 +660,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
* the user buffer, so recheck.
|
||||
* Return data written up to now on failure.
|
||||
*/
|
||||
size = vcs_size(inode);
|
||||
size = vcs_size(vc, attr, false);
|
||||
if (size < 0) {
|
||||
if (written)
|
||||
break;
|
||||
|
@ -531,95 +676,18 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
* under the lock using the local kernel buffer.
|
||||
*/
|
||||
|
||||
con_buf0 = con_buf;
|
||||
orig_count = this_round;
|
||||
maxcol = vc->vc_cols;
|
||||
p = pos;
|
||||
if (!attr) {
|
||||
org0 = org = screen_pos(vc, p, viewed);
|
||||
col = p % maxcol;
|
||||
p += maxcol - col;
|
||||
if (attr)
|
||||
org = vcs_write_buf(vc, con_buf, pos, this_round,
|
||||
viewed, &org0);
|
||||
else
|
||||
org = vcs_write_buf_noattr(vc, con_buf, pos, this_round,
|
||||
viewed, &org0);
|
||||
|
||||
while (this_round > 0) {
|
||||
unsigned char c = *con_buf0++;
|
||||
|
||||
this_round--;
|
||||
vcs_scr_writew(vc,
|
||||
(vcs_scr_readw(vc, org) & 0xff00) | c, org);
|
||||
org++;
|
||||
if (++col == maxcol) {
|
||||
org = screen_pos(vc, p, viewed);
|
||||
col = 0;
|
||||
p += maxcol;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (p < HEADER_SIZE) {
|
||||
char header[HEADER_SIZE];
|
||||
|
||||
getconsxy(vc, header + 2);
|
||||
while (p < HEADER_SIZE && this_round > 0) {
|
||||
this_round--;
|
||||
header[p++] = *con_buf0++;
|
||||
}
|
||||
if (!viewed)
|
||||
putconsxy(vc, header + 2);
|
||||
}
|
||||
p -= HEADER_SIZE;
|
||||
col = (p/2) % maxcol;
|
||||
if (this_round > 0) {
|
||||
org0 = org = screen_pos(vc, p/2, viewed);
|
||||
if ((p & 1) && this_round > 0) {
|
||||
char c;
|
||||
|
||||
this_round--;
|
||||
c = *con_buf0++;
|
||||
#ifdef __BIG_ENDIAN
|
||||
vcs_scr_writew(vc, c |
|
||||
(vcs_scr_readw(vc, org) & 0xff00), org);
|
||||
#else
|
||||
vcs_scr_writew(vc, (c << 8) |
|
||||
(vcs_scr_readw(vc, org) & 0xff), org);
|
||||
#endif
|
||||
org++;
|
||||
p++;
|
||||
if (++col == maxcol) {
|
||||
org = screen_pos(vc, p/2, viewed);
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
p /= 2;
|
||||
p += maxcol - col;
|
||||
}
|
||||
while (this_round > 1) {
|
||||
unsigned short w;
|
||||
|
||||
w = get_unaligned(((unsigned short *)con_buf0));
|
||||
vcs_scr_writew(vc, w, org++);
|
||||
con_buf0 += 2;
|
||||
this_round -= 2;
|
||||
if (++col == maxcol) {
|
||||
org = screen_pos(vc, p, viewed);
|
||||
col = 0;
|
||||
p += maxcol;
|
||||
}
|
||||
}
|
||||
if (this_round > 0) {
|
||||
unsigned char c;
|
||||
|
||||
c = *con_buf0++;
|
||||
#ifdef __BIG_ENDIAN
|
||||
vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org);
|
||||
#else
|
||||
vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
count -= orig_count;
|
||||
written += orig_count;
|
||||
buf += orig_count;
|
||||
pos += orig_count;
|
||||
if (org0)
|
||||
count -= this_round;
|
||||
written += this_round;
|
||||
buf += this_round;
|
||||
pos += this_round;
|
||||
if (org)
|
||||
update_region(vc, (unsigned long)(org0), org - org0);
|
||||
}
|
||||
*ppos += written;
|
||||
|
|
|
@ -283,7 +283,8 @@ static inline bool con_should_update(const struct vc_data *vc)
|
|||
return con_is_visible(vc) && !console_blanked;
|
||||
}
|
||||
|
||||
static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
|
||||
static inline unsigned short *screenpos(const struct vc_data *vc, int offset,
|
||||
bool viewed)
|
||||
{
|
||||
unsigned short *p;
|
||||
|
||||
|
@ -543,7 +544,7 @@ int vc_uniscr_check(struct vc_data *vc)
|
|||
* This must be preceded by a successful call to vc_uniscr_check() once
|
||||
* the console lock has been taken.
|
||||
*/
|
||||
void vc_uniscr_copy_line(struct vc_data *vc, void *dest, int viewed,
|
||||
void vc_uniscr_copy_line(const struct vc_data *vc, void *dest, bool viewed,
|
||||
unsigned int row, unsigned int col, unsigned int nr)
|
||||
{
|
||||
struct uni_screen *uniscr = get_vc_uniscr(vc);
|
||||
|
@ -752,7 +753,7 @@ static void update_attr(struct vc_data *vc)
|
|||
}
|
||||
|
||||
/* Note: inverting the screen twice should revert to the original state */
|
||||
void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
|
||||
void invert_screen(struct vc_data *vc, int offset, int count, bool viewed)
|
||||
{
|
||||
unsigned short *p;
|
||||
|
||||
|
@ -811,7 +812,7 @@ void complement_pos(struct vc_data *vc, int offset)
|
|||
|
||||
if (old_offset != -1 && old_offset >= 0 &&
|
||||
old_offset < vc->vc_screenbuf_size) {
|
||||
scr_writew(old, screenpos(vc, old_offset, 1));
|
||||
scr_writew(old, screenpos(vc, old_offset, true));
|
||||
if (con_should_update(vc))
|
||||
vc->vc_sw->con_putc(vc, old, oldy, oldx);
|
||||
notify_update(vc);
|
||||
|
@ -823,7 +824,7 @@ void complement_pos(struct vc_data *vc, int offset)
|
|||
offset < vc->vc_screenbuf_size) {
|
||||
unsigned short new;
|
||||
unsigned short *p;
|
||||
p = screenpos(vc, offset, 1);
|
||||
p = screenpos(vc, offset, true);
|
||||
old = scr_readw(p);
|
||||
new = old ^ vc->vc_complement_mask;
|
||||
scr_writew(new, p);
|
||||
|
@ -1180,7 +1181,6 @@ static inline int resize_screen(struct vc_data *vc, int width, int height,
|
|||
/**
|
||||
* vc_do_resize - resizing method for the tty
|
||||
* @tty: tty being resized
|
||||
* @real_tty: real tty (different to tty if a pty/tty pair)
|
||||
* @vc: virtual console private data
|
||||
* @cols: columns
|
||||
* @lines: lines
|
||||
|
@ -1885,7 +1885,9 @@ static void set_mode(struct vc_data *vc, int on_off)
|
|||
case 5: /* Inverted screen on/off */
|
||||
if (vc->vc_decscnm != on_off) {
|
||||
vc->vc_decscnm = on_off;
|
||||
invert_screen(vc, 0, vc->vc_screenbuf_size, 0);
|
||||
invert_screen(vc, 0,
|
||||
vc->vc_screenbuf_size,
|
||||
false);
|
||||
update_attr(vc);
|
||||
}
|
||||
break;
|
||||
|
@ -2605,6 +2607,9 @@ static inline int vc_sanitize_unicode(const int c)
|
|||
|
||||
/**
|
||||
* vc_translate_unicode -- Combine UTF-8 into Unicode in @vc_utf_char
|
||||
* @vc: virtual console
|
||||
* @c: character to translate
|
||||
* @rescan: we return true if we need more (continuation) data
|
||||
*
|
||||
* @vc_utf_char is the being-constructed unicode character.
|
||||
* @vc_utf_count is the number of continuation bytes still expected to arrive.
|
||||
|
@ -3980,7 +3985,7 @@ EXPORT_SYMBOL(con_is_visible);
|
|||
|
||||
/**
|
||||
* con_debug_enter - prepare the console for the kernel debugger
|
||||
* @sw: console driver
|
||||
* @vc: virtual console
|
||||
*
|
||||
* Called when the console is taken over by the kernel debugger, this
|
||||
* function needs to save the current console state, then put the console
|
||||
|
@ -4038,7 +4043,6 @@ EXPORT_SYMBOL_GPL(con_debug_enter);
|
|||
|
||||
/**
|
||||
* con_debug_leave - restore console state
|
||||
* @sw: console driver
|
||||
*
|
||||
* Restore the console state to what it was before the kernel debugger
|
||||
* was invoked.
|
||||
|
@ -4741,9 +4745,9 @@ int con_font_op(struct vc_data *vc, struct console_font_op *op)
|
|||
*/
|
||||
|
||||
/* used by selection */
|
||||
u16 screen_glyph(struct vc_data *vc, int offset)
|
||||
u16 screen_glyph(const struct vc_data *vc, int offset)
|
||||
{
|
||||
u16 w = scr_readw(screenpos(vc, offset, 1));
|
||||
u16 w = scr_readw(screenpos(vc, offset, true));
|
||||
u16 c = w & 0xff;
|
||||
|
||||
if (w & vc->vc_hi_font_mask)
|
||||
|
@ -4752,7 +4756,7 @@ u16 screen_glyph(struct vc_data *vc, int offset)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(screen_glyph);
|
||||
|
||||
u32 screen_glyph_unicode(struct vc_data *vc, int n)
|
||||
u32 screen_glyph_unicode(const struct vc_data *vc, int n)
|
||||
{
|
||||
struct uni_screen *uniscr = get_vc_uniscr(vc);
|
||||
|
||||
|
@ -4763,27 +4767,27 @@ u32 screen_glyph_unicode(struct vc_data *vc, int n)
|
|||
EXPORT_SYMBOL_GPL(screen_glyph_unicode);
|
||||
|
||||
/* used by vcs - note the word offset */
|
||||
unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed)
|
||||
unsigned short *screen_pos(const struct vc_data *vc, int w_offset, bool viewed)
|
||||
{
|
||||
return screenpos(vc, 2 * w_offset, viewed);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(screen_pos);
|
||||
|
||||
void getconsxy(struct vc_data *vc, unsigned char *p)
|
||||
void getconsxy(const struct vc_data *vc, unsigned char xy[static 2])
|
||||
{
|
||||
/* clamp values if they don't fit */
|
||||
p[0] = min(vc->state.x, 0xFFu);
|
||||
p[1] = min(vc->state.y, 0xFFu);
|
||||
xy[0] = min(vc->state.x, 0xFFu);
|
||||
xy[1] = min(vc->state.y, 0xFFu);
|
||||
}
|
||||
|
||||
void putconsxy(struct vc_data *vc, unsigned char *p)
|
||||
void putconsxy(struct vc_data *vc, unsigned char xy[static const 2])
|
||||
{
|
||||
hide_cursor(vc);
|
||||
gotoxy(vc, p[0], p[1]);
|
||||
gotoxy(vc, xy[0], xy[1]);
|
||||
set_cursor(vc);
|
||||
}
|
||||
|
||||
u16 vcs_scr_readw(struct vc_data *vc, const u16 *org)
|
||||
u16 vcs_scr_readw(const struct vc_data *vc, const u16 *org)
|
||||
{
|
||||
if ((unsigned long)org == vc->vc_pos && softcursor_original != -1)
|
||||
return softcursor_original;
|
||||
|
|
|
@ -181,7 +181,7 @@ static void vt_event_wait(struct vt_event_wait *vw)
|
|||
|
||||
/**
|
||||
* vt_event_wait_ioctl - event ioctl handler
|
||||
* @arg: argument to ioctl
|
||||
* @event: argument to ioctl (the event)
|
||||
*
|
||||
* Implement the VT_WAITEVENT ioctl using the VT event interface
|
||||
*/
|
||||
|
@ -208,7 +208,6 @@ static int vt_event_wait_ioctl(struct vt_event __user *event)
|
|||
|
||||
/**
|
||||
* vt_waitactive - active console wait
|
||||
* @event: event code
|
||||
* @n: new console
|
||||
*
|
||||
* Helper for event waits. Used to implement the legacy
|
||||
|
@ -773,58 +772,21 @@ static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)
|
|||
if (copy_from_user(&v, cs, sizeof(struct vt_consize)))
|
||||
return -EFAULT;
|
||||
|
||||
/* FIXME: Should check the copies properly */
|
||||
if (!v.v_vlin)
|
||||
v.v_vlin = vc->vc_scan_lines;
|
||||
|
||||
if (v.v_clin) {
|
||||
int rows = v.v_vlin / v.v_clin;
|
||||
if (v.v_rows != rows) {
|
||||
if (v.v_rows) /* Parameters don't add up */
|
||||
return -EINVAL;
|
||||
v.v_rows = rows;
|
||||
}
|
||||
}
|
||||
|
||||
if (v.v_vcol && v.v_ccol) {
|
||||
int cols = v.v_vcol / v.v_ccol;
|
||||
if (v.v_cols != cols) {
|
||||
if (v.v_cols)
|
||||
return -EINVAL;
|
||||
v.v_cols = cols;
|
||||
}
|
||||
}
|
||||
|
||||
if (v.v_clin > 32)
|
||||
return -EINVAL;
|
||||
if (v.v_vlin)
|
||||
pr_info_once("\"struct vt_consize\"->v_vlin is ignored. Please report if you need this.\n");
|
||||
if (v.v_clin)
|
||||
pr_info_once("\"struct vt_consize\"->v_clin is ignored. Please report if you need this.\n");
|
||||
|
||||
console_lock();
|
||||
for (i = 0; i < MAX_NR_CONSOLES; i++) {
|
||||
struct vc_data *vcp;
|
||||
vc = vc_cons[i].d;
|
||||
|
||||
if (!vc_cons[i].d)
|
||||
continue;
|
||||
console_lock();
|
||||
vcp = vc_cons[i].d;
|
||||
if (vcp) {
|
||||
int ret;
|
||||
int save_scan_lines = vcp->vc_scan_lines;
|
||||
int save_font_height = vcp->vc_font.height;
|
||||
|
||||
if (v.v_vlin)
|
||||
vcp->vc_scan_lines = v.v_vlin;
|
||||
if (v.v_clin)
|
||||
vcp->vc_font.height = v.v_clin;
|
||||
vcp->vc_resize_user = 1;
|
||||
ret = vc_resize(vcp, v.v_cols, v.v_rows);
|
||||
if (ret) {
|
||||
vcp->vc_scan_lines = save_scan_lines;
|
||||
vcp->vc_font.height = save_font_height;
|
||||
console_unlock();
|
||||
return ret;
|
||||
}
|
||||
if (vc) {
|
||||
vc->vc_resize_user = 1;
|
||||
vc_resize(vc, v.v_cols, v.v_rows);
|
||||
}
|
||||
console_unlock();
|
||||
}
|
||||
console_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -125,6 +125,8 @@ static const struct linux_logo *newport_show_logo(void)
|
|||
npregs->go.hostrw0 = *data++ << 24;
|
||||
|
||||
return logo;
|
||||
#else
|
||||
return NULL;
|
||||
#endif /* CONFIG_LOGO_SGI_CLUT224 */
|
||||
}
|
||||
|
||||
|
@ -671,11 +673,6 @@ static bool newport_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
|
|||
return true;
|
||||
}
|
||||
|
||||
static int newport_set_origin(struct vc_data *vc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void newport_save_screen(struct vc_data *vc) { }
|
||||
|
||||
const struct consw newport_con = {
|
||||
|
@ -692,7 +689,6 @@ const struct consw newport_con = {
|
|||
.con_blank = newport_blank,
|
||||
.con_font_set = newport_font_set,
|
||||
.con_font_default = newport_font_default,
|
||||
.con_set_origin = newport_set_origin,
|
||||
.con_save_screen = newport_save_screen
|
||||
};
|
||||
|
||||
|
@ -744,18 +740,6 @@ static struct gio_driver newport_driver = {
|
|||
.probe = newport_probe,
|
||||
.remove = newport_remove,
|
||||
};
|
||||
|
||||
int __init newport_console_init(void)
|
||||
{
|
||||
return gio_register_driver(&newport_driver);
|
||||
}
|
||||
|
||||
void __exit newport_console_exit(void)
|
||||
{
|
||||
gio_unregister_driver(&newport_driver);
|
||||
}
|
||||
|
||||
module_init(newport_console_init);
|
||||
module_exit(newport_console_exit);
|
||||
module_driver(newport_driver, gio_register_driver, gio_unregister_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -217,11 +217,6 @@ static int sticon_switch(struct vc_data *conp)
|
|||
return 1; /* needs refreshing */
|
||||
}
|
||||
|
||||
static int sticon_set_origin(struct vc_data *conp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sticon_blank(struct vc_data *c, int blank, int mode_switch)
|
||||
{
|
||||
if (blank == 0) {
|
||||
|
@ -229,14 +224,13 @@ static int sticon_blank(struct vc_data *c, int blank, int mode_switch)
|
|||
vga_is_gfx = 0;
|
||||
return 1;
|
||||
}
|
||||
sticon_set_origin(c);
|
||||
sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
|
||||
if (mode_switch)
|
||||
vga_is_gfx = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u16 *sticon_screen_pos(struct vc_data *conp, int offset)
|
||||
static u16 *sticon_screen_pos(const struct vc_data *conp, int offset)
|
||||
{
|
||||
int line;
|
||||
unsigned long p;
|
||||
|
@ -334,7 +328,6 @@ static const struct consw sti_con = {
|
|||
.con_scroll = sticon_scroll,
|
||||
.con_switch = sticon_switch,
|
||||
.con_blank = sticon_blank,
|
||||
.con_set_origin = sticon_set_origin,
|
||||
.con_save_screen = sticon_save_screen,
|
||||
.con_build_attr = sticon_build_attr,
|
||||
.con_invert_region = sticon_invert_region,
|
||||
|
|
|
@ -163,8 +163,6 @@ static const struct consw fb_con;
|
|||
|
||||
#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
|
||||
|
||||
static int fbcon_set_origin(struct vc_data *);
|
||||
|
||||
static int fbcon_cursor_noblink;
|
||||
|
||||
#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
|
||||
|
@ -2600,7 +2598,7 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
|
|||
fb_set_cmap(&palette_cmap, info);
|
||||
}
|
||||
|
||||
static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
|
||||
static u16 *fbcon_screen_pos(const struct vc_data *vc, int offset)
|
||||
{
|
||||
return (u16 *) (vc->vc_origin + offset);
|
||||
}
|
||||
|
@ -2647,11 +2645,6 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
|
|||
}
|
||||
}
|
||||
|
||||
static int fbcon_set_origin(struct vc_data *vc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fbcon_suspended(struct fb_info *info)
|
||||
{
|
||||
struct vc_data *vc = NULL;
|
||||
|
@ -3122,7 +3115,6 @@ static const struct consw fb_con = {
|
|||
.con_font_default = fbcon_set_def_font,
|
||||
.con_font_copy = fbcon_copy_font,
|
||||
.con_set_palette = fbcon_set_palette,
|
||||
.con_set_origin = fbcon_set_origin,
|
||||
.con_invert_region = fbcon_invert_region,
|
||||
.con_screen_pos = fbcon_screen_pos,
|
||||
.con_getxy = fbcon_getxy,
|
||||
|
|
|
@ -74,7 +74,7 @@ struct consw {
|
|||
enum vc_intensity intensity,
|
||||
bool blink, bool underline, bool reverse, bool italic);
|
||||
void (*con_invert_region)(struct vc_data *vc, u16 *p, int count);
|
||||
u16 *(*con_screen_pos)(struct vc_data *vc, int offset);
|
||||
u16 *(*con_screen_pos)(const struct vc_data *vc, int offset);
|
||||
unsigned long (*con_getxy)(struct vc_data *vc, unsigned long position,
|
||||
int *px, int *py);
|
||||
/*
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
#ifdef CONFIG_CONSOLE_TRANSLATIONS
|
||||
struct vc_data;
|
||||
|
||||
extern u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode);
|
||||
extern u16 inverse_translate(const struct vc_data *conp, int glyph,
|
||||
int use_unicode);
|
||||
extern unsigned short *set_translate(int m, struct vc_data *vc);
|
||||
extern int conv_uni_to_pc(struct vc_data *conp, long ucs);
|
||||
extern u32 conv_8bit_to_uni(unsigned char c);
|
||||
|
|
|
@ -248,6 +248,9 @@ struct geni_se {
|
|||
#define GENI_SE_VERSION_MINOR(ver) ((ver & HW_VER_MINOR_MASK) >> HW_VER_MINOR_SHFT)
|
||||
#define GENI_SE_VERSION_STEP(ver) (ver & HW_VER_STEP_MASK)
|
||||
|
||||
/* QUP SE VERSION value for major number 2 and minor number 5 */
|
||||
#define QUP_SE_VERSION_2_5 0x20050000
|
||||
|
||||
/*
|
||||
* Define bandwidth thresholds that cause the underlying Core 2X interconnect
|
||||
* clock to run at the named frequency. These baseline values are recommended
|
||||
|
|
|
@ -33,21 +33,23 @@ extern unsigned char default_red[];
|
|||
extern unsigned char default_grn[];
|
||||
extern unsigned char default_blu[];
|
||||
|
||||
extern unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed);
|
||||
extern u16 screen_glyph(struct vc_data *vc, int offset);
|
||||
extern u32 screen_glyph_unicode(struct vc_data *vc, int offset);
|
||||
extern unsigned short *screen_pos(const struct vc_data *vc, int w_offset,
|
||||
bool viewed);
|
||||
extern u16 screen_glyph(const struct vc_data *vc, int offset);
|
||||
extern u32 screen_glyph_unicode(const struct vc_data *vc, int offset);
|
||||
extern void complement_pos(struct vc_data *vc, int offset);
|
||||
extern void invert_screen(struct vc_data *vc, int offset, int count, int shift);
|
||||
extern void invert_screen(struct vc_data *vc, int offset, int count, bool viewed);
|
||||
|
||||
extern void getconsxy(struct vc_data *vc, unsigned char *p);
|
||||
extern void putconsxy(struct vc_data *vc, unsigned char *p);
|
||||
extern void getconsxy(const struct vc_data *vc, unsigned char xy[static 2]);
|
||||
extern void putconsxy(struct vc_data *vc, unsigned char xy[static const 2]);
|
||||
|
||||
extern u16 vcs_scr_readw(struct vc_data *vc, const u16 *org);
|
||||
extern u16 vcs_scr_readw(const struct vc_data *vc, const u16 *org);
|
||||
extern void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org);
|
||||
extern void vcs_scr_updated(struct vc_data *vc);
|
||||
|
||||
extern int vc_uniscr_check(struct vc_data *vc);
|
||||
extern void vc_uniscr_copy_line(struct vc_data *vc, void *dest, int viewed,
|
||||
extern void vc_uniscr_copy_line(const struct vc_data *vc, void *dest,
|
||||
bool viewed,
|
||||
unsigned int row, unsigned int col,
|
||||
unsigned int nr);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче