Message ID | cdd5ae526c65893998898cfb0734161df7048554.1596674377.git.thinhn@synopsys.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | usb: dwc3: gadget: Fix TRB preparation | expand |
Hi Thinh,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on e3ee0e740c3887d2293e8d54a8707218d70d86ca]
url: https://github.com/0day-ci/linux/commits/Thinh-Nguyen/usb-dwc3-gadget-Fix-TRB-preparation/20200806-084719
base: e3ee0e740c3887d2293e8d54a8707218d70d86ca
config: x86_64-randconfig-a004-20200805 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 076b120bebfd727b502208601012a44ab2e1028e)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/usb/dwc3/gadget.c:1177:16: warning: unused variable 'rem' [-Wunused-variable]
unsigned int rem = length % maxp;
^
>> drivers/usb/dwc3/gadget.c:1306:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
^
2 warnings generated.
vim +1306 drivers/usb/dwc3/gadget.c
5ee85d890f8de5 Felipe Balbi 2016-05-13 1235
5ee85d890f8de5 Felipe Balbi 2016-05-13 1236 /*
5ee85d890f8de5 Felipe Balbi 2016-05-13 1237 * dwc3_prepare_trbs - setup TRBs from requests
5ee85d890f8de5 Felipe Balbi 2016-05-13 1238 * @dep: endpoint for which requests are being prepared
5ee85d890f8de5 Felipe Balbi 2016-05-13 1239 *
5ee85d890f8de5 Felipe Balbi 2016-05-13 1240 * The function goes through the requests list and sets up TRBs for the
5ee85d890f8de5 Felipe Balbi 2016-05-13 1241 * transfers. The function returns once there are no more TRBs available or
5ee85d890f8de5 Felipe Balbi 2016-05-13 1242 * it runs out of requests.
5ee85d890f8de5 Felipe Balbi 2016-05-13 1243 */
e1a8607778079c Thinh Nguyen 2020-08-05 1244 static int dwc3_prepare_trbs(struct dwc3_ep *dep)
5ee85d890f8de5 Felipe Balbi 2016-05-13 1245 {
5ee85d890f8de5 Felipe Balbi 2016-05-13 1246 struct dwc3_request *req, *n;
e1a8607778079c Thinh Nguyen 2020-08-05 1247 int ret = 0;
5ee85d890f8de5 Felipe Balbi 2016-05-13 1248
5ee85d890f8de5 Felipe Balbi 2016-05-13 1249 BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
5ee85d890f8de5 Felipe Balbi 2016-05-13 1250
d86c5a676e5b1e Felipe Balbi 2016-10-25 1251 /*
d86c5a676e5b1e Felipe Balbi 2016-10-25 1252 * We can get in a situation where there's a request in the started list
d86c5a676e5b1e Felipe Balbi 2016-10-25 1253 * but there weren't enough TRBs to fully kick it in the first time
d86c5a676e5b1e Felipe Balbi 2016-10-25 1254 * around, so it has been waiting for more TRBs to be freed up.
d86c5a676e5b1e Felipe Balbi 2016-10-25 1255 *
d86c5a676e5b1e Felipe Balbi 2016-10-25 1256 * In that case, we should check if we have a request with pending_sgs
d86c5a676e5b1e Felipe Balbi 2016-10-25 1257 * in the started list and prepare TRBs for that request first,
d86c5a676e5b1e Felipe Balbi 2016-10-25 1258 * otherwise we will prepare TRBs completely out of order and that will
d86c5a676e5b1e Felipe Balbi 2016-10-25 1259 * break things.
d86c5a676e5b1e Felipe Balbi 2016-10-25 1260 */
d86c5a676e5b1e Felipe Balbi 2016-10-25 1261 list_for_each_entry(req, &dep->started_list, list) {
e1a8607778079c Thinh Nguyen 2020-08-05 1262 if (req->num_pending_sgs > 0) {
e1a8607778079c Thinh Nguyen 2020-08-05 1263 ret = dwc3_prepare_one_trb_sg(dep, req);
e1a8607778079c Thinh Nguyen 2020-08-05 1264 if (ret)
e1a8607778079c Thinh Nguyen 2020-08-05 1265 return ret;
e1a8607778079c Thinh Nguyen 2020-08-05 1266 }
63c7bb299fc9c4 Thinh Nguyen 2020-05-15 1267
63c7bb299fc9c4 Thinh Nguyen 2020-05-15 1268 /*
63c7bb299fc9c4 Thinh Nguyen 2020-05-15 1269 * Don't prepare beyond a transfer. In DWC_usb32, its transfer
63c7bb299fc9c4 Thinh Nguyen 2020-05-15 1270 * burst capability may try to read and use TRBs beyond the
63c7bb299fc9c4 Thinh Nguyen 2020-05-15 1271 * active transfer instead of stopping.
63c7bb299fc9c4 Thinh Nguyen 2020-05-15 1272 */
63c7bb299fc9c4 Thinh Nguyen 2020-05-15 1273 if (dep->stream_capable && req->request.is_last)
e1a8607778079c Thinh Nguyen 2020-08-05 1274 return 0;
d86c5a676e5b1e Felipe Balbi 2016-10-25 1275 }
d86c5a676e5b1e Felipe Balbi 2016-10-25 1276
5ee85d890f8de5 Felipe Balbi 2016-05-13 1277 list_for_each_entry_safe(req, n, &dep->pending_list, list) {
cdb55b39fab82b Felipe Balbi 2017-05-17 1278 struct dwc3 *dwc = dep->dwc;
cdb55b39fab82b Felipe Balbi 2017-05-17 1279
cdb55b39fab82b Felipe Balbi 2017-05-17 1280 ret = usb_gadget_map_request_by_dev(dwc->sysdev, &req->request,
cdb55b39fab82b Felipe Balbi 2017-05-17 1281 dep->direction);
cdb55b39fab82b Felipe Balbi 2017-05-17 1282 if (ret)
e1a8607778079c Thinh Nguyen 2020-08-05 1283 return ret;
cdb55b39fab82b Felipe Balbi 2017-05-17 1284
cdb55b39fab82b Felipe Balbi 2017-05-17 1285 req->sg = req->request.sg;
a31e63b608ff78 Anurag Kumar Vulisha 2018-03-27 1286 req->start_sg = req->sg;
c96e6725db9d6a Anurag Kumar Vulisha 2018-03-27 1287 req->num_queued_sgs = 0;
cdb55b39fab82b Felipe Balbi 2017-05-17 1288 req->num_pending_sgs = req->request.num_mapped_sgs;
cdb55b39fab82b Felipe Balbi 2017-05-17 1289
1f512119a08c0d Felipe Balbi 2016-08-12 1290 if (req->num_pending_sgs > 0)
e1a8607778079c Thinh Nguyen 2020-08-05 1291 ret = dwc3_prepare_one_trb_sg(dep, req);
5ee85d890f8de5 Felipe Balbi 2016-05-13 1292 else
e1a8607778079c Thinh Nguyen 2020-08-05 1293 ret = dwc3_prepare_one_trb_linear(dep, req);
5ee85d890f8de5 Felipe Balbi 2016-05-13 1294
e1a8607778079c Thinh Nguyen 2020-08-05 1295 if (ret)
e1a8607778079c Thinh Nguyen 2020-08-05 1296 return ret;
aefe3d232b6629 Thinh Nguyen 2020-05-05 1297
aefe3d232b6629 Thinh Nguyen 2020-05-05 1298 /*
aefe3d232b6629 Thinh Nguyen 2020-05-05 1299 * Don't prepare beyond a transfer. In DWC_usb32, its transfer
aefe3d232b6629 Thinh Nguyen 2020-05-05 1300 * burst capability may try to read and use TRBs beyond the
aefe3d232b6629 Thinh Nguyen 2020-05-05 1301 * active transfer instead of stopping.
aefe3d232b6629 Thinh Nguyen 2020-05-05 1302 */
aefe3d232b6629 Thinh Nguyen 2020-05-05 1303 if (dep->stream_capable && req->request.is_last)
e1a8607778079c Thinh Nguyen 2020-08-05 1304 return 0;
72246da40f3719 Felipe Balbi 2011-08-19 1305 }
72246da40f3719 Felipe Balbi 2011-08-19 @1306 }
72246da40f3719 Felipe Balbi 2011-08-19 1307
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Thinh,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on e3ee0e740c3887d2293e8d54a8707218d70d86ca]
url: https://github.com/0day-ci/linux/commits/Thinh-Nguyen/usb-dwc3-gadget-Fix-TRB-preparation/20200806-084719
base: e3ee0e740c3887d2293e8d54a8707218d70d86ca
config: mips-randconfig-r005-20200807 (attached as .config)
compiler: mipsel-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/usb/dwc3/gadget.c: In function 'dwc3_prepare_one_trb_sg':
drivers/usb/dwc3/gadget.c:1177:16: warning: unused variable 'rem' [-Wunused-variable]
1177 | unsigned int rem = length % maxp;
| ^~~
drivers/usb/dwc3/gadget.c: In function 'dwc3_prepare_trbs':
>> drivers/usb/dwc3/gadget.c:1306:1: warning: control reaches end of non-void function [-Wreturn-type]
1306 | }
| ^
vim +1306 drivers/usb/dwc3/gadget.c
5ee85d890f8de5c Felipe Balbi 2016-05-13 1235
5ee85d890f8de5c Felipe Balbi 2016-05-13 1236 /*
5ee85d890f8de5c Felipe Balbi 2016-05-13 1237 * dwc3_prepare_trbs - setup TRBs from requests
5ee85d890f8de5c Felipe Balbi 2016-05-13 1238 * @dep: endpoint for which requests are being prepared
5ee85d890f8de5c Felipe Balbi 2016-05-13 1239 *
5ee85d890f8de5c Felipe Balbi 2016-05-13 1240 * The function goes through the requests list and sets up TRBs for the
5ee85d890f8de5c Felipe Balbi 2016-05-13 1241 * transfers. The function returns once there are no more TRBs available or
5ee85d890f8de5c Felipe Balbi 2016-05-13 1242 * it runs out of requests.
5ee85d890f8de5c Felipe Balbi 2016-05-13 1243 */
e1a8607778079c1 Thinh Nguyen 2020-08-05 1244 static int dwc3_prepare_trbs(struct dwc3_ep *dep)
5ee85d890f8de5c Felipe Balbi 2016-05-13 1245 {
5ee85d890f8de5c Felipe Balbi 2016-05-13 1246 struct dwc3_request *req, *n;
e1a8607778079c1 Thinh Nguyen 2020-08-05 1247 int ret = 0;
5ee85d890f8de5c Felipe Balbi 2016-05-13 1248
5ee85d890f8de5c Felipe Balbi 2016-05-13 1249 BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
5ee85d890f8de5c Felipe Balbi 2016-05-13 1250
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1251 /*
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1252 * We can get in a situation where there's a request in the started list
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1253 * but there weren't enough TRBs to fully kick it in the first time
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1254 * around, so it has been waiting for more TRBs to be freed up.
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1255 *
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1256 * In that case, we should check if we have a request with pending_sgs
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1257 * in the started list and prepare TRBs for that request first,
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1258 * otherwise we will prepare TRBs completely out of order and that will
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1259 * break things.
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1260 */
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1261 list_for_each_entry(req, &dep->started_list, list) {
e1a8607778079c1 Thinh Nguyen 2020-08-05 1262 if (req->num_pending_sgs > 0) {
e1a8607778079c1 Thinh Nguyen 2020-08-05 1263 ret = dwc3_prepare_one_trb_sg(dep, req);
e1a8607778079c1 Thinh Nguyen 2020-08-05 1264 if (ret)
e1a8607778079c1 Thinh Nguyen 2020-08-05 1265 return ret;
e1a8607778079c1 Thinh Nguyen 2020-08-05 1266 }
63c7bb299fc9c43 Thinh Nguyen 2020-05-15 1267
63c7bb299fc9c43 Thinh Nguyen 2020-05-15 1268 /*
63c7bb299fc9c43 Thinh Nguyen 2020-05-15 1269 * Don't prepare beyond a transfer. In DWC_usb32, its transfer
63c7bb299fc9c43 Thinh Nguyen 2020-05-15 1270 * burst capability may try to read and use TRBs beyond the
63c7bb299fc9c43 Thinh Nguyen 2020-05-15 1271 * active transfer instead of stopping.
63c7bb299fc9c43 Thinh Nguyen 2020-05-15 1272 */
63c7bb299fc9c43 Thinh Nguyen 2020-05-15 1273 if (dep->stream_capable && req->request.is_last)
e1a8607778079c1 Thinh Nguyen 2020-08-05 1274 return 0;
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1275 }
d86c5a676e5b1ee Felipe Balbi 2016-10-25 1276
5ee85d890f8de5c Felipe Balbi 2016-05-13 1277 list_for_each_entry_safe(req, n, &dep->pending_list, list) {
cdb55b39fab82b5 Felipe Balbi 2017-05-17 1278 struct dwc3 *dwc = dep->dwc;
cdb55b39fab82b5 Felipe Balbi 2017-05-17 1279
cdb55b39fab82b5 Felipe Balbi 2017-05-17 1280 ret = usb_gadget_map_request_by_dev(dwc->sysdev, &req->request,
cdb55b39fab82b5 Felipe Balbi 2017-05-17 1281 dep->direction);
cdb55b39fab82b5 Felipe Balbi 2017-05-17 1282 if (ret)
e1a8607778079c1 Thinh Nguyen 2020-08-05 1283 return ret;
cdb55b39fab82b5 Felipe Balbi 2017-05-17 1284
cdb55b39fab82b5 Felipe Balbi 2017-05-17 1285 req->sg = req->request.sg;
a31e63b608ff78c Anurag Kumar Vulisha 2018-03-27 1286 req->start_sg = req->sg;
c96e6725db9d6a0 Anurag Kumar Vulisha 2018-03-27 1287 req->num_queued_sgs = 0;
cdb55b39fab82b5 Felipe Balbi 2017-05-17 1288 req->num_pending_sgs = req->request.num_mapped_sgs;
cdb55b39fab82b5 Felipe Balbi 2017-05-17 1289
1f512119a08c0d4 Felipe Balbi 2016-08-12 1290 if (req->num_pending_sgs > 0)
e1a8607778079c1 Thinh Nguyen 2020-08-05 1291 ret = dwc3_prepare_one_trb_sg(dep, req);
5ee85d890f8de5c Felipe Balbi 2016-05-13 1292 else
e1a8607778079c1 Thinh Nguyen 2020-08-05 1293 ret = dwc3_prepare_one_trb_linear(dep, req);
5ee85d890f8de5c Felipe Balbi 2016-05-13 1294
e1a8607778079c1 Thinh Nguyen 2020-08-05 1295 if (ret)
e1a8607778079c1 Thinh Nguyen 2020-08-05 1296 return ret;
aefe3d232b6629c Thinh Nguyen 2020-05-05 1297
aefe3d232b6629c Thinh Nguyen 2020-05-05 1298 /*
aefe3d232b6629c Thinh Nguyen 2020-05-05 1299 * Don't prepare beyond a transfer. In DWC_usb32, its transfer
aefe3d232b6629c Thinh Nguyen 2020-05-05 1300 * burst capability may try to read and use TRBs beyond the
aefe3d232b6629c Thinh Nguyen 2020-05-05 1301 * active transfer instead of stopping.
aefe3d232b6629c Thinh Nguyen 2020-05-05 1302 */
aefe3d232b6629c Thinh Nguyen 2020-05-05 1303 if (dep->stream_capable && req->request.is_last)
e1a8607778079c1 Thinh Nguyen 2020-08-05 1304 return 0;
72246da40f3719a Felipe Balbi 2011-08-19 1305 }
72246da40f3719a Felipe Balbi 2011-08-19 @1306 }
72246da40f3719a Felipe Balbi 2011-08-19 1307
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index dcadef105c2a..64c2ebacc73c 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1057,8 +1057,10 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, * @trb_length: buffer size of the TRB * @chain: should this TRB be chained to the next? * @node: only for isochronous endpoints. First TRB needs different type. + * + * Return 0 on success or -EAGAIN if there is not enough TRBs. */ -static void dwc3_prepare_one_trb(struct dwc3_ep *dep, +static int dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_request *req, unsigned int trb_length, unsigned chain, unsigned node) { @@ -1069,6 +1071,9 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, unsigned no_interrupt = req->request.no_interrupt; unsigned is_last = req->request.is_last; + if (!dwc3_calc_trbs_left(dep)) + return -EAGAIN; + if (req->request.num_sgs > 0) dma = sg_dma_address(req->start_sg); else @@ -1086,6 +1091,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, __dwc3_prepare_one_trb(dep, trb, dma, trb_length, chain, node, stream_id, short_not_ok, no_interrupt, is_last); + + return 0; } /** @@ -1094,11 +1101,13 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, * @req: The request to prepare * @entry_length: The last SG entry size * @node: Indicates whether this is not the first entry (for isoc only) + * + * Returns 0 on success or -EAGAIN if there is not enough TRBs. */ -static void dwc3_prepare_last_sg(struct dwc3_ep *dep, - struct dwc3_request *req, - unsigned int entry_length, - unsigned int node) +static int dwc3_prepare_last_sg(struct dwc3_ep *dep, + struct dwc3_request *req, + unsigned int entry_length, + unsigned int node) { unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); unsigned int rem = req->request.length % maxp; @@ -1118,6 +1127,9 @@ static void dwc3_prepare_last_sg(struct dwc3_ep *dep, if (num_extra_trbs > 0) req->needs_extra_trb = true; + if (dwc3_calc_trbs_left(dep) < num_extra_trbs + 1) + return -EAGAIN; + /* Prepare a normal TRB */ dwc3_prepare_one_trb(dep, req, entry_length, req->needs_extra_trb, node); @@ -1145,9 +1157,11 @@ static void dwc3_prepare_last_sg(struct dwc3_ep *dep, req->request.no_interrupt, req->request.is_last); } + + return 0; } -static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, +static int dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, struct dwc3_request *req) { struct scatterlist *sg = req->start_sg; @@ -1163,6 +1177,7 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, unsigned int rem = length % maxp; unsigned int trb_length; bool last_sg = false; + int ret = 0; trb_length = min_t(unsigned int, length, sg_dma_len(req->start_sg)); @@ -1179,9 +1194,13 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, last_sg = true; if (last_sg) - dwc3_prepare_last_sg(dep, req, trb_length, i); + ret = dwc3_prepare_last_sg(dep, req, trb_length, i); else - dwc3_prepare_one_trb(dep, req, trb_length, 1, i); + ret = dwc3_prepare_one_trb(dep, req, trb_length, 1, i); + + /* Ran out of TRBs */ + if (ret) + return ret; /* * There can be a situation where all sgs in sglist are not @@ -1204,16 +1223,14 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, req->num_pending_sgs -= req->request.num_mapped_sgs - req->num_queued_sgs; break; } - - if (!dwc3_calc_trbs_left(dep)) - break; } + return 0; } -static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, +static int dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, struct dwc3_request *req) { - dwc3_prepare_last_sg(dep, req, req->request.length, 0); + return dwc3_prepare_last_sg(dep, req, req->request.length, 0); } /* @@ -1224,9 +1241,10 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, * transfers. The function returns once there are no more TRBs available or * it runs out of requests. */ -static void dwc3_prepare_trbs(struct dwc3_ep *dep) +static int dwc3_prepare_trbs(struct dwc3_ep *dep) { struct dwc3_request *req, *n; + int ret = 0; BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM); @@ -1241,11 +1259,11 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) * break things. */ list_for_each_entry(req, &dep->started_list, list) { - if (req->num_pending_sgs > 0) - dwc3_prepare_one_trb_sg(dep, req); - - if (!dwc3_calc_trbs_left(dep)) - return; + if (req->num_pending_sgs > 0) { + ret = dwc3_prepare_one_trb_sg(dep, req); + if (ret) + return ret; + } /* * Don't prepare beyond a transfer. In DWC_usb32, its transfer @@ -1253,17 +1271,16 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) * active transfer instead of stopping. */ if (dep->stream_capable && req->request.is_last) - return; + return 0; } list_for_each_entry_safe(req, n, &dep->pending_list, list) { struct dwc3 *dwc = dep->dwc; - int ret; ret = usb_gadget_map_request_by_dev(dwc->sysdev, &req->request, dep->direction); if (ret) - return; + return ret; req->sg = req->request.sg; req->start_sg = req->sg; @@ -1271,12 +1288,12 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) req->num_pending_sgs = req->request.num_mapped_sgs; if (req->num_pending_sgs > 0) - dwc3_prepare_one_trb_sg(dep, req); + ret = dwc3_prepare_one_trb_sg(dep, req); else - dwc3_prepare_one_trb_linear(dep, req); + ret = dwc3_prepare_one_trb_linear(dep, req); - if (!dwc3_calc_trbs_left(dep)) - return; + if (ret) + return ret; /* * Don't prepare beyond a transfer. In DWC_usb32, its transfer @@ -1284,7 +1301,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) * active transfer instead of stopping. */ if (dep->stream_capable && req->request.is_last) - return; + return 0; } } @@ -1298,12 +1315,12 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) int ret; u32 cmd; - if (!dwc3_calc_trbs_left(dep)) - return 0; - starting = !(dep->flags & DWC3_EP_TRANSFER_STARTED); - dwc3_prepare_trbs(dep); + ret = dwc3_prepare_trbs(dep); + if (ret) + return 0; + req = next_request(&dep->started_list); if (!req) { dep->flags |= DWC3_EP_PENDING_REQUEST;
When checking for how many TRB remaining, make sure to account for extra TRBs for ZLP or MPS alignment transfers. Since the dwc3_prepare_trb* functions should know if we need the extra TRBs, make those functions return a status code -EAGAIN if there isn't enough TRB. Check against those status when preparing TRB instead. Fixes: c6267a51639b ("usb: dwc3: gadget: align transfers to wMaxPacketSize") Signed-off-by: Thinh Nguyen <thinhn@synopsys.com> --- drivers/usb/dwc3/gadget.c | 79 ++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 31 deletions(-)