static void airprime_close(struct usb_serial_port *port, struct file *filp) { struct airprime_private *priv = usb_get_serial_port_data(port); int i; dbg("%s - port %d", __func__, port->number); priv->rts_state = 0; priv->dtr_state = 0; mutex_lock(&port->serial->disc_mutex); if (!port->serial->disconnected) airprime_send_setup(port); mutex_unlock(&port->serial->disc_mutex); for (i = 0; i < NUM_READ_URBS; ++i) { usb_kill_urb(priv->read_urbp[i]); kfree(priv->read_urbp[i]->transfer_buffer); usb_free_urb(priv->read_urbp[i]); } /* free up private structure */ kfree(priv); usb_set_serial_port_data(port, NULL); }
static int airprime_open(struct usb_serial_port *port, struct file *filp) { struct airprime_private *priv = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; struct urb *urb; char *buffer = NULL; int i; int result = 0; dbg("%s - port %d", __FUNCTION__, port->number); /* initialize our private data structure if it isn't already created */ if (!priv) { priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { result = -ENOMEM; goto out; } spin_lock_init(&priv->lock); usb_set_serial_port_data(port, priv); } /* Set some sane defaults */ priv->rts_state = 1; priv->dtr_state = 1; for (i = 0; i < NUM_READ_URBS; ++i) { buffer = kmalloc(buffer_size, GFP_KERNEL); if (!buffer) { dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); result = -ENOMEM; goto errout; } urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { kfree(buffer); dev_err(&port->dev, "%s - no more urbs?\n", __FUNCTION__); result = -ENOMEM; goto errout; } usb_fill_bulk_urb(urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_out_endpointAddress), buffer, buffer_size, airprime_read_bulk_callback, port); result = usb_submit_urb(urb, GFP_KERNEL); if (result) { usb_free_urb(urb); kfree(buffer); dev_err(&port->dev, "%s - failed submitting read urb %d for port %d, error %d\n", __FUNCTION__, i, port->number, result); goto errout; } /* remember this urb so we can kill it when the port is closed */ priv->read_urbp[i] = urb; } airprime_send_setup(port); goto out; errout: /* some error happened, cancel any submitted urbs and clean up anything that got allocated successfully */ while (i-- != 0) { urb = priv->read_urbp[i]; buffer = urb->transfer_buffer; usb_kill_urb (urb); usb_free_urb (urb); kfree (buffer); } out: return result; }