diff options
author | Mian Yousaf Kaukab <yousaf.kaukab@intel.com> | 2015-02-02 04:55:25 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2015-03-10 16:33:31 -0400 |
commit | 9ceafcc2b3ad48ad2ef42608f1505ecad515d144 (patch) | |
tree | 116698d3e47be4c59f72c62fedac2ccdd8430144 | |
parent | fb2a85dd933c2793f5aabeb84af8b3bc00c0c968 (diff) |
usb: gadget: net2280: print error in ep_ops error paths
Hopefully, these prints will help localize the problems faster.
[ balbi@ti.com: removed 2 unnecessary OOM error messages ]
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r-- | drivers/usb/gadget/udc/net2280.c | 166 |
1 files changed, 119 insertions, 47 deletions
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index d51430f26ecf..5a8f6b6f7c8d 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c | |||
@@ -145,31 +145,44 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
145 | u32 max, tmp; | 145 | u32 max, tmp; |
146 | unsigned long flags; | 146 | unsigned long flags; |
147 | static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 }; | 147 | static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 }; |
148 | int ret = 0; | ||
148 | 149 | ||
149 | ep = container_of(_ep, struct net2280_ep, ep); | 150 | ep = container_of(_ep, struct net2280_ep, ep); |
150 | if (!_ep || !desc || ep->desc || _ep->name == ep0name || | 151 | if (!_ep || !desc || ep->desc || _ep->name == ep0name || |
151 | desc->bDescriptorType != USB_DT_ENDPOINT) | 152 | desc->bDescriptorType != USB_DT_ENDPOINT) { |
153 | pr_err("%s: failed at line=%d\n", __func__, __LINE__); | ||
152 | return -EINVAL; | 154 | return -EINVAL; |
155 | } | ||
153 | dev = ep->dev; | 156 | dev = ep->dev; |
154 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | 157 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { |
155 | return -ESHUTDOWN; | 158 | ret = -ESHUTDOWN; |
159 | goto print_err; | ||
160 | } | ||
156 | 161 | ||
157 | /* erratum 0119 workaround ties up an endpoint number */ | 162 | /* erratum 0119 workaround ties up an endpoint number */ |
158 | if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) | 163 | if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) { |
159 | return -EDOM; | 164 | ret = -EDOM; |
165 | goto print_err; | ||
166 | } | ||
160 | 167 | ||
161 | if (dev->quirks & PLX_SUPERSPEED) { | 168 | if (dev->quirks & PLX_SUPERSPEED) { |
162 | if ((desc->bEndpointAddress & 0x0f) >= 0x0c) | 169 | if ((desc->bEndpointAddress & 0x0f) >= 0x0c) { |
163 | return -EDOM; | 170 | ret = -EDOM; |
171 | goto print_err; | ||
172 | } | ||
164 | ep->is_in = !!usb_endpoint_dir_in(desc); | 173 | ep->is_in = !!usb_endpoint_dir_in(desc); |
165 | if (dev->enhanced_mode && ep->is_in && ep_key[ep->num]) | 174 | if (dev->enhanced_mode && ep->is_in && ep_key[ep->num]) { |
166 | return -EINVAL; | 175 | ret = -EINVAL; |
176 | goto print_err; | ||
177 | } | ||
167 | } | 178 | } |
168 | 179 | ||
169 | /* sanity check ep-e/ep-f since their fifos are small */ | 180 | /* sanity check ep-e/ep-f since their fifos are small */ |
170 | max = usb_endpoint_maxp(desc) & 0x1fff; | 181 | max = usb_endpoint_maxp(desc) & 0x1fff; |
171 | if (ep->num > 4 && max > 64 && (dev->quirks & PLX_LEGACY)) | 182 | if (ep->num > 4 && max > 64 && (dev->quirks & PLX_LEGACY)) { |
172 | return -ERANGE; | 183 | ret = -ERANGE; |
184 | goto print_err; | ||
185 | } | ||
173 | 186 | ||
174 | spin_lock_irqsave(&dev->lock, flags); | 187 | spin_lock_irqsave(&dev->lock, flags); |
175 | _ep->maxpacket = max & 0x7ff; | 188 | _ep->maxpacket = max & 0x7ff; |
@@ -199,7 +212,8 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
199 | (dev->gadget.speed == USB_SPEED_HIGH && max != 512) || | 212 | (dev->gadget.speed == USB_SPEED_HIGH && max != 512) || |
200 | (dev->gadget.speed == USB_SPEED_FULL && max > 64)) { | 213 | (dev->gadget.speed == USB_SPEED_FULL && max > 64)) { |
201 | spin_unlock_irqrestore(&dev->lock, flags); | 214 | spin_unlock_irqrestore(&dev->lock, flags); |
202 | return -ERANGE; | 215 | ret = -ERANGE; |
216 | goto print_err; | ||
203 | } | 217 | } |
204 | } | 218 | } |
205 | ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC); | 219 | ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC); |
@@ -278,7 +292,11 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
278 | 292 | ||
279 | /* pci writes may still be posted */ | 293 | /* pci writes may still be posted */ |
280 | spin_unlock_irqrestore(&dev->lock, flags); | 294 | spin_unlock_irqrestore(&dev->lock, flags); |
281 | return 0; | 295 | return ret; |
296 | |||
297 | print_err: | ||
298 | dev_err(&ep->dev->pdev->dev, "%s: error=%d\n", __func__, ret); | ||
299 | return ret; | ||
282 | } | 300 | } |
283 | 301 | ||
284 | static int handshake(u32 __iomem *ptr, u32 mask, u32 done, int usec) | 302 | static int handshake(u32 __iomem *ptr, u32 mask, u32 done, int usec) |
@@ -433,9 +451,10 @@ static int net2280_disable(struct usb_ep *_ep) | |||
433 | unsigned long flags; | 451 | unsigned long flags; |
434 | 452 | ||
435 | ep = container_of(_ep, struct net2280_ep, ep); | 453 | ep = container_of(_ep, struct net2280_ep, ep); |
436 | if (!_ep || !ep->desc || _ep->name == ep0name) | 454 | if (!_ep || !ep->desc || _ep->name == ep0name) { |
455 | pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); | ||
437 | return -EINVAL; | 456 | return -EINVAL; |
438 | 457 | } | |
439 | spin_lock_irqsave(&ep->dev->lock, flags); | 458 | spin_lock_irqsave(&ep->dev->lock, flags); |
440 | nuke(ep); | 459 | nuke(ep); |
441 | 460 | ||
@@ -465,8 +484,10 @@ static struct usb_request | |||
465 | struct net2280_ep *ep; | 484 | struct net2280_ep *ep; |
466 | struct net2280_request *req; | 485 | struct net2280_request *req; |
467 | 486 | ||
468 | if (!_ep) | 487 | if (!_ep) { |
488 | pr_err("%s: Invalid ep\n", __func__); | ||
469 | return NULL; | 489 | return NULL; |
490 | } | ||
470 | ep = container_of(_ep, struct net2280_ep, ep); | 491 | ep = container_of(_ep, struct net2280_ep, ep); |
471 | 492 | ||
472 | req = kzalloc(sizeof(*req), gfp_flags); | 493 | req = kzalloc(sizeof(*req), gfp_flags); |
@@ -498,8 +519,11 @@ static void net2280_free_request(struct usb_ep *_ep, struct usb_request *_req) | |||
498 | struct net2280_request *req; | 519 | struct net2280_request *req; |
499 | 520 | ||
500 | ep = container_of(_ep, struct net2280_ep, ep); | 521 | ep = container_of(_ep, struct net2280_ep, ep); |
501 | if (!_ep || !_req) | 522 | if (!_ep || !_req) { |
523 | dev_err(&ep->dev->pdev->dev, "%s: Inavlid ep=%p or req=%p\n", | ||
524 | __func__, _ep, _req); | ||
502 | return; | 525 | return; |
526 | } | ||
503 | 527 | ||
504 | req = container_of(_req, struct net2280_request, req); | 528 | req = container_of(_req, struct net2280_request, req); |
505 | WARN_ON(!list_empty(&req->queue)); | 529 | WARN_ON(!list_empty(&req->queue)); |
@@ -903,35 +927,44 @@ net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
903 | struct net2280_ep *ep; | 927 | struct net2280_ep *ep; |
904 | struct net2280 *dev; | 928 | struct net2280 *dev; |
905 | unsigned long flags; | 929 | unsigned long flags; |
930 | int ret = 0; | ||
906 | 931 | ||
907 | /* we always require a cpu-view buffer, so that we can | 932 | /* we always require a cpu-view buffer, so that we can |
908 | * always use pio (as fallback or whatever). | 933 | * always use pio (as fallback or whatever). |
909 | */ | 934 | */ |
910 | req = container_of(_req, struct net2280_request, req); | ||
911 | if (!_req || !_req->complete || !_req->buf || | ||
912 | !list_empty(&req->queue)) | ||
913 | return -EINVAL; | ||
914 | if (_req->length > (~0 & DMA_BYTE_COUNT_MASK)) | ||
915 | return -EDOM; | ||
916 | ep = container_of(_ep, struct net2280_ep, ep); | 935 | ep = container_of(_ep, struct net2280_ep, ep); |
917 | if (!_ep || (!ep->desc && ep->num != 0)) | 936 | if (!_ep || (!ep->desc && ep->num != 0)) { |
937 | pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); | ||
918 | return -EINVAL; | 938 | return -EINVAL; |
939 | } | ||
940 | req = container_of(_req, struct net2280_request, req); | ||
941 | if (!_req || !_req->complete || !_req->buf || | ||
942 | !list_empty(&req->queue)) { | ||
943 | ret = -EINVAL; | ||
944 | goto print_err; | ||
945 | } | ||
946 | if (_req->length > (~0 & DMA_BYTE_COUNT_MASK)) { | ||
947 | ret = -EDOM; | ||
948 | goto print_err; | ||
949 | } | ||
919 | dev = ep->dev; | 950 | dev = ep->dev; |
920 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | 951 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { |
921 | return -ESHUTDOWN; | 952 | ret = -ESHUTDOWN; |
953 | goto print_err; | ||
954 | } | ||
922 | 955 | ||
923 | /* FIXME implement PIO fallback for ZLPs with DMA */ | 956 | /* FIXME implement PIO fallback for ZLPs with DMA */ |
924 | if (ep->dma && _req->length == 0) | 957 | if (ep->dma && _req->length == 0) { |
925 | return -EOPNOTSUPP; | 958 | ret = -EOPNOTSUPP; |
959 | goto print_err; | ||
960 | } | ||
926 | 961 | ||
927 | /* set up dma mapping in case the caller didn't */ | 962 | /* set up dma mapping in case the caller didn't */ |
928 | if (ep->dma) { | 963 | if (ep->dma) { |
929 | int ret; | ||
930 | |||
931 | ret = usb_gadget_map_request(&dev->gadget, _req, | 964 | ret = usb_gadget_map_request(&dev->gadget, _req, |
932 | ep->is_in); | 965 | ep->is_in); |
933 | if (ret) | 966 | if (ret) |
934 | return ret; | 967 | goto print_err; |
935 | } | 968 | } |
936 | 969 | ||
937 | ep_vdbg(dev, "%s queue req %p, len %d buf %p\n", | 970 | ep_vdbg(dev, "%s queue req %p, len %d buf %p\n", |
@@ -1020,7 +1053,11 @@ done: | |||
1020 | spin_unlock_irqrestore(&dev->lock, flags); | 1053 | spin_unlock_irqrestore(&dev->lock, flags); |
1021 | 1054 | ||
1022 | /* pci writes may still be posted */ | 1055 | /* pci writes may still be posted */ |
1023 | return 0; | 1056 | return ret; |
1057 | |||
1058 | print_err: | ||
1059 | dev_err(&ep->dev->pdev->dev, "%s: error=%d\n", __func__, ret); | ||
1060 | return ret; | ||
1024 | } | 1061 | } |
1025 | 1062 | ||
1026 | static inline void | 1063 | static inline void |
@@ -1141,8 +1178,11 @@ static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
1141 | int stopped; | 1178 | int stopped; |
1142 | 1179 | ||
1143 | ep = container_of(_ep, struct net2280_ep, ep); | 1180 | ep = container_of(_ep, struct net2280_ep, ep); |
1144 | if (!_ep || (!ep->desc && ep->num != 0) || !_req) | 1181 | if (!_ep || (!ep->desc && ep->num != 0) || !_req) { |
1182 | pr_err("%s: Invalid ep=%p or ep->desc or req=%p\n", | ||
1183 | __func__, _ep, _req); | ||
1145 | return -EINVAL; | 1184 | return -EINVAL; |
1185 | } | ||
1146 | 1186 | ||
1147 | spin_lock_irqsave(&ep->dev->lock, flags); | 1187 | spin_lock_irqsave(&ep->dev->lock, flags); |
1148 | stopped = ep->stopped; | 1188 | stopped = ep->stopped; |
@@ -1164,6 +1204,8 @@ static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
1164 | } | 1204 | } |
1165 | if (&req->req != _req) { | 1205 | if (&req->req != _req) { |
1166 | spin_unlock_irqrestore(&ep->dev->lock, flags); | 1206 | spin_unlock_irqrestore(&ep->dev->lock, flags); |
1207 | dev_err(&ep->dev->pdev->dev, "%s: Request mismatch\n", | ||
1208 | __func__); | ||
1167 | return -EINVAL; | 1209 | return -EINVAL; |
1168 | } | 1210 | } |
1169 | 1211 | ||
@@ -1221,20 +1263,28 @@ net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) | |||
1221 | int retval = 0; | 1263 | int retval = 0; |
1222 | 1264 | ||
1223 | ep = container_of(_ep, struct net2280_ep, ep); | 1265 | ep = container_of(_ep, struct net2280_ep, ep); |
1224 | if (!_ep || (!ep->desc && ep->num != 0)) | 1266 | if (!_ep || (!ep->desc && ep->num != 0)) { |
1267 | pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); | ||
1225 | return -EINVAL; | 1268 | return -EINVAL; |
1226 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | 1269 | } |
1227 | return -ESHUTDOWN; | 1270 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) { |
1271 | retval = -ESHUTDOWN; | ||
1272 | goto print_err; | ||
1273 | } | ||
1228 | if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03) | 1274 | if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03) |
1229 | == USB_ENDPOINT_XFER_ISOC) | 1275 | == USB_ENDPOINT_XFER_ISOC) { |
1230 | return -EINVAL; | 1276 | retval = -EINVAL; |
1277 | goto print_err; | ||
1278 | } | ||
1231 | 1279 | ||
1232 | spin_lock_irqsave(&ep->dev->lock, flags); | 1280 | spin_lock_irqsave(&ep->dev->lock, flags); |
1233 | if (!list_empty(&ep->queue)) | 1281 | if (!list_empty(&ep->queue)) { |
1234 | retval = -EAGAIN; | 1282 | retval = -EAGAIN; |
1235 | else if (ep->is_in && value && net2280_fifo_status(_ep) != 0) | 1283 | goto print_unlock; |
1284 | } else if (ep->is_in && value && net2280_fifo_status(_ep) != 0) { | ||
1236 | retval = -EAGAIN; | 1285 | retval = -EAGAIN; |
1237 | else { | 1286 | goto print_unlock; |
1287 | } else { | ||
1238 | ep_vdbg(ep->dev, "%s %s %s\n", _ep->name, | 1288 | ep_vdbg(ep->dev, "%s %s %s\n", _ep->name, |
1239 | value ? "set" : "clear", | 1289 | value ? "set" : "clear", |
1240 | wedged ? "wedge" : "halt"); | 1290 | wedged ? "wedge" : "halt"); |
@@ -1258,6 +1308,12 @@ net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) | |||
1258 | spin_unlock_irqrestore(&ep->dev->lock, flags); | 1308 | spin_unlock_irqrestore(&ep->dev->lock, flags); |
1259 | 1309 | ||
1260 | return retval; | 1310 | return retval; |
1311 | |||
1312 | print_unlock: | ||
1313 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
1314 | print_err: | ||
1315 | dev_err(&ep->dev->pdev->dev, "%s: error=%d\n", __func__, retval); | ||
1316 | return retval; | ||
1261 | } | 1317 | } |
1262 | 1318 | ||
1263 | static int net2280_set_halt(struct usb_ep *_ep, int value) | 1319 | static int net2280_set_halt(struct usb_ep *_ep, int value) |
@@ -1267,8 +1323,10 @@ static int net2280_set_halt(struct usb_ep *_ep, int value) | |||
1267 | 1323 | ||
1268 | static int net2280_set_wedge(struct usb_ep *_ep) | 1324 | static int net2280_set_wedge(struct usb_ep *_ep) |
1269 | { | 1325 | { |
1270 | if (!_ep || _ep->name == ep0name) | 1326 | if (!_ep || _ep->name == ep0name) { |
1327 | pr_err("%s: Invalid ep=%p or ep0\n", __func__, _ep); | ||
1271 | return -EINVAL; | 1328 | return -EINVAL; |
1329 | } | ||
1272 | return net2280_set_halt_and_wedge(_ep, 1, 1); | 1330 | return net2280_set_halt_and_wedge(_ep, 1, 1); |
1273 | } | 1331 | } |
1274 | 1332 | ||
@@ -1278,14 +1336,22 @@ static int net2280_fifo_status(struct usb_ep *_ep) | |||
1278 | u32 avail; | 1336 | u32 avail; |
1279 | 1337 | ||
1280 | ep = container_of(_ep, struct net2280_ep, ep); | 1338 | ep = container_of(_ep, struct net2280_ep, ep); |
1281 | if (!_ep || (!ep->desc && ep->num != 0)) | 1339 | if (!_ep || (!ep->desc && ep->num != 0)) { |
1340 | pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); | ||
1282 | return -ENODEV; | 1341 | return -ENODEV; |
1283 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | 1342 | } |
1343 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) { | ||
1344 | dev_err(&ep->dev->pdev->dev, | ||
1345 | "%s: Invalid driver=%p or speed=%d\n", | ||
1346 | __func__, ep->dev->driver, ep->dev->gadget.speed); | ||
1284 | return -ESHUTDOWN; | 1347 | return -ESHUTDOWN; |
1348 | } | ||
1285 | 1349 | ||
1286 | avail = readl(&ep->regs->ep_avail) & (BIT(12) - 1); | 1350 | avail = readl(&ep->regs->ep_avail) & (BIT(12) - 1); |
1287 | if (avail > ep->fifo_size) | 1351 | if (avail > ep->fifo_size) { |
1352 | dev_err(&ep->dev->pdev->dev, "%s: Fifo overflow\n", __func__); | ||
1288 | return -EOVERFLOW; | 1353 | return -EOVERFLOW; |
1354 | } | ||
1289 | if (ep->is_in) | 1355 | if (ep->is_in) |
1290 | avail = ep->fifo_size - avail; | 1356 | avail = ep->fifo_size - avail; |
1291 | return avail; | 1357 | return avail; |
@@ -1296,10 +1362,16 @@ static void net2280_fifo_flush(struct usb_ep *_ep) | |||
1296 | struct net2280_ep *ep; | 1362 | struct net2280_ep *ep; |
1297 | 1363 | ||
1298 | ep = container_of(_ep, struct net2280_ep, ep); | 1364 | ep = container_of(_ep, struct net2280_ep, ep); |
1299 | if (!_ep || (!ep->desc && ep->num != 0)) | 1365 | if (!_ep || (!ep->desc && ep->num != 0)) { |
1366 | pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); | ||
1300 | return; | 1367 | return; |
1301 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | 1368 | } |
1369 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) { | ||
1370 | dev_err(&ep->dev->pdev->dev, | ||
1371 | "%s: Invalid driver=%p or speed=%d\n", | ||
1372 | __func__, ep->dev->driver, ep->dev->gadget.speed); | ||
1302 | return; | 1373 | return; |
1374 | } | ||
1303 | 1375 | ||
1304 | writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); | 1376 | writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); |
1305 | (void) readl(&ep->regs->ep_rsp); | 1377 | (void) readl(&ep->regs->ep_rsp); |