diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-08-24 15:41:18 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:55:23 -0400 |
commit | 888fda47051716765175d0008450126c837adb32 (patch) | |
tree | 0ea89f308464a86830d2799d9ab744655308ef5d /drivers/usb/host/r8a66597-hcd.c | |
parent | 65e51098d9094c7e840b6d6291867b95538d9442 (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/host/r8a66597-hcd.c')
-rw-r--r-- | drivers/usb/host/r8a66597-hcd.c | 61 |
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 */ |
1111 | static void finish_request(struct r8a66597 *r8a66597, struct r8a66597_td *td, | 1111 | static 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 | ||
1233 | static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | 1231 | static 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 | ||
1297 | static void check_next_phase(struct r8a66597 *r8a66597) | 1294 | static 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 | ||
1333 | static void set_urb_error(struct r8a66597 *r8a66597, u16 pipenum) | 1329 | static 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 | ||
1347 | static void irq_pipe_ready(struct r8a66597 *r8a66597) | 1344 | static 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); |