vdsk_common.c revision 4bac220845f606f60663ed6f3a2b88caa00ae87e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/vdsk_common.h>
/*
* Hooks for EFI support
*/
/*
* This code is a port of the functions efi_alloc_read() and efi_free() from
* the libefi userland library to the kernel so that the vDisk drivers (vdc
* and vds) can read EFI data. We will certaintly be able to remove that code
* once RFE 6213117 is implemented.
*/
/*
* The number of blocks the EFI label takes up (round up to nearest
* block)
*/
((l) - 1)) / (l)))
/* number of partitions -- limited by what we can malloc */
sizeof (struct dk_part))
/*
* The vd_efi_alloc_and_read() function will use some ioctls to get EFI data
* but the way we issue ioctl is different depending if we are on the vDisk
* server side (vds) or on the vDisk client side.
*
* On the server side (vds), we reference a layered device (ldi_handle_t) so we
* will use the LDI interface to execute ioctls (ldi_ioctl()). On the client
* side (vdc), we reference a vdc device (with a dev_t) so we directly invoke
* the function of the vdc driver implementing ioctls (vd_process_ioctl()).
*/
#define VD_EFI_CALLER_VDS 0
#define VD_EFI_CALLER_VDC 1
typedef struct vd_efi_dev {
int caller;
union {
} ioctl_dev;
} vd_efi_dev_t;
static int vd_efi_debug = 1;
static struct uuid_to_ptag {
} conversion_array[] = {
{ EFI_UNUSED },
{ EFI_BOOT },
{ EFI_ROOT },
{ EFI_SWAP },
{ EFI_USR },
{ EFI_BACKUP },
{ 0 }, /* STAND is never used */
{ EFI_VAR },
{ EFI_HOME },
{ EFI_ALTSCTR },
{ 0 }, /* CACHE (cachefs) is never used */
{ EFI_RESERVED },
{ EFI_SYSTEM },
{ EFI_LEGACY_MBR },
{ EFI_RESV3 },
{ EFI_RESV4 },
{ EFI_MSFT_RESV },
{ EFI_DELL_BASIC },
{ EFI_DELL_RAID },
{ EFI_DELL_SWAP },
{ EFI_DELL_LVM },
{ EFI_DELL_RESV }
};
static void
vd_efi_print(const char *format, ...)
{
}
/*
* Return a 32-bit CRC of the contents of the buffer.
*
* The seed is 0xffffffff and the result is XORed with 0xffffffff
* because this is what the Itanium firmware expects.
*/
unsigned int
vd_efi_crc32(const unsigned char *s, unsigned int len)
{
unsigned int crc32val;
return (crc32val ^ -1U);
}
static int
{
int error;
} else {
}
return (error);
}
static int
{
int error;
return (error);
}
static int
{
int status;
return (status);
VD_EFI_DEBUG("Bad EFI signature: 0x%llx != 0x%llx\n",
(long long)efi->efi_gpt_Signature,
(long long)LE_64(EFI_SIGNATURE));
return (EINVAL);
}
/*
* check CRC of the header; the size of the header should
* never be larger than one block
*/
efi->efi_gpt_HeaderCRC32 = 0;
VD_EFI_DEBUG("Bad EFI CRC: 0x%x != 0x%x\n",
sizeof (struct efi_gpt))));
return (EINVAL);
}
return (0);
}
static int
{
int i, j, status;
int label_len;
int md_flag = 0;
/*
* get the partition number for this file descriptor.
*/
return (status);
}
md_flag++;
}
/* get the LBA size */
}
if (disk_info.dki_lbsize == 0) {
VD_EFI_DEBUG("efi_read: assuming LBA 512 bytes\n");
}
/*
* Read the EFI GPT to figure out how many partitions we need
* to deal with.
*/
} else {
/* pad to physical sector size */
}
}
if (md_flag) {
return (status);
/* no valid label here; try the alternate */
VD_EFI_DEBUG("efi_read: primary label corrupt; "
"using backup\n");
vtoc->efi_nparts =
/*
* partitions are between last usable LBA and
* backup partition header
*/
} else {
&dk_ioc);
}
}
}
if (status != 0) {
return (status);
}
/* partitions start in the next block */
/* LINTED -- always longlong aligned */
/*
* Assemble this into a "dk_gpt" struct for easier
* digestibility by applications.
*/
/*
* If the array the user passed in is too small, set the length
* to what it needs to be and return
*/
return (EINVAL);
}
for (i = 0; i < vtoc->efi_nparts; i++) {
for (j = 0;
j < sizeof (conversion_array) / sizeof (struct uuid_to_ptag);
j++) {
&conversion_array[j].uuid,
sizeof (struct uuid)) == 0) {
break;
}
}
continue;
for (j = 0; j < EFI_PART_NAME_LEN; j++) {
}
}
return (0);
}
/*
* Read EFI - return 0 upon success.
*/
static int
{
int status;
int length;
/* figure out the number of entries that would fit into 16K */
(int) sizeof (struct dk_part) *
}
if (status != 0) {
VD_EFI_DEBUG("read of EFI table failed with error=%d\n",
status);
*vtoc_len = 0;
return (status);
}
return (0);
}
int
{
}
int
{
}
void
{
}
void
{
}
void
vdc_efi_fini(void)
{
}
/*
* This function stores EFI data (as returned by efi_alloc_and_read()) into
* a vtoc structure. The vDisk driver uses a vtoc structure to store generic
* information about disk partitions.
*/
void
{
int i, nparts;
for (i = 0; i < nparts; i++) {
continue;
break;
}
for (i = 0; i < nparts; i++) {
/*
* EFI can have more than 8 partitions. However the current
* implementation of EFI on Solaris only support 7 partitions
* (s0 to s6). There is no partition s7 but the minor number
* corresponding to slice 7 is used to represent the whole
* disk which data are stored in the "Sun Reserved" partition.
* So we use the entry 7 of the vtoc structure to store
* information about the whole disk.
*/
continue;
}
if (i >= VD_EFI_WD_SLICE) {
continue;
}
}
}
}