aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/dsbr100.c381
-rw-r--r--drivers/media/radio/radio-aimslab.c2
-rw-r--r--drivers/media/radio/radio-cadet.c2
-rw-r--r--drivers/media/radio/radio-gemtek.c2
-rw-r--r--drivers/media/radio/radio-mr800.c123
-rw-r--r--drivers/media/radio/radio-rtrack2.c2
-rw-r--r--drivers/media/radio/radio-sf16fmi.c2
7 files changed, 386 insertions, 128 deletions
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index a5ca176a7b08..5474a22c1b22 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -1,5 +1,5 @@
1/* A driver for the D-Link DSB-R100 USB radio. The R100 plugs 1/* A driver for the D-Link DSB-R100 USB radio and Gemtek USB Radio 21.
2 into both the USB and an analog audio input, so this thing 2 The device plugs into both the USB and an analog audio input, so this thing
3 only deals with initialisation and frequency setting, the 3 only deals with initialisation and frequency setting, the
4 audio data has to be handled by a sound driver. 4 audio data has to be handled by a sound driver.
5 5
@@ -33,6 +33,10 @@
33 33
34 History: 34 History:
35 35
36 Version 0.44:
37 Add suspend/resume functions, fix unplug of device,
38 a lot of cleanups and fixes by Alexey Klimov <klimov.linux@gmail.com>
39
36 Version 0.43: 40 Version 0.43:
37 Oliver Neukum: avoided DMA coherency issue 41 Oliver Neukum: avoided DMA coherency issue
38 42
@@ -93,8 +97,8 @@
93 */ 97 */
94#include <linux/version.h> /* for KERNEL_VERSION MACRO */ 98#include <linux/version.h> /* for KERNEL_VERSION MACRO */
95 99
96#define DRIVER_VERSION "v0.41" 100#define DRIVER_VERSION "v0.44"
97#define RADIO_VERSION KERNEL_VERSION(0,4,1) 101#define RADIO_VERSION KERNEL_VERSION(0, 4, 4)
98 102
99static struct v4l2_queryctrl radio_qctrl[] = { 103static struct v4l2_queryctrl radio_qctrl[] = {
100 { 104 {
@@ -104,7 +108,27 @@ static struct v4l2_queryctrl radio_qctrl[] = {
104 .maximum = 1, 108 .maximum = 1,
105 .default_value = 1, 109 .default_value = 1,
106 .type = V4L2_CTRL_TYPE_BOOLEAN, 110 .type = V4L2_CTRL_TYPE_BOOLEAN,
107 } 111 },
112/* HINT: the disabled controls are only here to satify kradio and such apps */
113 { .id = V4L2_CID_AUDIO_VOLUME,
114 .flags = V4L2_CTRL_FLAG_DISABLED,
115 },
116 {
117 .id = V4L2_CID_AUDIO_BALANCE,
118 .flags = V4L2_CTRL_FLAG_DISABLED,
119 },
120 {
121 .id = V4L2_CID_AUDIO_BASS,
122 .flags = V4L2_CTRL_FLAG_DISABLED,
123 },
124 {
125 .id = V4L2_CID_AUDIO_TREBLE,
126 .flags = V4L2_CTRL_FLAG_DISABLED,
127 },
128 {
129 .id = V4L2_CID_AUDIO_LOUDNESS,
130 .flags = V4L2_CTRL_FLAG_DISABLED,
131 },
108}; 132};
109 133
110#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>" 134#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
@@ -125,12 +149,16 @@ devices, that would be 76 and 91. */
125#define FREQ_MAX 108.0 149#define FREQ_MAX 108.0
126#define FREQ_MUL 16000 150#define FREQ_MUL 16000
127 151
152#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev)
128 153
129static int usb_dsbr100_probe(struct usb_interface *intf, 154static int usb_dsbr100_probe(struct usb_interface *intf,
130 const struct usb_device_id *id); 155 const struct usb_device_id *id);
131static void usb_dsbr100_disconnect(struct usb_interface *intf); 156static void usb_dsbr100_disconnect(struct usb_interface *intf);
132static int usb_dsbr100_open(struct inode *inode, struct file *file); 157static int usb_dsbr100_open(struct inode *inode, struct file *file);
133static int usb_dsbr100_close(struct inode *inode, struct file *file); 158static int usb_dsbr100_close(struct inode *inode, struct file *file);
159static int usb_dsbr100_suspend(struct usb_interface *intf,
160 pm_message_t message);
161static int usb_dsbr100_resume(struct usb_interface *intf);
134 162
135static int radio_nr = -1; 163static int radio_nr = -1;
136module_param(radio_nr, int, 0); 164module_param(radio_nr, int, 0);
@@ -138,8 +166,9 @@ module_param(radio_nr, int, 0);
138/* Data for one (physical) device */ 166/* Data for one (physical) device */
139struct dsbr100_device { 167struct dsbr100_device {
140 struct usb_device *usbdev; 168 struct usb_device *usbdev;
141 struct video_device *videodev; 169 struct video_device videodev;
142 u8 *transfer_buffer; 170 u8 *transfer_buffer;
171 struct mutex lock; /* buffer locking */
143 int curfreq; 172 int curfreq;
144 int stereo; 173 int stereo;
145 int users; 174 int users;
@@ -147,7 +176,6 @@ struct dsbr100_device {
147 int muted; 176 int muted;
148}; 177};
149 178
150
151static struct usb_device_id usb_dsbr100_device_table [] = { 179static struct usb_device_id usb_dsbr100_device_table [] = {
152 { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) }, 180 { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
153 { } /* Terminating entry */ 181 { } /* Terminating entry */
@@ -157,10 +185,14 @@ MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
157 185
158/* USB subsystem interface */ 186/* USB subsystem interface */
159static struct usb_driver usb_dsbr100_driver = { 187static struct usb_driver usb_dsbr100_driver = {
160 .name = "dsbr100", 188 .name = "dsbr100",
161 .probe = usb_dsbr100_probe, 189 .probe = usb_dsbr100_probe,
162 .disconnect = usb_dsbr100_disconnect, 190 .disconnect = usb_dsbr100_disconnect,
163 .id_table = usb_dsbr100_device_table, 191 .id_table = usb_dsbr100_device_table,
192 .suspend = usb_dsbr100_suspend,
193 .resume = usb_dsbr100_resume,
194 .reset_resume = usb_dsbr100_resume,
195 .supports_autosuspend = 0,
164}; 196};
165 197
166/* Low-level device interface begins here */ 198/* Low-level device interface begins here */
@@ -168,95 +200,190 @@ static struct usb_driver usb_dsbr100_driver = {
168/* switch on radio */ 200/* switch on radio */
169static int dsbr100_start(struct dsbr100_device *radio) 201static int dsbr100_start(struct dsbr100_device *radio)
170{ 202{
171 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 203 int retval;
172 USB_REQ_GET_STATUS, 204 int request;
173 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 205
174 0x00, 0xC7, radio->transfer_buffer, 8, 300) < 0 || 206 mutex_lock(&radio->lock);
175 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 207
176 DSB100_ONOFF, 208 retval = usb_control_msg(radio->usbdev,
177 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 209 usb_rcvctrlpipe(radio->usbdev, 0),
178 0x01, 0x00, radio->transfer_buffer, 8, 300) < 0) 210 USB_REQ_GET_STATUS,
179 return -1; 211 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
180 radio->muted=0; 212 0x00, 0xC7, radio->transfer_buffer, 8, 300);
213
214 if (retval < 0) {
215 request = USB_REQ_GET_STATUS;
216 goto usb_control_msg_failed;
217 }
218
219 retval = usb_control_msg(radio->usbdev,
220 usb_rcvctrlpipe(radio->usbdev, 0),
221 DSB100_ONOFF,
222 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
223 0x01, 0x00, radio->transfer_buffer, 8, 300);
224
225 if (retval < 0) {
226 request = DSB100_ONOFF;
227 goto usb_control_msg_failed;
228 }
229
230 radio->muted = 0;
231 mutex_unlock(&radio->lock);
181 return (radio->transfer_buffer)[0]; 232 return (radio->transfer_buffer)[0];
182}
183 233
234usb_control_msg_failed:
235 mutex_unlock(&radio->lock);
236 dev_err(&radio->usbdev->dev,
237 "%s - usb_control_msg returned %i, request %i\n",
238 __func__, retval, request);
239 return retval;
240
241}
184 242
185/* switch off radio */ 243/* switch off radio */
186static int dsbr100_stop(struct dsbr100_device *radio) 244static int dsbr100_stop(struct dsbr100_device *radio)
187{ 245{
188 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 246 int retval;
189 USB_REQ_GET_STATUS, 247 int request;
190 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 248
191 0x16, 0x1C, radio->transfer_buffer, 8, 300) < 0 || 249 mutex_lock(&radio->lock);
192 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 250
193 DSB100_ONOFF, 251 retval = usb_control_msg(radio->usbdev,
194 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 252 usb_rcvctrlpipe(radio->usbdev, 0),
195 0x00, 0x00, radio->transfer_buffer, 8, 300) < 0) 253 USB_REQ_GET_STATUS,
196 return -1; 254 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
197 radio->muted=1; 255 0x16, 0x1C, radio->transfer_buffer, 8, 300);
256
257 if (retval < 0) {
258 request = USB_REQ_GET_STATUS;
259 goto usb_control_msg_failed;
260 }
261
262 retval = usb_control_msg(radio->usbdev,
263 usb_rcvctrlpipe(radio->usbdev, 0),
264 DSB100_ONOFF,
265 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
266 0x00, 0x00, radio->transfer_buffer, 8, 300);
267
268 if (retval < 0) {
269 request = DSB100_ONOFF;
270 goto usb_control_msg_failed;
271 }
272
273 radio->muted = 1;
274 mutex_unlock(&radio->lock);
198 return (radio->transfer_buffer)[0]; 275 return (radio->transfer_buffer)[0];
276
277usb_control_msg_failed:
278 mutex_unlock(&radio->lock);
279 dev_err(&radio->usbdev->dev,
280 "%s - usb_control_msg returned %i, request %i\n",
281 __func__, retval, request);
282 return retval;
283
199} 284}
200 285
201/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ 286/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
202static int dsbr100_setfreq(struct dsbr100_device *radio, int freq) 287static int dsbr100_setfreq(struct dsbr100_device *radio, int freq)
203{ 288{
289 int retval;
290 int request;
291
204 freq = (freq / 16 * 80) / 1000 + 856; 292 freq = (freq / 16 * 80) / 1000 + 856;
205 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 293 mutex_lock(&radio->lock);
206 DSB100_TUNE, 294
207 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 295 retval = usb_control_msg(radio->usbdev,
208 (freq >> 8) & 0x00ff, freq & 0xff, 296 usb_rcvctrlpipe(radio->usbdev, 0),
209 radio->transfer_buffer, 8, 300) < 0 || 297 DSB100_TUNE,
210 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 298 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
211 USB_REQ_GET_STATUS, 299 (freq >> 8) & 0x00ff, freq & 0xff,
212 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 300 radio->transfer_buffer, 8, 300);
213 0x96, 0xB7, radio->transfer_buffer, 8, 300) < 0 || 301
214 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 302 if (retval < 0) {
215 USB_REQ_GET_STATUS, 303 request = DSB100_TUNE;
216 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 304 goto usb_control_msg_failed;
217 0x00, 0x24, radio->transfer_buffer, 8, 300) < 0) {
218 radio->stereo = -1;
219 return -1;
220 } 305 }
306
307 retval = usb_control_msg(radio->usbdev,
308 usb_rcvctrlpipe(radio->usbdev, 0),
309 USB_REQ_GET_STATUS,
310 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
311 0x96, 0xB7, radio->transfer_buffer, 8, 300);
312
313 if (retval < 0) {
314 request = USB_REQ_GET_STATUS;
315 goto usb_control_msg_failed;
316 }
317
318 retval = usb_control_msg(radio->usbdev,
319 usb_rcvctrlpipe(radio->usbdev, 0),
320 USB_REQ_GET_STATUS,
321 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
322 0x00, 0x24, radio->transfer_buffer, 8, 300);
323
324 if (retval < 0) {
325 request = USB_REQ_GET_STATUS;
326 goto usb_control_msg_failed;
327 }
328
221 radio->stereo = !((radio->transfer_buffer)[0] & 0x01); 329 radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
330 mutex_unlock(&radio->lock);
222 return (radio->transfer_buffer)[0]; 331 return (radio->transfer_buffer)[0];
332
333usb_control_msg_failed:
334 radio->stereo = -1;
335 mutex_unlock(&radio->lock);
336 dev_err(&radio->usbdev->dev,
337 "%s - usb_control_msg returned %i, request %i\n",
338 __func__, retval, request);
339 return retval;
223} 340}
224 341
225/* return the device status. This is, in effect, just whether it 342/* return the device status. This is, in effect, just whether it
226sees a stereo signal or not. Pity. */ 343sees a stereo signal or not. Pity. */
227static void dsbr100_getstat(struct dsbr100_device *radio) 344static void dsbr100_getstat(struct dsbr100_device *radio)
228{ 345{
229 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 346 int retval;
347
348 mutex_lock(&radio->lock);
349
350 retval = usb_control_msg(radio->usbdev,
351 usb_rcvctrlpipe(radio->usbdev, 0),
230 USB_REQ_GET_STATUS, 352 USB_REQ_GET_STATUS,
231 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 353 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
232 0x00 , 0x24, radio->transfer_buffer, 8, 300) < 0) 354 0x00 , 0x24, radio->transfer_buffer, 8, 300);
355
356 if (retval < 0) {
233 radio->stereo = -1; 357 radio->stereo = -1;
234 else 358 dev_err(&radio->usbdev->dev,
359 "%s - usb_control_msg returned %i, request %i\n",
360 __func__, retval, USB_REQ_GET_STATUS);
361 } else {
235 radio->stereo = !(radio->transfer_buffer[0] & 0x01); 362 radio->stereo = !(radio->transfer_buffer[0] & 0x01);
236} 363 }
237 364
365 mutex_unlock(&radio->lock);
366}
238 367
239/* USB subsystem interface begins here */ 368/* USB subsystem interface begins here */
240 369
241/* handle unplugging of the device, release data structures 370/*
242if nothing keeps us from doing it. If something is still 371 * Handle unplugging of the device.
243keeping us busy, the release callback of v4l will take care 372 * We call video_unregister_device in any case.
244of releasing it. */ 373 * The last function called in this procedure is
374 * usb_dsbr100_video_device_release
375 */
245static void usb_dsbr100_disconnect(struct usb_interface *intf) 376static void usb_dsbr100_disconnect(struct usb_interface *intf)
246{ 377{
247 struct dsbr100_device *radio = usb_get_intfdata(intf); 378 struct dsbr100_device *radio = usb_get_intfdata(intf);
248 379
249 usb_set_intfdata (intf, NULL); 380 usb_set_intfdata (intf, NULL);
250 if (radio) { 381
251 video_unregister_device(radio->videodev); 382 mutex_lock(&radio->lock);
252 radio->videodev = NULL; 383 radio->removed = 1;
253 if (radio->users) { 384 mutex_unlock(&radio->lock);
254 kfree(radio->transfer_buffer); 385
255 kfree(radio); 386 video_unregister_device(&radio->videodev);
256 } else {
257 radio->removed = 1;
258 }
259 }
260} 387}
261 388
262 389
@@ -276,6 +403,10 @@ static int vidioc_g_tuner(struct file *file, void *priv,
276{ 403{
277 struct dsbr100_device *radio = video_drvdata(file); 404 struct dsbr100_device *radio = video_drvdata(file);
278 405
406 /* safety check */
407 if (radio->removed)
408 return -EIO;
409
279 if (v->index > 0) 410 if (v->index > 0)
280 return -EINVAL; 411 return -EINVAL;
281 412
@@ -297,6 +428,12 @@ static int vidioc_g_tuner(struct file *file, void *priv,
297static int vidioc_s_tuner(struct file *file, void *priv, 428static int vidioc_s_tuner(struct file *file, void *priv,
298 struct v4l2_tuner *v) 429 struct v4l2_tuner *v)
299{ 430{
431 struct dsbr100_device *radio = video_drvdata(file);
432
433 /* safety check */
434 if (radio->removed)
435 return -EIO;
436
300 if (v->index > 0) 437 if (v->index > 0)
301 return -EINVAL; 438 return -EINVAL;
302 439
@@ -307,9 +444,15 @@ static int vidioc_s_frequency(struct file *file, void *priv,
307 struct v4l2_frequency *f) 444 struct v4l2_frequency *f)
308{ 445{
309 struct dsbr100_device *radio = video_drvdata(file); 446 struct dsbr100_device *radio = video_drvdata(file);
447 int retval;
448
449 /* safety check */
450 if (radio->removed)
451 return -EIO;
310 452
311 radio->curfreq = f->frequency; 453 radio->curfreq = f->frequency;
312 if (dsbr100_setfreq(radio, radio->curfreq) == -1) 454 retval = dsbr100_setfreq(radio, radio->curfreq);
455 if (retval < 0)
313 dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); 456 dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
314 return 0; 457 return 0;
315} 458}
@@ -319,6 +462,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
319{ 462{
320 struct dsbr100_device *radio = video_drvdata(file); 463 struct dsbr100_device *radio = video_drvdata(file);
321 464
465 /* safety check */
466 if (radio->removed)
467 return -EIO;
468
322 f->type = V4L2_TUNER_RADIO; 469 f->type = V4L2_TUNER_RADIO;
323 f->frequency = radio->curfreq; 470 f->frequency = radio->curfreq;
324 return 0; 471 return 0;
@@ -343,6 +490,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
343{ 490{
344 struct dsbr100_device *radio = video_drvdata(file); 491 struct dsbr100_device *radio = video_drvdata(file);
345 492
493 /* safety check */
494 if (radio->removed)
495 return -EIO;
496
346 switch (ctrl->id) { 497 switch (ctrl->id) {
347 case V4L2_CID_AUDIO_MUTE: 498 case V4L2_CID_AUDIO_MUTE:
348 ctrl->value = radio->muted; 499 ctrl->value = radio->muted;
@@ -355,17 +506,24 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
355 struct v4l2_control *ctrl) 506 struct v4l2_control *ctrl)
356{ 507{
357 struct dsbr100_device *radio = video_drvdata(file); 508 struct dsbr100_device *radio = video_drvdata(file);
509 int retval;
510
511 /* safety check */
512 if (radio->removed)
513 return -EIO;
358 514
359 switch (ctrl->id) { 515 switch (ctrl->id) {
360 case V4L2_CID_AUDIO_MUTE: 516 case V4L2_CID_AUDIO_MUTE:
361 if (ctrl->value) { 517 if (ctrl->value) {
362 if (dsbr100_stop(radio) == -1) { 518 retval = dsbr100_stop(radio);
519 if (retval < 0) {
363 dev_warn(&radio->usbdev->dev, 520 dev_warn(&radio->usbdev->dev,
364 "Radio did not respond properly\n"); 521 "Radio did not respond properly\n");
365 return -EBUSY; 522 return -EBUSY;
366 } 523 }
367 } else { 524 } else {
368 if (dsbr100_start(radio) == -1) { 525 retval = dsbr100_start(radio);
526 if (retval < 0) {
369 dev_warn(&radio->usbdev->dev, 527 dev_warn(&radio->usbdev->dev,
370 "Radio did not respond properly\n"); 528 "Radio did not respond properly\n");
371 return -EBUSY; 529 return -EBUSY;
@@ -417,7 +575,8 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
417 radio->users = 1; 575 radio->users = 1;
418 radio->muted = 1; 576 radio->muted = 1;
419 577
420 if (dsbr100_start(radio) < 0) { 578 retval = dsbr100_start(radio);
579 if (retval < 0) {
421 dev_warn(&radio->usbdev->dev, 580 dev_warn(&radio->usbdev->dev,
422 "Radio did not start up properly\n"); 581 "Radio did not start up properly\n");
423 radio->users = 0; 582 radio->users = 0;
@@ -426,9 +585,9 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
426 } 585 }
427 586
428 retval = dsbr100_setfreq(radio, radio->curfreq); 587 retval = dsbr100_setfreq(radio, radio->curfreq);
429 588 if (retval < 0)
430 if (retval == -1) 589 dev_warn(&radio->usbdev->dev,
431 printk(KERN_WARNING KBUILD_MODNAME ": Set frequency failed\n"); 590 "set frequency failed\n");
432 591
433 unlock_kernel(); 592 unlock_kernel();
434 return 0; 593 return 0;
@@ -437,17 +596,62 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
437static int usb_dsbr100_close(struct inode *inode, struct file *file) 596static int usb_dsbr100_close(struct inode *inode, struct file *file)
438{ 597{
439 struct dsbr100_device *radio = video_drvdata(file); 598 struct dsbr100_device *radio = video_drvdata(file);
599 int retval;
440 600
441 if (!radio) 601 if (!radio)
442 return -ENODEV; 602 return -ENODEV;
603
443 radio->users = 0; 604 radio->users = 0;
444 if (radio->removed) { 605 if (!radio->removed) {
445 kfree(radio->transfer_buffer); 606 retval = dsbr100_stop(radio);
446 kfree(radio); 607 if (retval < 0) {
608 dev_warn(&radio->usbdev->dev,
609 "dsbr100_stop failed\n");
610 }
611
447 } 612 }
448 return 0; 613 return 0;
449} 614}
450 615
616/* Suspend device - stop device. */
617static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
618{
619 struct dsbr100_device *radio = usb_get_intfdata(intf);
620 int retval;
621
622 retval = dsbr100_stop(radio);
623 if (retval < 0)
624 dev_warn(&intf->dev, "dsbr100_stop failed\n");
625
626 dev_info(&intf->dev, "going into suspend..\n");
627
628 return 0;
629}
630
631/* Resume device - start device. */
632static int usb_dsbr100_resume(struct usb_interface *intf)
633{
634 struct dsbr100_device *radio = usb_get_intfdata(intf);
635 int retval;
636
637 retval = dsbr100_start(radio);
638 if (retval < 0)
639 dev_warn(&intf->dev, "dsbr100_start failed\n");
640
641 dev_info(&intf->dev, "coming out of suspend..\n");
642
643 return 0;
644}
645
646/* free data structures */
647static void usb_dsbr100_video_device_release(struct video_device *videodev)
648{
649 struct dsbr100_device *radio = videodev_to_radio(videodev);
650
651 kfree(radio->transfer_buffer);
652 kfree(radio);
653}
654
451/* File system interface */ 655/* File system interface */
452static const struct file_operations usb_dsbr100_fops = { 656static const struct file_operations usb_dsbr100_fops = {
453 .owner = THIS_MODULE, 657 .owner = THIS_MODULE,
@@ -476,19 +680,19 @@ static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
476}; 680};
477 681
478/* V4L2 interface */ 682/* V4L2 interface */
479static struct video_device dsbr100_videodev_template = { 683static struct video_device dsbr100_videodev_data = {
480 .name = "D-Link DSB-R 100", 684 .name = "D-Link DSB-R 100",
481 .fops = &usb_dsbr100_fops, 685 .fops = &usb_dsbr100_fops,
482 .ioctl_ops = &usb_dsbr100_ioctl_ops, 686 .ioctl_ops = &usb_dsbr100_ioctl_ops,
483 .release = video_device_release, 687 .release = usb_dsbr100_video_device_release,
484}; 688};
485 689
486/* check if the device is present and register with v4l and 690/* check if the device is present and register with v4l and usb if it is */
487usb if it is */
488static int usb_dsbr100_probe(struct usb_interface *intf, 691static int usb_dsbr100_probe(struct usb_interface *intf,
489 const struct usb_device_id *id) 692 const struct usb_device_id *id)
490{ 693{
491 struct dsbr100_device *radio; 694 struct dsbr100_device *radio;
695 int retval;
492 696
493 radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL); 697 radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL);
494 698
@@ -501,23 +705,18 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
501 kfree(radio); 705 kfree(radio);
502 return -ENOMEM; 706 return -ENOMEM;
503 } 707 }
504 radio->videodev = video_device_alloc();
505 708
506 if (!(radio->videodev)) { 709 mutex_init(&radio->lock);
507 kfree(radio->transfer_buffer); 710 radio->videodev = dsbr100_videodev_data;
508 kfree(radio); 711
509 return -ENOMEM;
510 }
511 memcpy(radio->videodev, &dsbr100_videodev_template,
512 sizeof(dsbr100_videodev_template));
513 radio->removed = 0; 712 radio->removed = 0;
514 radio->users = 0; 713 radio->users = 0;
515 radio->usbdev = interface_to_usbdev(intf); 714 radio->usbdev = interface_to_usbdev(intf);
516 radio->curfreq = FREQ_MIN * FREQ_MUL; 715 radio->curfreq = FREQ_MIN * FREQ_MUL;
517 video_set_drvdata(radio->videodev, radio); 716 video_set_drvdata(&radio->videodev, radio);
518 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) { 717 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr);
519 dev_warn(&intf->dev, "Could not register video device\n"); 718 if (retval < 0) {
520 video_device_release(radio->videodev); 719 dev_err(&intf->dev, "couldn't register video device\n");
521 kfree(radio->transfer_buffer); 720 kfree(radio->transfer_buffer);
522 kfree(radio); 721 kfree(radio);
523 return -EIO; 722 return -EIO;
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 9305e958fc66..dd6d3dfcd7d2 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -1,7 +1,7 @@
1/* radiotrack (radioreveal) driver for Linux radio support 1/* radiotrack (radioreveal) driver for Linux radio support
2 * (c) 1997 M. Kirkwood 2 * (c) 1997 M. Kirkwood
3 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 3 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
4 * Converted to new API by Alan Cox <Alan.Cox@linux.org> 4 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
6 * 6 *
7 * History: 7 * History:
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 0490a1fa999d..bfd37f38b9ab 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -23,7 +23,7 @@
23 * 2002-01-17 Adam Belay <ambx1@neo.rr.com> 23 * 2002-01-17 Adam Belay <ambx1@neo.rr.com>
24 * Updated to latest pnp code 24 * Updated to latest pnp code
25 * 25 *
26 * 2003-01-31 Alan Cox <alan@redhat.com> 26 * 2003-01-31 Alan Cox <alan@lxorguk.ukuu.org.uk>
27 * Cleaned up locking, delay code, general odds and ends 27 * Cleaned up locking, delay code, general odds and ends
28 * 28 *
29 * 2006-07-30 Hans J. Koch <koch@hjk-az.de> 29 * 2006-07-30 Hans J. Koch <koch@hjk-az.de>
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index d131a5d38128..e13118da307b 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -8,7 +8,7 @@
8 * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff 8 * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
9 * 9 *
10 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood 10 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
11 * Converted to new API by Alan Cox <Alan.Cox@linux.org> 11 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
12 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 12 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
13 * 13 *
14 * TODO: Allow for more than one of these foolish entities :-) 14 * TODO: Allow for more than one of these foolish entities :-)
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 256cbeffdcb6..e730eddb2bb5 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -72,6 +72,11 @@ MODULE_LICENSE("GPL");
72#define USB_AMRADIO_VENDOR 0x07ca 72#define USB_AMRADIO_VENDOR 0x07ca
73#define USB_AMRADIO_PRODUCT 0xb800 73#define USB_AMRADIO_PRODUCT 0xb800
74 74
75/* dev_warn macro with driver name */
76#define MR800_DRIVER_NAME "radio-mr800"
77#define amradio_dev_warn(dev, fmt, arg...) \
78 dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
79
75/* Probably USB_TIMEOUT should be modified in module parameter */ 80/* Probably USB_TIMEOUT should be modified in module parameter */
76#define BUFFER_LENGTH 8 81#define BUFFER_LENGTH 8
77#define USB_TIMEOUT 500 82#define USB_TIMEOUT 500
@@ -154,14 +159,14 @@ MODULE_DEVICE_TABLE(usb, usb_amradio_device_table);
154 159
155/* USB subsystem interface */ 160/* USB subsystem interface */
156static struct usb_driver usb_amradio_driver = { 161static struct usb_driver usb_amradio_driver = {
157 .name = "radio-mr800", 162 .name = MR800_DRIVER_NAME,
158 .probe = usb_amradio_probe, 163 .probe = usb_amradio_probe,
159 .disconnect = usb_amradio_disconnect, 164 .disconnect = usb_amradio_disconnect,
160 .suspend = usb_amradio_suspend, 165 .suspend = usb_amradio_suspend,
161 .resume = usb_amradio_resume, 166 .resume = usb_amradio_resume,
162 .reset_resume = usb_amradio_resume, 167 .reset_resume = usb_amradio_resume,
163 .id_table = usb_amradio_device_table, 168 .id_table = usb_amradio_device_table,
164 .supports_autosuspend = 1, 169 .supports_autosuspend = 0,
165}; 170};
166 171
167/* switch on radio. Send 8 bytes to device. */ 172/* switch on radio. Send 8 bytes to device. */
@@ -202,6 +207,10 @@ static int amradio_stop(struct amradio_device *radio)
202 int retval; 207 int retval;
203 int size; 208 int size;
204 209
210 /* safety check */
211 if (radio->removed)
212 return -EIO;
213
205 mutex_lock(&radio->lock); 214 mutex_lock(&radio->lock);
206 215
207 radio->buffer[0] = 0x00; 216 radio->buffer[0] = 0x00;
@@ -235,6 +244,10 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
235 int size; 244 int size;
236 unsigned short freq_send = 0x13 + (freq >> 3) / 25; 245 unsigned short freq_send = 0x13 + (freq >> 3) / 25;
237 246
247 /* safety check */
248 if (radio->removed)
249 return -EIO;
250
238 mutex_lock(&radio->lock); 251 mutex_lock(&radio->lock);
239 252
240 radio->buffer[0] = 0x00; 253 radio->buffer[0] = 0x00;
@@ -288,18 +301,12 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
288{ 301{
289 struct amradio_device *radio = usb_get_intfdata(intf); 302 struct amradio_device *radio = usb_get_intfdata(intf);
290 303
291 usb_set_intfdata(intf, NULL); 304 mutex_lock(&radio->lock);
305 radio->removed = 1;
306 mutex_unlock(&radio->lock);
292 307
293 if (radio) { 308 usb_set_intfdata(intf, NULL);
294 video_unregister_device(radio->videodev); 309 video_unregister_device(radio->videodev);
295 radio->videodev = NULL;
296 if (radio->users) {
297 kfree(radio->buffer);
298 kfree(radio);
299 } else {
300 radio->removed = 1;
301 }
302 }
303} 310}
304 311
305/* vidioc_querycap - query device capabilities */ 312/* vidioc_querycap - query device capabilities */
@@ -320,6 +327,10 @@ static int vidioc_g_tuner(struct file *file, void *priv,
320{ 327{
321 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 328 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
322 329
330 /* safety check */
331 if (radio->removed)
332 return -EIO;
333
323 if (v->index > 0) 334 if (v->index > 0)
324 return -EINVAL; 335 return -EINVAL;
325 336
@@ -346,6 +357,12 @@ static int vidioc_g_tuner(struct file *file, void *priv,
346static int vidioc_s_tuner(struct file *file, void *priv, 357static int vidioc_s_tuner(struct file *file, void *priv,
347 struct v4l2_tuner *v) 358 struct v4l2_tuner *v)
348{ 359{
360 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
361
362 /* safety check */
363 if (radio->removed)
364 return -EIO;
365
349 if (v->index > 0) 366 if (v->index > 0)
350 return -EINVAL; 367 return -EINVAL;
351 return 0; 368 return 0;
@@ -357,9 +374,14 @@ static int vidioc_s_frequency(struct file *file, void *priv,
357{ 374{
358 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 375 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
359 376
377 /* safety check */
378 if (radio->removed)
379 return -EIO;
380
360 radio->curfreq = f->frequency; 381 radio->curfreq = f->frequency;
361 if (amradio_setfreq(radio, radio->curfreq) < 0) 382 if (amradio_setfreq(radio, radio->curfreq) < 0)
362 warn("Set frequency failed"); 383 amradio_dev_warn(&radio->videodev->dev,
384 "set frequency failed\n");
363 return 0; 385 return 0;
364} 386}
365 387
@@ -369,6 +391,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
369{ 391{
370 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 392 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
371 393
394 /* safety check */
395 if (radio->removed)
396 return -EIO;
397
372 f->type = V4L2_TUNER_RADIO; 398 f->type = V4L2_TUNER_RADIO;
373 f->frequency = radio->curfreq; 399 f->frequency = radio->curfreq;
374 return 0; 400 return 0;
@@ -382,8 +408,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
382 408
383 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 409 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
384 if (qc->id && qc->id == radio_qctrl[i].id) { 410 if (qc->id && qc->id == radio_qctrl[i].id) {
385 memcpy(qc, &(radio_qctrl[i]), 411 memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
386 sizeof(*qc));
387 return 0; 412 return 0;
388 } 413 }
389 } 414 }
@@ -396,6 +421,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
396{ 421{
397 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 422 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
398 423
424 /* safety check */
425 if (radio->removed)
426 return -EIO;
427
399 switch (ctrl->id) { 428 switch (ctrl->id) {
400 case V4L2_CID_AUDIO_MUTE: 429 case V4L2_CID_AUDIO_MUTE:
401 ctrl->value = radio->muted; 430 ctrl->value = radio->muted;
@@ -410,16 +439,22 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
410{ 439{
411 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 440 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
412 441
442 /* safety check */
443 if (radio->removed)
444 return -EIO;
445
413 switch (ctrl->id) { 446 switch (ctrl->id) {
414 case V4L2_CID_AUDIO_MUTE: 447 case V4L2_CID_AUDIO_MUTE:
415 if (ctrl->value) { 448 if (ctrl->value) {
416 if (amradio_stop(radio) < 0) { 449 if (amradio_stop(radio) < 0) {
417 warn("amradio_stop() failed"); 450 amradio_dev_warn(&radio->videodev->dev,
451 "amradio_stop failed\n");
418 return -1; 452 return -1;
419 } 453 }
420 } else { 454 } else {
421 if (amradio_start(radio) < 0) { 455 if (amradio_start(radio) < 0) {
422 warn("amradio_start() failed"); 456 amradio_dev_warn(&radio->videodev->dev,
457 "amradio_start failed\n");
423 return -1; 458 return -1;
424 } 459 }
425 } 460 }
@@ -475,30 +510,38 @@ static int usb_amradio_open(struct inode *inode, struct file *file)
475 radio->muted = 1; 510 radio->muted = 1;
476 511
477 if (amradio_start(radio) < 0) { 512 if (amradio_start(radio) < 0) {
478 warn("Radio did not start up properly"); 513 amradio_dev_warn(&radio->videodev->dev,
514 "radio did not start up properly\n");
479 radio->users = 0; 515 radio->users = 0;
480 unlock_kernel(); 516 unlock_kernel();
481 return -EIO; 517 return -EIO;
482 } 518 }
483 if (amradio_setfreq(radio, radio->curfreq) < 0) 519 if (amradio_setfreq(radio, radio->curfreq) < 0)
484 warn("Set frequency failed"); 520 amradio_dev_warn(&radio->videodev->dev,
521 "set frequency failed\n");
485 522
486 unlock_kernel(); 523 unlock_kernel();
487 return 0; 524 return 0;
488} 525}
489 526
490/*close device - free driver structures */ 527/*close device */
491static int usb_amradio_close(struct inode *inode, struct file *file) 528static int usb_amradio_close(struct inode *inode, struct file *file)
492{ 529{
493 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 530 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
531 int retval;
494 532
495 if (!radio) 533 if (!radio)
496 return -ENODEV; 534 return -ENODEV;
535
497 radio->users = 0; 536 radio->users = 0;
498 if (radio->removed) { 537
499 kfree(radio->buffer); 538 if (!radio->removed) {
500 kfree(radio); 539 retval = amradio_stop(radio);
540 if (retval < 0)
541 amradio_dev_warn(&radio->videodev->dev,
542 "amradio_stop failed\n");
501 } 543 }
544
502 return 0; 545 return 0;
503} 546}
504 547
@@ -508,9 +551,9 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
508 struct amradio_device *radio = usb_get_intfdata(intf); 551 struct amradio_device *radio = usb_get_intfdata(intf);
509 552
510 if (amradio_stop(radio) < 0) 553 if (amradio_stop(radio) < 0)
511 warn("amradio_stop() failed"); 554 dev_warn(&intf->dev, "amradio_stop failed\n");
512 555
513 info("radio-mr800: Going into suspend.."); 556 dev_info(&intf->dev, "going into suspend..\n");
514 557
515 return 0; 558 return 0;
516} 559}
@@ -521,9 +564,9 @@ static int usb_amradio_resume(struct usb_interface *intf)
521 struct amradio_device *radio = usb_get_intfdata(intf); 564 struct amradio_device *radio = usb_get_intfdata(intf);
522 565
523 if (amradio_start(radio) < 0) 566 if (amradio_start(radio) < 0)
524 warn("amradio_start() failed"); 567 dev_warn(&intf->dev, "amradio_start failed\n");
525 568
526 info("radio-mr800: Coming out of suspend.."); 569 dev_info(&intf->dev, "coming out of suspend..\n");
527 570
528 return 0; 571 return 0;
529} 572}
@@ -555,12 +598,24 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
555 .vidioc_s_input = vidioc_s_input, 598 .vidioc_s_input = vidioc_s_input,
556}; 599};
557 600
601static void usb_amradio_device_release(struct video_device *videodev)
602{
603 struct amradio_device *radio = video_get_drvdata(videodev);
604
605 /* we call v4l to free radio->videodev */
606 video_device_release(videodev);
607
608 /* free rest memory */
609 kfree(radio->buffer);
610 kfree(radio);
611}
612
558/* V4L2 interface */ 613/* V4L2 interface */
559static struct video_device amradio_videodev_template = { 614static struct video_device amradio_videodev_template = {
560 .name = "AverMedia MR 800 USB FM Radio", 615 .name = "AverMedia MR 800 USB FM Radio",
561 .fops = &usb_amradio_fops, 616 .fops = &usb_amradio_fops,
562 .ioctl_ops = &usb_amradio_ioctl_ops, 617 .ioctl_ops = &usb_amradio_ioctl_ops,
563 .release = video_device_release, 618 .release = usb_amradio_device_release,
564}; 619};
565 620
566/* check if the device is present and register with v4l and 621/* check if the device is present and register with v4l and
@@ -602,7 +657,7 @@ static int usb_amradio_probe(struct usb_interface *intf,
602 657
603 video_set_drvdata(radio->videodev, radio); 658 video_set_drvdata(radio->videodev, radio);
604 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { 659 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
605 warn("Could not register video device"); 660 dev_warn(&intf->dev, "could not register video device\n");
606 video_device_release(radio->videodev); 661 video_device_release(radio->videodev);
607 kfree(radio->buffer); 662 kfree(radio->buffer);
608 kfree(radio); 663 kfree(radio);
@@ -617,9 +672,13 @@ static int __init amradio_init(void)
617{ 672{
618 int retval = usb_register(&usb_amradio_driver); 673 int retval = usb_register(&usb_amradio_driver);
619 674
620 info(DRIVER_VERSION " " DRIVER_DESC); 675 pr_info(KBUILD_MODNAME
676 ": version " DRIVER_VERSION " " DRIVER_DESC "\n");
677
621 if (retval) 678 if (retval)
622 err("usb_register failed. Error number %d", retval); 679 pr_err(KBUILD_MODNAME
680 ": usb_register failed. Error number %d\n", retval);
681
623 return retval; 682 return retval;
624} 683}
625 684
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index a67079777419..7704f243b6f0 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -1,7 +1,7 @@
1/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff 1/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
2 * 2 *
3 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood 3 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
4 * Converted to new API by Alan Cox <Alan.Cox@linux.org> 4 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
6 * 6 *
7 * TODO: Allow for more than one of these foolish entities :-) 7 * TODO: Allow for more than one of these foolish entities :-)
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 329c90bddadd..834d43651c70 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -3,7 +3,7 @@
3 * (c) 1997 M. Kirkwood 3 * (c) 1997 M. Kirkwood
4 * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz 4 * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz
5 * 5 *
6 * Fitted to new interface by Alan Cox <alan.cox@linux.org> 6 * Fitted to new interface by Alan Cox <alan@lxorguk.ukuu.org.uk>
7 * Made working and cleaned up functions <mikael.hedin@irf.se> 7 * Made working and cleaned up functions <mikael.hedin@irf.se>
8 * Support for ISAPnP by Ladislav Michl <ladis@psi.cz> 8 * Support for ISAPnP by Ladislav Michl <ladis@psi.cz>
9 * 9 *