示例#1
1
文件: ikalcd.c 项目: hogeki/ikalcd
static ssize_t ikalcd_write(struct file *file, const char *user_buffer,
			  size_t count, loff_t *ppos)
{
	struct usb_ikalcd *dev;
	int retval = 0;
	struct urb *urb = NULL;
	char *buf = NULL;
	struct usb_ctrlrequest *cr;
	size_t writesize = min(count, (size_t)LCD_COMMAND_SIZE);
	int i;

	dev = file->private_data;

	/* verify that we actually have some data to write */
	if (count == 0)
		goto exit;

	/*
	 * limit the number of URBs in flight to stop a user from using up all
	 * RAM
	 */
	if (!(file->f_flags & O_NONBLOCK)) {
		if (down_interruptible(&dev->limit_sem)) {
			retval = -ERESTARTSYS;
			goto exit;
		}
	} else {
		if (down_trylock(&dev->limit_sem)) {
			retval = -EAGAIN;
			goto exit;
		}
	}

	spin_lock_irq(&dev->err_lock);
	retval = dev->errors;
	if (retval < 0) {
		/* any error is reported once */
		dev->errors = 0;
		/* to preserve notifications about reset */
		retval = (retval == -EPIPE) ? retval : -EIO;
	}
	spin_unlock_irq(&dev->err_lock);
	if (retval < 0)
		goto error;

	/* create a urb, and a buffer for it, and copy the data to the urb */
	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb) {
		retval = -ENOMEM;
		goto error;
	}

	/*
	buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
				 &urb->transfer_dma);
	*/
	buf = kmalloc(LCD_COMMAND_SIZE, GFP_KERNEL);
	if (!buf) {
		retval = -ENOMEM;
		goto error;
	}
	cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
	if (!cr) {
		retval = -ENOMEM;
		goto error;
	}

	for (i=0; i<LCD_COMMAND_SIZE; i++)
		buf[i] = 0x11;
	if (copy_from_user(buf, user_buffer, writesize)) {
		retval = -EFAULT;
		goto error;
	}

	/* this lock makes sure we don't submit URBs to gone devices */
	mutex_lock(&dev->io_mutex);
	if (!dev->interface) {		/* disconnect() was called */
		mutex_unlock(&dev->io_mutex);
		retval = -ENODEV;
		goto error;
	}

	cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
	cr->bRequest = 0x09;
	cr->wValue = cpu_to_le16(0x300);
	cr->wIndex = cpu_to_le16(dev->interface->cur_altsetting->desc.bInterfaceNumber);
	cr->wLength = cpu_to_le16(LCD_COMMAND_SIZE);
	/* initialize the urb properly */
	/*
	usb_fill_bulk_urb(urb, dev->udev,
			  usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
			  buf, writesize, ikalcd_write_bulk_callback, dev);
	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	*/
	usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0),
			     (unsigned char*)cr, (void*)buf, LCD_COMMAND_SIZE,
			     ikalcd_write_control_callback, dev);
	usb_anchor_urb(urb, &dev->submitted);

	/* send the data out the bulk port */
	retval = usb_submit_urb(urb, GFP_KERNEL);
	mutex_unlock(&dev->io_mutex);
	if (retval) {
		dev_err(&dev->interface->dev,
			"%s - failed submitting write urb, error %d\n",
			__func__, retval);
		goto error_unanchor;
	}

	/*
	 * release our reference to this urb, the USB core will eventually free
	 * it entirely
	 */
	usb_free_urb(urb);


	return writesize;

error_unanchor:
	usb_unanchor_urb(urb);
error:
	if (urb) {
		usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
		usb_free_urb(urb);
	}
	up(&dev->limit_sem);

exit:
	return retval;
}
示例#2
0
int __devinit st5481_setup_usb(struct st5481_adapter *adapter)
{
	struct usb_device *dev = adapter->usb_dev;
	struct st5481_ctrl *ctrl = &adapter->ctrl;
	struct st5481_intr *intr = &adapter->intr;
	struct usb_host_interface *altsetting;
	struct usb_host_endpoint *endpoint;
	int status;
	struct urb *urb;
	u8 *buf;
	
	DBG(1,"");
	
	if ((status = usb_reset_configuration (dev)) < 0) {
		WARN("reset_configuration failed,status=%d",status);
		return status;
	}

	
	altsetting = &(dev->config->interface[0]->altsetting[3]);	

	// Check if the config is sane
	if ( altsetting->desc.bNumEndpoints != 7 ) {
		WARN("expecting 7 got %d endpoints!", altsetting->desc.bNumEndpoints);
		return -EINVAL;
	}

	// The descriptor is wrong for some early samples of the ST5481 chip
	altsetting->endpoint[3].desc.wMaxPacketSize = 32;
	altsetting->endpoint[4].desc.wMaxPacketSize = 32;

	// Use alternative setting 3 on interface 0 to have 2B+D
	if ((status = usb_set_interface (dev, 0, 3)) < 0) {
		WARN("usb_set_interface failed,status=%d",status);
		return status;
	}

	// Allocate URB for control endpoint
	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb) {
		return -ENOMEM;
	}
	ctrl->urb = urb;
	
	// Fill the control URB
	usb_fill_control_urb (urb, dev, 
			  usb_sndctrlpipe(dev, 0),
			  NULL, NULL, 0, usb_ctrl_complete, adapter);

		
	fifo_init(&ctrl->msg_fifo.f, ARRAY_SIZE(ctrl->msg_fifo.data));

	// Allocate URBs and buffers for interrupt endpoint
	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb) { 
		return -ENOMEM;
	}
	intr->urb = urb;
	
	buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL);
	if (!buf) {
		return -ENOMEM;
	}

	endpoint = &altsetting->endpoint[EP_INT-1];
				
	// Fill the interrupt URB
	usb_fill_int_urb(urb, dev,
		     usb_rcvintpipe(dev, endpoint->desc.bEndpointAddress),
		     buf, INT_PKT_SIZE,
		     usb_int_complete, adapter,
		     endpoint->desc.bInterval);
		
	return 0;
}
示例#3
0
文件: redrat3.c 项目: mkrufky/linux
static int redrat3_dev_probe(struct usb_interface *intf,
			     const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct device *dev = &intf->dev;
	struct usb_host_interface *uhi;
	struct redrat3_dev *rr3;
	struct usb_endpoint_descriptor *ep;
	struct usb_endpoint_descriptor *ep_narrow = NULL;
	struct usb_endpoint_descriptor *ep_wide = NULL;
	struct usb_endpoint_descriptor *ep_out = NULL;
	u8 addr, attrs;
	int pipe, i;
	int retval = -ENOMEM;

	uhi = intf->cur_altsetting;

	/* find our bulk-in and bulk-out endpoints */
	for (i = 0; i < uhi->desc.bNumEndpoints; ++i) {
		ep = &uhi->endpoint[i].desc;
		addr = ep->bEndpointAddress;
		attrs = ep->bmAttributes;

		if (((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
		    ((attrs & USB_ENDPOINT_XFERTYPE_MASK) ==
		     USB_ENDPOINT_XFER_BULK)) {
			dev_dbg(dev, "found bulk-in endpoint at 0x%02x\n",
				ep->bEndpointAddress);
			/* data comes in on 0x82, 0x81 is for learning */
			if (ep->bEndpointAddress == RR3_NARROW_IN_EP_ADDR)
				ep_narrow = ep;
			if (ep->bEndpointAddress == RR3_WIDE_IN_EP_ADDR)
				ep_wide = ep;
		}

		if ((ep_out == NULL) &&
		    ((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
		    ((attrs & USB_ENDPOINT_XFERTYPE_MASK) ==
		     USB_ENDPOINT_XFER_BULK)) {
			dev_dbg(dev, "found bulk-out endpoint at 0x%02x\n",
				ep->bEndpointAddress);
			ep_out = ep;
		}
	}

	if (!ep_narrow || !ep_out || !ep_wide) {
		dev_err(dev, "Couldn't find all endpoints\n");
		retval = -ENODEV;
		goto no_endpoints;
	}

	/* allocate memory for our device state and initialize it */
	rr3 = kzalloc(sizeof(*rr3), GFP_KERNEL);
	if (!rr3)
		goto no_endpoints;

	rr3->dev = &intf->dev;
	rr3->ep_narrow = ep_narrow;
	rr3->ep_out = ep_out;
	rr3->udev = udev;

	/* set up bulk-in endpoint */
	rr3->narrow_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!rr3->narrow_urb)
		goto redrat_free;

	rr3->wide_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!rr3->wide_urb)
		goto redrat_free;

	rr3->bulk_in_buf = usb_alloc_coherent(udev,
		le16_to_cpu(ep_narrow->wMaxPacketSize),
		GFP_KERNEL, &rr3->dma_in);
	if (!rr3->bulk_in_buf)
		goto redrat_free;

	pipe = usb_rcvbulkpipe(udev, ep_narrow->bEndpointAddress);
	usb_fill_bulk_urb(rr3->narrow_urb, udev, pipe, rr3->bulk_in_buf,
		le16_to_cpu(ep_narrow->wMaxPacketSize),
		redrat3_handle_async, rr3);
	rr3->narrow_urb->transfer_dma = rr3->dma_in;
	rr3->narrow_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	pipe = usb_rcvbulkpipe(udev, ep_wide->bEndpointAddress);
	usb_fill_bulk_urb(rr3->wide_urb, udev, pipe, rr3->bulk_in_buf,
		le16_to_cpu(ep_narrow->wMaxPacketSize),
		redrat3_handle_async, rr3);
	rr3->wide_urb->transfer_dma = rr3->dma_in;
	rr3->wide_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	redrat3_reset(rr3);
	redrat3_get_firmware_rev(rr3);

	/* default.. will get overridden by any sends with a freq defined */
	rr3->carrier = 38000;

	atomic_set(&rr3->flash, 0);
	rr3->flash_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!rr3->flash_urb)
		goto redrat_free;

	/* learn urb */
	rr3->learn_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!rr3->learn_urb)
		goto redrat_free;

	/* setup packet is 'c0 b2 0000 0000 0001' */
	rr3->learn_control.bRequestType = 0xc0;
	rr3->learn_control.bRequest = RR3_MODSIG_CAPTURE;
	rr3->learn_control.wLength = cpu_to_le16(1);

	usb_fill_control_urb(rr3->learn_urb, udev, usb_rcvctrlpipe(udev, 0),
			(unsigned char *)&rr3->learn_control,
			&rr3->learn_buf, sizeof(rr3->learn_buf),
			redrat3_learn_complete, rr3);

	/* setup packet is 'c0 b9 0000 0000 0001' */
	rr3->flash_control.bRequestType = 0xc0;
	rr3->flash_control.bRequest = RR3_BLINK_LED;
	rr3->flash_control.wLength = cpu_to_le16(1);

	usb_fill_control_urb(rr3->flash_urb, udev, usb_rcvctrlpipe(udev, 0),
			(unsigned char *)&rr3->flash_control,
			&rr3->flash_in_buf, sizeof(rr3->flash_in_buf),
			redrat3_led_complete, rr3);

	/* led control */
	rr3->led.name = "redrat3:red:feedback";
	rr3->led.default_trigger = "rc-feedback";
	rr3->led.brightness_set = redrat3_brightness_set;
	retval = led_classdev_register(&intf->dev, &rr3->led);
	if (retval)
		goto redrat_free;

	rr3->rc = redrat3_init_rc_dev(rr3);
	if (!rr3->rc) {
		retval = -ENOMEM;
		goto led_free;
	}

	/* might be all we need to do? */
	retval = redrat3_enable_detector(rr3);
	if (retval < 0)
		goto led_free;

	/* we can register the device now, as it is ready */
	usb_set_intfdata(intf, rr3);

	return 0;

led_free:
	led_classdev_unregister(&rr3->led);
redrat_free:
	redrat3_delete(rr3, rr3->udev);

no_endpoints:
	return retval;
}
示例#4
0
static void notification_available_cb(struct urb *urb)
{
    int				status;
    struct usb_cdc_notification	*ctrl;
    struct ctrl_bridge		*dev = urb->context;
    struct bridge			*brdg = dev->brdg;
    unsigned int			ctrl_bits;
    unsigned char			*data;

    switch (urb->status) {
    case 0:

        break;
    case -ESHUTDOWN:
    case -ENOENT:
    case -ECONNRESET:
    case -EPROTO:

        return;
    case -EPIPE:
        dev_err(&dev->intf->dev,
                "%s: stall on int endpoint\n", __func__);

    case -EOVERFLOW:
    default:
        pr_debug_ratelimited("%s: non zero urb status = %d\n",
                             __func__, urb->status);
        goto resubmit_int_urb;
    }

    ctrl = (struct usb_cdc_notification *)urb->transfer_buffer;
    data = (unsigned char *)(ctrl + 1);

    switch (ctrl->bNotificationType) {
    case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
        dev->resp_avail++;
        usb_fill_control_urb(dev->readurb, dev->udev,
                             usb_rcvctrlpipe(dev->udev, 0),
                             (unsigned char *)dev->in_ctlreq,
                             dev->readbuf,
                             DEFAULT_READ_URB_LENGTH,
                             resp_avail_cb, dev);

        usb_anchor_urb(dev->readurb, &dev->tx_submitted);
        status = usb_submit_urb(dev->readurb, GFP_ATOMIC);
        if (status) {
            dev_err(&dev->intf->dev,
                    "%s: Error submitting Read URB %d\n",
                    __func__, status);
            usb_unanchor_urb(dev->readurb);
            goto resubmit_int_urb;
        }
        return;
    case USB_CDC_NOTIFY_NETWORK_CONNECTION:
        dev_dbg(&dev->intf->dev, "%s network\n", ctrl->wValue ?
                "connected to" : "disconnected from");
        break;
    case USB_CDC_NOTIFY_SERIAL_STATE:
        dev->notify_ser_state++;
        ctrl_bits = get_unaligned_le16(data);
        dev_dbg(&dev->intf->dev, "serial state: %d\n", ctrl_bits);
        dev->cbits_tohost = ctrl_bits;
        if (brdg && brdg->ops.send_cbits)
            brdg->ops.send_cbits(brdg->ctx, ctrl_bits);
        break;
    default:
        dev_err(&dev->intf->dev, "%s: unknown notification %d received:"
                "index %d len %d data0 %d data1 %d",
                __func__, ctrl->bNotificationType, ctrl->wIndex,
                ctrl->wLength, data[0], data[1]);
    }

resubmit_int_urb:
    usb_anchor_urb(urb, &dev->tx_submitted);
    status = usb_submit_urb(urb, GFP_ATOMIC);
    if (status) {
        dev_err(&dev->intf->dev, "%s: Error re-submitting Int URB %d\n",
                __func__, status);
        usb_unanchor_urb(urb);
    }
}
示例#5
0
static int rmnet_usb_ctrl_write(struct rmnet_ctrl_dev *dev, char *buf,
		size_t size)
{
	int			result;
	struct urb		*sndurb;
	struct usb_ctrlrequest	*out_ctlreq;
	struct usb_device	*udev;
#ifdef HTC_DEBUG_QMI_STUCK
	struct ctrl_write_context *context;
#endif	

	if (!is_dev_connected(dev))
		return -ENETRESET;

	udev = interface_to_usbdev(dev->intf);

	sndurb = usb_alloc_urb(0, GFP_KERNEL);
	if (!sndurb) {
		dev_err(dev->devicep, "Error allocating read urb\n");
		return -ENOMEM;
	}

	out_ctlreq = kmalloc(sizeof(*out_ctlreq), GFP_KERNEL);
	if (!out_ctlreq) {
		usb_free_urb(sndurb);
		dev_err(dev->devicep, "Error allocating setup packet buffer\n");
		return -ENOMEM;
	}

#ifdef HTC_DEBUG_QMI_STUCK
	context = kmalloc(sizeof(struct ctrl_write_context), GFP_KERNEL);
	if (!context) {
		kfree(out_ctlreq);
		usb_free_urb(sndurb);
		dev_err(dev->devicep, "Error allocating private data\n");
		return -ENOMEM;
	}
	context->dev = dev;
#endif	

	
	out_ctlreq->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS |
			     USB_RECIP_INTERFACE);
	out_ctlreq->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
	out_ctlreq->wValue = 0;
	out_ctlreq->wIndex = dev->intf->cur_altsetting->desc.bInterfaceNumber;
	out_ctlreq->wLength = cpu_to_le16(size);

	usb_fill_control_urb(sndurb, udev,
			     usb_sndctrlpipe(udev, 0),
			     (unsigned char *)out_ctlreq, (void *)buf, size,
#ifdef HTC_DEBUG_QMI_STUCK
			     ctrl_write_callback, context);
#else	
			     ctrl_write_callback, dev);
#endif	

	result = usb_autopm_get_interface(dev->intf);
	if (result < 0) {
		dev_err(dev->devicep, "%s: Unable to resume interface: %d\n",
			__func__, result);


		usb_free_urb(sndurb);
		kfree(out_ctlreq);
#ifdef HTC_DEBUG_QMI_STUCK
		kfree(context);
#endif	
		return result;
	}

#ifdef HTC_LOG_RMNET_USB_CTRL
	log_rmnet_usb_ctrl_event(dev->intf, "Tx", size);
#endif	

#ifdef HTC_DEBUG_QMI_STUCK
	init_timer(&context->timer);
	context->timer.function = rmnet_usb_ctrl_write_timer_expire;
	context->timer.data = (unsigned long)sndurb;
	context->start_jiffies = jiffies;
	mod_timer(&context->timer, jiffies + msecs_to_jiffies(QMI_TX_NO_CB_TIMEOUT));
#endif	

	usb_anchor_urb(sndurb, &dev->tx_submitted);
	dev->snd_encap_cmd_cnt++;
	result = usb_submit_urb(sndurb, GFP_KERNEL);
	if (result < 0) {
		dev_err(dev->devicep, "%s: Submit URB error %d\n",
			__func__, result);
		dev->snd_encap_cmd_cnt--;
		usb_autopm_put_interface(dev->intf);
		usb_unanchor_urb(sndurb);
		usb_free_urb(sndurb);
		kfree(out_ctlreq);
#ifdef HTC_DEBUG_QMI_STUCK
		del_timer(&context->timer);
		kfree(context);
#endif	
		return result;
	}

	return size;
}
示例#6
0
static int btusb_send_frame(struct sk_buff *skb)
{
	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
	struct btusb_data *data = hdev->driver_data;
	struct usb_ctrlrequest *dr;
	struct urb *urb;
	unsigned int pipe;
	int err;

	BT_DBG("%s", hdev->name);

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return -EBUSY;

	switch (bt_cb(skb)->pkt_type) {
	case HCI_COMMAND_PKT:
		urb = usb_alloc_urb(0, GFP_ATOMIC);
		if (!urb)
			return -ENOMEM;

		dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
		if (!dr) {
			usb_free_urb(urb);
			return -ENOMEM;
		}

		dr->bRequestType = data->cmdreq_type;
		dr->bRequest     = 0;
		dr->wIndex       = 0;
		dr->wValue       = 0;
		dr->wLength      = __cpu_to_le16(skb->len);

		pipe = usb_sndctrlpipe(data->udev, 0x00);

		usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
				skb->data, skb->len, btusb_tx_complete, skb);

		hdev->stat.cmd_tx++;
		break;

	case HCI_ACLDATA_PKT:
		if (!data->bulk_tx_ep)
			return -ENODEV;

		urb = usb_alloc_urb(0, GFP_ATOMIC);
		if (!urb)
			return -ENOMEM;

		pipe = usb_sndbulkpipe(data->udev,
					data->bulk_tx_ep->bEndpointAddress);

		usb_fill_bulk_urb(urb, data->udev, pipe,
				skb->data, skb->len, btusb_tx_complete, skb);

		hdev->stat.acl_tx++;
		break;

	case HCI_SCODATA_PKT:
		if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1)
			return -ENODEV;

		urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
		if (!urb)
			return -ENOMEM;

		pipe = usb_sndisocpipe(data->udev,
					data->isoc_tx_ep->bEndpointAddress);

		usb_fill_int_urb(urb, data->udev, pipe,
				skb->data, skb->len, btusb_isoc_tx_complete,
				skb, data->isoc_tx_ep->bInterval);

		urb->transfer_flags  = URB_ISO_ASAP;

		__fill_isoc_descriptor(urb, skb->len,
				le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));

		hdev->stat.sco_tx++;
		goto skip_waking;

	default:
		return -EILSEQ;
	}

	err = inc_tx(data);
	if (err) {
		usb_anchor_urb(urb, &data->deferred);
		schedule_work(&data->waker);
		err = 0;
		goto done;
	}

skip_waking:
	usb_anchor_urb(urb, &data->tx_anchor);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err < 0) {
		BT_ERR("%s urb %p submission failed", hdev->name, urb);
		kfree(urb->setup_packet);
		usb_unanchor_urb(urb);
	} else {
		usb_mark_last_busy(data->udev);
	}

done:
	usb_free_urb(urb);
	return err;
}
int PIPEnsControlIn(
     PSDevice     pDevice,
     BYTE         byRequest,
     WORD         wValue,
     WORD         wIndex,
     WORD         wLength,
       PBYTE   pbyBuffer
    )
{
	int ntStatus = 0;
    int ii;

    if (pDevice->Flags & fMP_DISCONNECTED)
        return STATUS_FAILURE;

    if (pDevice->Flags & fMP_CONTROL_READS)
	return STATUS_FAILURE;

	if (pDevice->Flags & fMP_CONTROL_WRITES)
		return STATUS_FAILURE;

	MP_SET_FLAG(pDevice, fMP_CONTROL_READS);

	pDevice->sUsbCtlRequest.bRequestType = 0xC0;
	pDevice->sUsbCtlRequest.bRequest = byRequest;
	pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
	pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
	pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
	pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
    pDevice->pControlURB->actual_length = 0;
	usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
			 usb_rcvctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
			 pbyBuffer, wLength, s_nsControlInUsbIoCompleteRead, pDevice);

	ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC);
	if (ntStatus != 0) {
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
			"control request submission failed: %d\n", ntStatus);
		MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
		return STATUS_FAILURE;
	}

	spin_unlock_irq(&pDevice->lock);
    for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {

	if (pDevice->Flags & fMP_CONTROL_READS)
		mdelay(1);
	else
		break;

	if (ii >= USB_CTL_WAIT) {
		DBG_PRT(MSG_LEVEL_DEBUG,
			KERN_INFO "control rcv request submission timeout\n");
            spin_lock_irq(&pDevice->lock);
            MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
            return STATUS_FAILURE;
        }
    }
	spin_lock_irq(&pDevice->lock);

    return ntStatus;
}
示例#8
0
static void wdm_int_callback(struct urb *urb)
{
    int rv = 0;
    int status = urb->status;
    struct wdm_device *desc;
    struct usb_ctrlrequest *req;
    struct usb_cdc_notification *dr;

    desc = urb->context;
    req = desc->irq;
    dr = (struct usb_cdc_notification *)desc->sbuf;

    if (status) {
        switch (status) {
        case -ESHUTDOWN:
        case -ENOENT:
        case -ECONNRESET:
            return; /* unplug */
        case -EPIPE:
            set_bit(WDM_INT_STALL, &desc->flags);
            dev_err(&desc->intf->dev, "Stall on int endpoint\n");
            goto sw; /* halt is cleared in work */
        default:
            dev_err(&desc->intf->dev,
                    "nonzero urb status received: %d\n", status);
            break;
        }
    }

    if (urb->actual_length < sizeof(struct usb_cdc_notification)) {
        dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n",
                urb->actual_length);
        goto exit;
    }

    switch (dr->bNotificationType) {
    case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
        dev_dbg(&desc->intf->dev,
                "NOTIFY_RESPONSE_AVAILABLE received: index %d len %d",
                dr->wIndex, dr->wLength);
        break;

    case USB_CDC_NOTIFY_NETWORK_CONNECTION:

        dev_dbg(&desc->intf->dev,
                "NOTIFY_NETWORK_CONNECTION %s network",
                dr->wValue ? "connected to" : "disconnected from");
        goto exit;
    default:
        clear_bit(WDM_POLL_RUNNING, &desc->flags);
        dev_err(&desc->intf->dev,
                "unknown notification %d received: index %d len %d\n",
                dr->bNotificationType, dr->wIndex, dr->wLength);
        goto exit;
    }

    req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
    req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
    req->wValue = 0;
    req->wIndex = desc->inum;
    req->wLength = cpu_to_le16(desc->wMaxCommand);

    usb_fill_control_urb(
        desc->response,
        interface_to_usbdev(desc->intf),
        /* using common endpoint 0 */
        usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0),
        (unsigned char *)req,
        desc->inbuf,
        desc->wMaxCommand,
        wdm_in_callback,
        desc
    );
    desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
    spin_lock(&desc->iuspin);
    clear_bit(WDM_READ, &desc->flags);
    if (!test_bit(WDM_DISCONNECTING, &desc->flags)) {
        rv = usb_submit_urb(desc->response, GFP_ATOMIC);
        dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d",
                __func__, rv);
    }
    spin_unlock(&desc->iuspin);
    if (rv < 0) {
        if (rv == -EPERM)
            return;
        if (rv == -ENOMEM) {
sw:
            rv = schedule_work(&desc->rxwork);
            if (rv)
                dev_err(&desc->intf->dev,
                        "Cannot schedule work\n");
        }
    }
exit:
    rv = usb_submit_urb(urb, GFP_ATOMIC);
    if (rv)
        dev_err(&desc->intf->dev,
                "%s - usb_submit_urb failed with result %d\n",
                __func__, rv);

}
示例#9
0
static int bpa10x_send_frame(struct sk_buff *skb)
{
    struct hci_dev *hdev = (struct hci_dev *) skb->dev;
    struct bpa10x_data *data = hdev->driver_data;
    struct usb_ctrlrequest *dr;
    struct urb *urb;
    unsigned int pipe;
    int err;

    BT_DBG("%s", hdev->name);

    if (!test_bit(HCI_RUNNING, &hdev->flags))
        return -EBUSY;

    urb = usb_alloc_urb(0, GFP_ATOMIC);
    if (!urb)
        return -ENOMEM;


    *skb_push(skb, 1) = bt_cb(skb)->pkt_type;

    switch (bt_cb(skb)->pkt_type) {
    case HCI_COMMAND_PKT:
        dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
        if (!dr) {
            usb_free_urb(urb);
            return -ENOMEM;
        }

        dr->bRequestType = USB_TYPE_VENDOR;
        dr->bRequest     = 0;
        dr->wIndex       = 0;
        dr->wValue       = 0;
        dr->wLength      = __cpu_to_le16(skb->len);

        pipe = usb_sndctrlpipe(data->udev, 0x00);

        usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
                             skb->data, skb->len, bpa10x_tx_complete, skb);

        hdev->stat.cmd_tx++;
        break;

    case HCI_ACLDATA_PKT:
        pipe = usb_sndbulkpipe(data->udev, 0x02);

        usb_fill_bulk_urb(urb, data->udev, pipe,
                          skb->data, skb->len, bpa10x_tx_complete, skb);

        hdev->stat.acl_tx++;
        break;

    case HCI_SCODATA_PKT:
        pipe = usb_sndbulkpipe(data->udev, 0x02);

        usb_fill_bulk_urb(urb, data->udev, pipe,
                          skb->data, skb->len, bpa10x_tx_complete, skb);

        hdev->stat.sco_tx++;
        break;

    default:
        usb_free_urb(urb);
        return -EILSEQ;
    }

    usb_anchor_urb(urb, &data->tx_anchor);

    err = usb_submit_urb(urb, GFP_ATOMIC);
    if (err < 0) {
        BT_ERR("%s urb %p submission failed", hdev->name, urb);
        kfree(urb->setup_packet);
        usb_unanchor_urb(urb);
    }

    usb_free_urb(urb);

    return 0;
}
示例#10
0
int usb_control_msg(struct usb_device *dev, u32 pipe,
		    u8 request, u8 requesttype, u16 value, u16 index,
		    void *data, u16 size, int *actual_length, int timeout)
{
	int rc;
	u64 tout;
	struct urb u;
	struct vmm_completion uc;
	struct usb_ctrlrequest __cacheline_aligned setup;

	/* Initialize setup packet */
	setup.bRequestType = requesttype;
	setup.bRequest = request;
	setup.wValue = vmm_cpu_to_le16(value);
	setup.wIndex = vmm_cpu_to_le16(index);
	setup.wLength = vmm_cpu_to_le16(size);
	DPRINTF("%s: request: 0x%X, requesttype: 0x%X, " \
		"value 0x%X index 0x%X length 0x%X\n", 
		__func__, request, requesttype, value, index, size);

	/* Initialize URB */
	usb_init_urb(&u);

	/* Initialize URB completion */
	INIT_COMPLETION(&uc);

	/* Fill URB */
	usb_fill_control_urb(&u, dev, pipe, 
			     (u8 *)&setup, data, size,
			     urb_request_complete, &uc);

	/* Submit URB */
	rc = usb_hcd_submit_urb(&u);
	if (rc) {
		return rc;
	}

	/* Wait for completion */
	if (timeout < 1) {
		vmm_completion_wait(&uc);
		rc = VMM_OK;
	} else {
		tout = timeout * 1000000ULL;
		rc = vmm_completion_wait_timeout(&uc, &tout);
	}
	if (rc) {
		return rc;
	}

	/* If URB failed then return status */
	if (u.status < 0) {
		return u.status;
	}

	/* Return actual transfer length */
	if (actual_length) {
		*actual_length = u.actual_length;
	}

	return VMM_OK;
}
示例#11
0
static int yurex_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
	struct usb_yurex *dev;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	int retval = -ENOMEM;
	int i;
	DEFINE_WAIT(wait);

	/* allocate memory for our device state and initialize it */
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		err("Out of memory");
		goto error;
	}
	kref_init(&dev->kref);
	mutex_init(&dev->io_mutex);
	spin_lock_init(&dev->lock);
	init_waitqueue_head(&dev->waitq);

	dev->udev = usb_get_dev(interface_to_usbdev(interface));
	dev->interface = interface;

	/* set up the endpoint information */
	iface_desc = interface->cur_altsetting;
	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (usb_endpoint_is_int_in(endpoint)) {
			dev->int_in_endpointAddr = endpoint->bEndpointAddress;
			break;
		}
	}
	if (!dev->int_in_endpointAddr) {
		retval = -ENODEV;
		err("Could not find endpoints");
		goto error;
	}


	/* allocate control URB */
	dev->cntl_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->cntl_urb) {
		err("Could not allocate control URB");
		goto error;
	}

	/* allocate buffer for control req */
	dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
					   GFP_KERNEL,
					   &dev->cntl_urb->setup_dma);
	if (!dev->cntl_req) {
		err("Could not allocate cntl_req");
		goto error;
	}

	/* allocate buffer for control msg */
	dev->cntl_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
					      GFP_KERNEL,
					      &dev->cntl_urb->transfer_dma);
	if (!dev->cntl_buffer) {
		err("Could not allocate cntl_buffer");
		goto error;
	}

	/* configure control URB */
	dev->cntl_req->bRequestType = USB_DIR_OUT | USB_TYPE_CLASS |
				      USB_RECIP_INTERFACE;
	dev->cntl_req->bRequest	= HID_REQ_SET_REPORT;
	dev->cntl_req->wValue	= cpu_to_le16((HID_OUTPUT_REPORT + 1) << 8);
	dev->cntl_req->wIndex	= cpu_to_le16(iface_desc->desc.bInterfaceNumber);
	dev->cntl_req->wLength	= cpu_to_le16(YUREX_BUF_SIZE);

	usb_fill_control_urb(dev->cntl_urb, dev->udev,
			     usb_sndctrlpipe(dev->udev, 0),
			     (void *)dev->cntl_req, dev->cntl_buffer,
			     YUREX_BUF_SIZE, yurex_control_callback, dev);
	dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;


	/* allocate interrupt URB */
	dev->urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->urb) {
		err("Could not allocate URB");
		goto error;
	}

	/* allocate buffer for interrupt in */
	dev->int_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
					GFP_KERNEL, &dev->urb->transfer_dma);
	if (!dev->int_buffer) {
		err("Could not allocate int_buffer");
		goto error;
	}

	/* configure interrupt URB */
	usb_fill_int_urb(dev->urb, dev->udev,
			 usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),
			 dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,
			 dev, 1);
	dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
		retval = -EIO;
		err("Could not submitting URB");
		goto error;
	}

	/* save our data pointer in this interface device */
	usb_set_intfdata(interface, dev);

	/* we can register the device now, as it is ready */
	retval = usb_register_dev(interface, &yurex_class);
	if (retval) {
		err("Not able to get a minor for this device.");
		usb_set_intfdata(interface, NULL);
		goto error;
	}

	dev->bbu = -1;

	dev_info(&interface->dev,
		 "USB YUREX device now attached to Yurex #%d\n",
		 interface->minor);

	return 0;

error:
	if (dev)
		/* this frees allocated memory */
		kref_put(&dev->kref, yurex_delete);
	return retval;
}
示例#12
0
static void
ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
				    u16 size, void *data)
{
	struct usb_ctrlrequest *req;
	int status;
	struct urb *urb;
	void *buf = NULL;
	u16 buf_le;

	if (2 == size) {
		buf_le = *((u16 *)data);
		cpu_to_le16s(&buf_le);
	}

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (urb == NULL) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
		netdev_err(dev->net, "Error allocating URB in write_cmd_async!");
#else
		deverr(dev, "Error allocating URB in write_cmd_async!");
#endif
		return;
	}

	if (data) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
		if (2 == size)
			buf = kmemdup(&buf_le, size, GFP_ATOMIC);
		else
			buf = kmemdup(data, size, GFP_ATOMIC);
#else
			buf = kmalloc(size, GFP_ATOMIC);
#endif

		if (!buf) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
			netdev_err(dev->net, "Error allocating buffer in %s!\n",
				   __func__);
#else
		deverr(dev,  "Error allocating buffer in %s!\n", __func__);
#endif
			return;
		} else {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
			if (2 == size)
				memcpy(buf, &buf_le, size);
			else
				memcpy(buf, data, size);
#endif
		}
	}

	req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
	if (req  == NULL) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
		netdev_err(dev->net, "Failed to allocate memory for control request");
#else
		deverr(dev, "Failed to allocate memory for control request");
#endif
		usb_free_urb(urb);
		return;
	}

	req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
	req->bRequest = cmd;
	req->wValue = cpu_to_le16(value);
	req->wIndex = cpu_to_le16(index);
	req->wLength = cpu_to_le16(size);

	usb_fill_control_urb(urb, dev->udev,
			     usb_sndctrlpipe(dev->udev, 0),
			     (void *)req, buf, size,
			     ax88179_async_cmd_callback, req);

	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status < 0) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
		netdev_err(dev->net, "Error submitting the control message: status=%d",
			   status);
#else
		deverr(dev, "Error submitting the control message: status=%d",
		       status);
#endif
		kfree(req);
		usb_free_urb(urb);
	}
}
static void ipc_bridge_int_cb(struct urb *urb)
{
	struct ipc_bridge *dev = urb->context;
	struct usb_cdc_notification *ctl;
	int status;
	unsigned long flags;

	if (urb->dev->state == USB_STATE_NOTATTACHED)
		return;

	spin_lock_irqsave(&dev->lock, flags);
	dev->rx_state = RX_IDLE;
	spin_unlock_irqrestore(&dev->lock, flags);

	switch (urb->status) {
	case 0:
	case -ENOENT:
		break;

	case -ESHUTDOWN:
	case -ECONNRESET:
	case -EPROTO:
	case -EPIPE:
		return;

	case -EOVERFLOW:
	default:
		ipc_bridge_submit_inturb(dev, GFP_ATOMIC);
		return;
	}

	if (!urb->actual_length)
		return;

	ctl = urb->transfer_buffer;

	switch (ctl->bNotificationType) {
	case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:

		spin_lock_irqsave(&dev->lock, flags);
		dev->rx_state = RX_BUSY;
		spin_unlock_irqrestore(&dev->lock, flags);

		usb_fill_control_urb(dev->readurb, dev->udev,
				usb_rcvctrlpipe(dev->udev, 0),
				(unsigned char *)dev->in_ctlreq,
				dev->readbuf, IPC_BRIDGE_MAX_READ_SZ,
				ipc_bridge_read_cb, dev);

		status = usb_submit_urb(dev->readurb, GFP_ATOMIC);
		if (status) {
			dev_err(&dev->intf->dev, "read urb submit err %d\n",
					status);
			goto resubmit_int_urb;
		}
		dev->get_encap_resp++;
		/* Tell runtime pm core that we are busy */
		usb_autopm_get_interface_no_resume(dev->intf);
		return;
	default:
		dev_err(&dev->intf->dev, "unknown data on int ep\n");
	}

resubmit_int_urb:
	ipc_bridge_submit_inturb(dev, GFP_ATOMIC);
}
示例#14
-1
static ssize_t wdm_write
(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
    u8 *buf;
    int rv = -EMSGSIZE, r, we;
    struct wdm_device *desc = file->private_data;
    struct usb_ctrlrequest *req;

    if (count > desc->wMaxCommand)
        count = desc->wMaxCommand;

    spin_lock_irq(&desc->iuspin);
    we = desc->werr;
    desc->werr = 0;
    spin_unlock_irq(&desc->iuspin);
    if (we < 0)
        return -EIO;

    r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */
    rv = -ERESTARTSYS;
    if (r)
        goto outnl;

    r = usb_autopm_get_interface(desc->intf);
    if (r < 0)
        goto outnp;

    if (!(file->f_flags & O_NONBLOCK))
        r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
                                     &desc->flags));
    else if (test_bit(WDM_IN_USE, &desc->flags))
        r = -EAGAIN;
    if (r < 0)
        goto out;

    if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
        rv = -ENODEV;
        goto out;
    }

    desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
    if (!buf) {
        rv = -ENOMEM;
        goto out;
    }

    r = copy_from_user(buf, buffer, count);
    if (r > 0) {
        kfree(buf);
        rv = -EFAULT;
        goto out;
    }

    req = desc->orq;
    usb_fill_control_urb(
        desc->command,
        interface_to_usbdev(desc->intf),
        /* using common endpoint 0 */
        usb_sndctrlpipe(interface_to_usbdev(desc->intf), 0),
        (unsigned char *)req,
        buf,
        count,
        wdm_out_callback,
        desc
    );

    req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS |
                         USB_RECIP_INTERFACE);
    req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
    req->wValue = 0;
    req->wIndex = desc->inum;
    req->wLength = cpu_to_le16(count);
    set_bit(WDM_IN_USE, &desc->flags);

    rv = usb_submit_urb(desc->command, GFP_KERNEL);
    if (rv < 0) {
        kfree(buf);
        clear_bit(WDM_IN_USE, &desc->flags);
        dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
    } else {
        dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
                req->wIndex);
    }
out:
    usb_autopm_put_interface(desc->intf);
outnp:
    mutex_unlock(&desc->wlock);
outnl:
    return rv < 0 ? rv : count;
}
示例#15
-1
static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
			 const unsigned char *buf, int count)
{
	struct opticon_private *priv = usb_get_serial_data(port->serial);
	struct usb_serial *serial = port->serial;
	struct urb *urb;
	unsigned char *buffer;
	unsigned long flags;
	int status;
	struct usb_ctrlrequest *dr;

	dbg("%s - port %d", __func__, port->number);

	spin_lock_irqsave(&priv->lock, flags);
	if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
		spin_unlock_irqrestore(&priv->lock, flags);
		dbg("%s - write limit hit", __func__);
		return 0;
	}
	priv->outstanding_urbs++;
	spin_unlock_irqrestore(&priv->lock, flags);

	buffer = kmalloc(count, GFP_ATOMIC);
	if (!buffer) {
		dev_err(&port->dev, "out of memory\n");
		count = -ENOMEM;

		goto error_no_buffer;
	}

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb) {
		dev_err(&port->dev, "no more free urbs\n");
		count = -ENOMEM;
		goto error_no_urb;
	}

	memcpy(buffer, buf, count);

	usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);

	/* The conncected devices do not have a bulk write endpoint,
	 * to transmit data to de barcode device the control endpoint is used */
	dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
	if (!dr) {
		dev_err(&port->dev, "out of memory\n");
		count = -ENOMEM;
		goto error_no_dr;
	}

	dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT;
	dr->bRequest = 0x01;
	dr->wValue = 0;
	dr->wIndex = 0;
	dr->wLength = cpu_to_le16(count);

	usb_fill_control_urb(urb, serial->dev,
		usb_sndctrlpipe(serial->dev, 0),
		(unsigned char *)dr, buffer, count,
		opticon_write_control_callback, priv);

	/* send it down the pipe */
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		dev_err(&port->dev,
		"%s - usb_submit_urb(write endpoint) failed status = %d\n",
							__func__, status);
		count = status;
		goto error;
	}

	/* we are done with this urb, so let the host driver
	 * really free it when it is finished with it */
	usb_free_urb(urb);

	return count;
error:
	kfree(dr);
error_no_dr:
	usb_free_urb(urb);
error_no_urb:
	kfree(buffer);
error_no_buffer:
	spin_lock_irqsave(&priv->lock, flags);
	--priv->outstanding_urbs;
	spin_unlock_irqrestore(&priv->lock, flags);
	return count;
}
示例#16
-1
/* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */
static void powermate_sync_state(struct powermate_device *pm)
{
	if (pm->requires_update == 0)
		return; /* no updates are required */
	if (pm->config->status == -EINPROGRESS)
		return; /* an update is already in progress; it'll issue this update when it completes */

	if (pm->requires_update & UPDATE_PULSE_ASLEEP){
		pm->configcr->wValue = cpu_to_le16( SET_PULSE_ASLEEP );
		pm->configcr->wIndex = cpu_to_le16( pm->pulse_asleep ? 1 : 0 );
		pm->requires_update &= ~UPDATE_PULSE_ASLEEP;
	}else if (pm->requires_update & UPDATE_PULSE_AWAKE){
		pm->configcr->wValue = cpu_to_le16( SET_PULSE_AWAKE );
		pm->configcr->wIndex = cpu_to_le16( pm->pulse_awake ? 1 : 0 );
		pm->requires_update &= ~UPDATE_PULSE_AWAKE;
	}else if (pm->requires_update & UPDATE_PULSE_MODE){
		int op, arg;
		/* the powermate takes an operation and an argument for its pulse algorithm.
		   the operation can be:
		   0: divide the speed
		   1: pulse at normal speed
		   2: multiply the speed
		   the argument only has an effect for operations 0 and 2, and ranges between
		   1 (least effect) to 255 (maximum effect).

		   thus, several states are equivalent and are coalesced into one state.

		   we map this onto a range from 0 to 510, with:
		   0 -- 254    -- use divide (0 = slowest)
		   255         -- use normal speed
		   256 -- 510  -- use multiple (510 = fastest).

		   Only values of 'arg' quite close to 255 are particularly useful/spectacular.
		*/
		if (pm->pulse_speed < 255) {
			op = 0;                   // divide
			arg = 255 - pm->pulse_speed;
		} else if (pm->pulse_speed > 255) {
			op = 2;                   // multiply
			arg = pm->pulse_speed - 255;
		} else {
			op = 1;                   // normal speed
			arg = 0;                  // can be any value
		}
		pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE );
		pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op );
		pm->requires_update &= ~UPDATE_PULSE_MODE;
	} else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS) {
		pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
		pm->configcr->wIndex = cpu_to_le16( pm->static_brightness );
		pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
	} else {
		printk(KERN_ERR "powermate: unknown update required");
		pm->requires_update = 0; /* fudge the bug */
		return;
	}

/*	printk("powermate: %04x %04x\n", pm->configcr->wValue, pm->configcr->wIndex); */

	pm->configcr->bRequestType = 0x41; /* vendor request */
	pm->configcr->bRequest = 0x01;
	pm->configcr->wLength = 0;

	usb_fill_control_urb(pm->config, pm->udev, usb_sndctrlpipe(pm->udev, 0),
			     (void *) pm->configcr, NULL, 0,
			     powermate_config_complete, pm);
	pm->config->setup_dma = pm->configcr_dma;
	pm->config->transfer_flags |= URB_NO_SETUP_DMA_MAP;

	if (usb_submit_urb(pm->config, GFP_ATOMIC))
		printk(KERN_ERR "powermate: usb_submit_urb(config) failed");
}
示例#17
-1
int ctrl_bridge_write(unsigned int id, char *data, size_t size)
{
	int			result;
	struct urb		*writeurb;
	struct usb_ctrlrequest	*out_ctlreq;
	struct usb_device	*udev;
	struct ctrl_bridge	*dev;

	if (id >= MAX_BRIDGE_DEVICES) {
		result = -EINVAL;
		goto free_data;
	}

	dev = __dev[id];

	if (!dev) {
		result = -ENODEV;
		goto free_data;
	}

	/* wait till, LPA wake complete */
	if (pm_dev_wait_lpa_wake() < 0)
		return -EAGAIN;

	udev = interface_to_usbdev(dev->intf);

	dev_dbg(&udev->dev, "%s:[id]:%u: write (%d bytes)\n",
		__func__, id, size);

	writeurb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!writeurb) {
		dev_err(&udev->dev, "%s: error allocating read urb\n",
			__func__);
		result = -ENOMEM;
		goto free_data;
	}

	out_ctlreq = kmalloc(sizeof(*out_ctlreq), GFP_ATOMIC);
	if (!out_ctlreq) {
		dev_err(&udev->dev,
			"%s: error allocating setup packet buffer\n",
			__func__);
		result = -ENOMEM;
		goto free_urb;
	}

	/* CDC Send Encapsulated Request packet */
	out_ctlreq->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS |
				 USB_RECIP_INTERFACE);
	if (!data && !size) {
		out_ctlreq->bRequest = USB_CDC_REQ_SET_CONTROL_LINE_STATE;
		out_ctlreq->wValue = dev->cbits_tomdm;
		dev->set_ctrl_line_sts++;
	} else {
		out_ctlreq->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
		out_ctlreq->wValue = 0;
		dev->snd_encap_cmd++;
	}
	out_ctlreq->wIndex =
		dev->intf->cur_altsetting->desc.bInterfaceNumber;
	out_ctlreq->wLength = cpu_to_le16(size);

	usb_fill_control_urb(writeurb, udev,
				 usb_sndctrlpipe(udev, 0),
				 (unsigned char *)out_ctlreq,
				 (void *)data, size,
				 ctrl_write_callback, dev);

	result = usb_autopm_get_interface_async(dev->intf);
	if (result < 0) {
		dev_err(&udev->dev, "%s: unable to resume interface: %d\n",
			__func__, result);

		/*
		  * Revisit: if (result == -EPERM)
		  * bridge_suspend(dev->intf, PMSG_SUSPEND);
		  */

		goto free_ctrlreq;
	}

	if (test_bit(SUSPENDED, &dev->flags)) {
		usb_anchor_urb(writeurb, &dev->tx_deferred);
		goto deferred;
	}

	usb_anchor_urb(writeurb, &dev->tx_submitted);
	result = usb_submit_urb(writeurb, GFP_ATOMIC);
	if (result < 0) {
		dev_err(&udev->dev, "%s: submit URB error %d\n",
			__func__, result);
		usb_autopm_put_interface_async(dev->intf);
		goto unanchor_urb;
	}
deferred:
	return size;

unanchor_urb:
	usb_unanchor_urb(writeurb);
free_ctrlreq:
	kfree(out_ctlreq);
free_urb:
	usb_free_urb(writeurb);
free_data:
	kfree(data);

	return result;
}
示例#18
-1
static void notification_available_cb(struct urb *urb)
{
	int				status;
	struct usb_cdc_notification	*ctrl;
	struct usb_device		*udev;
	struct ctrl_bridge		*dev = urb->context;
	struct bridge			*brdg = dev->brdg;
	unsigned int			ctrl_bits;
	unsigned char			*data;
	unsigned int		iface_num;

	/* if this intf is already disconnected, this urb free-ed before
	 * calling from qh_completions. just return and do nothing */
	if (!dev->intf)
		return;

	udev = interface_to_usbdev(dev->intf);
	iface_num = dev->intf->cur_altsetting->desc.bInterfaceNumber;

	switch (urb->status) {
	case 0:
		pr_info("[NACB:%d]<\n", iface_num);
		/*success*/
		break;
	case -ESHUTDOWN:
	case -ENOENT:
	case -ECONNRESET:
	case -EPROTO:
		 /* unplug */
		 return;
	case -EPIPE:
		dev_err(&udev->dev, "%s: stall on int endpoint\n", __func__);
		/* TBD : halt to be cleared in work */
	case -EOVERFLOW:
	default:
		pr_debug_ratelimited("%s: non zero urb status = %d\n",
					__func__, urb->status);
		goto resubmit_int_urb;
	}

	ctrl = (struct usb_cdc_notification *)urb->transfer_buffer;
	data = (unsigned char *)(ctrl + 1);

	switch (ctrl->bNotificationType) {
	case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
		dev->resp_avail++;
		usb_fill_control_urb(dev->readurb, udev,
					usb_rcvctrlpipe(udev, 0),
					(unsigned char *)dev->in_ctlreq,
					dev->readbuf,
					DEFAULT_READ_URB_LENGTH,
					resp_avail_cb, dev);

		status = usb_submit_urb(dev->readurb, GFP_ATOMIC);
		if (status) {
			dev_err(&udev->dev,
				"%s: Error submitting Read URB %d\n",
				__func__, status);
			goto resubmit_int_urb;
		} else
			pr_info("[NRA:%d]>\n", iface_num);
		return;
	case USB_CDC_NOTIFY_NETWORK_CONNECTION:
		dev_dbg(&udev->dev, "%s network\n", ctrl->wValue ?
					"connected to" : "disconnected from");
		break;
	case USB_CDC_NOTIFY_SERIAL_STATE:
		dev->notify_ser_state++;
		ctrl_bits = get_unaligned_le16(data);
		dev_dbg(&udev->dev, "serial state: %d\n", ctrl_bits);
		dev->cbits_tohost = ctrl_bits;
		if (brdg && brdg->ops.send_cbits)
			brdg->ops.send_cbits(brdg->ctx, ctrl_bits);
#ifdef CONFIG_MDM_HSIC_PM
		pr_info("%s: set lpa handling to false\n", __func__);
		lpa_handling = false;
#endif
		break;
	default:
		dev_err(&udev->dev, "%s: unknown notification %d received:"
			"index %d len %d data0 %d data1 %d",
			__func__, ctrl->bNotificationType, ctrl->wIndex,
			ctrl->wLength, data[0], data[1]);
	}

resubmit_int_urb:
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		dev_err(&udev->dev, "%s: Error re-submitting Int URB %d\n",
		__func__, status);
	} else
		pr_info("[CHKRA:%d]>\n", iface_num);
}
示例#19
-1
static int igorplugusb_probe(struct usb_interface *intf,
					const struct usb_device_id *id)
{
	struct usb_device *udev;
	struct usb_host_interface *idesc;
	struct usb_endpoint_descriptor *ep;
	struct igorplugusb *ir;
	struct rc_dev *rc;
	int ret = -ENOMEM;

	udev = interface_to_usbdev(intf);
	idesc = intf->cur_altsetting;

	if (idesc->desc.bNumEndpoints != 1) {
		dev_err(&intf->dev, "incorrect number of endpoints");
		return -ENODEV;
	}

	ep = &idesc->endpoint[0].desc;
	if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_control(ep)) {
		dev_err(&intf->dev, "endpoint incorrect");
		return -ENODEV;
	}

	ir = devm_kzalloc(&intf->dev, sizeof(*ir), GFP_KERNEL);
	if (!ir)
		return -ENOMEM;

	ir->dev = &intf->dev;

	setup_timer(&ir->timer, igorplugusb_timer, (unsigned long)ir);

	ir->request.bRequest = GET_INFRACODE;
	ir->request.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN;
	ir->request.wLength = cpu_to_le16(sizeof(ir->buf_in));

	ir->urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!ir->urb)
		goto fail;

	usb_fill_control_urb(ir->urb, udev,
		usb_rcvctrlpipe(udev, 0), (uint8_t *)&ir->request,
		ir->buf_in, sizeof(ir->buf_in), igorplugusb_callback, ir);

	usb_make_path(udev, ir->phys, sizeof(ir->phys));

	rc = rc_allocate_device(RC_DRIVER_IR_RAW);
	if (!rc)
		goto fail;

	rc->device_name = DRIVER_DESC;
	rc->input_phys = ir->phys;
	usb_to_input_id(udev, &rc->input_id);
	rc->dev.parent = &intf->dev;
	/*
	 * This device can only store 36 pulses + spaces, which is not enough
	 * for the NEC protocol and many others.
	 */
	rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER &
		~(RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 |
		  RC_PROTO_BIT_RC6_6A_20 | RC_PROTO_BIT_RC6_6A_24 |
		  RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE |
		  RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_SANYO);

	rc->priv = ir;
	rc->driver_name = DRIVER_NAME;
	rc->map_name = RC_MAP_HAUPPAUGE;
	rc->timeout = MS_TO_NS(100);
	rc->rx_resolution = 85333;

	ir->rc = rc;
	ret = rc_register_device(rc);
	if (ret) {
		dev_err(&intf->dev, "failed to register rc device: %d", ret);
		goto fail;
	}

	usb_set_intfdata(intf, ir);

	igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY);

	return 0;
fail:
	rc_free_device(ir->rc);
	usb_free_urb(ir->urb);
	del_timer(&ir->timer);

	return ret;
}
示例#20
-1
static int rmnet_usb_ctrl_write(struct rmnet_ctrl_dev *dev, char *buf,
		size_t size)
{
	int			result;
	struct urb		*sndurb;
	struct usb_ctrlrequest	*out_ctlreq;
	struct usb_device	*udev;

	if (!is_dev_connected(dev))
		return -ENETRESET;

	udev = interface_to_usbdev(dev->intf);
	usb_mark_last_busy(udev);

	sndurb = usb_alloc_urb(0, GFP_KERNEL);
	if (!sndurb) {
		dev_err(dev->devicep, "Error allocating read urb\n");
		return -ENOMEM;
	}

	out_ctlreq = kmalloc(sizeof(*out_ctlreq), GFP_KERNEL);
	if (!out_ctlreq) {
		kfree(buf);
		usb_free_urb(sndurb);
		dev_err(dev->devicep, "Error allocating setup packet buffer\n");
		return -ENOMEM;
	}

	/* CDC Send Encapsulated Request packet */
	out_ctlreq->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS |
			     USB_RECIP_INTERFACE);
	out_ctlreq->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
	out_ctlreq->wValue = 0;
	out_ctlreq->wIndex = dev->intf->cur_altsetting->desc.bInterfaceNumber;
	out_ctlreq->wLength = cpu_to_le16(size);

	usb_fill_control_urb(sndurb, udev,
			     usb_sndctrlpipe(udev, 0),
			     (unsigned char *)out_ctlreq, (void *)buf, size,
			     ctrl_write_callback, dev);

	result = usb_autopm_get_interface(dev->intf);
	if (result < 0) {
		dev_err(dev->devicep, "%s: Unable to resume interface: %d\n",
			__func__, result);

		/*
		* Revisit:  if (result == -EPERM)
		*		rmnet_usb_suspend(dev->intf, PMSG_SUSPEND);
		*/
		kfree(buf);
		usb_free_urb(sndurb);
		kfree(out_ctlreq);
		return result;
	}

	usb_anchor_urb(sndurb, &dev->tx_submitted);
	dev->snd_encap_cmd_cnt++;
	usb_mark_last_busy(udev);
	result = usb_submit_urb(sndurb, GFP_KERNEL);
	if (result < 0) {
		dev_err(dev->devicep, "%s: Submit URB error %d\n",
			__func__, result);
		dev->snd_encap_cmd_cnt--;
		usb_autopm_put_interface(dev->intf);
		usb_unanchor_urb(sndurb);
		kfree(buf);
		usb_free_urb(sndurb);
		kfree(out_ctlreq);
		return result;
	}

	return size;
}
示例#21
-1
static void notification_available_cb(struct urb *urb)
{
	int				status;
	struct usb_cdc_notification	*ctrl;
	struct usb_device		*udev;
	struct rmnet_ctrl_dev		*dev = urb->context;
	unsigned int		iface_num;

	if (!dev->intf)
		return;

	udev = interface_to_usbdev(dev->intf);
	iface_num = dev->intf->cur_altsetting->desc.bInterfaceNumber;

	switch (urb->status) {
	case 0:
		pr_info("[NACB:%d]<\n", iface_num);
		/*success*/
		break;

	/*do not resubmit*/
	case -ESHUTDOWN:
	case -ENOENT:
	case -ECONNRESET:
	case -EPROTO:
		return;
	case -EPIPE:
		pr_err_ratelimited("%s: Stall on int endpoint\n", __func__);
		/* TBD : halt to be cleared in work */
		return;

	/*resubmit*/
	case -EOVERFLOW:
		pr_err_ratelimited("%s: Babble error happened\n", __func__);
	default:
		 pr_debug_ratelimited("%s: Non zero urb status = %d\n",
			__func__, urb->status);
		goto resubmit_int_urb;
	}

	ctrl = urb->transfer_buffer;

	switch (ctrl->bNotificationType) {
	case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
		dev->resp_avail_cnt++;
		usb_fill_control_urb(dev->rcvurb, udev,
					usb_rcvctrlpipe(udev, 0),
					(unsigned char *)dev->in_ctlreq,
					dev->rcvbuf,
					DEFAULT_READ_URB_LENGTH,
					resp_avail_cb, dev);

		usb_mark_last_busy(udev);
		status = usb_submit_urb(dev->rcvurb, GFP_ATOMIC);
		if (status) {
			dev_err(dev->devicep,
			"%s: Error submitting Read URB %d\n", __func__, status);
			goto resubmit_int_urb;
		} else
			pr_info("[NRA:%d]>\n", iface_num);

		if (!dev->resp_available) {
			dev->resp_available = true;
			wake_up(&dev->open_wait_queue);
		}

		return;
	default:
		 dev_err(dev->devicep,
			"%s:Command not implemented\n", __func__);
	}

resubmit_int_urb:
	usb_mark_last_busy(udev);
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status)
		dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
		__func__, status);

	return;
}
static void notification_available_cb(struct urb *urb)
{
    int				status;
    struct usb_cdc_notification	*ctrl;
    struct ctrl_bridge		*dev = urb->context;
    struct bridge			*brdg = dev->brdg;
    unsigned int			ctrl_bits;
    unsigned char			*data;
    unsigned long			flags;

    /*usb device disconnect*/
    if (urb->dev->state == USB_STATE_NOTATTACHED)
        return;

    spin_lock_irqsave(&dev->lock, flags);
    dev->rx_state = RX_IDLE;
    spin_unlock_irqrestore(&dev->lock, flags);

    switch (urb->status) {
    case 0:
        /*success*/
        break;
    case -ESHUTDOWN:
    case -ENOENT:
    case -ECONNRESET:
    case -EPROTO:
        /* unplug */
        return;
    case -EPIPE:
        dev_err(&dev->intf->dev,
                "%s: stall on int endpoint\n", __func__);
    /* TBD : halt to be cleared in work */
    case -EOVERFLOW:
    default:
        pr_debug_ratelimited("%s: non zero urb status = %d\n",
                             __func__, urb->status);
        goto resubmit_int_urb;
    }

    ctrl = (struct usb_cdc_notification *)urb->transfer_buffer;
    data = (unsigned char *)(ctrl + 1);

    switch (ctrl->bNotificationType) {
    case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
        spin_lock_irqsave(&dev->lock, flags);
        dev->rx_state = RX_BUSY;
        spin_unlock_irqrestore(&dev->lock, flags);
        dev->resp_avail++;
        usb_autopm_get_interface_no_resume(dev->intf);
        usb_fill_control_urb(dev->readurb, dev->udev,
                             usb_rcvctrlpipe(dev->udev, 0),
                             (unsigned char *)dev->in_ctlreq,
                             dev->readbuf,
                             DEFAULT_READ_URB_LENGTH,
                             resp_avail_cb, dev);

        status = usb_submit_urb(dev->readurb, GFP_ATOMIC);
        if (status) {
            dev_err(&dev->intf->dev,
                    "%s: Error submitting Read URB %d\n",
                    __func__, status);
            usb_autopm_put_interface_async(dev->intf);
            goto resubmit_int_urb;
        }
        return;
    case USB_CDC_NOTIFY_NETWORK_CONNECTION:
        dev_dbg(&dev->intf->dev, "%s network\n", ctrl->wValue ?
                "connected to" : "disconnected from");
        break;
    case USB_CDC_NOTIFY_SERIAL_STATE:
        dev->notify_ser_state++;
        ctrl_bits = get_unaligned_le16(data);
        dev_dbg(&dev->intf->dev, "serial state: %d\n", ctrl_bits);
        dev->cbits_tohost = ctrl_bits;
        if (brdg && brdg->ops.send_cbits)
            brdg->ops.send_cbits(brdg->ctx, ctrl_bits);
        break;
    default:
        dev_err(&dev->intf->dev, "%s: unknown notification %d received:"
                "index %d len %d data0 %d data1 %d",
                __func__, ctrl->bNotificationType, ctrl->wIndex,
                ctrl->wLength, data[0], data[1]);
    }

resubmit_int_urb:
    ctrl_bridge_start_read(dev, GFP_ATOMIC);
}