return 0;
}
+static int usbdux_alloc_usb_buffers(struct usbdux_private *devpriv)
+{
+ struct urb *urb;
+ int i;
+
+ /* create space for the commands of the DA converter */
+ devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
+ if (!devpriv->dac_commands)
+ return -ENOMEM;
+
+ /* create space for the commands going to the usb device */
+ devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
+ if (!devpriv->dux_commands)
+ return -ENOMEM;
+
+ /* create space for the in buffer and set it to zero */
+ devpriv->in_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
+ if (!devpriv->in_buffer)
+ return -ENOMEM;
+
+ /* create space of the instruction buffer */
+ devpriv->insn_buffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
+ if (!devpriv->insn_buffer)
+ return -ENOMEM;
+
+ /* create space for the outbuffer */
+ devpriv->out_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
+ if (!devpriv->out_buffer)
+ return -ENOMEM;
+
+ /* in urbs */
+ devpriv->urb_in = kcalloc(devpriv->num_in_buffers, sizeof(*urb),
+ GFP_KERNEL);
+ if (!devpriv->urb_in)
+ return -ENOMEM;
+
+ for (i = 0; i < devpriv->num_in_buffers; i++) {
+ /* one frame: 1ms */
+ urb = usb_alloc_urb(1, GFP_KERNEL);
+ if (!urb)
+ return -ENOMEM;
+ devpriv->urb_in[i] = urb;
+
+ urb->dev = devpriv->usbdev;
+ /* will be filled later with a pointer to the comedi-device */
+ /* and ONLY then the urb should be submitted */
+ urb->context = NULL;
+ urb->pipe = usb_rcvisocpipe(devpriv->usbdev, ISOINEP);
+ urb->transfer_flags = URB_ISO_ASAP;
+ urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
+ if (!urb->transfer_buffer)
+ return -ENOMEM;
+
+ urb->complete = usbduxsub_ai_isoc_irq;
+ urb->number_of_packets = 1;
+ urb->transfer_buffer_length = SIZEINBUF;
+ urb->iso_frame_desc[0].offset = 0;
+ urb->iso_frame_desc[0].length = SIZEINBUF;
+ }
+
+ /* out urbs */
+ devpriv->urb_out = kcalloc(devpriv->num_out_buffers, sizeof(*urb),
+ GFP_KERNEL);
+ if (!devpriv->urb_out)
+ return -ENOMEM;
+
+ for (i = 0; i < devpriv->num_out_buffers; i++) {
+ /* one frame: 1ms */
+ urb = usb_alloc_urb(1, GFP_KERNEL);
+ if (!urb)
+ return -ENOMEM;
+ devpriv->urb_out[i] = urb;
+
+ urb->dev = devpriv->usbdev;
+ /* will be filled later with a pointer to the comedi-device */
+ /* and ONLY then the urb should be submitted */
+ urb->context = NULL;
+ urb->pipe = usb_sndisocpipe(devpriv->usbdev, ISOOUTEP);
+ urb->transfer_flags = URB_ISO_ASAP;
+ urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
+ if (!urb->transfer_buffer)
+ return -ENOMEM;
+
+ urb->complete = usbduxsub_ao_isoc_irq;
+ urb->number_of_packets = 1;
+ urb->transfer_buffer_length = SIZEOUTBUF;
+ urb->iso_frame_desc[0].offset = 0;
+ urb->iso_frame_desc[0].length = SIZEOUTBUF;
+ if (devpriv->high_speed)
+ urb->interval = 8; /* uframes */
+ else
+ urb->interval = 1; /* frames */
+ }
+
+ /* pwm */
+ if (devpriv->size_pwm_buf) {
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ return -ENOMEM;
+ devpriv->urb_pwm = urb;
+
+ /* max bulk ep size in high speed */
+ urb->transfer_buffer = kzalloc(devpriv->size_pwm_buf,
+ GFP_KERNEL);
+ if (!urb->transfer_buffer)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
static int usbdux_auto_attach(struct comedi_device *dev,
unsigned long context_unused)
{
struct usb_device *udev = interface_to_usbdev(uinterf);
struct device *dev = &uinterf->dev;
struct usbdux_private *devpriv = NULL;
- struct urb *urb;
+ int ret;
int i;
down(&start_stop_sem);
usb_set_intfdata(uinterf, devpriv);
devpriv->high_speed = (devpriv->usbdev->speed == USB_SPEED_HIGH);
-
- /* create space for the commands of the DA converter */
- devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
- if (!devpriv->dac_commands) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- /* create space for the commands going to the usb device */
- devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
- if (!devpriv->dux_commands) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- /* create space for the in buffer and set it to zero */
- devpriv->in_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
- if (!devpriv->in_buffer) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- /* create space of the instruction buffer */
- devpriv->insn_buffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
- if (!devpriv->insn_buffer) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- /* create space for the outbuffer */
- devpriv->out_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
- if (!devpriv->out_buffer) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- /* setting to alternate setting 3: enabling iso ep and bulk ep. */
- i = usb_set_interface(devpriv->usbdev, devpriv->ifnum, 3);
- if (i < 0) {
- dev_err(dev,
- "could not set alternate setting 3 in high speed\n");
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENODEV;
- }
- if (devpriv->high_speed)
+ if (devpriv->high_speed) {
devpriv->num_in_buffers = NUMOFINBUFFERSHIGH;
- else
+ devpriv->num_out_buffers = NUMOFOUTBUFFERSHIGH;
+ devpriv->size_pwm_buf = 512;
+ } else {
devpriv->num_in_buffers = NUMOFINBUFFERSFULL;
+ devpriv->num_out_buffers = NUMOFOUTBUFFERSFULL;
+ devpriv->size_pwm_buf = 0;
+ }
- devpriv->urb_in = kcalloc(devpriv->num_in_buffers, sizeof(*urb),
- GFP_KERNEL);
- if (!devpriv->urb_in) {
+ ret = usbdux_alloc_usb_buffers(devpriv);
+ if (ret) {
tidy_up(devpriv);
up(&start_stop_sem);
- return -ENOMEM;
- }
- for (i = 0; i < devpriv->num_in_buffers; i++) {
- /* one frame: 1ms */
- urb = usb_alloc_urb(1, GFP_KERNEL);
- if (!urb) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- devpriv->urb_in[i] = urb;
-
- urb->dev = devpriv->usbdev;
- /* will be filled later with a pointer to the comedi-device */
- /* and ONLY then the urb should be submitted */
- urb->context = NULL;
- urb->pipe = usb_rcvisocpipe(devpriv->usbdev, ISOINEP);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
- if (!urb->transfer_buffer) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- urb->complete = usbduxsub_ai_isoc_irq;
- urb->number_of_packets = 1;
- urb->transfer_buffer_length = SIZEINBUF;
- urb->iso_frame_desc[0].offset = 0;
- urb->iso_frame_desc[0].length = SIZEINBUF;
+ return ret;
}
- /* out */
- if (devpriv->high_speed)
- devpriv->num_out_buffers = NUMOFOUTBUFFERSHIGH;
- else
- devpriv->num_out_buffers = NUMOFOUTBUFFERSFULL;
-
- devpriv->urb_out = kcalloc(devpriv->num_out_buffers, sizeof(*urb),
- GFP_KERNEL);
- if (!devpriv->urb_out) {
+ /* setting to alternate setting 3: enabling iso ep and bulk ep. */
+ ret = usb_set_interface(devpriv->usbdev, devpriv->ifnum, 3);
+ if (ret < 0) {
+ dev_err(dev,
+ "could not set alternate setting 3 in high speed\n");
tidy_up(devpriv);
up(&start_stop_sem);
- return -ENOMEM;
- }
- for (i = 0; i < devpriv->num_out_buffers; i++) {
- /* one frame: 1ms */
- urb = usb_alloc_urb(1, GFP_KERNEL);
- if (!urb) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- devpriv->urb_out[i] = urb;
-
- urb->dev = devpriv->usbdev;
- /* will be filled later with a pointer to the comedi-device */
- /* and ONLY then the urb should be submitted */
- urb->context = NULL;
- urb->pipe = usb_sndisocpipe(devpriv->usbdev, ISOOUTEP);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
- if (!(urb->transfer_buffer)) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- urb->complete = usbduxsub_ao_isoc_irq;
- urb->number_of_packets = 1;
- urb->transfer_buffer_length = SIZEOUTBUF;
- urb->iso_frame_desc[0].offset = 0;
- urb->iso_frame_desc[0].length = SIZEOUTBUF;
- if (devpriv->high_speed)
- urb->interval = 8; /* uframes */
- else
- urb->interval = 1; /* frames */
- }
-
- /* pwm */
- if (devpriv->high_speed) {
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- devpriv->urb_pwm = urb;
-
- /* max bulk ep size in high speed */
- devpriv->size_pwm_buf = 512;
- urb->transfer_buffer = kzalloc(devpriv->size_pwm_buf,
- GFP_KERNEL);
- if (!urb->transfer_buffer) {
- tidy_up(devpriv);
- up(&start_stop_sem);
- return -ENOMEM;
- }
- } else {
- devpriv->urb_pwm = NULL;
- devpriv->size_pwm_buf = 0;
+ return ret;
}
devpriv->ai_cmd_running = 0;