diff options
-rw-r--r-- | drivers/char/amiserial.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 3d468f502d2d..8ab75a43231b 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -1074,6 +1074,7 @@ static int get_serial_info(struct async_struct * info, | |||
1074 | if (!retinfo) | 1074 | if (!retinfo) |
1075 | return -EFAULT; | 1075 | return -EFAULT; |
1076 | memset(&tmp, 0, sizeof(tmp)); | 1076 | memset(&tmp, 0, sizeof(tmp)); |
1077 | lock_kernel(); | ||
1077 | tmp.type = state->type; | 1078 | tmp.type = state->type; |
1078 | tmp.line = state->line; | 1079 | tmp.line = state->line; |
1079 | tmp.port = state->port; | 1080 | tmp.port = state->port; |
@@ -1084,6 +1085,7 @@ static int get_serial_info(struct async_struct * info, | |||
1084 | tmp.close_delay = state->close_delay; | 1085 | tmp.close_delay = state->close_delay; |
1085 | tmp.closing_wait = state->closing_wait; | 1086 | tmp.closing_wait = state->closing_wait; |
1086 | tmp.custom_divisor = state->custom_divisor; | 1087 | tmp.custom_divisor = state->custom_divisor; |
1088 | unlock_kernel(); | ||
1087 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) | 1089 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) |
1088 | return -EFAULT; | 1090 | return -EFAULT; |
1089 | return 0; | 1091 | return 0; |
@@ -1099,13 +1101,17 @@ static int set_serial_info(struct async_struct * info, | |||
1099 | 1101 | ||
1100 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) | 1102 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) |
1101 | return -EFAULT; | 1103 | return -EFAULT; |
1104 | |||
1105 | lock_kernel(); | ||
1102 | state = info->state; | 1106 | state = info->state; |
1103 | old_state = *state; | 1107 | old_state = *state; |
1104 | 1108 | ||
1105 | change_irq = new_serial.irq != state->irq; | 1109 | change_irq = new_serial.irq != state->irq; |
1106 | change_port = (new_serial.port != state->port); | 1110 | change_port = (new_serial.port != state->port); |
1107 | if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) | 1111 | if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) { |
1112 | unlock_kernel(); | ||
1108 | return -EINVAL; | 1113 | return -EINVAL; |
1114 | } | ||
1109 | 1115 | ||
1110 | if (!serial_isroot()) { | 1116 | if (!serial_isroot()) { |
1111 | if ((new_serial.baud_base != state->baud_base) || | 1117 | if ((new_serial.baud_base != state->baud_base) || |
@@ -1122,8 +1128,10 @@ static int set_serial_info(struct async_struct * info, | |||
1122 | goto check_and_exit; | 1128 | goto check_and_exit; |
1123 | } | 1129 | } |
1124 | 1130 | ||
1125 | if (new_serial.baud_base < 9600) | 1131 | if (new_serial.baud_base < 9600) { |
1132 | unlock_kernel(); | ||
1126 | return -EINVAL; | 1133 | return -EINVAL; |
1134 | } | ||
1127 | 1135 | ||
1128 | /* | 1136 | /* |
1129 | * OK, past this point, all the error checking has been done. | 1137 | * OK, past this point, all the error checking has been done. |
@@ -1157,6 +1165,7 @@ check_and_exit: | |||
1157 | } | 1165 | } |
1158 | } else | 1166 | } else |
1159 | retval = startup(info); | 1167 | retval = startup(info); |
1168 | unlock_kernel(); | ||
1160 | return retval; | 1169 | return retval; |
1161 | } | 1170 | } |
1162 | 1171 | ||