Beispiel #1
0
int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	static const char ifname[] = "usbpn%d";
	const struct usb_cdc_union_desc *union_header = NULL;
	const struct usb_host_interface *data_desc;
	struct usb_interface *data_intf;
	struct usb_device *usbdev = interface_to_usbdev(intf);
	struct net_device *dev;
	struct usbpn_dev *pnd;
	u8 *data;
	int phonet = 0;
	int len, err;

	data = intf->altsetting->extra;
	len = intf->altsetting->extralen;
	while (len >= 3) {
		u8 dlen = data[0];
		if (dlen < 3)
			return -EINVAL;

		/* bDescriptorType */
		if (data[1] == USB_DT_CS_INTERFACE) {
			/* bDescriptorSubType */
			switch (data[2]) {
			case USB_CDC_UNION_TYPE:
				if (union_header || dlen < 5)
					break;
				union_header =
					(struct usb_cdc_union_desc *)data;
				break;
			case 0xAB:
				phonet = 1;
				break;
			}
		}
		data += dlen;
		len -= dlen;
	}

	if (!union_header || !phonet)
		return -EINVAL;

	data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0);
	if (data_intf == NULL)
		return -ENODEV;
	/* Data interface has one inactive and one active setting */
	if (data_intf->num_altsetting != 2)
		return -EINVAL;
	if (data_intf->altsetting[0].desc.bNumEndpoints == 0 &&
	    data_intf->altsetting[1].desc.bNumEndpoints == 2)
		data_desc = data_intf->altsetting + 1;
	else
	if (data_intf->altsetting[0].desc.bNumEndpoints == 2 &&
	    data_intf->altsetting[1].desc.bNumEndpoints == 0)
		data_desc = data_intf->altsetting;
	else
		return -EINVAL;

	dev = alloc_netdev(sizeof(*pnd) + sizeof(pnd->urbs[0]) * rxq_size,
				ifname, usbpn_setup);
	if (!dev)
		return -ENOMEM;

	pnd = netdev_priv(dev);
	SET_NETDEV_DEV(dev, &intf->dev);
	netif_stop_queue(dev);

	pnd->dev = dev;
	pnd->usb = usb_get_dev(usbdev);
	pnd->intf = intf;
	pnd->data_intf = data_intf;
	spin_lock_init(&pnd->tx_lock);
	spin_lock_init(&pnd->rx_lock);
	/* Endpoints */
	if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) {
		pnd->rx_pipe = usb_rcvbulkpipe(usbdev,
			data_desc->endpoint[0].desc.bEndpointAddress);
		pnd->tx_pipe = usb_sndbulkpipe(usbdev,
			data_desc->endpoint[1].desc.bEndpointAddress);
	} else {
		pnd->rx_pipe = usb_rcvbulkpipe(usbdev,
			data_desc->endpoint[1].desc.bEndpointAddress);
		pnd->tx_pipe = usb_sndbulkpipe(usbdev,
			data_desc->endpoint[0].desc.bEndpointAddress);
	}
	pnd->active_setting = data_desc - data_intf->altsetting;

	err = usb_driver_claim_interface(&usbpn_driver, data_intf, pnd);
	if (err)
		goto out;

	/* Force inactive mode until the network device is brought UP */
	usb_set_interface(usbdev, union_header->bSlaveInterface0,
				!pnd->active_setting);
	usb_set_intfdata(intf, pnd);

	err = register_netdev(dev);
	if (err) {
		usb_driver_release_interface(&usbpn_driver, data_intf);
		goto out;
	}

	dev_dbg(&dev->dev, "USB CDC Phonet device found\n");
	return 0;

out:
	usb_set_intfdata(intf, NULL);
	free_netdev(dev);
	return err;
}
Beispiel #2
0
static int acm_probe (struct usb_interface *intf,
		      const struct usb_device_id *id)
{
	struct usb_cdc_union_desc *union_header = NULL;
	struct usb_cdc_country_functional_desc *cfd = NULL;
	char *buffer = intf->altsetting->extra;
	int buflen = intf->altsetting->extralen;
	struct usb_interface *control_interface;
	struct usb_interface *data_interface;
	struct usb_endpoint_descriptor *epctrl;
	struct usb_endpoint_descriptor *epread;
	struct usb_endpoint_descriptor *epwrite;
	struct usb_device *usb_dev = interface_to_usbdev(intf);
	struct acm *acm;
	int minor;
	int ctrlsize,readsize;
	u8 *buf;
	u8 ac_management_function = 0;
	u8 call_management_function = 0;
	int call_interface_num = -1;
	int data_interface_num;
	unsigned long quirks;
	int num_rx_buf;
	int i;

	/* normal quirks */
	quirks = (unsigned long)id->driver_info;
	num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;

	/* handle quirks deadly to normal probing*/
	if (quirks == NO_UNION_NORMAL) {
		data_interface = usb_ifnum_to_if(usb_dev, 1);
		control_interface = usb_ifnum_to_if(usb_dev, 0);
		goto skip_normal_probe;
	}
	
	/* normal probing*/
	if (!buffer) {
		err("Weird descriptor references\n");
		return -EINVAL;
	}

	if (!buflen) {
		if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) {
			dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n");
			buflen = intf->cur_altsetting->endpoint->extralen;
			buffer = intf->cur_altsetting->endpoint->extra;
		} else {
			err("Zero length descriptor references\n");
			return -EINVAL;
		}
	}

	while (buflen > 0) {
		if (buffer [1] != USB_DT_CS_INTERFACE) {
			err("skipping garbage\n");
			goto next_desc;
		}

		switch (buffer [2]) {
			case USB_CDC_UNION_TYPE: /* we've found it */
				if (union_header) {
					err("More than one union descriptor, skipping ...");
					goto next_desc;
				}
				union_header = (struct usb_cdc_union_desc *)
							buffer;
				break;
			case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/
				cfd = (struct usb_cdc_country_functional_desc *)buffer;
				break;
			case USB_CDC_HEADER_TYPE: /* maybe check version */ 
				break; /* for now we ignore it */ 
			case USB_CDC_ACM_TYPE:
				ac_management_function = buffer[3];
				break;
			case USB_CDC_CALL_MANAGEMENT_TYPE:
				call_management_function = buffer[3];
				call_interface_num = buffer[4];
				if ((call_management_function & 3) != 3)
					err("This device cannot do calls on its own. It is no modem.");
				break;
				
			default:
				err("Ignoring extra header, type %d, length %d", buffer[2], buffer[0]);
				break;
			}
next_desc:
		buflen -= buffer[0];
		buffer += buffer[0];
	}

	if (!union_header) {
		if (call_interface_num > 0) {
			dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n");
			data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
			control_interface = intf;
		} else {
			dev_dbg(&intf->dev,"No union descriptor, giving up\n");
			return -ENODEV;
		}
	} else {
		control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
		data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0));
		if (!control_interface || !data_interface) {
			dev_dbg(&intf->dev,"no interfaces\n");
			return -ENODEV;
		}
	}
	
	if (data_interface_num != call_interface_num)
		dev_dbg(&intf->dev,"Separate call control interface. That is not fully supported.\n");

skip_normal_probe:

	/*workaround for switched interfaces */
	if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
		if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) {
			struct usb_interface *t;
			dev_dbg(&intf->dev,"Your device has switched interfaces.\n");

			t = control_interface;
			control_interface = data_interface;
			data_interface = t;
		} else {
			return -EINVAL;
		}
	}

	/* Accept probe requests only for the control interface */
	if (intf != control_interface)
		return -ENODEV;
	
	if (usb_interface_claimed(data_interface)) { /* valid in this context */
		dev_dbg(&intf->dev,"The data interface isn't available\n");
		return -EBUSY;
	}


	if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
		return -EINVAL;

	epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
	epread = &data_interface->cur_altsetting->endpoint[0].desc;
	epwrite = &data_interface->cur_altsetting->endpoint[1].desc;


	/* workaround for switched endpoints */
	if (!usb_endpoint_dir_in(epread)) {
		/* descriptors are swapped */
		struct usb_endpoint_descriptor *t;
		dev_dbg(&intf->dev,"The data interface has switched endpoints\n");
		
		t = epread;
		epread = epwrite;
		epwrite = t;
	}
	dbg("interfaces are valid");
	for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);

	if (minor == ACM_TTY_MINORS) {
		err("no more free acm devices");
		return -ENODEV;
	}

	if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) {
		dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n");
		goto alloc_fail;
	}

	ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
	readsize = le16_to_cpu(epread->wMaxPacketSize)* ( quirks == SINGLE_RX_URB ? 1 : 2);
	acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize);
	acm->control = control_interface;
	acm->data = data_interface;
	acm->minor = minor;
	acm->dev = usb_dev;
	acm->ctrl_caps = ac_management_function;
	acm->ctrlsize = ctrlsize;
	acm->readsize = readsize;
	acm->rx_buflimit = num_rx_buf;
	acm->urb_task.func = acm_rx_tasklet;
	acm->urb_task.data = (unsigned long) acm;
	INIT_WORK(&acm->work, acm_softint);
	spin_lock_init(&acm->throttle_lock);
	spin_lock_init(&acm->write_lock);
	spin_lock_init(&acm->read_lock);
	mutex_init(&acm->mutex);
	acm->write_ready = 1;
	acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);

	buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
	if (!buf) {
		dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n");
		goto alloc_fail2;
	}
	acm->ctrl_buffer = buf;

	if (acm_write_buffers_alloc(acm) < 0) {
		dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
		goto alloc_fail4;
	}

	acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
	if (!acm->ctrlurb) {
		dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
		goto alloc_fail5;
	}
	for (i = 0; i < num_rx_buf; i++) {
		struct acm_ru *rcv = &(acm->ru[i]);

		if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
			dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
			goto alloc_fail7;
		}

		rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
		rcv->instance = acm;
	}
	for (i = 0; i < num_rx_buf; i++) {
		struct acm_rb *buf = &(acm->rb[i]);

		if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
			dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
			goto alloc_fail7;
		}
	}
	acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
	if (!acm->writeurb) {
		dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n");
		goto alloc_fail7;
	}

	usb_set_intfdata (intf, acm);

	i = device_create_file(&intf->dev, &dev_attr_bmCapabilities);
	if (i < 0)
		goto alloc_fail8;

	if (cfd) { /* export the country data */
		acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL);
		if (!acm->country_codes)
			goto skip_countries;
		acm->country_code_size = cfd->bLength - 4;
		memcpy(acm->country_codes, (u8 *)&cfd->wCountyCode0, cfd->bLength - 4);
		acm->country_rel_date = cfd->iCountryCodeRelDate;

		i = device_create_file(&intf->dev, &dev_attr_wCountryCodes);
		if (i < 0) {
			kfree(acm->country_codes);
			goto skip_countries;
		}

		i = device_create_file(&intf->dev, &dev_attr_iCountryCodeRelDate);
		if (i < 0) {
			kfree(acm->country_codes);
			goto skip_countries;
		}
	}

skip_countries:
	usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress),
			 acm->ctrl_buffer, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
	acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	acm->ctrlurb->transfer_dma = acm->ctrl_dma;

	usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
			  NULL, acm->writesize, acm_write_bulk, acm);
	acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;

	dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);

	acm_set_control(acm, acm->ctrlout);

	acm->line.dwDTERate = cpu_to_le32(9600);
	acm->line.bDataBits = 8;
	acm_set_line(acm, &acm->line);

	usb_driver_claim_interface(&acm_driver, data_interface, acm);

	usb_get_intf(control_interface);
	tty_register_device(acm_tty_driver, minor, &control_interface->dev);

	acm_table[minor] = acm;

	return 0;
alloc_fail8:
	usb_free_urb(acm->writeurb);
alloc_fail7:
	for (i = 0; i < num_rx_buf; i++)
		usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
	for (i = 0; i < num_rx_buf; i++)
		usb_free_urb(acm->ru[i].urb);
	usb_free_urb(acm->ctrlurb);
alloc_fail5:
	acm_write_buffers_free(acm);
alloc_fail4:
	usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
alloc_fail2:
	kfree(acm);
alloc_fail:
	return -ENOMEM;
}
/* handles CDC Ethernet and many other network "bulk data" interfaces */
int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
{
	int				tmp;
	struct usb_host_interface	*alt = NULL;
	struct usb_host_endpoint	*in = NULL, *out = NULL;
	struct usb_host_endpoint	*status = NULL;

	for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
		unsigned	ep;

		in = out = status = NULL;
		alt = intf->altsetting + tmp;

		/* take the first altsetting with in-bulk + out-bulk;
		 * remember any status endpoint, just in case;
		 * ignore other endpoints and altsettings.
		 */
		for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) {
			struct usb_host_endpoint	*e;
			int				intr = 0;

			e = alt->endpoint + ep;
			switch (e->desc.bmAttributes) {
			case USB_ENDPOINT_XFER_INT:
				if (!usb_endpoint_dir_in(&e->desc))
					continue;
				intr = 1;
				/* FALLTHROUGH */
			case USB_ENDPOINT_XFER_BULK:
				break;
			default:
				continue;
			}
			if (usb_endpoint_dir_in(&e->desc)) {
				if (!intr && !in)
					in = e;
				else if (intr && !status)
					status = e;
			} else {
				if (!out)
					out = e;
			}
		}
		if (in && out)
			break;
	}
	if (!alt || !in || !out)
		return -EINVAL;

	if (alt->desc.bAlternateSetting != 0 ||
	    !(dev->driver_info->flags & FLAG_NO_SETINT)) {
		tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber,
				alt->desc.bAlternateSetting);
		if (tmp < 0)
			return tmp;
	}

	dev->in = usb_rcvbulkpipe (dev->udev,
			in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
	dev->out = usb_sndbulkpipe (dev->udev,
			out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
	dev->status = status;
	return 0;
}
Beispiel #4
0
static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
{
	struct usb_skel *dev;
	int retval = 0;
	struct urb *urb = NULL;
	char *buf = NULL;
	size_t writesize = min(count, (size_t)MAX_TRANSFER);

	dev = (struct usb_skel *)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 (down_interruptible(&dev->limit_sem)) {
		retval = -ERESTARTSYS;
		goto exit;
	}

	spin_lock_irq(&dev->err_lock);
	if ((retval = dev->errors) < 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_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma);
	if (!buf) {
		retval = -ENOMEM;
		goto error;
	}

	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;
	}

	/* initialize the urb properly */
	usb_fill_bulk_urb(urb, dev->udev,
			  usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
			  buf, writesize, skel_write_bulk_callback, dev);
	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	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) {
		err("%s - failed submitting write urb, error %d", __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_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
		usb_free_urb(urb);
	}
	up(&dev->limit_sem);

exit:
	return retval;
}
static int empeg_write (struct usb_serial_port *port, const unsigned char *buf, int count)
{
	struct usb_serial *serial = port->serial;
	struct urb *urb;
	const unsigned char *current_position = buf;
	unsigned long flags;
	int status;
	int i;
	int bytes_sent = 0;
	int transfer_size;

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

	while (count > 0) {

		/* try to find a free urb in our list of them */
		urb = NULL;

		spin_lock_irqsave (&write_urb_pool_lock, flags);

		for (i = 0; i < NUM_URBS; ++i) {
			if (write_urb_pool[i]->status != -EINPROGRESS) {
				urb = write_urb_pool[i];
				break;
			}
		}

		spin_unlock_irqrestore (&write_urb_pool_lock, flags);

		if (urb == NULL) {
			dbg("%s - no more free urbs", __FUNCTION__);
			goto exit;
		}

		if (urb->transfer_buffer == NULL) {
			urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
			if (urb->transfer_buffer == NULL) {
				dev_err(&port->dev, "%s no more kernel memory...\n", __FUNCTION__);
				goto exit;
			}
		}

		transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE);

		memcpy (urb->transfer_buffer, current_position, transfer_size);

		usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, urb->transfer_buffer);

		/* build up our urb */
		usb_fill_bulk_urb (
			urb,
			serial->dev,
			usb_sndbulkpipe(serial->dev,
				port->bulk_out_endpointAddress), 
			urb->transfer_buffer,
			transfer_size,
			empeg_write_bulk_callback,
			port);

		/* send it down the pipe */
		status = usb_submit_urb(urb, GFP_ATOMIC);
		if (status) {
			dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __FUNCTION__, status);
			bytes_sent = status;
			break;
		}

		current_position += transfer_size;
		bytes_sent += transfer_size;
		count -= transfer_size;
		bytes_out += transfer_size;

	}

exit:
	return bytes_sent;

} 
Beispiel #6
0
static int init_card(struct snd_usb_caiaqdev *dev)
{
	char *c;
	struct usb_device *usb_dev = dev->chip.dev;
	struct snd_card *card = dev->chip.card;
	int err, len;
	
	if (usb_set_interface(usb_dev, 0, 1) != 0) {
		log("can't set alt interface.\n");
		return -EIO;
	}

	usb_init_urb(&dev->ep1_in_urb);
	usb_init_urb(&dev->midi_out_urb);

	usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev, 
			  usb_rcvbulkpipe(usb_dev, 0x1),
			  dev->ep1_in_buf, EP1_BUFSIZE, 
			  usb_ep1_command_reply_dispatch, dev);

	usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev, 
			  usb_sndbulkpipe(usb_dev, 0x1),
			  dev->midi_out_buf, EP1_BUFSIZE, 
			  snd_usb_caiaq_midi_output_done, dev);
	
	init_waitqueue_head(&dev->ep1_wait_queue);
	init_waitqueue_head(&dev->prepare_wait_queue);
	
	if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0)
		return -EIO;

	err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
	if (err)
		return err;

	if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ))
		return -ENODEV;

	usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
		   dev->vendor_name, CAIAQ_USB_STR_LEN);
	
	usb_string(usb_dev, usb_dev->descriptor.iProduct,
		   dev->product_name, CAIAQ_USB_STR_LEN);
	
	usb_string(usb_dev, usb_dev->descriptor.iSerialNumber,
		   dev->serial, CAIAQ_USB_STR_LEN);

	/* terminate serial string at first white space occurence */
	c = strchr(dev->serial, ' ');
	if (c)
		*c = '\0';
	
	strcpy(card->driver, MODNAME);
	strcpy(card->shortname, dev->product_name);

	len = snprintf(card->longname, sizeof(card->longname),
		       "%s %s (serial %s, ",
		       dev->vendor_name, dev->product_name, dev->serial);

	if (len < sizeof(card->longname) - 2)
		len += usb_make_path(usb_dev, card->longname + len,
				     sizeof(card->longname) - len);

	card->longname[len++] = ')';
	card->longname[len] = '\0';
	setup_card(dev);
	return 0;
}
Beispiel #7
0
/**
 * hdm_enqueue - receive a buffer to be used for data transfer
 * @iface: interface to enqueue to
 * @channel: ID of the channel
 * @mbo: pointer to the buffer object
 *
 * This allocates a new URB and fills it according to the channel
 * that is being used for transmission of data. Before the URB is
 * submitted it is stored in the private anchor list.
 *
 * Returns 0 on success. On any error the URB is freed and a error code
 * is returned.
 *
 * Context: Could in _some_ cases be interrupt!
 */
static int hdm_enqueue(struct most_interface *iface, int channel,
		       struct mbo *mbo)
{
	struct most_dev *mdev;
	struct most_channel_config *conf;
	struct device *dev;
	int retval = 0;
	struct urb *urb;
	unsigned long length;
	void *virt_address;

	if (unlikely(!iface || !mbo))
		return -EIO;
	if (unlikely(iface->num_channels <= channel || channel < 0))
		return -ECHRNG;

	mdev = to_mdev(iface);
	conf = &mdev->conf[channel];
	dev = &mdev->usb_device->dev;

	if (!mdev->usb_device)
		return -ENODEV;

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

	if ((conf->direction & MOST_CH_TX) && mdev->padding_active[channel] &&
	    hdm_add_padding(mdev, channel, mbo)) {
		retval = -EIO;
		goto _error;
	}

	urb->transfer_dma = mbo->bus_address;
	virt_address = mbo->virt_address;
	length = mbo->buffer_length;

	if (conf->direction & MOST_CH_TX) {
		usb_fill_bulk_urb(urb, mdev->usb_device,
				  usb_sndbulkpipe(mdev->usb_device,
						  mdev->ep_address[channel]),
				  virt_address,
				  length,
				  hdm_write_completion,
				  mbo);
		if (conf->data_type != MOST_CH_ISOC)
			urb->transfer_flags |= URB_ZERO_PACKET;
	} else {
		usb_fill_bulk_urb(urb, mdev->usb_device,
				  usb_rcvbulkpipe(mdev->usb_device,
						  mdev->ep_address[channel]),
				  virt_address,
				  length + conf->extra_len,
				  hdm_read_completion,
				  mbo);
	}
	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	usb_anchor_urb(urb, &mdev->busy_urbs[channel]);

	retval = usb_submit_urb(urb, GFP_KERNEL);
	if (retval) {
		dev_err(dev, "URB submit failed with error %d.\n", retval);
		goto _error_1;
	}
	return 0;

_error_1:
	usb_unanchor_urb(urb);
_error:
	usb_free_urb(urb);
	return retval;
}
Beispiel #8
0
static int whiteheat_attach(struct usb_serial *serial)
{
	struct usb_serial_port *command_port;
	struct whiteheat_command_private *command_info;
	struct whiteheat_hw_info *hw_info;
	int pipe;
	int ret;
	int alen;
	__u8 *command;
	__u8 *result;

	command_port = serial->port[COMMAND_PORT];

	pipe = usb_sndbulkpipe(serial->dev,
			command_port->bulk_out_endpointAddress);
	command = kmalloc(2, GFP_KERNEL);
	if (!command)
		goto no_command_buffer;
	command[0] = WHITEHEAT_GET_HW_INFO;
	command[1] = 0;

	result = kmalloc(sizeof(*hw_info) + 1, GFP_KERNEL);
	if (!result)
		goto no_result_buffer;
	/*
	 * When the module is reloaded the firmware is still there and
	 * the endpoints are still in the usb core unchanged. This is the
	 * unlinking bug in disguise. Same for the call below.
	 */
	usb_clear_halt(serial->dev, pipe);
	ret = usb_bulk_msg(serial->dev, pipe, command, 2,
						&alen, COMMAND_TIMEOUT_MS);
	if (ret) {
		dev_err(&serial->dev->dev, "%s: Couldn't send command [%d]\n",
			serial->type->description, ret);
		goto no_firmware;
	} else if (alen != 2) {
		dev_err(&serial->dev->dev, "%s: Send command incomplete [%d]\n",
			serial->type->description, alen);
		goto no_firmware;
	}

	pipe = usb_rcvbulkpipe(serial->dev,
				command_port->bulk_in_endpointAddress);
	/* See the comment on the usb_clear_halt() above */
	usb_clear_halt(serial->dev, pipe);
	ret = usb_bulk_msg(serial->dev, pipe, result,
			sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS);
	if (ret) {
		dev_err(&serial->dev->dev, "%s: Couldn't get results [%d]\n",
			serial->type->description, ret);
		goto no_firmware;
	} else if (alen != sizeof(*hw_info) + 1) {
		dev_err(&serial->dev->dev, "%s: Get results incomplete [%d]\n",
			serial->type->description, alen);
		goto no_firmware;
	} else if (result[0] != command[0]) {
		dev_err(&serial->dev->dev, "%s: Command failed [%d]\n",
			serial->type->description, result[0]);
		goto no_firmware;
	}

	hw_info = (struct whiteheat_hw_info *)&result[1];

	dev_info(&serial->dev->dev, "%s: Firmware v%d.%02d\n",
		 serial->type->description,
		 hw_info->sw_major_rev, hw_info->sw_minor_rev);

	command_info = kmalloc(sizeof(struct whiteheat_command_private),
								GFP_KERNEL);
	if (command_info == NULL) {
		dev_err(&serial->dev->dev,
			"%s: Out of memory for port structures\n",
			serial->type->description);
		goto no_command_private;
	}

	mutex_init(&command_info->mutex);
	command_info->port_running = 0;
	init_waitqueue_head(&command_info->wait_command);
	usb_set_serial_port_data(command_port, command_info);
	command_port->write_urb->complete = command_port_write_callback;
	command_port->read_urb->complete = command_port_read_callback;
	kfree(result);
	kfree(command);

	return 0;

no_firmware:
	/* Firmware likely not running */
	dev_err(&serial->dev->dev,
		"%s: Unable to retrieve firmware version, try replugging\n",
		serial->type->description);
	dev_err(&serial->dev->dev,
		"%s: If the firmware is not running (status led not blinking)\n",
		serial->type->description);
	dev_err(&serial->dev->dev,
		"%s: please contact [email protected]\n",
		serial->type->description);
	kfree(result);
	kfree(command);
	return -ENODEV;

no_command_private:
	kfree(result);
no_result_buffer:
	kfree(command);
no_command_buffer:
	return -ENOMEM;
}
Beispiel #9
0
static int sddr55_raw_bulk(struct us_data *us, 
		int direction,
		unsigned char *data,
		unsigned int len) {

	int result;
	int act_len;
	int pipe;

	if (direction == SCSI_DATA_READ)
		pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
	else
		pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);

	result = usb_stor_bulk_msg(us, data, pipe, len, &act_len);

	/* if we stall, we need to clear it before we go on */
	if (result == -EPIPE) {
		US_DEBUGP("EPIPE: clearing endpoint halt for"
			" pipe 0x%x, stalled at %d bytes\n",
			pipe, act_len);
		usb_clear_halt(us->pusb_dev, pipe);
	}

	if (result) {

		/* NAK - that means we've retried a few times already */
		if (result == -ETIMEDOUT) {
			US_DEBUGP("usbat_raw_bulk():"
				" device NAKed\n");

			return US_BULK_TRANSFER_FAILED;
		}

		/* -ENOENT -- we canceled this transfer */
		if (result == -ENOENT) {
			US_DEBUGP("usbat_raw_bulk():"
				" transfer aborted\n");
			return US_BULK_TRANSFER_ABORTED;
		}

		if (result == -EPIPE) {
			US_DEBUGP("usbat_raw_bulk():"
				" output pipe stalled\n");
			return US_BULK_TRANSFER_FAILED;
		}

		/* the catch-all case */
		US_DEBUGP("us_transfer_partial(): unknown error\n");
		return US_BULK_TRANSFER_FAILED;
	}

	if (act_len != len) {
		US_DEBUGP("Warning: Transferred only %d bytes\n",
			act_len);
		return US_BULK_TRANSFER_SHORT;
	}

	US_DEBUGP("Transferred %d of %d bytes\n", act_len, len);

	return US_BULK_TRANSFER_GOOD;
}
Beispiel #10
0
/*
 * Synchronous write to the device
 *
 * Takes care of updating EDC counts and thus, handle device errors.
 */
static
ssize_t i2400mu_tx_bulk_out(struct i2400mu *i2400mu, void *buf, size_t buf_size)
{
	int result;
	struct device *dev = &i2400mu->usb_iface->dev;
	int len;
	struct usb_endpoint_descriptor *epd;
	int pipe, do_autopm = 1;

	result = usb_autopm_get_interface(i2400mu->usb_iface);
	if (result < 0) {
		dev_err(dev, "BM-CMD: can't get autopm: %d\n", result);
		do_autopm = 0;
	}
	epd = usb_get_epd(i2400mu->usb_iface, i2400mu->endpoint_cfg.bulk_out);
	pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress);
retry:
	result = usb_bulk_msg(i2400mu->usb_dev, pipe, buf, buf_size, &len, 200);
	switch (result) {
	case 0:
		if (len != buf_size) {
			dev_err(dev, "BM-CMD: short write (%u B vs %zu "
				"expected)\n", len, buf_size);
			result = -EIO;
			break;
		}
		result = len;
		break;
	case -EPIPE:
		/*
		 * Stall -- maybe the device is choking with our
		 * requests. Clear it and give it some time. If they
		 * happen to often, it might be another symptom, so we
		 * reset.
		 *
		 * No error handling for usb_clear_halt(0; if it
		 * works, the retry works; if it fails, this switch
		 * does the error handling for us.
		 */
		if (edc_inc(&i2400mu->urb_edc,
			    10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
			dev_err(dev, "BM-CMD: too many stalls in "
				"URB; resetting device\n");
			usb_queue_reset_device(i2400mu->usb_iface);
			/* fallthrough */
		} else {
			usb_clear_halt(i2400mu->usb_dev, pipe);
			msleep(10);	/* give the device some time */
			goto retry;
		}
	case -EINVAL:			/* while removing driver */
	case -ENODEV:			/* dev disconnect ... */
	case -ENOENT:			/* just ignore it */
	case -ESHUTDOWN:		/* and exit */
	case -ECONNRESET:
		result = -ESHUTDOWN;
		break;
	case -ETIMEDOUT:			/* bah... */
		break;
	default:				/* any other? */
		if (edc_inc(&i2400mu->urb_edc,
			    EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
				dev_err(dev, "BM-CMD: maximum errors in "
					"URB exceeded; resetting device\n");
				usb_queue_reset_device(i2400mu->usb_iface);
				result = -ENODEV;
				break;
		}
		dev_err(dev, "BM-CMD: URB error %d, retrying\n",
			result);
		goto retry;
	}
	if (do_autopm)
		usb_autopm_put_interface(i2400mu->usb_iface);
	return result;
}
static int speedtch_upload_firmware(struct speedtch_instance_data *instance,
				     const struct firmware *fw1,
				     const struct firmware *fw2)
{
	unsigned char *buffer;
	struct usbatm_data *usbatm = instance->usbatm;
	struct usb_device *usb_dev = usbatm->usb_dev;
	int actual_length;
	int ret = 0;
	int offset;

	usb_dbg(usbatm, "%s entered\n", __func__);

	if (!(buffer = (unsigned char *)__get_free_page(GFP_KERNEL))) {
		ret = -ENOMEM;
		usb_dbg(usbatm, "%s: no memory for buffer!\n", __func__);
		goto out;
	}

	if (!usb_ifnum_to_if(usb_dev, 2)) {
		ret = -ENODEV;
		usb_dbg(usbatm, "%s: interface not found!\n", __func__);
		goto out_free;
	}

	/* URB 7 */
	if (dl_512_first) {	/* some modems need a read before writing the firmware */
		ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE),
				   buffer, 0x200, &actual_length, 2000);

		if (ret < 0 && ret != -ETIMEDOUT)
			usb_warn(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret);
		else
			usb_dbg(usbatm, "%s: BLOCK0 downloaded (%d bytes)\n", __func__, ret);
	}

	/* URB 8 : both leds are static green */
	for (offset = 0; offset < fw1->size; offset += PAGE_SIZE) {
		int thislen = min_t(int, PAGE_SIZE, fw1->size - offset);
		memcpy(buffer, fw1->data + offset, thislen);

		ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, ENDPOINT_FIRMWARE),
				   buffer, thislen, &actual_length, DATA_TIMEOUT);

		if (ret < 0) {
			usb_err(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret);
			goto out_free;
		}
		usb_dbg(usbatm, "%s: BLOCK1 uploaded (%zu bytes)\n", __func__, fw1->size);
	}

	/* USB led blinking green, ADSL led off */

	/* URB 11 */
	ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE),
			   buffer, 0x200, &actual_length, DATA_TIMEOUT);

	if (ret < 0) {
		usb_err(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret);
		goto out_free;
	}
	usb_dbg(usbatm, "%s: BLOCK2 downloaded (%d bytes)\n", __func__, actual_length);

	/* URBs 12 to 139 - USB led blinking green, ADSL led off */
	for (offset = 0; offset < fw2->size; offset += PAGE_SIZE) {
		int thislen = min_t(int, PAGE_SIZE, fw2->size - offset);
		memcpy(buffer, fw2->data + offset, thislen);

		ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, ENDPOINT_FIRMWARE),
				   buffer, thislen, &actual_length, DATA_TIMEOUT);

		if (ret < 0) {
			usb_err(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret);
			goto out_free;
		}
	}
	usb_dbg(usbatm, "%s: BLOCK3 uploaded (%zu bytes)\n", __func__, fw2->size);

	/* USB led static green, ADSL led static red */

	/* URB 142 */
	ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE),
			   buffer, 0x200, &actual_length, DATA_TIMEOUT);

	if (ret < 0) {
		usb_err(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret);
		goto out_free;
	}

	/* success */
	usb_dbg(usbatm, "%s: BLOCK4 downloaded (%d bytes)\n", __func__, actual_length);

	/* Delay to allow firmware to start up. We can do this here
	   because we're in our own kernel thread anyway. */
	msleep_interruptible(1000);

	if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->params.altsetting)) < 0) {
		usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->params.altsetting, ret);
		goto out_free;
	}

	/* Enable software buffering, if requested */
	if (sw_buffering)
		speedtch_set_swbuff(instance, 1);

	/* Magic spell; don't ask us what this does */
	speedtch_test_sequence(instance);

	ret = 0;

out_free:
	free_page((unsigned long)buffer);
out:
	return ret;
}
Beispiel #12
0
s32 rtl8188eu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
{
#ifdef PLATFORM_LINUX
	u16 fc;
	int rc, len, pipe;	
	unsigned int bmcst, tid, qsel;
	struct sk_buff *skb, *pxmit_skb;
	struct urb *urb;
	unsigned char *pxmitbuf;
	struct tx_desc *ptxdesc;
	struct rtw_ieee80211_hdr *tx_hdr;
	struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;	
	struct net_device *pnetdev = padapter->pnetdev;
	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
	struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);	

	
	//DBG_8192C("%s\n", __FUNCTION__);

	skb = pkt;
	
	len = skb->len;
	tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data);
	fc = le16_to_cpu(tx_hdr->frame_ctl);
	bmcst = IS_MCAST(tx_hdr->addr1);

	if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT)
		goto _exit;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/[email protected]/msg17214.html
	pxmit_skb = dev_alloc_skb(len + TXDESC_SIZE);			
#else			
	pxmit_skb = netdev_alloc_skb(pnetdev, len + TXDESC_SIZE);
#endif		

	if(!pxmit_skb)
		goto _exit;

	pxmitbuf = pxmit_skb->data;

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb) {
		goto _exit;
	}

	// ----- fill tx desc -----	
	ptxdesc = (struct tx_desc *)pxmitbuf;	
	_rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
		
	//offset 0	
	ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff); 
	ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//default = 32 bytes for TX Desc
	ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);

	if(bmcst)	
	{
		ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
	}	

	//offset 4	
	ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID

	ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);

	ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode

	//offset 8			

	//offset 12		
	ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);

	//offset 16		
	ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
		
	//offset 20


	//HW append seq
	ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
	ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
	

	rtl8188eu_cal_txdesc_chksum(ptxdesc);
	// ----- end of fill tx desc -----

	//
	skb_put(pxmit_skb, len + TXDESC_SIZE);
	pxmitbuf = pxmitbuf + TXDESC_SIZE;
	_rtw_memcpy(pxmitbuf, skb->data, len);

	//DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);


	// ----- prepare urb for submit -----
	
	//translate DMA FIFO addr to pipehandle
	//pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX);
	pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f);
	
	usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
			  pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
	
	urb->transfer_flags |= URB_ZERO_PACKET;
	usb_anchor_urb(urb, &phostapdpriv->anchored);
	rc = usb_submit_urb(urb, GFP_ATOMIC);
	if (rc < 0) {
		usb_unanchor_urb(urb);
		kfree_skb(skb);
	}
	usb_free_urb(urb);

	
_exit:	
	
	dev_kfree_skb_any(skb);

#endif

	return 0;

}
Beispiel #13
0
int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
{
	struct bulk_cb_wrap *bcb;
	struct bulk_cs_wrap *bcs;
	int result;
	int pipe;
	int partial;
	int ret = USB_STOR_TRANSPORT_ERROR;

	bcb = kmalloc(sizeof *bcb, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
	if (!bcb) {
		return USB_STOR_TRANSPORT_ERROR;
	}
	bcs = kmalloc(sizeof *bcs, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
	if (!bcs) {
		kfree(bcb);
		return USB_STOR_TRANSPORT_ERROR;
	}

	/* set up the command wrapper */
	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
	bcb->DataTransferLength = cpu_to_le32(usb_stor_transfer_length(srb));
	bcb->Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
	bcb->Tag = ++(us->tag);
	bcb->Lun = srb->cmnd[1] >> 5;
	if (us->flags & US_FL_SCM_MULT_TARG)
		bcb->Lun |= srb->target << 4;
	bcb->Length = srb->cmd_len;

	/* construct the pipe handle */
	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);

	/* copy the command payload */
	memset(bcb->CDB, 0, sizeof(bcb->CDB));
	memcpy(bcb->CDB, srb->cmnd, bcb->Length);

	/* send it to out endpoint */
	US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n",
		  le32_to_cpu(bcb->Signature), bcb->Tag,
		  (bcb->Lun >> 4), (bcb->Lun & 0x0F), 
		  le32_to_cpu(bcb->DataTransferLength), bcb->Flags, bcb->Length);
	result = usb_stor_bulk_msg(us, bcb, pipe, US_BULK_CB_WRAP_LEN, 
				   &partial);
	US_DEBUGP("Bulk command transfer result=%d\n", result);

	/* if the command was aborted, indicate that */
	if (result == -ECONNRESET) {
		ret = USB_STOR_TRANSPORT_ABORTED;
		goto out;
	}

	/* if we stall, we need to clear it before we go on */
	if (result == -EPIPE) {
		US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
		result = usb_stor_clear_halt(us, pipe);

		/* if the command was aborted, indicate that */
		if (result == -ECONNRESET) {
			ret = USB_STOR_TRANSPORT_ABORTED;
			goto out;
		}
		result = -EPIPE;
	} else if (result) {
		/* unknown error -- we've got a problem */
		ret = USB_STOR_TRANSPORT_ERROR;
		goto out;
	}

	/* if the command transfered well, then we go to the data stage */
	if (result == 0) {
		/* send/receive data payload, if there is any */
		if (bcb->DataTransferLength) {
			usb_stor_transfer(srb, us);
			result = srb->result;
			US_DEBUGP("Bulk data transfer result 0x%x\n", result);

			/* if it was aborted, we need to indicate that */
			if (result == US_BULK_TRANSFER_ABORTED) {
				ret = USB_STOR_TRANSPORT_ABORTED;
				goto out;
			}
		}
	}

	/* See flow chart on pg 15 of the Bulk Only Transport spec for
	 * an explanation of how this code works.
	 */

	/* construct the pipe handle */
	pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);

	/* get CSW for device status */
	US_DEBUGP("Attempting to get CSW...\n");
	result = usb_stor_bulk_msg(us, bcs, pipe, US_BULK_CS_WRAP_LEN, 
				   &partial);

	/* if the command was aborted, indicate that */
	if (result == -ECONNRESET) {
		ret = USB_STOR_TRANSPORT_ABORTED;
		goto out;
	}

	/* did the attempt to read the CSW fail? */
	if (result == -EPIPE) {
		US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
		result = usb_stor_clear_halt(us, pipe);

		/* if the command was aborted, indicate that */
		if (result == -ECONNRESET) {
			ret = USB_STOR_TRANSPORT_ABORTED;
			goto out;
		}

		/* get the status again */
		US_DEBUGP("Attempting to get CSW (2nd try)...\n");
		result = usb_stor_bulk_msg(us, bcs, pipe,
					   US_BULK_CS_WRAP_LEN, &partial);

		/* if the command was aborted, indicate that */
		if (result == -ECONNRESET) {
			ret = USB_STOR_TRANSPORT_ABORTED;
			goto out;
		}

		/* if it fails again, we need a reset and return an error*/
		if (result == -EPIPE) {
			US_DEBUGP("clearing halt for pipe 0x%x\n", pipe);
			result = usb_stor_clear_halt(us, pipe);

			/* if the command was aborted, indicate that */
			if (result == -ECONNRESET) {
				ret = USB_STOR_TRANSPORT_ABORTED;
			} else {
				ret = USB_STOR_TRANSPORT_ERROR;
			}
			goto out;
		}
	}

	/* if we still have a failure at this point, we're in trouble */
	US_DEBUGP("Bulk status result = %d\n", result);
	if (result) {
		ret = USB_STOR_TRANSPORT_ERROR;
		goto out;
	}

	/* check bulk status */
	US_DEBUGP("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n",
		  le32_to_cpu(bcs->Signature), bcs->Tag, 
		  bcs->Residue, bcs->Status);
	if ((bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) && bcs->Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) ||
	    bcs->Tag != bcb->Tag || 
	    bcs->Status > US_BULK_STAT_PHASE || partial != 13) {
		US_DEBUGP("Bulk logical error\n");
		ret = USB_STOR_TRANSPORT_ERROR;
		goto out;
	}

	/* based on the status code, we report good or bad */
	switch (bcs->Status) {
		case US_BULK_STAT_OK:
			/* command good -- note that data could be short */
			ret = USB_STOR_TRANSPORT_GOOD;
			goto out;

		case US_BULK_STAT_FAIL:
			/* command failed */
			ret = USB_STOR_TRANSPORT_FAILED;
			goto out;

		case US_BULK_STAT_PHASE:
			/* phase error -- note that a transport reset will be
			 * invoked by the invoke_transport() function
			 */
			ret = USB_STOR_TRANSPORT_ERROR;
			goto out;
	}

	/* we should never get here, but if we do, we're in trouble */

 out:
	kfree(bcb);
	kfree(bcs);
	return ret;
}
Beispiel #14
0
static void ir_set_termios(struct tty_struct *tty,
		struct usb_serial_port *port, struct ktermios *old_termios)
{
	struct urb *urb;
	unsigned char *transfer_buffer;
	int result;
	speed_t baud;
	int ir_baud;

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

	baud = tty_get_baud_rate(tty);

	/*
	 * FIXME, we should compare the baud request against the
	 * capability stated in the IR header that we got in the
	 * startup function.
	 */

	switch (baud) {
	case 2400:
		ir_baud = USB_IRDA_BR_2400;
		break;
	case 9600:
		ir_baud = USB_IRDA_BR_9600;
		break;
	case 19200:
		ir_baud = USB_IRDA_BR_19200;
		break;
	case 38400:
		ir_baud = USB_IRDA_BR_38400;
		break;
	case 57600:
		ir_baud = USB_IRDA_BR_57600;
		break;
	case 115200:
		ir_baud = USB_IRDA_BR_115200;
		break;
	case 576000:
		ir_baud = USB_IRDA_BR_576000;
		break;
	case 1152000:
		ir_baud = USB_IRDA_BR_1152000;
		break;
	case 4000000:
		ir_baud = USB_IRDA_BR_4000000;
		break;
	default:
		ir_baud = USB_IRDA_BR_9600;
		baud = 9600;
	}

	if (xbof == -1)
		ir_xbof = ir_xbof_change(ir_add_bof);
	else
		ir_xbof = ir_xbof_change(xbof) ;

	/* Only speed changes are supported */
	tty_termios_copy_hw(tty->termios, old_termios);
	tty_encode_baud_rate(tty, baud, baud);

	/*
	 * send the baud change out on an "empty" data packet
	 */
	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb) {
		dev_err(&port->dev, "%s - no more urbs\n", __func__);
		return;
	}
	transfer_buffer = kmalloc(1, GFP_KERNEL);
	if (!transfer_buffer) {
		dev_err(&port->dev, "%s - out of memory\n", __func__);
		goto err_buf;
	}

	*transfer_buffer = ir_xbof | ir_baud;

	usb_fill_bulk_urb(
		urb,
		port->serial->dev,
		usb_sndbulkpipe(port->serial->dev,
			port->bulk_out_endpointAddress),
		transfer_buffer,
		1,
		ir_set_termios_callback,
		port);

	urb->transfer_flags = URB_ZERO_PACKET;

	result = usb_submit_urb(urb, GFP_KERNEL);
	if (result) {
		dev_err(&port->dev, "%s - failed to submit urb: %d\n",
							__func__, result);
		goto err_subm;
	}

	usb_free_urb(urb);

	return;
err_subm:
	kfree(transfer_buffer);
err_buf:
	usb_free_urb(urb);
}
Beispiel #15
0
static ssize_t camera_write (struct file *file,
	const char *buf, size_t len, loff_t *ppos)
{
	struct camera_state	*camera;
	ssize_t			bytes_written = 0;

	if (len > MAX_PACKET_SIZE)
		return -EINVAL;

	camera = (struct camera_state *) file->private_data;
	down (&camera->sem);
	if (!camera->dev) {
		up (&camera->sem);
		return -ENODEV;
	}
	
	/* most writes will be small: simple commands, sometimes with
	 * parameters.  putting images (like borders) into the camera
	 * would be the main use of big writes.
	 */
	while (len > 0) {
		char		*obuf = camera->buf;
		int		maxretry = MAX_WRITE_RETRY;
		unsigned long	copy_size, thistime;

		/* it's not clear that retrying can do any good ... or that
		 * fragmenting application packets into N writes is correct.
		 */
		thistime = copy_size = len;
		if (copy_from_user (obuf, buf, copy_size)) {
			bytes_written = -EFAULT;
			break;
		}
		while (thistime) {
			int		result;
			int		count;

			if (signal_pending (current)) {
				if (!bytes_written)
					bytes_written = -EINTR;
				goto done;
			}

			result = usb_bulk_msg (camera->dev,
				 usb_sndbulkpipe (camera->dev, camera->outEP),
				 obuf, thistime, &count, HZ*10);

			if (result)
				dbg ("write USB err - %d", result);

			if (count) {
				obuf += count;
				thistime -= count;
				maxretry = MAX_WRITE_RETRY;
				continue;
			} else if (!result)
				break;
				
			if (result == -ETIMEDOUT) {	/* NAK - delay a bit */
				if (!maxretry--) {
					if (!bytes_written)
						bytes_written = -ETIME;
					goto done;
				}
                                interruptible_sleep_on_timeout (&camera->wait,
					RETRY_TIMEOUT);
				continue;
			} 
			if (!bytes_written)
				bytes_written = -EIO;
			goto done;
		}
		bytes_written += copy_size;
		len -= copy_size;
		buf += copy_size;
	}
done:
	up (&camera->sem);
	dbg ("wrote %Zd", bytes_written); 
	return bytes_written;
}
int
usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
{
	struct usbnet			*dev;
	struct net_device		*net;
	struct usb_host_interface	*interface;
	struct driver_info		*info;
	struct usb_device		*xdev;
	int				status;
	const char			*name;

	name = udev->dev.driver->name;
	info = (struct driver_info *) prod->driver_info;
	if (!info) {
		dev_dbg (&udev->dev, "blacklisted by %s\n", name);
		return -ENODEV;
	}
	xdev = interface_to_usbdev (udev);
	interface = udev->cur_altsetting;

	usb_get_dev (xdev);

	status = -ENOMEM;

	// set up our own records
	net = alloc_etherdev(sizeof(*dev));
	if (!net) {
		dbg ("can't kmalloc dev");
		goto out;
	}

	dev = netdev_priv(net);
	dev->udev = xdev;
	dev->intf = udev;
	dev->driver_info = info;
	dev->driver_name = name;
	dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV
				| NETIF_MSG_PROBE | NETIF_MSG_LINK);
	skb_queue_head_init (&dev->rxq);
	skb_queue_head_init (&dev->txq);
	skb_queue_head_init (&dev->done);
	skb_queue_head_init(&dev->rxq_pause);
	dev->bh.func = usbnet_bh;
	dev->bh.data = (unsigned long) dev;
	INIT_WORK (&dev->kevent, kevent);
	dev->delay.function = usbnet_bh;
	dev->delay.data = (unsigned long) dev;
	init_timer (&dev->delay);
	mutex_init (&dev->phy_mutex);

	dev->net = net;
	strcpy (net->name, "usb%d");
	memcpy (net->dev_addr, node_id, sizeof node_id);

	/* rx and tx sides can use different message sizes;
	 * bind() should set rx_urb_size in that case.
	 */
	dev->hard_mtu = net->mtu + net->hard_header_len;
#if 0
// dma_supported() is deeply broken on almost all architectures
	// possible with some EHCI controllers
	if (dma_supported (&udev->dev, DMA_BIT_MASK(64)))
		net->features |= NETIF_F_HIGHDMA;
#endif

	net->netdev_ops = &usbnet_netdev_ops;
	net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
	net->ethtool_ops = &usbnet_ethtool_ops;

	// allow device-specific bind/init procedures
	// NOTE net->name still not usable ...
	if (info->bind) {
		status = info->bind (dev, udev);
		if (status < 0)
			goto out1;

		// heuristic:  "usb%d" for links we know are two-host,
		// else "eth%d" when there's reasonable doubt.  userspace
		// can rename the link if it knows better.
		if ((dev->driver_info->flags & FLAG_ETHER) != 0
				&& (net->dev_addr [0] & 0x02) == 0)
			strcpy (net->name, "eth%d");
		/* WLAN devices should always be named "wlan%d" */
		if ((dev->driver_info->flags & FLAG_WLAN) != 0)
			strcpy(net->name, "wlan%d");

		/* maybe the remote can't receive an Ethernet MTU */
		if (net->mtu > (dev->hard_mtu - net->hard_header_len))
			net->mtu = dev->hard_mtu - net->hard_header_len;
	} else if (!info->in || !info->out)
		status = usbnet_get_endpoints (dev, udev);
	else {
		dev->in = usb_rcvbulkpipe (xdev, info->in);
		dev->out = usb_sndbulkpipe (xdev, info->out);
		if (!(info->flags & FLAG_NO_SETINT))
			status = usb_set_interface (xdev,
				interface->desc.bInterfaceNumber,
				interface->desc.bAlternateSetting);
		else
			status = 0;

	}
	if (status >= 0 && dev->status)
		status = init_status (dev, udev);
	if (status < 0)
		goto out3;

	if (!dev->rx_urb_size)
		dev->rx_urb_size = dev->hard_mtu;
	dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);

	SET_NETDEV_DEV(net, &udev->dev);
	status = register_netdev (net);
	if (status)
		goto out3;
	if (netif_msg_probe (dev))
		devinfo (dev, "register '%s' at usb-%s-%s, %s, %pM",
			udev->dev.driver->name,
			xdev->bus->bus_name, xdev->devpath,
			dev->driver_info->description,
			net->dev_addr);

	// ok, it's ready to go.
	usb_set_intfdata (udev, dev);

	// start as if the link is up
	netif_device_attach (net);

	return 0;

out3:
	if (info->unbind)
		info->unbind (dev, udev);
out1:
	free_netdev(net);
out:
	usb_put_dev(xdev);
	return status;
}
Beispiel #17
0
/*
 * Callback to search the Mustek MDC800 on the USB Bus
 */
static int mdc800_usb_probe (struct usb_interface *intf,
			       const struct usb_device_id *id)
{
	int i,j;
	struct usb_host_interface *intf_desc;
	struct usb_device *dev = interface_to_usbdev (intf);
	int irq_interval=0;
	int retval;

	dbg ("(mdc800_usb_probe) called.");


	if (mdc800->dev != 0)
	{
		warn ("only one Mustek MDC800 is supported.");
		return -ENODEV;
	}

	if (dev->descriptor.bNumConfigurations != 1)
	{
		err ("probe fails -> wrong Number of Configuration");
		return -ENODEV;
	}
	intf_desc = intf->cur_altsetting;

	if (
			( intf_desc->desc.bInterfaceClass != 0xff )
		||	( intf_desc->desc.bInterfaceSubClass != 0 )
		|| ( intf_desc->desc.bInterfaceProtocol != 0 )
		|| ( intf_desc->desc.bNumEndpoints != 4)
	)
	{
		err ("probe fails -> wrong Interface");
		return -ENODEV;
	}

	/* Check the Endpoints */
	for (i=0; i<4; i++)
	{
		mdc800->endpoint[i]=-1;
		for (j=0; j<4; j++)
		{
			if (mdc800_endpoint_equals (&intf_desc->endpoint [j].desc,&mdc800_ed [i]))
			{
				mdc800->endpoint[i]=intf_desc->endpoint [j].desc.bEndpointAddress ;
				if (i==1)
				{
					irq_interval=intf_desc->endpoint [j].desc.bInterval;
				}

				continue;
			}
		}
		if (mdc800->endpoint[i] == -1)
		{
			err ("probe fails -> Wrong Endpoints.");
			return -ENODEV;
		}
	}


	info ("Found Mustek MDC800 on USB.");

	down (&mdc800->io_lock);

	retval = usb_register_dev(intf, &mdc800_class);
	if (retval) {
		err ("Not able to get a minor for this device.");
		return -ENODEV;
	}

	mdc800->dev=dev;
	mdc800->open=0;

	/* Setup URB Structs */
	usb_fill_int_urb (
		mdc800->irq_urb,
		mdc800->dev,
		usb_rcvintpipe (mdc800->dev,mdc800->endpoint [1]),
		mdc800->irq_urb_buffer,
		8,
		mdc800_usb_irq,
		mdc800,
		irq_interval
	);

	usb_fill_bulk_urb (
		mdc800->write_urb,
		mdc800->dev,
		usb_sndbulkpipe (mdc800->dev, mdc800->endpoint[0]),
		mdc800->write_urb_buffer,
		8,
		mdc800_usb_write_notify,
		mdc800
	);

	usb_fill_bulk_urb (
		mdc800->download_urb,
		mdc800->dev,
		usb_rcvbulkpipe (mdc800->dev, mdc800->endpoint [3]),
		mdc800->download_urb_buffer,
		64,
		mdc800_usb_download_notify,
		mdc800
	);

	mdc800->state=READY;

	up (&mdc800->io_lock);
	
	usb_set_intfdata(intf, mdc800);
	return 0;
}
Beispiel #18
0
int  UMAS_BulkTransport(SCSI_CMD_T *srb, UMAS_DATA_T *umas)
{
    int     result, status = 0;
    int     pipe;
    uint32_t    partial;
    struct bulk_cb_wrap  bcb;
    struct bulk_cs_wrap  bcs;

    /* if the device was removed, then we're already reset */
    if(!umas->pusb_dev)
        return SUCCESS;

    /* set up the command wrapper */
    bcb.Signature = UMAS_BULK_CB_SIGN;
    bcb.DataTransferLength = usb_stor_transfer_length(srb);
    bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
    bcb.Tag = srb->serial_number;
    bcb.Lun = srb->cmnd[1] >> 5;

    if(umas->flags & UMAS_FL_SCM_MULT_TARG)
        bcb.Lun |= srb->target << 4;
    bcb.Length = srb->cmd_len;

    /* construct the pipe handle */
    pipe = usb_sndbulkpipe(umas->pusb_dev, umas->ep_out);

    /* copy the command payload */
    memset(bcb.CDB, 0, sizeof(bcb.CDB));
    memcpy(bcb.CDB, srb->cmnd, bcb.Length);

    /* send it to out endpoint */
    UMAS_VDEBUG("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n",
                bcb.Signature, bcb.Tag, (bcb.Lun >> 4), (bcb.Lun & 0x0F),
                bcb.DataTransferLength, bcb.Flags, bcb.Length);
    result = usb_stor_bulk_msg(umas, &bcb, pipe, UMAS_BULK_CB_WRAP_LEN, &partial);
    UMAS_VDEBUG("Bulk command transfer result=%d\n", result);

    /* if the command was aborted, indicate that */
    if(result == USB_ERR_NOENT)
        return USB_STOR_TRANSPORT_ABORTED;

    /* if we stall, we need to clear it before we go on */
    if(result == USB_ERR_PIPE)
    {
        UMAS_DEBUG("UMAS_BulkTransport - 1 clearing endpoint halt for pipe 0x%x\n", pipe);
        clear_halt(umas->pusb_dev, pipe);
    }
    else if(result)
    {
        /* unknown error -- we've got a problem */
        status = USB_STOR_TRANSPORT_ERROR;
        goto bulk_error;
    }

    /* if the command transferred well, then we go to the data stage */
    if(result == 0)
    {
        /* send/receive data payload, if there is any */
        if(bcb.DataTransferLength)
        {
            us_transfer(srb, umas);

            /* if it was aborted, we need to indicate that */
            if(srb->result == USB_STOR_TRANSPORT_ABORTED)
            {
                status = USB_STOR_TRANSPORT_ABORTED;
                goto bulk_error;
            }
        }
    }

    /*
     *  See flow chart on pg 15 of the Bulk Only Transport spec for
     *  an explanation of how this code works.
     */

    /* construct the pipe handle */
    pipe = usb_rcvbulkpipe(umas->pusb_dev, umas->ep_in);

    /* get CSW for device status */
    UMAS_VDEBUG("Attempting to get CSW...\n");
    result = usb_stor_bulk_msg(umas, (char *)&bcs, pipe, UMAS_BULK_CS_WRAP_LEN, &partial);

    /* if the command was aborted, indicate that */
    if(result == USB_ERR_NOENT)
    {
        status = USB_STOR_TRANSPORT_ABORTED;
        goto bulk_error;
    }

    /* did the attempt to read the CSW fail? */
    if(result == USB_ERR_PIPE)
    {
        UMAS_DEBUG("get CSW failed - clearing endpoint halt for pipe 0x%x\n", pipe);
        clear_halt(umas->pusb_dev, pipe);

        /* get the status again */
        UMAS_DEBUG("Attempting to get CSW (2nd try)...\n");
        result = usb_stor_bulk_msg(umas, &bcs, pipe, UMAS_BULK_CS_WRAP_LEN, &partial);

        /* if the command was aborted, indicate that */
        if(result == USB_ERR_NOENT)
        {
            UMAS_DEBUG("get CSW Command was aborted!\n");
            status = USB_STOR_TRANSPORT_ABORTED;
            goto bulk_error;
        }

        /* if it fails again, we need a reset and return an error*/
        if(result == USB_ERR_PIPE)
        {
            UMAS_DEBUG("get CSW command 2nd try failed - clearing halt for pipe 0x%x\n", pipe);
            clear_halt(umas->pusb_dev, pipe);
            status = USB_STOR_TRANSPORT_ERROR;
            goto bulk_error;
        }
    }

    /* if we still have a failure at this point, we're in trouble */
    UMAS_VDEBUG("Bulk status result = %d\n", result);
    if(result)
    {
        status = USB_STOR_TRANSPORT_ERROR;
        goto bulk_error;
    }

    /* check bulk status */
    UMAS_VDEBUG("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n",
                USB_SWAP32(bcs.Signature), bcs.Tag, bcs.Residue, bcs.Status);
    if((bcs.Signature != UMAS_BULK_CS_SIGN) || (bcs.Tag != bcb.Tag) ||
            (bcs.Status > UMAS_BULK_STAT_PHASE) || (partial != 13))
    {
        UMAS_DEBUG("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n",
                   USB_SWAP32(bcs.Signature), bcs.Tag, bcs.Residue, bcs.Status);
        status = USB_STOR_TRANSPORT_ERROR;
        goto bulk_error;
    }

    /* based on the status code, we report good or bad */
    switch(bcs.Status)
    {
        case UMAS_BULK_STAT_OK:
            /* command good -- note that data could be short */
            return USB_STOR_TRANSPORT_GOOD;

        case UMAS_BULK_STAT_FAIL:
            /* command failed */
            status = USB_STOR_TRANSPORT_FAILED;
            goto bulk_error;

        case UMAS_BULK_STAT_PHASE:
            /* phase error -- note that a transport reset will be
             * invoked by the invoke_transport() function
             */
            status = USB_STOR_TRANSPORT_ERROR;
            goto bulk_error;
    }
    /* we should never get here, but if we do, we're in trouble */

bulk_error:
    return status;
}
Beispiel #19
0
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_xpad *xpad;
	struct input_dev *input_dev;
	struct usb_endpoint_descriptor *ep_irq_in;
	int i, error;

	for (i = 0; xpad_device[i].idVendor; i++) {
		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
			break;
	}

	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!xpad || !input_dev) {
		error = -ENOMEM;
		goto fail1;
	}

	xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
					 GFP_KERNEL, &xpad->idata_dma);
	if (!xpad->idata) {
		error = -ENOMEM;
		goto fail1;
	}

	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
	if (!xpad->irq_in) {
		error = -ENOMEM;
		goto fail2;
	}

	xpad->udev = udev;
	xpad->mapping = xpad_device[i].mapping;
	xpad->xtype = xpad_device[i].xtype;

	if (xpad->xtype == XTYPE_UNKNOWN) {
		if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
				xpad->xtype = XTYPE_XBOX360W;
			else
				xpad->xtype = XTYPE_XBOX360;
		} else
			xpad->xtype = XTYPE_XBOX;

		if (dpad_to_buttons)
			xpad->mapping |= MAP_DPAD_TO_BUTTONS;
		if (triggers_to_buttons)
			xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
		if (sticks_to_null)
			xpad->mapping |= MAP_STICKS_TO_NULL;
	}

	xpad->dev = input_dev;
	usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
	strlcat(xpad->phys, "/input0", sizeof(xpad->phys));

	input_dev->name = xpad_device[i].name;
	input_dev->phys = xpad->phys;
	usb_to_input_id(udev, &input_dev->id);
	input_dev->dev.parent = &intf->dev;

	input_set_drvdata(input_dev, xpad);

	input_dev->open = xpad_open;
	input_dev->close = xpad_close;

	input_dev->evbit[0] = BIT_MASK(EV_KEY);

	if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
		input_dev->evbit[0] |= BIT_MASK(EV_ABS);
		/*             */
		for (i = 0; xpad_abs[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs[i]);
	}

	/*                         */
	for (i = 0; xpad_common_btn[i] >= 0; i++)
		__set_bit(xpad_common_btn[i], input_dev->keybit);

	/*                            */
	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
		for (i = 0; xpad360_btn[i] >= 0; i++)
			__set_bit(xpad360_btn[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_btn[i] >= 0; i++)
			__set_bit(xpad_btn[i], input_dev->keybit);
	}

	if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
		for (i = 0; xpad_btn_pad[i] >= 0; i++)
			__set_bit(xpad_btn_pad[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_pad[i] >= 0; i++)
		    xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
	}

	if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
		for (i = 0; xpad_btn_triggers[i] >= 0; i++)
			__set_bit(xpad_btn_triggers[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_triggers[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
	}

	error = xpad_init_output(intf, xpad);
	if (error)
		goto fail3;

	error = xpad_init_ff(xpad);
	if (error)
		goto fail4;

	error = xpad_led_probe(xpad);
	if (error)
		goto fail5;

	ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
	usb_fill_int_urb(xpad->irq_in, udev,
			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
			 xpad, ep_irq_in->bInterval);
	xpad->irq_in->transfer_dma = xpad->idata_dma;
	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	error = input_register_device(xpad->dev);
	if (error)
		goto fail6;

	usb_set_intfdata(intf, xpad);

	if (xpad->xtype == XTYPE_XBOX360W) {
		/*
                                             
                                
   */
		xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL);
		if (!xpad->bulk_out) {
			error = -ENOMEM;
			goto fail7;
		}

		xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL);
		if (!xpad->bdata) {
			error = -ENOMEM;
			goto fail8;
		}

		xpad->bdata[2] = 0x08;
		switch (intf->cur_altsetting->desc.bInterfaceNumber) {
		case 0:
			xpad->bdata[3] = 0x42;
			break;
		case 2:
			xpad->bdata[3] = 0x43;
			break;
		case 4:
			xpad->bdata[3] = 0x44;
			break;
		case 6:
			xpad->bdata[3] = 0x45;
		}

		ep_irq_in = &intf->cur_altsetting->endpoint[1].desc;
		usb_fill_bulk_urb(xpad->bulk_out, udev,
				usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress),
				xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad);

		/*
                                                                
                                                           
                                                        
                                                           
                       
   */
		xpad->irq_in->dev = xpad->udev;
		error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
		if (error)
			goto fail9;
	}

	return 0;

 fail9:	kfree(xpad->bdata);
 fail8:	usb_free_urb(xpad->bulk_out);
 fail7:	input_unregister_device(input_dev);
	input_dev = NULL;
 fail6:	xpad_led_disconnect(xpad);
 fail5:	if (input_dev)
		input_ff_destroy(input_dev);
 fail4:	xpad_deinit_output(xpad);
 fail3:	usb_free_urb(xpad->irq_in);
 fail2:	usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
 fail1:	input_free_device(input_dev);
	kfree(xpad);
	return error;

}
Beispiel #20
0
static ssize_t
write_rio(struct file *file, const char __user *buffer,
	  size_t count, loff_t * ppos)
{
	DEFINE_WAIT(wait);
	struct rio_usb_data *rio = &rio_instance;

	unsigned long copy_size;
	unsigned long bytes_written = 0;
	unsigned int partial;

	int result = 0;
	int maxretry;
	int errn = 0;
	int intr;

	intr = mutex_lock_interruptible(&(rio->lock));
	if (intr)
		return -EINTR;
        /* Sanity check to make sure rio is connected, powered, etc */
        if (rio->present == 0 || rio->rio_dev == NULL) {
		mutex_unlock(&(rio->lock));
		return -ENODEV;
	}



	do {
		unsigned long thistime;
		char *obuf = rio->obuf;

		thistime = copy_size =
		    (count >= OBUF_SIZE) ? OBUF_SIZE : count;
		if (copy_from_user(rio->obuf, buffer, copy_size)) {
			errn = -EFAULT;
			goto error;
		}
		maxretry = 5;
		while (thistime) {
			if (!rio->rio_dev) {
				errn = -ENODEV;
				goto error;
			}
			if (signal_pending(current)) {
				mutex_unlock(&(rio->lock));
				return bytes_written ? bytes_written : -EINTR;
			}

			result = usb_bulk_msg(rio->rio_dev,
					 usb_sndbulkpipe(rio->rio_dev, 2),
					 obuf, thistime, &partial, 5000);

			dbg("write stats: result:%d thistime:%lu partial:%u",
			     result, thistime, partial);

			if (result == -ETIMEDOUT) {	/* NAK - so hold for a while */
				if (!maxretry--) {
					errn = -ETIME;
					goto error;
				}
				prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
				schedule_timeout(NAK_TIMEOUT);
				finish_wait(&rio->wait_q, &wait);
				continue;
			} else if (!result && partial) {
				obuf += partial;
				thistime -= partial;
			} else
				break;
		};
		if (result) {
			err("Write Whoops - %x", result);
			errn = -EIO;
			goto error;
		}
		bytes_written += copy_size;
		count -= copy_size;
		buffer += copy_size;
	} while (count > 0);

	mutex_unlock(&(rio->lock));

	return bytes_written ? bytes_written : -EIO;

error:
	mutex_unlock(&(rio->lock));
	return errn;
}
Beispiel #21
0
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_xpad *xpad;
	struct input_dev *input_dev;
	struct usb_endpoint_descriptor *ep_irq_in;
	int i;
	int error = -ENOMEM;

	for (i = 0; xpad_device[i].idVendor; i++) {
		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
			break;
	}

	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!xpad || !input_dev)
		goto fail1;

	xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
				       GFP_KERNEL, &xpad->idata_dma);
	if (!xpad->idata)
		goto fail1;

	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
	if (!xpad->irq_in)
		goto fail2;

	xpad->udev = udev;
	xpad->dpad_mapping = xpad_device[i].dpad_mapping;
	xpad->xtype = xpad_device[i].xtype;
	if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN)
		xpad->dpad_mapping = !dpad_to_buttons;
	if (xpad->xtype == XTYPE_UNKNOWN) {
		if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
				xpad->xtype = XTYPE_XBOX360W;
			else
				xpad->xtype = XTYPE_XBOX360;
		} else
			xpad->xtype = XTYPE_XBOX;
	}
	xpad->dev = input_dev;
	usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
	strlcat(xpad->phys, "/input0", sizeof(xpad->phys));

	input_dev->name = xpad_device[i].name;
	input_dev->phys = xpad->phys;
	usb_to_input_id(udev, &input_dev->id);
	input_dev->dev.parent = &intf->dev;

	input_set_drvdata(input_dev, xpad);

	input_dev->open = xpad_open;
	input_dev->close = xpad_close;

	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);

	/* set up buttons */
	for (i = 0; xpad_common_btn[i] >= 0; i++)
		set_bit(xpad_common_btn[i], input_dev->keybit);
	if ((xpad->xtype == XTYPE_XBOX360) || (xpad->xtype == XTYPE_XBOX360W))
		for (i = 0; xpad360_btn[i] >= 0; i++)
			set_bit(xpad360_btn[i], input_dev->keybit);
	else
		for (i = 0; xpad_btn[i] >= 0; i++)
			set_bit(xpad_btn[i], input_dev->keybit);
	if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS)
		for (i = 0; xpad_btn_pad[i] >= 0; i++)
			set_bit(xpad_btn_pad[i], input_dev->keybit);

	/* set up axes */
	for (i = 0; xpad_abs[i] >= 0; i++)
		xpad_set_up_abs(input_dev, xpad_abs[i]);
	if (xpad->dpad_mapping == MAP_DPAD_TO_AXES)
		for (i = 0; xpad_abs_pad[i] >= 0; i++)
		    xpad_set_up_abs(input_dev, xpad_abs_pad[i]);

	error = xpad_init_output(intf, xpad);
	if (error)
		goto fail2;

	error = xpad_init_ff(xpad);
	if (error)
		goto fail3;

	error = xpad_led_probe(xpad);
	if (error)
		goto fail3;

	ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
	usb_fill_int_urb(xpad->irq_in, udev,
			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
			 xpad, ep_irq_in->bInterval);
	xpad->irq_in->transfer_dma = xpad->idata_dma;
	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	error = input_register_device(xpad->dev);
	if (error)
		goto fail4;

	usb_set_intfdata(intf, xpad);

	/*
	 * Submit the int URB immediatly rather than waiting for open
	 * because we get status messages from the device whether
	 * or not any controllers are attached.  In fact, it's
	 * exactly the message that a controller has arrived that
	 * we're waiting for.
	 */
	if (xpad->xtype == XTYPE_XBOX360W) {
		xpad->irq_in->dev = xpad->udev;
		error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
		if (error)
			goto fail4;

		/*
		 * Setup the message to set the LEDs on the
		 * controller when it shows up
		 */
		xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL);
		if(!xpad->bulk_out)
			goto fail5;

		xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL);
		if(!xpad->bdata)
			goto fail6;

		xpad->bdata[2] = 0x08;
		switch (intf->cur_altsetting->desc.bInterfaceNumber) {
		case 0:
			xpad->bdata[3] = 0x42;
			break;
		case 2:
			xpad->bdata[3] = 0x43;
			break;
		case 4:
			xpad->bdata[3] = 0x44;
			break;
		case 6:
			xpad->bdata[3] = 0x45;
		}

		ep_irq_in = &intf->cur_altsetting->endpoint[1].desc;
		usb_fill_bulk_urb(xpad->bulk_out, udev,
				usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress),
				xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad);
	}

	return 0;

 fail6:	usb_free_urb(xpad->bulk_out);
 fail5:	usb_kill_urb(xpad->irq_in);
 fail4:	usb_free_urb(xpad->irq_in);
 fail3:	xpad_deinit_output(xpad);
 fail2:	usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
 fail1:	input_free_device(input_dev);
	kfree(xpad);
	return error;

}
Beispiel #22
0
static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
			       unsigned int plen, void *payload,
			       unsigned int outlen, void *out)
{
	struct ar9170_usb *aru = (void *) ar;
	struct urb *urb = NULL;
	unsigned long flags;
	int err = -ENOMEM;

	if (unlikely(!IS_ACCEPTING_CMD(ar)))
		return -EPERM;

	if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
		return -EINVAL;

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (unlikely(!urb))
		goto err_free;

	ar->cmdbuf[0] = cpu_to_le32(plen);
	ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
	/* writing multiple regs fills this buffer already */
	if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
		memcpy(&ar->cmdbuf[1], payload, plen);

	spin_lock_irqsave(&aru->common.cmdlock, flags);
	aru->readbuf = (u8 *)out;
	aru->readlen = outlen;
	spin_unlock_irqrestore(&aru->common.cmdlock, flags);

	usb_fill_int_urb(urb, aru->udev,
			 usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
			 aru->common.cmdbuf, plen + 4,
			 ar9170_usb_tx_urb_complete, NULL, 1);

	usb_anchor_urb(urb, &aru->tx_submitted);
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (unlikely(err)) {
		usb_unanchor_urb(urb);
		usb_free_urb(urb);
		goto err_unbuf;
	}
	usb_free_urb(urb);

	err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
	if (err == 0) {
		err = -ETIMEDOUT;
		goto err_unbuf;
	}

	if (aru->readlen != outlen) {
		err = -EMSGSIZE;
		goto err_unbuf;
	}

	return 0;

err_unbuf:
	/* Maybe the device was removed in the second we were waiting? */
	if (IS_STARTED(ar)) {
		dev_err(&aru->udev->dev, "no command feedback "
					 "received (%d).\n", err);

		/* provide some maybe useful debug information */
		print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
				     aru->common.cmdbuf, plen + 4);
		dump_stack();
	}

	/* invalidate to avoid completing the next prematurely */
	spin_lock_irqsave(&aru->common.cmdlock, flags);
	aru->readbuf = NULL;
	aru->readlen = 0;
	spin_unlock_irqrestore(&aru->common.cmdlock, flags);

err_free:

	return err;
}
Beispiel #23
0
static int acm_probe(struct usb_interface *intf,
		     const struct usb_device_id *id)
{
	struct usb_cdc_union_desc *union_header = NULL;
	struct usb_cdc_country_functional_desc *cfd = NULL;
	unsigned char *buffer = intf->altsetting->extra;
	int buflen = intf->altsetting->extralen;
	struct usb_interface *control_interface;
	struct usb_interface *data_interface;
	struct usb_endpoint_descriptor *epctrl = NULL;
	struct usb_endpoint_descriptor *epread = NULL;
	struct usb_endpoint_descriptor *epwrite = NULL;
	struct usb_device *usb_dev = interface_to_usbdev(intf);
	struct acm *acm;
	int minor;
	int ctrlsize, readsize;
	u8 *buf;
	u8 ac_management_function = 0;
	u8 call_management_function = 0;
	int call_interface_num = -1;
	int data_interface_num = -1;
	unsigned long quirks;
	int num_rx_buf;
	int i;
	int combined_interfaces = 0;

	/* normal quirks */
	quirks = (unsigned long)id->driver_info;
	num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;

	/* not a real CDC ACM device */
	if (quirks & NOT_REAL_ACM)
		return -ENODEV;
	

	if (max_intfs == 1) {
		/* XMM HACK - use ACM for interfaces 0/1 only */
		switch (intf->cur_altsetting->desc.bInterfaceNumber)
		{
		case 0: case 1:
		    I("XMM HACK -"
				" interface #%d create for ttyACM device\n",
				intf->cur_altsetting->desc.bInterfaceNumber);
				break;
		default:
			D("XMM HACK -"
				" interface #%d reserved for RAW-IP network driver\n",
				intf->cur_altsetting->desc.bInterfaceNumber);
			return -EINVAL;
		}
	} else if (max_intfs == 2) {
		/* XMM HACK - use ACM for interfaces 0/1 & 6/7 only */
		switch (intf->cur_altsetting->desc.bInterfaceNumber)
		{
		case 0: case 1:
		case 6: case 7:
		    I("XMM HACK -"
				" interface #%d create for ttyACM device\n",
				intf->cur_altsetting->desc.bInterfaceNumber);
				break;
		default:
			D("XMM HACK -"
				" interface #%d reserved for RAW-IP network driver\n",
				intf->cur_altsetting->desc.bInterfaceNumber);
			return -EINVAL;
		}
	}

	/* handle quirks deadly to normal probing*/
	if (quirks & NO_UNION_NORMAL) {
		data_interface = usb_ifnum_to_if(usb_dev, 1);
		control_interface = usb_ifnum_to_if(usb_dev, 0);
		if (!control_interface || !data_interface) {
			E("no ctrl or data interfaces\n");
			return -ENODEV;
		}
		goto skip_normal_probe;
	}

	/* normal probing*/
	if (!buffer) {
		E("Weird descriptor references\n");
		return -EINVAL;
	}

	if (!buflen) {
		if (intf->cur_altsetting->endpoint &&
				intf->cur_altsetting->endpoint->extralen &&
				intf->cur_altsetting->endpoint->extra) {
			D("Seeking extra descriptors on endpoint\n");
			buflen = intf->cur_altsetting->endpoint->extralen;
			buffer = intf->cur_altsetting->endpoint->extra;
		} else {
			E("Zero length descriptor references\n");
			return -EINVAL;
		}
	}

	while (buflen > 0) {
		if (buffer[1] != USB_DT_CS_INTERFACE) {
			E("skipping garbage\n");
			goto next_desc;
		}

		switch (buffer[2]) {
		case USB_CDC_UNION_TYPE: /* we've found it */
			if (union_header) {
				E("More than one "
					"union descriptor, skipping ...\n");
				goto next_desc;
			}
			union_header = (struct usb_cdc_union_desc *)buffer;
			break;
		case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/
			cfd = (struct usb_cdc_country_functional_desc *)buffer;
			break;
		case USB_CDC_HEADER_TYPE: /* maybe check version */
			break; /* for now we ignore it */
		case USB_CDC_ACM_TYPE:
			ac_management_function = buffer[3];
			break;
		case USB_CDC_CALL_MANAGEMENT_TYPE:
			call_management_function = buffer[3];
			call_interface_num = buffer[4];
			if ( (quirks & NOT_A_MODEM) == 0 && (call_management_function & 3) != 3)
				D("This device cannot do calls on its own. It is not a modem.\n");
			break;
		default:
			/* there are LOTS more CDC descriptors that
			 * could legitimately be found here.
			 */
			D("Ignoring descriptor: "
					"type %02x, length %d\n",
					buffer[2], buffer[0]);
			break;
		}
next_desc:
		buflen -= buffer[0];
		buffer += buffer[0];
	}

	if (!union_header) {
		if (call_interface_num > 0) {
			D("No union descriptor, using call management descriptor\n");
			/* quirks for Droids MuIn LCD */
			if (quirks & NO_DATA_INTERFACE)
				data_interface = usb_ifnum_to_if(usb_dev, 0);
			else
				data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
			control_interface = intf;

			if (!data_interface) {
				D("no data interfaces\n");
				return -ENODEV;
			}

		} else {
			if (intf->cur_altsetting->desc.bNumEndpoints != 3) {
				D("No union descriptor, giving up\n");
				return -ENODEV;
			} else {
				D("No union descriptor, testing for castrated device\n");
				combined_interfaces = 1;
				control_interface = data_interface = intf;
				goto look_for_collapsed_interface;
			}
		}
	} else {
		control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
		data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0));
		if (!control_interface || !data_interface) {
			D("no interfaces\n");
			return -ENODEV;
		}
	}

	if (data_interface_num != call_interface_num)
		D("Separate call control interface. That is not fully supported.\n");

	if (control_interface == data_interface) {
		/* some broken devices designed for windows work this way */
		D("Control and data interfaces are not separated!\n");
		combined_interfaces = 1;
		/* a popular other OS doesn't use it */
		quirks |= NO_CAP_LINE;
		if (data_interface->cur_altsetting->desc.bNumEndpoints != 3) {
			E("This needs exactly 3 endpoints\n");
			return -EINVAL;
		}
look_for_collapsed_interface:
		for (i = 0; i < 3; i++) {
			struct usb_endpoint_descriptor *ep;
			ep = &data_interface->cur_altsetting->endpoint[i].desc;

			if (usb_endpoint_is_int_in(ep))
				epctrl = ep;
			else if (usb_endpoint_is_bulk_out(ep))
				epwrite = ep;
			else if (usb_endpoint_is_bulk_in(ep))
				epread = ep;
			else
				return -EINVAL;
		}
		if (!epctrl || !epread || !epwrite)
			return -ENODEV;
		else
			goto made_compressed_probe;
	}

skip_normal_probe:

	/*workaround for switched interfaces */
	if (data_interface->cur_altsetting->desc.bInterfaceClass
						!= CDC_DATA_INTERFACE_TYPE) {
		if (control_interface->cur_altsetting->desc.bInterfaceClass
						== CDC_DATA_INTERFACE_TYPE) {
			struct usb_interface *t;
			D("Your device has switched interfaces.\n");
			t = control_interface;
			control_interface = data_interface;
			data_interface = t;
		} else {
			return -EINVAL;
		}
	}

	/* Accept probe requests only for the control interface */
	if (!combined_interfaces && intf != control_interface)
		return -ENODEV;

	if (!combined_interfaces && usb_interface_claimed(data_interface)) {
		/* valid in this context */
		D("The data interface isn't available\n");
		return -EBUSY;
	}


	if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
		return -EINVAL;

	epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
	epread = &data_interface->cur_altsetting->endpoint[0].desc;
	epwrite = &data_interface->cur_altsetting->endpoint[1].desc;


	/* workaround for switched endpoints */
	if (!usb_endpoint_dir_in(epread)) {
		/* descriptors are swapped */
		struct usb_endpoint_descriptor *t;
		D("The data interface has switched endpoints\n");
		t = epread;
		epread = epwrite;
		epwrite = t;
	}
made_compressed_probe:
	D( "interfaces are valid\n");
	for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);

	if (minor == ACM_TTY_MINORS) {
		E("no more free acm devices\n");
		return -ENODEV;
	}

	acm = kzalloc(sizeof(struct acm), GFP_KERNEL);
	if (acm == NULL) {
		E("out of memory (acm kzalloc)\n");
		goto alloc_fail;
	}

	ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
	readsize = le16_to_cpu(epread->wMaxPacketSize) *
				(quirks == SINGLE_RX_URB ? 1 : 2);
	acm->combined_interfaces = combined_interfaces;
	acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize) * 20;
	acm->control = control_interface;
	acm->data = data_interface;
	acm->minor = minor;
	acm->dev = usb_dev;
	acm->ctrl_caps = ac_management_function;
	if (quirks & NO_CAP_LINE)
		acm->ctrl_caps &= ~USB_CDC_CAP_LINE;
	acm->ctrlsize = ctrlsize;
	acm->readsize = readsize;
	acm->rx_buflimit = num_rx_buf;
	INIT_WORK(&acm->work, acm_softint);
	init_usb_anchor(&acm->deferred);
	spin_lock_init(&acm->write_lock);
	spin_lock_init(&acm->read_lock);
	mutex_init(&acm->mutex);
	acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);
	acm->is_int_ep = usb_endpoint_xfer_int(epread);
	if (acm->is_int_ep)
		acm->bInterval = epread->bInterval;
	if (quirks & NO_HANGUP_IN_RESET_RESUME)
		acm->no_hangup_in_reset_resume = 1;
	tty_port_init(&acm->port);
	acm->port.ops = &acm_port_ops;

	buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
	if (!buf) {
		E("out of memory (ctrl buffer alloc)\n");
		goto alloc_fail2;
	}
	acm->ctrl_buffer = buf;

	if (acm_write_buffers_alloc(acm) < 0) {
		E("out of memory (write buffer alloc)\n");
		goto alloc_fail4;
	}

	acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
	if (!acm->ctrlurb) {
		E("out of memory (ctrlurb kmalloc)\n");
		goto alloc_fail5;
	}
	for (i = 0; i < num_rx_buf; i++) {
		struct acm_rb *rb = &(acm->read_buffers[i]);
		struct urb *urb;

		rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL,
								&rb->dma);
		if (!rb->base) {
			E("out of memory "
					"(read bufs usb_alloc_coherent)\n");
			goto alloc_fail6;
		}
		rb->index = i;
		rb->instance = acm;

		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!urb) {
			E("out of memory (read urbs usb_alloc_urb)\n");
			goto alloc_fail6;
		}
		urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
		urb->transfer_dma = rb->dma;
		if (acm->is_int_ep) {
			usb_fill_int_urb(urb, acm->dev,
					 acm->rx_endpoint,
					 rb->base,
					 acm->readsize,
					 acm_read_bulk_callback, rb,
					 acm->bInterval);
		} else {
			usb_fill_bulk_urb(urb, acm->dev,
					  acm->rx_endpoint,
					  rb->base,
					  acm->readsize,
					  acm_read_bulk_callback, rb);
		}

		acm->read_urbs[i] = urb;
		__set_bit(i, &acm->read_urbs_free);
	}
	for (i = 0; i < ACM_NW; i++) {
		struct acm_wb *snd = &(acm->wb[i]);

		snd->urb = usb_alloc_urb(0, GFP_KERNEL);
		if (snd->urb == NULL) {
			E("out of memory (write urbs usb_alloc_urb)\n");
			goto alloc_fail7;
		}

		if (usb_endpoint_xfer_int(epwrite))
			usb_fill_int_urb(snd->urb, usb_dev,
				usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
				NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval);
		else
			usb_fill_bulk_urb(snd->urb, usb_dev,
				usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
				NULL, acm->writesize, acm_write_bulk, snd);
		snd->urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP+URB_ZERO_PACKET);
		snd->instance = acm;
	}

	usb_set_intfdata(intf, acm);

	i = device_create_file(&intf->dev, &dev_attr_bmCapabilities);
	if (i < 0)
		goto alloc_fail7;

	if (cfd) { /* export the country data */
		acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL);
		if (!acm->country_codes)
			goto skip_countries;
		acm->country_code_size = cfd->bLength - 4;
		memcpy(acm->country_codes, (u8 *)&cfd->wCountyCode0,
							cfd->bLength - 4);
		acm->country_rel_date = cfd->iCountryCodeRelDate;

		i = device_create_file(&intf->dev, &dev_attr_wCountryCodes);
		if (i < 0) {
			kfree(acm->country_codes);
			acm->country_codes = NULL;
			acm->country_code_size = 0;
			goto skip_countries;
		}

		i = device_create_file(&intf->dev,
						&dev_attr_iCountryCodeRelDate);
		if (i < 0) {
			device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
			kfree(acm->country_codes);
			acm->country_codes = NULL;
			acm->country_code_size = 0;
			goto skip_countries;
		}
	}

skip_countries:
	usb_fill_int_urb(acm->ctrlurb, usb_dev,
			 usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress),
			 acm->ctrl_buffer, ctrlsize, acm_ctrl_irq, acm,
			 /* works around buggy devices */
			 epctrl->bInterval ? epctrl->bInterval : 0xff);
	acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	acm->ctrlurb->transfer_dma = acm->ctrl_dma;

	I("ttyACM%d: USB ACM device\n", minor);

	acm_set_control(acm, acm->ctrlout);

	acm->line.dwDTERate = cpu_to_le32(9600);
	acm->line.bDataBits = 8;
	acm_set_line(acm, &acm->line);

	usb_driver_claim_interface(&acm_driver, data_interface, acm);
	usb_set_intfdata(data_interface, acm);

	usb_get_intf(control_interface);
	tty_register_device(acm_tty_driver, minor, &control_interface->dev);

	acm_table[minor] = acm;

	return 0;
alloc_fail7:
	for (i = 0; i < ACM_NW; i++)
		usb_free_urb(acm->wb[i].urb);
alloc_fail6:
	for (i = 0; i < num_rx_buf; i++)
		usb_free_urb(acm->read_urbs[i]);
	acm_read_buffers_free(acm);
	usb_free_urb(acm->ctrlurb);
alloc_fail5:
	acm_write_buffers_free(acm);
alloc_fail4:
	usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
alloc_fail2:
	kfree(acm);
alloc_fail:
	return -ENOMEM;
}
static int __devinit if_usb_probe(struct usb_interface *intf,
					const struct usb_device_id *id)
{
	struct usb_host_interface *data_desc;
	struct usb_link_device *usb_ld =
			(struct usb_link_device *)id->driver_info;
	struct link_device *ld = &usb_ld->ld;
	struct usb_interface *data_intf;
	struct usb_device *usbdev = interface_to_usbdev(intf);
	struct device *dev, *ehci_dev, *root_hub;
	struct if_usb_devdata *pipe;
	struct urb *urb;
	int i;
	int j;
	int dev_id;
	int err;

	/* To detect usb device order probed */
	dev_id = intf->cur_altsetting->desc.bInterfaceNumber;

	if (dev_id >= IF_USB_DEVNUM_MAX) {
		dev_err(&intf->dev, "Device id %d cannot support\n",
								dev_id);
		return -EINVAL;
	}

	if (!usb_ld) {
		dev_err(&intf->dev,
		"if_usb device doesn't be allocated\n");
		err = ENOMEM;
		goto out;
	}

	mif_info("probe dev_id=%d usb_device_id(0x%p), usb_ld (0x%p)\n",
				dev_id, id, usb_ld);

	usb_ld->usbdev = usbdev;
	usb_get_dev(usbdev);

	for (i = 0; i < IF_USB_DEVNUM_MAX; i++) {
		data_intf = usb_ifnum_to_if(usbdev, i);

		/* remap endpoint of RAW to no.1 for LTE modem */
		if (i == 0)
			pipe = &usb_ld->devdata[1];
		else if (i == 1)
			pipe = &usb_ld->devdata[0];
		else
			pipe = &usb_ld->devdata[i];

		pipe->disconnected = 0;
		pipe->data_intf = data_intf;
		data_desc = data_intf->cur_altsetting;

		/* Endpoints */
		if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) {
			pipe->rx_pipe = usb_rcvbulkpipe(usbdev,
				data_desc->endpoint[0].desc.bEndpointAddress);
			pipe->tx_pipe = usb_sndbulkpipe(usbdev,
				data_desc->endpoint[1].desc.bEndpointAddress);
			pipe->rx_buf_size = 1024*4;
		} else {
			pipe->rx_pipe = usb_rcvbulkpipe(usbdev,
				data_desc->endpoint[1].desc.bEndpointAddress);
			pipe->tx_pipe = usb_sndbulkpipe(usbdev,
				data_desc->endpoint[0].desc.bEndpointAddress);
			pipe->rx_buf_size = 1024*4;
		}

		if (i == 0) {
			dev_info(&usbdev->dev, "USB IF USB device found\n");
		} else {
			err = usb_driver_claim_interface(&if_usb_driver,
					data_intf, usb_ld);
			if (err < 0) {
				mif_err("failed to cliam usb interface\n");
				goto out;
			}
		}

		usb_set_intfdata(data_intf, usb_ld);
		usb_ld->dev_count++;
		pm_suspend_ignore_children(&data_intf->dev, true);

		for (j = 0; j < URB_COUNT; j++) {
			urb = usb_alloc_urb(0, GFP_KERNEL);
			if (!urb) {
				mif_err("alloc urb fail\n");
				err = -ENOMEM;
				goto out2;
			}

			urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
			urb->transfer_buffer = usb_alloc_coherent(usbdev,
				pipe->rx_buf_size, GFP_KERNEL,
				&urb->transfer_dma);
			if (!urb->transfer_buffer) {
				mif_err(
				"Failed to allocate transfer buffer\n");
				usb_free_urb(urb);
				err = -ENOMEM;
				goto out2;
			}

			usb_fill_bulk_urb(urb, usbdev, pipe->rx_pipe,
				urb->transfer_buffer, pipe->rx_buf_size,
				usb_rx_complete, pipe);
			usb_anchor_urb(urb, &pipe->urbs);
		}
	}

	/* temporary call reset_resume */
	atomic_set(&usb_ld->suspend_count, 1);
	if_usb_reset_resume(data_intf);
	atomic_set(&usb_ld->suspend_count, 0);

	SET_HOST_ACTIVE(usb_ld->pdata, 1);
	usb_ld->host_wake_timeout_flag = 0;

	if (gpio_get_value(usb_ld->pdata->gpio_phone_active)) {
		struct link_pm_data *pm_data = usb_ld->link_pm_data;
		int delay = pm_data->autosuspend_delay_ms ?:
				DEFAULT_AUTOSUSPEND_DELAY_MS;
		pm_runtime_set_autosuspend_delay(&usbdev->dev, delay);
		dev = &usbdev->dev;
		if (dev->parent) {
			dev_dbg(&usbdev->dev, "if_usb Runtime PM Start!!\n");
			usb_enable_autosuspend(usb_ld->usbdev);
			/* s5p-ehci runtime pm allow - usb phy suspend mode */
			root_hub = &usbdev->bus->root_hub->dev;
			ehci_dev = root_hub->parent;
			mif_debug("ehci device = %s, %s\n",
					dev_driver_string(ehci_dev),
					dev_name(ehci_dev));
			pm_runtime_allow(ehci_dev);

			if (!pm_data->autosuspend)
				pm_runtime_forbid(dev);

			if (has_hub(usb_ld))
				link_pm_preactive(pm_data);

			pm_data->root_hub = root_hub;
		}

		usb_ld->flow_suspend = 0;
		/* Queue work if skbs were pending before a disconnect/probe */
		if (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen)
			queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work, 0);

		usb_ld->if_usb_connected = 1;
		/*USB3503*/
		mif_debug("hub active complete\n");

		usb_change_modem_state(usb_ld, STATE_ONLINE);
	} else {
Beispiel #25
0
static int
brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *usb = interface_to_usbdev(intf);
	struct brcmf_usbdev_info *devinfo;
	struct usb_interface_descriptor	*desc;
	struct usb_endpoint_descriptor *endpoint;
	int ret = 0;
	u32 num_of_eps;
	u8 endpoint_num, ep;

	brcmf_dbg(USB, "Enter 0x%04x:0x%04x\n", id->idVendor, id->idProduct);

	devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC);
	if (devinfo == NULL)
		return -ENOMEM;

	devinfo->usbdev = usb;
	devinfo->dev = &usb->dev;
	/* Take an init lock, to protect for disconnect while still loading.
	 * Necessary because of the asynchronous firmware load construction
	 */
	mutex_init(&devinfo->dev_init_lock);
	mutex_lock(&devinfo->dev_init_lock);

	usb_set_intfdata(intf, devinfo);

	/* Check that the device supports only one configuration */
	if (usb->descriptor.bNumConfigurations != 1) {
		brcmf_err("Number of configurations: %d not supported\n",
			  usb->descriptor.bNumConfigurations);
		ret = -ENODEV;
		goto fail;
	}

	if ((usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) &&
	    (usb->descriptor.bDeviceClass != USB_CLASS_MISC) &&
	    (usb->descriptor.bDeviceClass != USB_CLASS_WIRELESS_CONTROLLER)) {
		brcmf_err("Device class: 0x%x not supported\n",
			  usb->descriptor.bDeviceClass);
		ret = -ENODEV;
		goto fail;
	}

	desc = &intf->altsetting[0].desc;
	if ((desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
	    (desc->bInterfaceSubClass != 2) ||
	    (desc->bInterfaceProtocol != 0xff)) {
		brcmf_err("non WLAN interface %d: 0x%x:0x%x:0x%x\n",
			  desc->bInterfaceNumber, desc->bInterfaceClass,
			  desc->bInterfaceSubClass, desc->bInterfaceProtocol);
		ret = -ENODEV;
		goto fail;
	}

	num_of_eps = desc->bNumEndpoints;
	for (ep = 0; ep < num_of_eps; ep++) {
		endpoint = &intf->altsetting[0].endpoint[ep].desc;
		endpoint_num = usb_endpoint_num(endpoint);
		if (!usb_endpoint_xfer_bulk(endpoint))
			continue;
		if (usb_endpoint_dir_in(endpoint)) {
			if (!devinfo->rx_pipe)
				devinfo->rx_pipe =
					usb_rcvbulkpipe(usb, endpoint_num);
		} else {
			if (!devinfo->tx_pipe)
				devinfo->tx_pipe =
					usb_sndbulkpipe(usb, endpoint_num);
		}
	}
	if (devinfo->rx_pipe == 0) {
		brcmf_err("No RX (in) Bulk EP found\n");
		ret = -ENODEV;
		goto fail;
	}
	if (devinfo->tx_pipe == 0) {
		brcmf_err("No TX (out) Bulk EP found\n");
		ret = -ENODEV;
		goto fail;
	}

	devinfo->ifnum = desc->bInterfaceNumber;

	if (usb->speed == USB_SPEED_SUPER)
		brcmf_dbg(USB, "Broadcom super speed USB WLAN interface detected\n");
	else if (usb->speed == USB_SPEED_HIGH)
		brcmf_dbg(USB, "Broadcom high speed USB WLAN interface detected\n");
	else
		brcmf_dbg(USB, "Broadcom full speed USB WLAN interface detected\n");

	ret = brcmf_usb_probe_cb(devinfo);
	if (ret)
		goto fail;

	/* Success */
	return 0;

fail:
	mutex_unlock(&devinfo->dev_init_lock);
	kfree(devinfo);
	usb_set_intfdata(intf, NULL);
	return ret;
}
Beispiel #26
0
int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting)
{
	struct cdc_ncm_ctx *ctx;
	struct usb_driver *driver;
	u8 *buf;
	int len;
	int temp;
	u8 iface_no;

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

	hrtimer_init(&ctx->tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	ctx->tx_timer.function = &cdc_ncm_tx_timer_cb;
	ctx->bh.data = (unsigned long)ctx;
	ctx->bh.func = cdc_ncm_txpath_bh;
	atomic_set(&ctx->stop, 0);
	spin_lock_init(&ctx->mtx);
	ctx->netdev = dev->net;

	/* store ctx pointer in device data field */
	dev->data[0] = (unsigned long)ctx;

	/* get some pointers */
	driver = driver_of(intf);
	buf = intf->cur_altsetting->extra;
	len = intf->cur_altsetting->extralen;

	ctx->udev = dev->udev;
	ctx->intf = intf;

	/* parse through descriptors associated with control interface */
	while ((len > 0) && (buf[0] > 2) && (buf[0] <= len)) {

		if (buf[1] != USB_DT_CS_INTERFACE)
			goto advance;

		switch (buf[2]) {
		case USB_CDC_UNION_TYPE:
			if (buf[0] < sizeof(*(ctx->union_desc)))
				break;

			ctx->union_desc =
					(const struct usb_cdc_union_desc *)buf;

			ctx->control = usb_ifnum_to_if(dev->udev,
					ctx->union_desc->bMasterInterface0);
			ctx->data = usb_ifnum_to_if(dev->udev,
					ctx->union_desc->bSlaveInterface0);
			break;

		case USB_CDC_ETHERNET_TYPE:
			if (buf[0] < sizeof(*(ctx->ether_desc)))
				break;

			ctx->ether_desc =
					(const struct usb_cdc_ether_desc *)buf;
			dev->hard_mtu =
				le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);

			if (dev->hard_mtu < CDC_NCM_MIN_DATAGRAM_SIZE)
				dev->hard_mtu =	CDC_NCM_MIN_DATAGRAM_SIZE;
			else if (dev->hard_mtu > CDC_NCM_MAX_DATAGRAM_SIZE)
				dev->hard_mtu =	CDC_NCM_MAX_DATAGRAM_SIZE;
			break;

		case USB_CDC_NCM_TYPE:
			if (buf[0] < sizeof(*(ctx->func_desc)))
				break;

			ctx->func_desc = (const struct usb_cdc_ncm_desc *)buf;
			break;

		case USB_CDC_MBIM_TYPE:
			if (buf[0] < sizeof(*(ctx->mbim_desc)))
				break;

			ctx->mbim_desc = (const struct usb_cdc_mbim_desc *)buf;
			break;

		default:
			break;
		}
advance:
		/* advance to next descriptor */
		temp = buf[0];
		buf += temp;
		len -= temp;
	}

	/* some buggy devices have an IAD but no CDC Union */
	if (!ctx->union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) {
		ctx->control = intf;
		ctx->data = usb_ifnum_to_if(dev->udev, intf->cur_altsetting->desc.bInterfaceNumber + 1);
		dev_dbg(&intf->dev, "CDC Union missing - got slave from IAD\n");
	}

	/* check if we got everything */
	if ((ctx->control == NULL) || (ctx->data == NULL) ||
	    ((!ctx->mbim_desc) && ((ctx->ether_desc == NULL) || (ctx->control != intf))))
		goto error;

	/* claim data interface, if different from control */
	if (ctx->data != ctx->control) {
		temp = usb_driver_claim_interface(driver, ctx->data, dev);
		if (temp)
			goto error;
	}

	iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;

	/* Reset data interface. Some devices will not reset properly
	 * unless they are configured first.  Toggle the altsetting to
	 * force a reset
	 */
	usb_set_interface(dev->udev, iface_no, data_altsetting);
	temp = usb_set_interface(dev->udev, iface_no, 0);
	if (temp)
		goto error2;

	/* initialize data interface */
	if (cdc_ncm_setup(ctx))
		goto error2;

	/* Some firmwares need a pause here or they will silently fail
	 * to set up the interface properly.  This value was decided
	 * empirically on a Sierra Wireless MC7455 running 02.08.02.00
	 * firmware.
	 */
	usleep_range(10000, 20000);

	/* configure data interface */
	temp = usb_set_interface(dev->udev, iface_no, data_altsetting);
	if (temp)
		goto error2;

	cdc_ncm_find_endpoints(ctx, ctx->data);
	cdc_ncm_find_endpoints(ctx, ctx->control);

	if ((ctx->in_ep == NULL) || (ctx->out_ep == NULL) ||
	    (ctx->status_ep == NULL))
		goto error2;

	dev->net->ethtool_ops = &cdc_ncm_ethtool_ops;

	usb_set_intfdata(ctx->data, dev);
	usb_set_intfdata(ctx->control, dev);
	usb_set_intfdata(ctx->intf, dev);

	if (ctx->ether_desc) {
		temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress);
		if (temp)
			goto error2;
		dev_info(&dev->udev->dev, "MAC-Address: %pM\n", dev->net->dev_addr);
	}


	dev->in = usb_rcvbulkpipe(dev->udev,
		ctx->in_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
	dev->out = usb_sndbulkpipe(dev->udev,
		ctx->out_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
	dev->status = ctx->status_ep;
	dev->rx_urb_size = ctx->rx_max;

	ctx->tx_speed = ctx->rx_speed = 0;
	return 0;

error2:
	usb_set_intfdata(ctx->control, NULL);
	usb_set_intfdata(ctx->data, NULL);
	if (ctx->data != ctx->control)
		usb_driver_release_interface(driver, ctx->data);
error:
	cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]);
	dev->data[0] = 0;
	dev_info(&dev->udev->dev, "bind() failure\n");
	return -ENODEV;
}
static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
{
	struct cmdbuf_t *tcb;
	unsigned long flags;
	int count;
	int status = -ENOENT;
	struct usb_cardstate *ucs = cs->hw.usb;

	do {
		if (!cb->len) {
			tcb = cb;

			spin_lock_irqsave(&cs->cmdlock, flags);
			cs->cmdbytes -= cs->curlen;
			gig_dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left",
				cs->curlen, cs->cmdbytes);
			cs->cmdbuf = cb = cb->next;
			if (cb) {
				cb->prev = NULL;
				cs->curlen = cb->len;
			} else {
				cs->lastcmdbuf = NULL;
				cs->curlen = 0;
			}
			spin_unlock_irqrestore(&cs->cmdlock, flags);

			if (tcb->wake_tasklet)
				tasklet_schedule(tcb->wake_tasklet);
			kfree(tcb);
		}
		if (cb) {
			count = min(cb->len, ucs->bulk_out_size);
			gig_dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count);

			usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
					  usb_sndbulkpipe(ucs->udev,
					     ucs->bulk_out_endpointAddr & 0x0f),
					  cb->buf + cb->offset, count,
					  gigaset_write_bulk_callback, cs);

			cb->offset += count;
			cb->len -= count;
			ucs->busy = 1;

			spin_lock_irqsave(&cs->lock, flags);
			status = cs->connected ?
				usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) :
				-ENODEV;
			spin_unlock_irqrestore(&cs->lock, flags);

			if (status) {
				ucs->busy = 0;
				dev_err(cs->dev,
					"could not submit urb (error %d)\n",
					-status);
				cb->len = 0; /* skip urb => remove cb+wakeup
						in next loop cycle */
			}
		}
	} while (cb && status); /* next command on error */

	return status;
}
Beispiel #28
0
/*
 * Sends a barker buffer to the device
 *
 * This helper will allocate a kmalloced buffer and use it to transmit
 * (then free it). Reason for this is that other arches cannot use
 * stack/vmalloc/text areas for DMA transfers.
 *
 * Error recovery here is simpler: anything is considered a hard error
 * and will move the reset code to use a last-resort bus-based reset.
 */
static
int __i2400mu_send_barker(struct i2400mu *i2400mu,
			  const __le32 *barker,
			  size_t barker_size,
			  unsigned endpoint)
{
	struct usb_endpoint_descriptor *epd = NULL;
	int pipe, actual_len, ret;
	struct device *dev = &i2400mu->usb_iface->dev;
	void *buffer;
	int do_autopm = 1;

	ret = usb_autopm_get_interface(i2400mu->usb_iface);
	if (ret < 0) {
		dev_err(dev, "RESET: can't get autopm: %d\n", ret);
		do_autopm = 0;
	}
	ret = -ENOMEM;
	buffer = kmalloc(barker_size, GFP_KERNEL);
	if (buffer == NULL)
		goto error_kzalloc;
	epd = usb_get_epd(i2400mu->usb_iface, endpoint);
	pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress);
	memcpy(buffer, barker, barker_size);
retry:
	ret = usb_bulk_msg(i2400mu->usb_dev, pipe, buffer, barker_size,
			   &actual_len, 200);
	switch (ret) {
	case 0:
		if (actual_len != barker_size) {	/* Too short? drop it */
			dev_err(dev, "E: %s: short write (%d B vs %zu "
				"expected)\n",
				__func__, actual_len, barker_size);
			ret = -EIO;
		}
		break;
	case -EPIPE:
		/*
		 * Stall -- maybe the device is choking with our
		 * requests. Clear it and give it some time. If they
		 * happen to often, it might be another symptom, so we
		 * reset.
		 *
		 * No error handling for usb_clear_halt(0; if it
		 * works, the retry works; if it fails, this switch
		 * does the error handling for us.
		 */
		if (edc_inc(&i2400mu->urb_edc,
			    10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
			dev_err(dev, "E: %s: too many stalls in "
				"URB; resetting device\n", __func__);
			usb_queue_reset_device(i2400mu->usb_iface);
			/* fallthrough */
		} else {
			usb_clear_halt(i2400mu->usb_dev, pipe);
			msleep(10);	/* give the device some time */
			goto retry;
		}
	case -EINVAL:			/* while removing driver */
	case -ENODEV:			/* dev disconnect ... */
	case -ENOENT:			/* just ignore it */
	case -ESHUTDOWN:		/* and exit */
	case -ECONNRESET:
		ret = -ESHUTDOWN;
		break;
	default:			/* Some error? */
		if (edc_inc(&i2400mu->urb_edc,
			    EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
			dev_err(dev, "E: %s: maximum errors in URB "
				"exceeded; resetting device\n",
				__func__);
			usb_queue_reset_device(i2400mu->usb_iface);
		} else {
			dev_warn(dev, "W: %s: cannot send URB: %d\n",
				 __func__, ret);
			goto retry;
		}
	}
	kfree(buffer);
error_kzalloc:
	if (do_autopm)
		usb_autopm_put_interface(i2400mu->usb_iface);
	return ret;
}
Beispiel #29
0
static int btusb_send_frame(struct sk_buff *skb)
{
    struct hci_dev *hdev = (struct hci_dev *) skb->dev;
    struct btusb_data *data = hci_get_drvdata(hdev);
    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) {
        if (err != -EPERM && err != -ENODEV)
            BT_ERR("%s urb %p submission failed (%d)",
                   hdev->name, urb, -err);
        kfree(urb->setup_packet);
        usb_unanchor_urb(urb);
    } else {
        usb_mark_last_busy(data->udev);
    }

done:
    usb_free_urb(urb);
    return err;
}
/**
 *  @brief  This function downloads data/comand packet to device
 *
 *  @param handle	Pointer to moal_handle structure
 *  @param pmbuf	Pointer to mlan_buffer structure
 *  @param ep		Endpoint to send
 *
 *  @return 	   	MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE
 */
mlan_status
woal_write_data_async(moal_handle * handle, mlan_buffer * pmbuf, t_u8 ep)
{
    struct usb_card_rec *cardp = handle->card;
    urb_context *context = NULL;
    t_u8 *data = (t_u8 *) (pmbuf->pbuf + pmbuf->data_offset);
    struct urb *tx_urb = NULL;
    mlan_status ret = MLAN_STATUS_SUCCESS;

    ENTER();

    /* Check if device is removed */
    if (handle->surprise_removed) {
        PRINTM(ERROR, "Device removed\n");
        ret = MLAN_STATUS_FAILURE;
        goto tx_ret;
    }

    if ((ep == cardp->tx_data_ep) &&
        (atomic_read(&cardp->tx_data_urb_pending) >= MVUSB_TX_HIGH_WMARK)) {
        ret = MLAN_STATUS_RESOURCE;
        goto tx_ret;
    }

    PRINTM(DATA, "woal_write_data_async: ep=%d\n", ep);

    if (ep == cardp->tx_cmd_ep) {
        context = &cardp->tx_cmd;
    } else {
        if (cardp->tx_data_ix >= MVUSB_TX_HIGH_WMARK)
            cardp->tx_data_ix = 0;
        context = &cardp->tx_data_list[cardp->tx_data_ix++];
    }

    context->handle = handle;
    context->ep = ep;
    context->pmbuf = pmbuf;
    tx_urb = context->urb;

    /* 
     * Use USB API usb_fill_bulk_urb() to set the
     * configuration information of the Tx bulk URB
     * and initialize the Tx callback
     */
    usb_fill_bulk_urb(tx_urb, cardp->udev,
                      usb_sndbulkpipe(cardp->udev,
                                      ep), data, pmbuf->data_len,
                      woal_usb_tx_complete, (void *) context);

    tx_urb->transfer_flags |= URB_ZERO_PACKET;
    if (ep == cardp->tx_cmd_ep)
        atomic_inc(&cardp->tx_cmd_urb_pending);
    else
        atomic_inc(&cardp->tx_data_urb_pending);
    if ((ret = usb_submit_urb(tx_urb, GFP_ATOMIC))) {
        /* Submit URB failure */
        PRINTM(ERROR, "Submit Tx data URB failed: %d\n", ret);
        if (ep == cardp->tx_cmd_ep)
            atomic_dec(&cardp->tx_cmd_urb_pending);
        else {
            atomic_dec(&cardp->tx_data_urb_pending);
            if (cardp->tx_data_ix)
                cardp->tx_data_ix--;
            else
                cardp->tx_data_ix = MVUSB_TX_HIGH_WMARK;
        }
        ret = MLAN_STATUS_FAILURE;
    } else {
        ret = MLAN_STATUS_SUCCESS;
    }

  tx_ret:
    if (!ret)
        ret = MLAN_STATUS_PENDING;

    LEAVE();
    return ret;
}