PageRenderTime 54ms CodeModel.GetById 20ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/bluetooth/hci_ldisc.c

https://bitbucket.org/evzijst/gittest
C | 593 lines | 372 code | 117 blank | 104 comment | 47 complexity | 3c0895aa5c04bcd3936ca33fba913f04 MD5 | raw file
  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
 64static int reset = 0;
 65
 66static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
 67
 68int 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
 80int 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
 92static 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
 99static 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
119static 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
129int 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
142restart:
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 */
171static 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 */
182static 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 */
205static 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 */
217static 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
242static 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 */
264static 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 */
301static 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 */
330static 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 */
357static 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 */
374static 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
393static 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
431static 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 */
467static 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 */
507static 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}
511static 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}
515static 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
521int h4_init(void);
522int h4_deinit(void);
523#endif
524#ifdef CONFIG_BT_HCIUART_BCSP
525int bcsp_init(void);
526int bcsp_deinit(void);
527#endif
528
529static 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
567static 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
583module_init(hci_uart_init);
584module_exit(hci_uart_exit);
585
586module_param(reset, bool, 0644);
587MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
588
589MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
590MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
591MODULE_VERSION(VERSION);
592MODULE_LICENSE("GPL");
593MODULE_ALIAS_LDISC(N_HCI);