/* * 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; }
/* * 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; }
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; }
/* * 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; }
/* * 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; }
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 = ¤t_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; }
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; }
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; }
/***************************************************************************** * 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/** * 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); }
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; }
/* 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; }
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; }
/* * 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; }
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; }
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; }
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; }
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(¤t_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; }
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; }
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( ¶m_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, ¶m_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; }