Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
{
	int max_size;
	int this_xfer;
	int result;
	int partial;
	int maxtry;
	int stat;

	/* determine the maximum packet size for these transfers */
	max_size = usb_maxpacket(us->pusb_dev, pipe) * 16;

	/* while we have data left to transfer */
	while (length) {

		/* calculate how long this will be -- maximum or a remainder */
		this_xfer = length > max_size ? max_size : length;
		length -= this_xfer;

		/* setup the retry counter */
		maxtry = 10;

		/* set up the transfer loop */
		do {
			/* transfer the data */
			USB_STOR_PRINTF("Bulk xfer 0x%x(%d) try #%d\n",
				  (unsigned int)buf, this_xfer, 11 - maxtry);
			result = usb_bulk_msg(us->pusb_dev, pipe, buf,
					      this_xfer, &partial, USB_CNTL_TIMEOUT*5);
			USB_STOR_PRINTF("bulk_msg returned %d xferred %d/%d\n",
				  result, partial, this_xfer);
			if(us->pusb_dev->status!=0) {
				/* if we stall, we need to clear it before we go on */
#ifdef USB_STOR_DEBUG
				display_int_status(us->pusb_dev->status);
#endif
				if (us->pusb_dev->status & USB_ST_STALLED) {
					USB_STOR_PRINTF("stalled ->clearing endpoint halt for pipe 0x%x\n", pipe);
					stat = us->pusb_dev->status;
					usb_clear_halt(us->pusb_dev, pipe);
					us->pusb_dev->status=stat;
					if(this_xfer == partial) {
						USB_STOR_PRINTF("bulk transferred with error %X, but data ok\n",us->pusb_dev->status);
						return 0;
					}
					else
						return result;
				}
				if (us->pusb_dev->status & USB_ST_NAK_REC) {
					USB_STOR_PRINTF("Device NAKed bulk_msg\n");
					return result;
				}
				if(this_xfer == partial) {
					USB_STOR_PRINTF("bulk transferred with error %d, but data ok\n",us->pusb_dev->status);
					return 0;
				}
				/* if our try counter reaches 0, bail out */
				USB_STOR_PRINTF("bulk transferred with error %d, data %d\n",us->pusb_dev->status,partial);
				if (!maxtry--)
						return result;
			}
			/* update to show what data was transferred */
			this_xfer -= partial;
			buf += partial;
			/* continue until this transfer is done */
		} while ( this_xfer );
	}

	/* if we get here, we're done and successful */
	return 0;
}
Ejemplo n.º 4
0
/*
 * Get the next TX message in the TX FIFO and send it to the device
 *
 * Note that any iteration consumes a message to be sent, no matter if
 * it succeeds or fails (we have no real way to retry or complain).
 *
 * Return: 0 if ok, < 0 errno code on hard error.
 */
static
int i2400mu_tx(struct i2400mu *i2400mu, struct i2400m_msg_hdr *tx_msg,
	       size_t tx_msg_size)
{
	int result = 0;
	struct i2400m *i2400m = &i2400mu->i2400m;
	struct device *dev = &i2400mu->usb_iface->dev;
	int usb_pipe, sent_size, do_autopm;
	struct usb_endpoint_descriptor *epd;

	d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu);
	do_autopm = atomic_read(&i2400mu->do_autopm);
	result = do_autopm ?
		usb_autopm_get_interface(i2400mu->usb_iface) : 0;
	if (result < 0) {
		dev_err(dev, "TX: can't get autopm: %d\n", result);
		do_autopm = 0;
	}
	epd = usb_get_epd(i2400mu->usb_iface, i2400mu->endpoint_cfg.bulk_out);
	usb_pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress);
retry:
	result = usb_bulk_msg(i2400mu->usb_dev, usb_pipe,
			      tx_msg, tx_msg_size, &sent_size, 200);
	usb_mark_last_busy(i2400mu->usb_dev);
	switch (result) {
	case 0:
		if (sent_size != tx_msg_size) {	/* Too short? drop it */
			dev_err(dev, "TX: short write (%d B vs %zu "
				"expected)\n", sent_size, tx_msg_size);
			result = -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, "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, usb_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;
	default:			/* Some error? */
		if (edc_inc(&i2400mu->urb_edc,
			    EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
			dev_err(dev, "TX: maximum errors in URB "
				"exceeded; resetting device\n");
			usb_queue_reset_device(i2400mu->usb_iface);
		} else {
			dev_err(dev, "TX: cannot send URB; retrying. "
				"tx_msg @%zu %zu B [%d sent]: %d\n",
				(void *) tx_msg - i2400m->tx_buf,
				tx_msg_size, sent_size, result);
			goto retry;
		}
	}
	if (do_autopm)
		usb_autopm_put_interface(i2400mu->usb_iface);
	d_fnend(4, dev, "(i2400mu %p) = result\n", i2400mu);
	return result;
}
Ejemplo n.º 5
0
/*
 * Receive a message with payloads from the USB bus into an skb
 *
 * @i2400mu: USB device descriptor
 * @rx_skb: skb where to place the received message
 *
 * Deals with all the USB-specifics of receiving, dynamically
 * increasing the buffer size if so needed. Returns the payload in the
 * skb, ready to process. On a zero-length packet, we retry.
 *
 * On soft USB errors, we retry (until they become too frequent and
 * then are promoted to hard); on hard USB errors, we reset the
 * device. On other errors (skb realloacation, we just drop it and
 * hope for the next invocation to solve it).
 *
 * Returns: pointer to the skb if ok, ERR_PTR on error.
 *   NOTE: this function might realloc the skb (if it is too small),
 *   so always update with the one returned.
 *   ERR_PTR() is < 0 on error.
 *   Will return NULL if it cannot reallocate -- this can be
 *   considered a transient retryable error.
 */
static
struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb)
{
	int result = 0;
	struct device *dev = &i2400mu->usb_iface->dev;
	int usb_pipe, read_size, rx_size, do_autopm;
	struct usb_endpoint_descriptor *epd;
	const size_t max_pkt_size = 512;

	d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu);
	do_autopm = atomic_read(&i2400mu->do_autopm);
	result = do_autopm ?
		usb_autopm_get_interface(i2400mu->usb_iface) : 0;
	if (result < 0) {
		dev_err(dev, "RX: can't get autopm: %d\n", result);
		do_autopm = 0;
	}
	epd = usb_get_epd(i2400mu->usb_iface, i2400mu->endpoint_cfg.bulk_in);
	usb_pipe = usb_rcvbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress);
retry:
	rx_size = skb_end_pointer(rx_skb) - rx_skb->data - rx_skb->len;
	if (unlikely(rx_size % max_pkt_size == 0)) {
		rx_size -= 8;
		d_printf(1, dev, "RX: rx_size adapted to %d [-8]\n", rx_size);
	}
	result = usb_bulk_msg(
		i2400mu->usb_dev, usb_pipe, rx_skb->data + rx_skb->len,
		rx_size, &read_size, 200);
	usb_mark_last_busy(i2400mu->usb_dev);
	switch (result) {
	case 0:
		if (read_size == 0)
			goto retry;	/* ZLP, just resubmit */
		skb_put(rx_skb, read_size);
		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");
			goto do_reset;
		}
		usb_clear_halt(i2400mu->usb_dev, usb_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:
	case -ECONNRESET:
		break;
	case -EOVERFLOW: {		/* too small, reallocate */
		struct sk_buff *new_skb;
		rx_size = i2400mu_rx_size_grow(i2400mu);
		if (rx_size <= (1 << 16))	/* cap it */
			i2400mu->rx_size = rx_size;
		else if (printk_ratelimit()) {
			dev_err(dev, "BUG? rx_size up to %d\n", rx_size);
			result = -EINVAL;
			goto out;
		}
		skb_put(rx_skb, read_size);
		new_skb = skb_copy_expand(rx_skb, 0, rx_size - rx_skb->len,
					  GFP_KERNEL);
		if (new_skb == NULL) {
			if (printk_ratelimit())
				dev_err(dev, "RX: Can't reallocate skb to %d; "
					"RX dropped\n", rx_size);
			kfree_skb(rx_skb);
			rx_skb = NULL;
			goto out;	/* drop it...*/
		}
		kfree_skb(rx_skb);
		rx_skb = new_skb;
		i2400mu->rx_size_cnt = 0;
		i2400mu->rx_size_acc = i2400mu->rx_size;
		d_printf(1, dev, "RX: size changed to %d, received %d, "
			 "copied %d, capacity %ld\n",
			 rx_size, read_size, rx_skb->len,
			 (long) (skb_end_pointer(new_skb) - new_skb->head));
		goto retry;
	}
		/* In most cases, it happens due to the hardware scheduling a
		 * read when there was no data - unfortunately, we have no way
		 * to tell this timeout from a USB timeout. So we just ignore
		 * it. */
	case -ETIMEDOUT:
		dev_err(dev, "RX: timeout: %d\n", result);
		result = 0;
		break;
	default:			/* Any error */
		if (edc_inc(&i2400mu->urb_edc,
			    EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME))
			goto error_reset;
		dev_err(dev, "RX: error receiving URB: %d, retrying\n", result);
		goto retry;
	}
out:
	if (do_autopm)
		usb_autopm_put_interface(i2400mu->usb_iface);
	d_fnend(4, dev, "(i2400mu %p) = %p\n", i2400mu, rx_skb);
	return rx_skb;

error_reset:
	dev_err(dev, "RX: maximum errors in URB exceeded; "
		"resetting device\n");
do_reset:
	usb_queue_reset_device(i2400mu->usb_iface);
	rx_skb = ERR_PTR(result);
	goto out;
}
Ejemplo n.º 6
0
static int usbtmc_ioctl_clear(struct usbtmc_device_data *data)
{
	struct usb_host_interface *current_setting;
	struct usb_endpoint_descriptor *desc;
	struct device *dev;
	u8 *buffer;
	int rv;
	int n;
	int actual = 0;
	int max_size;

	dev = &data->intf->dev;

	dev_dbg(dev, "Sending INITIATE_CLEAR request\n");

	buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	rv = usb_control_msg(data->usb_dev,
			     usb_rcvctrlpipe(data->usb_dev, 0),
			     USBTMC_REQUEST_INITIATE_CLEAR,
			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			     0, 0, buffer, 1, USBTMC_TIMEOUT);
	if (rv < 0) {
		dev_err(dev, "usb_control_msg returned %d\n", rv);
		goto exit;
	}

	dev_dbg(dev, "INITIATE_CLEAR returned %x\n", buffer[0]);

	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
		dev_err(dev, "INITIATE_CLEAR returned %x\n", buffer[0]);
		rv = -EPERM;
		goto exit;
	}

	max_size = 0;
	current_setting = data->intf->cur_altsetting;
	for (n = 0; n < current_setting->desc.bNumEndpoints; n++) {
		desc = &current_setting->endpoint[n].desc;
		if (desc->bEndpointAddress == data->bulk_in)
			max_size = usb_endpoint_maxp(desc);
	}

	if (max_size == 0) {
		dev_err(dev, "Couldn't get wMaxPacketSize\n");
		rv = -EPERM;
		goto exit;
	}

	dev_dbg(dev, "wMaxPacketSize is %d\n", max_size);

	n = 0;

usbtmc_clear_check_status:

	dev_dbg(dev, "Sending CHECK_CLEAR_STATUS request\n");

	rv = usb_control_msg(data->usb_dev,
			     usb_rcvctrlpipe(data->usb_dev, 0),
			     USBTMC_REQUEST_CHECK_CLEAR_STATUS,
			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			     0, 0, buffer, 2, USBTMC_TIMEOUT);
	if (rv < 0) {
		dev_err(dev, "usb_control_msg returned %d\n", rv);
		goto exit;
	}

	dev_dbg(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]);

	if (buffer[0] == USBTMC_STATUS_SUCCESS)
		goto usbtmc_clear_bulk_out_halt;

	if (buffer[0] != USBTMC_STATUS_PENDING) {
		dev_err(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]);
		rv = -EPERM;
		goto exit;
	}

	if (buffer[1] == 1)
		do {
			dev_dbg(dev, "Reading from bulk in EP\n");

			rv = usb_bulk_msg(data->usb_dev,
					  usb_rcvbulkpipe(data->usb_dev,
							  data->bulk_in),
					  buffer, USBTMC_SIZE_IOBUFFER,
					  &actual, USBTMC_TIMEOUT);
			n++;

			if (rv < 0) {
				dev_err(dev, "usb_control_msg returned %d\n",
					rv);
				goto exit;
			}
		} while ((actual == max_size) &&
			  (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));

	if (actual == max_size) {
		dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
			USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
		rv = -EPERM;
		goto exit;
	}

	goto usbtmc_clear_check_status;

usbtmc_clear_bulk_out_halt:

	rv = usb_clear_halt(data->usb_dev,
			    usb_sndbulkpipe(data->usb_dev, data->bulk_out));
	if (rv < 0) {
		dev_err(dev, "usb_control_msg returned %d\n", rv);
		goto exit;
	}
	rv = 0;

exit:
	kfree(buffer);
	return rv;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n)
{
	struct redrat3_dev *rr3 = rcdev->priv;
	struct device *dev = rr3->dev;
	struct redrat3_signal_header header;
	int i, j, count, ret, ret_len, offset;
	int lencheck, cur_sample_len, pipe;
	char *buffer = NULL, *sigdata = NULL;
	int *sample_lens = NULL;
	u32 tmpi;
	u16 tmps;
	u8 *datap;
	u8 curlencheck = 0;
	u16 *lengths_ptr;
	int sendbuf_len;

	rr3_ftr(dev, "Entering %s\n", __func__);

	if (rr3->transmitting) {
		dev_warn(dev, "%s: transmitter already in use\n", __func__);
		return -EAGAIN;
	}

	count = n / sizeof(int);
	if (count > (RR3_DRIVER_MAXLENS * 2))
		return -EINVAL;

	rr3->transmitting = true;

	redrat3_disable_detector(rr3);

	if (rr3->det_enabled) {
		dev_err(dev, "%s: cannot tx while rx is enabled\n", __func__);
		ret = -EIO;
		goto out;
	}

	sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL);
	if (!sample_lens) {
		ret = -ENOMEM;
		goto out;
	}

	for (i = 0; i < count; i++) {
		for (lencheck = 0; lencheck < curlencheck; lencheck++) {
			cur_sample_len = redrat3_us_to_len(txbuf[i]);
			if (sample_lens[lencheck] == cur_sample_len)
				break;
		}
		if (lencheck == curlencheck) {
			cur_sample_len = redrat3_us_to_len(txbuf[i]);
			rr3_dbg(dev, "txbuf[%d]=%u, pos %d, enc %u\n",
				i, txbuf[i], curlencheck, cur_sample_len);
			if (curlencheck < 255) {
				/* now convert the value to a proper
				 * rr3 value.. */
				sample_lens[curlencheck] = cur_sample_len;
				curlencheck++;
			} else {
				dev_err(dev, "signal too long\n");
				ret = -EINVAL;
				goto out;
			}
		}
	}

	sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL);
	if (!sigdata) {
		ret = -ENOMEM;
		goto out;
	}

	sigdata[count] = RR3_END_OF_SIGNAL;
	sigdata[count + 1] = RR3_END_OF_SIGNAL;
	for (i = 0; i < count; i++) {
		for (j = 0; j < curlencheck; j++) {
			if (sample_lens[j] == redrat3_us_to_len(txbuf[i]))
				sigdata[i] = j;
		}
	}

	offset = RR3_TX_HEADER_OFFSET;
	sendbuf_len = RR3_HEADER_LENGTH + (sizeof(u16) * RR3_DRIVER_MAXLENS)
			+ count + RR3_TX_TRAILER_LEN + offset;

	buffer = kzalloc(sendbuf_len, GFP_KERNEL);
	if (!buffer) {
		ret = -ENOMEM;
		goto out;
	}

	/* fill in our packet header */
	header.length = sendbuf_len - offset;
	header.transfer_type = RR3_MOD_SIGNAL_OUT;
	header.pause = redrat3_len_to_us(100);
	header.mod_freq_count = mod_freq_to_val(rr3->carrier);
	header.no_periods = 0; /* n/a to transmit */
	header.max_lengths = RR3_DRIVER_MAXLENS;
	header.no_lengths = curlencheck;
	header.max_sig_size = RR3_MAX_SIG_SIZE;
	header.sig_size = count + RR3_TX_TRAILER_LEN;
	/* we currently rely on repeat handling in the IR encoding source */
	header.no_repeats = 0;

	tmps = cpu_to_be16(header.length);
	memcpy(buffer, &tmps, 2);

	tmps = cpu_to_be16(header.transfer_type);
	memcpy(buffer + 2, &tmps, 2);

	tmpi = cpu_to_be32(header.pause);
	memcpy(buffer + offset, &tmpi, sizeof(tmpi));

	tmps = cpu_to_be16(header.mod_freq_count);
	memcpy(buffer + offset + RR3_FREQ_COUNT_OFFSET, &tmps, 2);

	buffer[offset + RR3_NUM_LENGTHS_OFFSET] = header.no_lengths;

	tmps = cpu_to_be16(header.sig_size);
	memcpy(buffer + offset + RR3_NUM_SIGS_OFFSET, &tmps, 2);

	buffer[offset + RR3_REPEATS_OFFSET] = header.no_repeats;

	lengths_ptr = (u16 *)(buffer + offset + RR3_HEADER_LENGTH);
	for (i = 0; i < curlencheck; ++i)
		lengths_ptr[i] = cpu_to_be16(sample_lens[i]);

	datap = (u8 *)(buffer + offset + RR3_HEADER_LENGTH +
			    (sizeof(u16) * RR3_DRIVER_MAXLENS));
	memcpy(datap, sigdata, (count + RR3_TX_TRAILER_LEN));

	if (debug) {
		redrat3_dump_signal_header(&header);
		redrat3_dump_signal_data(buffer, header.sig_size);
	}

	pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress);
	tmps = usb_bulk_msg(rr3->udev, pipe, buffer,
			    sendbuf_len, &ret_len, 10 * HZ);
	rr3_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, tmps);

	/* now tell the hardware to transmit what we sent it */
	pipe = usb_rcvctrlpipe(rr3->udev, 0);
	ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL,
			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
			      0, 0, buffer, 2, HZ * 10);

	if (ret < 0)
		dev_err(dev, "Error: control msg send failed, rc %d\n", ret);
	else
		ret = n;

out:
	kfree(sample_lens);
	kfree(buffer);
	kfree(sigdata);

	rr3->transmitting = false;

	redrat3_enable_detector(rr3);

	return ret;
}
Ejemplo n.º 9
0
/*****************************************************************************
 * Connect Tech's White Heat serial driver functions
 *****************************************************************************/
static int whiteheat_attach(struct usb_serial *serial)
{
	struct usb_serial_port *command_port;
	struct whiteheat_command_private *command_info;
	struct usb_serial_port *port;
	struct whiteheat_private *info;
	struct whiteheat_hw_info *hw_info;
	int pipe;
	int ret;
	int alen;
	__u8 *command;
	__u8 *result;
	int i;

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

	for (i = 0; i < serial->num_ports; i++) {
		port = serial->port[i];

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

		info->mcr = 0;

		usb_set_serial_port_data(port, info);
	}

	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);
	return -ENODEV;

no_command_private:
	for (i = serial->num_ports - 1; i >= 0; i--) {
		port = serial->port[i];
		info = usb_get_serial_port_data(port);
		kfree(info);
no_private:
		;
	}
	kfree(result);
no_result_buffer:
	kfree(command);
no_command_buffer:
	return -ENOMEM;
}
Ejemplo n.º 10
0
static ssize_t bladerf_write(struct file *file, const char *user_buf, size_t count, loff_t *ppos)
{
    bladerf_device_t *dev;
    unsigned long flags;
    char *buf = NULL;
    struct data_buffer *db = NULL;
    unsigned int idx;
    int reread;
    int status = 0;

    /* TODO truncate count to be within range of ssize_t here? */

    dev = (bladerf_device_t *)file->private_data;

    if (dev->intnum == 0) {
        int llen;
        buf = (char *)kmalloc(count, GFP_KERNEL);
        if (buf) {
            if (copy_from_user(buf, user_buf, count)) {
                status = -EFAULT;
            } else {
                status = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, count, &llen, BLADE_USB_TIMEOUT_MS);
            }
            kfree(buf);
        } else {
            dev_err(&dev->interface->dev, "Failed to allocate write buffer\n");
            status = -ENOMEM;
        }

        if (status < 0)
            return status;
        else
            return llen;
    }

    if (dev->writer) {
        if (file != dev->writer) {
            return -EPERM;
        }
    } else
        dev->writer = file;

    reread = atomic_read(&dev->data_out_used);
    if (reread >= NUM_DATA_URB) {
        status = wait_event_interruptible_timeout(dev->data_out_wait, atomic_read(&dev->data_out_used) < NUM_DATA_URB, 2 * HZ);

        if (status < 0) {
            return status;
        } else if (status == 0) {
            return -ETIMEDOUT;
        }
    }

    spin_lock_irqsave(&dev->data_out_lock, flags);

    idx = dev->data_out_producer_idx++;
    dev->data_out_producer_idx &= (NUM_DATA_URB - 1);
    db = &dev->data_out_bufs[idx];
    atomic_inc(&dev->data_out_cnt);
    atomic_inc(&dev->data_out_used);

    spin_unlock_irqrestore(&dev->data_out_lock, flags);

    if (copy_from_user(db->addr, user_buf, count)) {
        return -EFAULT;
    }

    db->valid = 1; // mark this TX packet as having valid data

    __submit_tx_urb(dev);
    if (!dev->tx_en)
        enable_tx(dev);

    return count;
}
Ejemplo n.º 11
0
long bladerf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    bladerf_device_t *dev;
    void __user *data;
    struct bladeRF_version ver;
    int ret;
    int retval = -EINVAL;
    int sz, nread, nwrite;
    struct uart_cmd spi_reg;
    int sectors_to_wipe, sector_idx;
    int pages_to_write, page_idx;
    int pages_to_read;
    int check_idx;
    int count, tries;
    int targetdev;

    /* FIXME this large buffer should be kmalloc'd and kept with the dev, no? */
    unsigned char buf[1024];
    struct bladeRF_firmware brf_fw;
    struct bladeRF_sector brf_sector;
    unsigned char *fw_buf;

    dev = file->private_data;
    data = (void __user *)arg;


    switch (cmd) {
        case BLADE_QUERY_VERSION:
            retval = __bladerf_rcv_cmd(dev, BLADE_USB_CMD_QUERY_VERSION, &ver, sizeof(ver));
            if (retval >= 0) {
                ver.major = le16_to_cpu(ver.major);
                ver.minor = le16_to_cpu(ver.minor);
                if (copy_to_user(data, &ver, sizeof(struct bladeRF_version))) {
                    retval = -EFAULT;
                } else {
                    retval = 0;
                }
            }
            break;

        case BLADE_QUERY_FPGA_STATUS:
            retval = __bladerf_rcv_one_word(dev, BLADE_USB_CMD_QUERY_FPGA_STATUS, data);
            break;

        case BLADE_BEGIN_PROG:
            if (dev->intnum != 0) {
                ret = usb_set_interface(dev->udev, 0,0);
                dev->intnum = 0;
            }

            retval = __bladerf_rcv_one_word(dev, BLADE_USB_CMD_BEGIN_PROG, data);
            break;

        case BLADE_END_PROG:
            // TODO: send another 2 DCLK cycles to ensure compliance with C4's boot procedure
            retval = __bladerf_rcv_one_word(dev, BLADE_USB_CMD_QUERY_FPGA_STATUS, data);

            if (!retval) {
                ret = usb_set_interface(dev->udev, 0,1);
                dev->intnum = 1;
            }
            break;

        case BLADE_CAL:
            if (dev->intnum != 2) {
                retval = usb_set_interface(dev->udev, 0,2);

                if (retval)
                    break;

                dev->intnum = 2;
            }
            if (copy_from_user(&brf_fw, data, sizeof(struct bladeRF_firmware))) {
                return -EFAULT;
            }

            fw_buf = kzalloc(256, GFP_KERNEL);
            if (!fw_buf)
                return -EINVAL;

            memset(fw_buf, 0xff, 256);

            if (copy_from_user(fw_buf, brf_fw.ptr, brf_fw.len)) {
                retval = -EFAULT;
                break;
            }

            retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
                    BLADE_USB_CMD_FLASH_ERASE, BLADE_USB_TYPE_IN, 0x0000, 3,
                    &ret, 4, BLADE_USB_TIMEOUT_MS * 100);

            if (!retval) {
                dev_err(&dev->interface->dev, "Could not erase NAND cal sector 3.\n");
                break;
            }

            retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
                    BLADE_USB_CMD_FLASH_WRITE, BLADE_USB_TYPE_OUT, 0x0000, 768,
                    fw_buf, 256, BLADE_USB_TIMEOUT_MS);

            if (!retval) {
                dev_err(&dev->interface->dev, "Could not write NAND cal sector 768.\n");
                break;
            }

            memset(buf, 0, 256);

            retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
                    BLADE_USB_CMD_FLASH_READ, BLADE_USB_TYPE_IN, 0x0000, 768,
                    buf, 256, BLADE_USB_TIMEOUT_MS);

            if (!retval) {
                dev_err(&dev->interface->dev, "Could not read NAND cal sector 768.\n");
                break;
            }

            retval = memcmp(fw_buf, buf, 256);
            break;

        case BLADE_FLASH_ERASE:
                retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
                        BLADE_USB_CMD_FLASH_ERASE, BLADE_USB_TYPE_IN, 0x0000, arg,
                        &ret, 4, BLADE_USB_TIMEOUT_MS * 100);

                if (!retval) {
                    dev_err(&dev->interface->dev, "Could not read NAND cal sector 768.\n");
                    break;
                }

                retval = !ret;
        break;

        case BLADE_OTP:
            if (dev->intnum != 2) {
                retval = usb_set_interface(dev->udev, 0,2);

                if (retval)
                    break;

                dev->intnum = 2;
            }

            if (copy_from_user(&brf_fw, data, sizeof(struct bladeRF_firmware))) {
                return -EFAULT;
            }

            fw_buf = kzalloc(256, GFP_KERNEL);
            if (!fw_buf)
                return -EINVAL;
            memset(fw_buf, 0xff, 256);

            if (copy_from_user(fw_buf, brf_fw.ptr, brf_fw.len)) {
                retval = -EFAULT;
                kfree(fw_buf);
                break;
            }

            memcpy(buf, fw_buf, brf_fw.len);

            retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
                    BLADE_USB_CMD_WRITE_OTP, BLADE_USB_TYPE_OUT, 0x0000, 0,
                    fw_buf, 256, BLADE_USB_TIMEOUT_MS);

            if (!retval) {
                dev_err(&dev->interface->dev, "Could not write OTP.\n");
                break;
            }

            memset(buf, 0, 256);

            retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
                    BLADE_USB_CMD_READ_OTP, BLADE_USB_TYPE_IN, 0x0000, 0,
                    buf, 256, BLADE_USB_TIMEOUT_MS);

            if (!retval) {
                dev_err(&dev->interface->dev, "Could not read OTP.\n");
                break;
            }

            retval = memcmp(fw_buf, buf, 256);
            break;

        case BLADE_OTP_READ:
        case BLADE_FLASH_READ:
        case BLADE_FLASH_WRITE:
            if (dev->intnum != 2) {
                retval = usb_set_interface(dev->udev, 0,2);

                if (retval)
                    break;

                dev->intnum = 2;
            }

            if (copy_from_user(&brf_sector, data, sizeof(struct bladeRF_sector))) {
                return -EFAULT;
            }

            if (cmd == BLADE_OTP_READ) {
                if (brf_sector.idx != 0 || brf_sector.len != 0x100)
                    dev_err(&dev->interface->dev, "Invalid OTP settings, expecting idx=0, len=256\n");
            }


            sz = 0;
            if (dev->udev->speed == USB_SPEED_HIGH) {
                sz = 64;
            } else if (dev->udev->speed == USB_SPEED_SUPER) {
                sz = 256;
            }

            count = brf_sector.len + (sz - (brf_sector.len % sz));
            fw_buf = kzalloc(count, GFP_KERNEL);

            if (!fw_buf)
                return -EFAULT;

            memset(fw_buf, 0xff, count);

            if (cmd == BLADE_FLASH_READ || cmd == BLADE_OTP_READ) {
                pages_to_read = (brf_sector.len + 255) / 0x100;
                nread = 0;
                for (page_idx = 0; page_idx < pages_to_read; page_idx++) {
                    do {
                        retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
                                (cmd == BLADE_FLASH_READ) ? BLADE_USB_CMD_FLASH_READ : BLADE_USB_CMD_READ_OTP,
                                BLADE_USB_TYPE_IN, 0x0000, brf_sector.idx + page_idx,
                                &fw_buf[nread], sz, BLADE_USB_TIMEOUT_MS);
                        printk("%d read %d bytes %x %x %x %x\n", retval, sz, fw_buf[nread], fw_buf[nread+1], fw_buf[nread+2], fw_buf[nread+3]);
                        nread += sz;
                        if (retval != sz) break;
                    } while (nread != 256);
                    if (retval != sz) break;
                }

                if (!retval) {
                    dev_err(&dev->interface->dev, "Could not read NAND cal page idx %d.\n", page_idx);
                    break;
                }
                if (copy_to_user((void __user *)brf_sector.ptr, fw_buf, brf_sector.len)) {
                    retval = -EFAULT;
                    break;
                }
            } else if (cmd == BLADE_FLASH_WRITE) {
                if (copy_from_user(fw_buf, brf_sector.ptr, brf_sector.len)) {
                    retval = -EFAULT;
                    break;
                }

                pages_to_write = (brf_sector.len + 255) / 0x100;
                nwrite = 0;
                for (page_idx = 0; page_idx < pages_to_write; page_idx++) {
                    do {
                        retval = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
                                BLADE_USB_CMD_FLASH_WRITE, BLADE_USB_TYPE_OUT, 0x0000, brf_sector.idx + page_idx,
                                &fw_buf[page_idx * 256 + nwrite], sz, BLADE_USB_TIMEOUT_MS);
                        nwrite += sz;
                        if (retval != sz) break;
                    } while (nwrite != 256);
                    if (retval != sz) break;
                }

                if (!retval) {
                    dev_err(&dev->interface->dev, "Could not write NAND cal page idx %d.\n", page_idx);
                    break;
                }
            }

            break;

        case BLADE_UPGRADE_FW:

            if (dev->intnum != 2) {
                retval = usb_set_interface(dev->udev, 0,2);

                if (retval)
                    break;

                dev->intnum = 2;
            }

            if (copy_from_user(&brf_fw, data, sizeof(struct bladeRF_firmware))) {
                return -EFAULT;
            }

            brf_fw.len = ((brf_fw.len + 255) / 256) * 256;

            fw_buf = kzalloc(brf_fw.len, GFP_KERNEL);
            if (!fw_buf)
                goto leave_fw;

            if (copy_from_user(fw_buf, brf_fw.ptr, brf_fw.len)) {
                retval = -EFAULT;
                goto leave_fw;
            }

            retval = -ENODEV;

            sectors_to_wipe = (brf_fw.len + 0xffff) / 0x10000;
            printk("Going to wipe %d sectors\n", sectors_to_wipe);
            for (sector_idx = 0; sector_idx < sectors_to_wipe; sector_idx++) {
                printk("Erasing sector %d... ", sector_idx);
                retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
                        BLADE_USB_CMD_FLASH_ERASE, BLADE_USB_TYPE_IN, 0x0000, sector_idx,
                        &ret, 4, BLADE_USB_TIMEOUT_MS * 100);
                printk("- erased\n");

                if (retval != 4) {
                    goto leave_fw;
                }
                ret = le32_to_cpu(ret);
                if (ret != 1) {
                    printk("Unable to erase previous sector, quitting\n");
                    goto leave_fw;
                }
            }

            sz = 0;
            if (dev->udev->speed == USB_SPEED_HIGH) {
                sz = 64;
            } else if (dev->udev->speed == USB_SPEED_SUPER) {
                sz = 256;
            }

            pages_to_write = (brf_fw.len + 255) / 0x100;
            for (page_idx = pages_to_write - 1; page_idx >= 0; page_idx--) {
                nwrite = 0;
                do {
                    retval = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
                            BLADE_USB_CMD_FLASH_WRITE, BLADE_USB_TYPE_OUT, 0x0000, page_idx,
                            &fw_buf[page_idx * 256 + nwrite], sz, BLADE_USB_TIMEOUT_MS);
                    nwrite += sz;
                } while (nwrite != 256);
            }

            pages_to_read = (brf_fw.len + 255) / 0x100;

            for (page_idx = 0; page_idx < pages_to_read; page_idx++) {
                nread = 0;
                do {
                    retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
                            BLADE_USB_CMD_FLASH_READ, BLADE_USB_TYPE_IN, 0x0000, page_idx,
                            &buf[nread], sz, BLADE_USB_TIMEOUT_MS);
                    nread += sz;
                } while (nread != 256);

                for (check_idx = 0; check_idx < 256; check_idx++) {
                    if (buf[check_idx] != fw_buf[page_idx * 256 + check_idx]) {
                        printk("ERROR: bladeRF firmware verification detected a mismatch at byte offset 0x%.8x\n", page_idx * 256 + check_idx);
                        printk("ERROR: expected byte 0x%.2X, got 0x%.2X\n", fw_buf[page_idx * 256 + check_idx], buf[check_idx]);
                        retval = -EINVAL;
                        goto leave_fw;
                    }
                }
            }
            retval = 0;
            printk("SUCCESSFULLY VERIFIED\n");

leave_fw:
            kfree(fw_buf);
            break;

        case BLADE_DEVICE_RESET:
            ret = 1;
            retval = __bladerf_snd_cmd(dev, BLADE_USB_CMD_RESET, &ret, sizeof(ret));
            break;


        case BLADE_CHECK_PROG:
            retval = 0;
            printk("ok %d\n", dev->intnum);
            if (dev->intnum == 0) {
                retval = __bladerf_rcv_cmd(dev, BLADE_USB_CMD_QUERY_FPGA_STATUS, &ret, sizeof(ret));
                printk("retval =%d     ret=%d\n", retval, ret);
                if (retval >= 0 && ret) {
                    retval = 0;
                    ret = usb_set_interface(dev->udev, 0,1);
                    dev->intnum = 1;

                    if (copy_to_user((void __user *)arg, &ret, sizeof(ret))){
                        retval = -EFAULT;
                    } else {
                        retval = 0;
                    }
                }
            }
            break;

        case BLADE_RF_RX:
            if (dev->intnum != 1) {
                dev_err(&dev->interface->dev, "Cannot enable RX from config mode\n");
                retval = -1;
                break;
            }

            printk("RF_RX!\n");
            retval = __bladerf_snd_one_word(dev, BLADE_USB_CMD_RF_RX, data);
            break;

        case BLADE_RF_TX:
            if (dev->intnum != 1) {
                dev_err(&dev->interface->dev, "Cannot enable TX from config mode\n");
                retval = -1;
                break;
            }

            printk("RF_TX!\n");
            retval = __bladerf_snd_one_word(dev, BLADE_USB_CMD_RF_TX, data);
            break;

        case BLADE_LMS_WRITE:
        case BLADE_LMS_READ:
        case BLADE_SI5338_WRITE:
        case BLADE_SI5338_READ:
        case BLADE_GPIO_WRITE:
        case BLADE_GPIO_READ:
        case BLADE_VCTCXO_WRITE:

            if (copy_from_user(&spi_reg, (void __user *)arg, sizeof(struct uart_cmd))) {
                retval = -EFAULT;
                break;
            }

            nread = count = 16;
            memset(buf, 0, 20);
            buf[0] = 'N';

            targetdev = UART_PKT_DEV_SI5338;
            if (cmd == BLADE_GPIO_WRITE || cmd == BLADE_GPIO_READ)
                targetdev = UART_PKT_DEV_GPIO;
            if (cmd == BLADE_LMS_WRITE || cmd == BLADE_LMS_READ)
                targetdev = UART_PKT_DEV_LMS;
            if (cmd == BLADE_VCTCXO_WRITE)
                targetdev = UART_PKT_DEV_VCTCXO;

            if (cmd == BLADE_LMS_WRITE || cmd == BLADE_GPIO_WRITE || cmd == BLADE_SI5338_WRITE || cmd == BLADE_VCTCXO_WRITE) {
                buf[1] = UART_PKT_MODE_DIR_WRITE | targetdev | 0x01;
                buf[2] = spi_reg.addr;
                buf[3] = spi_reg.data;
            } else if (cmd == BLADE_LMS_READ || cmd == BLADE_GPIO_READ || cmd == BLADE_SI5338_READ) {
                buf[1] = UART_PKT_MODE_DIR_READ | targetdev | 0x01;
                buf[2] = spi_reg.addr;
                buf[3] = 0xff;
            }

            retval = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, count, &nread, BLADE_USB_TIMEOUT_MS);
            if (!retval) {
                memset(buf, 0, 20);

                tries = 3;
                do {
                    retval = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, 0x82), buf, count, &nread, BLADE_USB_TIMEOUT_MS);
                } while(retval == -ETIMEDOUT && tries--);

                if (!retval) {
                    spi_reg.addr = buf[2];
                    spi_reg.data = buf[3];
                }

                if (copy_to_user((void __user *)arg, &spi_reg, sizeof(struct uart_cmd))) {
                    retval = -EFAULT;
                } else {
                    retval = 0;
                }
            }
            break;

        case BLADE_GET_SPEED:
            ret = dev->udev->speed == USB_SPEED_SUPER;
            if (copy_to_user((void __user *)arg, &ret, sizeof(ret))) {
                retval = -EFAULT;
            } else {
                retval = 0;
            }
            break;

        case BLADE_GET_ADDR:
            ret = dev->udev->devnum;
            if (copy_to_user((void __user *)arg, &ret, sizeof(ret))) {
                retval = -EFAULT;
            } else {
                retval = 0;
            }
            break;

        case BLADE_GET_BUS:
            ret = dev->udev->bus->busnum;
            if (copy_to_user((void __user *)arg, &ret, sizeof(ret))) {
                retval = -EFAULT;
            } else {
                retval = 0;
            }
            break;

    }

    return retval;
}
Ejemplo n.º 12
0
static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
{
	static char start_string[] = "~~~~<\r";
	struct p54u_priv *priv = dev->priv;
	const struct firmware *fw_entry = NULL;
	int err, alen;
	u8 carry = 0;
	u8 *buf, *tmp, *data;
	unsigned int left, remains, block_size;
	struct x2_header *hdr;
	unsigned long timeout;

	tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
	if (!buf) {
		printk(KERN_ERR "p54usb: cannot allocate firmware upload buffer!\n");
		err = -ENOMEM;
		goto err_bufalloc;
	}

	memcpy(buf, start_string, 4);
	err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
	if (err) {
		printk(KERN_ERR "p54usb: reset failed! (%d)\n", err);
		goto err_reset;
	}

	err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev);
	if (err) {
		printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb_bare)!\n");
		goto err_req_fw_failed;
	}

	p54_parse_firmware(dev, fw_entry);

	left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
	strcpy(buf, start_string);
	left -= strlen(start_string);
	tmp += strlen(start_string);

	data = fw_entry->data;
	remains = fw_entry->size;

	hdr = (struct x2_header *)(buf + strlen(start_string));
	memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
	hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
	hdr->fw_length = cpu_to_le32(fw_entry->size);
	hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
					 sizeof(u32)*2));
	left -= sizeof(*hdr);
	tmp += sizeof(*hdr);

	while (remains) {
		while (left--) {
			if (carry) {
				*tmp++ = carry;
				carry = 0;
				remains--;
				continue;
			}
			switch (*data) {
			case '~':
				*tmp++ = '}';
				carry = '^';
				break;
			case '}':
				*tmp++ = '}';
				carry = ']';
				break;
			default:
				*tmp++ = *data;
				remains--;
				break;
			}
			data++;
		}

		err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
		if (err) {
			printk(KERN_ERR "prism54usb: firmware upload failed!\n");
			goto err_upload_failed;
		}

		tmp = buf;
		left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
	}

	*((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
	err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
	if (err) {
		printk(KERN_ERR "prism54usb: firmware upload failed!\n");
		goto err_upload_failed;
	}

	timeout = jiffies + msecs_to_jiffies(1000);
	while (!(err = usb_bulk_msg(priv->udev,
		usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
		if (alen > 2 && !memcmp(buf, "OK", 2))
			break;

		if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
			printk(KERN_INFO "prism54usb: firmware upload failed!\n");
			err = -EINVAL;
			break;
		}

		if (time_after(jiffies, timeout)) {
			printk(KERN_ERR "prism54usb: firmware boot timed out!\n");
			err = -ETIMEDOUT;
			break;
		}
	}
	if (err)
		goto err_upload_failed;

	buf[0] = 'g';
	buf[1] = '\r';
	err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
	if (err) {
		printk(KERN_ERR "prism54usb: firmware boot failed!\n");
		goto err_upload_failed;
	}

	timeout = jiffies + msecs_to_jiffies(1000);
	while (!(err = usb_bulk_msg(priv->udev,
		usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
		if (alen > 0 && buf[0] == 'g')
			break;

		if (time_after(jiffies, timeout)) {
			err = -ETIMEDOUT;
			break;
		}
	}
	if (err)
		goto err_upload_failed;

  err_upload_failed:
	release_firmware(fw_entry);
  err_req_fw_failed:
  err_reset:
	kfree(buf);
  err_bufalloc:
	return err;
}
Ejemplo n.º 13
0
static int p54u_read_eeprom(struct ieee80211_hw *dev)
{
	struct p54u_priv *priv = dev->priv;
	void *buf;
	struct p54_control_hdr *hdr;
	int err, alen;
	size_t offset = priv->hw_type ? 0x10 : 0x20;

	buf = kmalloc(0x2020, GFP_KERNEL);
	if (!buf) {
		printk(KERN_ERR "prism54usb: cannot allocate memory for "
		       "eeprom readback!\n");
		return -ENOMEM;
	}

	if (priv->hw_type) {
		*((u32 *) buf) = priv->common.rx_start;
		err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
		if (err) {
			printk(KERN_ERR "prism54usb: addr send failed\n");
			goto fail;
		}
	} else {
		struct net2280_reg_write *reg = buf;
		reg->port = cpu_to_le16(NET2280_DEV_U32);
		reg->addr = cpu_to_le32(P54U_DEV_BASE);
		reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
		err = p54u_bulk_msg(priv, P54U_PIPE_DEV, buf, sizeof(*reg));
		if (err) {
			printk(KERN_ERR "prism54usb: dev_int send failed\n");
			goto fail;
		}
	}

	hdr = buf + priv->common.tx_hdr_len;
	p54_fill_eeprom_readback(hdr);
	hdr->req_id = cpu_to_le32(priv->common.rx_start);
	if (priv->common.tx_hdr_len) {
		struct net2280_tx_hdr *tx_hdr = buf;
		tx_hdr->device_addr = hdr->req_id;
		tx_hdr->len = cpu_to_le16(EEPROM_READBACK_LEN);
	}

	/* we can just pretend to send 0x2000 bytes of nothing in the headers */
	err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf,
			    EEPROM_READBACK_LEN + priv->common.tx_hdr_len);
	if (err) {
		printk(KERN_ERR "prism54usb: eeprom req send failed\n");
		goto fail;
	}

	err = usb_bulk_msg(priv->udev,
			   usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
			   buf, 0x2020, &alen, 1000);
	if (!err && alen > offset) {
		p54_parse_eeprom(dev, (u8 *)buf + offset, alen - offset);
	} else {
		printk(KERN_ERR "prism54usb: eeprom read failed!\n");
		err = -EINVAL;
		goto fail;
	}

 fail:
	kfree(buf);
	return err;
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
static ssize_t usbtmc_read(struct file *filp, char __user *buf,
			   size_t count, loff_t *f_pos)
{
	struct usbtmc_device_data *data;
	struct device *dev;
	u32 n_characters;
	u8 *buffer;
	int actual;
	size_t done;
	size_t remaining;
	int retval;
	size_t this_part;

	/* Get pointer to private data structure */
	data = filp->private_data;
	dev = &data->intf->dev;

	buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	mutex_lock(&data->io_mutex);
	if (data->zombie) {
		retval = -ENODEV;
		goto exit;
	}

	if (data->rigol_quirk) {
		dev_dbg(dev, "usb_bulk_msg_in: count(%zu)\n", count);

		retval = send_request_dev_dep_msg_in(data, count);

		if (retval < 0) {
			if (data->auto_abort)
				usbtmc_ioctl_abort_bulk_out(data);
			goto exit;
		}
	}

	/* Loop until we have fetched everything we requested */
	remaining = count;
	this_part = remaining;
	done = 0;

	while (remaining > 0) {
		if (!data->rigol_quirk) {
			dev_dbg(dev, "usb_bulk_msg_in: remaining(%zu), count(%zu)\n", remaining, count);

			if (remaining > USBTMC_SIZE_IOBUFFER - USBTMC_HEADER_SIZE - 3)
				this_part = USBTMC_SIZE_IOBUFFER - USBTMC_HEADER_SIZE - 3;
			else
				this_part = remaining;

			retval = send_request_dev_dep_msg_in(data, this_part);
			if (retval < 0) {
			dev_err(dev, "usb_bulk_msg returned %d\n", retval);
				if (data->auto_abort)
					usbtmc_ioctl_abort_bulk_out(data);
				goto exit;
			}
		}

		/* Send bulk URB */
		retval = usb_bulk_msg(data->usb_dev,
				      usb_rcvbulkpipe(data->usb_dev,
						      data->bulk_in),
				      buffer, USBTMC_SIZE_IOBUFFER, &actual,
				      USBTMC_TIMEOUT);

		dev_dbg(dev, "usb_bulk_msg: retval(%u), done(%zu), remaining(%zu), actual(%d)\n", retval, done, remaining, actual);

		/* Store bTag (in case we need to abort) */
		data->bTag_last_read = data->bTag;

		if (retval < 0) {
			dev_dbg(dev, "Unable to read data, error %d\n", retval);
			if (data->auto_abort)
				usbtmc_ioctl_abort_bulk_in(data);
			goto exit;
		}

		/* Parse header in first packet */
		if ((done == 0) || !data->rigol_quirk) {
			/* Sanity checks for the header */
			if (actual < USBTMC_HEADER_SIZE) {
				dev_err(dev, "Device sent too small first packet: %u < %u\n", actual, USBTMC_HEADER_SIZE);
				if (data->auto_abort)
					usbtmc_ioctl_abort_bulk_in(data);
				goto exit;
			}

			if (buffer[0] != 2) {
				dev_err(dev, "Device sent reply with wrong MsgID: %u != 2\n", buffer[0]);
				if (data->auto_abort)
					usbtmc_ioctl_abort_bulk_in(data);
				goto exit;
			}

			if (buffer[1] != data->bTag_last_write) {
				dev_err(dev, "Device sent reply with wrong bTag: %u != %u\n", buffer[1], data->bTag_last_write);
				if (data->auto_abort)
					usbtmc_ioctl_abort_bulk_in(data);
				goto exit;
			}

			/* How many characters did the instrument send? */
			n_characters = buffer[4] +
				       (buffer[5] << 8) +
				       (buffer[6] << 16) +
				       (buffer[7] << 24);

			if (n_characters > this_part) {
				dev_err(dev, "Device wants to return more data than requested: %u > %zu\n", n_characters, count);
				if (data->auto_abort)
					usbtmc_ioctl_abort_bulk_in(data);
				goto exit;
			}

			/* Remove the USBTMC header */
			actual -= USBTMC_HEADER_SIZE;

			/* Check if the message is smaller than requested */
			if (data->rigol_quirk) {
				if (remaining > n_characters)
					remaining = n_characters;
				/* Remove padding if it exists */
				if (actual > remaining)
					actual = remaining;
			}
			else {
				if (this_part > n_characters)
					this_part = n_characters;
				/* Remove padding if it exists */
				if (actual > this_part)
					actual = this_part;
			}

			dev_dbg(dev, "Bulk-IN header: N_characters(%u), bTransAttr(%u)\n", n_characters, buffer[8]);

			remaining -= actual;

			/* Terminate if end-of-message bit received from device */
			if ((buffer[8] & 0x01) && (actual >= n_characters))
				remaining = 0;

			dev_dbg(dev, "Bulk-IN header: remaining(%zu), buf(%p), buffer(%p) done(%zu)\n", remaining,buf,buffer,done);


			/* Copy buffer to user space */
			if (copy_to_user(buf + done, &buffer[USBTMC_HEADER_SIZE], actual)) {
				/* There must have been an addressing problem */
				retval = -EFAULT;
				goto exit;
			}
			done += actual;
		}
		else  {
			if (actual > remaining)
				actual = remaining;

			remaining -= actual;

			dev_dbg(dev, "Bulk-IN header cont: actual(%u), done(%zu), remaining(%zu), buf(%p), buffer(%p)\n", actual, done, remaining,buf,buffer);

			/* Copy buffer to user space */
			if (copy_to_user(buf + done, buffer, actual)) {
				/* There must have been an addressing problem */
				retval = -EFAULT;
				goto exit;
			}
			done += actual;
		}
	}

	/* Update file position value */
	*f_pos = *f_pos + done;
	retval = done;

exit:
	mutex_unlock(&data->io_mutex);
	kfree(buffer);
	return retval;
}
Ejemplo n.º 16
0
int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
                     const zd_addr_t *addresses, unsigned int count)
{
    int r;
    int i, req_len, actual_req_len;
    struct usb_device *udev;
    struct usb_req_read_regs *req = NULL;
    unsigned long timeout;

    if (count < 1) {
        dev_dbg_f(zd_usb_dev(usb), "error: count is zero\n");
        return -EINVAL;
    }
    if (count > USB_MAX_IOREAD16_COUNT) {
        dev_dbg_f(zd_usb_dev(usb),
                  "error: count %u exceeds possible max %u\n",
                  count, USB_MAX_IOREAD16_COUNT);
        return -EINVAL;
    }
    if (in_atomic()) {
        dev_dbg_f(zd_usb_dev(usb),
                  "error: io in atomic context not supported\n");
        return -EWOULDBLOCK;
    }
    if (!usb_int_enabled(usb)) {
        dev_dbg_f(zd_usb_dev(usb),
                  "error: usb interrupt not enabled\n");
        return -EWOULDBLOCK;
    }

    req_len = sizeof(struct usb_req_read_regs) + count * sizeof(__le16);
    req = kmalloc(req_len, GFP_KERNEL);
    if (!req)
        return -ENOMEM;
    req->id = cpu_to_le16(USB_REQ_READ_REGS);
    for (i = 0; i < count; i++)
        req->addr[i] = cpu_to_le16((u16)addresses[i]);

    udev = zd_usb_to_usbdev(usb);
    prepare_read_regs_int(usb);
    r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
                     req, req_len, &actual_req_len, 1000 /* ms */);
    if (r) {
        dev_dbg_f(zd_usb_dev(usb),
                  "error in usb_bulk_msg(). Error number %d\n", r);
        goto error;
    }
    if (req_len != actual_req_len) {
        dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()\n"
                  " req_len %d != actual_req_len %d\n",
                  req_len, actual_req_len);
        r = -EIO;
        goto error;
    }

    timeout = wait_for_completion_timeout(&usb->intr.read_regs.completion,
                                          msecs_to_jiffies(1000));
    if (!timeout) {
        disable_read_regs_int(usb);
        dev_dbg_f(zd_usb_dev(usb), "read timed out\n");
        r = -ETIMEDOUT;
        goto error;
    }

    r = get_results(usb, values, req, count);
error:
    kfree(req);
    return r;
}
Ejemplo n.º 17
0
static ssize_t usbtmc_write(struct file *filp, const char __user *buf,
			    size_t count, loff_t *f_pos)
{
	struct usbtmc_device_data *data;
	u8 *buffer;
	int retval;
	int actual;
	unsigned long int n_bytes;
	int remaining;
	int done;
	int this_part;

	data = filp->private_data;

	buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	mutex_lock(&data->io_mutex);
	if (data->zombie) {
		retval = -ENODEV;
		goto exit;
	}

	remaining = count;
	done = 0;

	while (remaining > 0) {
		if (remaining > USBTMC_SIZE_IOBUFFER - USBTMC_HEADER_SIZE) {
			this_part = USBTMC_SIZE_IOBUFFER - USBTMC_HEADER_SIZE;
			buffer[8] = 0;
		} else {
			this_part = remaining;
			buffer[8] = 1;
		}

		/* Setup IO buffer for DEV_DEP_MSG_OUT message */
		buffer[0] = 1;
		buffer[1] = data->bTag;
		buffer[2] = ~data->bTag;
		buffer[3] = 0; /* Reserved */
		buffer[4] = this_part >> 0;
		buffer[5] = this_part >> 8;
		buffer[6] = this_part >> 16;
		buffer[7] = this_part >> 24;
		/* buffer[8] is set above... */
		buffer[9] = 0; /* Reserved */
		buffer[10] = 0; /* Reserved */
		buffer[11] = 0; /* Reserved */

		if (copy_from_user(&buffer[USBTMC_HEADER_SIZE], buf + done, this_part)) {
			retval = -EFAULT;
			goto exit;
		}

		n_bytes = roundup(USBTMC_HEADER_SIZE + this_part, 4);
		memset(buffer + USBTMC_HEADER_SIZE + this_part, 0, n_bytes - (USBTMC_HEADER_SIZE + this_part));

		do {
			retval = usb_bulk_msg(data->usb_dev,
					      usb_sndbulkpipe(data->usb_dev,
							      data->bulk_out),
					      buffer, n_bytes,
					      &actual, USBTMC_TIMEOUT);
			if (retval != 0)
				break;
			n_bytes -= actual;
		} while (n_bytes);

		data->bTag_last_write = data->bTag;
		data->bTag++;

		if (!data->bTag)
			data->bTag++;

		if (retval < 0) {
			dev_err(&data->intf->dev,
				"Unable to send data, error %d\n", retval);
			if (data->auto_abort)
				usbtmc_ioctl_abort_bulk_out(data);
			goto exit;
		}

		remaining -= this_part;
		done += this_part;
	}

	retval = count;
exit:
	mutex_unlock(&data->io_mutex);
	kfree(buffer);
	return retval;
}
Ejemplo n.º 18
0
int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
{
    int r;
    struct usb_device *udev;
    struct usb_req_rfwrite *req = NULL;
    int i, req_len, actual_req_len;
    u16 bit_value_template;

    if (in_atomic()) {
        dev_dbg_f(zd_usb_dev(usb),
                  "error: io in atomic context not supported\n");
        return -EWOULDBLOCK;
    }
    if (bits < USB_MIN_RFWRITE_BIT_COUNT) {
        dev_dbg_f(zd_usb_dev(usb),
                  "error: bits %d are smaller than"
                  " USB_MIN_RFWRITE_BIT_COUNT %d\n",
                  bits, USB_MIN_RFWRITE_BIT_COUNT);
        return -EINVAL;
    }
    if (bits > USB_MAX_RFWRITE_BIT_COUNT) {
        dev_dbg_f(zd_usb_dev(usb),
                  "error: bits %d exceed USB_MAX_RFWRITE_BIT_COUNT %d\n",
                  bits, USB_MAX_RFWRITE_BIT_COUNT);
        return -EINVAL;
    }
#ifdef DEBUG
    if (value & (~0UL << bits)) {
        dev_dbg_f(zd_usb_dev(usb),
                  "error: value %#09x has bits >= %d set\n",
                  value, bits);
        return -EINVAL;
    }
#endif /* DEBUG */

    dev_dbg_f(zd_usb_dev(usb), "value %#09x bits %d\n", value, bits);

    r = zd_usb_ioread16(usb, &bit_value_template, CR203);
    if (r) {
        dev_dbg_f(zd_usb_dev(usb),
                  "error %d: Couldn't read CR203\n", r);
        goto out;
    }
    bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA);

    req_len = sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16);
    req = kmalloc(req_len, GFP_KERNEL);
    if (!req)
        return -ENOMEM;

    req->id = cpu_to_le16(USB_REQ_WRITE_RF);
    /* 1: 3683a, but not used in ZYDAS driver */
    req->value = cpu_to_le16(2);
    req->bits = cpu_to_le16(bits);

    for (i = 0; i < bits; i++) {
        u16 bv = bit_value_template;
        if (value & (1 << (bits-1-i)))
            bv |= RF_DATA;
        req->bit_values[i] = cpu_to_le16(bv);
    }

    udev = zd_usb_to_usbdev(usb);
    r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
                     req, req_len, &actual_req_len, 1000 /* ms */);
    if (r) {
        dev_dbg_f(zd_usb_dev(usb),
                  "error in usb_bulk_msg(). Error number %d\n", r);
        goto out;
    }
    if (req_len != actual_req_len) {
        dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()"
                  " req_len %d != actual_req_len %d\n",
                  req_len, actual_req_len);
        r = -EIO;
        goto out;
    }

    /* FALL-THROUGH with r == 0 */
out:
    kfree(req);
    return r;
}
Ejemplo n.º 19
0
int usb_stor_Bulk_transport(ccb *srb, struct us_data *us)
{
	struct bulk_cb_wrap cbw;
	struct bulk_cs_wrap csw;
	int actlen, data_actlen;
	int result;
	unsigned int residue;
	unsigned int pipein = usb_rcvbulkpipe(us->pusb_dev, us->recv_bulk_ep);
	unsigned int pipeout = usb_sndbulkpipe(us->pusb_dev, us->send_bulk_ep);
	int dir_in = US_DIRECTION(srb->cmd[0]);

	srb->trans_bytes = 0;

	/* set up the command wrapper */
	cbw.Signature = cpu_to_le32(US_BULK_CB_SIGN);
	cbw.DataTransferLength = cpu_to_le32(srb->datalen);
	cbw.Flags = (dir_in ? US_BULK_FLAG_IN : US_BULK_FLAG_OUT);
	cbw.Tag = ++cbw_tag;
	cbw.Lun = srb->lun;
	cbw.Length = srb->cmdlen;

	/* copy the command payload */
	memcpy(cbw.CDB, srb->cmd, cbw.Length);

	/* send it to out endpoint */
	US_DEBUGP("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n",
	                le32_to_cpu(cbw.Signature), cbw.Tag,
	                le32_to_cpu(cbw.DataTransferLength), cbw.Flags,
	                (cbw.Lun >> 4), (cbw.Lun & 0x0F),
	                cbw.Length);
	result = usb_bulk_msg(us->pusb_dev, pipeout, &cbw, US_BULK_CB_WRAP_LEN,
			      &actlen, USB_BULK_TO);
	US_DEBUGP("Bulk command transfer result=%d\n", result);
	if (result < 0) {
		usb_stor_Bulk_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	}

	/* DATA STAGE */
	/* send/receive data payload, if there is any */

	wait_ms(1);

	data_actlen = 0;
	if (srb->datalen) {
		unsigned int pipe = dir_in ? pipein : pipeout;
		result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata,
		                      srb->datalen, &data_actlen, USB_BULK_TO);
		US_DEBUGP("Bulk data transfer result 0x%x\n", result);
		/* special handling of STALL in DATA phase */
		if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
			US_DEBUGP("DATA: stall\n");
			/* clear the STALL on the endpoint */
			result = usb_stor_Bulk_clear_endpt_stall(us, pipe);
		}
		if (result < 0) {
			US_DEBUGP("Device status: %lx\n", us->pusb_dev->status);
			usb_stor_Bulk_reset(us);
			return USB_STOR_TRANSPORT_FAILED;
		}
	}

	/* STATUS phase + error handling */
	US_DEBUGP("Attempting to get CSW...\n");
	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, US_BULK_CS_WRAP_LEN,
	                      &actlen, USB_BULK_TO);

	/* did the endpoint stall? */
	if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
		US_DEBUGP("STATUS: stall\n");
		/* clear the STALL on the endpoint */
		result = usb_stor_Bulk_clear_endpt_stall(us, pipein);
		if (result >= 0) {
			US_DEBUGP("Attempting to get CSW...\n");
			result = usb_bulk_msg(us->pusb_dev, pipein,
			                      &csw, US_BULK_CS_WRAP_LEN,
			                      &actlen, USB_BULK_TO);
		}
	}

	if (result < 0) {
		US_DEBUGP("Device status: %lx\n", us->pusb_dev->status);
		usb_stor_Bulk_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	}

	/* check bulk status */
	residue = le32_to_cpu(csw.Residue);
	US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
	          le32_to_cpu(csw.Signature), csw.Tag, residue, csw.Status);
	if (csw.Signature != cpu_to_le32(US_BULK_CS_SIGN)) {
		US_DEBUGP("Bad CSW signature\n");
		usb_stor_Bulk_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	} else if (csw.Tag != cbw_tag) {
		US_DEBUGP("Mismatching tag\n");
		usb_stor_Bulk_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	} else if (csw.Status >= US_BULK_STAT_PHASE) {
		US_DEBUGP("Status >= phase\n");
		usb_stor_Bulk_reset(us);
		return USB_STOR_TRANSPORT_ERROR;
	} else if (residue > srb->datalen) {
		US_DEBUGP("residue (%uB) > req data (%luB)\n",
		          residue, srb->datalen);
		return USB_STOR_TRANSPORT_FAILED;
	} else if (csw.Status == US_BULK_STAT_FAIL) {
		US_DEBUGP("FAILED\n");
		return USB_STOR_TRANSPORT_FAILED;
	}
	srb->trans_bytes = min(srb->datalen - residue, (ulong)data_actlen);

	return 0;
}
Ejemplo n.º 20
0
/**
 * usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion
 * @usb_dev: pointer to the usb device to send the message to
 * @pipe: endpoint "pipe" to send the message to
 * @data: pointer to the data to send
 * @len: length in bytes of the data to send
 * @actual_length: pointer to a location to put the actual length transferred in bytes
 * @timeout: time in msecs to wait for the message to complete before
 *	timing out (if 0 the wait is forever)
 * Context: !in_interrupt ()
 *
 * This function sends a simple interrupt message to a specified endpoint and
 * waits for the message to complete, or timeout.
 *
 * If successful, it returns 0, otherwise a negative error number.  The number
 * of actual bytes transferred will be stored in the actual_length paramater.
 *
 * Don't use this function from within an interrupt context, like a bottom half
 * handler.  If you need an asynchronous message, or need to send a message
 * from within interrupt context, use usb_submit_urb() If a thread in your
 * driver uses this call, make sure your disconnect() method can wait for it to
 * complete.  Since you don't have a handle on the URB used, you can't cancel
 * the request.
 */
int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
		      void *data, int len, int *actual_length, int timeout)
{
	return usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout);
}
Ejemplo n.º 21
0
static ssize_t
read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
{
	DEFINE_WAIT(wait);
	struct rio_usb_data *rio = &rio_instance;
	ssize_t read_count;
	unsigned int partial;
	int this_read;
	int result;
	int maxretry = 10;
	char *ibuf;
	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;
	}

	ibuf = rio->ibuf;

	read_count = 0;


	while (count > 0) {
		if (signal_pending(current)) {
			mutex_unlock(&(rio->lock));
			return read_count ? read_count : -EINTR;
		}
		if (!rio->rio_dev) {
			mutex_unlock(&(rio->lock));
			return -ENODEV;
		}
		this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;

		result = usb_bulk_msg(rio->rio_dev,
				      usb_rcvbulkpipe(rio->rio_dev, 1),
				      ibuf, this_read, &partial,
				      8000);

		dbg("read stats: result:%d this_read:%u partial:%u",
		       result, this_read, partial);

		if (partial) {
			count = this_read = partial;
		} else if (result == -ETIMEDOUT || result == 15) {	/* FIXME: 15 ??? */
			if (!maxretry--) {
				mutex_unlock(&(rio->lock));
				err("read_rio: maxretry timeout");
				return -ETIME;
			}
			prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
			schedule_timeout(NAK_TIMEOUT);
			finish_wait(&rio->wait_q, &wait);
			continue;
		} else if (result != -EREMOTEIO) {
			mutex_unlock(&(rio->lock));
			err("Read Whoops - result:%u partial:%u this_read:%u",
			     result, partial, this_read);
			return -EIO;
		} else {
			mutex_unlock(&(rio->lock));
			return (0);
		}

		if (this_read) {
			if (copy_to_user(buffer, ibuf, this_read)) {
				mutex_unlock(&(rio->lock));
				return -EFAULT;
			}
			count -= this_read;
			read_count += this_read;
			buffer += this_read;
		}
	}
	mutex_unlock(&(rio->lock));
	return read_count;
}
Ejemplo n.º 22
0
/* this function reads a full JPEG picture synchronously
 * TODO: do it asynchronously... */
static int read_frame(struct zr364xx_camera *cam, int framenum)
{
	int i, n, temp, head, size, actual_length;
	unsigned char *ptr = NULL, *jpeg;

      redo:
	/* hardware brightness */
	n = send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
	temp = (0x60 << 8) + 127 - cam->brightness;
	n = send_control_msg(cam->udev, 1, temp, 0, NULL, 0);

	/* during the first loop we are going to insert JPEG header */
	head = 0;
	/* this is the place in memory where we are going to build
	 * the JPEG image */
	jpeg = cam->framebuf + framenum * MAX_FRAME_SIZE;
	/* read data... */
	do {
		n = usb_bulk_msg(cam->udev,
				 usb_rcvbulkpipe(cam->udev, 0x81),
				 cam->buffer, BUFFER_SIZE, &actual_length,
				 CTRL_TIMEOUT);
		DBG("buffer : %d %d", cam->buffer[0], cam->buffer[1]);
		DBG("bulk : n=%d size=%d", n, actual_length);
		if (n < 0) {
			dev_err(&cam->udev->dev, "error reading bulk msg\n");
			return 0;
		}
		if (actual_length < 0 || actual_length > BUFFER_SIZE) {
			dev_err(&cam->udev->dev, "wrong number of bytes\n");
			return 0;
		}

		/* swap bytes if camera needs it */
		if (cam->method == METHOD0) {
			u16 *buf = (u16*)cam->buffer;
			for (i = 0; i < BUFFER_SIZE/2; i++)
				swab16s(buf + i);
		}

		/* write the JPEG header */
		if (!head) {
			DBG("jpeg header");
			ptr = jpeg;
			memcpy(ptr, header1, sizeof(header1));
			ptr += sizeof(header1);
			header3 = 0;
			memcpy(ptr, &header3, 1);
			ptr++;
			memcpy(ptr, cam->buffer, 64);
			ptr += 64;
			header3 = 1;
			memcpy(ptr, &header3, 1);
			ptr++;
			memcpy(ptr, cam->buffer + 64, 64);
			ptr += 64;
			memcpy(ptr, header2, sizeof(header2));
			ptr += sizeof(header2);
			memcpy(ptr, cam->buffer + 128,
			       actual_length - 128);
			ptr += actual_length - 128;
			head = 1;
			DBG("header : %d %d %d %d %d %d %d %d %d",
			    cam->buffer[0], cam->buffer[1], cam->buffer[2],
			    cam->buffer[3], cam->buffer[4], cam->buffer[5],
			    cam->buffer[6], cam->buffer[7], cam->buffer[8]);
		} else {
			memcpy(ptr, cam->buffer, actual_length);
			ptr += actual_length;
		}
	}
	/* ... until there is no more */
	while (actual_length == BUFFER_SIZE);

	/* we skip the 2 first frames which are usually buggy */
	if (cam->skip) {
		cam->skip--;
		goto redo;
	}

	/* go back to find the JPEG EOI marker */
	size = ptr - jpeg;
	ptr -= 2;
	while (ptr > jpeg) {
		if (*ptr == 0xFF && *(ptr + 1) == 0xD9
		    && *(ptr + 2) == 0xFF)
			break;
		ptr--;
	}
	if (ptr == jpeg)
		DBG("No EOI marker");

	/* Sometimes there is junk data in the middle of the picture,
	 * we want to skip this bogus frames */
	while (ptr > jpeg) {
		if (*ptr == 0xFF && *(ptr + 1) == 0xFF
		    && *(ptr + 2) == 0xFF)
			break;
		ptr--;
	}
	if (ptr != jpeg) {
		DBG("Bogus frame ? %d", cam->nb);
		goto redo;
	}

	DBG("jpeg : %d %d %d %d %d %d %d %d",
	    jpeg[0], jpeg[1], jpeg[2], jpeg[3],
	    jpeg[4], jpeg[5], jpeg[6], jpeg[7]);

	return size;
}
Ejemplo n.º 23
0
static int bfusb_load_firmware(struct bfusb_data *data,
			       const unsigned char *firmware, int count)
{
	unsigned char *buf;
	int err, pipe, len, size, sent = 0;

	BT_DBG("bfusb %p udev %p", data, data->udev);

	BT_INFO("BlueFRITZ! USB loading firmware");

	buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_KERNEL);
	if (!buf) {
		BT_ERR("Can't allocate memory chunk for firmware");
		return -ENOMEM;
	}

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

	if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
				0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
		BT_ERR("Can't change to loading configuration");
		kfree(buf);
		return -EBUSY;
	}

	data->udev->toggle[0] = data->udev->toggle[1] = 0;

	pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);

	while (count) {
		size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);

		memcpy(buf, firmware + sent, size);

		err = usb_bulk_msg(data->udev, pipe, buf, size,
					&len, BFUSB_BLOCK_TIMEOUT);

		if (err || (len != size)) {
			BT_ERR("Error in firmware loading");
			goto error;
		}

		sent  += size;
		count -= size;
	}

	err = usb_bulk_msg(data->udev, pipe, NULL, 0,
					&len, BFUSB_BLOCK_TIMEOUT);
	if (err < 0) {
		BT_ERR("Error in null packet request");
		goto error;
	}

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

	err = usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
				0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
	if (err < 0) {
		BT_ERR("Can't change to running configuration");
		goto error;
	}

	data->udev->toggle[0] = data->udev->toggle[1] = 0;

	BT_INFO("BlueFRITZ! USB device ready");

	kfree(buf);
	return 0;

error:
	kfree(buf);

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

	usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
				0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);

	return err;
}
Ejemplo n.º 24
0
/*
 * Load the MIPS R4000 microcode into the device.  Once the image is loaded,
 * the device will detach itself from the bus and reattach later with a new
 * product Id (a la ezusb).
 */
static int ar5523_load_firmware(struct usb_device *dev)
{
	struct ar5523_fwblock *txblock, *rxblock;
	const struct firmware *fw;
	void *fwbuf;
	int len, offset;
	int foolen; /* XXX(hch): handle short transfers */
	int error = -ENXIO;

	if (request_firmware(&fw, AR5523_FIRMWARE_FILE, &dev->dev)) {
		dev_err(&dev->dev, "no firmware found: %s\n",
			AR5523_FIRMWARE_FILE);
		return -ENOENT;
	}

	txblock = kmalloc(sizeof(*txblock), GFP_KERNEL);
	if (!txblock)
		goto out;

	rxblock = kmalloc(sizeof(*rxblock), GFP_KERNEL);
	if (!rxblock)
		goto out_free_txblock;

	fwbuf = kmalloc(AR5523_MAX_FWBLOCK_SIZE, GFP_KERNEL);
	if (!fwbuf)
		goto out_free_rxblock;

	memset(txblock, 0, sizeof(struct ar5523_fwblock));
	txblock->flags = cpu_to_be32(AR5523_WRITE_BLOCK);
	txblock->total = cpu_to_be32(fw->size);

	offset = 0;
	len = fw->size;
	while (len > 0) {
		int mlen = min(len, AR5523_MAX_FWBLOCK_SIZE);

		txblock->remain = cpu_to_be32(len - mlen);
		txblock->len = cpu_to_be32(mlen);

		/* send firmware block meta-data */
		error = usb_bulk_msg(dev, ar5523_cmd_tx_pipe(dev),
				     txblock, sizeof(*txblock), &foolen,
				     AR5523_CMD_TIMEOUT);
		if (error) {
			dev_err(&dev->dev,
				"could not send firmware block info\n");
			goto out_free_fwbuf;
		}

		/* send firmware block data */
		memcpy(fwbuf, fw->data + offset, mlen);
		error = usb_bulk_msg(dev, ar5523_data_tx_pipe(dev),
				     fwbuf, mlen, &foolen,
				     AR5523_DATA_TIMEOUT);
		if (error) {
			dev_err(&dev->dev,
				"could not send firmware block data\n");
			goto out_free_fwbuf;
		}

		/* wait for ack from firmware */
		error = usb_bulk_msg(dev, ar5523_cmd_rx_pipe(dev),
				     rxblock, sizeof(*rxblock), &foolen,
				     AR5523_CMD_TIMEOUT);
		if (error) {
			dev_err(&dev->dev,
				"could not read firmware answer\n");
			goto out_free_fwbuf;
		}

		len -= mlen;
		offset += mlen;
	}

	/*
	 * Set the error to -ENXIO to make sure we continue probing for
	 * a driver.
	 */
	error = -ENXIO;

 out_free_fwbuf:
	kfree(fwbuf);
 out_free_rxblock:
	kfree(rxblock);
 out_free_txblock:
	kfree(txblock);
 out:
	release_firmware(fw);
	return error;
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
{
#define BUF_LEN 63
#define REQ_HDR_LEN 8 /* send header size */
#define ACK_HDR_LEN 2 /* rece header size */
	int act_len, ret;
	u8 buf[BUF_LEN];
	u8 write = 1;
	u8 msg_len = REQ_HDR_LEN;
	static u8 seq; /* packet sequence number */

	if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
		return -EAGAIN;

	buf[0] = req->cmd;
	buf[1] = seq++;
	buf[2] = req->i2c_addr;
	buf[3] = req->addr >> 8;
	buf[4] = req->addr & 0xff;
	buf[5] = req->mbox;
	buf[6] = req->addr_len;
	buf[7] = req->data_len;

	switch (req->cmd) {
	case GET_CONFIG:
	case READ_MEMORY:
	case RECONNECT_USB:
		write = 0;
		break;
	case READ_I2C:
		write = 0;
		buf[2] |= 0x01; /* set I2C direction */
	case WRITE_I2C:
		buf[0] = READ_WRITE_I2C;
		break;
	case WRITE_MEMORY:
		if (((req->addr & 0xff00) == 0xff00) ||
		    ((req->addr & 0xff00) == 0xae00))
			buf[0] = WRITE_VIRTUAL_MEMORY;
	case WRITE_VIRTUAL_MEMORY:
	case COPY_FIRMWARE:
	case DOWNLOAD_FIRMWARE:
	case BOOT:
		break;
	default:
		err("unknown command:%d", req->cmd);
		ret = -1;
		goto error_unlock;
	}

	/* buffer overflow check */
	if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
		(!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
		err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
		ret = -EINVAL;
		goto error_unlock;
	}

	/* write requested */
	if (write) {
		memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
		msg_len += req->data_len;
	}

	deb_xfer(">>> ");
	debug_dump(buf, msg_len, deb_xfer);

	/* send req */
	ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
		&act_len, AF9015_USB_TIMEOUT);
	if (ret)
		err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
	else
		if (act_len != msg_len)
			ret = -1; /* all data is not send */
	if (ret)
		goto error_unlock;

	/* no ack for those packets */
	if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
		goto exit_unlock;

	/* write receives seq + status = 2 bytes
	   read receives seq + status + data = 2 + N bytes */
	msg_len = ACK_HDR_LEN;
	if (!write)
		msg_len += req->data_len;

	ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
		&act_len, AF9015_USB_TIMEOUT);
	if (ret) {
		err("recv bulk message failed:%d", ret);
		ret = -1;
		goto error_unlock;
	}

	deb_xfer("<<< ");
	debug_dump(buf, act_len, deb_xfer);

	/* check status */
	if (buf[1]) {
		err("command failed:%d", buf[1]);
		ret = -1;
		goto error_unlock;
	}

	/* read request, copy returned data to return buf */
	if (!write)
		memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);

error_unlock:
exit_unlock:
	mutex_unlock(&af9015_usb_mutex);

	return ret;
}
Ejemplo n.º 27
0
static int usX2Y_create_usbmidi(struct snd_card *card)
{
	static struct snd_usb_midi_endpoint_info quirk_data_1 = {
		.out_ep = 0x06,
		.in_ep = 0x06,
		.out_cables =	0x001,
		.in_cables =	0x001
	};
	static struct snd_usb_audio_quirk quirk_1 = {
		.vendor_name =	"TASCAM",
		.product_name =	NAME_ALLCAPS,
		.ifnum = 	0,
       		.type = QUIRK_MIDI_FIXED_ENDPOINT,
		.data = &quirk_data_1
	};
	static struct snd_usb_midi_endpoint_info quirk_data_2 = {
		.out_ep = 0x06,
		.in_ep = 0x06,
		.out_cables =	0x003,
		.in_cables =	0x003
	};
	static struct snd_usb_audio_quirk quirk_2 = {
		.vendor_name =	"TASCAM",
		.product_name =	"US428",
		.ifnum = 	0,
       		.type = QUIRK_MIDI_FIXED_ENDPOINT,
		.data = &quirk_data_2
	};
	struct usb_device *dev = usX2Y(card)->chip.dev;
	struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
	struct snd_usb_audio_quirk *quirk =
		le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ?
		&quirk_2 : &quirk_1;

	snd_printdd("usX2Y_create_usbmidi \n");
	return snd_usb_create_midi_interface(&usX2Y(card)->chip, iface, quirk);
}

static int usX2Y_create_alsa_devices(struct snd_card *card)
{
	int err;

	do {
		if ((err = usX2Y_create_usbmidi(card)) < 0) {
			snd_printk(KERN_ERR "usX2Y_create_alsa_devices: usX2Y_create_usbmidi error %i \n", err);
			break;
		}
		if ((err = usX2Y_audio_create(card)) < 0) 
			break;
		if ((err = usX2Y_hwdep_pcm_new(card)) < 0)
			break;
		if ((err = snd_card_register(card)) < 0)
			break;
	} while (0);

	return err;
} 

static int snd_usX2Y_hwdep_dsp_load(struct snd_hwdep *hw,
				    struct snd_hwdep_dsp_image *dsp)
{
	struct usX2Ydev *priv = hw->private_data;
	int	lret, err = -EINVAL;
	snd_printdd( "dsp_load %s\n", dsp->name);

	if (access_ok(VERIFY_READ, dsp->image, dsp->length)) {
		struct usb_device* dev = priv->chip.dev;
		char *buf = kmalloc(dsp->length, GFP_KERNEL);
		if (!buf)
			return -ENOMEM;
		if (copy_from_user(buf, dsp->image, dsp->length)) {
			kfree(buf);
			return -EFAULT;
		}
		err = usb_set_interface(dev, 0, 1);
		if (err)
			snd_printk(KERN_ERR "usb_set_interface error \n");
		else
			err = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 2), buf, dsp->length, &lret, 6000);
		kfree(buf);
	}
	if (err)
		return err;
	if (dsp->index == 1) {
		msleep(250);				// give the device some time
		err = usX2Y_AsyncSeq04_init(priv);
		if (err) {
			snd_printk(KERN_ERR "usX2Y_AsyncSeq04_init error \n");
			return err;
		}
		err = usX2Y_In04_init(priv);
		if (err) {
			snd_printk(KERN_ERR "usX2Y_In04_init error \n");
			return err;
		}
		err = usX2Y_create_alsa_devices(hw->card);
		if (err) {
			snd_printk(KERN_ERR "usX2Y_create_alsa_devices error %i \n", err);
			snd_card_free(hw->card);
			return err;
		}
		priv->chip_status |= USX2Y_STAT_CHIP_INIT; 
		snd_printdd("%s: alsa all started\n", hw->name);
	}
	return err;
}


int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device)
{
	int err;
	struct snd_hwdep *hw;

	if ((err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw)) < 0)
		return err;

	hw->iface = SNDRV_HWDEP_IFACE_USX2Y;
	hw->private_data = usX2Y(card);
	hw->ops.open = snd_usX2Y_hwdep_open;
	hw->ops.release = snd_usX2Y_hwdep_release;
	hw->ops.dsp_status = snd_usX2Y_hwdep_dsp_status;
	hw->ops.dsp_load = snd_usX2Y_hwdep_dsp_load;
	hw->ops.mmap = snd_us428ctls_mmap;
	hw->ops.poll = snd_us428ctls_poll;
	hw->exclusive = 1;
	sprintf(hw->name, "/proc/bus/usb/%03d/%03d", device->bus->busnum, device->devnum);
	return 0;
}
Ejemplo n.º 28
0
static int usbtmc_ioctl_abort_bulk_in(struct usbtmc_device_data *data)
{
	u8 *buffer;
	struct device *dev;
	int rv;
	int n;
	int actual;
	struct usb_host_interface *current_setting;
	int max_size;

	dev = &data->intf->dev;
	buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	rv = usb_control_msg(data->usb_dev,
			     usb_rcvctrlpipe(data->usb_dev, 0),
			     USBTMC_REQUEST_INITIATE_ABORT_BULK_IN,
			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
			     data->bTag_last_read, data->bulk_in,
			     buffer, 2, USBTMC_TIMEOUT);

	if (rv < 0) {
		dev_err(dev, "usb_control_msg returned %d\n", rv);
		goto exit;
	}

	dev_dbg(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]);

	if (buffer[0] == USBTMC_STATUS_FAILED) {
		rv = 0;
		goto exit;
	}

	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
		dev_err(dev, "INITIATE_ABORT_BULK_IN returned %x\n",
			buffer[0]);
		rv = -EPERM;
		goto exit;
	}

	max_size = 0;
	current_setting = data->intf->cur_altsetting;
	for (n = 0; n < current_setting->desc.bNumEndpoints; n++)
		if (current_setting->endpoint[n].desc.bEndpointAddress ==
			data->bulk_in)
			max_size = usb_endpoint_maxp(&current_setting->endpoint[n].desc);

	if (max_size == 0) {
		dev_err(dev, "Couldn't get wMaxPacketSize\n");
		rv = -EPERM;
		goto exit;
	}

	dev_dbg(&data->intf->dev, "wMaxPacketSize is %d\n", max_size);

	n = 0;

	do {
		dev_dbg(dev, "Reading from bulk in EP\n");

		rv = usb_bulk_msg(data->usb_dev,
				  usb_rcvbulkpipe(data->usb_dev,
						  data->bulk_in),
				  buffer, USBTMC_SIZE_IOBUFFER,
				  &actual, USBTMC_TIMEOUT);

		n++;

		if (rv < 0) {
			dev_err(dev, "usb_bulk_msg returned %d\n", rv);
			goto exit;
		}
	} while ((actual == max_size) &&
		 (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));

	if (actual == max_size) {
		dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
			USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
		rv = -EPERM;
		goto exit;
	}

	n = 0;

usbtmc_abort_bulk_in_status:
	rv = usb_control_msg(data->usb_dev,
			     usb_rcvctrlpipe(data->usb_dev, 0),
			     USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS,
			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
			     0, data->bulk_in, buffer, 0x08,
			     USBTMC_TIMEOUT);

	if (rv < 0) {
		dev_err(dev, "usb_control_msg returned %d\n", rv);
		goto exit;
	}

	dev_dbg(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]);

	if (buffer[0] == USBTMC_STATUS_SUCCESS) {
		rv = 0;
		goto exit;
	}

	if (buffer[0] != USBTMC_STATUS_PENDING) {
		dev_err(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]);
		rv = -EPERM;
		goto exit;
	}

	if (buffer[1] == 1)
		do {
			dev_dbg(dev, "Reading from bulk in EP\n");

			rv = usb_bulk_msg(data->usb_dev,
					  usb_rcvbulkpipe(data->usb_dev,
							  data->bulk_in),
					  buffer, USBTMC_SIZE_IOBUFFER,
					  &actual, USBTMC_TIMEOUT);

			n++;

			if (rv < 0) {
				dev_err(dev, "usb_bulk_msg returned %d\n", rv);
				goto exit;
			}
		} while ((actual == max_size) &&
			 (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));

	if (actual == max_size) {
		dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
			USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
		rv = -EPERM;
		goto exit;
	}

	goto usbtmc_abort_bulk_in_status;

exit:
	kfree(buffer);
	return rv;

}
Ejemplo n.º 29
0
int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
{
	int result, retry;
	int dir_in;
	int actlen, data_actlen;
	unsigned int pipe, pipein, pipeout;
	umass_bbb_csw_t csw;
#ifdef BBB_XPORT_TRACE
	unsigned char *ptr;
	int index;
#endif

	dir_in = US_DIRECTION(srb->cmd[0]);

	/* COMMAND phase */
	USB_STOR_PRINTF("COMMAND phase\n");
	result = usb_stor_BBB_comdat(srb, us);
	if (result < 0) {
		USB_STOR_PRINTF("failed to send CBW status %ld\n",
			us->pusb_dev->status);
		usb_stor_BBB_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	}
	wait_ms(5);
	pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
	pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
	/* DATA phase + error handling */
	data_actlen = 0;
	/* no data, go immediately to the STATUS phase */
	if (srb->datalen == 0)
		goto st;
	USB_STOR_PRINTF("DATA phase\n");
	if (dir_in)
		pipe = pipein;
	else
		pipe = pipeout;
	result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata, srb->datalen, &data_actlen, USB_CNTL_TIMEOUT*5);
	/* special handling of STALL in DATA phase */
	if((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
		USB_STOR_PRINTF("DATA:stall\n");
		/* clear the STALL on the endpoint */
		result = usb_stor_BBB_clear_endpt_stall(us, dir_in? us->ep_in : us->ep_out);
		if (result >= 0)
			/* continue on to STATUS phase */
			goto st;
	}
	if (result < 0) {
		USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
			us->pusb_dev->status);
		usb_stor_BBB_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	}
#ifdef BBB_XPORT_TRACE
	for (index = 0; index < data_actlen; index++)
		printf("pdata[%d] %#x ", index, srb->pdata[index]);
	printf("\n");
#endif
	/* STATUS phase + error handling */
   st:
	retry = 0;
   again:
	USB_STOR_PRINTF("STATUS phase\n");
	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
				&actlen, USB_CNTL_TIMEOUT*5);

	/* special handling of STALL in STATUS phase */
	if((result < 0) && (retry < 1) && (us->pusb_dev->status & USB_ST_STALLED)) {
		USB_STOR_PRINTF("STATUS:stall\n");
		/* clear the STALL on the endpoint */
		result = usb_stor_BBB_clear_endpt_stall(us, us->ep_in);
		if (result >= 0 && (retry++ < 1))
			/* do a retry */
			goto again;
	}
	if (result < 0) {
		USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
			us->pusb_dev->status);
		usb_stor_BBB_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	}
#ifdef BBB_XPORT_TRACE
	ptr = (unsigned char *)&csw;
	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
		printf("ptr[%d] %#x ", index, ptr[index]);
	printf("\n");
#endif
	/* misuse pipe to get the residue */
	pipe = swap_32(csw.dCSWDataResidue);
	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
		pipe = srb->datalen - data_actlen;
	if (CSWSIGNATURE != swap_32(csw.dCSWSignature)) {
		USB_STOR_PRINTF("!CSWSIGNATURE\n");
		usb_stor_BBB_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	} else if ((CBWTag - 1) != swap_32(csw.dCSWTag)) {
		USB_STOR_PRINTF("!Tag\n");
		usb_stor_BBB_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
		USB_STOR_PRINTF(">PHASE\n");
		usb_stor_BBB_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
		USB_STOR_PRINTF("=PHASE\n");
		usb_stor_BBB_reset(us);
		return USB_STOR_TRANSPORT_FAILED;
	} else if (data_actlen > srb->datalen) {
		USB_STOR_PRINTF("transferred %dB instead of %dB\n",
			data_actlen, srb->datalen);
		return USB_STOR_TRANSPORT_FAILED;
	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
		USB_STOR_PRINTF("FAILED\n");
		return USB_STOR_TRANSPORT_FAILED;
	}

	return result;
}
Ejemplo n.º 30
0
static long ioctl_aw(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct aw_usb_data *aw = &aw_instance;
	int retval = 0;
	struct usb_param param_tmp;

	struct aw_command aw_cmd;
	void __user *data;
	unsigned char *buffer;
	int value = 0;
	int buffer_len = 0;

	int result = 0;
	int actual_len = 0;

	mutex_lock(&(aw->lock));
	if (aw->present == 0 || aw->aw_dev == NULL) {
		retval = -ENODEV;
	goto err_out;
	}

	pr_debug("ioctl_aw--enter\n");

	pr_debug("cmd = %d\n", cmd);

	param_tmp.test_num = 0;
	param_tmp.p1 = 0;
	param_tmp.p2 = 0;
	param_tmp.p3 = 0;

	switch (cmd) {
	case AWUSB_IOCRESET:
		pr_debug("ioctl_aw--AWUSB_IOCRESET\n");
		break;

	case AWUSB_IOCSET:
		pr_debug("ioctl_aw--AWUSB_IOCSET\n");

		if (copy_from_user(
			&param_tmp, (void __user *)arg, sizeof(param_tmp))) {
			retval = -EFAULT;
		}

		pr_debug("param_tmp.test_num = %d\n", param_tmp.test_num);
		pr_debug("param_tmp.p1 = %d\n", param_tmp.p1);
		pr_debug("param_tmp.p2 = %d\n", param_tmp.p2);
		pr_debug("param_tmp.p3 = %d\n", param_tmp.p3);
		break;

	case AWUSB_IOCGET:
		pr_debug("ioctl_aw--AWUSB_IOCGET\n");

		param_tmp.test_num = 3;
		param_tmp.p1 = 4;
		param_tmp.p2 = 5;
		param_tmp.p3 = 6;

		if (copy_to_user(
			(void __user *)arg, &param_tmp, sizeof(param_tmp))) {
			retval = -EFAULT;
		}
		break;

	case AWUSB_IOCSEND:
		pr_debug("ioctl_aw--AWUSB_IOCSEND\n");

		data = (void __user *)arg;
		if (data == NULL)
			break;

		if (copy_from_user(&aw_cmd, data, sizeof(struct aw_command))) {
			retval = -EFAULT;
			goto err_out;
		}

		buffer_len = aw_cmd.length;
		value = aw_cmd.value;
		pr_debug("buffer_len=%d\n", buffer_len);
		pr_debug("value=%d\n", value);
		if (buffer_len > IOCTL_SIZE) {
			retval = -EINVAL;
			goto err_out;
		}
		buffer = kmalloc(buffer_len, GFP_KERNEL);
		if (!(buffer)) {
			dev_err(&aw->aw_dev->dev,
				"AWUSB_IOCSEND: Not enough memory for the send buffer");
			retval = -ENOMEM;
			goto err_out;
		}

		/* stage 1, get data from app */
		if (copy_from_user(buffer, aw_cmd.buffer, aw_cmd.length)) {
			retval = -EFAULT;
			kfree(buffer);
			goto err_out;
		}

#if 0
		int ii = 0;

		for (ii = 0; ii < buffer_len; ii++)
				pr_debug(
				"*(buffer + %d) = %d\n", ii, *(buffer + ii));
		pr_debug("*buffer=%d, *(buffer+1)=%d\n", *buffer, *(buffer+1));
#endif

		/* stage 2, send data to usb device */
		result = usb_bulk_msg(aw->aw_dev,
		usb_sndbulkpipe(aw->aw_dev, 1),
		buffer, buffer_len, &actual_len, 5000);
		if (result) {
			kfree(buffer);

			dev_err(&aw->aw_dev->dev,
				"Write Whoops - %08x", result);
			retval = -EIO;
			goto err_out;
		}

		kfree(buffer);

		pr_debug("ioctl_aw--AWUSB_IOCSEND-exit\n");
		break;

	case AWUSB_IOCRECV:
		pr_debug("ioctl_aw--AWUSB_IOCRECV\n");

		data = (void __user *)arg;
		if (data == NULL)
			break;
		if (copy_from_user(&aw_cmd, data, sizeof(struct aw_command))) {
			retval = -EFAULT;
			goto err_out;
		}
		if (aw_cmd.length < 0) {
			retval = -EINVAL;
			goto err_out;
		}
		buffer_len = aw_cmd.length;
		value = aw_cmd.value;
		pr_debug("buffer_len=%d\n", buffer_len);
		pr_debug("value=%d\n", value);
		buffer = kmalloc(buffer_len, GFP_KERNEL);
		if (!(buffer)) {
			dev_err(&aw->aw_dev->dev,
				"AWUSB_IOCSEND: Not enough memory for the receive buffer");
			retval = -ENOMEM;
			goto err_out;
		}
		memset(buffer, 0x33, buffer_len);

		/* stage 1, get data from usb device */
		result = usb_bulk_msg(aw->aw_dev,
		usb_rcvbulkpipe(aw->aw_dev, 2),
		buffer, buffer_len, &actual_len, 0);/*8000); */

		if (result) {
			kfree(buffer);

			dev_err(&aw->aw_dev->dev, "Read Whoops - %x", result);
			retval = -EIO;
			goto err_out;
		}

		/* stage 2, copy data to app in user space */
		if (copy_to_user(aw_cmd.buffer, buffer, aw_cmd.length)) {
			kfree(buffer);
			retval = -EFAULT;
			goto err_out;
		}

		kfree(buffer);

		break;

	case AWUSB_IOCSEND_RECV:
		pr_debug("ioctl_aw--AWUSB_IOCSEND_RECV\n");

		break;

	default:
		retval = -ENOTTY;
		break;
	}

	pr_debug("ioctl_aw--exit\n");

err_out:
	mutex_unlock(&(aw->lock));
	return retval;
}