aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2007-01-17 01:53:58 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 18:44:38 -0500
commit0864c7a9286b02319d3db2103bada1c2269c1e1e (patch)
treec88010084741f6f89a22bb3da211a9aa5a610f64 /drivers/usb/gadget
parent7489d14943181731ef8694e2ea2d5a919b93b956 (diff)
USB: gadgetfs simplifications
This simplifies event reading by eliminating arithmetic and being more direct/obvious, and tweaks some debug messages slightly. The math elimination will change timings, sometimes enough to allow a race to appear. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/inode.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index cbdcb3c10c5e..ea8e3160d05e 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1062,39 +1062,36 @@ scan:
1062 /* return queued events right away */ 1062 /* return queued events right away */
1063 if (dev->ev_next != 0) { 1063 if (dev->ev_next != 0) {
1064 unsigned i, n; 1064 unsigned i, n;
1065 int tmp = dev->ev_next;
1066 1065
1067 len = min (len, tmp * sizeof (struct usb_gadgetfs_event));
1068 n = len / sizeof (struct usb_gadgetfs_event); 1066 n = len / sizeof (struct usb_gadgetfs_event);
1067 if (dev->ev_next < n)
1068 n = dev->ev_next;
1069 1069
1070 /* ep0 can't deliver events when STATE_DEV_SETUP */ 1070 /* ep0 i/o has special semantics during STATE_DEV_SETUP */
1071 for (i = 0; i < n; i++) { 1071 for (i = 0; i < n; i++) {
1072 if (dev->event [i].type == GADGETFS_SETUP) { 1072 if (dev->event [i].type == GADGETFS_SETUP) {
1073 len = i + 1; 1073 dev->state = STATE_DEV_SETUP;
1074 len *= sizeof (struct usb_gadgetfs_event); 1074 n = i + 1;
1075 n = 0;
1076 break; 1075 break;
1077 } 1076 }
1078 } 1077 }
1079 spin_unlock_irq (&dev->lock); 1078 spin_unlock_irq (&dev->lock);
1079 len = n * sizeof (struct usb_gadgetfs_event);
1080 if (copy_to_user (buf, &dev->event, len)) 1080 if (copy_to_user (buf, &dev->event, len))
1081 retval = -EFAULT; 1081 retval = -EFAULT;
1082 else 1082 else
1083 retval = len; 1083 retval = len;
1084 if (len > 0) { 1084 if (len > 0) {
1085 len /= sizeof (struct usb_gadgetfs_event);
1086
1087 /* NOTE this doesn't guard against broken drivers; 1085 /* NOTE this doesn't guard against broken drivers;
1088 * concurrent ep0 readers may lose events. 1086 * concurrent ep0 readers may lose events.
1089 */ 1087 */
1090 spin_lock_irq (&dev->lock); 1088 spin_lock_irq (&dev->lock);
1091 dev->ev_next -= len; 1089 if (dev->ev_next > n) {
1092 if (dev->ev_next != 0) 1090 memmove(&dev->event[0], &dev->event[n],
1093 memmove (&dev->event, &dev->event [len],
1094 sizeof (struct usb_gadgetfs_event) 1091 sizeof (struct usb_gadgetfs_event)
1095 * (tmp - len)); 1092 * (dev->ev_next - n));
1096 if (n == 0) 1093 }
1097 dev->state = STATE_DEV_SETUP; 1094 dev->ev_next -= n;
1098 spin_unlock_irq (&dev->lock); 1095 spin_unlock_irq (&dev->lock);
1099 } 1096 }
1100 return retval; 1097 return retval;
@@ -1149,7 +1146,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type)
1149 for (i = 0; i != dev->ev_next; i++) { 1146 for (i = 0; i != dev->ev_next; i++) {
1150 if (dev->event [i].type != type) 1147 if (dev->event [i].type != type)
1151 continue; 1148 continue;
1152 DBG (dev, "discard old event %d\n", type); 1149 DBG(dev, "discard old event[%d] %d\n", i, type);
1153 dev->ev_next--; 1150 dev->ev_next--;
1154 if (i == dev->ev_next) 1151 if (i == dev->ev_next)
1155 break; 1152 break;
@@ -1162,9 +1159,9 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type)
1162 default: 1159 default:
1163 BUG (); 1160 BUG ();
1164 } 1161 }
1162 VDEBUG(dev, "event[%d] = %d\n", dev->ev_next, type);
1165 event = &dev->event [dev->ev_next++]; 1163 event = &dev->event [dev->ev_next++];
1166 BUG_ON (dev->ev_next > N_EVENT); 1164 BUG_ON (dev->ev_next > N_EVENT);
1167 VDEBUG (dev, "ev %d, next %d\n", type, dev->ev_next);
1168 memset (event, 0, sizeof *event); 1165 memset (event, 0, sizeof *event);
1169 event->type = type; 1166 event->type = type;
1170 return event; 1167 return event;