+ if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
+ dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
+ goto alloc_fail7;
+ }
+
+ rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ rcv->instance = acm;
+ }
+ for (i = 0; i < ACM_NRB; i++) {
+ struct acm_rb *buf = &(acm->rb[i]);
+
+ // Using usb_buffer_alloc instead of kmalloc as Oliver suggested
+ if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
+ dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
+ goto alloc_fail7;
+ }
+ }
+ acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!acm->writeurb) {
+ dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n");
+ goto alloc_fail7;
+ }
+
+ usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress),
+ acm->ctrl_buffer, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
+ acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ acm->ctrlurb->transfer_dma = acm->ctrl_dma;
+
+ usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
+ NULL, acm->writesize, acm_write_bulk, acm);
+ acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
+
+ dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
+
+ acm_set_control(acm, acm->ctrlout);
+
+ acm->line.dwDTERate = cpu_to_le32(9600);
+ acm->line.bDataBits = 8;
+ acm_set_line(acm, &acm->line);
+
+ usb_driver_claim_interface(&acm_driver, data_interface, acm);
+
+ usb_get_intf(control_interface);
+ tty_register_device(acm_tty_driver, minor, &control_interface->dev);
+
+ acm_table[minor] = acm;
+ usb_set_intfdata (intf, acm);
+ return 0;
+
+alloc_fail7:
+ for (i = 0; i < ACM_NRB; i++)
+ usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
+ for (i = 0; i < ACM_NRU; i++)
+ usb_free_urb(acm->ru[i].urb);
+ usb_free_urb(acm->ctrlurb);
+alloc_fail5:
+ acm_write_buffers_free(acm);
+alloc_fail4:
+ usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
+alloc_fail2:
+ kfree(acm);
+alloc_fail:
+ return -ENOMEM;