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