Hi, > Here is the patch:
your mailer mangled the patch. > + if (num_bulk_out == 0) { > + dbg("Invalid interface, discarding.\n"); > + return -5; symbolic values are mandatory > + } > + return 0; > +} > + > + > + > +/* > + * Based on Generic_write and AIRcable Windows driver > + * Thanks Juergen Kienhoefer from AIRcable for the support, and > + * giving me access to their Windows Driver. > + */ > +int aircable_write(struct usb_serial_port *port, const unsigned char > *pSrcBuf, int count) > +{ > + struct usb_serial *serial = port->serial; > + unsigned char *pBuf; > + int result; > + unsigned long no_headers; > + unsigned long payload_length; > + unsigned long length; > + unsigned long i; > + unsigned long offset; > + unsigned long src_offset; > + > + dbg("%s - port %d", __FUNCTION__, port->number); > + > + if (count == 0) { > + dbg("%s - write request of 0 bytes", __FUNCTION__); > + return (0); no parentheses please > + } > + > + /* only do something if we have a bulk out endpoint */ > + if (serial->num_bulk_out) { > + if (port->write_urb->status == -EINPROGRESS) { this is a race condition, use a flag > + dbg("%s - already writing", __FUNCTION__); > + return (0); > + } > + > + dbg("Writting: %s", pSrcBuf); > + > + no_headers = (count / MAX_HCI_FRAMESIZE) + 1; > + > + pBuf = kmalloc(count + (no_headers *HCI_HEADER_LENGTH) , + > > GFP_KERNEL); You must check for an allocation failure here > + memset (pBuf, 0, count + (no_headers *HCI_HEADER_LENGTH + > )); > + > + payload_length = count; > + length = 0; > + > + for(i = 0; i < no_headers; i++) { > + if(payload_length >= MAX_HCI_FRAMESIZE) > + length = MAX_HCI_FRAMESIZE; > + else > + length = payload_length; > + payload_length -= length; > + > + offset = i * COMPLETE_PACKAGE; > + src_offset = i * MAX_HCI_FRAMESIZE; > + pBuf[offset] = HCI_HEADER_0; > + pBuf[offset+1] = HCI_HEADER_1; > + pBuf[offset+2] = (unsigned char) length; > + pBuf[offset+3] = (unsigned char)(length >> 8); We have macros for that > + memcpy(pBuf + offset + HCI_HEADER_LENGTH, + > pSrcBuf + > src_offset, length); > + } > + > + port->write_urb->transfer_buffer = pBuf; > + > + /* set up our urb */ > + usb_fill_bulk_urb (port->write_urb, serial->dev, > + usb_sndbulkpipe (serial->dev, + > > port->bulk_out_endpointAddress), > + port->write_urb->transfer_buffer, + > (count + > (no_headers + > *HCI_HEADER_LENGTH )), > + serial->type->write_bulk_callback, + > port); > + > + /* send the data out the bulk port */ > + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); No need for atomic > + > + if (result) > + dev_err(&port->dev, + > "%s - failed submitting write urb, > error %d\n", + __FUNCTION__, result); > + else > + result = count; > + > + return result; > + > + kfree(pBuf); > + } > + > + /* no bulk out, so return 0 bytes written */ > + return (0); > +} > + > +/* > + * This internal function simply drops the Header on every read, > + * It must only recive complete packages. > + */ > +void aircable_parse_read(struct tty_struct *tty, unsigned > char *data, + > int lenght) > +{ > + int i; > + if ( lenght > HCI_HEADER_LENGTH) { > + for (i = HCI_HEADER_LENGTH; i < lenght; i++) { > +/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ > + if(tty->flip.count >= TTY_FLIPBUF_SIZE) { > + tty_flip_buffer_push(tty); > + } > + > + /* this doesn't actually push the data through > + unless tty->low_latency is set */ > + tty_insert_flip_char(tty, data[i], 0); > + } > + } > +} > + > +void aircable_read_bulk_callback(struct urb *urb, struct pt_regs *regs) > +{ > + struct usb_serial_port *port = (struct usb_serial_port > + *)urb->context; > + struct usb_serial *serial = port->serial; > + struct tty_struct *tty; > + unsigned char *data; > + unsigned long no_packages; > + unsigned long remaining, package_length; > + unsigned long i; > + int result; > + > + dbg("%s - port %d", __FUNCTION__, port->number); > + > + if (urb->status) { > + dbg("%s - nonzero read bulk status received: %d", > + __FUNCTION__, urb->status); > + return; > + } > + > + usb_serial_debug_data(debug, &port->dev, __FUNCTION__, > + urb->actual_length, urb->transfer_buffer); > + > + tty = port->tty; > + if (tty && urb->actual_length) { > + //Does this package includes more information than the header??? > + if (urb->actual_length > HCI_HEADER_LENGTH) { > + remaining = urb->actual_length; > + > + no_packages = (urb->actual_length / > + COMPLETE_PACKAGE )+1; > + > + for (i = 0; i < no_packages ; ++i) { > + if (remaining > COMPLETE_PACKAGE) > + > + package_length = COMPLETE_PACKAGE; > + else > + package_length = remaining; > + > + > + remaining -= package_length; > + > + > + data = kmalloc(package_length, > + GFP_KERNEL); No. You are in interrupt. Preallocate a buffer if you can. If you cannot GFP_ATOMIC Regards Oliver Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel