xref: /illumos-gate/usr/src/lib/fm/topo/modules/common/usb/topo_usb_acpi.c (revision 672fc84a1840ce8ef60fc752e9ea374723d1135a)
1*672fc84aSRobert Mustacchi /*
2*672fc84aSRobert Mustacchi  * Copyright (C) 2000 - 2016, Intel Corp.
3*672fc84aSRobert Mustacchi  * Copyright (c) 2018, Joyent, Inc.
4*672fc84aSRobert Mustacchi  * All rights reserved.
5*672fc84aSRobert Mustacchi  *
6*672fc84aSRobert Mustacchi  * Redistribution and use in source and binary forms, with or without
7*672fc84aSRobert Mustacchi  * modification, are permitted provided that the following conditions
8*672fc84aSRobert Mustacchi  * are met:
9*672fc84aSRobert Mustacchi  * 1. Redistributions of source code must retain the above copyright
10*672fc84aSRobert Mustacchi  *    notice, this list of conditions, and the following disclaimer,
11*672fc84aSRobert Mustacchi  *    without modification.
12*672fc84aSRobert Mustacchi  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
13*672fc84aSRobert Mustacchi  *    substantially similar to the "NO WARRANTY" disclaimer below
14*672fc84aSRobert Mustacchi  *    ("Disclaimer") and any redistribution must be conditioned upon
15*672fc84aSRobert Mustacchi  *    including a substantially similar Disclaimer requirement for further
16*672fc84aSRobert Mustacchi  *    binary redistribution.
17*672fc84aSRobert Mustacchi  * 3. Neither the names of the above-listed copyright holders nor the names
18*672fc84aSRobert Mustacchi  *    of any contributors may be used to endorse or promote products derived
19*672fc84aSRobert Mustacchi  *    from this software without specific prior written permission.
20*672fc84aSRobert Mustacchi  *
21*672fc84aSRobert Mustacchi  * Alternatively, this software may be distributed under the terms of the
22*672fc84aSRobert Mustacchi  * GNU General Public License ("GPL") version 2 as published by the Free
23*672fc84aSRobert Mustacchi  * Software Foundation.
24*672fc84aSRobert Mustacchi  *
25*672fc84aSRobert Mustacchi  * NO WARRANTY
26*672fc84aSRobert Mustacchi  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27*672fc84aSRobert Mustacchi  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28*672fc84aSRobert Mustacchi  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
29*672fc84aSRobert Mustacchi  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30*672fc84aSRobert Mustacchi  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31*672fc84aSRobert Mustacchi  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32*672fc84aSRobert Mustacchi  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33*672fc84aSRobert Mustacchi  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34*672fc84aSRobert Mustacchi  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35*672fc84aSRobert Mustacchi  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36*672fc84aSRobert Mustacchi  * POSSIBILITY OF SUCH DAMAGES.
37*672fc84aSRobert Mustacchi  */
38*672fc84aSRobert Mustacchi 
39*672fc84aSRobert Mustacchi /*
40*672fc84aSRobert Mustacchi  * This allows us to embed the decoding of the _PLD data structure method. While
41*672fc84aSRobert Mustacchi  * this is normally part of the broader ACPI code dump, it has been pulled out
42*672fc84aSRobert Mustacchi  * to simplify the management and required set of ACPI tools. The _PLD is the
43*672fc84aSRobert Mustacchi  * physical location of the device. It is a series of fields that is
44*672fc84aSRobert Mustacchi  * theoretically supposed to tell you information about where a given device is,
45*672fc84aSRobert Mustacchi  * its shape, color, etc. This data is only as good as the firwmare that
46*672fc84aSRobert Mustacchi  * provides it. This is defined in the ACPI specification in section 6.1.8 (ACPI
47*672fc84aSRobert Mustacchi  * 6.2).
48*672fc84aSRobert Mustacchi  */
49*672fc84aSRobert Mustacchi 
50*672fc84aSRobert Mustacchi #include <strings.h>
51*672fc84aSRobert Mustacchi #include "topo_usb_int.h"
52*672fc84aSRobert Mustacchi 
53*672fc84aSRobert Mustacchi boolean_t
usbtopo_decode_pld(uint8_t * buf,size_t len,ACPI_PLD_INFO * infop)54*672fc84aSRobert Mustacchi usbtopo_decode_pld(uint8_t *buf, size_t len, ACPI_PLD_INFO *infop)
55*672fc84aSRobert Mustacchi {
56*672fc84aSRobert Mustacchi 	uint32_t *buf32p;
57*672fc84aSRobert Mustacchi 	size_t i;
58*672fc84aSRobert Mustacchi 
59*672fc84aSRobert Mustacchi 	if (buf == NULL || len < ACPI_PLD_REV1_BUFFER_SIZE)
60*672fc84aSRobert Mustacchi 		return (B_FALSE);
61*672fc84aSRobert Mustacchi 
62*672fc84aSRobert Mustacchi 	/*
63*672fc84aSRobert Mustacchi 	 * Look through the array of bytes that we have. We've found some cases
64*672fc84aSRobert Mustacchi 	 * where we have buffers that are basically all zeros aside from the
65*672fc84aSRobert Mustacchi 	 * revision, which is revision one.
66*672fc84aSRobert Mustacchi 	 */
67*672fc84aSRobert Mustacchi 	for (i = 1; i < len; i++) {
68*672fc84aSRobert Mustacchi 		if (buf[i] != 0)
69*672fc84aSRobert Mustacchi 			break;
70*672fc84aSRobert Mustacchi 	}
71*672fc84aSRobert Mustacchi 	if (i == len && buf[0] == 0x01)
72*672fc84aSRobert Mustacchi 		return (B_FALSE);
73*672fc84aSRobert Mustacchi 
74*672fc84aSRobert Mustacchi 	buf32p = (uint32_t *)buf;
75*672fc84aSRobert Mustacchi 	bzero(infop, sizeof (*infop));
76*672fc84aSRobert Mustacchi 
77*672fc84aSRobert Mustacchi 	/* First 32-bit DWord */
78*672fc84aSRobert Mustacchi 	infop->Revision = ACPI_PLD_GET_REVISION(&buf32p[0]);
79*672fc84aSRobert Mustacchi 	infop->IgnoreColor = ACPI_PLD_GET_IGNORE_COLOR(&buf32p[0]);
80*672fc84aSRobert Mustacchi 	infop->Red = ACPI_PLD_GET_RED(&buf32p[0]);
81*672fc84aSRobert Mustacchi 	infop->Green = ACPI_PLD_GET_GREEN(&buf32p[0]);
82*672fc84aSRobert Mustacchi 	infop->Blue = ACPI_PLD_GET_BLUE(&buf32p[0]);
83*672fc84aSRobert Mustacchi 
84*672fc84aSRobert Mustacchi 	/* Second 32-bit DWord */
85*672fc84aSRobert Mustacchi 	infop->Width = ACPI_PLD_GET_WIDTH(&buf32p[1]);
86*672fc84aSRobert Mustacchi 	infop->Height = ACPI_PLD_GET_HEIGHT(&buf32p[1]);
87*672fc84aSRobert Mustacchi 
88*672fc84aSRobert Mustacchi 	/* Third 32-bit DWord */
89*672fc84aSRobert Mustacchi 	infop->UserVisible = ACPI_PLD_GET_USER_VISIBLE(&buf32p[2]);
90*672fc84aSRobert Mustacchi 	infop->Dock = ACPI_PLD_GET_DOCK(&buf32p[2]);
91*672fc84aSRobert Mustacchi 	infop->Lid = ACPI_PLD_GET_LID(&buf32p[2]);
92*672fc84aSRobert Mustacchi 	infop->Panel = ACPI_PLD_GET_PANEL(&buf32p[2]);
93*672fc84aSRobert Mustacchi 	infop->VerticalPosition = ACPI_PLD_GET_VERTICAL(&buf32p[2]);
94*672fc84aSRobert Mustacchi 	infop->HorizontalPosition = ACPI_PLD_GET_HORIZONTAL(&buf32p[2]);
95*672fc84aSRobert Mustacchi 	infop->Shape = ACPI_PLD_GET_SHAPE(&buf32p[2]);
96*672fc84aSRobert Mustacchi 	infop->GroupOrientation = ACPI_PLD_GET_ORIENTATION(&buf32p[2]);
97*672fc84aSRobert Mustacchi 	infop->GroupToken = ACPI_PLD_GET_TOKEN(&buf32p[2]);
98*672fc84aSRobert Mustacchi 	infop->GroupPosition = ACPI_PLD_GET_POSITION(&buf32p[2]);
99*672fc84aSRobert Mustacchi 	infop->Bay = ACPI_PLD_GET_BAY(&buf32p[2]);
100*672fc84aSRobert Mustacchi 
101*672fc84aSRobert Mustacchi 	/* Fourth 32-bit DWord */
102*672fc84aSRobert Mustacchi 	infop->Ejectable = ACPI_PLD_GET_EJECTABLE(&buf32p[3]);
103*672fc84aSRobert Mustacchi 	infop->OspmEjectRequired = ACPI_PLD_GET_OSPM_EJECT(&buf32p[3]);
104*672fc84aSRobert Mustacchi 	infop->CabinetNumber = ACPI_PLD_GET_CABINET(&buf32p[3]);
105*672fc84aSRobert Mustacchi 	infop->CardCageNumber = ACPI_PLD_GET_CARD_CAGE(&buf32p[3]);
106*672fc84aSRobert Mustacchi 	infop->Reference = ACPI_PLD_GET_REFERENCE(&buf32p[3]);
107*672fc84aSRobert Mustacchi 	infop->Rotation = ACPI_PLD_GET_ROTATION(&buf32p[3]);
108*672fc84aSRobert Mustacchi 	infop->Order = ACPI_PLD_GET_ORDER(&buf32p[3]);
109*672fc84aSRobert Mustacchi 
110*672fc84aSRobert Mustacchi 	if (len >= ACPI_PLD_REV2_BUFFER_SIZE && infop->Revision >= 2) {
111*672fc84aSRobert Mustacchi 		/* Fifth 32-bit DWord (Revision 2 of _PLD) */
112*672fc84aSRobert Mustacchi 
113*672fc84aSRobert Mustacchi 		infop->VerticalOffset = ACPI_PLD_GET_VERT_OFFSET(&buf32p[4]);
114*672fc84aSRobert Mustacchi 		infop->HorizontalOffset = ACPI_PLD_GET_HORIZ_OFFSET(&buf32p[4]);
115*672fc84aSRobert Mustacchi 	}
116*672fc84aSRobert Mustacchi 
117*672fc84aSRobert Mustacchi 	return (B_TRUE);
118*672fc84aSRobert Mustacchi }
119