aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/devio.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2011-11-17 16:41:14 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-18 14:09:07 -0500
commit52fb743d3aa7ee27a4f3182816aa02dc3e513d9d (patch)
treec4ef377d4d501a1347203fbf296bcd44cdb2a6bb /drivers/usb/core/devio.c
parent86dc243cb2ddecb6984401463ebb0963ceff3cdc (diff)
USB: unify some error pathways in usbfs
This patch (as1496) unifies the error-return pathways of several functions in the usbfs driver. This is not a very important change by itself; it merely prepares the way for the next patch in this series. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r--drivers/usb/core/devio.c96
1 files changed, 50 insertions, 46 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index e3beaf229ee..e8ade68f64e 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -806,8 +806,8 @@ static int proc_control(struct dev_state *ps, void __user *arg)
806 if (ctrl.bRequestType & 0x80) { 806 if (ctrl.bRequestType & 0x80) {
807 if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data, 807 if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data,
808 ctrl.wLength)) { 808 ctrl.wLength)) {
809 free_page((unsigned long)tbuf); 809 ret = -EINVAL;
810 return -EINVAL; 810 goto done;
811 } 811 }
812 pipe = usb_rcvctrlpipe(dev, 0); 812 pipe = usb_rcvctrlpipe(dev, 0);
813 snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT, NULL, 0); 813 snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT, NULL, 0);
@@ -821,15 +821,15 @@ static int proc_control(struct dev_state *ps, void __user *arg)
821 tbuf, max(i, 0)); 821 tbuf, max(i, 0));
822 if ((i > 0) && ctrl.wLength) { 822 if ((i > 0) && ctrl.wLength) {
823 if (copy_to_user(ctrl.data, tbuf, i)) { 823 if (copy_to_user(ctrl.data, tbuf, i)) {
824 free_page((unsigned long)tbuf); 824 ret = -EFAULT;
825 return -EFAULT; 825 goto done;
826 } 826 }
827 } 827 }
828 } else { 828 } else {
829 if (ctrl.wLength) { 829 if (ctrl.wLength) {
830 if (copy_from_user(tbuf, ctrl.data, ctrl.wLength)) { 830 if (copy_from_user(tbuf, ctrl.data, ctrl.wLength)) {
831 free_page((unsigned long)tbuf); 831 ret = -EFAULT;
832 return -EFAULT; 832 goto done;
833 } 833 }
834 } 834 }
835 pipe = usb_sndctrlpipe(dev, 0); 835 pipe = usb_sndctrlpipe(dev, 0);
@@ -843,14 +843,16 @@ static int proc_control(struct dev_state *ps, void __user *arg)
843 usb_lock_device(dev); 843 usb_lock_device(dev);
844 snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, NULL, 0); 844 snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, NULL, 0);
845 } 845 }
846 free_page((unsigned long)tbuf);
847 if (i < 0 && i != -EPIPE) { 846 if (i < 0 && i != -EPIPE) {
848 dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL " 847 dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL "
849 "failed cmd %s rqt %u rq %u len %u ret %d\n", 848 "failed cmd %s rqt %u rq %u len %u ret %d\n",
850 current->comm, ctrl.bRequestType, ctrl.bRequest, 849 current->comm, ctrl.bRequestType, ctrl.bRequest,
851 ctrl.wLength, i); 850 ctrl.wLength, i);
852 } 851 }
853 return i; 852 ret = i;
853 done:
854 free_page((unsigned long) tbuf);
855 return ret;
854} 856}
855 857
856static int proc_bulk(struct dev_state *ps, void __user *arg) 858static int proc_bulk(struct dev_state *ps, void __user *arg)
@@ -884,8 +886,8 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)
884 tmo = bulk.timeout; 886 tmo = bulk.timeout;
885 if (bulk.ep & 0x80) { 887 if (bulk.ep & 0x80) {
886 if (len1 && !access_ok(VERIFY_WRITE, bulk.data, len1)) { 888 if (len1 && !access_ok(VERIFY_WRITE, bulk.data, len1)) {
887 kfree(tbuf); 889 ret = -EINVAL;
888 return -EINVAL; 890 goto done;
889 } 891 }
890 snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, NULL, 0); 892 snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, NULL, 0);
891 893
@@ -896,15 +898,15 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)
896 898
897 if (!i && len2) { 899 if (!i && len2) {
898 if (copy_to_user(bulk.data, tbuf, len2)) { 900 if (copy_to_user(bulk.data, tbuf, len2)) {
899 kfree(tbuf); 901 ret = -EFAULT;
900 return -EFAULT; 902 goto done;
901 } 903 }
902 } 904 }
903 } else { 905 } else {
904 if (len1) { 906 if (len1) {
905 if (copy_from_user(tbuf, bulk.data, len1)) { 907 if (copy_from_user(tbuf, bulk.data, len1)) {
906 kfree(tbuf); 908 ret = -EFAULT;
907 return -EFAULT; 909 goto done;
908 } 910 }
909 } 911 }
910 snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, tbuf, len1); 912 snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, tbuf, len1);
@@ -914,10 +916,10 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)
914 usb_lock_device(dev); 916 usb_lock_device(dev);
915 snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, NULL, 0); 917 snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, NULL, 0);
916 } 918 }
919 ret = (i < 0 ? i : len2);
920 done:
917 kfree(tbuf); 921 kfree(tbuf);
918 if (i < 0) 922 return ret;
919 return i;
920 return len2;
921} 923}
922 924
923static int proc_resetep(struct dev_state *ps, void __user *arg) 925static int proc_resetep(struct dev_state *ps, void __user *arg)
@@ -1062,7 +1064,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1062{ 1064{
1063 struct usbdevfs_iso_packet_desc *isopkt = NULL; 1065 struct usbdevfs_iso_packet_desc *isopkt = NULL;
1064 struct usb_host_endpoint *ep; 1066 struct usb_host_endpoint *ep;
1065 struct async *as; 1067 struct async *as = NULL;
1066 struct usb_ctrlrequest *dr = NULL; 1068 struct usb_ctrlrequest *dr = NULL;
1067 unsigned int u, totlen, isofrmlen; 1069 unsigned int u, totlen, isofrmlen;
1068 int ret, ifnum = -1; 1070 int ret, ifnum = -1;
@@ -1108,19 +1110,17 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1108 if (!dr) 1110 if (!dr)
1109 return -ENOMEM; 1111 return -ENOMEM;
1110 if (copy_from_user(dr, uurb->buffer, 8)) { 1112 if (copy_from_user(dr, uurb->buffer, 8)) {
1111 kfree(dr); 1113 ret = -EFAULT;
1112 return -EFAULT; 1114 goto error;
1113 } 1115 }
1114 if (uurb->buffer_length < (le16_to_cpup(&dr->wLength) + 8)) { 1116 if (uurb->buffer_length < (le16_to_cpup(&dr->wLength) + 8)) {
1115 kfree(dr); 1117 ret = -EINVAL;
1116 return -EINVAL; 1118 goto error;
1117 } 1119 }
1118 ret = check_ctrlrecip(ps, dr->bRequestType, dr->bRequest, 1120 ret = check_ctrlrecip(ps, dr->bRequestType, dr->bRequest,
1119 le16_to_cpup(&dr->wIndex)); 1121 le16_to_cpup(&dr->wIndex));
1120 if (ret) { 1122 if (ret)
1121 kfree(dr); 1123 goto error;
1122 return ret;
1123 }
1124 uurb->number_of_packets = 0; 1124 uurb->number_of_packets = 0;
1125 uurb->buffer_length = le16_to_cpup(&dr->wLength); 1125 uurb->buffer_length = le16_to_cpup(&dr->wLength);
1126 uurb->buffer += 8; 1126 uurb->buffer += 8;
@@ -1176,22 +1176,22 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1176 if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) 1176 if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))
1177 return -ENOMEM; 1177 return -ENOMEM;
1178 if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { 1178 if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) {
1179 kfree(isopkt); 1179 ret = -EFAULT;
1180 return -EFAULT; 1180 goto error;
1181 } 1181 }
1182 for (totlen = u = 0; u < uurb->number_of_packets; u++) { 1182 for (totlen = u = 0; u < uurb->number_of_packets; u++) {
1183 /* arbitrary limit, 1183 /* arbitrary limit,
1184 * sufficient for USB 2.0 high-bandwidth iso */ 1184 * sufficient for USB 2.0 high-bandwidth iso */
1185 if (isopkt[u].length > 8192) { 1185 if (isopkt[u].length > 8192) {
1186 kfree(isopkt); 1186 ret = -EINVAL;
1187 return -EINVAL; 1187 goto error;
1188 } 1188 }
1189 totlen += isopkt[u].length; 1189 totlen += isopkt[u].length;
1190 } 1190 }
1191 /* 3072 * 64 microframes */ 1191 /* 3072 * 64 microframes */
1192 if (totlen > 196608) { 1192 if (totlen > 196608) {
1193 kfree(isopkt); 1193 ret = -EINVAL;
1194 return -EINVAL; 1194 goto error;
1195 } 1195 }
1196 uurb->buffer_length = totlen; 1196 uurb->buffer_length = totlen;
1197 break; 1197 break;
@@ -1202,24 +1202,20 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1202 if (uurb->buffer_length > 0 && 1202 if (uurb->buffer_length > 0 &&
1203 !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, 1203 !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
1204 uurb->buffer, uurb->buffer_length)) { 1204 uurb->buffer, uurb->buffer_length)) {
1205 kfree(isopkt); 1205 ret = -EFAULT;
1206 kfree(dr); 1206 goto error;
1207 return -EFAULT;
1208 } 1207 }
1209 as = alloc_async(uurb->number_of_packets); 1208 as = alloc_async(uurb->number_of_packets);
1210 if (!as) { 1209 if (!as) {
1211 kfree(isopkt); 1210 ret = -ENOMEM;
1212 kfree(dr); 1211 goto error;
1213 return -ENOMEM;
1214 } 1212 }
1215 if (uurb->buffer_length > 0) { 1213 if (uurb->buffer_length > 0) {
1216 as->urb->transfer_buffer = kmalloc(uurb->buffer_length, 1214 as->urb->transfer_buffer = kmalloc(uurb->buffer_length,
1217 GFP_KERNEL); 1215 GFP_KERNEL);
1218 if (!as->urb->transfer_buffer) { 1216 if (!as->urb->transfer_buffer) {
1219 kfree(isopkt); 1217 ret = -ENOMEM;
1220 kfree(dr); 1218 goto error;
1221 free_async(as);
1222 return -ENOMEM;
1223 } 1219 }
1224 /* Isochronous input data may end up being discontiguous 1220 /* Isochronous input data may end up being discontiguous
1225 * if some of the packets are short. Clear the buffer so 1221 * if some of the packets are short. Clear the buffer so
@@ -1253,6 +1249,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1253 1249
1254 as->urb->transfer_buffer_length = uurb->buffer_length; 1250 as->urb->transfer_buffer_length = uurb->buffer_length;
1255 as->urb->setup_packet = (unsigned char *)dr; 1251 as->urb->setup_packet = (unsigned char *)dr;
1252 dr = NULL;
1256 as->urb->start_frame = uurb->start_frame; 1253 as->urb->start_frame = uurb->start_frame;
1257 as->urb->number_of_packets = uurb->number_of_packets; 1254 as->urb->number_of_packets = uurb->number_of_packets;
1258 if (uurb->type == USBDEVFS_URB_TYPE_ISO || 1255 if (uurb->type == USBDEVFS_URB_TYPE_ISO ||
@@ -1268,6 +1265,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1268 totlen += isopkt[u].length; 1265 totlen += isopkt[u].length;
1269 } 1266 }
1270 kfree(isopkt); 1267 kfree(isopkt);
1268 isopkt = NULL;
1271 as->ps = ps; 1269 as->ps = ps;
1272 as->userurb = arg; 1270 as->userurb = arg;
1273 if (is_in && uurb->buffer_length > 0) 1271 if (is_in && uurb->buffer_length > 0)
@@ -1282,8 +1280,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1282 if (!is_in && uurb->buffer_length > 0) { 1280 if (!is_in && uurb->buffer_length > 0) {
1283 if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, 1281 if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,
1284 uurb->buffer_length)) { 1282 uurb->buffer_length)) {
1285 free_async(as); 1283 ret = -EFAULT;
1286 return -EFAULT; 1284 goto error;
1287 } 1285 }
1288 } 1286 }
1289 snoop_urb(ps->dev, as->userurb, as->urb->pipe, 1287 snoop_urb(ps->dev, as->userurb, as->urb->pipe,
@@ -1329,10 +1327,16 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1329 snoop_urb(ps->dev, as->userurb, as->urb->pipe, 1327 snoop_urb(ps->dev, as->userurb, as->urb->pipe,
1330 0, ret, COMPLETE, NULL, 0); 1328 0, ret, COMPLETE, NULL, 0);
1331 async_removepending(as); 1329 async_removepending(as);
1332 free_async(as); 1330 goto error;
1333 return ret;
1334 } 1331 }
1335 return 0; 1332 return 0;
1333
1334 error:
1335 kfree(isopkt);
1336 kfree(dr);
1337 if (as)
1338 free_async(as);
1339 return ret;
1336} 1340}
1337 1341
1338static int proc_submiturb(struct dev_state *ps, void __user *arg) 1342static int proc_submiturb(struct dev_state *ps, void __user *arg)