aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-08-24 15:41:18 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-12 17:55:23 -0400
commit888fda47051716765175d0008450126c837adb32 (patch)
tree0ea89f308464a86830d2799d9ab744655308ef5d /drivers/usb
parent65e51098d9094c7e840b6d6291867b95538d9442 (diff)
USB: reorganize urb->status use in r8a66597-hcd
This patch (as977) reorganizes the way r8a66597-hcd sets urb->status. It now keeps the information in a local variable until the last moment. Parts of this patch were written by Yoshihiro Shimoda. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> CC: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/r8a66597-hcd.c61
1 files changed, 30 insertions, 31 deletions
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 98b9e0547544..fea6036771f6 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -1109,7 +1109,7 @@ static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
1109 1109
1110/* this function must be called with interrupt disabled */ 1110/* this function must be called with interrupt disabled */
1111static void finish_request(struct r8a66597 *r8a66597, struct r8a66597_td *td, 1111static void finish_request(struct r8a66597 *r8a66597, struct r8a66597_td *td,
1112 u16 pipenum, struct urb *urb) 1112 u16 pipenum, struct urb *urb, int status)
1113__releases(r8a66597->lock) __acquires(r8a66597->lock) 1113__releases(r8a66597->lock) __acquires(r8a66597->lock)
1114{ 1114{
1115 int restart = 0; 1115 int restart = 0;
@@ -1118,7 +1118,7 @@ __releases(r8a66597->lock) __acquires(r8a66597->lock)
1118 r8a66597->timeout_map &= ~(1 << pipenum); 1118 r8a66597->timeout_map &= ~(1 << pipenum);
1119 1119
1120 if (likely(td)) { 1120 if (likely(td)) {
1121 if (td->set_address && (urb->status != 0 || urb->unlinked)) 1121 if (td->set_address && (status != 0 || urb->unlinked))
1122 r8a66597->address_map &= ~(1 << urb->setup_packet[2]); 1122 r8a66597->address_map &= ~(1 << urb->setup_packet[2]);
1123 1123
1124 pipe_toggle_save(r8a66597, td->pipe, urb); 1124 pipe_toggle_save(r8a66597, td->pipe, urb);
@@ -1135,6 +1135,7 @@ __releases(r8a66597->lock) __acquires(r8a66597->lock)
1135 1135
1136 usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); 1136 usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb);
1137 1137
1138 urb->status = status;
1138 spin_unlock(&r8a66597->lock); 1139 spin_unlock(&r8a66597->lock);
1139 usb_hcd_giveback_urb(hcd, urb); 1140 usb_hcd_giveback_urb(hcd, urb);
1140 spin_lock(&r8a66597->lock); 1141 spin_lock(&r8a66597->lock);
@@ -1167,11 +1168,10 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum)
1167 fifo_change_from_pipe(r8a66597, td->pipe); 1168 fifo_change_from_pipe(r8a66597, td->pipe);
1168 tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); 1169 tmp = r8a66597_read(r8a66597, td->pipe->fifoctr);
1169 if (unlikely((tmp & FRDY) == 0)) { 1170 if (unlikely((tmp & FRDY) == 0)) {
1170 urb->status = -EPIPE;
1171 pipe_stop(r8a66597, td->pipe); 1171 pipe_stop(r8a66597, td->pipe);
1172 pipe_irq_disable(r8a66597, pipenum); 1172 pipe_irq_disable(r8a66597, pipenum);
1173 err("in fifo not ready (%d)", pipenum); 1173 err("in fifo not ready (%d)", pipenum);
1174 finish_request(r8a66597, td, pipenum, td->urb); 1174 finish_request(r8a66597, td, pipenum, td->urb, -EPIPE);
1175 return; 1175 return;
1176 } 1176 }
1177 1177
@@ -1224,10 +1224,8 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum)
1224 buf, size); 1224 buf, size);
1225 } 1225 }
1226 1226
1227 if (finish && pipenum != 0) { 1227 if (finish && pipenum != 0)
1228 td->urb->status = status; 1228 finish_request(r8a66597, td, pipenum, urb, status);
1229 finish_request(r8a66597, td, pipenum, urb);
1230 }
1231} 1229}
1232 1230
1233static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) 1231static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
@@ -1245,11 +1243,10 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
1245 fifo_change_from_pipe(r8a66597, td->pipe); 1243 fifo_change_from_pipe(r8a66597, td->pipe);
1246 tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); 1244 tmp = r8a66597_read(r8a66597, td->pipe->fifoctr);
1247 if (unlikely((tmp & FRDY) == 0)) { 1245 if (unlikely((tmp & FRDY) == 0)) {
1248 urb->status = -EPIPE;
1249 pipe_stop(r8a66597, td->pipe); 1246 pipe_stop(r8a66597, td->pipe);
1250 pipe_irq_disable(r8a66597, pipenum); 1247 pipe_irq_disable(r8a66597, pipenum);
1251 err("out write fifo not ready. (%d)", pipenum); 1248 err("out write fifo not ready. (%d)", pipenum);
1252 finish_request(r8a66597, td, pipenum, td->urb); 1249 finish_request(r8a66597, td, pipenum, urb, -EPIPE);
1253 return; 1250 return;
1254 } 1251 }
1255 1252
@@ -1294,7 +1291,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
1294} 1291}
1295 1292
1296 1293
1297static void check_next_phase(struct r8a66597 *r8a66597) 1294static void check_next_phase(struct r8a66597 *r8a66597, int status)
1298{ 1295{
1299 struct r8a66597_td *td = r8a66597_get_td(r8a66597, 0); 1296 struct r8a66597_td *td = r8a66597_get_td(r8a66597, 0);
1300 struct urb *urb; 1297 struct urb *urb;
@@ -1320,28 +1317,28 @@ static void check_next_phase(struct r8a66597 *r8a66597)
1320 break; 1317 break;
1321 case USB_PID_ACK: 1318 case USB_PID_ACK:
1322 finish = 1; 1319 finish = 1;
1323 urb->status = 0;
1324 break; 1320 break;
1325 } 1321 }
1326 1322
1327 if (finish || urb->unlinked) 1323 if (finish || status != 0 || urb->unlinked)
1328 finish_request(r8a66597, td, 0, urb); 1324 finish_request(r8a66597, td, 0, urb, status);
1329 else 1325 else
1330 start_transfer(r8a66597, td); 1326 start_transfer(r8a66597, td);
1331} 1327}
1332 1328
1333static void set_urb_error(struct r8a66597 *r8a66597, u16 pipenum) 1329static int get_urb_error(struct r8a66597 *r8a66597, u16 pipenum)
1334{ 1330{
1335 struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum); 1331 struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum);
1336 1332
1337 if (td && td->urb) { 1333 if (td) {
1338 u16 pid = r8a66597_read(r8a66597, td->pipe->pipectr) & PID; 1334 u16 pid = r8a66597_read(r8a66597, td->pipe->pipectr) & PID;
1339 1335
1340 if (pid == PID_NAK) 1336 if (pid == PID_NAK)
1341 td->urb->status = -ECONNRESET; 1337 return -ECONNRESET;
1342 else 1338 else
1343 td->urb->status = -EPIPE; 1339 return -EPIPE;
1344 } 1340 }
1341 return 0;
1345} 1342}
1346 1343
1347static void irq_pipe_ready(struct r8a66597 *r8a66597) 1344static void irq_pipe_ready(struct r8a66597 *r8a66597)
@@ -1360,7 +1357,7 @@ static void irq_pipe_ready(struct r8a66597 *r8a66597)
1360 packet_read(r8a66597, 0); 1357 packet_read(r8a66597, 0);
1361 else 1358 else
1362 pipe_irq_disable(r8a66597, 0); 1359 pipe_irq_disable(r8a66597, 0);
1363 check_next_phase(r8a66597); 1360 check_next_phase(r8a66597, 0);
1364 } 1361 }
1365 1362
1366 for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { 1363 for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
@@ -1394,7 +1391,7 @@ static void irq_pipe_empty(struct r8a66597 *r8a66597)
1394 td = r8a66597_get_td(r8a66597, 0); 1391 td = r8a66597_get_td(r8a66597, 0);
1395 if (td && td->type != USB_PID_OUT) 1392 if (td && td->type != USB_PID_OUT)
1396 disable_irq_empty(r8a66597, 0); 1393 disable_irq_empty(r8a66597, 0);
1397 check_next_phase(r8a66597); 1394 check_next_phase(r8a66597, 0);
1398 } 1395 }
1399 1396
1400 for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { 1397 for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
@@ -1409,8 +1406,8 @@ static void irq_pipe_empty(struct r8a66597 *r8a66597)
1409 if ((tmp & INBUFM) == 0) { 1406 if ((tmp & INBUFM) == 0) {
1410 disable_irq_empty(r8a66597, pipenum); 1407 disable_irq_empty(r8a66597, pipenum);
1411 pipe_irq_disable(r8a66597, pipenum); 1408 pipe_irq_disable(r8a66597, pipenum);
1412 td->urb->status = 0; 1409 finish_request(r8a66597, td, pipenum, td->urb,
1413 finish_request(r8a66597, td, pipenum, td->urb); 1410 0);
1414 } 1411 }
1415 } 1412 }
1416 } 1413 }
@@ -1421,15 +1418,16 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597)
1421 u16 check; 1418 u16 check;
1422 u16 pipenum; 1419 u16 pipenum;
1423 u16 mask; 1420 u16 mask;
1421 int status;
1424 1422
1425 mask = r8a66597_read(r8a66597, NRDYSTS) 1423 mask = r8a66597_read(r8a66597, NRDYSTS)
1426 & r8a66597_read(r8a66597, NRDYENB); 1424 & r8a66597_read(r8a66597, NRDYENB);
1427 r8a66597_write(r8a66597, ~mask, NRDYSTS); 1425 r8a66597_write(r8a66597, ~mask, NRDYSTS);
1428 if (mask & NRDY0) { 1426 if (mask & NRDY0) {
1429 cfifo_change(r8a66597, 0); 1427 cfifo_change(r8a66597, 0);
1430 set_urb_error(r8a66597, 0); 1428 status = get_urb_error(r8a66597, 0);
1431 pipe_irq_disable(r8a66597, 0); 1429 pipe_irq_disable(r8a66597, 0);
1432 check_next_phase(r8a66597); 1430 check_next_phase(r8a66597, status);
1433 } 1431 }
1434 1432
1435 for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { 1433 for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
@@ -1440,10 +1438,10 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597)
1440 if (unlikely(!td)) 1438 if (unlikely(!td))
1441 continue; 1439 continue;
1442 1440
1443 set_urb_error(r8a66597, pipenum); 1441 status = get_urb_error(r8a66597, pipenum);
1444 pipe_irq_disable(r8a66597, pipenum); 1442 pipe_irq_disable(r8a66597, pipenum);
1445 pipe_stop(r8a66597, td->pipe); 1443 pipe_stop(r8a66597, td->pipe);
1446 finish_request(r8a66597, td, pipenum, td->urb); 1444 finish_request(r8a66597, td, pipenum, td->urb, status);
1447 } 1445 }
1448 } 1446 }
1449} 1447}
@@ -1463,6 +1461,7 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
1463 u16 intsts0, intsts1, intsts2; 1461 u16 intsts0, intsts1, intsts2;
1464 u16 intenb0, intenb1, intenb2; 1462 u16 intenb0, intenb1, intenb2;
1465 u16 mask0, mask1, mask2; 1463 u16 mask0, mask1, mask2;
1464 int status;
1466 1465
1467 spin_lock(&r8a66597->lock); 1466 spin_lock(&r8a66597->lock);
1468 1467
@@ -1506,12 +1505,12 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
1506 } 1505 }
1507 if (mask1 & SIGN) { 1506 if (mask1 & SIGN) {
1508 r8a66597_write(r8a66597, ~SIGN, INTSTS1); 1507 r8a66597_write(r8a66597, ~SIGN, INTSTS1);
1509 set_urb_error(r8a66597, 0); 1508 status = get_urb_error(r8a66597, 0);
1510 check_next_phase(r8a66597); 1509 check_next_phase(r8a66597, status);
1511 } 1510 }
1512 if (mask1 & SACK) { 1511 if (mask1 & SACK) {
1513 r8a66597_write(r8a66597, ~SACK, INTSTS1); 1512 r8a66597_write(r8a66597, ~SACK, INTSTS1);
1514 check_next_phase(r8a66597); 1513 check_next_phase(r8a66597, 0);
1515 } 1514 }
1516 } 1515 }
1517 if (mask0) { 1516 if (mask0) {
@@ -1790,7 +1789,7 @@ static int r8a66597_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
1790 pipe_stop(r8a66597, td->pipe); 1789 pipe_stop(r8a66597, td->pipe);
1791 pipe_irq_disable(r8a66597, td->pipenum); 1790 pipe_irq_disable(r8a66597, td->pipenum);
1792 disable_irq_empty(r8a66597, td->pipenum); 1791 disable_irq_empty(r8a66597, td->pipenum);
1793 finish_request(r8a66597, td, td->pipenum, urb); 1792 finish_request(r8a66597, td, td->pipenum, urb, status);
1794 } 1793 }
1795 done: 1794 done:
1796 spin_unlock_irqrestore(&r8a66597->lock, flags); 1795 spin_unlock_irqrestore(&r8a66597->lock, flags);
@@ -1824,7 +1823,7 @@ static void r8a66597_endpoint_disable(struct usb_hcd *hcd,
1824 td = r8a66597_get_td(r8a66597, pipenum); 1823 td = r8a66597_get_td(r8a66597, pipenum);
1825 if (td) 1824 if (td)
1826 urb = td->urb; 1825 urb = td->urb;
1827 finish_request(r8a66597, td, pipenum, urb); 1826 finish_request(r8a66597, td, pipenum, urb, -ESHUTDOWN);
1828 kfree(hep->hcpriv); 1827 kfree(hep->hcpriv);
1829 hep->hcpriv = NULL; 1828 hep->hcpriv = NULL;
1830 spin_unlock_irqrestore(&r8a66597->lock, flags); 1829 spin_unlock_irqrestore(&r8a66597->lock, flags);