diff options
| -rw-r--r-- | drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 61 | ||||
| -rw-r--r-- | drivers/net/can/usb/peak_usb/pcan_usb_pro.h | 1 |
2 files changed, 41 insertions, 21 deletions
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 30d79bfa5b10..8ee9d1556e6e 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c | |||
| @@ -504,15 +504,24 @@ static int pcan_usb_pro_restart_async(struct peak_usb_device *dev, | |||
| 504 | return usb_submit_urb(urb, GFP_ATOMIC); | 504 | return usb_submit_urb(urb, GFP_ATOMIC); |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | static void pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded) | 507 | static int pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded) |
| 508 | { | 508 | { |
| 509 | u8 buffer[16]; | 509 | u8 *buffer; |
| 510 | int err; | ||
| 511 | |||
| 512 | buffer = kmalloc(PCAN_USBPRO_FCT_DRVLD_REQ_LEN, GFP_KERNEL); | ||
| 513 | if (!buffer) | ||
| 514 | return -ENOMEM; | ||
| 510 | 515 | ||
| 511 | buffer[0] = 0; | 516 | buffer[0] = 0; |
| 512 | buffer[1] = !!loaded; | 517 | buffer[1] = !!loaded; |
| 513 | 518 | ||
| 514 | pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT, | 519 | err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT, |
| 515 | PCAN_USBPRO_FCT_DRVLD, buffer, sizeof(buffer)); | 520 | PCAN_USBPRO_FCT_DRVLD, buffer, |
| 521 | PCAN_USBPRO_FCT_DRVLD_REQ_LEN); | ||
| 522 | kfree(buffer); | ||
| 523 | |||
| 524 | return err; | ||
| 516 | } | 525 | } |
| 517 | 526 | ||
| 518 | static inline | 527 | static inline |
| @@ -851,21 +860,24 @@ static int pcan_usb_pro_stop(struct peak_usb_device *dev) | |||
| 851 | */ | 860 | */ |
| 852 | static int pcan_usb_pro_init(struct peak_usb_device *dev) | 861 | static int pcan_usb_pro_init(struct peak_usb_device *dev) |
| 853 | { | 862 | { |
| 854 | struct pcan_usb_pro_interface *usb_if; | ||
| 855 | struct pcan_usb_pro_device *pdev = | 863 | struct pcan_usb_pro_device *pdev = |
| 856 | container_of(dev, struct pcan_usb_pro_device, dev); | 864 | container_of(dev, struct pcan_usb_pro_device, dev); |
| 865 | struct pcan_usb_pro_interface *usb_if = NULL; | ||
| 866 | struct pcan_usb_pro_fwinfo *fi = NULL; | ||
| 867 | struct pcan_usb_pro_blinfo *bi = NULL; | ||
| 868 | int err; | ||
| 857 | 869 | ||
| 858 | /* do this for 1st channel only */ | 870 | /* do this for 1st channel only */ |
| 859 | if (!dev->prev_siblings) { | 871 | if (!dev->prev_siblings) { |
| 860 | struct pcan_usb_pro_fwinfo fi; | ||
| 861 | struct pcan_usb_pro_blinfo bi; | ||
| 862 | int err; | ||
| 863 | |||
| 864 | /* allocate netdevices common structure attached to first one */ | 872 | /* allocate netdevices common structure attached to first one */ |
| 865 | usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface), | 873 | usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface), |
| 866 | GFP_KERNEL); | 874 | GFP_KERNEL); |
| 867 | if (!usb_if) | 875 | fi = kmalloc(sizeof(struct pcan_usb_pro_fwinfo), GFP_KERNEL); |
| 868 | return -ENOMEM; | 876 | bi = kmalloc(sizeof(struct pcan_usb_pro_blinfo), GFP_KERNEL); |
| 877 | if (!usb_if || !fi || !bi) { | ||
| 878 | err = -ENOMEM; | ||
| 879 | goto err_out; | ||
| 880 | } | ||
| 869 | 881 | ||
| 870 | /* number of ts msgs to ignore before taking one into account */ | 882 | /* number of ts msgs to ignore before taking one into account */ |
| 871 | usb_if->cm_ignore_count = 5; | 883 | usb_if->cm_ignore_count = 5; |
| @@ -877,34 +889,34 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) | |||
| 877 | */ | 889 | */ |
| 878 | err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO, | 890 | err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO, |
| 879 | PCAN_USBPRO_INFO_FW, | 891 | PCAN_USBPRO_INFO_FW, |
| 880 | &fi, sizeof(fi)); | 892 | fi, sizeof(*fi)); |
| 881 | if (err) { | 893 | if (err) { |
| 882 | kfree(usb_if); | ||
| 883 | dev_err(dev->netdev->dev.parent, | 894 | dev_err(dev->netdev->dev.parent, |
| 884 | "unable to read %s firmware info (err %d)\n", | 895 | "unable to read %s firmware info (err %d)\n", |
| 885 | pcan_usb_pro.name, err); | 896 | pcan_usb_pro.name, err); |
| 886 | return err; | 897 | goto err_out; |
| 887 | } | 898 | } |
| 888 | 899 | ||
| 889 | err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO, | 900 | err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO, |
| 890 | PCAN_USBPRO_INFO_BL, | 901 | PCAN_USBPRO_INFO_BL, |
| 891 | &bi, sizeof(bi)); | 902 | bi, sizeof(*bi)); |
| 892 | if (err) { | 903 | if (err) { |
| 893 | kfree(usb_if); | ||
| 894 | dev_err(dev->netdev->dev.parent, | 904 | dev_err(dev->netdev->dev.parent, |
| 895 | "unable to read %s bootloader info (err %d)\n", | 905 | "unable to read %s bootloader info (err %d)\n", |
| 896 | pcan_usb_pro.name, err); | 906 | pcan_usb_pro.name, err); |
| 897 | return err; | 907 | goto err_out; |
| 898 | } | 908 | } |
| 899 | 909 | ||
| 910 | /* tell the device the can driver is running */ | ||
| 911 | err = pcan_usb_pro_drv_loaded(dev, 1); | ||
| 912 | if (err) | ||
| 913 | goto err_out; | ||
| 914 | |||
| 900 | dev_info(dev->netdev->dev.parent, | 915 | dev_info(dev->netdev->dev.parent, |
| 901 | "PEAK-System %s hwrev %u serial %08X.%08X (%u channels)\n", | 916 | "PEAK-System %s hwrev %u serial %08X.%08X (%u channels)\n", |
| 902 | pcan_usb_pro.name, | 917 | pcan_usb_pro.name, |
| 903 | bi.hw_rev, bi.serial_num_hi, bi.serial_num_lo, | 918 | bi->hw_rev, bi->serial_num_hi, bi->serial_num_lo, |
| 904 | pcan_usb_pro.ctrl_count); | 919 | pcan_usb_pro.ctrl_count); |
| 905 | |||
| 906 | /* tell the device the can driver is running */ | ||
| 907 | pcan_usb_pro_drv_loaded(dev, 1); | ||
| 908 | } else { | 920 | } else { |
| 909 | usb_if = pcan_usb_pro_dev_if(dev->prev_siblings); | 921 | usb_if = pcan_usb_pro_dev_if(dev->prev_siblings); |
| 910 | } | 922 | } |
| @@ -916,6 +928,13 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) | |||
| 916 | pcan_usb_pro_set_led(dev, 0, 1); | 928 | pcan_usb_pro_set_led(dev, 0, 1); |
| 917 | 929 | ||
| 918 | return 0; | 930 | return 0; |
| 931 | |||
| 932 | err_out: | ||
| 933 | kfree(bi); | ||
| 934 | kfree(fi); | ||
| 935 | kfree(usb_if); | ||
| 936 | |||
| 937 | return err; | ||
| 919 | } | 938 | } |
| 920 | 939 | ||
| 921 | static void pcan_usb_pro_exit(struct peak_usb_device *dev) | 940 | static void pcan_usb_pro_exit(struct peak_usb_device *dev) |
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h index a869918c5620..32275af547e0 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | /* Vendor Request value for XXX_FCT */ | 30 | /* Vendor Request value for XXX_FCT */ |
| 31 | #define PCAN_USBPRO_FCT_DRVLD 5 /* tell device driver is loaded */ | 31 | #define PCAN_USBPRO_FCT_DRVLD 5 /* tell device driver is loaded */ |
| 32 | #define PCAN_USBPRO_FCT_DRVLD_REQ_LEN 16 | ||
| 32 | 33 | ||
| 33 | /* PCAN_USBPRO_INFO_BL vendor request record type */ | 34 | /* PCAN_USBPRO_INFO_BL vendor request record type */ |
| 34 | struct __packed pcan_usb_pro_blinfo { | 35 | struct __packed pcan_usb_pro_blinfo { |
