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