Attachment 'multifix-13.3-RELEASE.diff'
Download 1 diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf
2 index 824751078833..2846e7f1d144 100644
3 --- a/libexec/rc/rc.conf
4 +++ b/libexec/rc/rc.conf
5 @@ -70,6 +70,10 @@ local_startup="${_localbase}/etc/rc.d" # startup script dirs.
6 script_name_sep=" " # Change if your startup scripts' names contain spaces
7 rc_conf_files="/etc/rc.conf /etc/rc.conf.local"
8
9 +# List of UEFI and kenv(1) variables to synchronize.
10 +uefivars_variables='LoaderRotate' # Space separated list of names of variables
11 +uefivars_kenv_LoaderRotate='screen.rotate' # List kenv(1) keys, one per UEFI variable
12 +
13 # ZFS support
14 zfs_enable="NO" # Set to YES to automatically mount ZFS file systems
15 zfskeys_enable="NO" # Set YES to autoload ZFS encryption keys
16 @@ -718,8 +722,12 @@ devfs_set_rulesets="" # A list of /mount/dev=ruleset_name settings to
17 devfs_load_rulesets="YES" # Enable to always load the default rulesets
18 performance_cx_lowest="NONE" # Online CPU idle state
19 performance_cpu_freq="NONE" # Online CPU frequency
20 +performance_tz0_active="NONE" # Online forced active cooling zone
21 +performance_tz0_PSV="NONE" # Online passive cooling threshold
22 economy_cx_lowest="Cmax" # Offline CPU idle state
23 economy_cpu_freq="NONE" # Offline CPU frequency
24 +economy_tz0_active="NONE" # Offline forced active cooling zone
25 +economy_tz0_PSV="NONE" # Offline passive cooling threshold
26 virecover_enable="YES" # Perform housekeeping for the vi(1) editor
27 ugidfw_enable="NO" # Load mac_bsdextended(4) rules on boot
28 bsdextended_script="/etc/rc.bsdextended" # Default mac_bsdextended(4)
29 diff --git a/libexec/rc/rc.d/Makefile b/libexec/rc/rc.d/Makefile
30 index ac35a2b5e28f..bc259c290135 100644
31 --- a/libexec/rc/rc.d/Makefile
32 +++ b/libexec/rc/rc.d/Makefile
33 @@ -201,6 +201,10 @@ BSNMPPACKAGE= bsnmp
34 CONFS+= ccd
35 .endif
36
37 +.if ${MK_EFI} != "no"
38 +CONFS+= uefivars
39 +.endif
40 +
41 .if ${MK_FTP} != "no"
42 CONFS+= ftpd
43 .endif
44 diff --git a/libexec/rc/rc.d/power_profile b/libexec/rc/rc.d/power_profile
45 index 71f3f3ad8792..ec07eb920c93 100755
46 --- a/libexec/rc/rc.d/power_profile
47 +++ b/libexec/rc/rc.d/power_profile
48 @@ -79,6 +79,14 @@ case ${state} in
49 esac
50
51 # Set the various sysctls based on the profile's values.
52 +node="hw.acpi.thermal.tz0._PSV"
53 +eval value=\$${profile}_tz0_PSV
54 +sysctl_set
55 +
56 +node="hw.acpi.thermal.tz0.active"
57 +eval value=\$${profile}_tz0_active
58 +sysctl_set
59 +
60 node="hw.acpi.cpu.cx_lowest"
61 highest_value="C1"
62 lowest_value="Cmax"
63 diff --git a/libexec/rc/rc.d/uefivars b/libexec/rc/rc.d/uefivars
64 new file mode 100755
65 index 000000000000..18d20cec7aa1
66 --- /dev/null
67 +++ b/libexec/rc/rc.d/uefivars
68 @@ -0,0 +1,71 @@
69 +#!/bin/sh
70 +#
71 +# Copyright (c) 2003 The FreeBSD Project. All rights reserved.
72 +#
73 +# Redistribution and use in source and binary forms, with or without
74 +# modification, are permitted provided that the following conditions
75 +# are met:
76 +# 1. Redistributions of source code must retain the above copyright
77 +# notice, this list of conditions and the following disclaimer.
78 +# 2. Redistributions in binary form must reproduce the above copyright
79 +# notice, this list of conditions and the following disclaimer in the
80 +# documentation and/or other materials provided with the distribution.
81 +#
82 +# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
83 +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
84 +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
85 +# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
86 +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
87 +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
88 +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
89 +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
90 +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
91 +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
92 +# SUCH DAMAGE.
93 +#
94 +# $FreeBSD$
95 +#
96 +
97 +# PROVIDE: uefivars
98 +# REQUIRE: kld
99 +# KEYWORD: shutdown
100 +
101 +. /etc/rc.subr
102 +
103 +name="uefivars"
104 +desc="Synchronize UEFI with kenv(1) variables"
105 +start_cmd="uefivars_start"
106 +stop_cmd="uefivars_start"
107 +
108 +efivar="/usr/sbin/efivar -q"
109 +freebsd_guid='cfee69ad-a0de-47a9-93a8-f63106f8ae99'
110 +iconv="/usr/bin/iconv -t UCS-2-INTERNAL"
111 +kenv="/bin/kenv -q"
112 +
113 +uefivars_start()
114 +{
115 + local var kenv_key kenv_value UEFI_value
116 + for var in $uefivars_variables
117 + do
118 + eval kenv_key=\$uefivars_kenv_$var
119 + kenv_value=`$kenv $kenv_key`
120 + if [ -z "$kenv_value" ]
121 + then
122 + debug "DELETE LoaderRotate"
123 + # Delete UEFI variables without corresponding kenv(1) key.
124 + $efivar -D ${freebsd_guid}-${var}
125 + else
126 + # Update UEFI variables that differ from $kenv_value.
127 + UEFI_value=`$efivar -p -N -u ${freebsd_guid}-${var}`
128 + if [ "$kenv_value" != "$UEFI_value" ]
129 + then
130 + debug "UPDATE LoaderRotate $config_value"
131 + echo -n $kenv_value | $iconv | \
132 + $efivar -w ${freebsd_guid}-${var}
133 + fi
134 + fi
135 + done
136 +}
137 +
138 +load_rc_config $name
139 +run_rc_command "$1"
140 diff --git a/share/man/man4/acpi_thermal.4 b/share/man/man4/acpi_thermal.4
141 index 3961ed36276c..256aa978b486 100644
142 --- a/share/man/man4/acpi_thermal.4
143 +++ b/share/man/man4/acpi_thermal.4
144 @@ -22,7 +22,7 @@
145 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
146 .\" SUCH DAMAGE.
147 .\"
148 -.Dd March 17, 2007
149 +.Dd July 31, 2022
150 .Dt ACPI_THERMAL 4
151 .Os
152 .Sh NAME
153 @@ -82,6 +82,9 @@ Current temperature for this zone.
154 .It Va hw.acpi.thermal.tz%d._PSV
155 Temperature to start passive cooling by throttling down CPU, etc.
156 This value can be overridden by the user.
157 +.It Va hw.acpi.thermal.tz%d._CR3
158 +Temperature to start critical suspend to RAM (S3).
159 +This value can be overridden by the user.
160 .It Va hw.acpi.thermal.tz%d._HOT
161 Temperature to start critical suspend to disk (S4).
162 This value can be overridden by the user.
163 diff --git a/share/man/man4/usb_quirk.4 b/share/man/man4/usb_quirk.4
164 index 15f5a9718c8f..f199ad56a758 100644
165 --- a/share/man/man4/usb_quirk.4
166 +++ b/share/man/man4/usb_quirk.4
167 @@ -74,6 +74,8 @@ device should be ignored by ums class
168 does not identify properly
169 .It UQ_MS_LEADING_BYTE
170 mouse sends an unknown leading byte
171 +.It UQ_MS_NO_SETPROTO
172 +device should not receive "SetProtocol" requests
173 .It UQ_MS_REVZ
174 mouse has Z-axis reversed
175 .It UQ_MS_VENDOR_BTN
176 diff --git a/share/man/man4/vt.4 b/share/man/man4/vt.4
177 index c75830bdd44f..f6ba0754fb3f 100644
178 --- a/share/man/man4/vt.4
179 +++ b/share/man/man4/vt.4
180 @@ -356,6 +356,24 @@ To set black and white colors of console palette
181 .Pp
182 .Dl kern.vt.color.0.rgb="10,10,10"
183 .Dl kern.vt.color.15.rgb="#f0f0f0"
184 +.Pp
185 +The mode option
186 +.Sy rotate
187 +is also supported, with values 0, 90, 180, and 270 representing the degrees
188 +counterclockwise to rotate the display. Follow an optional connector name
189 +and mode with a comma and the mode option. For example,
190 +to set the default rotation for all output connectors 90 degrees clockwise:
191 +.Pp
192 +.Dl kern.vt.fb.default_mode=",rotate=270"
193 +.Pp
194 +This option is only supported by
195 +.Cm vt_fb
196 +when it is paired with a KMS video driver, and in most cases the
197 +.Pp
198 +.Dl screen.rotate=90
199 +.Pp
200 +.Xr loader.conf 5
201 +setting, which will work with and without KMS, is more appropriate.
202 .Sh SEE ALSO
203 .Xr kbdcontrol 1 ,
204 .Xr login 1 ,
205 diff --git a/stand/common/gfx_fb.c b/stand/common/gfx_fb.c
206 index 27ac66f259b1..00e7b77b532c 100644
207 --- a/stand/common/gfx_fb.c
208 +++ b/stand/common/gfx_fb.c
209 @@ -771,6 +771,282 @@ gfxfb_shadow_fill(uint32_t *BltBuffer,
210 }
211 }
212
213 +#if defined(EFI)
214 +/*
215 + * Rotate a UEFI Blt buffer of pixels by the specified angle (0,90,180,270) clockwise.
216 + * Returns NULL if no rotation is performed, or a pointer to a static buffer
217 + * containing the rotated data.
218 + * We build the rotated buffer with Delta = 0 since there's no way to know what
219 + * it should be if the rotation is 90 or 270 degrees.
220 + */
221 +static EFI_GRAPHICS_OUTPUT_BLT_PIXEL *
222 +RotateBuffer(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *inbuf,
223 + UINTN angle, UINTN SourceX, UINTN SourceY,
224 + UINTN Width, UINTN Height,
225 + UINTN Delta)
226 +{
227 + EFI_GRAPHICS_OUTPUT *gop = gfx_state.tg_private;
228 + UINTN srcWidth, destOffset, srcOffset;
229 + static EFI_GRAPHICS_OUTPUT_BLT_PIXEL *outbuf = NULL;
230 +
231 + if (angle != 90 && angle != 180 && angle != 270)
232 + return NULL;
233 +
234 + if (outbuf == NULL &&
235 + (outbuf = malloc(gop->Mode->Info->VerticalResolution *
236 + gop->Mode->Info->HorizontalResolution *
237 + sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) == NULL)
238 + return NULL;
239 +
240 + srcWidth = Width;
241 + if (Delta != 0)
242 + srcWidth = Delta;
243 +
244 + /* Check for out-of-bounds access. */
245 + if (srcWidth < SourceX + Width ||
246 + srcWidth > gop->Mode->Info->HorizontalResolution ||
247 + SourceX + Width > gop->Mode->Info->HorizontalResolution ||
248 + SourceY + Height > gop->Mode->Info->VerticalResolution)
249 + return NULL;
250 +
251 + for (UINTN y = 0; y < Height; y++) {
252 + for (UINTN x = 0; x < Width; x++) {
253 + srcOffset = (SourceX + x) + (SourceY + y) * srcWidth;
254 + switch ((int)angle) {
255 + case 0: /* For reference */
256 + destOffset = (SourceX + x) + (SourceY + y) * Width;
257 + break;
258 + case 90:
259 + destOffset = (SourceY + ((Height - 1) - y)) +
260 + (SourceX + x) * Height;
261 + break;
262 + case 180:
263 + destOffset = (SourceX + ((Width - 1) - x)) +
264 + (SourceY + ((Height - 1) - y)) * Width;
265 + break;
266 + case 270:
267 + destOffset = (SourceY + y) +
268 + (SourceX + ((Width - 1) - x)) * Height;
269 + break;
270 + }
271 + outbuf[destOffset] = inbuf[srcOffset];
272 + }
273 + }
274 + return (outbuf);
275 +}
276 +
277 +/* Macros to facilitate rotation. */
278 +#define SWITCH_VALIDATE
279 +#ifdef SWITCH_VALIDATE
280 +#define SWITCH(DIR, AXIS, ORIENT, EXTENT) \
281 + if (Panel##DIR##AXIS + Rotated##EXTENT > \
282 + gop->Mode->Info->ORIENT##Resolution - 1) \
283 + Panel##DIR##AXIS = 0; \
284 + else \
285 + Panel##DIR##AXIS = (gop->Mode->Info->ORIENT##Resolution - 1) - \
286 + (Panel##DIR##AXIS + Rotated##EXTENT)
287 +#define NO_SWITCH(DIR, AXIS, ORIENTATION) \
288 + if (Panel##DIR##AXIS > gop->Mode->Info->ORIENTATION##Resolution - 1) \
289 + Panel##DIR##AXIS = gop->Mode->Info->ORIENTATION##Resolution - 1
290 +#else
291 +#define SWITCH(DIR, AXIS, ORIENT, EXTENT) \
292 + Panel##DIR##AXIS = (gop->Mode->Info->ORIENT##Resolution - 1) - \
293 + (Panel##DIR##AXIS + Rotated##EXTENT)
294 +#define NO_SWITCH(DIR, AXIS, ORIENTATION)
295 +#endif
296 +#define SWITCH_SRC_X SWITCH(Src, X, Horizontal, Width)
297 +#define SWITCH_DST_X SWITCH(Dst, X, Horizontal, Width)
298 +#define SWITCH_SRC_Y SWITCH(Src, Y, Vertical, Height)
299 +#define SWITCH_DST_Y SWITCH(Dst, Y, Vertical, Height)
300 +#define NO_SWITCH_SRC_X NO_SWITCH(Src, X, Horizontal)
301 +#define NO_SWITCH_DST_X NO_SWITCH(Dst, X, Horizontal)
302 +#define NO_SWITCH_SRC_Y NO_SWITCH(Src, Y, Vertical)
303 +#define NO_SWITCH_DST_Y NO_SWITCH(Dst, Y, Vertical)
304 +
305 +/*
306 + * Perhaps better implemented as a separate UEFI gop layer (c.f.
307 + * https://github.com/apop2/GopRotate), this rotation layer resides in the
308 + * loader itself, above the UEFI, and will rotate gop->Blt() requests by the
309 + * specified angle. It is more complex than a simple rotation because the
310 + * gop->Blt interface is complex; using the gop direct bitmap interface would be
311 + * simpler but would require more changes to the loader graphics code.
312 + */
313 +EFI_STATUS
314 +BltRot(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
315 + EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
316 + UINTN SourceX, UINTN SourceY,
317 + UINTN DestinationX, UINTN DestinationY,
318 + UINTN Width, UINTN Height,
319 + UINTN Delta)
320 +{
321 + EFI_STATUS status;
322 + EFI_GRAPHICS_OUTPUT *gop = gfx_state.tg_private;
323 + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *PanelBuffer, *unrotatedBuffer;
324 + static EFI_GRAPHICS_OUTPUT_BLT_PIXEL *transformBuffer = NULL;
325 + UINTN PanelSrcX, PanelSrcY, PanelDstX, PanelDstY, RotatedWidth, RotatedHeight;
326 + UINTN destWidth;
327 +
328 + /*
329 + * Translate logical:
330 + * BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height
331 + * to physical:
332 + * PanelBuffer, PanelSrcX, PanelSrcY, PanelDstX, PanelDstY, RotatedWidth,
333 + * RotatedHeight
334 + * corresponding to the display hardware.
335 + *
336 + * Typically DestinationX = 0, DestinationY= 0 will correspond to the upper left
337 + * pixel of the display in its mounted orientation, whereas PanelDstX = 0,
338 + * PanelDstY = 0 will correspond to the hardware panel 0,0 coordinate.
339 + */
340 + PanelSrcX = SourceX, PanelSrcY = SourceY;
341 + PanelDstX = DestinationX, PanelDstY = DestinationY;
342 + RotatedWidth = Width, RotatedHeight = Height;
343 + PanelBuffer = BltBuffer;
344 +
345 + switch (BltOperation) {
346 + /*
347 + * Not only do we need to rotate the coordinates, we also need to rotate
348 + * the origin of the BltBuffer transfer box (which itself must be
349 + * rotated).
350 + */
351 + case EfiBltBufferToVideo:
352 + if (rotation == 0 ||
353 + (PanelBuffer = RotateBuffer(BltBuffer, rotation, SourceX, SourceY,
354 + Width, Height, Delta)) == NULL) {
355 + PanelBuffer = BltBuffer;
356 + break;
357 + }
358 + Delta = 0; /* PanelBuffer is built with no delta */
359 + /* Fallthrough */
360 +
361 + /* Rotate the coordinates to the panel coordinates. */
362 + case EfiBltVideoFill:
363 + if (rotation == 90 || rotation == 270) {
364 + PanelDstX = DestinationY, PanelDstY = DestinationX;
365 + RotatedWidth = Height, RotatedHeight = Width;
366 + }
367 + switch (rotation) {
368 + case 0:
369 + break;
370 + case 90:
371 + SWITCH_DST_X;
372 + NO_SWITCH_DST_Y;
373 + break;
374 + case 180:
375 + SWITCH_DST_X;
376 + SWITCH_DST_Y;
377 + break;
378 + case 270:
379 + NO_SWITCH_DST_X;
380 + SWITCH_DST_Y;
381 + break;
382 + }
383 + break;
384 +
385 + /* Rotate the coordinates to and from the panel coordinates. */
386 + case EfiBltVideoToVideo:
387 + if (rotation == 90 || rotation == 270) {
388 + PanelSrcX = SourceY, PanelSrcY = SourceX;
389 + PanelDstX = DestinationY, PanelDstY = DestinationX;
390 + RotatedWidth = Height, RotatedHeight = Width;
391 + }
392 + switch (rotation) {
393 + case 90:
394 + SWITCH_SRC_X;
395 + SWITCH_DST_X;
396 + NO_SWITCH_SRC_Y;
397 + NO_SWITCH_DST_Y;
398 + break;
399 + case 180:
400 + SWITCH_SRC_X;
401 + SWITCH_DST_X;
402 + SWITCH_SRC_Y;
403 + SWITCH_DST_Y;
404 + break;
405 + case 270:
406 + NO_SWITCH_SRC_X;
407 + NO_SWITCH_DST_X;
408 + SWITCH_SRC_Y;
409 + SWITCH_DST_Y;
410 + break;
411 + }
412 + break;
413 +
414 + /* Rotate the coordinates from the panel coordinates. */
415 + case EfiBltVideoToBltBuffer:
416 + if (rotation == 0 ||
417 + (transformBuffer == NULL &&
418 + (transformBuffer = malloc(gop->Mode->Info->HorizontalResolution *
419 + gop->Mode->Info->VerticalResolution *
420 + sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) == NULL))
421 + break;
422 +
423 + PanelBuffer = transformBuffer;
424 + if (rotation == 90 || rotation == 270) {
425 + PanelSrcX = SourceY, PanelSrcY = SourceX;
426 + RotatedWidth = Height, RotatedHeight = Width;
427 + }
428 + switch (rotation) {
429 + case 90:
430 + SWITCH_SRC_X;
431 + NO_SWITCH_SRC_Y;
432 + break;
433 + case 180:
434 + SWITCH_SRC_X;
435 + SWITCH_SRC_Y;
436 + break;
437 + case 270:
438 + NO_SWITCH_SRC_X;
439 + SWITCH_SRC_Y;
440 + break;
441 + }
442 + break;
443 + }
444 +
445 + status = gop->Blt(gop, PanelBuffer, BltOperation,
446 + PanelSrcX, PanelSrcY, PanelDstX, PanelDstY,
447 + RotatedWidth, RotatedHeight, Delta);
448 + if (EFI_ERROR(status))
449 + return (status);
450 +
451 + /* Unless we need to unrotate and merge data into BltBuffer, we are done. */
452 + if (BltOperation != EfiBltVideoToBltBuffer || PanelBuffer == BltBuffer)
453 + return (status);
454 +
455 + /*
456 + * Until this point, on rotation failure we simply pass the data
457 + * unrotated. From here on, we return an error (which will likely cause
458 + * loader failure).
459 + */
460 + unrotatedBuffer = RotateBuffer(PanelBuffer, 360 - rotation,
461 + DestinationX, DestinationY, Width, Height, Delta);
462 + if (unrotatedBuffer == NULL)
463 + return (EFI_OUT_OF_RESOURCES);
464 +
465 + /*
466 + * It is not obvious what the correct reconstruction of a non-zero delta
467 + * should be. This is likely to work correctly.
468 + */
469 + destWidth = Width;
470 + if (Delta != 0)
471 + destWidth = Delta;
472 +
473 + /* Check for out-of-bounds access. */
474 + if (destWidth < DestinationX + Width ||
475 + destWidth > gop->Mode->Info->HorizontalResolution ||
476 + DestinationX + Width > gop->Mode->Info->HorizontalResolution ||
477 + DestinationY + Height > gop->Mode->Info->VerticalResolution)
478 + return (EFI_INVALID_PARAMETER);
479 +
480 + for (UINTN y = DestinationY; y < DestinationY + Height; y++) {
481 + for (UINTN x = DestinationX; x < DestinationX + Width; x++) {
482 + BltBuffer[x + y * destWidth] = unrotatedBuffer[x + y * Width];
483 + }
484 + }
485 + return (status);
486 +}
487 +#endif
488 +
489 int
490 gfxfb_blt(void *BltBuffer, GFXFB_BLT_OPERATION BltOperation,
491 uint32_t SourceX, uint32_t SourceY,
492 @@ -794,28 +1070,26 @@ gfxfb_blt(void *BltBuffer, GFXFB_BLT_OPERATION BltOperation,
493 tpl = BS->RaiseTPL(TPL_NOTIFY);
494 switch (BltOperation) {
495 case GfxFbBltVideoFill:
496 - gfxfb_shadow_fill(BltBuffer, DestinationX,
497 - DestinationY, Width, Height);
498 - status = gop->Blt(gop, BltBuffer, EfiBltVideoFill,
499 + status = BltRot(BltBuffer, EfiBltVideoFill,
500 SourceX, SourceY, DestinationX, DestinationY,
501 Width, Height, Delta);
502 break;
503
504 case GfxFbBltVideoToBltBuffer:
505 - status = gop->Blt(gop, BltBuffer,
506 + status = BltRot(BltBuffer,
507 EfiBltVideoToBltBuffer,
508 SourceX, SourceY, DestinationX, DestinationY,
509 Width, Height, Delta);
510 break;
511
512 case GfxFbBltBufferToVideo:
513 - status = gop->Blt(gop, BltBuffer, EfiBltBufferToVideo,
514 + status = BltRot(BltBuffer, EfiBltBufferToVideo,
515 SourceX, SourceY, DestinationX, DestinationY,
516 Width, Height, Delta);
517 break;
518
519 case GfxFbBltVideoToVideo:
520 - status = gop->Blt(gop, BltBuffer, EfiBltVideoToVideo,
521 + status = BltRot(BltBuffer, EfiBltVideoToVideo,
522 SourceX, SourceY, DestinationX, DestinationY,
523 Width, Height, Delta);
524 break;
525 diff --git a/stand/common/gfx_fb.h b/stand/common/gfx_fb.h
526 index adb60c673ea9..50bfe0748f8d 100644
527 --- a/stand/common/gfx_fb.h
528 +++ b/stand/common/gfx_fb.h
529 @@ -257,6 +257,9 @@ struct text_pixel {
530
531 extern const int cons_to_vga_colors[NCOLORS];
532
533 +/* Set by freebsd-LoaderRotate UEFI variable, determines rotation of framebuffer. */
534 +extern uint32_t rotation;
535 +
536 /* Screen buffer to track changes on the terminal screen. */
537 extern struct text_pixel *screen_buffer;
538 bool is_same_pixel(struct text_pixel *, struct text_pixel *);
539 diff --git a/stand/defaults/loader.conf.5 b/stand/defaults/loader.conf.5
540 index bb40df0333cf..7c82dbd3c7f1 100644
541 --- a/stand/defaults/loader.conf.5
542 +++ b/stand/defaults/loader.conf.5
543 @@ -306,6 +306,16 @@ If EDID is not available, the default resolution is 800x600 (if available).
544 .Va screen.width ,
545 .Va screen.depth
546 are set by loader when loader is using framebuffer mode to draw the screen.
547 +.It Va screen.rotate
548 +Sets the rotation of the framebuffer console to 0, 90, 180, or 270 degrees clockwise.
549 +If KMS is present, the rotation may be performed in hardware,
550 +and an additional value, "AUTO", is supported which will often detect the
551 +correct rotation.
552 +.Pp
553 +This option will also rotate the screen of the EFI boot loader; because the rotation
554 +setting for the EFI loader is stored in the EFI itself during shutdown based upon the
555 +value present in the current kernel environment,
556 +it will take a second reboot to pass a change to the loader.
557 .It Va efi_max_resolution
558 .It Va vbe_max_resolution
559 Specify the maximum desired resolution for the EFI or VBE framebuffer console.
560 diff --git a/stand/efi/libefi/env.c b/stand/efi/libefi/env.c
561 index 6887038fe950..a495580de17d 100644
562 --- a/stand/efi/libefi/env.c
563 +++ b/stand/efi/libefi/env.c
564 @@ -467,7 +467,7 @@ efi_print_mem_type(const CHAR16 *varnamearg __unused, uint8_t *data,
565
566 /*
567 * Print FreeBSD variables.
568 - * We have LoaderPath and LoaderDev as CHAR16 strings.
569 + * We have LoaderRotate, LoaderPath and LoaderDev as CHAR16 strings.
570 */
571 static int
572 efi_print_freebsd(const CHAR16 *varnamearg, uint8_t *data,
573 @@ -479,7 +479,8 @@ efi_print_freebsd(const CHAR16 *varnamearg, uint8_t *data,
574 if (ucs2_to_utf8(varnamearg, &var) != 0)
575 return (CMD_ERROR);
576
577 - if (strcmp("LoaderPath", var) == 0 ||
578 + if (strcmp("LoaderRotate", var) == 0 ||
579 + strcmp("LoaderPath", var) == 0 ||
580 strcmp("LoaderDev", var) == 0) {
581 printf(" = ");
582 printf("%S", (CHAR16 *)data);
583 diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c
584 index 1f3664b50948..df004d8808f2 100644
585 --- a/stand/efi/loader/bootinfo.c
586 +++ b/stand/efi/loader/bootinfo.c
587 @@ -184,8 +184,17 @@ bi_load_efi_data(struct preloaded_file *kfp, bool exit_bs)
588
589 efifb.fb_addr = gfx_state.tg_fb.fb_addr;
590 efifb.fb_size = gfx_state.tg_fb.fb_size;
591 - efifb.fb_height = gfx_state.tg_fb.fb_height;
592 - efifb.fb_width = gfx_state.tg_fb.fb_width;
593 + /*
594 + * If we have rotated the framebuffer height and width, rotate them back
595 + * before passing them to the kernel
596 + */
597 + if (rotation == 90 || rotation == 270) {
598 + efifb.fb_height = gfx_state.tg_fb.fb_width;
599 + efifb.fb_width = gfx_state.tg_fb.fb_height;
600 + } else {
601 + efifb.fb_height = gfx_state.tg_fb.fb_height;
602 + efifb.fb_width = gfx_state.tg_fb.fb_width;
603 + }
604 efifb.fb_stride = gfx_state.tg_fb.fb_stride;
605 efifb.fb_mask_red = gfx_state.tg_fb.fb_mask_red;
606 efifb.fb_mask_green = gfx_state.tg_fb.fb_mask_green;
607 @@ -327,6 +336,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs)
608 vm_offset_t size;
609 char *rootdevname;
610 int howto;
611 + char *autorotate, strbuf[4];
612 bool is64 = sizeof(long) == 8;
613 #if defined(LOADER_FDT_SUPPORT)
614 vm_offset_t dtbp;
615 @@ -349,6 +359,17 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs)
616 #endif
617 howto = bi_getboothowto(args);
618
619 + /*
620 + * If screen.rotate="AUTO", pass the current rotation to the kernel to
621 + * use until the autodetection completes.
622 + */
623 + if (rotation != 0 &&
624 + (autorotate = getenv("screen.rotate")) != NULL &&
625 + strncasecmp(autorotate, "auto", 5) == 0) {
626 + snprintf(strbuf, sizeof(strbuf), "%d", rotation);
627 + setenv("screen.autorotate", strbuf, 1);
628 + }
629 +
630 /*
631 * Allow the environment variable 'rootdev' to override the supplied
632 * device. This should perhaps go to MI code and/or have $rootdev
633 diff --git a/stand/efi/loader/framebuffer.c b/stand/efi/loader/framebuffer.c
634 index 56693187b576..6be3d384e741 100644
635 --- a/stand/efi/loader/framebuffer.c
636 +++ b/stand/efi/loader/framebuffer.c
637 @@ -40,7 +40,9 @@
638 #include <machine/metadata.h>
639
640 #include "bootstrap.h"
641 +#include "efichar.h"
642 #include "framebuffer.h"
643 +#include "gfx_fb.h"
644
645 static EFI_GUID conout_guid = EFI_CONSOLE_OUT_DEVICE_GUID;
646 EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
647 @@ -53,6 +55,9 @@ static EFI_HANDLE gop_handle;
648 /* Cached EDID. */
649 struct vesa_edid_info *edid_info = NULL;
650
651 +/* Angle to rotate boot console display. */
652 +uint32_t rotation = 0;
653 +
654 static EFI_GRAPHICS_OUTPUT *gop;
655 static EFI_UGA_DRAW_PROTOCOL *uga;
656
657 @@ -149,11 +154,42 @@ efifb_from_gop(struct efi_fb *efifb, EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *mode,
658 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info)
659 {
660 int result;
661 + size_t len = 0;
662 + efi_char *buf;
663 + char *angle = NULL;
664 + EFI_STATUS rv;
665 +
666 + /*
667 + * Use the UEFI variable freebsd-LoaderRotate to rotate the framebuffer
668 + * to match the panel orientation. We use a UEFI variable because
669 + * the framebuffer is set up very early in the boot process, before
670 + * loader variables (even the early /boot/efi/EFI/FreeBSD/loader.env
671 + * variables) are set up.
672 + *
673 + * It is intended that an rc.d script shall use the screen.rotate loader
674 + * variable to update freebsd-LoaderRotate for the next boot.
675 + */
676 + if (efi_freebsd_getenv("LoaderRotate", NULL, &len) == EFI_BUFFER_TOO_SMALL)
677 + if ((buf = calloc(len + 1, sizeof(efi_char)))) {
678 + if (efi_freebsd_getenv("LoaderRotate", buf, &len) == EFI_SUCCESS)
679 + if (ucs2_to_utf8(buf, &angle) == 0) {
680 + rotation = strtol(angle, NULL, 0);
681 + free(angle);
682 + }
683 + free(buf);
684 + }
685 + if (rotation != 90 && rotation != 180 && rotation != 270)
686 + rotation = 0;
687
688 efifb->fb_addr = mode->FrameBufferBase;
689 efifb->fb_size = mode->FrameBufferSize;
690 - efifb->fb_height = info->VerticalResolution;
691 - efifb->fb_width = info->HorizontalResolution;
692 + if (rotation == 90 || rotation == 270) {
693 + efifb->fb_width = info->VerticalResolution;
694 + efifb->fb_height = info->HorizontalResolution;
695 + } else {
696 + efifb->fb_height = info->VerticalResolution;
697 + efifb->fb_width = info->HorizontalResolution;
698 + }
699 efifb->fb_stride = info->PixelsPerScanLine;
700 result = efifb_mask_from_pixfmt(efifb, info->PixelFormat,
701 &info->PixelInformation);
702 diff --git a/stand/lua/config.lua b/stand/lua/config.lua
703 index 2f22056efde2..b235553b061e 100644
704 --- a/stand/lua/config.lua
705 +++ b/stand/lua/config.lua
706 @@ -64,7 +64,7 @@ local MSG_FAILSYN_BADVAR = "Malformed variable expression at position '%d'"
707 -- env_var entries in the pattern table. This is perhaps a good target for a
708 -- little refactoring.
709 local MODULEEXPR = '([%w%d-_.]+)'
710 -local QVALEXPR = '"(.*)"'
711 +local QVALEXPR = '"([^"]*)"'
712 local QVALREPL = QVALEXPR:gsub('%%', '%%%%')
713 local WORDEXPR = "([-%w%d][-%w%d_.]*)"
714 local WORDREPL = WORDEXPR:gsub('%%', '%%%%')
715 diff --git a/sys/dev/acpica/acpi_thermal.c b/sys/dev/acpica/acpi_thermal.c
716 index c436390d84b4..fb7a478fd479 100644
717 --- a/sys/dev/acpica/acpi_thermal.c
718 +++ b/sys/dev/acpica/acpi_thermal.c
719 @@ -58,7 +58,7 @@ ACPI_MODULE_NAME("THERMAL")
720 #define TZ_NOTIFY_TEMPERATURE 0x80 /* Temperature changed. */
721 #define TZ_NOTIFY_LEVELS 0x81 /* Cooling levels changed. */
722 #define TZ_NOTIFY_DEVICES 0x82 /* Device lists changed. */
723 -#define TZ_NOTIFY_CRITICAL 0xcc /* Fake notify that _CRT/_HOT reached. */
724 +#define TZ_NOTIFY_CRITICAL 0xcc /* Fake notify that _CRT/_HOT/_CR3 reached. */
725
726 /* Check for temperature changes every 10 seconds by default */
727 #define TZ_POLLRATE 10
728 @@ -76,6 +76,7 @@ struct acpi_tz_zone {
729 ACPI_BUFFER al[TZ_NUMLEVELS];
730 int crt;
731 int hot;
732 + int cr3;
733 ACPI_BUFFER psl;
734 int psv;
735 int tc1;
736 @@ -95,8 +96,9 @@ struct acpi_tz_softc {
737 int tz_thflags; /*Current temp-related flags*/
738 #define TZ_THFLAG_NONE 0
739 #define TZ_THFLAG_PSV (1<<0)
740 -#define TZ_THFLAG_HOT (1<<2)
741 -#define TZ_THFLAG_CRT (1<<3)
742 +#define TZ_THFLAG_CR3 (1<<2)
743 +#define TZ_THFLAG_HOT (1<<3)
744 +#define TZ_THFLAG_CRT (1<<4)
745 int tz_flags;
746 #define TZ_FLAG_NO_SCP (1<<0) /*No _SCP method*/
747 #define TZ_FLAG_GETPROFILE (1<<1) /*Get power_profile in timeout*/
748 @@ -280,6 +282,10 @@ acpi_tz_attach(device_t dev)
749 OID_AUTO, "_PSV", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
750 offsetof(struct acpi_tz_softc, tz_zone.psv), acpi_tz_temp_sysctl, "IK",
751 "passive cooling temp setpoint");
752 + SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
753 + OID_AUTO, "_CR3", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
754 + offsetof(struct acpi_tz_softc, tz_zone.cr3), acpi_tz_temp_sysctl, "IK",
755 + "too warm temp setpoint (standby now)");
756 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
757 OID_AUTO, "_HOT", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
758 offsetof(struct acpi_tz_softc, tz_zone.hot), acpi_tz_temp_sysctl, "IK",
759 @@ -419,6 +425,7 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
760 }
761 acpi_tz_getparam(sc, "_CRT", &sc->tz_zone.crt);
762 acpi_tz_getparam(sc, "_HOT", &sc->tz_zone.hot);
763 + acpi_tz_getparam(sc, "_CR3", &sc->tz_zone.cr3);
764 sc->tz_zone.psl.Length = ACPI_ALLOCATE_BUFFER;
765 sc->tz_zone.psl.Pointer = NULL;
766 AcpiEvaluateObject(sc->tz_handle, "_PSL", NULL, &sc->tz_zone.psl);
767 @@ -436,6 +443,7 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
768 */
769 acpi_tz_sanity(sc, &sc->tz_zone.crt, "_CRT");
770 acpi_tz_sanity(sc, &sc->tz_zone.hot, "_HOT");
771 + acpi_tz_sanity(sc, &sc->tz_zone.cr3, "_CR3");
772 acpi_tz_sanity(sc, &sc->tz_zone.psv, "_PSV");
773 for (i = 0; i < TZ_NUMLEVELS; i++)
774 acpi_tz_sanity(sc, &sc->tz_zone.ac[i], "_ACx");
775 @@ -493,6 +501,7 @@ acpi_tz_get_temperature(struct acpi_tz_softc *sc)
776 static void
777 acpi_tz_monitor(void *Context)
778 {
779 + struct acpi_softc *acpi_sc;
780 struct acpi_tz_softc *sc;
781 struct timespec curtime;
782 int temp;
783 @@ -543,6 +552,8 @@ acpi_tz_monitor(void *Context)
784 newflags = TZ_THFLAG_NONE;
785 if (sc->tz_zone.psv != -1 && temp >= sc->tz_zone.psv)
786 newflags |= TZ_THFLAG_PSV;
787 + if (sc->tz_zone.cr3 != -1 && temp >= sc->tz_zone.cr3)
788 + newflags |= TZ_THFLAG_CR3;
789 if (sc->tz_zone.hot != -1 && temp >= sc->tz_zone.hot)
790 newflags |= TZ_THFLAG_HOT;
791 if (sc->tz_zone.crt != -1 && temp >= sc->tz_zone.crt)
792 @@ -593,7 +604,7 @@ acpi_tz_monitor(void *Context)
793 /* XXX (de)activate any passive cooling that may be required. */
794
795 /*
796 - * If the temperature is at _HOT or _CRT, increment our event count.
797 + * If the temperature is at _CR3, _HOT or _CRT, increment our event count.
798 * If it has occurred enough times, shutdown the system. This is
799 * needed because some systems will report an invalid high temperature
800 * for one poll cycle. It is suspected this is due to the embedded
801 @@ -602,13 +613,18 @@ acpi_tz_monitor(void *Context)
802 *
803 * If we're almost at that threshold, notify the user through devd(8).
804 */
805 - if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0) {
806 + if ((newflags & (TZ_THFLAG_CR3 | TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0) {
807 sc->tz_validchecks++;
808 if (sc->tz_validchecks == TZ_VALIDCHECKS) {
809 device_printf(sc->tz_dev,
810 "WARNING - current temperature (%d.%dC) exceeds safe limits\n",
811 TZ_KELVTOC(sc->tz_temperature));
812 - shutdown_nice(RB_POWEROFF);
813 + if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0)
814 + shutdown_nice(RB_POWEROFF);
815 + else {
816 + acpi_sc = acpi_device_get_parent_softc(sc->tz_dev);
817 + acpi_ReqSleepState(acpi_sc, ACPI_STATE_S3);
818 + }
819 } else if (sc->tz_validchecks == TZ_NOTIFYCOUNT)
820 acpi_UserNotify("Thermal", sc->tz_handle, TZ_NOTIFY_CRITICAL);
821 } else {
822 @@ -1004,51 +1020,68 @@ acpi_tz_thread(void *arg)
823 static int
824 acpi_tz_cpufreq_restore(struct acpi_tz_softc *sc)
825 {
826 - device_t dev;
827 - int error;
828 + device_t *devs;
829 + int devcount, error, n;
830
831 if (!sc->tz_cooling_updated)
832 return (0);
833 - if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL)
834 +
835 + if ((error = devclass_get_devices(devclass_find("cpufreq"), &devs, &devcount))) {
836 + free(devs, M_TEMP);
837 return (ENXIO);
838 + }
839 +
840 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
841 "temperature %d.%dC: resuming previous clock speed (%d MHz)\n",
842 TZ_KELVTOC(sc->tz_temperature), sc->tz_cooling_saved_freq);
843 - error = CPUFREQ_SET(dev, NULL, CPUFREQ_PRIO_KERN);
844 + for (n = 0; n < devcount; n++) {
845 + if ((error = CPUFREQ_SET(devs[n], NULL, CPUFREQ_PRIO_KERN))) {
846 + /*
847 + * If you find yourself here: cf_set_method() in kern_cpu.c
848 + * requires CPUFREQ_GET() be run before CPUFREQ_SET(), otherwise on
849 + * a restore sc->curr_level.total_set.freq = CPUFREQ_VAL_UNKNOWN,
850 + * and then if it hasn't been updated the next save/restore will fail.
851 + */
852 + device_printf(sc->tz_dev, "cpu%d: failed to restore cpufreq priority\n", n);
853 + break;
854 + }
855 + }
856 if (error == 0)
857 sc->tz_cooling_updated = FALSE;
858 +
859 + free(devs, M_TEMP);
860 return (error);
861 }
862
863 static int
864 acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req)
865 {
866 - device_t dev;
867 + device_t *devs;
868 struct cf_level *levels;
869 - int num_levels, error, freq, desired_freq, perf, i;
870 + int num_levels, error, freq, desired_freq, perf, devcount, i, n;
871
872 levels = malloc(CPUFREQ_MAX_LEVELS * sizeof(*levels), M_TEMP, M_NOWAIT);
873 if (levels == NULL)
874 return (ENOMEM);
875
876 /*
877 - * Find the main device, cpufreq0. We don't yet support independent
878 - * CPU frequency control on SMP.
879 + * Find the main device, cpufreq0. We make plans based upon cpu0, and
880 + * change all the cpu frequencies to the same level.
881 */
882 - if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL) {
883 - error = ENXIO;
884 + if ((error = devclass_get_devices(devclass_find("cpufreq"), &devs, &devcount))) {
885 + free(devs, M_TEMP);
886 goto out;
887 }
888
889 - /* Get the current frequency. */
890 - error = CPUFREQ_GET(dev, &levels[0]);
891 + /* Get the current frequency for cpu0. */
892 + error = CPUFREQ_GET(devs[0], &levels[0]);
893 if (error)
894 goto out;
895 freq = levels[0].total_set.freq;
896
897 - /* Get the current available frequency levels. */
898 + /* Get the current available frequency levels for cpu0. */
899 num_levels = CPUFREQ_MAX_LEVELS;
900 - error = CPUFREQ_LEVELS(dev, levels, &num_levels);
901 + error = CPUFREQ_LEVELS(devs[0], levels, &num_levels);
902 if (error) {
903 if (error == E2BIG)
904 printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n");
905 @@ -1109,8 +1142,22 @@ acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req)
906 TZ_KELVTOC(sc->tz_temperature),
907 (freq > levels[i].total_set.freq) ? "de" : "in",
908 freq, levels[i].total_set.freq);
909 - error = CPUFREQ_SET(dev, &levels[i], CPUFREQ_PRIO_KERN);
910 - if (error == 0 && !sc->tz_cooling_updated) {
911 +
912 + /* Change all the cpus to the chosen frequency. */
913 + for (n = 0; n < devcount; n++) {
914 + /* CPUFREQ_SET() fails occasionally without this. */
915 + if ((error = CPUFREQ_GET(devs[n], &levels[0])))
916 + goto out;
917 +
918 + if ((error = CPUFREQ_LEVELS(devs[n], levels, &num_levels))) {
919 + if (error == E2BIG)
920 + printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n");
921 + goto out;
922 + }
923 + if ((error = CPUFREQ_SET(devs[n], &levels[i], CPUFREQ_PRIO_KERN)))
924 + goto out;
925 + }
926 + if (!sc->tz_cooling_updated) {
927 sc->tz_cooling_saved_freq = freq;
928 sc->tz_cooling_updated = TRUE;
929 }
930 @@ -1119,6 +1166,7 @@ acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req)
931 out:
932 if (levels)
933 free(levels, M_TEMP);
934 + free(devs, M_TEMP);
935 return (error);
936 }
937
938 diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c
939 index 4eac1b546b4d..88c95ad04ef5 100644
940 --- a/sys/dev/usb/input/ukbd.c
941 +++ b/sys/dev/usb/input/ukbd.c
942 @@ -962,7 +962,8 @@ ukbd_probe(device_t dev)
943 return (ENXIO);
944
945 if (hid_is_keyboard(d_ptr, d_len)) {
946 - if (hid_is_mouse(d_ptr, d_len)) {
947 + if (hid_is_mouse(d_ptr, d_len) &&
948 + !usb_test_quirk(uaa, UQ_UMS_IGNORE)) {
949 /*
950 * NOTE: We currently don't support USB mouse
951 * and USB keyboard on the same USB endpoint.
952 diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c
953 index d8dc2e8f19c3..1dbf4446b14f 100644
954 --- a/sys/dev/usb/input/ums.c
955 +++ b/sys/dev/usb/input/ums.c
956 @@ -590,13 +590,15 @@ ums_attach(device_t dev)
957 usb_callout_init_mtx(&sc->sc_callout, &sc->sc_mtx, 0);
958
959 /*
960 - * Force the report (non-boot) protocol.
961 + * Force the report (non-boot) protocol unless
962 + * UQ_MS_NO_SETPROTO is set.
963 *
964 * Mice without boot protocol support may choose not to implement
965 * Set_Protocol at all; Ignore any error.
966 */
967 - err = usbd_req_set_protocol(uaa->device, NULL,
968 - uaa->info.bIfaceIndex, 1);
969 + if (!usb_test_quirk(uaa, UQ_MS_NO_SETPROTO))
970 + err = usbd_req_set_protocol(uaa->device, NULL,
971 + uaa->info.bIfaceIndex, 1);
972
973 err = usbd_transfer_setup(uaa->device,
974 &uaa->info.bIfaceIndex, sc->sc_xfer, ums_config,
975 diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
976 index 91d47935221f..d3075466dbb3 100644
977 --- a/sys/dev/usb/quirk/usb_quirk.c
978 +++ b/sys/dev/usb/quirk/usb_quirk.c
979 @@ -654,6 +654,7 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
980 [UQ_UMS_IGNORE] = "UQ_UMS_IGNORE",
981 [UQ_MS_BAD_CLASS] = "UQ_MS_BAD_CLASS",
982 [UQ_MS_LEADING_BYTE] = "UQ_MS_LEADING_BYTE",
983 + [UQ_MS_NO_SETPROTO] = "UQ_MS_NO_SETPROTO",
984 [UQ_MS_REVZ] = "UQ_MS_REVZ",
985 [UQ_MS_VENDOR_BTN] = "UQ_MS_VENDOR_BTN",
986 [UQ_NO_STRINGS] = "UQ_NO_STRINGS",
987 diff --git a/sys/dev/usb/quirk/usb_quirk.h b/sys/dev/usb/quirk/usb_quirk.h
988 index 8e8bfd152eb8..e5dd0c950785 100644
989 --- a/sys/dev/usb/quirk/usb_quirk.h
990 +++ b/sys/dev/usb/quirk/usb_quirk.h
991 @@ -53,6 +53,7 @@ enum {
992 UQ_UMS_IGNORE, /* device should be ignored by ums class */
993 UQ_MS_BAD_CLASS, /* doesn't identify properly */
994 UQ_MS_LEADING_BYTE, /* mouse sends an unknown leading byte */
995 + UQ_MS_NO_SETPROTO, /* device should not receive SetProtocol requests */
996 UQ_MS_REVZ, /* mouse has Z-axis reversed */
997 UQ_MS_VENDOR_BTN, /* mouse has buttons in vendor usage page */
998 UQ_NO_STRINGS, /* string descriptors are broken */
999 diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c
1000 index 96c54cfbe6ca..011aa1b3ebc4 100644
1001 --- a/sys/dev/vt/hw/fb/vt_fb.c
1002 +++ b/sys/dev/vt/hw/fb/vt_fb.c
1003 @@ -160,11 +160,22 @@ vt_fb_setpixel(struct vt_device *vd, int x, int y, term_color_t color)
1004 {
1005 struct fb_info *info;
1006 uint32_t c;
1007 - u_int o;
1008 + u_int o, row, col;
1009
1010 info = vd->vd_softc;
1011 c = info->fb_cmap[color];
1012 - o = info->fb_stride * y + x * FBTYPE_GET_BYTESPP(info);
1013 +
1014 + /* Rotations */
1015 + if (info->fb_flags & FB_FLAG_ROTATE_90)
1016 + row = x, col = y;
1017 + else
1018 + row = y, col = x;
1019 + if (info->fb_flags & FB_FLAG_ROTATE_180)
1020 + row = (info->fb_height - 1) - row;
1021 + if (!(info->fb_flags & FB_FLAG_ROTATE_90) !=
1022 + !(info->fb_flags & FB_FLAG_ROTATE_180))
1023 + col = (info->fb_width - 1) - col;
1024 + o = info->fb_stride * row + col * FBTYPE_GET_BYTESPP(info);
1025
1026 if (info->fb_flags & FB_FLAG_NOWRITE)
1027 return;
1028 @@ -264,7 +275,7 @@ vt_fb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw,
1029 unsigned int x, unsigned int y, term_color_t fg, term_color_t bg)
1030 {
1031 struct fb_info *info;
1032 - uint32_t fgc, bgc, cc, o;
1033 + uint32_t fgc, bgc, cc, o, row, col;
1034 int bpp, bpl, xi, yi;
1035 int bit, byte;
1036
1037 @@ -297,7 +308,18 @@ vt_fb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw,
1038 /* Skip pixel write, if mask bit not set. */
1039 if (mask != NULL && (mask[byte] & bit) == 0)
1040 continue;
1041 - o = (y + yi) * info->fb_stride + (x + xi) * bpp;
1042 +
1043 + /* Rotations */
1044 + if (info->fb_flags & FB_FLAG_ROTATE_90)
1045 + row = x + xi, col = y + yi;
1046 + else
1047 + row = y + yi, col = x + xi;
1048 + if (info->fb_flags & FB_FLAG_ROTATE_180)
1049 + row = (info->fb_height - 1) - row;
1050 + if (!(info->fb_flags & FB_FLAG_ROTATE_90) !=
1051 + !(info->fb_flags & FB_FLAG_ROTATE_180))
1052 + col = (info->fb_width - 1) - col;
1053 + o = row * info->fb_stride + col * bpp;
1054 o += vd->vd_transpose;
1055 cc = pattern[byte] & bit ? fgc : bgc;
1056
1057 @@ -457,15 +479,64 @@ vt_fb_init(struct vt_device *vd)
1058 {
1059 struct fb_info *info;
1060 u_int margin;
1061 - int bg, err;
1062 + int angle = 0, bg, err;
1063 term_color_t c;
1064 + char *rotation, strbuf[4];
1065
1066 info = vd->vd_softc;
1067 - vd->vd_height = MIN(VT_FB_MAX_HEIGHT, info->fb_height);
1068 - margin = (info->fb_height - vd->vd_height) >> 1;
1069 - vd->vd_transpose = margin * info->fb_stride;
1070 - vd->vd_width = MIN(VT_FB_MAX_WIDTH, info->fb_width);
1071 - margin = (info->fb_width - vd->vd_width) >> 1;
1072 +
1073 + /*
1074 + * If we have been passed a rotation, and screen.rotate="AUTO", change
1075 + * screen.rotate to the autodetected rotation for use during the next
1076 + * reboot.
1077 + */
1078 + if (info->fb_flags & FB_FLAG_ROTATE_NODEFAULT) {
1079 + if ((rotation = kern_getenv("screen.rotate")) != NULL &&
1080 + strncasecmp(rotation, "auto", 5) == 0) {
1081 + if (info->fb_flags & FB_FLAG_ROTATE_90)
1082 + angle += 90;
1083 + if (info->fb_flags & FB_FLAG_ROTATE_180)
1084 + angle += 180;
1085 + snprintf(strbuf, sizeof(strbuf), "%d", angle);
1086 + kern_setenv("screen.rotate", strbuf);
1087 + }
1088 + freeenv(rotation);
1089 + }
1090 +
1091 + /* Default angle to rotate console clockwise, in 90 degree increments. */
1092 + if (!(info->fb_flags & FB_FLAG_ROTATE_NODEFAULT)) {
1093 + if ((TUNABLE_INT_FETCH("screen.autorotate", &angle) == 0))
1094 + TUNABLE_INT_FETCH("screen.rotate", &angle);
1095 + info->fb_flags &= ~FB_FLAG_ROTATE_MASK;
1096 + switch (angle) {
1097 + case 270:
1098 + info->fb_flags |= FB_FLAG_ROTATE_270;
1099 + break;
1100 + case 180:
1101 + info->fb_flags |= FB_FLAG_ROTATE_180;
1102 + break;
1103 + case 90:
1104 + info->fb_flags |= FB_FLAG_ROTATE_90;
1105 + break;
1106 + default:
1107 + info->fb_flags |= FB_FLAG_ROTATE_0;
1108 + break;
1109 + }
1110 + }
1111 +
1112 + if (info->fb_flags & FB_FLAG_ROTATE_90) { /* +/-90 degrees rotation */
1113 + vd->vd_height = MIN(VT_FB_MAX_HEIGHT, info->fb_width);
1114 + vd->vd_width = MIN(VT_FB_MAX_WIDTH, info->fb_height);
1115 + margin = (info->fb_height - vd->vd_width) >> 1;
1116 + vd->vd_transpose = margin * info->fb_stride;
1117 + margin = (info->fb_width - vd->vd_height) >> 1;
1118 + } else {
1119 + vd->vd_height = MIN(VT_FB_MAX_HEIGHT, info->fb_height);
1120 + vd->vd_width = MIN(VT_FB_MAX_WIDTH, info->fb_width);
1121 + margin = (info->fb_height - vd->vd_height) >> 1;
1122 + vd->vd_transpose = margin * info->fb_stride;
1123 + margin = (info->fb_width - vd->vd_width) >> 1;
1124 + }
1125 vd->vd_transpose += margin * (info->fb_bpp / NBBY);
1126 vd->vd_video_dev = info->fb_video_dev;
1127
1128 diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c
1129 index a36016680a21..1d3e1dd2e65d 100644
1130 --- a/sys/kern/kern_ntptime.c
1131 +++ b/sys/kern/kern_ntptime.c
1132 @@ -1078,6 +1078,10 @@ static void
1133 start_periodic_resettodr(void *arg __unused)
1134 {
1135
1136 + EVENTHANDLER_REGISTER(power_resume, periodic_resettodr, NULL,
1137 + EVENTHANDLER_PRI_ANY);
1138 + EVENTHANDLER_REGISTER(power_suspend_early, shutdown_resettodr, NULL,
1139 + EVENTHANDLER_PRI_FIRST);
1140 EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_resettodr, NULL,
1141 SHUTDOWN_PRI_FIRST);
1142 callout_init(&resettodr_callout, 1);
1143 diff --git a/sys/sys/fbio.h b/sys/sys/fbio.h
1144 index 9123a2008b7a..d8e3e83d423b 100644
1145 --- a/sys/sys/fbio.h
1146 +++ b/sys/sys/fbio.h
1147 @@ -141,9 +141,15 @@ struct fb_info {
1148 void *fb_priv; /* First argument for read/write. */
1149 const char *fb_name;
1150 uint32_t fb_flags;
1151 -#define FB_FLAG_NOMMAP 1 /* mmap unsupported. */
1152 -#define FB_FLAG_NOWRITE 2 /* disable writes for the time being */
1153 -#define FB_FLAG_MEMATTR 4 /* override memattr for mmap */
1154 +#define FB_FLAG_NOMMAP 0x01 /* mmap unsupported. */
1155 +#define FB_FLAG_NOWRITE 0x02 /* disable writes for the time being */
1156 +#define FB_FLAG_MEMATTR 0x04 /* override memattr for mmap */
1157 +#define FB_FLAG_ROTATE_0 0x00 /* rotate fb 0 degrees clockwise */
1158 +#define FB_FLAG_ROTATE_90 0x08 /* rotate fb 90 degrees clockwise */
1159 +#define FB_FLAG_ROTATE_180 0x10 /* rotate fb 180 degrees clockwise */
1160 +#define FB_FLAG_ROTATE_270 (FB_FLAG_ROTATE_90 | FB_FLAG_ROTATE_180)
1161 +#define FB_FLAG_ROTATE_MASK 0x18
1162 +#define FB_FLAG_ROTATE_NODEFAULT 0x20 /* do not load console defaults */
1163 vm_memattr_t fb_memattr;
1164 int fb_stride;
1165 int fb_bpp; /* bits per pixel */
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.