diff options
author | David Brownell <david-b@pacbell.net> | 2007-01-17 01:53:58 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-07 18:44:38 -0500 |
commit | 0864c7a9286b02319d3db2103bada1c2269c1e1e (patch) | |
tree | c88010084741f6f89a22bb3da211a9aa5a610f64 /drivers/usb/gadget/inode.c | |
parent | 7489d14943181731ef8694e2ea2d5a919b93b956 (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/inode.c')
-rw-r--r-- | drivers/usb/gadget/inode.c | 29 |
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; |