/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
*/
/*
* Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
*/
/*
* Supported IOCTLs :
* CPQARY3_IOCTL_DRIVER_INFO - to get driver details
* CPQARY3_IOCTL_CTLR_INFO - to get controller details
* CPQARY3_IOCTL_BMIC_PASS - to pass BMIC commands
* CPQARY3_IOCTL_SCSI_PASS - to pass SCSI commands
*/
#include "cpqary3.h"
/*
* Local Functions Declaration
*/
int);
int);
/*
* Global Variables Definitions
*/
/* Function Definitions */
/*
* Function : cpqary3_ioctl_driver_info
* Description : This routine will get major/ minor versions, Number of
* controllers detected & MAX Number of controllers
* supported
* Called By : cpqary3_ioctl
* Parameters : ioctl_reqp - address of the parameter sent from
* the application
* cpqary3p - address of the PerController structure
* mode - mode which comes from application
* Return Values: EFAULT on Failure, 0 on SUCCESS
*/
{
MEM_ZALLOC(sizeof (cpqary3_ioctl_request_t));
return (FAILURE);
/*
* First let us copyin the ioctl_reqp user buffer to request(kernel)
* memory. This is very much recomended before we access any of the
* fields.
*/
sizeof (cpqary3_ioctl_request_t), mode)) {
return (EFAULT);
}
/*
* Fill up the global structure "gdriver_info" memory.
* Fill this structure with available info, which will be copied
* back later
*/
/*
* First Copy out the driver_info structure
*/
sizeof (cpqary3_driver_info_t), mode)) {
return (EFAULT);
}
/*
* Copy out the request structure back
*/
sizeof (cpqary3_ioctl_request_t), mode)) {
return (EFAULT);
}
/*
* Everything looks fine. So return SUCCESS
*/
return (SUCCESS);
}
/*
* Function : cpqary3_ioctl_ctlr_info
* Description : This routine will get the controller related info, like
* board-id, subsystem-id, num of logical drives,
* slot number
* Called By : cpqary3_ioctl
* Parameters : ioctl_reqp - address of the parameter sent form the
* application
* cpqary3p - address of the PerController structure
* mode - mode which comes from application
* Return Values: EFAULT on Failure, 0 on SUCCESS
*/
{
MEM_ZALLOC(sizeof (cpqary3_ioctl_request_t));
return (FAILURE);
/*
* First let us copyin the buffer to kernel memory. This is very much
* recomended before we access any of the fields.
*/
sizeof (cpqary3_ioctl_request_t), mode)) {
return (EFAULT);
}
ctlr_info = (cpqary3_ctlr_info_t *)
MEM_ZALLOC(sizeof (cpqary3_ctlr_info_t));
return (FAILURE);
}
/*
* in the driver, board_id is actually subsystem_id
*/
/*
* TODO: ctlr_info.slot_num has to be implemented
* state & board_id fields are kept for future implementation i
* if required!
*/
/*
* First Copy out the ctlr_info structure
*/
sizeof (cpqary3_ctlr_info_t), mode)) {
return (EFAULT);
}
/*
* Copy out the request structure back
*/
sizeof (cpqary3_ioctl_request_t), mode)) {
return (EFAULT);
}
/*
* Everything looks fine. So return SUCCESS
*/
return (SUCCESS);
}
/*
* Function : cpqary3_ioctl_bmic_pass
* Description : This routine will pass the BMIC commands to controller
* Called By : cpqary3_ioctl
* Parameters : ioctl_reqp - address of the parameter sent from the
* application
* cpqary3p - address of the PerController structure
* mode - mode which comes directly from application
* Return Values: EFAULT on Failure, 0 on SUCCESS
*/
{
MEM_ZALLOC(sizeof (cpqary3_ioctl_request_t));
return (FAILURE);
/*
* First let us copyin the ioctl_reqp(user) buffer to request(kernel)
* memory. This is very much recommended before we access any of the
* fields.
*/
sizeof (cpqary3_ioctl_request_t), mode)) {
return (EFAULT);
}
bmic_pass = (cpqary3_bmic_pass_t *)
MEM_ZALLOC(sizeof (cpqary3_bmic_pass_t));
return (FAILURE);
}
/*
* Copy in "cpqary3_bmic_pass_t" structure from argp member
* of ioctl_reqp.
*/
sizeof (cpqary3_bmic_pass_t), mode)) {
return (EFAULT);
}
/*
* Get the free command list, fill in the bmic command and send it
* to the controller. This will return 0 on success.
*/
/*
* Now copy the bmic_pass (kernel) to the user argp
*/
sizeof (cpqary3_bmic_pass_t), mode)) {
}
/*
* Now copy the request(kernel) to ioctl_reqp(user)
*/
sizeof (cpqary3_ioctl_request_t), mode)) {
}
return (retval);
}
/*
* Function : cpqary3_ioctl_send_bmiccmd
* Description : This routine will get the free command,
* allocate memory and send it to controller.
* Called By : cpqary3_ioctl_bmic_pass
* Parameters : cpqary3_t - PerController structure
* cpqary3_bmic_pass_t - bmic structure
* mode - mode value sent from application
* Return Values: 0 on success
* FAILURE, EFAULT, ETIMEOUT based on the failure
*/
static int32_t
{
/* allocate a command with a dma buffer */
return (FAILURE);
/* Get the databuf when buf_len is greater than zero */
}
/*
* If io_direction is CPQARY3_SCSI_OUT, we have to copy user buffer
* to databuf
*/
/* Do a copyin when buf_len is greater than zero */
return (EFAULT);
}
}
}
/*
* Now fill the command as per the BMIC
*/
} else {
}
/* PERF */
/* PERF */
/* send command to controller and wait for a reply */
CPQARY3_SYNCCMD_SEND_WAITSIG) != 0) {
return (ETIMEDOUT);
}
/*
* Now the command is completed and copy the buffers back
* First copy the buffer databuf to bmic_pass.buf
* which is used as a buffer before passing the command to the
* controller.
*/
/* Do a copyout when buf_len is greater than zero */
if (ddi_copyout((void *)databuf,
}
}
}
/*
* This is case where the command completes with error,
* Then tag would have set its 1st(10) bit.
*/
sizeof (ErrorInfo_t));
case CISS_CMD_DATA_OVERRUN :
case CISS_CMD_DATA_UNDERRUN :
case CISS_CMD_SUCCESS :
case CISS_CMD_TARGET_STATUS :
break;
default :
break;
}
}
return (retval);
}
/*
* Function : cpqary3_ioctl_fil_bmic
* Description : This routine will fill the cmdlist with BMIC details
* Called By : cpqary3_ioctl_send_bmiccmd
* Parameters : cmdlist - command packet
* bmic_pass - bmic structure
* Return Values: void
*/
static void
{
switch (bmic_pass->io_direction) {
case CPQARY3_SCSI_OUT:
break;
case CPQARY3_SCSI_IN:
break;
case CPQARY3_NODATA_XFER:
break;
default:
break;
}
/*
* BMIC Detail - bytes 2[MSB] to 5[LSB]
*/
/* Transfer Length - bytes 7[MSB] to 8[LSB] */
/*
* Copy the Lun address from the request
*/
sizeof (LUNAddr_t));
}
/*
* Function : cpqary3_ioctl_scsi_pass
* Description : This routine will pass the SCSI commands to controller
* Called By : cpqary3_ioctl
* Parameters : ioctl_reqp - address of the parameter sent
* from the application
* cpqary3p - Addess of the percontroller stucture
* mode - mode which comes directly from application
* Return Values: EFAULT on Failure, 0 on SUCCESS
*/
{
MEM_ZALLOC(sizeof (cpqary3_ioctl_request_t));
return (FAILURE);
/*
* First let us copyin the ioctl_reqp(user) buffer to request(kernel)
* memory. * This is very much recommended before we access any of
* the fields.
*/
sizeof (cpqary3_ioctl_request_t), mode)) {
return (EFAULT);
}
scsi_pass = (cpqary3_scsi_pass_t *)
MEM_ZALLOC(sizeof (cpqary3_scsi_pass_t));
return (FAILURE);
}
/*
* Copy in "cpqary3_scsi_pass_t" structure from argp member
* of ioctl_reqp.
*/
sizeof (cpqary3_scsi_pass_t), mode)) {
return (EFAULT);
}
/*
* Get the free command list, fill in the scsi command and send it
* to the controller. This will return 0 on success.
*/
/*
* Now copy the scsi_pass (kernel) to the user argp
*/
sizeof (cpqary3_scsi_pass_t), mode)) {
}
/*
* Now copy the request(kernel) to ioctl_reqp(user)
*/
sizeof (cpqary3_ioctl_request_t), mode)) {
}
return (retval);
}
/*
* Function : cpqary3_ioctl_send_scsiccmd
* Description : This routine will pass the SCSI commands to controller
* Called By : cpqary3_ioctl_scsi_pass
* Parameters : cpqary3_t - PerController structure,
* cpqary3_scsi_pass_t - scsi parameter
* mode - sent from the application
* Return Values: 0 on success
* FAILURE, EFAULT, ETIMEOUT based on the failure
*/
static int32_t
{
/* allocate a command with a dma buffer */
return (FAILURE);
/* Get the databuf when buf_len is greater than zero */
}
/* Do a copyin when buf_len is greater than zero */
return (EFAULT);
}
}
}
/*
* Fill the scsi command
*/
/* PERF */
/* PERF */
/* send command to controller and wait for a reply */
CPQARY3_SYNCCMD_SEND_WAITSIG) != 0) {
return (ETIMEDOUT);
}
/*
* If the command sent is NOE
* if the event class is CLASS_LOGICAL_DRIVE
* if the subcalls code is zero and if detail change is zero
* if the event specific data[3] is either 1 or 2 ie., if
* if the logical drive is failed set the target type to
* CPQARY3_TARGET_NONE
*/
/* NOE */
if (cpqary3p->noe_support == 0 &&
/* LINTED: alignment */
}
}
}
/*
* Now the command is completed and copy the buffers back
* First copy the buffer databuf to scsi_pass->buf
* which is used as a buffer before passing the command to the
* controller.
*/
if (ddi_copyout((void *)databuf,
}
}
}
/*
* This is case where the command completes with error,
* Then tag would have set its 1st(10) bit.
*/
sizeof (ErrorInfo_t));
case CISS_CMD_DATA_OVERRUN:
case CISS_CMD_DATA_UNDERRUN:
case CISS_CMD_SUCCESS:
case CISS_CMD_TARGET_STATUS:
break;
default:
break;
}
}
return (retval);
}
/*
* Function : cpqary3_ioctl_fil_scsi_
* Description : This routine will fill the cmdlist with SCSI CDB
* Called By : cpqary3_ioctl_send_scsicmd
* Parameters : cmdlist - command packet
* cpqary3_scsi_pass_t - scsi parameter
* Return Values: void
*/
static void
{
switch (scsi_pass->io_direction) {
case CPQARY3_SCSI_OUT:
break;
case CPQARY3_SCSI_IN:
break;
case CPQARY3_NODATA_XFER:
break;
default:
break;
}
/*
* Copy the SCSI CDB as is
*/
/*
* Copy the Lun address from the request
*/
sizeof (LUNAddr_t));
}
/*
* Function : cpqary3_ioctl_fil_bmic_sas
* Description : This routine will fill the cmdlist with BMIC details
* Called By : cpqary3_ioctl_send_bmiccmd
* Parameters : cmdlist - command packet
* bmic_pass - bmic structure
* Return Values: void
*/
static void
{
switch (bmic_pass->io_direction) {
case CPQARY3_SCSI_OUT:
break;
case CPQARY3_SCSI_IN:
break;
case CPQARY3_NODATA_XFER:
break;
default:
break;
}
/*
* BMIC Detail - bytes 2[MSB] to 5[LSB]
*/
/* Transfer Length - bytes 7[MSB] to 8[LSB] */
/* Update CDB[2] = LSB bmix_index and CDB[9] = MSB bmic_index */
case HPSAS_ID_PHYSICAL_DRIVE:
case HPSAS_TAPE_INQUIRY:
case HPSAS_SENSE_MP_STAT:
case HPSAS_SET_MP_THRESHOLD:
case HPSAS_MP_PARAM_CONTROL:
case HPSAS_SENSE_DRV_ERR_LOG:
case HPSAS_SET_MP_VALUE:
break;
case HPSAS_ID_LOG_DRIVE:
case HPSAS_SENSE_LOG_DRIVE:
case HPSAS_READ:
case HPSAS_WRITE:
case HPSAS_WRITE_THROUGH:
case HPSAS_SENSE_CONFIG:
case HPSAS_SET_CONFIG:
case HPSAS_BYPASS_VOL_STATE:
case HPSAS_CHANGE_CONFIG:
case HPSAS_SENSE_ORIG_CONFIG:
case HPSAS_LABEL_LOG_DRIVE:
/* Unit Number MSB */
break;
default:
break;
}
/*
* Copy the Lun address from the request
*/
sizeof (LUNAddr_t));
}