aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/isp1760-hcd.c
diff options
context:
space:
mode:
authorArvid Brodin <arvid.brodin@enea.com>2011-04-26 15:47:37 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-02 20:02:54 -0400
commit34537731d7f64d20116fbef4a665ec6a37195573 (patch)
treefc3fdf167bd96b43fa66a30fbacc57dcb794c95a /drivers/usb/host/isp1760-hcd.c
parent847ed3e8f18b9cc401677e6e14eb7c89c7b8dfb6 (diff)
usb/isp1760: Clean up urb enqueueing
This collects urb enqueue code that was spread out all over the place into a couple of more readable functions. Signed-off-by: Arvid Brodin <arvid.brodin@enea.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/isp1760-hcd.c')
-rw-r--r--drivers/usb/host/isp1760-hcd.c327
1 files changed, 129 insertions, 198 deletions
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index ff3b3165d19d..6b2bf4684f45 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -272,7 +272,7 @@ static void init_memory(struct isp1760_hcd *priv)
272 payload_addr += priv->memory_pool[curr + i].size; 272 payload_addr += priv->memory_pool[curr + i].size;
273 } 273 }
274 274
275 BUG_ON(payload_addr - priv->memory_pool[0].start > PAYLOAD_AREA_SIZE); 275 WARN_ON(payload_addr - priv->memory_pool[0].start > PAYLOAD_AREA_SIZE);
276} 276}
277 277
278static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd) 278static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
@@ -280,7 +280,7 @@ static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
280 struct isp1760_hcd *priv = hcd_to_priv(hcd); 280 struct isp1760_hcd *priv = hcd_to_priv(hcd);
281 int i; 281 int i;
282 282
283 BUG_ON(qtd->payload_addr); 283 WARN_ON(qtd->payload_addr);
284 284
285 if (!qtd->length) 285 if (!qtd->length)
286 return; 286 return;
@@ -318,7 +318,7 @@ static void free_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
318 318
319 for (i = 0; i < BLOCKS; i++) { 319 for (i = 0; i < BLOCKS; i++) {
320 if (priv->memory_pool[i].start == qtd->payload_addr) { 320 if (priv->memory_pool[i].start == qtd->payload_addr) {
321 BUG_ON(priv->memory_pool[i].free); 321 WARN_ON(priv->memory_pool[i].free);
322 priv->memory_pool[i].free = 1; 322 priv->memory_pool[i].free = 1;
323 qtd->payload_addr = 0; 323 qtd->payload_addr = 0;
324 return; 324 return;
@@ -379,7 +379,7 @@ static int ehci_reset(struct usb_hcd *hcd)
379 379
380static void qh_destroy(struct isp1760_qh *qh) 380static void qh_destroy(struct isp1760_qh *qh)
381{ 381{
382 BUG_ON(!list_empty(&qh->qtd_list)); 382 WARN_ON(!list_empty(&qh->qtd_list));
383 kmem_cache_free(qh_cachep, qh); 383 kmem_cache_free(qh_cachep, qh);
384} 384}
385 385
@@ -738,23 +738,6 @@ static void transform_into_int(struct isp1760_qh *qh,
738 transform_add_int(qh, qtd, ptd); 738 transform_add_int(qh, qtd, ptd);
739} 739}
740 740
741static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len,
742 u32 token)
743{
744 int count;
745
746 qtd->data_buffer = databuffer;
747 qtd->packet_type = GET_QTD_TOKEN_TYPE(token);
748
749 if (len > MAX_PAYLOAD_SIZE)
750 count = MAX_PAYLOAD_SIZE;
751 else
752 count = len;
753
754 qtd->length = count;
755 return count;
756}
757
758static int check_error(struct usb_hcd *hcd, struct ptd *ptd) 741static int check_error(struct usb_hcd *hcd, struct ptd *ptd)
759{ 742{
760 int error = 0; 743 int error = 0;
@@ -948,9 +931,25 @@ __acquires(priv->lock)
948 spin_lock(&priv->lock); 931 spin_lock(&priv->lock);
949} 932}
950 933
951static void isp1760_qtd_free(struct isp1760_qtd *qtd) 934static struct isp1760_qtd *qtd_alloc(gfp_t flags, struct urb *urb,
935 u8 packet_type)
936{
937 struct isp1760_qtd *qtd;
938
939 qtd = kmem_cache_zalloc(qtd_cachep, flags);
940 if (!qtd)
941 return NULL;
942
943 INIT_LIST_HEAD(&qtd->qtd_list);
944 qtd->urb = urb;
945 qtd->packet_type = packet_type;
946
947 return qtd;
948}
949
950static void qtd_free(struct isp1760_qtd *qtd)
952{ 951{
953 BUG_ON(qtd->payload_addr); 952 WARN_ON(qtd->payload_addr);
954 kmem_cache_free(qtd_cachep, qtd); 953 kmem_cache_free(qtd_cachep, qtd);
955} 954}
956 955
@@ -965,7 +964,7 @@ static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd,
965 tmp_qtd = list_entry(qtd->qtd_list.next, struct isp1760_qtd, 964 tmp_qtd = list_entry(qtd->qtd_list.next, struct isp1760_qtd,
966 qtd_list); 965 qtd_list);
967 list_del(&qtd->qtd_list); 966 list_del(&qtd->qtd_list);
968 isp1760_qtd_free(qtd); 967 qtd_free(qtd);
969 return tmp_qtd; 968 return tmp_qtd;
970} 969}
971 970
@@ -1294,210 +1293,95 @@ static void do_intl_int(struct usb_hcd *hcd)
1294 } 1293 }
1295} 1294}
1296 1295
1297static struct isp1760_qh *qh_make(struct usb_hcd *hcd, struct urb *urb, 1296static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len)
1298 gfp_t flags)
1299{
1300 struct isp1760_qh *qh;
1301 int is_input, type;
1302
1303 qh = isp1760_qh_alloc(flags);
1304 if (!qh)
1305 return qh;
1306
1307 /*
1308 * init endpoint/device data for this QH
1309 */
1310 is_input = usb_pipein(urb->pipe);
1311 type = usb_pipetype(urb->pipe);
1312
1313 if (!usb_pipecontrol(urb->pipe))
1314 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input,
1315 1);
1316 return qh;
1317}
1318
1319/*
1320 * For control/bulk/interrupt, return QH with these TDs appended.
1321 * Allocates and initializes the QH if necessary.
1322 * Returns null if it can't allocate a QH it needs to.
1323 * If the QH has TDs (urbs) already, that's great.
1324 */
1325static struct isp1760_qh *qh_append_tds(struct usb_hcd *hcd,
1326 struct urb *urb, struct list_head *qtd_list, int epnum,
1327 void **ptr)
1328{ 1297{
1329 struct isp1760_qh *qh; 1298 qtd->data_buffer = databuffer;
1330
1331 qh = (struct isp1760_qh *)*ptr;
1332 if (!qh) {
1333 /* can't sleep here, we have priv->lock... */
1334 qh = qh_make(hcd, urb, GFP_ATOMIC);
1335 if (!qh)
1336 return qh;
1337 *ptr = qh;
1338 }
1339 1299
1340 list_splice(qtd_list, qh->qtd_list.prev); 1300 if (len > MAX_PAYLOAD_SIZE)
1301 len = MAX_PAYLOAD_SIZE;
1302 qtd->length = len;
1341 1303
1342 return qh; 1304 return qtd->length;
1343} 1305}
1344 1306
1345static void qtd_list_free(struct urb *urb, struct list_head *qtd_list) 1307static void qtd_list_free(struct list_head *qtd_list)
1346{ 1308{
1347 struct list_head *entry, *temp; 1309 struct isp1760_qtd *qtd, *qtd_next;
1348 1310
1349 list_for_each_safe(entry, temp, qtd_list) { 1311 list_for_each_entry_safe(qtd, qtd_next, qtd_list, qtd_list) {
1350 struct isp1760_qtd *qtd;
1351
1352 qtd = list_entry(entry, struct isp1760_qtd, qtd_list);
1353 list_del(&qtd->qtd_list); 1312 list_del(&qtd->qtd_list);
1354 isp1760_qtd_free(qtd); 1313 qtd_free(qtd);
1355 } 1314 }
1356} 1315}
1357 1316
1358static int isp1760_prepare_enqueue(struct usb_hcd *hcd, struct urb *urb,
1359 struct list_head *qtd_list, gfp_t mem_flags, packet_enqueue *p)
1360{
1361 struct isp1760_hcd *priv = hcd_to_priv(hcd);
1362 struct isp1760_qtd *qtd;
1363 int epnum;
1364 unsigned long flags;
1365 struct isp1760_qh *qh = NULL;
1366 int rc;
1367 int qh_busy;
1368
1369 qtd = list_entry(qtd_list->next, struct isp1760_qtd, qtd_list);
1370 epnum = urb->ep->desc.bEndpointAddress;
1371
1372 spin_lock_irqsave(&priv->lock, flags);
1373 if (!HCD_HW_ACCESSIBLE(hcd)) {
1374 rc = -ESHUTDOWN;
1375 goto done;
1376 }
1377 rc = usb_hcd_link_urb_to_ep(hcd, urb);
1378 if (rc)
1379 goto done;
1380
1381 qh = urb->ep->hcpriv;
1382 if (qh)
1383 qh_busy = !list_empty(&qh->qtd_list);
1384 else
1385 qh_busy = 0;
1386
1387 qh = qh_append_tds(hcd, urb, qtd_list, epnum, &urb->ep->hcpriv);
1388 if (!qh) {
1389 usb_hcd_unlink_urb_from_ep(hcd, urb);
1390 rc = -ENOMEM;
1391 goto done;
1392 }
1393
1394 if (!qh_busy)
1395 p(hcd, qh, qtd);
1396
1397done:
1398 spin_unlock_irqrestore(&priv->lock, flags);
1399 if (!qh)
1400 qtd_list_free(urb, qtd_list);
1401 return rc;
1402}
1403
1404static struct isp1760_qtd *isp1760_qtd_alloc(gfp_t flags)
1405{
1406 struct isp1760_qtd *qtd;
1407
1408 qtd = kmem_cache_zalloc(qtd_cachep, flags);
1409 if (qtd)
1410 INIT_LIST_HEAD(&qtd->qtd_list);
1411
1412 return qtd;
1413}
1414
1415/* 1317/*
1416 * create a list of filled qtds for this URB; won't link into qh. 1318 * Packetize urb->transfer_buffer into list of packets of size wMaxPacketSize.
1319 * Also calculate the PID type (SETUP/IN/OUT) for each packet.
1417 */ 1320 */
1418#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) 1321#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
1419static struct list_head *qh_urb_transaction(struct usb_hcd *hcd, 1322static void packetize_urb(struct usb_hcd *hcd,
1420 struct urb *urb, struct list_head *head, gfp_t flags) 1323 struct urb *urb, struct list_head *head, gfp_t flags)
1421{ 1324{
1422 struct isp1760_qtd *qtd; 1325 struct isp1760_qtd *qtd;
1423 void *buf; 1326 void *buf;
1424 int len, maxpacket; 1327 int len, maxpacketsize;
1425 int is_input; 1328 u8 packet_type;
1426 u32 token;
1427 1329
1428 /* 1330 /*
1429 * URBs map to sequences of QTDs: one logical transaction 1331 * URBs map to sequences of QTDs: one logical transaction
1430 */ 1332 */
1431 qtd = isp1760_qtd_alloc(flags);
1432 if (!qtd)
1433 return NULL;
1434 1333
1435 list_add_tail(&qtd->qtd_list, head); 1334 if (!urb->transfer_buffer && urb->transfer_buffer_length) {
1436 qtd->urb = urb; 1335 /* XXX This looks like usb storage / SCSI bug */
1437 urb->status = -EINPROGRESS; 1336 dev_err(hcd->self.controller,
1337 "buf is null, dma is %08lx len is %d\n",
1338 (long unsigned)urb->transfer_dma,
1339 urb->transfer_buffer_length);
1340 WARN_ON(1);
1341 }
1438 1342
1439 token = 0; 1343 if (usb_pipein(urb->pipe))
1440 /* for split transactions, SplitXState initialized to zero */ 1344 packet_type = IN_PID;
1345 else
1346 packet_type = OUT_PID;
1441 1347
1442 len = urb->transfer_buffer_length;
1443 is_input = usb_pipein(urb->pipe);
1444 if (usb_pipecontrol(urb->pipe)) { 1348 if (usb_pipecontrol(urb->pipe)) {
1445 /* SETUP pid */ 1349 qtd = qtd_alloc(flags, urb, SETUP_PID);
1446 qtd_fill(qtd, urb->setup_packet,
1447 sizeof(struct usb_ctrlrequest),
1448 token | SETUP_PID);
1449
1450 /* ... and always at least one more pid */
1451 qtd = isp1760_qtd_alloc(flags);
1452 if (!qtd) 1350 if (!qtd)
1453 goto cleanup; 1351 goto cleanup;
1454 qtd->urb = urb; 1352 qtd_fill(qtd, urb->setup_packet, sizeof(struct usb_ctrlrequest));
1455 list_add_tail(&qtd->qtd_list, head); 1353 list_add_tail(&qtd->qtd_list, head);
1456 1354
1457 /* for zero length DATA stages, STATUS is always IN */ 1355 /* for zero length DATA stages, STATUS is always IN */
1458 if (len == 0) 1356 if (urb->transfer_buffer_length == 0)
1459 token |= IN_PID; 1357 packet_type = IN_PID;
1460 } 1358 }
1461 1359
1462 /* 1360 maxpacketsize = max_packet(usb_maxpacket(urb->dev, urb->pipe,
1463 * data transfer stage: buffer setup 1361 usb_pipeout(urb->pipe)));
1464 */
1465 buf = urb->transfer_buffer;
1466
1467 if (is_input)
1468 token |= IN_PID;
1469 else
1470 token |= OUT_PID;
1471
1472 maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
1473 1362
1474 /* 1363 /*
1475 * buffer gets wrapped in one or more qtds; 1364 * buffer gets wrapped in one or more qtds;
1476 * last one may be "short" (including zero len) 1365 * last one may be "short" (including zero len)
1477 * and may serve as a control status ack 1366 * and may serve as a control status ack
1478 */ 1367 */
1368 buf = urb->transfer_buffer;
1369 len = urb->transfer_buffer_length;
1370
1479 for (;;) { 1371 for (;;) {
1480 int this_qtd_len; 1372 int this_qtd_len;
1481 1373
1482 if (!buf && len) { 1374 qtd = qtd_alloc(flags, urb, packet_type);
1483 /* XXX This looks like usb storage / SCSI bug */ 1375 if (!qtd)
1484 dev_err(hcd->self.controller, "buf is null, dma is %08lx len is %d\n", 1376 goto cleanup;
1485 (long unsigned)urb->transfer_dma, len); 1377 this_qtd_len = qtd_fill(qtd, buf, len);
1486 WARN_ON(1); 1378 list_add_tail(&qtd->qtd_list, head);
1487 }
1488 1379
1489 this_qtd_len = qtd_fill(qtd, buf, len, token);
1490 len -= this_qtd_len; 1380 len -= this_qtd_len;
1491 buf += this_qtd_len; 1381 buf += this_qtd_len;
1492 1382
1493 if (len <= 0) 1383 if (len <= 0)
1494 break; 1384 break;
1495
1496 qtd = isp1760_qtd_alloc(flags);
1497 if (!qtd)
1498 goto cleanup;
1499 qtd->urb = urb;
1500 list_add_tail(&qtd->qtd_list, head);
1501 } 1385 }
1502 1386
1503 /* 1387 /*
@@ -1509,31 +1393,78 @@ static struct list_head *qh_urb_transaction(struct usb_hcd *hcd,
1509 1393
1510 if (usb_pipecontrol(urb->pipe)) { 1394 if (usb_pipecontrol(urb->pipe)) {
1511 one_more = 1; 1395 one_more = 1;
1512 /* "in" <--> "out" */ 1396 if (packet_type == IN_PID)
1513 token ^= IN_PID; 1397 packet_type = OUT_PID;
1398 else
1399 packet_type = IN_PID;
1514 } else if (usb_pipebulk(urb->pipe) 1400 } else if (usb_pipebulk(urb->pipe)
1515 && (urb->transfer_flags & URB_ZERO_PACKET) 1401 && (urb->transfer_flags & URB_ZERO_PACKET)
1516 && !(urb->transfer_buffer_length % maxpacket)) { 1402 && !(urb->transfer_buffer_length %
1403 maxpacketsize)) {
1517 one_more = 1; 1404 one_more = 1;
1518 } 1405 }
1519 if (one_more) { 1406 if (one_more) {
1520 qtd = isp1760_qtd_alloc(flags); 1407 qtd = qtd_alloc(flags, urb, packet_type);
1521 if (!qtd) 1408 if (!qtd)
1522 goto cleanup; 1409 goto cleanup;
1523 qtd->urb = urb;
1524 list_add_tail(&qtd->qtd_list, head);
1525 1410
1526 /* never any data in such packets */ 1411 /* never any data in such packets */
1527 qtd_fill(qtd, NULL, 0, token); 1412 qtd_fill(qtd, NULL, 0);
1413 list_add_tail(&qtd->qtd_list, head);
1528 } 1414 }
1529 } 1415 }
1530 1416
1531 qtd->status = 0; 1417 return;
1532 return head;
1533 1418
1534cleanup: 1419cleanup:
1535 qtd_list_free(urb, head); 1420 qtd_list_free(head);
1536 return NULL; 1421}
1422
1423static int enqueue_qtdlist(struct usb_hcd *hcd, struct urb *urb,
1424 struct list_head *qtd_list, gfp_t mem_flags, packet_enqueue *p)
1425{
1426 struct isp1760_hcd *priv = hcd_to_priv(hcd);
1427 struct isp1760_qtd *qtd;
1428 struct isp1760_qh *qh = NULL;
1429 unsigned long flags;
1430 int qh_empty;
1431 int rc;
1432
1433 spin_lock_irqsave(&priv->lock, flags);
1434 if (!HCD_HW_ACCESSIBLE(hcd)) {
1435 rc = -ESHUTDOWN;
1436 goto done;
1437 }
1438 rc = usb_hcd_link_urb_to_ep(hcd, urb);
1439 if (rc)
1440 goto done;
1441
1442 qh = urb->ep->hcpriv;
1443 if (!qh) {
1444 qh = isp1760_qh_alloc(GFP_ATOMIC);
1445 if (!qh) {
1446 usb_hcd_unlink_urb_from_ep(hcd, urb);
1447 rc = -ENOMEM;
1448 goto done;
1449 }
1450 if (!usb_pipecontrol(urb->pipe))
1451 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
1452 !usb_pipein(urb->pipe), 1);
1453 urb->ep->hcpriv = qh;
1454 }
1455
1456 qh_empty = list_empty(&qh->qtd_list);
1457 list_splice_tail(qtd_list, &qh->qtd_list);
1458 if (qh_empty) {
1459 qtd = list_entry(qtd_list->next, struct isp1760_qtd, qtd_list);
1460 p(hcd, qh, qtd);
1461 }
1462
1463done:
1464 spin_unlock_irqrestore(&priv->lock, flags);
1465 if (!qh)
1466 qtd_list_free(qtd_list);
1467 return rc;
1537} 1468}
1538 1469
1539static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, 1470static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
@@ -1547,14 +1478,10 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
1547 switch (usb_pipetype(urb->pipe)) { 1478 switch (usb_pipetype(urb->pipe)) {
1548 case PIPE_CONTROL: 1479 case PIPE_CONTROL:
1549 case PIPE_BULK: 1480 case PIPE_BULK:
1550 if (!qh_urb_transaction(hcd, urb, &qtd_list, mem_flags)) 1481 pe = enqueue_an_ATL_packet;
1551 return -ENOMEM;
1552 pe = enqueue_an_ATL_packet;
1553 break; 1482 break;
1554 1483
1555 case PIPE_INTERRUPT: 1484 case PIPE_INTERRUPT:
1556 if (!qh_urb_transaction(hcd, urb, &qtd_list, mem_flags))
1557 return -ENOMEM;
1558 pe = enqueue_an_INT_packet; 1485 pe = enqueue_an_INT_packet;
1559 break; 1486 break;
1560 1487
@@ -1564,7 +1491,11 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
1564 return -EPIPE; 1491 return -EPIPE;
1565 } 1492 }
1566 1493
1567 return isp1760_prepare_enqueue(hcd, urb, &qtd_list, mem_flags, pe); 1494 packetize_urb(hcd, urb, &qtd_list, mem_flags);
1495 if (list_empty(&qtd_list))
1496 return -ENOMEM;
1497
1498 return enqueue_qtdlist(hcd, urb, &qtd_list, mem_flags, pe);
1568} 1499}
1569 1500
1570static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) 1501static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
@@ -1605,7 +1536,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
1605 for (i = 0; i < 32; i++) { 1536 for (i = 0; i < 32; i++) {
1606 if (!ints[i].qh) 1537 if (!ints[i].qh)
1607 continue; 1538 continue;
1608 BUG_ON(!ints[i].qtd); 1539 WARN_ON(!ints[i].qtd);
1609 1540
1610 if (ints[i].qtd->urb == urb) { 1541 if (ints[i].qtd->urb == urb) {
1611 u32 skip_map; 1542 u32 skip_map;