diff options
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index ba86fec872b4..93b28ee8e8bd 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -838,7 +838,7 @@ static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios | |||
| 838 | * USB probe and disconnect routines. | 838 | * USB probe and disconnect routines. |
| 839 | */ | 839 | */ |
| 840 | 840 | ||
| 841 | /* Little helper: write buffers free */ | 841 | /* Little helpers: write/read buffers free */ |
| 842 | static void acm_write_buffers_free(struct acm *acm) | 842 | static void acm_write_buffers_free(struct acm *acm) |
| 843 | { | 843 | { |
| 844 | int i; | 844 | int i; |
| @@ -849,6 +849,15 @@ static void acm_write_buffers_free(struct acm *acm) | |||
| 849 | } | 849 | } |
| 850 | } | 850 | } |
| 851 | 851 | ||
| 852 | static void acm_read_buffers_free(struct acm *acm) | ||
| 853 | { | ||
| 854 | struct usb_device *usb_dev = interface_to_usbdev(acm->control); | ||
| 855 | int i, n = acm->rx_buflimit; | ||
| 856 | |||
| 857 | for (i = 0; i < n; i++) | ||
| 858 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); | ||
| 859 | } | ||
| 860 | |||
| 852 | /* Little helper: write buffers allocate */ | 861 | /* Little helper: write buffers allocate */ |
| 853 | static int acm_write_buffers_alloc(struct acm *acm) | 862 | static int acm_write_buffers_alloc(struct acm *acm) |
| 854 | { | 863 | { |
| @@ -1171,8 +1180,7 @@ alloc_fail8: | |||
| 1171 | for (i = 0; i < ACM_NW; i++) | 1180 | for (i = 0; i < ACM_NW; i++) |
| 1172 | usb_free_urb(acm->wb[i].urb); | 1181 | usb_free_urb(acm->wb[i].urb); |
| 1173 | alloc_fail7: | 1182 | alloc_fail7: |
| 1174 | for (i = 0; i < num_rx_buf; i++) | 1183 | acm_read_buffers_free(acm); |
| 1175 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); | ||
| 1176 | for (i = 0; i < num_rx_buf; i++) | 1184 | for (i = 0; i < num_rx_buf; i++) |
| 1177 | usb_free_urb(acm->ru[i].urb); | 1185 | usb_free_urb(acm->ru[i].urb); |
| 1178 | usb_free_urb(acm->ctrlurb); | 1186 | usb_free_urb(acm->ctrlurb); |
| @@ -1209,15 +1217,9 @@ static void acm_disconnect(struct usb_interface *intf) | |||
| 1209 | { | 1217 | { |
| 1210 | struct acm *acm = usb_get_intfdata(intf); | 1218 | struct acm *acm = usb_get_intfdata(intf); |
| 1211 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 1219 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
| 1212 | int i; | ||
| 1213 | |||
| 1214 | if (!acm || !acm->dev) { | ||
| 1215 | dbg("disconnect on nonexisting interface"); | ||
| 1216 | return; | ||
| 1217 | } | ||
| 1218 | 1220 | ||
| 1219 | mutex_lock(&open_mutex); | 1221 | mutex_lock(&open_mutex); |
| 1220 | if (!usb_get_intfdata(intf)) { | 1222 | if (!acm || !acm->dev) { |
| 1221 | mutex_unlock(&open_mutex); | 1223 | mutex_unlock(&open_mutex); |
| 1222 | return; | 1224 | return; |
| 1223 | } | 1225 | } |
| @@ -1236,10 +1238,10 @@ static void acm_disconnect(struct usb_interface *intf) | |||
| 1236 | 1238 | ||
| 1237 | acm_write_buffers_free(acm); | 1239 | acm_write_buffers_free(acm); |
| 1238 | usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); | 1240 | usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); |
| 1239 | for (i = 0; i < acm->rx_buflimit; i++) | 1241 | acm_read_buffers_free(acm); |
| 1240 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); | ||
| 1241 | 1242 | ||
| 1242 | usb_driver_release_interface(&acm_driver, intf == acm->control ? acm->data : intf); | 1243 | usb_driver_release_interface(&acm_driver, intf == acm->control ? |
| 1244 | acm->data : acm->control); | ||
| 1243 | 1245 | ||
| 1244 | if (!acm->used) { | 1246 | if (!acm->used) { |
| 1245 | acm_tty_unregister(acm); | 1247 | acm_tty_unregister(acm); |
