Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'usb-3.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
"Here are some tiny USB fixes for 3.11-rc4

Nothing major, some gadget fixes, some new device ids, a new tiny
driver for the ANT+ USB device, and a number of fixes for the mos7840
driver that were much needed"

* tag 'usb-3.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
USB: serial: ftdi_sio: add more RT Systems ftdi devices
usb: chipidea: fix the build error with randconfig
usb: chipidea: cast PORTSC_PTS and DEVLC_PTS macros
usb: gadget: udc-core: fix the typo of udc state attribute
usb: gadget: f_phonet: remove unused preprocessor conditional
usb: gadget: multi: fix error return code in cdc_do_config()
USB: mos7840: fix pointer casts
USB: mos7840: fix race in led handling
USB: mos7840: fix device-type detection
USB: mos7840: fix race in register handling
USB: serial: add driver for Suunto ANT+ USB device
usb: gadget: free opts struct on error recovery
usb: gadget: ether: put_usb_function on unbind
usb: musb: fix resource passed from glue layer to musb

+223 -91
+2 -2
drivers/usb/chipidea/Kconfig
··· 12 12 13 13 config USB_CHIPIDEA_UDC 14 14 bool "ChipIdea device controller" 15 - depends on USB_GADGET=y || USB_CHIPIDEA=m 15 + depends on USB_GADGET=y || (USB_CHIPIDEA=m && USB_GADGET=m) 16 16 help 17 17 Say Y here to enable device controller functionality of the 18 18 ChipIdea driver. ··· 20 20 config USB_CHIPIDEA_HOST 21 21 bool "ChipIdea host controller" 22 22 depends on USB=y 23 - depends on USB_EHCI_HCD=y || USB_CHIPIDEA=m 23 + depends on USB_EHCI_HCD=y || (USB_CHIPIDEA=m && USB_EHCI_HCD=m) 24 24 select USB_EHCI_ROOT_HUB_TT 25 25 help 26 26 Say Y here to enable host controller functionality of the
+2 -2
drivers/usb/chipidea/bits.h
··· 50 50 #define PORTSC_PTC (0x0FUL << 16) 51 51 /* PTS and PTW for non lpm version only */ 52 52 #define PORTSC_PTS(d) \ 53 - ((((d) & 0x3) << 30) | (((d) & 0x4) ? BIT(25) : 0)) 53 + (u32)((((d) & 0x3) << 30) | (((d) & 0x4) ? BIT(25) : 0)) 54 54 #define PORTSC_PTW BIT(28) 55 55 #define PORTSC_STS BIT(29) 56 56 ··· 59 59 #define DEVLC_PSPD_HS (0x02UL << 25) 60 60 #define DEVLC_PTW BIT(27) 61 61 #define DEVLC_STS BIT(28) 62 - #define DEVLC_PTS(d) (((d) & 0x7) << 29) 62 + #define DEVLC_PTS(d) (u32)(((d) & 0x7) << 29) 63 63 64 64 /* Encoding for DEVLC_PTS and PORTSC_PTS */ 65 65 #define PTS_UTMI 0
+10 -4
drivers/usb/gadget/ether.c
··· 449 449 450 450 static int __exit eth_unbind(struct usb_composite_dev *cdev) 451 451 { 452 - if (has_rndis()) 452 + if (has_rndis()) { 453 + usb_put_function(f_rndis); 453 454 usb_put_function_instance(fi_rndis); 454 - if (use_eem) 455 + } 456 + if (use_eem) { 457 + usb_put_function(f_eem); 455 458 usb_put_function_instance(fi_eem); 456 - else if (can_support_ecm(cdev->gadget)) 459 + } else if (can_support_ecm(cdev->gadget)) { 460 + usb_put_function(f_ecm); 457 461 usb_put_function_instance(fi_ecm); 458 - else 462 + } else { 463 + usb_put_function(f_geth); 459 464 usb_put_function_instance(fi_geth); 465 + } 460 466 return 0; 461 467 } 462 468
-2
drivers/usb/gadget/f_phonet.c
··· 488 488 struct usb_ep *ep; 489 489 int status, i; 490 490 491 - #ifndef USBF_PHONET_INCLUDED 492 491 struct f_phonet_opts *phonet_opts; 493 492 494 493 phonet_opts = container_of(f->fi, struct f_phonet_opts, func_inst); ··· 506 507 return status; 507 508 phonet_opts->bound = true; 508 509 } 509 - #endif 510 510 511 511 /* Reserve interface IDs */ 512 512 status = usb_interface_id(c, f);
+3 -7
drivers/usb/gadget/multi.c
··· 160 160 return ret; 161 161 162 162 f_acm_rndis = usb_get_function(fi_acm); 163 - if (IS_ERR(f_acm_rndis)) { 164 - ret = PTR_ERR(f_acm_rndis); 165 - goto err_func_acm; 166 - } 163 + if (IS_ERR(f_acm_rndis)) 164 + return PTR_ERR(f_acm_rndis); 167 165 168 166 ret = usb_add_function(c, f_acm_rndis); 169 167 if (ret) ··· 176 178 usb_remove_function(c, f_acm_rndis); 177 179 err_conf: 178 180 usb_put_function(f_acm_rndis); 179 - err_func_acm: 180 181 return ret; 181 182 } 182 183 ··· 223 226 /* implicit port_num is zero */ 224 227 f_acm_multi = usb_get_function(fi_acm); 225 228 if (IS_ERR(f_acm_multi)) 226 - goto err_func_acm; 229 + return PTR_ERR(f_acm_multi); 227 230 228 231 ret = usb_add_function(c, f_acm_multi); 229 232 if (ret) ··· 238 241 usb_remove_function(c, f_acm_multi); 239 242 err_conf: 240 243 usb_put_function(f_acm_multi); 241 - err_func_acm: 242 244 return ret; 243 245 } 244 246
+1 -1
drivers/usb/gadget/udc-core.c
··· 109 109 enum usb_device_state state) 110 110 { 111 111 gadget->state = state; 112 - sysfs_notify(&gadget->dev.kobj, NULL, "status"); 112 + sysfs_notify(&gadget->dev.kobj, NULL, "state"); 113 113 } 114 114 EXPORT_SYMBOL_GPL(usb_gadget_set_state); 115 115
+6 -1
drivers/usb/musb/omap2430.c
··· 481 481 482 482 static int omap2430_probe(struct platform_device *pdev) 483 483 { 484 - struct resource musb_resources[2]; 484 + struct resource musb_resources[3]; 485 485 struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; 486 486 struct omap_musb_board_data *data; 487 487 struct platform_device *musb; ··· 580 580 musb_resources[1].start = pdev->resource[1].start; 581 581 musb_resources[1].end = pdev->resource[1].end; 582 582 musb_resources[1].flags = pdev->resource[1].flags; 583 + 584 + musb_resources[2].name = pdev->resource[2].name; 585 + musb_resources[2].start = pdev->resource[2].start; 586 + musb_resources[2].end = pdev->resource[2].end; 587 + musb_resources[2].flags = pdev->resource[2].flags; 583 588 584 589 ret = platform_device_add_resources(musb, musb_resources, 585 590 ARRAY_SIZE(musb_resources));
+6 -1
drivers/usb/musb/tusb6010.c
··· 1156 1156 1157 1157 static int tusb_probe(struct platform_device *pdev) 1158 1158 { 1159 - struct resource musb_resources[2]; 1159 + struct resource musb_resources[3]; 1160 1160 struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; 1161 1161 struct platform_device *musb; 1162 1162 struct tusb6010_glue *glue; ··· 1198 1198 musb_resources[1].start = pdev->resource[1].start; 1199 1199 musb_resources[1].end = pdev->resource[1].end; 1200 1200 musb_resources[1].flags = pdev->resource[1].flags; 1201 + 1202 + musb_resources[2].name = pdev->resource[2].name; 1203 + musb_resources[2].start = pdev->resource[2].start; 1204 + musb_resources[2].end = pdev->resource[2].end; 1205 + musb_resources[2].flags = pdev->resource[2].flags; 1201 1206 1202 1207 ret = platform_device_add_resources(musb, musb_resources, 1203 1208 ARRAY_SIZE(musb_resources));
+7
drivers/usb/serial/Kconfig
··· 719 719 To compile this driver as a module, choose M here: the 720 720 module will be called flashloader. 721 721 722 + config USB_SERIAL_SUUNTO 723 + tristate "USB Suunto ANT+ driver" 724 + help 725 + Say Y here if you want to use the Suunto ANT+ USB device. 726 + 727 + To compile this driver as a module, choose M here: the 728 + module will be called suunto. 722 729 723 730 config USB_SERIAL_DEBUG 724 731 tristate "USB Debugging Device"
+1
drivers/usb/serial/Makefile
··· 54 54 obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o 55 55 obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o 56 56 obj-$(CONFIG_USB_SERIAL_SSU100) += ssu100.o 57 + obj-$(CONFIG_USB_SERIAL_SUUNTO) += suunto.o 57 58 obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o 58 59 obj-$(CONFIG_USB_SERIAL_WWAN) += usb_wwan.o 59 60 obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o
+28 -3
drivers/usb/serial/ftdi_sio.c
··· 735 735 { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), 736 736 .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, 737 737 { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, 738 - { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) }, 739 - { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) }, 740 - { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_RTS01_PID) }, 738 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S03_PID) }, 739 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_59_PID) }, 740 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57A_PID) }, 741 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57B_PID) }, 742 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29A_PID) }, 743 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29B_PID) }, 744 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29F_PID) }, 745 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62B_PID) }, 746 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S01_PID) }, 747 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63_PID) }, 748 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29C_PID) }, 749 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_81B_PID) }, 750 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_82B_PID) }, 751 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5D_PID) }, 752 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K4Y_PID) }, 753 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5G_PID) }, 754 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S05_PID) }, 755 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_60_PID) }, 756 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_61_PID) }, 757 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62_PID) }, 758 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63B_PID) }, 759 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_64_PID) }, 760 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_65_PID) }, 761 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92_PID) }, 762 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92D_PID) }, 763 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_W5R_PID) }, 764 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_A5R_PID) }, 765 + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_PW1_PID) }, 741 766 { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, 742 767 { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, 743 768 { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
+29 -5
drivers/usb/serial/ftdi_sio_ids.h
··· 815 815 /* 816 816 * RT Systems programming cables for various ham radios 817 817 */ 818 - #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ 819 - #define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */ 820 - #define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */ 821 - #define RTSYSTEMS_RTS01_PID 0x9e57 /* USB-RTS01 Radio Cable */ 822 - 818 + #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ 819 + #define RTSYSTEMS_USB_S03_PID 0x9001 /* RTS-03 USB to Serial Adapter */ 820 + #define RTSYSTEMS_USB_59_PID 0x9e50 /* USB-59 USB to 8 pin plug */ 821 + #define RTSYSTEMS_USB_57A_PID 0x9e51 /* USB-57A USB to 4pin 3.5mm plug */ 822 + #define RTSYSTEMS_USB_57B_PID 0x9e52 /* USB-57B USB to extended 4pin 3.5mm plug */ 823 + #define RTSYSTEMS_USB_29A_PID 0x9e53 /* USB-29A USB to 3.5mm stereo plug */ 824 + #define RTSYSTEMS_USB_29B_PID 0x9e54 /* USB-29B USB to 6 pin mini din */ 825 + #define RTSYSTEMS_USB_29F_PID 0x9e55 /* USB-29F USB to 6 pin modular plug */ 826 + #define RTSYSTEMS_USB_62B_PID 0x9e56 /* USB-62B USB to 8 pin mini din plug*/ 827 + #define RTSYSTEMS_USB_S01_PID 0x9e57 /* USB-RTS01 USB to 3.5 mm stereo plug*/ 828 + #define RTSYSTEMS_USB_63_PID 0x9e58 /* USB-63 USB to 9 pin female*/ 829 + #define RTSYSTEMS_USB_29C_PID 0x9e59 /* USB-29C USB to 4 pin modular plug*/ 830 + #define RTSYSTEMS_USB_81B_PID 0x9e5A /* USB-81 USB to 8 pin mini din plug*/ 831 + #define RTSYSTEMS_USB_82B_PID 0x9e5B /* USB-82 USB to 2.5 mm stereo plug*/ 832 + #define RTSYSTEMS_USB_K5D_PID 0x9e5C /* USB-K5D USB to 8 pin modular plug*/ 833 + #define RTSYSTEMS_USB_K4Y_PID 0x9e5D /* USB-K4Y USB to 2.5/3.5 mm plugs*/ 834 + #define RTSYSTEMS_USB_K5G_PID 0x9e5E /* USB-K5G USB to 8 pin modular plug*/ 835 + #define RTSYSTEMS_USB_S05_PID 0x9e5F /* USB-RTS05 USB to 2.5 mm stereo plug*/ 836 + #define RTSYSTEMS_USB_60_PID 0x9e60 /* USB-60 USB to 6 pin din*/ 837 + #define RTSYSTEMS_USB_61_PID 0x9e61 /* USB-61 USB to 6 pin mini din*/ 838 + #define RTSYSTEMS_USB_62_PID 0x9e62 /* USB-62 USB to 8 pin mini din*/ 839 + #define RTSYSTEMS_USB_63B_PID 0x9e63 /* USB-63 USB to 9 pin female*/ 840 + #define RTSYSTEMS_USB_64_PID 0x9e64 /* USB-64 USB to 9 pin male*/ 841 + #define RTSYSTEMS_USB_65_PID 0x9e65 /* USB-65 USB to 9 pin female null modem*/ 842 + #define RTSYSTEMS_USB_92_PID 0x9e66 /* USB-92 USB to 12 pin plug*/ 843 + #define RTSYSTEMS_USB_92D_PID 0x9e67 /* USB-92D USB to 12 pin plug data*/ 844 + #define RTSYSTEMS_USB_W5R_PID 0x9e68 /* USB-W5R USB to 8 pin modular plug*/ 845 + #define RTSYSTEMS_USB_A5R_PID 0x9e69 /* USB-A5R USB to 8 pin modular plug*/ 846 + #define RTSYSTEMS_USB_PW1_PID 0x9e6A /* USB-PW1 USB to 8 pin modular plug*/ 823 847 824 848 /* 825 849 * Physik Instrumente
+87 -63
drivers/usb/serial/mos7840.c
··· 183 183 #define LED_ON_MS 500 184 184 #define LED_OFF_MS 500 185 185 186 - static int device_type; 186 + enum mos7840_flag { 187 + MOS7840_FLAG_CTRL_BUSY, 188 + MOS7840_FLAG_LED_BUSY, 189 + }; 187 190 188 191 static const struct usb_device_id id_table[] = { 189 192 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, ··· 241 238 242 239 /* For device(s) with LED indicator */ 243 240 bool has_led; 244 - bool led_flag; 245 241 struct timer_list led_timer1; /* Timer for LED on */ 246 242 struct timer_list led_timer2; /* Timer for LED off */ 243 + struct urb *led_urb; 244 + struct usb_ctrlrequest *led_dr; 245 + 246 + unsigned long flags; 247 247 }; 248 248 249 249 /* ··· 466 460 case -ESHUTDOWN: 467 461 /* this urb is terminated, clean up */ 468 462 dev_dbg(dev, "%s - urb shutting down with status: %d\n", __func__, status); 469 - return; 463 + goto out; 470 464 default: 471 465 dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status); 472 - return; 466 + goto out; 473 467 } 474 468 475 469 dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length); ··· 482 476 mos7840_handle_new_msr(mos7840_port, regval); 483 477 else if (mos7840_port->MsrLsr == 1) 484 478 mos7840_handle_new_lsr(mos7840_port, regval); 479 + out: 480 + clear_bit_unlock(MOS7840_FLAG_CTRL_BUSY, &mos7840_port->flags); 485 481 } 486 482 487 483 static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, ··· 493 485 struct usb_ctrlrequest *dr = mcs->dr; 494 486 unsigned char *buffer = mcs->ctrl_buf; 495 487 int ret; 488 + 489 + if (test_and_set_bit_lock(MOS7840_FLAG_CTRL_BUSY, &mcs->flags)) 490 + return -EBUSY; 496 491 497 492 dr->bRequestType = MCS_RD_RTYPE; 498 493 dr->bRequest = MCS_RDREQ; ··· 508 497 mos7840_control_callback, mcs); 509 498 mcs->control_urb->transfer_buffer_length = 2; 510 499 ret = usb_submit_urb(mcs->control_urb, GFP_ATOMIC); 500 + if (ret) 501 + clear_bit_unlock(MOS7840_FLAG_CTRL_BUSY, &mcs->flags); 502 + 511 503 return ret; 512 504 } 513 505 ··· 537 523 __u16 reg) 538 524 { 539 525 struct usb_device *dev = mcs->port->serial->dev; 540 - struct usb_ctrlrequest *dr = mcs->dr; 526 + struct usb_ctrlrequest *dr = mcs->led_dr; 541 527 542 528 dr->bRequestType = MCS_WR_RTYPE; 543 529 dr->bRequest = MCS_WRREQ; ··· 545 531 dr->wIndex = cpu_to_le16(reg); 546 532 dr->wLength = cpu_to_le16(0); 547 533 548 - usb_fill_control_urb(mcs->control_urb, dev, usb_sndctrlpipe(dev, 0), 534 + usb_fill_control_urb(mcs->led_urb, dev, usb_sndctrlpipe(dev, 0), 549 535 (unsigned char *)dr, NULL, 0, mos7840_set_led_callback, NULL); 550 536 551 - usb_submit_urb(mcs->control_urb, GFP_ATOMIC); 537 + usb_submit_urb(mcs->led_urb, GFP_ATOMIC); 552 538 } 553 539 554 540 static void mos7840_set_led_sync(struct usb_serial_port *port, __u16 reg, ··· 574 560 { 575 561 struct moschip_port *mcs = (struct moschip_port *) arg; 576 562 577 - mcs->led_flag = false; 563 + clear_bit_unlock(MOS7840_FLAG_LED_BUSY, &mcs->flags); 564 + } 565 + 566 + static void mos7840_led_activity(struct usb_serial_port *port) 567 + { 568 + struct moschip_port *mos7840_port = usb_get_serial_port_data(port); 569 + 570 + if (test_and_set_bit_lock(MOS7840_FLAG_LED_BUSY, &mos7840_port->flags)) 571 + return; 572 + 573 + mos7840_set_led_async(mos7840_port, 0x0301, MODEM_CONTROL_REGISTER); 574 + mod_timer(&mos7840_port->led_timer1, 575 + jiffies + msecs_to_jiffies(LED_ON_MS)); 578 576 } 579 577 580 578 /***************************************************************************** ··· 784 758 return; 785 759 } 786 760 787 - /* Turn on LED */ 788 - if (mos7840_port->has_led && !mos7840_port->led_flag) { 789 - mos7840_port->led_flag = true; 790 - mos7840_set_led_async(mos7840_port, 0x0301, 791 - MODEM_CONTROL_REGISTER); 792 - mod_timer(&mos7840_port->led_timer1, 793 - jiffies + msecs_to_jiffies(LED_ON_MS)); 794 - } 761 + if (mos7840_port->has_led) 762 + mos7840_led_activity(port); 795 763 796 764 mos7840_port->read_urb_busy = true; 797 765 retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); ··· 836 816 /************************************************************************/ 837 817 /* D R I V E R T T Y I N T E R F A C E F U N C T I O N S */ 838 818 /************************************************************************/ 839 - #ifdef MCSSerialProbe 840 - static int mos7840_serial_probe(struct usb_serial *serial, 841 - const struct usb_device_id *id) 842 - { 843 - 844 - /*need to implement the mode_reg reading and updating\ 845 - structures usb_serial_ device_type\ 846 - (i.e num_ports, num_bulkin,bulkout etc) */ 847 - /* Also we can update the changes attach */ 848 - return 1; 849 - } 850 - #endif 851 819 852 820 /***************************************************************************** 853 821 * mos7840_open ··· 1462 1454 data1 = urb->transfer_buffer; 1463 1455 dev_dbg(&port->dev, "bulkout endpoint is %d\n", port->bulk_out_endpointAddress); 1464 1456 1465 - /* Turn on LED */ 1466 - if (mos7840_port->has_led && !mos7840_port->led_flag) { 1467 - mos7840_port->led_flag = true; 1468 - mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0301); 1469 - mod_timer(&mos7840_port->led_timer1, 1470 - jiffies + msecs_to_jiffies(LED_ON_MS)); 1471 - } 1457 + if (mos7840_port->has_led) 1458 + mos7840_led_activity(port); 1472 1459 1473 1460 /* send it down the pipe */ 1474 1461 status = usb_submit_urb(urb, GFP_ATOMIC); ··· 2190 2187 return 0; 2191 2188 } 2192 2189 2193 - static int mos7840_calc_num_ports(struct usb_serial *serial) 2190 + static int mos7840_probe(struct usb_serial *serial, 2191 + const struct usb_device_id *id) 2194 2192 { 2195 - __u16 data = 0x00; 2193 + u16 product = serial->dev->descriptor.idProduct; 2196 2194 u8 *buf; 2197 - int mos7840_num_ports; 2195 + int device_type; 2196 + 2197 + if (product == MOSCHIP_DEVICE_ID_7810 || 2198 + product == MOSCHIP_DEVICE_ID_7820) { 2199 + device_type = product; 2200 + goto out; 2201 + } 2198 2202 2199 2203 buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL); 2200 - if (buf) { 2201 - usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 2204 + if (!buf) 2205 + return -ENOMEM; 2206 + 2207 + usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 2202 2208 MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf, 2203 2209 VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); 2204 - data = *buf; 2205 - kfree(buf); 2206 - } 2207 2210 2208 - if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 || 2209 - serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) { 2210 - device_type = serial->dev->descriptor.idProduct; 2211 - } else { 2212 - /* For a MCS7840 device GPIO0 must be set to 1 */ 2213 - if ((data & 0x01) == 1) 2214 - device_type = MOSCHIP_DEVICE_ID_7840; 2215 - else if (mos7810_check(serial)) 2216 - device_type = MOSCHIP_DEVICE_ID_7810; 2217 - else 2218 - device_type = MOSCHIP_DEVICE_ID_7820; 2219 - } 2211 + /* For a MCS7840 device GPIO0 must be set to 1 */ 2212 + if (buf[0] & 0x01) 2213 + device_type = MOSCHIP_DEVICE_ID_7840; 2214 + else if (mos7810_check(serial)) 2215 + device_type = MOSCHIP_DEVICE_ID_7810; 2216 + else 2217 + device_type = MOSCHIP_DEVICE_ID_7820; 2218 + 2219 + kfree(buf); 2220 + out: 2221 + usb_set_serial_data(serial, (void *)(unsigned long)device_type); 2222 + 2223 + return 0; 2224 + } 2225 + 2226 + static int mos7840_calc_num_ports(struct usb_serial *serial) 2227 + { 2228 + int device_type = (unsigned long)usb_get_serial_data(serial); 2229 + int mos7840_num_ports; 2220 2230 2221 2231 mos7840_num_ports = (device_type >> 4) & 0x000F; 2222 - serial->num_bulk_in = mos7840_num_ports; 2223 - serial->num_bulk_out = mos7840_num_ports; 2224 - serial->num_ports = mos7840_num_ports; 2225 2232 2226 2233 return mos7840_num_ports; 2227 2234 } ··· 2239 2226 static int mos7840_port_probe(struct usb_serial_port *port) 2240 2227 { 2241 2228 struct usb_serial *serial = port->serial; 2229 + int device_type = (unsigned long)usb_get_serial_data(serial); 2242 2230 struct moschip_port *mos7840_port; 2243 2231 int status; 2244 2232 int pnum; ··· 2415 2401 if (device_type == MOSCHIP_DEVICE_ID_7810) { 2416 2402 mos7840_port->has_led = true; 2417 2403 2404 + mos7840_port->led_urb = usb_alloc_urb(0, GFP_KERNEL); 2405 + mos7840_port->led_dr = kmalloc(sizeof(*mos7840_port->led_dr), 2406 + GFP_KERNEL); 2407 + if (!mos7840_port->led_urb || !mos7840_port->led_dr) { 2408 + status = -ENOMEM; 2409 + goto error; 2410 + } 2411 + 2418 2412 init_timer(&mos7840_port->led_timer1); 2419 2413 mos7840_port->led_timer1.function = mos7840_led_off; 2420 2414 mos7840_port->led_timer1.expires = ··· 2434 2412 mos7840_port->led_timer2.expires = 2435 2413 jiffies + msecs_to_jiffies(LED_OFF_MS); 2436 2414 mos7840_port->led_timer2.data = (unsigned long)mos7840_port; 2437 - 2438 - mos7840_port->led_flag = false; 2439 2415 2440 2416 /* Turn off LED */ 2441 2417 mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); ··· 2456 2436 } 2457 2437 return 0; 2458 2438 error: 2439 + kfree(mos7840_port->led_dr); 2440 + usb_free_urb(mos7840_port->led_urb); 2459 2441 kfree(mos7840_port->dr); 2460 2442 kfree(mos7840_port->ctrl_buf); 2461 2443 usb_free_urb(mos7840_port->control_urb); ··· 2478 2456 2479 2457 del_timer_sync(&mos7840_port->led_timer1); 2480 2458 del_timer_sync(&mos7840_port->led_timer2); 2459 + 2460 + usb_kill_urb(mos7840_port->led_urb); 2461 + usb_free_urb(mos7840_port->led_urb); 2462 + kfree(mos7840_port->led_dr); 2481 2463 } 2482 2464 usb_kill_urb(mos7840_port->control_urb); 2483 2465 usb_free_urb(mos7840_port->control_urb); ··· 2508 2482 .throttle = mos7840_throttle, 2509 2483 .unthrottle = mos7840_unthrottle, 2510 2484 .calc_num_ports = mos7840_calc_num_ports, 2511 - #ifdef MCSSerialProbe 2512 - .probe = mos7840_serial_probe, 2513 - #endif 2485 + .probe = mos7840_probe, 2514 2486 .ioctl = mos7840_ioctl, 2515 2487 .set_termios = mos7840_set_termios, 2516 2488 .break_ctl = mos7840_break,
+41
drivers/usb/serial/suunto.c
··· 1 + /* 2 + * Suunto ANT+ USB Driver 3 + * 4 + * Copyright (C) 2013 Greg Kroah-Hartman <gregkh@linuxfoundation.org> 5 + * Copyright (C) 2013 Linux Foundation 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published by 9 + * the Free Software Foundation only. 10 + */ 11 + 12 + #include <linux/kernel.h> 13 + #include <linux/init.h> 14 + #include <linux/tty.h> 15 + #include <linux/module.h> 16 + #include <linux/usb.h> 17 + #include <linux/usb/serial.h> 18 + #include <linux/uaccess.h> 19 + 20 + static const struct usb_device_id id_table[] = { 21 + { USB_DEVICE(0x0fcf, 0x1008) }, 22 + { }, 23 + }; 24 + MODULE_DEVICE_TABLE(usb, id_table); 25 + 26 + static struct usb_serial_driver suunto_device = { 27 + .driver = { 28 + .owner = THIS_MODULE, 29 + .name = KBUILD_MODNAME, 30 + }, 31 + .id_table = id_table, 32 + .num_ports = 1, 33 + }; 34 + 35 + static struct usb_serial_driver * const serial_drivers[] = { 36 + &suunto_device, 37 + NULL, 38 + }; 39 + 40 + module_usb_serial_driver(serial_drivers, id_table); 41 + MODULE_LICENSE("GPL");