1252206Sdavidcs/* 2252206Sdavidcs * Copyright (c) 2013-2014 Qlogic Corporation 3252206Sdavidcs * All rights reserved. 4252206Sdavidcs * 5252206Sdavidcs * Redistribution and use in source and binary forms, with or without 6252206Sdavidcs * modification, are permitted provided that the following conditions 7252206Sdavidcs * are met: 8252206Sdavidcs * 9252206Sdavidcs * 1. Redistributions of source code must retain the above copyright 10252206Sdavidcs * notice, this list of conditions and the following disclaimer. 11252206Sdavidcs * 2. Redistributions in binary form must reproduce the above copyright 12252206Sdavidcs * notice, this list of conditions and the following disclaimer in the 13252206Sdavidcs * documentation and/or other materials provided with the distribution. 14252206Sdavidcs * 15252206Sdavidcs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16252206Sdavidcs * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17252206Sdavidcs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18252206Sdavidcs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19252206Sdavidcs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20252206Sdavidcs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21252206Sdavidcs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22252206Sdavidcs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23252206Sdavidcs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24252206Sdavidcs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25252206Sdavidcs * POSSIBILITY OF SUCH DAMAGE. 26252206Sdavidcs */ 27252206Sdavidcs/* 28252206Sdavidcs * File: qls_ioctl.c 29252206Sdavidcs * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656. 30252206Sdavidcs */ 31252206Sdavidcs#include <sys/cdefs.h> 32252206Sdavidcs__FBSDID("$FreeBSD: releng/10.2/sys/dev/qlxge/qls_ioctl.c 258457 2013-11-22 00:26:21Z davidcs $"); 33252206Sdavidcs 34252206Sdavidcs 35252206Sdavidcs#include "qls_os.h" 36252206Sdavidcs#include "qls_hw.h" 37252206Sdavidcs#include "qls_def.h" 38252206Sdavidcs#include "qls_inline.h" 39252206Sdavidcs#include "qls_glbl.h" 40252206Sdavidcs#include "qls_ioctl.h" 41252206Sdavidcs#include "qls_dump.h" 42252206Sdavidcsextern qls_mpi_coredump_t ql_mpi_coredump; 43252206Sdavidcs 44252206Sdavidcsstatic int qls_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 45252206Sdavidcs struct thread *td); 46252206Sdavidcs 47252206Sdavidcsstatic struct cdevsw qla_cdevsw = { 48252206Sdavidcs .d_version = D_VERSION, 49252206Sdavidcs .d_ioctl = qls_eioctl, 50252206Sdavidcs .d_name = "qlxge", 51252206Sdavidcs}; 52252206Sdavidcs 53252206Sdavidcsint 54252206Sdavidcsqls_make_cdev(qla_host_t *ha) 55252206Sdavidcs{ 56252206Sdavidcs ha->ioctl_dev = make_dev(&qla_cdevsw, 57252206Sdavidcs ha->ifp->if_dunit, 58252206Sdavidcs UID_ROOT, 59252206Sdavidcs GID_WHEEL, 60252206Sdavidcs 0600, 61252206Sdavidcs "%s", 62252206Sdavidcs if_name(ha->ifp)); 63252206Sdavidcs 64252206Sdavidcs if (ha->ioctl_dev == NULL) 65252206Sdavidcs return (-1); 66252206Sdavidcs 67252206Sdavidcs ha->ioctl_dev->si_drv1 = ha; 68252206Sdavidcs 69252206Sdavidcs return (0); 70252206Sdavidcs} 71252206Sdavidcs 72252206Sdavidcsvoid 73252206Sdavidcsqls_del_cdev(qla_host_t *ha) 74252206Sdavidcs{ 75252206Sdavidcs if (ha->ioctl_dev != NULL) 76252206Sdavidcs destroy_dev(ha->ioctl_dev); 77252206Sdavidcs return; 78252206Sdavidcs} 79252206Sdavidcs 80252206Sdavidcsstatic int 81252206Sdavidcsqls_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 82252206Sdavidcs struct thread *td) 83252206Sdavidcs{ 84252206Sdavidcs qla_host_t *ha; 85252206Sdavidcs int rval = 0; 86252206Sdavidcs device_t pci_dev; 87252206Sdavidcs 88252206Sdavidcs qls_mpi_dump_t *mpi_dump; 89252206Sdavidcs 90252206Sdavidcs if ((ha = (qla_host_t *)dev->si_drv1) == NULL) 91252206Sdavidcs return ENXIO; 92252206Sdavidcs 93252206Sdavidcs pci_dev= ha->pci_dev; 94252206Sdavidcs 95252206Sdavidcs switch(cmd) { 96252206Sdavidcs 97252206Sdavidcs case QLA_MPI_DUMP: 98252206Sdavidcs mpi_dump = (qls_mpi_dump_t *)data; 99252206Sdavidcs 100252206Sdavidcs if (mpi_dump->size == 0) { 101252206Sdavidcs mpi_dump->size = sizeof (qls_mpi_coredump_t); 102252206Sdavidcs } else { 103258457Sdavidcs if ((mpi_dump->size != sizeof (qls_mpi_coredump_t)) || 104258457Sdavidcs (mpi_dump->dbuf == NULL)) 105252206Sdavidcs rval = EINVAL; 106252206Sdavidcs else { 107258457Sdavidcs if (qls_mpi_core_dump(ha) == 0) { 108258457Sdavidcs rval = copyout(&ql_mpi_coredump, 109258457Sdavidcs mpi_dump->dbuf, 110258457Sdavidcs mpi_dump->size); 111258457Sdavidcs } else 112258457Sdavidcs rval = ENXIO; 113252206Sdavidcs 114252206Sdavidcs if (rval) { 115252206Sdavidcs device_printf(ha->pci_dev, 116252206Sdavidcs "%s: mpidump failed[%d]\n", 117252206Sdavidcs __func__, rval); 118252206Sdavidcs } 119252206Sdavidcs } 120252206Sdavidcs 121252206Sdavidcs } 122252206Sdavidcs 123252206Sdavidcs break; 124252206Sdavidcs default: 125252206Sdavidcs break; 126252206Sdavidcs } 127252206Sdavidcs 128252206Sdavidcs return rval; 129252206Sdavidcs} 130252206Sdavidcs 131