Hi Alex, Nice job with this crappy hardware. Some comments on your driver below:
On Fri, Jul 20, 2007 at 04:21:53PM -0500, Alex Villacís Lasso wrote: > +/* Callback transmission routine */ > +static void ks959_speed_irq(struct urb *urb) > +{ > + /* unlink, shutdown, unplug, other nasties */ > + if (urb->status != 0) { > + err("ks959_speed_irq: urb asynchronously failed - %d", > urb->status); Here, shouldn't we call unlink_urb() if depending on the status value (in the -EINPROGRESS at least) ? > +static int ks959_change_speed(struct ks959_cb * kingsun, unsigned speed) > +{ > + static unsigned int supported_speeds[] = {2400, 9600, 19200, 38400, > + 57600, 115200, 576000, 1152000, 4000000, 0}; > + int err; > + unsigned int i; > + > + if (kingsun->speed_setuprequest == NULL || kingsun->speed_urb == NULL) > + return -ENOMEM; > + > + /* Check that requested speed is among the supported ones */ > + for (i = 0; supported_speeds[i] != 0 && supported_speeds[i] != speed; > i++); > + if (supported_speeds[i] == 0) return -EOPNOTSUPP; > + > + memset(&(kingsun->speedparams), 0, sizeof(struct ks959_speedparams)); > + kingsun->speedparams.baudrate = cpu_to_le32(speed); > + kingsun->speedparams.data_bits = 3; /* 8 data bits */ > + > + kingsun->speed_setuprequest->bRequestType = USB_DIR_OUT | > USB_TYPE_CLASS | USB_RECIP_INTERFACE; > + kingsun->speed_setuprequest->bRequest = KINGSUN_REQ_SEND; > + kingsun->speed_setuprequest->wValue = cpu_to_le16(0x0200); > + kingsun->speed_setuprequest->wIndex = cpu_to_le16(0x0001); > + kingsun->speed_setuprequest->wLength = cpu_to_le16(8); Any reason why we have to initialise the speed_setuprequest everytime ? Same question goes for tx_setuprequest and rx_setuprequest. > +static int ks959_probe(struct usb_interface *intf, > + const struct usb_device_id *id) > +{ > + struct usb_device *dev = interface_to_usbdev(intf); > + struct ks959_cb *kingsun = NULL; > + struct net_device *net = NULL; > + int ret = -ENOMEM; > + > + > + /* Allocate network device container. */ > + net = alloc_irdadev(sizeof(*kingsun)); > + if(!net) > + goto err_out1; > + > + SET_MODULE_OWNER(net); > + SET_NETDEV_DEV(net, &intf->dev); > + kingsun = netdev_priv(net); > + kingsun->netdev = net; > + kingsun->usbdev = dev; > + kingsun->irlap = NULL; > + kingsun->tx_setuprequest = NULL; > + kingsun->tx_urb = NULL; > + kingsun->tx_buf_clear = NULL; > + kingsun->tx_buf_xored = NULL; > + kingsun->tx_buf_clear_used = 0; > + kingsun->tx_buf_clear_sent = 0; > + > + kingsun->rx_setuprequest = NULL; > + kingsun->rx_urb = NULL; > + kingsun->rx_buf = NULL; > + kingsun->rx_variable_xormask = 0; > + kingsun->rx_unwrap_buff.in_frame = FALSE; > + kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; > + kingsun->rx_unwrap_buff.skb = NULL; > + kingsun->receiving = 0; > + spin_lock_init(&kingsun->lock); > + > + kingsun->speed_setuprequest = NULL; > + kingsun->speed_urb = NULL; > + kingsun->speedparams.baudrate = 0; > + > + /* Allocate input buffer */ > + kingsun->rx_buf = (__u8 *)kmalloc(KINGSUN_RCV_FIFO_SIZE, GFP_KERNEL); As Domen pointed out earlier, you don't need the cast here and in all the below kmalloc() calls. > + if (!kingsun->rx_buf) > + goto free_mem; > + > + /* Allocate input setup packet */ > + kingsun->rx_setuprequest = (struct usb_ctrlrequest > *)kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); > + if (!kingsun->rx_setuprequest) > + goto free_mem; > + > + /* Allocate output buffer */ > + kingsun->tx_buf_clear = (__u8 *)kmalloc(KINGSUN_SND_FIFO_SIZE, > GFP_KERNEL); > + if (!kingsun->tx_buf_clear) > + goto free_mem; > + kingsun->tx_buf_xored = (__u8 *)kmalloc(KINGSUN_SND_PACKET_SIZE, > GFP_KERNEL); > + if (!kingsun->tx_buf_xored) > + goto free_mem; > + > + /* Allocate output setup packet */ > + kingsun->tx_setuprequest = (struct usb_ctrlrequest > *)kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); > + if (!kingsun->tx_setuprequest) > + goto free_mem; > + > + /* Allocate speed setup packet */ > + kingsun->speed_setuprequest = (struct usb_ctrlrequest > *)kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); > + if (!kingsun->speed_setuprequest) > + goto free_mem; > + > + printk(KERN_INFO "KingSun KS-959 IRDA/USB found at address %d, " > + "Vendor: %x, Product: %x\n", > + dev->devnum, le16_to_cpu(dev->descriptor.idVendor), > + le16_to_cpu(dev->descriptor.idProduct)); > + > + /* Initialize QoS for this device */ > + irda_init_max_qos_capabilies(&kingsun->qos); > + > + /* Baud rates known to be supported. Please uncomment if devices (other > + than a Sony Ericcson K300 phone) can be shown to support higher > speeds > + with this dongle. > + */ > + kingsun->qos.baud_rate.bits = IR_2400 | IR_9600 | IR_19200 | IR_38400 > | IR_57600; > + kingsun->qos.min_turn_time.bits &= KINGSUN_MTT; > + irda_qos_bits_to_value(&kingsun->qos); > + > + /* Override the network functions we need to use */ > + net->hard_start_xmit = ks959_hard_xmit; > + net->open = ks959_net_open; > + net->stop = ks959_net_close; > + net->get_stats = ks959_net_get_stats; > + net->do_ioctl = ks959_net_ioctl; > + > + ret = register_netdev(net); > + if (ret != 0) > + goto free_mem; > + > + info("IrDA: Registered KingSun KS-959 device %s", net->name); > + > + usb_set_intfdata(intf, kingsun); > + > + /* Situation at this point: > + - all work buffers allocated > + - urbs not allocated, set to NULL > + - max rx packet known (is KINGSUN_FIFO_SIZE) > + - unwrap state machine (partially) initialized, but skb == NULL > + */ > + > + return 0; > + > +free_mem: > + if (kingsun->speed_setuprequest) kfree(kingsun->speed_setuprequest); > + if (kingsun->tx_setuprequest) kfree(kingsun->tx_setuprequest); > + if (kingsun->tx_buf_xored) kfree(kingsun->tx_buf_xored); > + if (kingsun->tx_buf_clear) kfree(kingsun->tx_buf_clear); > + if (kingsun->rx_setuprequest) kfree(kingsun->rx_setuprequest); > + if (kingsun->rx_buf) kfree(kingsun->rx_buf); You can pass a NULL pointer to kfree(). You also have quite many lines on your patch being longer than 80 chars. Mind fixing that as well ? Besides those minor comments, the patch looks good to me. Let's try to push it to netdev as soon as possible. Cheers, Samuel. ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel