[RFC 1/5] Bluetooth: hci_uart: Add HCIUARTSETDEVTYPE ioctl

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This allows user space application to set the correct vendor specific
setup function.

Signed-off-by: Frederic Danis <frederic.danis@xxxxxxxxxxxxxxx>
---
 drivers/bluetooth/hci_ldisc.c | 50 +++++++++++++++++++++++++++++++++++++++++++
 drivers/bluetooth/hci_uart.h  |  4 ++++
 2 files changed, 54 insertions(+)

diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 1363dc6..cb7fcc6 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -467,9 +467,19 @@ static int hci_uart_register_dev(struct hci_uart *hu)
 	return 0;
 }
 
+struct hci_uart_devtype_t {
+	char type[HCI_UART_DEVTYPE_SIZE];
+	int (*setup)(struct hci_uart *hu);
+};
+
+struct hci_uart_devtype_t devtypes[] = {
+		{ "", 0 }
+};
+
 static int hci_uart_set_proto(struct hci_uart *hu, int id)
 {
 	struct hci_uart_proto *p;
+	int i;
 	int err;
 
 	p = hci_uart_get_proto(id);
@@ -482,6 +492,13 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
 
 	hu->proto = p;
 
+	/* Select vendor specific setup */
+	hu->proto->setup = NULL;
+	for (i = 0; devtypes[i].type[0]; i++) {
+		if (!strcmp(devtypes[i].type, hu->dev_type))
+			hu->proto->setup = devtypes[i].setup;
+	}
+
 	err = hci_uart_register_dev(hu);
 	if (err) {
 		p->close(hu);
@@ -507,6 +524,33 @@ static int hci_uart_set_flags(struct hci_uart *hu, unsigned long flags)
 	return 0;
 }
 
+static int hci_tty_ioctl_set_devtype(struct hci_uart *hu, unsigned int cmd,
+							unsigned long arg)
+{
+	unsigned int size = _IOC_SIZE(cmd);
+	char dev_type[HCI_UART_DEVTYPE_SIZE];
+	int i;
+	bool found = false;
+
+	if (size > HCI_UART_DEVTYPE_SIZE)
+		return -EINVAL;
+
+	if (copy_from_user(dev_type, (void __user *)arg, size))
+		return -EFAULT;
+
+	for (i = 0; devtypes[i].type[0]; i++) {
+		if (!strcmp(devtypes[i].type, dev_type))
+			found = true;
+	}
+
+	if (!found)
+		return -EINVAL;
+
+	strncpy(hu->dev_type, dev_type, size);
+
+	return 0;
+}
+
 /* hci_uart_tty_ioctl()
  *
  *    Process IOCTL system call for the tty device.
@@ -565,6 +609,12 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
 	case HCIUARTGETFLAGS:
 		return hu->hdev_flags;
 
+	case HCIUARTSETDEVTYPE:
+		err = hci_tty_ioctl_set_devtype(hu, cmd, arg);
+		if (err)
+			return err;
+		break;
+
 	default:
 		err = n_tty_ioctl_helper(tty, file, cmd, arg);
 		break;
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index 074ed29..bd56409 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -33,6 +33,7 @@
 #define HCIUARTGETDEVICE	_IOR('U', 202, int)
 #define HCIUARTSETFLAGS		_IOW('U', 203, int)
 #define HCIUARTGETFLAGS		_IOR('U', 204, int)
+#define HCIUARTSETDEVTYPE	_IOW('U', 205, int)
 
 /* UART protocols */
 #define HCI_UART_MAX_PROTO	6
@@ -50,6 +51,8 @@
 #define HCI_UART_INIT_PENDING	3
 #define HCI_UART_EXT_CONFIG	4
 
+#define HCI_UART_DEVTYPE_SIZE	32
+
 struct hci_uart;
 
 struct hci_uart_proto {
@@ -68,6 +71,7 @@ struct hci_uart {
 	struct hci_dev		*hdev;
 	unsigned long		flags;
 	unsigned long		hdev_flags;
+	char			dev_type[HCI_UART_DEVTYPE_SIZE];
 
 	struct work_struct	init_ready;
 	struct work_struct	write_work;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux