diff options
Diffstat (limited to 'drivers/usb/serial/sierra.c')
| -rw-r--r-- | drivers/usb/serial/sierra.c | 133 |
1 files changed, 68 insertions, 65 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 01d882cf3775..270860f6bb2a 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
| @@ -161,7 +161,6 @@ static int sierra_probe(struct usb_serial *serial, | |||
| 161 | { | 161 | { |
| 162 | int result = 0; | 162 | int result = 0; |
| 163 | struct usb_device *udev; | 163 | struct usb_device *udev; |
| 164 | struct sierra_intf_private *data; | ||
| 165 | u8 ifnum; | 164 | u8 ifnum; |
| 166 | 165 | ||
| 167 | udev = serial->dev; | 166 | udev = serial->dev; |
| @@ -188,11 +187,6 @@ static int sierra_probe(struct usb_serial *serial, | |||
| 188 | return -ENODEV; | 187 | return -ENODEV; |
| 189 | } | 188 | } |
| 190 | 189 | ||
| 191 | data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); | ||
| 192 | if (!data) | ||
| 193 | return -ENOMEM; | ||
| 194 | spin_lock_init(&data->susp_lock); | ||
| 195 | |||
| 196 | return result; | 190 | return result; |
| 197 | } | 191 | } |
| 198 | 192 | ||
| @@ -884,11 +878,15 @@ static void sierra_dtr_rts(struct usb_serial_port *port, int on) | |||
| 884 | 878 | ||
| 885 | static int sierra_startup(struct usb_serial *serial) | 879 | static int sierra_startup(struct usb_serial *serial) |
| 886 | { | 880 | { |
| 887 | struct usb_serial_port *port; | 881 | struct sierra_intf_private *intfdata; |
| 888 | struct sierra_port_private *portdata; | 882 | |
| 889 | struct sierra_iface_info *himemoryp = NULL; | 883 | intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL); |
| 890 | int i; | 884 | if (!intfdata) |
| 891 | u8 ifnum; | 885 | return -ENOMEM; |
| 886 | |||
| 887 | spin_lock_init(&intfdata->susp_lock); | ||
| 888 | |||
| 889 | usb_set_serial_data(serial, intfdata); | ||
| 892 | 890 | ||
| 893 | /* Set Device mode to D0 */ | 891 | /* Set Device mode to D0 */ |
| 894 | sierra_set_power_state(serial->dev, 0x0000); | 892 | sierra_set_power_state(serial->dev, 0x0000); |
| @@ -897,68 +895,71 @@ static int sierra_startup(struct usb_serial *serial) | |||
| 897 | if (nmea) | 895 | if (nmea) |
| 898 | sierra_vsc_set_nmea(serial->dev, 1); | 896 | sierra_vsc_set_nmea(serial->dev, 1); |
| 899 | 897 | ||
| 900 | /* Now setup per port private data */ | ||
| 901 | for (i = 0; i < serial->num_ports; i++) { | ||
| 902 | port = serial->port[i]; | ||
| 903 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | ||
| 904 | if (!portdata) { | ||
| 905 | dev_dbg(&port->dev, "%s: kmalloc for " | ||
| 906 | "sierra_port_private (%d) failed!\n", | ||
| 907 | __func__, i); | ||
| 908 | return -ENOMEM; | ||
| 909 | } | ||
| 910 | spin_lock_init(&portdata->lock); | ||
| 911 | init_usb_anchor(&portdata->active); | ||
| 912 | init_usb_anchor(&portdata->delayed); | ||
| 913 | ifnum = i; | ||
| 914 | /* Assume low memory requirements */ | ||
| 915 | portdata->num_out_urbs = N_OUT_URB; | ||
| 916 | portdata->num_in_urbs = N_IN_URB; | ||
| 917 | |||
| 918 | /* Determine actual memory requirements */ | ||
| 919 | if (serial->num_ports == 1) { | ||
| 920 | /* Get interface number for composite device */ | ||
| 921 | ifnum = sierra_calc_interface(serial); | ||
| 922 | himemoryp = | ||
| 923 | (struct sierra_iface_info *)&typeB_interface_list; | ||
| 924 | if (is_himemory(ifnum, himemoryp)) { | ||
| 925 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
| 926 | portdata->num_in_urbs = N_IN_URB_HM; | ||
| 927 | } | ||
| 928 | } | ||
| 929 | else { | ||
| 930 | himemoryp = | ||
| 931 | (struct sierra_iface_info *)&typeA_interface_list; | ||
| 932 | if (is_himemory(i, himemoryp)) { | ||
| 933 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
| 934 | portdata->num_in_urbs = N_IN_URB_HM; | ||
| 935 | } | ||
| 936 | } | ||
| 937 | dev_dbg(&serial->dev->dev, | ||
| 938 | "Memory usage (urbs) interface #%d, in=%d, out=%d\n", | ||
| 939 | ifnum,portdata->num_in_urbs, portdata->num_out_urbs ); | ||
| 940 | /* Set the port private data pointer */ | ||
| 941 | usb_set_serial_port_data(port, portdata); | ||
| 942 | } | ||
| 943 | |||
| 944 | return 0; | 898 | return 0; |
| 945 | } | 899 | } |
| 946 | 900 | ||
| 947 | static void sierra_release(struct usb_serial *serial) | 901 | static void sierra_release(struct usb_serial *serial) |
| 948 | { | 902 | { |
| 949 | int i; | 903 | struct sierra_intf_private *intfdata; |
| 950 | struct usb_serial_port *port; | 904 | |
| 905 | intfdata = usb_get_serial_data(serial); | ||
| 906 | kfree(intfdata); | ||
| 907 | } | ||
| 908 | |||
| 909 | static int sierra_port_probe(struct usb_serial_port *port) | ||
| 910 | { | ||
| 911 | struct usb_serial *serial = port->serial; | ||
| 951 | struct sierra_port_private *portdata; | 912 | struct sierra_port_private *portdata; |
| 913 | const struct sierra_iface_info *himemoryp; | ||
| 914 | u8 ifnum; | ||
| 952 | 915 | ||
| 953 | for (i = 0; i < serial->num_ports; ++i) { | 916 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); |
| 954 | port = serial->port[i]; | 917 | if (!portdata) |
| 955 | if (!port) | 918 | return -ENOMEM; |
| 956 | continue; | 919 | |
| 957 | portdata = usb_get_serial_port_data(port); | 920 | spin_lock_init(&portdata->lock); |
| 958 | if (!portdata) | 921 | init_usb_anchor(&portdata->active); |
| 959 | continue; | 922 | init_usb_anchor(&portdata->delayed); |
| 960 | kfree(portdata); | 923 | |
| 924 | /* Assume low memory requirements */ | ||
| 925 | portdata->num_out_urbs = N_OUT_URB; | ||
| 926 | portdata->num_in_urbs = N_IN_URB; | ||
| 927 | |||
| 928 | /* Determine actual memory requirements */ | ||
| 929 | if (serial->num_ports == 1) { | ||
| 930 | /* Get interface number for composite device */ | ||
| 931 | ifnum = sierra_calc_interface(serial); | ||
| 932 | himemoryp = &typeB_interface_list; | ||
| 933 | } else { | ||
| 934 | /* This is really the usb-serial port number of the interface | ||
| 935 | * rather than the interface number. | ||
| 936 | */ | ||
| 937 | ifnum = port->number - serial->minor; | ||
| 938 | himemoryp = &typeA_interface_list; | ||
| 961 | } | 939 | } |
| 940 | |||
| 941 | if (is_himemory(ifnum, himemoryp)) { | ||
| 942 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
| 943 | portdata->num_in_urbs = N_IN_URB_HM; | ||
| 944 | } | ||
| 945 | |||
| 946 | dev_dbg(&port->dev, | ||
| 947 | "Memory usage (urbs) interface #%d, in=%d, out=%d\n", | ||
| 948 | ifnum, portdata->num_in_urbs, portdata->num_out_urbs); | ||
| 949 | |||
| 950 | usb_set_serial_port_data(port, portdata); | ||
| 951 | |||
| 952 | return 0; | ||
| 953 | } | ||
| 954 | |||
| 955 | static int sierra_port_remove(struct usb_serial_port *port) | ||
| 956 | { | ||
| 957 | struct sierra_port_private *portdata; | ||
| 958 | |||
| 959 | portdata = usb_get_serial_port_data(port); | ||
| 960 | kfree(portdata); | ||
| 961 | |||
| 962 | return 0; | ||
| 962 | } | 963 | } |
| 963 | 964 | ||
| 964 | #ifdef CONFIG_PM | 965 | #ifdef CONFIG_PM |
| @@ -1062,6 +1063,8 @@ static struct usb_serial_driver sierra_device = { | |||
| 1062 | .tiocmset = sierra_tiocmset, | 1063 | .tiocmset = sierra_tiocmset, |
| 1063 | .attach = sierra_startup, | 1064 | .attach = sierra_startup, |
| 1064 | .release = sierra_release, | 1065 | .release = sierra_release, |
| 1066 | .port_probe = sierra_port_probe, | ||
| 1067 | .port_remove = sierra_port_remove, | ||
| 1065 | .suspend = sierra_suspend, | 1068 | .suspend = sierra_suspend, |
| 1066 | .resume = sierra_resume, | 1069 | .resume = sierra_resume, |
| 1067 | .read_int_callback = sierra_instat_callback, | 1070 | .read_int_callback = sierra_instat_callback, |
