static int pl2303_startup(struct usb_serial *serial) { struct pl2303_serial_private *spriv; enum pl2303_type type = type_0; unsigned char *buf; spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); if (!spriv) return -ENOMEM; buf = kmalloc(10, GFP_KERNEL); if (!buf) { kfree(spriv); return -ENOMEM; } if (serial->dev->descriptor.bDeviceClass == 0x02) type = type_0; else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) type = HX; else if (serial->dev->descriptor.bDeviceClass == 0x00) type = type_1; else if (serial->dev->descriptor.bDeviceClass == 0xFF) type = type_1; dev_dbg(&serial->interface->dev, "device type: %d\n", type); spriv->type = type; usb_set_serial_data(serial, spriv); pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_write(0x0404, 0, serial); pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_read(0x8383, 0, serial, buf); pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_write(0x0404, 1, serial); pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_read(0x8383, 0, serial, buf); pl2303_vendor_write(0, 1, serial); pl2303_vendor_write(1, 0, serial); if (type == HX) pl2303_vendor_write(2, 0x44, serial); else pl2303_vendor_write(2, 0x24, serial); kfree(buf); return 0; }
static int pl2303_startup(struct usb_serial *serial) { struct pl2303_serial_private *spriv; enum pl2303_type type = type_0; char *type_str = "unknown (treating as type_0)"; unsigned char *buf; spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); if (!spriv) return -ENOMEM; buf = kmalloc(10, GFP_KERNEL); if (!buf) { kfree(spriv); return -ENOMEM; } if (serial->dev->descriptor.bDeviceClass == 0x02) { type = type_0; type_str = "type_0"; } else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) { /* * NOTE: The bcdDevice version is the only difference between * the device descriptors of the X/HX, HXD, EA, RA, SA, TA, TB */ if (le16_to_cpu(serial->dev->descriptor.bcdDevice) == 0x300) { type = HX_TA; type_str = "X/HX/TA"; } else if (le16_to_cpu(serial->dev->descriptor.bcdDevice) == 0x400) { type = HXD_EA_RA_SA; type_str = "HXD/EA/RA/SA"; } else if (le16_to_cpu(serial->dev->descriptor.bcdDevice) == 0x500) { type = TB; type_str = "TB"; } else { dev_info(&serial->interface->dev, "unknown/unsupported device type\n"); kfree(spriv); kfree(buf); return -ENODEV; } } else if (serial->dev->descriptor.bDeviceClass == 0x00 || serial->dev->descriptor.bDeviceClass == 0xFF) { type = type_1; type_str = "type_1"; } dev_dbg(&serial->interface->dev, "device type: %s\n", type_str); spriv->type = type; usb_set_serial_data(serial, spriv); pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_write(0x0404, 0, serial); pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_read(0x8383, 0, serial, buf); pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_write(0x0404, 1, serial); pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_read(0x8383, 0, serial, buf); pl2303_vendor_write(0, 1, serial); pl2303_vendor_write(1, 0, serial); if (type == type_0 || type == type_1) pl2303_vendor_write(2, 0x24, serial); else pl2303_vendor_write(2, 0x44, serial); kfree(buf); return 0; }