xref: /freebsd/sys/dev/qlxge/qls_ioctl.c (revision 685dc743)
1718cf2ccSPedro F. Giffuni /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
4711bcba0SDavid C Somayajulu  * Copyright (c) 2013-2014 Qlogic Corporation
5711bcba0SDavid C Somayajulu  * All rights reserved.
6711bcba0SDavid C Somayajulu  *
7711bcba0SDavid C Somayajulu  *  Redistribution and use in source and binary forms, with or without
8711bcba0SDavid C Somayajulu  *  modification, are permitted provided that the following conditions
9711bcba0SDavid C Somayajulu  *  are met:
10711bcba0SDavid C Somayajulu  *
11711bcba0SDavid C Somayajulu  *  1. Redistributions of source code must retain the above copyright
12711bcba0SDavid C Somayajulu  *     notice, this list of conditions and the following disclaimer.
13711bcba0SDavid C Somayajulu  *  2. Redistributions in binary form must reproduce the above copyright
14711bcba0SDavid C Somayajulu  *     notice, this list of conditions and the following disclaimer in the
15711bcba0SDavid C Somayajulu  *     documentation and/or other materials provided with the distribution.
16711bcba0SDavid C Somayajulu  *
17711bcba0SDavid C Somayajulu  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18711bcba0SDavid C Somayajulu  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19711bcba0SDavid C Somayajulu  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20711bcba0SDavid C Somayajulu  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21711bcba0SDavid C Somayajulu  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22711bcba0SDavid C Somayajulu  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23711bcba0SDavid C Somayajulu  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24711bcba0SDavid C Somayajulu  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25711bcba0SDavid C Somayajulu  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26711bcba0SDavid C Somayajulu  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27711bcba0SDavid C Somayajulu  *  POSSIBILITY OF SUCH DAMAGE.
28711bcba0SDavid C Somayajulu  */
29711bcba0SDavid C Somayajulu /*
30711bcba0SDavid C Somayajulu  * File: qls_ioctl.c
31711bcba0SDavid C Somayajulu  * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
32711bcba0SDavid C Somayajulu  */
33711bcba0SDavid C Somayajulu #include <sys/cdefs.h>
34711bcba0SDavid C Somayajulu #include "qls_os.h"
35711bcba0SDavid C Somayajulu #include "qls_hw.h"
36711bcba0SDavid C Somayajulu #include "qls_def.h"
37711bcba0SDavid C Somayajulu #include "qls_inline.h"
38711bcba0SDavid C Somayajulu #include "qls_glbl.h"
39711bcba0SDavid C Somayajulu #include "qls_ioctl.h"
40711bcba0SDavid C Somayajulu #include "qls_dump.h"
41711bcba0SDavid C Somayajulu extern qls_mpi_coredump_t ql_mpi_coredump;
42711bcba0SDavid C Somayajulu 
43711bcba0SDavid C Somayajulu static int qls_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
44711bcba0SDavid C Somayajulu 		struct thread *td);
45711bcba0SDavid C Somayajulu 
46711bcba0SDavid C Somayajulu static struct cdevsw qla_cdevsw = {
47711bcba0SDavid C Somayajulu 	.d_version = D_VERSION,
48711bcba0SDavid C Somayajulu 	.d_ioctl = qls_eioctl,
49711bcba0SDavid C Somayajulu 	.d_name = "qlxge",
50711bcba0SDavid C Somayajulu };
51711bcba0SDavid C Somayajulu 
52711bcba0SDavid C Somayajulu int
qls_make_cdev(qla_host_t * ha)53711bcba0SDavid C Somayajulu qls_make_cdev(qla_host_t *ha)
54711bcba0SDavid C Somayajulu {
55711bcba0SDavid C Somayajulu         ha->ioctl_dev = make_dev(&qla_cdevsw,
5664c618edSJustin Hibbits 				if_getdunit(ha->ifp),
57711bcba0SDavid C Somayajulu                                 UID_ROOT,
58711bcba0SDavid C Somayajulu                                 GID_WHEEL,
59711bcba0SDavid C Somayajulu                                 0600,
60711bcba0SDavid C Somayajulu                                 "%s",
61711bcba0SDavid C Somayajulu                                 if_name(ha->ifp));
62711bcba0SDavid C Somayajulu 
63711bcba0SDavid C Somayajulu 	if (ha->ioctl_dev == NULL)
64711bcba0SDavid C Somayajulu 		return (-1);
65711bcba0SDavid C Somayajulu 
66711bcba0SDavid C Somayajulu         ha->ioctl_dev->si_drv1 = ha;
67711bcba0SDavid C Somayajulu 
68711bcba0SDavid C Somayajulu 	return (0);
69711bcba0SDavid C Somayajulu }
70711bcba0SDavid C Somayajulu 
71711bcba0SDavid C Somayajulu void
qls_del_cdev(qla_host_t * ha)72711bcba0SDavid C Somayajulu qls_del_cdev(qla_host_t *ha)
73711bcba0SDavid C Somayajulu {
74711bcba0SDavid C Somayajulu 	if (ha->ioctl_dev != NULL)
75711bcba0SDavid C Somayajulu 		destroy_dev(ha->ioctl_dev);
76711bcba0SDavid C Somayajulu 	return;
77711bcba0SDavid C Somayajulu }
78711bcba0SDavid C Somayajulu 
79711bcba0SDavid C Somayajulu static int
qls_eioctl(struct cdev * dev,u_long cmd,caddr_t data,int fflag,struct thread * td)80711bcba0SDavid C Somayajulu qls_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
81711bcba0SDavid C Somayajulu         struct thread *td)
82711bcba0SDavid C Somayajulu {
83711bcba0SDavid C Somayajulu         qla_host_t *ha;
84711bcba0SDavid C Somayajulu         int rval = 0;
85711bcba0SDavid C Somayajulu 
86711bcba0SDavid C Somayajulu 	qls_mpi_dump_t *mpi_dump;
87711bcba0SDavid C Somayajulu 
88711bcba0SDavid C Somayajulu         if ((ha = (qla_host_t *)dev->si_drv1) == NULL)
89711bcba0SDavid C Somayajulu                 return ENXIO;
90711bcba0SDavid C Somayajulu 
91711bcba0SDavid C Somayajulu         switch(cmd) {
92711bcba0SDavid C Somayajulu 	case QLA_MPI_DUMP:
93711bcba0SDavid C Somayajulu 		mpi_dump = (qls_mpi_dump_t *)data;
94711bcba0SDavid C Somayajulu 
95711bcba0SDavid C Somayajulu 		if (mpi_dump->size == 0) {
96711bcba0SDavid C Somayajulu 			mpi_dump->size = sizeof (qls_mpi_coredump_t);
97711bcba0SDavid C Somayajulu 		} else {
98280c10ebSDavid C Somayajulu 			if ((mpi_dump->size != sizeof (qls_mpi_coredump_t)) ||
99280c10ebSDavid C Somayajulu 				(mpi_dump->dbuf == NULL))
100711bcba0SDavid C Somayajulu 				rval = EINVAL;
101711bcba0SDavid C Somayajulu 			else {
102280c10ebSDavid C Somayajulu 				if (qls_mpi_core_dump(ha) == 0) {
103711bcba0SDavid C Somayajulu 					rval = copyout(&ql_mpi_coredump,
104711bcba0SDavid C Somayajulu 							mpi_dump->dbuf,
105711bcba0SDavid C Somayajulu 							mpi_dump->size);
106280c10ebSDavid C Somayajulu 				} else
107280c10ebSDavid C Somayajulu 					rval = ENXIO;
108711bcba0SDavid C Somayajulu 
109711bcba0SDavid C Somayajulu 				if (rval) {
110711bcba0SDavid C Somayajulu 					device_printf(ha->pci_dev,
111711bcba0SDavid C Somayajulu 						"%s: mpidump failed[%d]\n",
112711bcba0SDavid C Somayajulu 						__func__, rval);
113711bcba0SDavid C Somayajulu 				}
114711bcba0SDavid C Somayajulu 			}
115711bcba0SDavid C Somayajulu 		}
116711bcba0SDavid C Somayajulu 
117711bcba0SDavid C Somayajulu 		break;
118711bcba0SDavid C Somayajulu         default:
119711bcba0SDavid C Somayajulu                 break;
120711bcba0SDavid C Somayajulu         }
121711bcba0SDavid C Somayajulu 
122711bcba0SDavid C Somayajulu         return rval;
123711bcba0SDavid C Somayajulu }
124