aac_ioctl.c revision 830d82f7f87041e48127cac2e92b5cb2d878202e
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright 2005-06 Adaptec, Inc.
* Copyright (c) 2005-06 Adaptec Inc., Achim Leubner
* Copyright (c) 2000 Michael Smith
* Copyright (c) 2001 Scott Long
* Copyright (c) 2000 BSDi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/ddidmareq.h>
#include <sys/byteorder.h>
#include "aac_regs.h"
#include "aac.h"
#include "aac_ioctl.h"
/*
* External functions
*/
extern ddi_device_acc_attr_t aac_acc_attr;
/*
* IOCTL command handling functions
*/
static int aac_check_revision(intptr_t, int);
static int aac_get_pci_info(intptr_t, int);
caddr_t, int);
int
{
int status;
switch (cmd) {
break;
case FSACTL_SENDFIB:
case FSACTL_SEND_LARGE_FIB:
break;
break;
break;
break;
case FSACTL_SEND_RAW_SRB:
break;
case FSACTL_GET_PCI_INFO:
break;
case FSACTL_QUERY_DISK:
break;
case FSACTL_DELETE_DISK:
break;
case FSACTL_GET_FEATURES:
break;
default:
break;
}
return (status);
}
static int
{
struct aac_revision aac_rev;
DBCALLED(1);
/* Copyin the revision struct from userspace */
sizeof (struct aac_revision), mode) != 0)
return (EFAULT);
/* Doctor up the response struct */
sizeof (struct aac_revision), mode) != 0)
return (EFAULT);
return (0);
}
static int
{
unsigned size;
DBCALLED(1);
return (ENOMEM);
sizeof (struct aac_fib_header), mode) != 0) {
goto finish;
}
goto finish;
}
goto finish;
}
0, 0, 0, 0, NULL);
} else {
goto finish;
}
}
if (rval == 0) {
goto finish;
}
}
return (rval);
}
static int
{
DBCALLED(1);
return (ENOMEM);
/* All elements are already 0, add to queue */
else {
;
}
/* Evaluate unique value */
} else {
}
}
return (EFAULT);
return (0);
}
static int
{
struct aac_get_adapter_fib af;
struct aac_fib_context *ctx;
int rval;
DBCALLED(1);
return (EFAULT);
break;
}
if (!ctx)
return (EFAULT);
#ifdef _LP64
#else
#endif
"aac_next_getadapter_fib(): waiting for AIF"));
if (rval == 0)
else
#ifdef _LP64
#else
#endif
}
return (rval);
}
static int
{
struct aac_fib_context *ctx;
DBCALLED(1);
continue;
else {
}
break;
}
if (ctx)
return (0);
}
/*
* The following function comes from Adaptec:
*
* SRB is required for the new management tools
*/
static int
{
struct aac_srb_reply *srbreply;
void *user_reply;
DBCALLED(1);
return (ENOMEM);
goto finish;
}
sizeof (struct aac_fib_header))) {
goto finish;
}
goto finish;
}
/* Only one sg element from userspace supported */
goto finish;
}
/* Check fibsize */
goto finish;
}
/* Allocate and bind DMA memory space */
acp->left_cookien = 0;
if (err != DDI_SUCCESS) {
"Can't allocate DMA handle, errno=%d", err));
goto finish;
}
/* TODO: remove duplicate code with aac_tran_init_pkt() */
if (err != DDI_SUCCESS) {
"Cannot alloc DMA to non-aligned buf"));
goto finish;
}
if (err != DDI_DMA_MAPPED) {
goto finish;
}
if (ddi_copyin(
#ifdef _LP64
#else
#endif
mode) != 0) {
goto finish;
}
}
}
/* Fill in command, sg elements */
for (i = 0; i < acp->left_cookien &&
i < softs->aac_sg_tablesize; i++) {
cookiep);
}
sizeof (struct aac_sg_entry) + \
i * sizeof (struct aac_sg_entry64);
} else {
for (i = 0; i < acp->left_cookien &&
i < softs->aac_sg_tablesize; i++) {
cookiep);
}
(i - 1) * sizeof (struct aac_sg_entry);
}
/* Fill fib header */
/* TODO: remove duplicate code with aac_ioctl_send_fib() */
/* Send command */
goto finish;
}
if (rval != 0) {
goto finish;
}
#ifdef _LP64
#else
#endif
goto finish;
}
}
/* Status struct. */
sizeof (struct aac_srb_reply), mode) != 0) {
goto finish;
}
if (cookiep)
if (acp->buf_dma_handle)
return (rval);
}
static int
{
struct aac_pci_info response;
DBCALLED(1);
sizeof (struct aac_pci_info), mode) != 0)
return (EFAULT);
return (0);
}
static int
{
struct aac_query_disk qdisk;
DBCALLED(1);
return (EFAULT);
return (EINVAL);
} else
return (EINVAL);
return (EFAULT);
return (0);
}
static int
{
struct aac_delete_disk ddisk;
DBCALLED(1);
return (EFAULT);
return (EINVAL);
return (EBUSY);
/*
* We don't trust the userland to tell us when to delete
* a container, rather we rely on an AIF coming from the
* controller.
*/
return (0);
}
/*
* The following function comes from Adaptec to support creation of arrays
* bigger than 2TB.
*/
static int
{
struct aac_features f;
DBCALLED(1);
return (EFAULT);
/*
* When the management driver receives FSACTL_GET_FEATURES ioctl with
* ALL zero in the featuresState, the driver will return the current
* state of all the supported features, the data field will not be
* valid.
* When the management driver receives FSACTL_GET_FEATURES ioctl with
* a specific bit set in the featuresState, the driver will return the
* current state of this specific feature and whatever data that are
* associated with the feature in the data field or perform whatever
* action needed indicates in the data field.
*/
/* TODO: In the future, add other features state here as well */
} else {
/* TODO: Add other features state and data in the future */
}
return (EFAULT);
return (0);
}
static int
{
int current;
/* Empty */
return (EAGAIN);
}
return (EFAULT);
}
return (0);
}