/*
* 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
*/
/*
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include <sys/sysmacros.h>
#include <sys/pci_param.h>
#include <sys/iov_param.h>
#include <libnvpair.h>
#include <libdevinfo.h>
#include "libiov.h"
struct devlink_cb_arg {
char *linkname;
};
static int
{
char *node_type;
if (di_root) {
if (node == DI_NODE_NIL)
return (0);
return (1); /* streams device */
else
return (0);
} else
return (0);
}
static void
{
#ifdef DEBUG
char *minor_path;
char *d_path;
#endif
linkname[0] = '\0';
if (di_root) {
if (node == DI_NODE_NIL)
return;
#ifdef DEBUG
(void) printf("node_type = %s\n",
(void) printf("spec_type = 0x%x\n",
#endif
} else {
return;
}
#ifdef DEBUG
(void) printf("major = %d minor = %d devfs_minor_path = %s\n",
#endif
/* found a match */
#ifdef DEBUG
(void) printf("matching path = %s\n",
linkname);
#endif
break;
}
}
#ifdef DEBUG
if (is_streams_device(devfspath))
(void) printf("this is a STREAMS device\n");
#endif
}
/*
* Obtain the list of PFs in the system.
* Returns:
* Success: rv: 0
* Failure:
* rv:
* EINVAL - Invalid pf_list_nvlist pointer
* ENOMEM - Couldn't allocate memory for PF list
* ENODEV - No PFs (modctl())
*/
int
{
char *pfp;
char *pf_pathname;
if (pf_list_nvlist == NULL)
return (EINVAL);
*pf_list_nvlist = NULL;
if (rv != 0) {
return (rv);
}
/*
* We cache the size of the list we allocate in 'alloc_len' in
* case we have to make another call to MODIOVOPS_GET_PF_LIST
* if one or more PFs do not have "pf-mgmt-property" and 'pfp'
* has to be resized.
*/
return (ENOMEM);
}
if (rv != 0)
goto exit;
if (rv != 0)
goto exit;
/*
* if a PF has no "pfg-mgmt-supported" property set, it could also
* be because it is not attached yet. Try opening all PFs that do not
* have "pf-mgmt-property" to force an attach and refresh the PF list
* again to get the accurate info.
*/
goto exit;
if (nvp_type != DATA_TYPE_NVLIST_ARRAY)
goto exit;
if (err)
goto exit;
for (i = 0; i < nelem; i++) {
if (nvlist_lookup_boolean(nvl_array[i],
"pf-mgmt-supported") != ENOENT)
continue;
/*
* pf-mgmt-supported property is absent.
* Get the pathname for the PF device.
*/
"path", &pf_pathname);
if (err)
continue;
if (linkname[0] == '\0')
continue;
/*
* Attach the PF device
*/
if (fd == -1) {
continue;
}
}
if (get_pf_list_again) {
/*
* One or more PF devices had missing pf-mgmt-supported
* property.
*/
*pf_list_nvlist = NULL;
if (rv != 0) {
goto exit;
}
/*
* Check to see if more PFs would be listed than when
* the memory was allocated first time around and
* reallocate if necessary.
*/
return (ENOMEM);
}
if (rv == 0)
}
exit:
return (rv);
}
/*
* Obtain the device specific private properties for the given PF(pathname).
* Returns:
* Success: rv: 0
* Failure:
* rv:
* 1 - General failure
* EINVAL - Invalid Handle
* ENOMEM - Couldn't allocate memory for prop list
* ENODEV - No such PF (modctl())
* ENOTSUP - ioctl not supported
*/
int
void **buf)
{
int rv;
int fd;
int streams_device = 0;
return (EINVAL);
*num_params = 0;
*version = 0;
if (linkname[0] == '\0') {
return (1);
}
if (fd == -1) {
return (1);
}
if (streams_device) {
} else {
}
if (rv) {
#ifdef DEBUG
perror("ioctl to get version info failed\n");
#endif
return (ENOTSUP);
}
if (iov_param_ver.num_params == 0) {
return (0); /* no params to configure */
}
pdesc_list = malloc(
if (pdesc_list == NULL) {
return (ENOMEM);
}
if (streams_device) {
} else {
}
if (rv) {
#ifdef DEBUG
perror("ioctl to get param info failed\n");
#endif
return (ENOTSUP);
}
*buf = (void *)pdesc_list;
return (0);
}
/*
* The client wants to validate the properties now; we go ahead and issue the
* modctl() command to do this.
* The caller is responsible to free the reason_p if it is not NULL
* This string if non NULL describes the reason for failure
*/
int
{
int i, rv;
int fd;
int saved_errno = 0;
int streams_device = 0;
int rlen;
char *reason;
if (reason_p)
if (linkname[0] == '\0') {
return (1);
}
if (fd == -1)
return (errno);
if (rv) {
return (rv);
}
if (num_vfs)
for (i = 0; i < num_vfs; i++) {
if (rv)
goto error_exit;
}
if (rv) {
#ifdef DEBUG
(void) printf("iov_devparam_validate: nvlist_dup() failed:"
" rv(%d)\n", rv);
#endif
goto error_exit;
}
for (i = 0; i < num_vfs; i++) {
if (nvl[ i + 1]) {
} else {
if (rv)
goto error_exit;
}
}
goto error_exit;
goto error_exit;
goto error_exit;
goto error_exit;
goto error_exit;
goto error_exit;
goto error_exit;
if (streams_device) {
} else {
}
#ifdef DEBUG
(void) printf("ic_len = %d after call to VALIDATE_PARAMS\n",
#endif
saved_errno = errno;
/*
* The ioctl failed. Driver is supposed to have returned an
* error string.
*/
}
}
if (devparam_nvl)
if (vf_nvlist)
if (buf)
errno = saved_errno;
return (rv);
}