Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /* 
  2    BlueZ - Bluetooth protocol stack for Linux
  3    Copyright (C) 2000-2001 Qualcomm Incorporated
  4 
  5    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
  6 
  7    This program is free software; you can redistribute it and/or modify
  8    it under the terms of the GNU General Public License version 2 as
  9    published by the Free Software Foundation;
 10 
 11    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 12    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 13    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
 14    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
 15    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
 16    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
 17    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
 18    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 19 
 20    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
 21    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
 22    SOFTWARE IS DISCLAIMED.
 23 */
 24 
 25 /*
 26  * Bluetooth HCI UART driver.
 27  *
 28  * $Id: hci_ldisc.c,v 1.5 2002/10/02 18:37:20 maxk Exp $    
 29  */
 30 #define VERSION "2.1"
 31 
 32 #include <linux/config.h>
 33 #include <linux/module.h>
 34 
 35 #include <linux/kernel.h>
 36 #include <linux/init.h>
 37 #include <linux/sched.h>
 38 #include <linux/types.h>
 39 #include <linux/fcntl.h>
 40 #include <linux/interrupt.h>
 41 #include <linux/ptrace.h>
 42 #include <linux/poll.h>
 43 
 44 #include <linux/slab.h>
 45 #include <linux/tty.h>
 46 #include <linux/errno.h>
 47 #include <linux/string.h>
 48 #include <linux/signal.h>
 49 #include <linux/ioctl.h>
 50 #include <linux/skbuff.h>
 51 
 52 #include <net/bluetooth/bluetooth.h>
 53 #include <net/bluetooth/hci_core.h>
 54 
 55 #include "hci_uart.h"
 56 
 57 #ifndef CONFIG_BT_HCIUART_DEBUG
 58 #undef  BT_DBG
 59 #define BT_DBG( A... )
 60 #undef  BT_DMP
 61 #define BT_DMP( A... )
 62 #endif
 63 
 64 static int reset = 0;
 65 
 66 static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
 67 
 68 int hci_uart_register_proto(struct hci_uart_proto *p)
 69 {
 70         if (p->id >= HCI_UART_MAX_PROTO)
 71                 return -EINVAL;
 72 
 73         if (hup[p->id])
 74                 return -EEXIST;
 75 
 76         hup[p->id] = p;
 77         return 0;
 78 }
 79 
 80 int hci_uart_unregister_proto(struct hci_uart_proto *p)
 81 {
 82         if (p->id >= HCI_UART_MAX_PROTO)
 83                 return -EINVAL;
 84 
 85         if (!hup[p->id])
 86                 return -EINVAL;
 87 
 88         hup[p->id] = NULL;
 89         return 0;
 90 }
 91 
 92 static struct hci_uart_proto *hci_uart_get_proto(unsigned int id)
 93 {
 94         if (id >= HCI_UART_MAX_PROTO)
 95                 return NULL;
 96         return hup[id];
 97 }
 98 
 99 static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
100 {
101         struct hci_dev *hdev = hu->hdev;
102         
103         /* Update HCI stat counters */
104         switch (pkt_type) {
105         case HCI_COMMAND_PKT:
106                 hdev->stat.cmd_tx++;
107                 break;
108 
109         case HCI_ACLDATA_PKT:
110                 hdev->stat.acl_tx++;
111                 break;
112 
113         case HCI_SCODATA_PKT:
114                 hdev->stat.cmd_tx++;
115                 break;
116         }
117 }
118 
119 static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
120 {
121         struct sk_buff *skb = hu->tx_skb;
122         if (!skb)
123                 skb = hu->proto->dequeue(hu);
124         else
125                 hu->tx_skb = NULL;
126         return skb;
127 }
128 
129 int hci_uart_tx_wakeup(struct hci_uart *hu)
130 {
131         struct tty_struct *tty = hu->tty;
132         struct hci_dev *hdev = hu->hdev;
133         struct sk_buff *skb;
134         
135         if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
136                 set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
137                 return 0;
138         }
139 
140         BT_DBG("");
141 
142 restart:
143         clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
144 
145         while ((skb = hci_uart_dequeue(hu))) {
146                 int len;
147         
148                 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
149                 len = tty->driver->write(tty, skb->data, skb->len);
150                 hdev->stat.byte_tx += len;
151 
152                 skb_pull(skb, len);
153                 if (skb->len) {
154                         hu->tx_skb = skb;
155                         break;
156                 }
157         
158                 hci_uart_tx_complete(hu, skb->pkt_type);
159                 kfree_skb(skb);
160         } 
161         
162         if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
163                 goto restart;
164 
165         clear_bit(HCI_UART_SENDING, &hu->tx_state);
166         return 0;
167 }
168 
169 /* ------- Interface to HCI layer ------ */
170 /* Initialize device */
171 static int hci_uart_open(struct hci_dev *hdev)
172 {
173         BT_DBG("%s %p", hdev->name, hdev);
174 
175         /* Nothing to do for UART driver */
176 
177         set_bit(HCI_RUNNING, &hdev->flags);
178         return 0;
179 }
180 
181 /* Reset device */
182 static int hci_uart_flush(struct hci_dev *hdev)
183 {
184         struct hci_uart *hu  = (struct hci_uart *) hdev->driver_data;
185         struct tty_struct *tty = hu->tty;
186 
187         BT_DBG("hdev %p tty %p", hdev, tty);
188 
189         if (hu->tx_skb) {
190                 kfree_skb(hu->tx_skb); hu->tx_skb = NULL;
191         }
192 
193         /* Flush any pending characters in the driver and discipline. */
194         tty_ldisc_flush(tty);
195         if (tty->driver->flush_buffer)
196                 tty->driver->flush_buffer(tty);
197 
198         if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
199                 hu->proto->flush(hu);
200 
201         return 0;
202 }
203 
204 /* Close device */
205 static int hci_uart_close(struct hci_dev *hdev)
206 {
207         BT_DBG("hdev %p", hdev);
208 
209         if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
210                 return 0;
211 
212         hci_uart_flush(hdev);
213         return 0;
214 }
215 
216 /* Send frames from HCI layer */
217 static int hci_uart_send_frame(struct sk_buff *skb)
218 {
219         struct hci_dev* hdev = (struct hci_dev *) skb->dev;
220         struct tty_struct *tty;
221         struct hci_uart *hu;
222 
223         if (!hdev) {
224                 BT_ERR("Frame for uknown device (hdev=NULL)");
225                 return -ENODEV;
226         }
227 
228         if (!test_bit(HCI_RUNNING, &hdev->flags))
229                 return -EBUSY;
230 
231         hu = (struct hci_uart *) hdev->driver_data;
232         tty = hu->tty;
233 
234         BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
235 
236         hu->proto->enqueue(hu, skb);
237 
238         hci_uart_tx_wakeup(hu);
239         return 0;
240 }
241 
242 static void hci_uart_destruct(struct hci_dev *hdev)
243 {
244         struct hci_uart *hu;
245 
246         if (!hdev) return;
247 
248         BT_DBG("%s", hdev->name);
249 
250         hu = (struct hci_uart *) hdev->driver_data;
251         kfree(hu);
252 }
253 
254 /* ------ LDISC part ------ */
255 /* hci_uart_tty_open
256  * 
257  *     Called when line discipline changed to HCI_UART.
258  *
259  * Arguments:
260  *     tty    pointer to tty info structure
261  * Return Value:    
262  *     0 if success, otherwise error code
263  */
264 static int hci_uart_tty_open(struct tty_struct *tty)
265 {
266         struct hci_uart *hu = (void *) tty->disc_data;
267 
268         BT_DBG("tty %p", tty);
269 
270         if (hu)
271                 return -EEXIST;
272 
273         if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
274                 BT_ERR("Can't allocate controll structure");
275                 return -ENFILE;
276         }
277         memset(hu, 0, sizeof(struct hci_uart));
278 
279         tty->disc_data = hu;
280         hu->tty = tty;
281 
282         spin_lock_init(&hu->rx_lock);
283 
284         /* Flush any pending characters in the driver and line discipline. */
285         /* FIXME: why is this needed. Note don't use ldisc_ref here as the
286            open path is before the ldisc is referencable */
287         if (tty->ldisc.flush_buffer)
288                 tty->ldisc.flush_buffer(tty);
289 
290         if (tty->driver->flush_buffer)
291                 tty->driver->flush_buffer(tty);
292 
293         return 0;
294 }
295 
296 /* hci_uart_tty_close()
297  *
298  *    Called when the line discipline is changed to something
299  *    else, the tty is closed, or the tty detects a hangup.
300  */
301 static void hci_uart_tty_close(struct tty_struct *tty)
302 {
303         struct hci_uart *hu = (void *)tty->disc_data;
304 
305         BT_DBG("tty %p", tty);
306 
307         /* Detach from the tty */
308         tty->disc_data = NULL;
309 
310         if (hu) {
311                 struct hci_dev *hdev = hu->hdev;
312                 hci_uart_close(hdev);
313 
314                 if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
315                         hu->proto->close(hu);
316                         hci_unregister_dev(hdev);
317                         hci_free_dev(hdev);
318                 }
319         }
320 }
321 
322 /* hci_uart_tty_wakeup()
323  *
324  *    Callback for transmit wakeup. Called when low level
325  *    device driver can accept more send data.
326  *
327  * Arguments:        tty    pointer to associated tty instance data
328  * Return Value:    None
329  */
330 static void hci_uart_tty_wakeup(struct tty_struct *tty)
331 {
332         struct hci_uart *hu = (void *)tty->disc_data;
333 
334         BT_DBG("");
335 
336         if (!hu)
337                 return;
338 
339         clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
340 
341         if (tty != hu->tty)
342                 return;
343 
344         if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
345                 hci_uart_tx_wakeup(hu);
346 }
347 
348 /* hci_uart_tty_room()
349  * 
350  *    Callback function from tty driver. Return the amount of 
351  *    space left in the receiver's buffer to decide if remote
352  *    transmitter is to be throttled.
353  *
354  * Arguments:        tty    pointer to associated tty instance data
355  * Return Value:    number of bytes left in receive buffer
356  */
357 static int hci_uart_tty_room (struct tty_struct *tty)
358 {
359         return 65536;
360 }
361 
362 /* hci_uart_tty_receive()
363  * 
364  *     Called by tty low level driver when receive data is
365  *     available.
366  *     
367  * Arguments:  tty          pointer to tty isntance data
368  *             data         pointer to received data
369  *             flags        pointer to flags for data
370  *             count        count of received data in bytes
371  *     
372  * Return Value:    None
373  */
374 static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
375 {
376         struct hci_uart *hu = (void *)tty->disc_data;
377         
378         if (!hu || tty != hu->tty)
379                 return;
380 
381         if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
382                 return;
383         
384         spin_lock(&hu->rx_lock);
385         hu->proto->recv(hu, (void *) data, count);
386         hu->hdev->stat.byte_rx += count;
387         spin_unlock(&hu->rx_lock);
388 
389         if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver->unthrottle)
390                 tty->driver->unthrottle(tty);
391 }
392 
393 static int hci_uart_register_dev(struct hci_uart *hu)
394 {
395         struct hci_dev *hdev;
396 
397         BT_DBG("");
398 
399         /* Initialize and register HCI device */
400         hdev = hci_alloc_dev();
401         if (!hdev) {
402                 BT_ERR("Can't allocate HCI device");
403                 return -ENOMEM;
404         }
405 
406         hu->hdev = hdev;
407 
408         hdev->type = HCI_UART;
409         hdev->driver_data = hu;
410 
411         hdev->open  = hci_uart_open;
412         hdev->close = hci_uart_close;
413         hdev->flush = hci_uart_flush;
414         hdev->send  = hci_uart_send_frame;
415         hdev->destruct = hci_uart_destruct;
416 
417         hdev->owner = THIS_MODULE;
418 
419         if (reset)
420                 set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
421 
422         if (hci_register_dev(hdev) < 0) {
423                 BT_ERR("Can't register HCI device");
424                 hci_free_dev(hdev);
425                 return -ENODEV;
426         }
427 
428         return 0;
429 }
430 
431 static int hci_uart_set_proto(struct hci_uart *hu, int id)
432 {
433         struct hci_uart_proto *p;
434         int err;        
435         
436         p = hci_uart_get_proto(id);
437         if (!p)
438                 return -EPROTONOSUPPORT;
439 
440         err = p->open(hu);
441         if (err)
442                 return err;
443 
444         hu->proto = p;
445 
446         err = hci_uart_register_dev(hu);
447         if (err) {
448                 p->close(hu);
449                 return err;
450         }
451         return 0;
452 }
453 
454 /* hci_uart_tty_ioctl()
455  *
456  *    Process IOCTL system call for the tty device.
457  *
458  * Arguments:
459  *
460  *    tty        pointer to tty instance data
461  *    file       pointer to open file object for device
462  *    cmd        IOCTL command code
463  *    arg        argument for IOCTL call (cmd dependent)
464  *
465  * Return Value:    Command dependent
466  */
467 static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
468                             unsigned int cmd, unsigned long arg)
469 {
470         struct hci_uart *hu = (void *)tty->disc_data;
471         int err = 0;
472 
473         BT_DBG("");
474 
475         /* Verify the status of the device */
476         if (!hu)
477                 return -EBADF;
478 
479         switch (cmd) {
480         case HCIUARTSETPROTO:
481                 if (!test_and_set_bit(HCI_UART_PROTO_SET, &hu->flags)) {
482                         err = hci_uart_set_proto(hu, arg);
483                         if (err) {
484                                 clear_bit(HCI_UART_PROTO_SET, &hu->flags);
485                                 return err;
486                         }
487                         tty->low_latency = 1;
488                 } else  
489                         return -EBUSY;
490 
491         case HCIUARTGETPROTO:
492                 if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
493                         return hu->proto->id;
494                 return -EUNATCH;
495                 
496         default:
497                 err = n_tty_ioctl(tty, file, cmd, arg);
498                 break;
499         };
500 
501         return err;
502 }
503 
504 /*
505  * We don't provide read/write/poll interface for user space.
506  */
507 static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char __user *buf, size_t nr)
508 {
509         return 0;
510 }
511 static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
512 {
513         return 0;
514 }
515 static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
516 {
517         return 0;
518 }
519 
520 #ifdef CONFIG_BT_HCIUART_H4
521 int h4_init(void);
522 int h4_deinit(void);
523 #endif
524 #ifdef CONFIG_BT_HCIUART_BCSP
525 int bcsp_init(void);
526 int bcsp_deinit(void);
527 #endif
528 
529 static int __init hci_uart_init(void)
530 {
531         static struct tty_ldisc hci_uart_ldisc;
532         int err;
533 
534         BT_INFO("HCI UART driver ver %s", VERSION);
535 
536         /* Register the tty discipline */
537 
538         memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc));
539         hci_uart_ldisc.magic       = TTY_LDISC_MAGIC;
540         hci_uart_ldisc.name        = "n_hci";
541         hci_uart_ldisc.open        = hci_uart_tty_open;
542         hci_uart_ldisc.close       = hci_uart_tty_close;
543         hci_uart_ldisc.read        = hci_uart_tty_read;
544         hci_uart_ldisc.write       = hci_uart_tty_write;
545         hci_uart_ldisc.ioctl       = hci_uart_tty_ioctl;
546         hci_uart_ldisc.poll        = hci_uart_tty_poll;
547         hci_uart_ldisc.receive_room= hci_uart_tty_room;
548         hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
549         hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
550         hci_uart_ldisc.owner       = THIS_MODULE;
551 
552         if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
553                 BT_ERR("HCI line discipline registration failed. (%d)", err);
554                 return err;
555         }
556 
557 #ifdef CONFIG_BT_HCIUART_H4
558         h4_init();
559 #endif
560 #ifdef CONFIG_BT_HCIUART_BCSP
561         bcsp_init();
562 #endif
563         
564         return 0;
565 }
566 
567 static void __exit hci_uart_exit(void)
568 {
569         int err;
570 
571 #ifdef CONFIG_BT_HCIUART_H4
572         h4_deinit();
573 #endif
574 #ifdef CONFIG_BT_HCIUART_BCSP
575         bcsp_deinit();
576 #endif
577 
578         /* Release tty registration of line discipline */
579         if ((err = tty_register_ldisc(N_HCI, NULL)))
580                 BT_ERR("Can't unregister HCI line discipline (%d)", err);
581 }
582 
583 module_init(hci_uart_init);
584 module_exit(hci_uart_exit);
585 
586 module_param(reset, bool, 0644);
587 MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
588 
589 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
590 MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
591 MODULE_VERSION(VERSION);
592 MODULE_LICENSE("GPL");
593 MODULE_ALIAS_LDISC(N_HCI);
594 
  This page was automatically generated by the LXR engine.