aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Toth <stoth@hauppauge.com>2008-05-19 18:09:21 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:19:53 -0400
commitc6465799c38762b963bb819e033d2a56a3d3c233 (patch)
tree73548c0e8a8c1475f0be488ca089d5bae8be024e
parent464a77dd8845fc8f3beeaad24478081576c4b83a (diff)
V4L/DVB (8262): sms1xxx: remove smschar.o
Signed-off-by: Steven Toth <stoth@hauppauge.com> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/mdtv/Makefile2
-rw-r--r--drivers/media/mdtv/smschar.c577
-rw-r--r--drivers/media/mdtv/smschar.h7
-rw-r--r--drivers/media/mdtv/smscharioctl.h17
-rw-r--r--drivers/media/mdtv/smscoreapi.c8
5 files changed, 2 insertions, 609 deletions
diff --git a/drivers/media/mdtv/Makefile b/drivers/media/mdtv/Makefile
index c3cf917d726a..0af1b3827821 100644
--- a/drivers/media/mdtv/Makefile
+++ b/drivers/media/mdtv/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the kernel MDTV driver 2# Makefile for the kernel MDTV driver
3# 3#
4 4
5smscore-objs := smschar.o smscoreapi.o 5smscore-objs := smscoreapi.o
6 6
7obj-$(CONFIG_MDTV_SIANO_STELLAR_COMMON) += smscore.o 7obj-$(CONFIG_MDTV_SIANO_STELLAR_COMMON) += smscore.o
8obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsusb.o 8obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsusb.o
diff --git a/drivers/media/mdtv/smschar.c b/drivers/media/mdtv/smschar.c
deleted file mode 100644
index 15ebecd598ec..000000000000
--- a/drivers/media/mdtv/smschar.c
+++ /dev/null
@@ -1,577 +0,0 @@
1/*!
2
3 \file smschar.c
4
5 \brief Implementation of smscore client for cdev based access
6
7 \par Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
8
9 \par This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3 as
11 published by the Free Software Foundation;
12
13 Software distributed under the License is distributed on an "AS
14 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
15 implied.
16
17 \author Anatoly Greenblat
18
19*/
20
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/init.h>
24
25#include <linux/kernel.h> /* printk() */
26#include <linux/fs.h> /* everything... */
27#include <linux/types.h> /* size_t */
28#include <linux/cdev.h>
29#include <linux/sched.h>
30#include <asm/system.h> /* cli(), *_flags */
31#include <asm/uaccess.h> /* copy_*_user */
32
33#include "smskdefs.h" // page, scatterlist, kmutex
34#include "smscoreapi.h"
35#include "smstypes.h"
36
37#include "smscharioctl.h"
38
39#define SMS_CHR_MAX_Q_LEN 10 // max number of packets allowed to be pending on queue
40#define SMSCHAR_NR_DEVS 7
41
42typedef struct _smschar_device
43{
44 struct cdev cdev; //!< Char device structure - kernel's device model representation
45
46 wait_queue_head_t waitq; /* Processes waiting */
47 spinlock_t lock; //!< critical section
48 int pending_count;
49 struct list_head pending_data; //!< list of pending data
50
51 smscore_buffer_t *currentcb;
52
53 int device_index;
54
55 smscore_device_t *coredev;
56 smscore_client_t *smsclient;
57} smschar_device_t;
58
59//! Holds the major number of the device node. may be changed at load time.
60int smschar_major = 251;
61
62//! Holds the first minor number of the device node. may be changed at load time.
63int smschar_minor = 0;
64
65// macros that allow the load time parameters change
66module_param ( smschar_major, int, S_IRUGO );
67module_param ( smschar_minor, int, S_IRUGO );
68
69#ifdef SMSCHAR_DEBUG
70
71 #undef PERROR
72# define PERROR(fmt, args...) printk( KERN_INFO "smschar error: line %d- %s(): " fmt,__LINE__, __FUNCTION__, ## args)
73 #undef PWARNING
74# define PWARNING(fmt, args...) printk( KERN_INFO "smschar warning: line %d- %s(): " fmt,__LINE__, __FUNCTION__, ## args)
75 #undef PDEBUG /* undef it, just in case */
76# define PDEBUG(fmt, args...) printk( KERN_INFO "smschar - %s(): " fmt, __FUNCTION__, ## args)
77
78#else /* not debugging: nothing */
79
80 #define PDEBUG(fmt, args...)
81 #define PERROR(fmt, args...)
82 #define PWARNING(fmt, args...)
83
84#endif
85
86smschar_device_t smschar_devices[SMSCHAR_NR_DEVS];
87static int g_smschar_inuse = 0;
88
89/**
90 * unregisters sms client and returns all queued buffers
91 *
92 * @param dev pointer to the client context (smschar parameters block)
93 *
94 */
95void smschar_unregister_client(smschar_device_t* dev)
96{
97 unsigned long flags;
98
99 if (dev->coredev && dev->smsclient)
100 {
101 wake_up_interruptible(&dev->waitq);
102
103 spin_lock_irqsave(&dev->lock, flags);
104
105 while (!list_empty(&dev->pending_data))
106 {
107 smscore_buffer_t *cb = (smscore_buffer_t *) dev->pending_data.next;
108 list_del(&cb->entry);
109
110 smscore_putbuffer(dev->coredev, cb);
111
112 dev->pending_count --;
113 }
114
115 if (dev->currentcb)
116 {
117 smscore_putbuffer(dev->coredev, dev->currentcb);
118 dev->currentcb = NULL;
119 dev->pending_count --;
120 }
121
122 smscore_unregister_client(dev->smsclient);
123 dev->smsclient = NULL;
124
125 spin_unlock_irqrestore(&dev->lock, flags);
126 }
127}
128
129/**
130 * queues incoming buffers into buffers queue
131 *
132 * @param context pointer to the client context (smschar parameters block)
133 * @param cb pointer to incoming buffer descriptor
134 *
135 * @return 0 on success, <0 on queue overflow.
136 */
137int smschar_onresponse(void *context, smscore_buffer_t *cb)
138{
139 smschar_device_t *dev = context;
140 unsigned long flags;
141
142 spin_lock_irqsave(&dev->lock, flags);
143
144 if (dev->pending_count > SMS_CHR_MAX_Q_LEN)
145 {
146 spin_unlock_irqrestore(&dev->lock, flags);
147 return -EBUSY;
148 }
149
150 dev->pending_count ++;
151
152 // if data channel, remove header
153 if (dev->device_index)
154 {
155 cb->size -= sizeof(SmsMsgHdr_ST);
156 cb->offset += sizeof(SmsMsgHdr_ST);
157 }
158
159 list_add_tail(&cb->entry, &dev->pending_data);
160 spin_unlock_irqrestore(&dev->lock, flags);
161
162 if (waitqueue_active(&dev->waitq))
163 wake_up_interruptible(&dev->waitq);
164
165 return 0;
166}
167
168/**
169 * handles device removal event
170 *
171 * @param context pointer to the client context (smschar parameters block)
172 *
173 */
174void smschar_onremove(void *context)
175{
176 smschar_device_t *dev = (smschar_device_t *) context;
177
178 smschar_unregister_client(dev);
179 dev->coredev = NULL;
180}
181
182/**
183 * registers client associated with the node
184 *
185 * @param inode Inode concerned.
186 * @param file File concerned.
187 *
188 * @return 0 on success, <0 on error.
189 */
190int smschar_open (struct inode *inode, struct file *file)
191{
192 smschar_device_t *dev = container_of(inode->i_cdev, smschar_device_t, cdev);
193 int rc = -ENODEV;
194
195 PDEBUG("entering index %d\n", dev->device_index);
196
197 if (dev->coredev)
198 {
199 smsclient_params_t params;
200
201 params.initial_id = dev->device_index ? dev->device_index : SMS_HOST_LIB;
202 params.data_type = dev->device_index ? MSG_SMS_DAB_CHANNEL : 0;
203 params.onresponse_handler = smschar_onresponse;
204 params.onremove_handler = smschar_onremove;
205 params.context = dev;
206
207 rc = smscore_register_client(dev->coredev, &params, &dev->smsclient);
208 if (!rc)
209 {
210 file->private_data = dev;
211 }
212 }
213
214 PDEBUG("exiting, rc %d\n", rc);
215
216 return rc;
217}
218
219/**
220 * unregisters client associated with the node
221 *
222 * @param inode Inode concerned.
223 * @param file File concerned.
224 *
225 */
226int smschar_release(struct inode *inode, struct file *file)
227{
228 smschar_unregister_client(file->private_data);
229
230 PDEBUG("exiting\n");
231
232 return 0;
233}
234
235/**
236 * copies data from buffers in incoming queue into a user buffer
237 *
238 * @param file File structure.
239 * @param buf Source buffer.
240 * @param count Size of source buffer.
241 * @param f_pos Position in file (ignored).
242 *
243 * @return Number of bytes read, or <0 on error.
244 */
245ssize_t smschar_read ( struct file * file, char __user * buf, size_t count, loff_t * f_pos )
246{
247 smschar_device_t *dev = file->private_data;
248 unsigned long flags;
249 int copied = 0;
250
251 if (!dev->coredev || !dev->smsclient)
252 {
253 PERROR("no client\n");
254 return -ENODEV;
255 }
256
257 while (copied != count)
258 {
259 if (0 > wait_event_interruptible(dev->waitq, !list_empty(&dev->pending_data)))
260 {
261 PERROR("wait_event_interruptible error\n");
262 return -ENODEV;
263 }
264
265 if (!dev->smsclient)
266 {
267 PERROR("no client\n");
268 return -ENODEV;
269 }
270
271 spin_lock_irqsave(&dev->lock, flags);
272
273 while (!list_empty(&dev->pending_data) && (copied != count))
274 {
275 smscore_buffer_t *cb = (smscore_buffer_t *) dev->pending_data.next;
276 int actual_size = min(((int) count - copied), cb->size);
277
278 copy_to_user(&buf[copied], &((char*)cb->p)[cb->offset], actual_size);
279
280 copied += actual_size;
281 cb->offset += actual_size;
282 cb->size -= actual_size;
283
284 if (!cb->size)
285 {
286 list_del(&cb->entry);
287 smscore_putbuffer(dev->coredev, cb);
288
289 dev->pending_count --;
290 }
291 }
292
293 spin_unlock_irqrestore(&dev->lock, flags);
294 }
295
296 return copied;
297}
298
299/**
300 * sends the buffer to the associated device
301 *
302 * @param file File structure.
303 * @param buf Source buffer.
304 * @param count Size of source buffer.
305 * @param f_pos Position in file (ignored).
306 *
307 * @return Number of bytes read, or <0 on error.
308 */
309ssize_t smschar_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos)
310{
311 smschar_device_t *dev = file->private_data;
312 void *buffer;
313
314 if (!dev->smsclient)
315 {
316 PERROR("no client\n");
317 return -ENODEV;
318 }
319
320 buffer = kmalloc(ALIGN(count, SMS_ALLOC_ALIGNMENT) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
321 if (buffer)
322 {
323 void *msg_buffer = (void*) SMS_ALIGN_ADDRESS(buffer);
324
325 if (!copy_from_user(msg_buffer, buf, count))
326 smsclient_sendrequest(dev->smsclient, msg_buffer, count);
327 else
328 count = 0;
329
330 kfree(buffer);
331 }
332
333 return count;
334}
335
336int smschar_mmap(struct file *file, struct vm_area_struct *vma)
337{
338 smschar_device_t *dev = file->private_data;
339 return smscore_map_common_buffer(dev->coredev, vma);
340}
341
342/**
343 * waits until buffer inserted into a queue. when inserted buffer offset are reported
344 * to the calling process. previously reported buffer is returned to smscore pool
345 *
346 * @param dev pointer to smschar parameters block
347 * @param touser pointer to a structure that receives incoming buffer offsets
348 *
349 * @return 0 on success, <0 on error.
350 */
351int smschar_wait_get_buffer(smschar_device_t* dev, smschar_buffer_t* touser)
352{
353 unsigned long flags;
354 int rc;
355
356 spin_lock_irqsave(&dev->lock, flags);
357
358 if (dev->currentcb)
359 {
360 smscore_putbuffer(dev->coredev, dev->currentcb);
361 dev->currentcb = NULL;
362 dev->pending_count --;
363 }
364
365 spin_unlock_irqrestore(&dev->lock, flags);
366
367 rc = wait_event_interruptible(dev->waitq, !list_empty(&dev->pending_data));
368 if (rc < 0)
369 {
370 PERROR("wait_event_interruptible error\n");
371 return rc;
372 }
373
374 if (!dev->smsclient)
375 {
376 PERROR("no client\n");
377 return -ENODEV;
378 }
379
380 spin_lock_irqsave(&dev->lock, flags);
381
382 if (!list_empty(&dev->pending_data))
383 {
384 smscore_buffer_t *cb = (smscore_buffer_t *) dev->pending_data.next;
385
386 touser->offset = cb->offset_in_common + cb->offset;
387 touser->size = cb->size;
388
389 list_del(&cb->entry);
390
391 dev->currentcb = cb;
392 }
393 else
394 {
395 touser->offset = 0;
396 touser->size = 0;
397 }
398
399 spin_unlock_irqrestore(&dev->lock, flags);
400
401 return 0;
402}
403
404int smschar_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
405{
406 smschar_device_t *dev = file->private_data;
407 void __user *up = (void __user *) arg;
408
409 if (!dev->coredev || !dev->smsclient)
410 {
411 PERROR("no client\n");
412 return -ENODEV;
413 }
414
415 switch(cmd)
416 {
417 case SMSCHAR_SET_DEVICE_MODE:
418 return smscore_set_device_mode(dev->coredev, (int) arg);
419
420 case SMSCHAR_GET_DEVICE_MODE:
421 {
422 if (put_user(smscore_get_device_mode(dev->coredev), (int*) up))
423 return -EFAULT;
424
425 break;
426 }
427
428 case SMSCHAR_GET_BUFFER_SIZE:
429 {
430 if (put_user(smscore_get_common_buffer_size(dev->coredev), (int*) up))
431 return -EFAULT;
432
433 break;
434 }
435
436 case SMSCHAR_WAIT_GET_BUFFER:
437 {
438 smschar_buffer_t touser;
439 int rc;
440
441 rc = smschar_wait_get_buffer(dev, &touser);
442 if (rc < 0)
443 return rc;
444
445 if (copy_to_user(up, &touser, sizeof(smschar_buffer_t)))
446 return -EFAULT;
447
448 break;
449 }
450
451 default:
452 return -ENOIOCTLCMD;
453 }
454
455 return 0;
456}
457
458struct file_operations smschar_fops =
459{
460 .owner = THIS_MODULE,
461 .read = smschar_read,
462 .write = smschar_write,
463 .open = smschar_open,
464 .release = smschar_release,
465 .mmap = smschar_mmap,
466 .ioctl = smschar_ioctl,
467};
468
469static int smschar_setup_cdev ( smschar_device_t *dev, int index )
470{
471 int rc, devno = MKDEV ( smschar_major, smschar_minor + index );
472
473 cdev_init ( &dev->cdev, &smschar_fops );
474
475 dev->cdev.owner = THIS_MODULE;
476 dev->cdev.ops = &smschar_fops;
477
478 kobject_set_name(&dev->cdev.kobj, "Siano_sms%d", index);
479
480 rc = cdev_add ( &dev->cdev, devno, 1 );
481
482 PDEBUG("exiting %p %d, rc %d\n", dev, index, rc);
483
484 return rc;
485}
486
487/**
488 * smschar callback that called when device plugged in/out. the function
489 * register or unregisters char device interface according to plug in/out
490 *
491 * @param coredev pointer to device that is being plugged in/out
492 * @param device pointer to system device object
493 * @param arrival 1 on plug-on, 0 othewise
494 *
495 * @return 0 on success, <0 on error.
496 */
497int smschar_hotplug(smscore_device_t* coredev, struct device* device, int arrival)
498{
499 int rc = 0, i;
500
501 PDEBUG("entering %d\n", arrival);
502
503 if (arrival)
504 {
505 // currently only 1 instance supported
506 if (!g_smschar_inuse)
507 {
508 /* data notification callbacks assignment */
509 memset ( smschar_devices, 0, SMSCHAR_NR_DEVS * sizeof ( smschar_device_t ) );
510
511 /* Initialize each device. */
512 for (i = 0; i < SMSCHAR_NR_DEVS; i++)
513 {
514 smschar_setup_cdev ( &smschar_devices[i], i );
515
516 INIT_LIST_HEAD(&smschar_devices[i].pending_data);
517 spin_lock_init(&smschar_devices[i].lock);
518 init_waitqueue_head(&smschar_devices[i].waitq);
519
520 smschar_devices[i].coredev = coredev;
521 smschar_devices[i].device_index = i;
522 }
523
524 g_smschar_inuse = 1;
525 }
526 }
527 else
528 {
529 // currently only 1 instance supported
530 if (g_smschar_inuse)
531 {
532 /* Get rid of our char dev entries */
533 for(i = 0; i < SMSCHAR_NR_DEVS; i++)
534 cdev_del(&smschar_devices[i].cdev);
535
536 g_smschar_inuse = 0;
537 }
538 }
539
540 PDEBUG("exiting, rc %d\n", rc);
541
542 return rc; /* succeed */
543}
544
545int smschar_initialize(void)
546{
547 dev_t devno = MKDEV ( smschar_major, smschar_minor );
548 int rc;
549
550 if(smschar_major)
551 {
552 rc = register_chrdev_region ( devno, SMSCHAR_NR_DEVS, "smschar" );
553 }
554 else
555 {
556 rc = alloc_chrdev_region ( &devno, smschar_minor, SMSCHAR_NR_DEVS, "smschar" );
557 smschar_major = MAJOR ( devno );
558 }
559
560 if (rc < 0)
561 {
562 PWARNING ( "smschar: can't get major %d\n", smschar_major );
563 return rc;
564 }
565
566 return smscore_register_hotplug(smschar_hotplug);
567}
568EXPORT_SYMBOL(smschar_initialize);
569
570void smschar_terminate(void)
571{
572 dev_t devno = MKDEV ( smschar_major, smschar_minor );
573
574 unregister_chrdev_region(devno, SMSCHAR_NR_DEVS);
575 smscore_unregister_hotplug(smschar_hotplug);
576}
577EXPORT_SYMBOL(smschar_terminate);
diff --git a/drivers/media/mdtv/smschar.h b/drivers/media/mdtv/smschar.h
deleted file mode 100644
index 1cd2f32a7f71..000000000000
--- a/drivers/media/mdtv/smschar.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __smschar_h__
2#define __smschar_h__
3
4extern int smschar_initialize(void);
5extern void smschar_terminate(void);
6
7#endif // __smschar_h__
diff --git a/drivers/media/mdtv/smscharioctl.h b/drivers/media/mdtv/smscharioctl.h
deleted file mode 100644
index e57b89efc499..000000000000
--- a/drivers/media/mdtv/smscharioctl.h
+++ /dev/null
@@ -1,17 +0,0 @@
1#ifndef __smscharioctl_h__
2#define __smscharioctl_h__
3
4#include <linux/ioctl.h>
5
6typedef struct _smschar_buffer_t
7{
8 unsigned long offset; // offset in common buffer (mapped to user space)
9 int size;
10} smschar_buffer_t;
11
12#define SMSCHAR_SET_DEVICE_MODE _IOW('K', 0, int)
13#define SMSCHAR_GET_DEVICE_MODE _IOR('K', 1, int)
14#define SMSCHAR_GET_BUFFER_SIZE _IOR('K', 2, int)
15#define SMSCHAR_WAIT_GET_BUFFER _IOR('K', 3, smschar_buffer_t)
16
17#endif // __smscharioctl_h__
diff --git a/drivers/media/mdtv/smscoreapi.c b/drivers/media/mdtv/smscoreapi.c
index a354912391a0..315319483798 100644
--- a/drivers/media/mdtv/smscoreapi.c
+++ b/drivers/media/mdtv/smscoreapi.c
@@ -34,8 +34,6 @@
34#include "smscoreapi.h" 34#include "smscoreapi.h"
35#include "smstypes.h" 35#include "smstypes.h"
36 36
37#include "smschar.h"
38
39typedef struct _smscore_device_notifyee 37typedef struct _smscore_device_notifyee
40{ 38{
41 struct list_head entry; 39 struct list_head entry;
@@ -1100,7 +1098,7 @@ int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct *
1100 1098
1101int smscore_module_init(void) 1099int smscore_module_init(void)
1102{ 1100{
1103 int rc; 1101 int rc = 0;
1104 1102
1105 INIT_LIST_HEAD(&g_smscore_notifyees); 1103 INIT_LIST_HEAD(&g_smscore_notifyees);
1106 INIT_LIST_HEAD(&g_smscore_devices); 1104 INIT_LIST_HEAD(&g_smscore_devices);
@@ -1109,8 +1107,6 @@ int smscore_module_init(void)
1109 INIT_LIST_HEAD(&g_smscore_registry); 1107 INIT_LIST_HEAD(&g_smscore_registry);
1110 kmutex_init(&g_smscore_registrylock); 1108 kmutex_init(&g_smscore_registrylock);
1111 1109
1112 rc = smschar_initialize();
1113
1114 printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); 1110 printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc);
1115 1111
1116 return rc; 1112 return rc;
@@ -1118,8 +1114,6 @@ int smscore_module_init(void)
1118 1114
1119void smscore_module_exit(void) 1115void smscore_module_exit(void)
1120{ 1116{
1121 smschar_terminate();
1122
1123 kmutex_lock(&g_smscore_deviceslock); 1117 kmutex_lock(&g_smscore_deviceslock);
1124 while (!list_empty(&g_smscore_notifyees)) 1118 while (!list_empty(&g_smscore_notifyees))
1125 { 1119 {