コード例 #1
0
ファイル: btuart_cs.c プロジェクト: FatSunHYS/OSCourseDesign
static int btuart_open(btuart_info_t *info)
{
	unsigned long flags;
	unsigned int iobase = info->p_dev->io.BasePort1;
	struct hci_dev *hdev;

	spin_lock_init(&(info->lock));

	skb_queue_head_init(&(info->txq));

	info->rx_state = RECV_WAIT_PACKET_TYPE;
	info->rx_count = 0;
	info->rx_skb = NULL;

	/* Initialize HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		return -ENOMEM;
	}

	info->hdev = hdev;

	hdev->type = HCI_PCCARD;
	hdev->driver_data = info;
	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);

	hdev->open     = btuart_hci_open;
	hdev->close    = btuart_hci_close;
	hdev->flush    = btuart_hci_flush;
	hdev->send     = btuart_hci_send_frame;
	hdev->destruct = btuart_hci_destruct;
	hdev->ioctl    = btuart_hci_ioctl;

	hdev->owner = THIS_MODULE;

	spin_lock_irqsave(&(info->lock), flags);

	/* Reset UART */
	outb(0, iobase + UART_MCR);

	/* Turn off interrupts */
	outb(0, iobase + UART_IER);

	/* Initialize UART */
	outb(UART_LCR_WLEN8, iobase + UART_LCR);	/* Reset DLAB */
	outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);

	/* Turn on interrupts */
	// outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);

	spin_unlock_irqrestore(&(info->lock), flags);

	btuart_change_speed(info, DEFAULT_BAUD_RATE);

	/* Timeout before it is safe to send the first HCI packet */
	msleep(1000);

	/* Register HCI device */
	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		info->hdev = NULL;
		hci_free_dev(hdev);
		return -ENODEV;
	}

	return 0;
}
コード例 #2
0
static int btusb_probe(struct usb_interface *intf,
				const struct usb_device_id *id)
{
	struct usb_endpoint_descriptor *ep_desc;
	struct btusb_data *data;
	struct hci_dev *hdev;
	int i, err;

	BT_DBG("intf %p id %p", intf, id);

	/* interface numbers are hardcoded in the spec */
	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
		return -ENODEV;

	if (!id->driver_info) {
		const struct usb_device_id *match;
		match = usb_match_id(intf, blacklist_table);
		if (match)
			id = match;
	}

	if (id->driver_info == BTUSB_IGNORE)
		return -ENODEV;

	if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
		return -ENODEV;

	if (ignore_csr && id->driver_info & BTUSB_CSR)
		return -ENODEV;

	if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
		return -ENODEV;

	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
		ep_desc = &intf->cur_altsetting->endpoint[i].desc;

		if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
			data->intr_ep = ep_desc;
			continue;
		}

		if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
			data->bulk_tx_ep = ep_desc;
			continue;
		}

		if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
			data->bulk_rx_ep = ep_desc;
			continue;
		}
	}

	if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
		kfree(data);
		return -ENODEV;
	}

	data->cmdreq_type = USB_TYPE_CLASS;

	data->udev = interface_to_usbdev(intf);
	data->intf = intf;

	spin_lock_init(&data->lock);

	INIT_WORK(&data->work, btusb_work);
	INIT_WORK(&data->waker, btusb_waker);
	spin_lock_init(&data->txlock);

	init_usb_anchor(&data->tx_anchor);
	init_usb_anchor(&data->intr_anchor);
	init_usb_anchor(&data->bulk_anchor);
	init_usb_anchor(&data->isoc_anchor);
	init_usb_anchor(&data->deferred);

	hdev = hci_alloc_dev();
	if (!hdev) {
		kfree(data);
		return -ENOMEM;
	}

	hdev->bus = HCI_USB;
	hdev->driver_data = data;

	data->hdev = hdev;

	SET_HCIDEV_DEV(hdev, &intf->dev);

	hdev->open     = btusb_open;
	hdev->close    = btusb_close;
	hdev->flush    = btusb_flush;
	hdev->send     = btusb_send_frame;
	hdev->destruct = btusb_destruct;
	hdev->notify   = btusb_notify;

	hdev->owner = THIS_MODULE;

	/* Interface numbers are hardcoded in the specification */
	data->isoc = usb_ifnum_to_if(data->udev, 1);

	if (!reset)
		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);

	if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) {
		if (!disable_scofix)
			set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
	}

	if (id->driver_info & BTUSB_BROKEN_ISOC)
		data->isoc = NULL;

	if (id->driver_info & BTUSB_DIGIANSWER) {
		data->cmdreq_type = USB_TYPE_VENDOR;
		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
	}

	if (id->driver_info & BTUSB_CSR) {
		struct usb_device *udev = data->udev;

		/* Old firmware would otherwise execute USB reset */
		if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117)
			set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
	}

	if (id->driver_info & BTUSB_SNIFFER) {
		struct usb_device *udev = data->udev;

		/* New sniffer firmware has crippled HCI interface */
		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);

		data->isoc = NULL;
	}

	if (id->driver_info & BTUSB_BCM92035) {
		unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 };
		struct sk_buff *skb;

		skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
		if (skb) {
			memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
			skb_queue_tail(&hdev->driver_init, skb);
		}
	}

	if (data->isoc) {
		err = usb_driver_claim_interface(&btusb_driver,
							data->isoc, data);
		if (err < 0) {
			hci_free_dev(hdev);
			kfree(data);
			return err;
		}
	}

	err = hci_register_dev(hdev);
	if (err < 0) {
		hci_free_dev(hdev);
		kfree(data);
		return err;
	}

	usb_set_intfdata(intf, data);

	return 0;
}
コード例 #3
0
ファイル: bfusb.c プロジェクト: 0-T-0/ps4-linux
static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	const struct firmware *firmware;
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_host_endpoint *bulk_out_ep;
	struct usb_host_endpoint *bulk_in_ep;
	struct hci_dev *hdev;
	struct bfusb_data *data;

	BT_DBG("intf %p id %p", intf, id);

	/* Check number of endpoints */
	if (intf->cur_altsetting->desc.bNumEndpoints < 2)
		return -EIO;

	bulk_out_ep = &intf->cur_altsetting->endpoint[0];
	bulk_in_ep  = &intf->cur_altsetting->endpoint[1];

	if (!bulk_out_ep || !bulk_in_ep) {
		BT_ERR("Bulk endpoints not found");
		goto done;
	}

	/* Initialize control structure and load firmware */
	data = devm_kzalloc(&intf->dev, sizeof(struct bfusb_data), GFP_KERNEL);
	if (!data) {
		BT_ERR("Can't allocate memory for control structure");
		goto done;
	}

	data->udev = udev;
	data->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
	data->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
	data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);

	rwlock_init(&data->lock);

	data->reassembly = NULL;

	skb_queue_head_init(&data->transmit_q);
	skb_queue_head_init(&data->pending_q);
	skb_queue_head_init(&data->completed_q);

	if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {
		BT_ERR("Firmware request failed");
		goto done;
	}

	BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);

	if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) {
		BT_ERR("Firmware loading failed");
		goto release;
	}

	release_firmware(firmware);

	/* Initialize and register HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		goto done;
	}

	data->hdev = hdev;

	hdev->bus = HCI_USB;
	hci_set_drvdata(hdev, data);
	SET_HCIDEV_DEV(hdev, &intf->dev);

	hdev->open  = bfusb_open;
	hdev->close = bfusb_close;
	hdev->flush = bfusb_flush;
	hdev->send  = bfusb_send_frame;

	set_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks);

	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		hci_free_dev(hdev);
		goto done;
	}

	usb_set_intfdata(intf, data);

	return 0;

release:
	release_firmware(firmware);

done:
	return -EIO;
}
コード例 #4
0
ファイル: dtl1_cs.c プロジェクト: 1703011/asuswrt-merlin
static int dtl1_open(dtl1_info_t *info)
{
	unsigned long flags;
	unsigned int iobase = info->p_dev->resource[0]->start;
	struct hci_dev *hdev;

	spin_lock_init(&(info->lock));

	skb_queue_head_init(&(info->txq));

	info->rx_state = RECV_WAIT_NSH;
	info->rx_count = NSHL;
	info->rx_skb = NULL;

	set_bit(XMIT_WAITING, &(info->tx_state));

	/* Initialize HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		return -ENOMEM;
	}

	info->hdev = hdev;

	hdev->bus = HCI_PCCARD;
	hdev->driver_data = info;
	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);

	hdev->open     = dtl1_hci_open;
	hdev->close    = dtl1_hci_close;
	hdev->flush    = dtl1_hci_flush;
	hdev->send     = dtl1_hci_send_frame;
	hdev->destruct = dtl1_hci_destruct;
	hdev->ioctl    = dtl1_hci_ioctl;

	hdev->owner = THIS_MODULE;

	spin_lock_irqsave(&(info->lock), flags);

	/* Reset UART */
	outb(0, iobase + UART_MCR);

	/* Turn off interrupts */
	outb(0, iobase + UART_IER);

	/* Initialize UART */
	outb(UART_LCR_WLEN8, iobase + UART_LCR);	/* Reset DLAB */
	outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);

	info->ri_latch = inb(info->p_dev->resource[0]->start + UART_MSR)
				& UART_MSR_RI;

	/* Turn on interrupts */
	outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);

	spin_unlock_irqrestore(&(info->lock), flags);

	/* Timeout before it is safe to send the first HCI packet */
	msleep(2000);

	/* Register HCI device */
	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		info->hdev = NULL;
		hci_free_dev(hdev);
		return -ENODEV;
	}

	return 0;
}
コード例 #5
0
ファイル: hci_smd.c プロジェクト: marc1706/hd2_kernel
static int hci_smd_register_dev(struct hci_smd_data *hsmd)
{
	static struct hci_dev *hdev;
	int rc;

	/* Initialize and register HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		return -ENOMEM;
	}

	hsmd->hdev = hdev;
	hdev->bus = HCI_SMD;
	hdev->driver_data = NULL;
	hdev->open  = hci_smd_open;
	hdev->close = hci_smd_close;
	hdev->send  = hci_smd_send_frame;
	hdev->destruct = hci_smd_destruct;
	hdev->owner = THIS_MODULE;

	tasklet_init(&hsmd->hci_event_task,
			hci_smd_recv_event, (unsigned long) hsmd);
	tasklet_init(&hsmd->hci_data_task,
			hci_smd_recv_data, (unsigned long) hsmd);
	/*
	 * Setup the timer to monitor whether the Rx queue is empty,
	 * to control the wake lock release
	 */
	setup_timer(&hsmd->rx_q_timer, schedule_timer,
			(unsigned long) hsmd->hdev);

	/* Open the SMD Channel and device and register the callback function */
	rc = smd_named_open_on_edge(EVENT_CHANNEL, SMD_APPS_WCNSS,
			&hsmd->event_channel, hdev, hci_smd_notify_event);
	if (rc < 0) {
		BT_ERR("Cannot open the command channel");
		hci_free_dev(hdev);
		hdev = NULL;
		return -ENODEV;
	}

	rc = smd_named_open_on_edge(DATA_CHANNEL, SMD_APPS_WCNSS,
			&hsmd->data_channel, hdev, hci_smd_notify_data);
	if (rc < 0) {
		BT_ERR("Failed to open the Data channel");
		hci_free_dev(hdev);
		hdev = NULL;
		return -ENODEV;
	}

	/* Disable the read interrupts on the channel */
	smd_disable_read_intr(hsmd->event_channel);
	smd_disable_read_intr(hsmd->data_channel);
	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		hci_free_dev(hdev);
		return -ENODEV;
	}
	return 0;
}
コード例 #6
0
ファイル: hci_usb.c プロジェクト: TitaniumBoy/lin
static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
{
	struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;
	struct usb_interface_descriptor *uif;
	struct usb_endpoint_descriptor *ep;
	struct hci_usb *husb;
	struct hci_dev *hdev;
	int i, size, pipe;
	__u8 * buf;

	DBG("udev %p ifnum %d", udev, ifnum);

	/* Check device signature */
	if ((udev->descriptor.bDeviceClass    != HCI_DEV_CLASS)   ||
	    (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||
	    (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )
		return NULL;

	MOD_INC_USE_COUNT;

	uif = &udev->actconfig->interface[ifnum].altsetting[0];

	if (uif->bNumEndpoints != 3) {
		DBG("Wrong number of endpoints %d", uif->bNumEndpoints);
		MOD_DEC_USE_COUNT;
		return NULL;
	}

	bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;

	/* Find endpoints that we need */
	for ( i = 0; i < uif->bNumEndpoints; ++i) {
		ep = &uif->endpoint[i];

		switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
			case USB_ENDPOINT_XFER_BULK:
				if (ep->bEndpointAddress & USB_DIR_IN)
					bulk_in_ep  = ep;
				else
					bulk_out_ep = ep;
				break;

			case USB_ENDPOINT_XFER_INT:
				intr_in_ep = ep;
				break;
		};
	}

	if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
		DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);
		MOD_DEC_USE_COUNT;
		return NULL;
	}

	if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
		ERR("Can't allocate: control structure");
		MOD_DEC_USE_COUNT;
		return NULL;
	}

	memset(husb, 0, sizeof(struct hci_usb));

	husb->udev = udev;
	husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;

	if (!(husb->ctrl_urb = usb_alloc_urb(0))) {
		ERR("Can't allocate: control URB");
		goto probe_error;
	}

	if (!(husb->write_urb = usb_alloc_urb(0))) {
		ERR("Can't allocate: write URB");
		goto probe_error;
	}

	if (!(husb->read_urb = usb_alloc_urb(0))) {
		ERR("Can't allocate: read URB");
		goto probe_error;
	}

	ep = bulk_in_ep;
	pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
	size = HCI_MAX_FRAME_SIZE;

	if (!(buf = kmalloc(size, GFP_KERNEL))) {
		ERR("Can't allocate: read buffer");
		goto probe_error;
	}

	FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);
	husb->read_urb->transfer_flags |= USB_QUEUE_BULK;

	ep = intr_in_ep;
	pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);
	size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));

	if (!(husb->intr_urb = usb_alloc_urb(0))) {
		ERR("Can't allocate: interrupt URB");
		goto probe_error;
	}

	if (!(buf = kmalloc(size, GFP_KERNEL))) {
		ERR("Can't allocate: interrupt buffer");
		goto probe_error;
	}

	FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);

	skb_queue_head_init(&husb->tx_ctrl_q);
	skb_queue_head_init(&husb->tx_write_q);

	/* Initialize and register HCI device */
	hdev = &husb->hdev;

	hdev->type = HCI_USB;
	hdev->driver_data = husb;

	hdev->open  = hci_usb_open;
	hdev->close = hci_usb_close;
	hdev->flush = hci_usb_flush;
	hdev->send	= hci_usb_send_frame;

	if (hci_register_dev(hdev) < 0) {
		ERR("Can't register HCI device %s", hdev->name);
		goto probe_error;
	}

	return husb;

probe_error:
	hci_usb_free_bufs(husb);
	kfree(husb);
	MOD_DEC_USE_COUNT;
	return NULL;
}
コード例 #7
0
static int btusb_probe(struct usb_interface *intf,
				const struct usb_device_id *id)
{
	struct usb_endpoint_descriptor *ep_desc;
	struct btusb_data *data;
	struct hci_dev *hdev;
	int i, version, err;

	BT_DBG("intf %p id %p", intf, id);

	/* interface numbers are hardcoded in the spec */
	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
		return -ENODEV;

	if (!id->driver_info) {
		const struct usb_device_id *match;
		match = usb_match_id(intf, blacklist_table);
		if (match)
			id = match;
	}

	if (id->driver_info == BTUSB_IGNORE)
		return -ENODEV;

	if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
		return -ENODEV;

	if (ignore_csr && id->driver_info & BTUSB_CSR)
		return -ENODEV;

	if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
		return -ENODEV;

	if (id->driver_info & BTUSB_ATH3012) {
		struct usb_device *udev = interface_to_usbdev(intf);

		version = get_rome_version(udev);
		BT_INFO("Rome Version: 0x%x",  version);
		/* Old firmware would otherwise let ath3k driver load
		 * patch and sysconfig files */
		if (version)
			rome_download(udev);
		else if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001) {
			BT_INFO("FW for ar3k is yet to be downloaded");
			return -ENODEV;
		}
	}
	data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
		ep_desc = &intf->cur_altsetting->endpoint[i].desc;

		if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
			data->intr_ep = ep_desc;
			continue;
		}

		if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
			data->bulk_tx_ep = ep_desc;
			continue;
		}

		if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
			data->bulk_rx_ep = ep_desc;
			continue;
		}
	}

	if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep)
		return -ENODEV;

	data->cmdreq_type = USB_TYPE_CLASS;

	data->udev = interface_to_usbdev(intf);
	data->intf = intf;

	spin_lock_init(&data->lock);

	INIT_WORK(&data->work, btusb_work);
	INIT_WORK(&data->waker, btusb_waker);
	spin_lock_init(&data->txlock);

	init_usb_anchor(&data->tx_anchor);
	init_usb_anchor(&data->intr_anchor);
	init_usb_anchor(&data->bulk_anchor);
	init_usb_anchor(&data->isoc_anchor);
	init_usb_anchor(&data->deferred);

	hdev = hci_alloc_dev();
	if (!hdev)
		return -ENOMEM;

	hdev->bus = HCI_USB;
	hci_set_drvdata(hdev, data);

	data->hdev = hdev;

	SET_HCIDEV_DEV(hdev, &intf->dev);

	hdev->open   = btusb_open;
	hdev->close  = btusb_close;
	hdev->flush  = btusb_flush;
	hdev->send   = btusb_send_frame;
	hdev->notify = btusb_notify;

	if (id->driver_info & BTUSB_BCM92035)
		hdev->setup = btusb_setup_bcm92035;

	if (id->driver_info & BTUSB_INTEL)
		hdev->setup = btusb_setup_intel;

	/* Interface numbers are hardcoded in the specification */
	data->isoc = usb_ifnum_to_if(data->udev, 1);

	if (!reset)
		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);

	if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) {
		if (!disable_scofix)
			set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
	}

	if (id->driver_info & BTUSB_BROKEN_ISOC)
		data->isoc = NULL;

	if (id->driver_info & BTUSB_DIGIANSWER) {
		data->cmdreq_type = USB_TYPE_VENDOR;
		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
	}

	if (id->driver_info & BTUSB_CSR) {
		struct usb_device *udev = data->udev;

		/* Old firmware would otherwise execute USB reset */
		if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117)
			set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
	}

	if (id->driver_info & BTUSB_SNIFFER) {
		struct usb_device *udev = data->udev;

		/* New sniffer firmware has crippled HCI interface */
		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);

		data->isoc = NULL;
	}

	if (data->isoc) {
		err = usb_driver_claim_interface(&btusb_driver,
							data->isoc, data);
		if (err < 0) {
			hci_free_dev(hdev);
			return err;
		}
	}

	err = hci_register_dev(hdev);
	if (err < 0) {
		hci_free_dev(hdev);
		return err;
	}

	usb_set_intfdata(intf, data);
	usb_enable_autosuspend(data->udev);

	return 0;
}
コード例 #8
0
ファイル: hci_vhci.c プロジェクト: PimsJay01/myscripts
static int vhci_create_device(struct vhci_data *data, __u8 opcode)
{
	struct hci_dev *hdev;
	struct sk_buff *skb;
	__u8 dev_type;

	/* bits 0-1 are dev_type (BR/EDR or AMP) */
	dev_type = opcode & 0x03;

	if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
		return -EINVAL;

	/* bits 2-5 are reserved (must be zero) */
	if (opcode & 0x3c)
		return -EINVAL;

	skb = bt_skb_alloc(4, GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	hdev = hci_alloc_dev();
	if (!hdev) {
		kfree_skb(skb);
		return -ENOMEM;
	}

	data->hdev = hdev;

	hdev->bus = HCI_VIRTUAL;
	hdev->dev_type = dev_type;
	hci_set_drvdata(hdev, data);

	hdev->open  = vhci_open_dev;
	hdev->close = vhci_close_dev;
	hdev->flush = vhci_flush;
	hdev->send  = vhci_send_frame;

	/* bit 6 is for external configuration */
	if (opcode & 0x40)
		set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);

	/* bit 7 is for raw device */
	if (opcode & 0x80)
		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);

	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		hci_free_dev(hdev);
		data->hdev = NULL;
		kfree_skb(skb);
		return -EBUSY;
	}

	bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;

	*skb_put(skb, 1) = 0xff;
	*skb_put(skb, 1) = opcode;
	put_unaligned_le16(hdev->id, skb_put(skb, 2));
	skb_queue_tail(&data->readq, skb);

	wake_up_interruptible(&data->read_wait);
	return 0;
}
コード例 #9
0
ファイル: hci_serdev.c プロジェクト: EMFPGA/linux_media
int hci_uart_register_device(struct hci_uart *hu,
			     const struct hci_uart_proto *p)
{
	int err;
	struct hci_dev *hdev;

	BT_DBG("");

	serdev_device_set_client_ops(hu->serdev, &hci_serdev_client_ops);

	err = p->open(hu);
	if (err)
		return err;

	hu->proto = p;
	set_bit(HCI_UART_PROTO_READY, &hu->flags);

	/* Initialize and register HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		err = -ENOMEM;
		goto err_alloc;
	}

	hu->hdev = hdev;

	hdev->bus = HCI_UART;
	hci_set_drvdata(hdev, hu);

	INIT_WORK(&hu->write_work, hci_uart_write_work);

	/* Only when vendor specific setup callback is provided, consider
	 * the manufacturer information valid. This avoids filling in the
	 * value for Ericsson when nothing is specified.
	 */
	if (hu->proto->setup)
		hdev->manufacturer = hu->proto->manufacturer;

	hdev->open  = hci_uart_open;
	hdev->close = hci_uart_close;
	hdev->flush = hci_uart_flush;
	hdev->send  = hci_uart_send_frame;
	hdev->setup = hci_uart_setup;
	SET_HCIDEV_DEV(hdev, &hu->serdev->dev);

	if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);

	if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags))
		set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);

	if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags))
		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);

	if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags))
		hdev->dev_type = HCI_AMP;
	else
		hdev->dev_type = HCI_PRIMARY;

	if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
		return 0;

	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		err = -ENODEV;
		goto err_register;
	}

	set_bit(HCI_UART_REGISTERED, &hu->flags);

	return 0;

err_register:
	hci_free_dev(hdev);
err_alloc:
	clear_bit(HCI_UART_PROTO_READY, &hu->flags);
	p->close(hu);
	return err;
}
コード例 #10
0
ファイル: bluecard_cs.c プロジェクト: Kratos1982/UbuntuTouch
static int bluecard_open(bluecard_info_t *info)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
	unsigned int iobase = info->p_dev->resource[0]->start;
#else
	unsigned int iobase = info->p_dev->io.BasePort1;
#endif
	struct hci_dev *hdev;
	unsigned char id;

	spin_lock_init(&(info->lock));

	init_timer(&(info->timer));
	info->timer.function = &bluecard_activity_led_timeout;
	info->timer.data = (u_long)info;

	skb_queue_head_init(&(info->txq));

	info->rx_state = RECV_WAIT_PACKET_TYPE;
	info->rx_count = 0;
	info->rx_skb = NULL;

	/* Initialize HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		return -ENOMEM;
	}

	info->hdev = hdev;

	hdev->bus = HCI_PCCARD;
	hci_set_drvdata(hdev, info);
	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);

	hdev->open     = bluecard_hci_open;
	hdev->close    = bluecard_hci_close;
	hdev->flush    = bluecard_hci_flush;
	hdev->send     = bluecard_hci_send_frame;
	hdev->ioctl    = bluecard_hci_ioctl;

	id = inb(iobase + 0x30);

	if ((id & 0x0f) == 0x02)
		set_bit(CARD_HAS_PCCARD_ID, &(info->hw_state));

	if (id & 0x10)
		set_bit(CARD_HAS_POWER_LED, &(info->hw_state));

	if (id & 0x20)
		set_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state));

	/* Reset card */
	info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
	outb(info->ctrl_reg, iobase + REG_CONTROL);

	/* Turn FPGA off */
	outb(0x80, iobase + 0x30);

	/* Wait some time */
	msleep(10);

	/* Turn FPGA on */
	outb(0x00, iobase + 0x30);

	/* Activate card */
	info->ctrl_reg = REG_CONTROL_BT_ON | REG_CONTROL_BT_RES_PU;
	outb(info->ctrl_reg, iobase + REG_CONTROL);

	/* Enable interrupt */
	outb(0xff, iobase + REG_INTERRUPT);
	info->ctrl_reg |= REG_CONTROL_INTERRUPT;
	outb(info->ctrl_reg, iobase + REG_CONTROL);

	if ((id & 0x0f) == 0x03) {
		/* Disable RTS */
		info->ctrl_reg |= REG_CONTROL_RTS;
		outb(info->ctrl_reg, iobase + REG_CONTROL);

		/* Set baud rate */
		info->ctrl_reg |= 0x03;
		outb(info->ctrl_reg, iobase + REG_CONTROL);

		/* Enable RTS */
		info->ctrl_reg &= ~REG_CONTROL_RTS;
		outb(info->ctrl_reg, iobase + REG_CONTROL);

		set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
		set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
		set_bit(XMIT_SENDING_READY, &(info->tx_state));
	}

	/* Start the RX buffers */
	outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
	outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);

	/* Signal that the hardware is ready */
	set_bit(CARD_READY, &(info->hw_state));

	/* Drop TX queue */
	skb_queue_purge(&(info->txq));

	/* Control the point at which RTS is enabled */
	outb((0x0f << RTS_LEVEL_SHIFT_BITS) | 1, iobase + REG_RX_CONTROL);

	/* Timeout before it is safe to send the first HCI packet */
	msleep(1250);

	/* Register HCI device */
	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		info->hdev = NULL;
		hci_free_dev(hdev);
		return -ENODEV;
	}

	return 0;
}
コード例 #11
0
ファイル: bt3c_cs.c プロジェクト: wxlong/Test
int bt3c_open(bt3c_info_t *info)
{
	const struct firmware *firmware;
	struct hci_dev *hdev;
	int err;

	spin_lock_init(&(info->lock));

	skb_queue_head_init(&(info->txq));

	info->rx_state = RECV_WAIT_PACKET_TYPE;
	info->rx_count = 0;
	info->rx_skb = NULL;

	/* Initialize HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		return -ENOMEM;
	}

	info->hdev = hdev;

	hdev->type = HCI_PCCARD;
	hdev->driver_data = info;

	hdev->open     = bt3c_hci_open;
	hdev->close    = bt3c_hci_close;
	hdev->flush    = bt3c_hci_flush;
	hdev->send     = bt3c_hci_send_frame;
	hdev->destruct = bt3c_hci_destruct;
	hdev->ioctl    = bt3c_hci_ioctl;

	hdev->owner = THIS_MODULE;

	/* Load firmware */
	err = request_firmware(&firmware, "BT3CPCC.bin", &bt3c_device);
	if (err < 0) {
		BT_ERR("Firmware request failed");
		goto error;
	}

	err = bt3c_load_firmware(info, firmware->data, firmware->size);

	release_firmware(firmware);

	if (err < 0) {
		BT_ERR("Firmware loading failed");
		goto error;
	}

	/* Timeout before it is safe to send the first HCI packet */
	set_current_state(TASK_INTERRUPTIBLE);
	schedule_timeout(HZ);

	/* Register HCI device */
	err = hci_register_dev(hdev);
	if (err < 0) {
		BT_ERR("Can't register HCI device");
		goto error;
	}

	return 0;

error:
	info->hdev = NULL;
	hci_free_dev(hdev);
	return err;
}
コード例 #12
0
int bluecard_open(bluecard_info_t *info)
{
	unsigned int iobase = info->link.io.BasePort1;
	struct hci_dev *hdev;
	unsigned char id;

	spin_lock_init(&(info->lock));

	init_timer(&(info->timer));
	info->timer.function = &bluecard_activity_led_timeout;
	info->timer.data = (u_long)info;

	skb_queue_head_init(&(info->txq));

	info->rx_state = RECV_WAIT_PACKET_TYPE;
	info->rx_count = 0;
	info->rx_skb = NULL;

	id = inb(iobase + 0x30);

	if ((id & 0x0f) == 0x02)
		set_bit(CARD_HAS_PCCARD_ID, &(info->hw_state));

	if (id & 0x10)
		set_bit(CARD_HAS_POWER_LED, &(info->hw_state));

	if (id & 0x20)
		set_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state));

	/* Reset card */
	info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
	outb(info->ctrl_reg, iobase + REG_CONTROL);

	/* Turn FPGA off */
	outb(0x80, iobase + 0x30);

	/* Wait some time */
	set_current_state(TASK_INTERRUPTIBLE);
	schedule_timeout(HZ / 100);

	/* Turn FPGA on */
	outb(0x00, iobase + 0x30);

	/* Activate card */
	info->ctrl_reg = REG_CONTROL_BT_ON | REG_CONTROL_BT_RES_PU;
	outb(info->ctrl_reg, iobase + REG_CONTROL);

	/* Enable interrupt */
	outb(0xff, iobase + REG_INTERRUPT);
	info->ctrl_reg |= REG_CONTROL_INTERRUPT;
	outb(info->ctrl_reg, iobase + REG_CONTROL);

	/* Start the RX buffers */
	outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
	outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);

	/* Signal that the hardware is ready */
	set_bit(CARD_READY, &(info->hw_state));

	/* Drop TX queue */
	skb_queue_purge(&(info->txq));

	/* Control the point at which RTS is enabled */
	outb((0x0f << RTS_LEVEL_SHIFT_BITS) | 1, iobase + REG_RX_CONTROL);

	/* Timeout before it is safe to send the first HCI packet */
	set_current_state(TASK_INTERRUPTIBLE);
	schedule_timeout((HZ * 5) / 4);		// or set it to 3/2


	/* Initialize and register HCI device */

	hdev = &(info->hdev);

	hdev->type = HCI_PCCARD;
	hdev->driver_data = info;

	hdev->open = bluecard_hci_open;
	hdev->close = bluecard_hci_close;
	hdev->flush = bluecard_hci_flush;
	hdev->send = bluecard_hci_send_frame;
	hdev->destruct = bluecard_hci_destruct;
	hdev->ioctl = bluecard_hci_ioctl;

	if (hci_register_dev(hdev) < 0) {
		printk(KERN_WARNING "bluecard_cs: Can't register HCI device %s.\n", hdev->name);
		return -ENODEV;
	}

	return 0;
}
コード例 #13
0
ファイル: bfusb.c プロジェクト: QiuLihua83/linux-2.6.10
static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	const struct firmware *firmware;
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_host_endpoint *bulk_out_ep;
	struct usb_host_endpoint *bulk_in_ep;
	struct hci_dev *hdev;
	struct bfusb *bfusb;

	BT_DBG("intf %p id %p", intf, id);

	/* Check number of endpoints */
	if (intf->cur_altsetting->desc.bNumEndpoints < 2)
		return -EIO;

	bulk_out_ep = &intf->cur_altsetting->endpoint[0];
	bulk_in_ep  = &intf->cur_altsetting->endpoint[1];

	if (!bulk_out_ep || !bulk_in_ep) {
		BT_ERR("Bulk endpoints not found");
		goto done;
	}

	/* Initialize control structure and load firmware */
	if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
		BT_ERR("Can't allocate memory for control structure");
		goto done;
	}

	memset(bfusb, 0, sizeof(struct bfusb));

	bfusb->udev = udev;
	bfusb->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
	bfusb->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
	bfusb->bulk_pkt_size = bulk_out_ep->desc.wMaxPacketSize;

	rwlock_init(&bfusb->lock);

	bfusb->reassembly = NULL;

	skb_queue_head_init(&bfusb->transmit_q);
	skb_queue_head_init(&bfusb->pending_q);
	skb_queue_head_init(&bfusb->completed_q);

	if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {
		BT_ERR("Firmware request failed");
		goto error;
	}

	BT_DBG("firmware data %p size %d", firmware->data, firmware->size);

	if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) {
		BT_ERR("Firmware loading failed");
		goto release;
	}

	release_firmware(firmware);

	/* Initialize and register HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		goto error;
	}

	bfusb->hdev = hdev;

	hdev->type = HCI_USB;
	hdev->driver_data = bfusb;
	SET_HCIDEV_DEV(hdev, &intf->dev);

	hdev->open     = bfusb_open;
	hdev->close    = bfusb_close;
	hdev->flush    = bfusb_flush;
	hdev->send     = bfusb_send_frame;
	hdev->destruct = bfusb_destruct;
	hdev->ioctl    = bfusb_ioctl;

	hdev->owner = THIS_MODULE;

	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		hci_free_dev(hdev);
		goto error;
	}

	usb_set_intfdata(intf, bfusb);

	return 0;

release:
	release_firmware(firmware);

error:
	kfree(bfusb);

done:
	return -EIO;
}
コード例 #14
0
static int btusb_probe(struct usb_interface *intf,
                       const struct usb_device_id *id)
{
    struct usb_endpoint_descriptor *ep_desc;
    struct btusb_data *data;
    struct hci_dev *hdev;
    int i, err,flag1,flag2;
    struct usb_device *udev;
    udev = interface_to_usbdev(intf);

    /* interface numbers are hardcoded in the spec */
    if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
        return -ENODEV;

    /*******************************/
    flag1=device_can_wakeup(&udev->dev);
    flag2=device_may_wakeup(&udev->dev);
    RTKBT_DBG("btusb_probe 1==========can_wakeup=%x	 flag2=%x",flag1,flag2);
    //device_wakeup_enable(&udev->dev);
    /*device_wakeup_disable(&udev->dev);
    flag1=device_can_wakeup(&udev->dev);
    flag2=device_may_wakeup(&udev->dev);
    RTKBT_DBG("btusb_probe 2==========can_wakeup=%x	 flag2=%x",flag1,flag2);
    */
    err = patch_add(intf);
    if (err < 0) return -1;
    /*******************************/

    data = kzalloc(sizeof(*data), GFP_KERNEL);
    if (!data)
        return -ENOMEM;


    for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
        ep_desc = &intf->cur_altsetting->endpoint[i].desc;

        if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
            data->intr_ep = ep_desc;
            continue;
        }

        if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
            data->bulk_tx_ep = ep_desc;
            continue;
        }

        if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
            data->bulk_rx_ep = ep_desc;
            continue;
        }
    }

    if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
        kfree(data);
        return -ENODEV;
    }

    data->cmdreq_type = USB_TYPE_CLASS;

    data->udev = interface_to_usbdev(intf);
    data->intf = intf;

    spin_lock_init(&data->lock);

    INIT_WORK(&data->work, btusb_work);
    INIT_WORK(&data->waker, btusb_waker);
    spin_lock_init(&data->txlock);

    init_usb_anchor(&data->tx_anchor);
    init_usb_anchor(&data->intr_anchor);
    init_usb_anchor(&data->bulk_anchor);
    init_usb_anchor(&data->isoc_anchor);
    init_usb_anchor(&data->deferred);

    hdev = hci_alloc_dev();
    if (!hdev) {
        kfree(data);
        return -ENOMEM;
    }

    HDEV_BUS = HCI_USB;

    data->hdev = hdev;

    SET_HCIDEV_DEV(hdev, &intf->dev);

    hdev->open     = btusb_open;
    hdev->close    = btusb_close;
    hdev->flush    = btusb_flush;
    hdev->send     = btusb_send_frame;
    hdev->notify   = btusb_notify;


#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0)
    hci_set_drvdata(hdev, data);
#else
    hdev->driver_data = data;
    hdev->destruct = btusb_destruct;
    hdev->owner = THIS_MODULE;
#endif



    /* Interface numbers are hardcoded in the specification */
    data->isoc = usb_ifnum_to_if(data->udev, 1);

    if (data->isoc) {
        err = usb_driver_claim_interface(&btusb_driver,
                                         data->isoc, data);
        if (err < 0) {
            hci_free_dev(hdev);
            kfree(data);
            return err;
        }
    }

    err = hci_register_dev(hdev);
    if (err < 0) {
        hci_free_dev(hdev);
        kfree(data);
        return err;
    }

    usb_set_intfdata(intf, data);

    return 0;
}
コード例 #15
0
ファイル: hci_ldisc.c プロジェクト: akuster/linux-meson
static int hci_uart_register_dev(struct hci_uart *hu)
{
	struct hci_dev *hdev;

	BT_INFO("hci_uart_register_dev");

	/* Initialize and register HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		return -ENOMEM;
	}

	hu->hdev = hdev;

#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 33)
	hdev->bus = HCI_UART;
#else
	hdev->type = HCI_UART;
#endif

#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0)
	hci_set_drvdata(hdev, hu);
#else
	hdev->driver_data = hu;
#endif
	hdev->open  = hci_uart_open;
	hdev->close = hci_uart_close;
	hdev->flush = hci_uart_flush;
	hdev->send  = hci_uart_send_frame;

#if ( (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)) )
	hdev->parent = hu->tty->dev;
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
	hdev->destruct = hci_uart_destruct;
	hdev->owner = THIS_MODULE;
#endif	

#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
	if (!reset)
		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);

	if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
	
#else
	if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
            set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)	
    if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags))
            set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
#endif
 
    if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags))
            hdev->dev_type = HCI_AMP;
    else
            hdev->dev_type = HCI_BREDR;
#endif

	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		hci_free_dev(hdev);
		return -ENODEV;
	}

#ifdef BTCOEX
	rtk_uart_coex_probe(hdev);
#endif

	return 0;
}