From 1c055e55a242a33e574e48be530e06770a210dcd Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 19 Feb 2024 03:26:26 +0000
Subject: [PATCH] add r8169 read mac form eeprom

---
 kernel/drivers/tty/mxser.c |  121 +++++++++++++++++++++------------------
 1 files changed, 65 insertions(+), 56 deletions(-)

diff --git a/kernel/drivers/tty/mxser.c b/kernel/drivers/tty/mxser.c
index 8bc15cb..8344265 100644
--- a/kernel/drivers/tty/mxser.c
+++ b/kernel/drivers/tty/mxser.c
@@ -638,16 +638,15 @@
  * This routine is called to set the UART divisor registers to match
  * the specified baud rate for a serial port.
  */
-static int mxser_change_speed(struct tty_struct *tty)
+static void mxser_change_speed(struct tty_struct *tty)
 {
 	struct mxser_port *info = tty->driver_data;
 	unsigned cflag, cval, fcr;
-	int ret = 0;
 	unsigned char status;
 
 	cflag = tty->termios.c_cflag;
 	if (!info->ioaddr)
-		return ret;
+		return;
 
 	if (mxser_set_baud_method[tty->index] == 0)
 		mxser_set_baud(tty, tty_get_baud_rate(tty));
@@ -803,8 +802,6 @@
 
 	outb(fcr, info->ioaddr + UART_FCR);	/* set fcr */
 	outb(cval, info->ioaddr + UART_LCR);
-
-	return ret;
 }
 
 static void mxser_check_modem_status(struct tty_struct *tty,
@@ -861,6 +858,7 @@
 	struct mxser_port *info = container_of(port, struct mxser_port, port);
 	unsigned long page;
 	unsigned long flags;
+	int ret;
 
 	page = __get_free_page(GFP_KERNEL);
 	if (!page)
@@ -870,9 +868,9 @@
 
 	if (!info->ioaddr || !info->type) {
 		set_bit(TTY_IO_ERROR, &tty->flags);
-		free_page(page);
 		spin_unlock_irqrestore(&info->slock, flags);
-		return 0;
+		ret = 0;
+		goto err_free_xmit;
 	}
 	info->port.xmit_buf = (unsigned char *) page;
 
@@ -898,8 +896,10 @@
 		if (capable(CAP_SYS_ADMIN)) {
 			set_bit(TTY_IO_ERROR, &tty->flags);
 			return 0;
-		} else
-			return -ENODEV;
+		}
+
+		ret = -ENODEV;
+		goto err_free_xmit;
 	}
 
 	/*
@@ -944,6 +944,10 @@
 	spin_unlock_irqrestore(&info->slock, flags);
 
 	return 0;
+err_free_xmit:
+	free_page(page);
+	info->port.xmit_buf = NULL;
+	return ret;
 }
 
 /*
@@ -1207,76 +1211,90 @@
  * ------------------------------------------------------------
  */
 static int mxser_get_serial_info(struct tty_struct *tty,
-		struct serial_struct __user *retinfo)
+		struct serial_struct *ss)
 {
 	struct mxser_port *info = tty->driver_data;
-	struct serial_struct tmp = {
-		.type = info->type,
-		.line = tty->index,
-		.port = info->ioaddr,
-		.irq = info->board->irq,
-		.flags = info->port.flags,
-		.baud_base = info->baud_base,
-		.close_delay = info->port.close_delay,
-		.closing_wait = info->port.closing_wait,
-		.custom_divisor = info->custom_divisor,
-	};
-	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
-		return -EFAULT;
+	struct tty_port *port = &info->port;
+
+	if (tty->index == MXSER_PORTS)
+		return -ENOTTY;
+
+	mutex_lock(&port->mutex);
+	ss->type = info->type,
+	ss->line = tty->index,
+	ss->port = info->ioaddr,
+	ss->irq = info->board->irq,
+	ss->flags = info->port.flags,
+	ss->baud_base = info->baud_base,
+	ss->close_delay = info->port.close_delay,
+	ss->closing_wait = info->port.closing_wait,
+	ss->custom_divisor = info->custom_divisor,
+	mutex_unlock(&port->mutex);
 	return 0;
 }
 
 static int mxser_set_serial_info(struct tty_struct *tty,
-		struct serial_struct __user *new_info)
+		struct serial_struct *ss)
 {
 	struct mxser_port *info = tty->driver_data;
 	struct tty_port *port = &info->port;
-	struct serial_struct new_serial;
 	speed_t baud;
 	unsigned long sl_flags;
 	unsigned int flags;
 	int retval = 0;
 
-	if (!new_info || !info->ioaddr)
-		return -ENODEV;
-	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
-		return -EFAULT;
+	if (tty->index == MXSER_PORTS)
+		return -ENOTTY;
+	if (tty_io_error(tty))
+		return -EIO;
 
-	if (new_serial.irq != info->board->irq ||
-			new_serial.port != info->ioaddr)
+	mutex_lock(&port->mutex);
+	if (!info->ioaddr) {
+		mutex_unlock(&port->mutex);
+		return -ENODEV;
+	}
+
+	if (ss->irq != info->board->irq ||
+			ss->port != info->ioaddr) {
+		mutex_unlock(&port->mutex);
 		return -EINVAL;
+	}
 
 	flags = port->flags & ASYNC_SPD_MASK;
 
 	if (!capable(CAP_SYS_ADMIN)) {
-		if ((new_serial.baud_base != info->baud_base) ||
-				(new_serial.close_delay != info->port.close_delay) ||
-				((new_serial.flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK)))
+		if ((ss->baud_base != info->baud_base) ||
+				(ss->close_delay != info->port.close_delay) ||
+				((ss->flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK))) {
+			mutex_unlock(&port->mutex);
 			return -EPERM;
+		}
 		info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) |
-				(new_serial.flags & ASYNC_USR_MASK));
+				(ss->flags & ASYNC_USR_MASK));
 	} else {
 		/*
 		 * OK, past this point, all the error checking has been done.
 		 * At this point, we start making changes.....
 		 */
 		port->flags = ((port->flags & ~ASYNC_FLAGS) |
-				(new_serial.flags & ASYNC_FLAGS));
-		port->close_delay = new_serial.close_delay * HZ / 100;
-		port->closing_wait = new_serial.closing_wait * HZ / 100;
+				(ss->flags & ASYNC_FLAGS));
+		port->close_delay = ss->close_delay * HZ / 100;
+		port->closing_wait = ss->closing_wait * HZ / 100;
 		port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 		if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
-				(new_serial.baud_base != info->baud_base ||
-				new_serial.custom_divisor !=
+				(ss->baud_base != info->baud_base ||
+				ss->custom_divisor !=
 				info->custom_divisor)) {
-			if (new_serial.custom_divisor == 0)
+			if (ss->custom_divisor == 0) {
+				mutex_unlock(&port->mutex);
 				return -EINVAL;
-			baud = new_serial.baud_base / new_serial.custom_divisor;
+			}
+			baud = ss->baud_base / ss->custom_divisor;
 			tty_encode_baud_rate(tty, baud, baud);
 		}
 	}
 
-	info->type = new_serial.type;
+	info->type = ss->type;
 
 	process_txrx_fifo(info);
 
@@ -1291,6 +1309,7 @@
 		if (retval == 0)
 			tty_port_set_initialized(port, 1);
 	}
+	mutex_unlock(&port->mutex);
 	return retval;
 }
 
@@ -1660,11 +1679,9 @@
 		unsigned int cmd, unsigned long arg)
 {
 	struct mxser_port *info = tty->driver_data;
-	struct tty_port *port = &info->port;
 	struct async_icount cnow;
 	unsigned long flags;
 	void __user *argp = (void __user *)arg;
-	int retval;
 
 	if (tty->index == MXSER_PORTS)
 		return mxser_ioctl_special(cmd, argp);
@@ -1708,20 +1725,10 @@
 		return 0;
 	}
 
-	if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && tty_io_error(tty))
+	if (cmd != TIOCMIWAIT && tty_io_error(tty))
 		return -EIO;
 
 	switch (cmd) {
-	case TIOCGSERIAL:
-		mutex_lock(&port->mutex);
-		retval = mxser_get_serial_info(tty, argp);
-		mutex_unlock(&port->mutex);
-		return retval;
-	case TIOCSSERIAL:
-		mutex_lock(&port->mutex);
-		retval = mxser_set_serial_info(tty, argp);
-		mutex_unlock(&port->mutex);
-		return retval;
 	case TIOCSERGETLSR:	/* Get line status register */
 		return  mxser_get_lsr_info(info, argp);
 		/*
@@ -2325,6 +2332,8 @@
 	.wait_until_sent = mxser_wait_until_sent,
 	.tiocmget = mxser_tiocmget,
 	.tiocmset = mxser_tiocmset,
+	.set_serial = mxser_set_serial_info,
+	.get_serial = mxser_get_serial_info,
 	.get_icount = mxser_get_icount,
 };
 

--
Gitblit v1.6.2