^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * mwavedd.c -- mwave device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Written By: Mike Sullivan IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 1999 IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * the Free Software Foundation; either version 2 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * NO WARRANTY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * solely responsible for determining the appropriateness of using and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * distributing the Program and assumes all risks associated with its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * exercise of rights under this Agreement, including but not limited to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * the risks and costs of program errors, damage to or loss of data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * programs or equipment, and unavailability or interruption of operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * DISCLAIMER OF LIABILITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * 10/23/2000 - Alpha Release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * First release to the public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <linux/serial_8250.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include "smapi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include "mwavedd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include "3780i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include "tp3780i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) MODULE_DESCRIPTION("3780i Advanced Communications Processor (Mwave) driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) MODULE_AUTHOR("Mike Sullivan and Paul Schroeder");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * These parameters support the setting of MWave resources. Note that no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * checks are made against other devices (ie. superio) for conflicts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * We'll depend on users using the tpctl utility to do that for now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static DEFINE_MUTEX(mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int mwave_debug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int mwave_3780i_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int mwave_3780i_io = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int mwave_uart_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int mwave_uart_io = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) module_param(mwave_debug, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) module_param_hw(mwave_3780i_irq, int, irq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) module_param_hw(mwave_3780i_io, int, ioport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) module_param_hw(mwave_uart_irq, int, irq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) module_param_hw(mwave_uart_io, int, ioport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static int mwave_open(struct inode *inode, struct file *file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static int mwave_close(struct inode *inode, struct file *file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static long mwave_ioctl(struct file *filp, unsigned int iocmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned long ioarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) MWAVE_DEVICE_DATA mwave_s_mdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static int mwave_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) PRINTK_3(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) "mwavedd::mwave_open, entry inode %p file %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) "mwavedd::mwave_open, exit return retval %x\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static int mwave_close(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) PRINTK_3(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) "mwavedd::mwave_close, entry inode %p file %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_close, exit retval %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static long mwave_ioctl(struct file *file, unsigned int iocmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned long ioarg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) void __user *arg = (void __user *)ioarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) PRINTK_4(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) "mwavedd::mwave_ioctl, entry file %p cmd %x arg %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) file, iocmd, (int) ioarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) switch (iocmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) case IOCTL_MW_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) PRINTK_1(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) "mwavedd::mwave_ioctl, IOCTL_MW_RESET"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) " calling tp3780I_ResetDSP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) mutex_lock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) retval = tp3780I_ResetDSP(&pDrvData->rBDData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mutex_unlock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) "mwavedd::mwave_ioctl, IOCTL_MW_RESET"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) " retval %x from tp3780I_ResetDSP\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) case IOCTL_MW_RUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) PRINTK_1(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) "mwavedd::mwave_ioctl, IOCTL_MW_RUN"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) " calling tp3780I_StartDSP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) mutex_lock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) retval = tp3780I_StartDSP(&pDrvData->rBDData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mutex_unlock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) "mwavedd::mwave_ioctl, IOCTL_MW_RUN"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) " retval %x from tp3780I_StartDSP\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case IOCTL_MW_DSP_ABILITIES: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) MW_ABILITIES rAbilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) PRINTK_1(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) "mwavedd::mwave_ioctl,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) " IOCTL_MW_DSP_ABILITIES calling"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) " tp3780I_QueryAbilities\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) mutex_lock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) retval = tp3780I_QueryAbilities(&pDrvData->rBDData,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) &rAbilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) mutex_unlock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) " retval %x from tp3780I_QueryAbilities\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (retval == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if( copy_to_user(arg, &rAbilities,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) sizeof(MW_ABILITIES)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) " exit retval %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) case IOCTL_MW_READ_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case IOCTL_MW_READCLEAR_DATA: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) MW_READWRITE rReadData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) unsigned short __user *pusBuffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if( copy_from_user(&rReadData, arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) sizeof(MW_READWRITE)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) pusBuffer = (unsigned short __user *) (rReadData.pBuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) PRINTK_4(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) "mwavedd::mwave_ioctl IOCTL_MW_READ_DATA,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) " size %lx, ioarg %lx pusBuffer %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) rReadData.ulDataLength, ioarg, pusBuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) mutex_lock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) iocmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) pusBuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) rReadData.ulDataLength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) rReadData.usDspAddress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) mutex_unlock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case IOCTL_MW_READ_INST: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) MW_READWRITE rReadData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unsigned short __user *pusBuffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if( copy_from_user(&rReadData, arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) sizeof(MW_READWRITE)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pusBuffer = (unsigned short __user *) (rReadData.pBuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) PRINTK_4(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) "mwavedd::mwave_ioctl IOCTL_MW_READ_INST,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) " size %lx, ioarg %lx pusBuffer %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) rReadData.ulDataLength / 2, ioarg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) pusBuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) mutex_lock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) iocmd, pusBuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rReadData.ulDataLength / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) rReadData.usDspAddress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mutex_unlock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) case IOCTL_MW_WRITE_DATA: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) MW_READWRITE rWriteData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) unsigned short __user *pusBuffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if( copy_from_user(&rWriteData, arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) sizeof(MW_READWRITE)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) pusBuffer = (unsigned short __user *) (rWriteData.pBuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) PRINTK_4(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) "mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) " size %lx, ioarg %lx pusBuffer %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) rWriteData.ulDataLength, ioarg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) pusBuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) mutex_lock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) iocmd, pusBuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) rWriteData.ulDataLength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) rWriteData.usDspAddress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mutex_unlock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case IOCTL_MW_WRITE_INST: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) MW_READWRITE rWriteData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) unsigned short __user *pusBuffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if( copy_from_user(&rWriteData, arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) sizeof(MW_READWRITE)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) pusBuffer = (unsigned short __user *)(rWriteData.pBuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) PRINTK_4(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) "mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) " size %lx, ioarg %lx pusBuffer %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) rWriteData.ulDataLength, ioarg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) pusBuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) mutex_lock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) iocmd, pusBuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) rWriteData.ulDataLength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) rWriteData.usDspAddress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) mutex_unlock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case IOCTL_MW_REGISTER_IPC: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) unsigned int ipcnum = (unsigned int) ioarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) "mwavedd::mwave_ioctl:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) " IOCTL_MW_REGISTER_IPC:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) " Error: Invalid ipcnum %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ipcnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ipcnum = array_index_nospec(ipcnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ARRAY_SIZE(pDrvData->IPCs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) PRINTK_3(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) " ipcnum %x entry usIntCount %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ipcnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) pDrvData->IPCs[ipcnum].usIntCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) mutex_lock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) pDrvData->IPCs[ipcnum].bIsHere = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) pDrvData->IPCs[ipcnum].bIsEnabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) mutex_unlock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) " ipcnum %x exit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ipcnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case IOCTL_MW_GET_IPC: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) unsigned int ipcnum = (unsigned int) ioarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) "mwavedd::mwave_ioctl:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) " IOCTL_MW_GET_IPC: Error:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) " Invalid ipcnum %x\n", ipcnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ipcnum = array_index_nospec(ipcnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ARRAY_SIZE(pDrvData->IPCs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) PRINTK_3(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) " ipcnum %x, usIntCount %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ipcnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) pDrvData->IPCs[ipcnum].usIntCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) mutex_lock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (pDrvData->IPCs[ipcnum].bIsEnabled == true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) "mwavedd::mwave_ioctl, thread for"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) " ipc %x going to sleep\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ipcnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) add_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) pDrvData->IPCs[ipcnum].bIsHere = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /* check whether an event was signalled by */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* the interrupt handler while we were gone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (pDrvData->IPCs[ipcnum].usIntCount == 1) { /* first int has occurred (race condition) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) pDrvData->IPCs[ipcnum].usIntCount = 2; /* first int has been handled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) "mwavedd::mwave_ioctl"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) " IOCTL_MW_GET_IPC ipcnum %x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) " handling first int\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ipcnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) } else { /* either 1st int has not yet occurred, or we have already handled the first int */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (pDrvData->IPCs[ipcnum].usIntCount == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) pDrvData->IPCs[ipcnum].usIntCount = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) "mwavedd::mwave_ioctl"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) " IOCTL_MW_GET_IPC ipcnum %x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) " woke up and returning to"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) " application\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ipcnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) pDrvData->IPCs[ipcnum].bIsHere = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) remove_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) " returning thread for ipc %x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) " processing\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ipcnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) mutex_unlock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case IOCTL_MW_UNREGISTER_IPC: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) unsigned int ipcnum = (unsigned int) ioarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) "mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) " ipcnum %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ipcnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) "mwavedd::mwave_ioctl:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) " IOCTL_MW_UNREGISTER_IPC:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) " Error: Invalid ipcnum %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ipcnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ipcnum = array_index_nospec(ipcnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ARRAY_SIZE(pDrvData->IPCs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mutex_lock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (pDrvData->IPCs[ipcnum].bIsEnabled == true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) pDrvData->IPCs[ipcnum].bIsEnabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (pDrvData->IPCs[ipcnum].bIsHere == true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) mutex_unlock(&mwave_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) } /* switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_ioctl, exit retval %x\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static ssize_t mwave_read(struct file *file, char __user *buf, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) loff_t * ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) PRINTK_5(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) "mwavedd::mwave_read entry file %p, buf %p, count %zx ppos %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) file, buf, count, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static ssize_t mwave_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) size_t count, loff_t * ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) PRINTK_5(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) "mwavedd::mwave_write entry file %p, buf %p,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) " count %zx ppos %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) file, buf, count, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static int register_serial_portandirq(unsigned int port, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct uart_8250_port uart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) switch ( port ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) case 0x3f8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) case 0x2f8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) case 0x3e8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) case 0x2e8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) "mwavedd::register_serial_portandirq:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) " Error: Illegal port %x\n", port );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) } /* switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* port is okay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) switch ( irq ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) "mwavedd::register_serial_portandirq:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) " Error: Illegal irq %x\n", irq );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) } /* switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /* irq is okay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) memset(&uart, 0, sizeof(uart));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) uart.port.uartclk = 1843200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) uart.port.iobase = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) uart.port.irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) uart.port.iotype = UPIO_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) uart.port.flags = UPF_SHARE_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return serial8250_register_8250_port(&uart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static const struct file_operations mwave_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .read = mwave_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .write = mwave_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .unlocked_ioctl = mwave_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) .open = mwave_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .release = mwave_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static struct miscdevice mwave_misc_dev = { MWAVE_MINOR, "mwave", &mwave_fops };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) #if 0 /* totally b0rked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * sysfs support <paulsch@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct device mwave_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* Prevent code redundancy, create a macro for mwave_show_* functions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #define mwave_show_function(attr_name, format_string, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static ssize_t mwave_show_##attr_name(struct device *dev, struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) DSP_3780I_CONFIG_SETTINGS *pSettings = \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) &mwave_s_mdd.rBDData.rDspSettings; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return sprintf(buf, format_string, pSettings->field); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* All of our attributes are read attributes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) #define mwave_dev_rd_attr(attr_name, format_string, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) mwave_show_function(attr_name, format_string, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static DEVICE_ATTR(attr_name, S_IRUGO, mwave_show_##attr_name, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) mwave_dev_rd_attr (3780i_dma, "%i\n", usDspDma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) mwave_dev_rd_attr (3780i_irq, "%i\n", usDspIrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) mwave_dev_rd_attr (3780i_io, "%#.4x\n", usDspBaseIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) mwave_dev_rd_attr (uart_irq, "%i\n", usUartIrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) mwave_dev_rd_attr (uart_io, "%#.4x\n", usUartBaseIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static struct device_attribute * const mwave_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) &dev_attr_3780i_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) &dev_attr_3780i_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) &dev_attr_3780i_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) &dev_attr_uart_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) &dev_attr_uart_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * mwave_init is called on module load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * mwave_exit is called on module unload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * mwave_exit is also used to clean up after an aborted mwave_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static void mwave_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) for (i = 0; i < pDrvData->nr_registered_attrs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) device_remove_file(&mwave_device, mwave_dev_attrs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) pDrvData->nr_registered_attrs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (pDrvData->device_registered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) device_unregister(&mwave_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) pDrvData->device_registered = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if ( pDrvData->sLine >= 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) serial8250_unregister_port(pDrvData->sLine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (pDrvData->bMwaveDevRegistered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) misc_deregister(&mwave_misc_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (pDrvData->bDSPEnabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) tp3780I_DisableDSP(&pDrvData->rBDData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (pDrvData->bResourcesClaimed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) tp3780I_ReleaseResources(&pDrvData->rBDData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (pDrvData->bBDInitialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) tp3780I_Cleanup(&pDrvData->rBDData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit exit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) module_exit(mwave_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int __init mwave_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_init entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) memset(&mwave_s_mdd, 0, sizeof(MWAVE_DEVICE_DATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) pDrvData->bBDInitialized = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) pDrvData->bResourcesClaimed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) pDrvData->bDSPEnabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) pDrvData->bDSPReset = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) pDrvData->bMwaveDevRegistered = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) pDrvData->sLine = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) for (i = 0; i < ARRAY_SIZE(pDrvData->IPCs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) pDrvData->IPCs[i].bIsEnabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) pDrvData->IPCs[i].bIsHere = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) pDrvData->IPCs[i].usIntCount = 0; /* no ints received yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) init_waitqueue_head(&pDrvData->IPCs[i].ipc_wait_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) retval = tp3780I_InitializeBoardData(&pDrvData->rBDData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) "mwavedd::mwave_init, return from tp3780I_InitializeBoardData"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) " retval %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) "mwavedd::mwave_init: Error:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) " Failed to initialize board data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) goto cleanup_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) pDrvData->bBDInitialized = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) retval = tp3780I_CalcResources(&pDrvData->rBDData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) "mwavedd::mwave_init, return from tp3780I_CalcResources"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) " retval %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) "mwavedd:mwave_init: Error:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) " Failed to calculate resources\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) goto cleanup_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) retval = tp3780I_ClaimResources(&pDrvData->rBDData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) "mwavedd::mwave_init, return from tp3780I_ClaimResources"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) " retval %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) "mwavedd:mwave_init: Error:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) " Failed to claim resources\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) goto cleanup_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) pDrvData->bResourcesClaimed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) retval = tp3780I_EnableDSP(&pDrvData->rBDData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) PRINTK_2(TRACE_MWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) "mwavedd::mwave_init, return from tp3780I_EnableDSP"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) " retval %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) "mwavedd:mwave_init: Error:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) " Failed to enable DSP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) goto cleanup_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) pDrvData->bDSPEnabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (misc_register(&mwave_misc_dev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) "mwavedd:mwave_init: Error:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) " Failed to register misc device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) goto cleanup_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) pDrvData->bMwaveDevRegistered = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) pDrvData->sLine = register_serial_portandirq(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) pDrvData->rBDData.rDspSettings.usUartBaseIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) pDrvData->rBDData.rDspSettings.usUartIrq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (pDrvData->sLine < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) "mwavedd:mwave_init: Error:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) " Failed to register serial driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) goto cleanup_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /* uart is registered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /* sysfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) memset(&mwave_device, 0, sizeof (struct device));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dev_set_name(&mwave_device, "mwave");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (device_register(&mwave_device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) goto cleanup_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) pDrvData->device_registered = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) for (i = 0; i < ARRAY_SIZE(mwave_dev_attrs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if(device_create_file(&mwave_device, mwave_dev_attrs[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) "mwavedd:mwave_init: Error:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) " Failed to create sysfs file %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) mwave_dev_attrs[i]->attr.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) goto cleanup_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) pDrvData->nr_registered_attrs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* SUCCESS! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) cleanup_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) PRINTK_ERROR(KERN_ERR_MWAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) "mwavedd::mwave_init: Error:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) " Failed to initialize\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) mwave_exit(); /* clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) module_init(mwave_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)