Felipe writes: usb: patches for v3.17 merge window Surprisingly enough, while a big set of patches, the majority is composed of cleanups (using devm_*, fixing sparse errors, moving code around, adding const, etc). The highlights are addition of new support for PLX USB338x devices, and support for USB 2.0-only configurations of the DWC3 IP core.
Unified · Split
| @@ -556,11 +556,11 @@ been converted to this framework. · 555 unmodified lines | |||
| 556 | Near-term plans include converting all of them, except for "gadgetfs". | 556 | Near-term plans include converting all of them, except for "gadgetfs". |
| 557 | </para> | 557 | </para> |
| 558 | 558 | ||
| 559 | !Edrivers/usb/gadget/f_acm.c | 559 | !Edrivers/usb/gadget/function/f_acm.c |
| 560 | !Edrivers/usb/gadget/f_ecm.c | 560 | !Edrivers/usb/gadget/function/f_ecm.c |
| 561 | !Edrivers/usb/gadget/f_subset.c | 561 | !Edrivers/usb/gadget/function/f_subset.c |
| 562 | !Edrivers/usb/gadget/f_obex.c | 562 | !Edrivers/usb/gadget/function/f_obex.c |
| 563 | !Edrivers/usb/gadget/f_serial.c | 563 | !Edrivers/usb/gadget/function/f_serial.c |
| 564 | 564 | ||
| 565 | </sect1> | 565 | </sect1> |
| 566 | 566 | ||
| @@ -386,6 +386,13 @@ static int dwc3_core_init(struct dwc3 *dwc) · 385 unmodified lines | |||
| 386 | } | 386 | } |
| 387 | dwc->revision = reg; | 387 | dwc->revision = reg; |
| 388 | 388 | ||
| 389 | /* Handle USB2.0-only core configuration */ | ||
| 390 | if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == | ||
| 391 | DWC3_GHWPARAMS3_SSPHY_IFC_DIS) { | ||
| 392 | if (dwc->maximum_speed == USB_SPEED_SUPER) | ||
| 393 | dwc->maximum_speed = USB_SPEED_HIGH; | ||
| 394 | } | ||
| 395 | |||
| 389 | /* issue device SoftReset too */ | 396 | /* issue device SoftReset too */ |
| 390 | timeout = jiffies + msecs_to_jiffies(500); | 397 | timeout = jiffies + msecs_to_jiffies(500); |
| 391 | dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); | 398 | dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); |
| @@ -656,6 +663,31 @@ static int dwc3_probe(struct platform_device *pdev) · 264 unmodified lines | |||
| 656 | return -ENODEV; | 663 | return -ENODEV; |
| 657 | } | 664 | } |
| 658 | 665 | ||
| 666 | dwc->xhci_resources[0].start = res->start; | ||
| 667 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + | ||
| 668 | DWC3_XHCI_REGS_END; | ||
| 669 | dwc->xhci_resources[0].flags = res->flags; | ||
| 670 | dwc->xhci_resources[0].name = res->name; | ||
| 671 | |||
| 672 | res->start += DWC3_GLOBALS_REGS_START; | ||
| 673 | |||
| 674 | /* | ||
| 675 | * Request memory region but exclude xHCI regs, | ||
| 676 | * since it will be requested by the xhci-plat driver. | ||
| 677 | */ | ||
| 678 | regs = devm_ioremap_resource(dev, res); | ||
| 679 | if (IS_ERR(regs)) | ||
| 680 | return PTR_ERR(regs); | ||
| 681 | |||
| 682 | dwc->regs = regs; | ||
| 683 | dwc->regs_size = resource_size(res); | ||
| 684 | /* | ||
| 685 | * restore res->start back to its original value so that, | ||
| 686 | * in case the probe is deferred, we don't end up getting error in | ||
| 687 | * request the memory region the next time probe is called. | ||
| 688 | */ | ||
| 689 | res->start -= DWC3_GLOBALS_REGS_START; | ||
| 690 | |||
| 659 | if (node) { | 691 | if (node) { |
| 660 | dwc->maximum_speed = of_usb_get_maximum_speed(node); | 692 | dwc->maximum_speed = of_usb_get_maximum_speed(node); |
| 661 | 693 | ||
| @@ -676,28 +708,9 @@ static int dwc3_probe(struct platform_device *pdev) · 14 unmodified lines | |||
| 676 | if (ret) | 708 | if (ret) |
| 677 | return ret; | 709 | return ret; |
| 678 | 710 | ||
| 679 | dwc->xhci_resources[0].start = res->start; | ||
| 680 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + | ||
| 681 | DWC3_XHCI_REGS_END; | ||
| 682 | dwc->xhci_resources[0].flags = res->flags; | ||
| 683 | dwc->xhci_resources[0].name = res->name; | ||
| 684 | |||
| 685 | res->start += DWC3_GLOBALS_REGS_START; | ||
| 686 | |||
| 687 | /* | ||
| 688 | * Request memory region but exclude xHCI regs, | ||
| 689 | * since it will be requested by the xhci-plat driver. | ||
| 690 | */ | ||
| 691 | regs = devm_ioremap_resource(dev, res); | ||
| 692 | if (IS_ERR(regs)) | ||
| 693 | return PTR_ERR(regs); | ||
| 694 | |||
| 695 | spin_lock_init(&dwc->lock); | 711 | spin_lock_init(&dwc->lock); |
| 696 | platform_set_drvdata(pdev, dwc); | 712 | platform_set_drvdata(pdev, dwc); |
| 697 | 713 | ||
| 698 | dwc->regs = regs; | ||
| 699 | dwc->regs_size = resource_size(res); | ||
| 700 | |||
| 701 | dev->dma_mask = dev->parent->dma_mask; | 714 | dev->dma_mask = dev->parent->dma_mask; |
| 702 | dev->dma_parms = dev->parent->dma_parms; | 715 | dev->dma_parms = dev->parent->dma_parms; |
| 703 | dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); | 716 | dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); |
| @@ -191,6 +191,19 @@ · 190 unmodified lines | |||
| 191 | #define DWC3_GHWPARAMS1_PWROPT(n) ((n) << 24) | 191 | #define DWC3_GHWPARAMS1_PWROPT(n) ((n) << 24) |
| 192 | #define DWC3_GHWPARAMS1_PWROPT_MASK DWC3_GHWPARAMS1_PWROPT(3) | 192 | #define DWC3_GHWPARAMS1_PWROPT_MASK DWC3_GHWPARAMS1_PWROPT(3) |
| 193 | 193 | ||
| 194 | /* Global HWPARAMS3 Register */ | ||
| 195 | #define DWC3_GHWPARAMS3_SSPHY_IFC(n) ((n) & 3) | ||
| 196 | #define DWC3_GHWPARAMS3_SSPHY_IFC_DIS 0 | ||
| 197 | #define DWC3_GHWPARAMS3_SSPHY_IFC_ENA 1 | ||
| 198 | #define DWC3_GHWPARAMS3_HSPHY_IFC(n) (((n) & (3 << 2)) >> 2) | ||
| 199 | #define DWC3_GHWPARAMS3_HSPHY_IFC_DIS 0 | ||
| 200 | #define DWC3_GHWPARAMS3_HSPHY_IFC_UTMI 1 | ||
| 201 | #define DWC3_GHWPARAMS3_HSPHY_IFC_ULPI 2 | ||
| 202 | #define DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI 3 | ||
| 203 | #define DWC3_GHWPARAMS3_FSPHY_IFC(n) (((n) & (3 << 4)) >> 4) | ||
| 204 | #define DWC3_GHWPARAMS3_FSPHY_IFC_DIS 0 | ||
| 205 | #define DWC3_GHWPARAMS3_FSPHY_IFC_ENA 1 | ||
| 206 | |||
| 194 | /* Global HWPARAMS4 Register */ | 207 | /* Global HWPARAMS4 Register */ |
| 195 | #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n) (((n) & (0x0f << 13)) >> 13) | 208 | #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n) (((n) & (0x0f << 13)) >> 13) |
| 196 | #define DWC3_MAX_HIBER_SCRATCHBUFS 15 | 209 | #define DWC3_MAX_HIBER_SCRATCHBUFS 15 |
| @@ -77,10 +77,6 @@ · 76 unmodified lines | |||
| 77 | #define USBOTGSS_DEV_EBC_EN 0x0110 | 77 | #define USBOTGSS_DEV_EBC_EN 0x0110 |
| 78 | #define USBOTGSS_DEBUG_OFFSET 0x0600 | 78 | #define USBOTGSS_DEBUG_OFFSET 0x0600 |
| 79 | 79 | ||
| 80 | /* REVISION REGISTER */ | ||
| 81 | #define USBOTGSS_REVISION_XMAJOR(reg) ((reg >> 8) & 0x7) | ||
| 82 | #define USBOTGSS_REVISION_XMAJOR1 1 | ||
| 83 | #define USBOTGSS_REVISION_XMAJOR2 2 | ||
| 84 | /* SYSCONFIG REGISTER */ | 80 | /* SYSCONFIG REGISTER */ |
| 85 | #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) | 81 | #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) |
| 86 | 82 | ||
| @@ -129,7 +125,6 @@ struct dwc3_omap { · 42 unmodified lines | |||
| 129 | u32 irq_eoi_offset; | 125 | u32 irq_eoi_offset; |
| 130 | u32 debug_offset; | 126 | u32 debug_offset; |
| 131 | u32 irq0_offset; | 127 | u32 irq0_offset; |
| 132 | u32 revision; | ||
| 133 | 128 | ||
| 134 | u32 dma_status:1; | 129 | u32 dma_status:1; |
| 135 | 130 | ||
| @@ -383,6 +378,87 @@ static int dwc3_omap_vbus_notifier(struct notifier_block *nb, · 247 unmodified lines | |||
| 383 | return NOTIFY_DONE; | 378 | return NOTIFY_DONE; |
| 384 | } | 379 | } |
| 385 | 380 | ||
| 381 | static void dwc3_omap_map_offset(struct dwc3_omap *omap) | ||
| 382 | { | ||
| 383 | struct device_node *node = omap->dev->of_node; | ||
| 384 | |||
| 385 | /* | ||
| 386 | * Differentiate between OMAP5 and AM437x. | ||
| 387 | * | ||
| 388 | * For OMAP5(ES2.0) and AM437x wrapper revision is same, even | ||
| 389 | * though there are changes in wrapper register offsets. | ||
| 390 | * | ||
| 391 | * Using dt compatible to differentiate AM437x. | ||
| 392 | */ | ||
| 393 | if (of_device_is_compatible(node, "ti,am437x-dwc3")) { | ||
| 394 | omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; | ||
| 395 | omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; | ||
| 396 | omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; | ||
| 397 | omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; | ||
| 398 | omap->debug_offset = USBOTGSS_DEBUG_OFFSET; | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 402 | static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap) | ||
| 403 | { | ||
| 404 | u32 reg; | ||
| 405 | struct device_node *node = omap->dev->of_node; | ||
| 406 | int utmi_mode = 0; | ||
| 407 | |||
| 408 | reg = dwc3_omap_read_utmi_status(omap); | ||
| 409 | |||
| 410 | of_property_read_u32(node, "utmi-mode", &utmi_mode); | ||
| 411 | |||
| 412 | switch (utmi_mode) { | ||
| 413 | case DWC3_OMAP_UTMI_MODE_SW: | ||
| 414 | reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
| 415 | break; | ||
| 416 | case DWC3_OMAP_UTMI_MODE_HW: | ||
| 417 | reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
| 418 | break; | ||
| 419 | default: | ||
| 420 | dev_dbg(omap->dev, "UNKNOWN utmi mode %d\n", utmi_mode); | ||
| 421 | } | ||
| 422 | |||
| 423 | dwc3_omap_write_utmi_status(omap, reg); | ||
| 424 | } | ||
| 425 | |||
| 426 | static int dwc3_omap_extcon_register(struct dwc3_omap *omap) | ||
| 427 | { | ||
| 428 | u32 ret; | ||
| 429 | struct device_node *node = omap->dev->of_node; | ||
| 430 | struct extcon_dev *edev; | ||
| 431 | |||
| 432 | if (of_property_read_bool(node, "extcon")) { | ||
| 433 | edev = extcon_get_edev_by_phandle(omap->dev, 0); | ||
| 434 | if (IS_ERR(edev)) { | ||
| 435 | dev_vdbg(omap->dev, "couldn't get extcon device\n"); | ||
| 436 | return -EPROBE_DEFER; | ||
| 437 | } | ||
| 438 | |||
| 439 | omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier; | ||
| 440 | ret = extcon_register_interest(&omap->extcon_vbus_dev, | ||
| 441 | edev->name, "USB", | ||
| 442 | &omap->vbus_nb); | ||
| 443 | if (ret < 0) | ||
| 444 | dev_vdbg(omap->dev, "failed to register notifier for USB\n"); | ||
| 445 | |||
| 446 | omap->id_nb.notifier_call = dwc3_omap_id_notifier; | ||
| 447 | ret = extcon_register_interest(&omap->extcon_id_dev, | ||
| 448 | edev->name, "USB-HOST", | ||
| 449 | &omap->id_nb); | ||
| 450 | if (ret < 0) | ||
| 451 | dev_vdbg(omap->dev, "failed to register notifier for USB-HOST\n"); | ||
| 452 | |||
| 453 | if (extcon_get_cable_state(edev, "USB") == true) | ||
| 454 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); | ||
| 455 | if (extcon_get_cable_state(edev, "USB-HOST") == true) | ||
| 456 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); | ||
| 457 | } | ||
| 458 | |||
| 459 | return 0; | ||
| 460 | } | ||
| 461 | |||
| 386 | static int dwc3_omap_probe(struct platform_device *pdev) | 462 | static int dwc3_omap_probe(struct platform_device *pdev) |
| 387 | { | 463 | { |
| 388 | struct device_node *node = pdev->dev.of_node; | 464 | struct device_node *node = pdev->dev.of_node; |
| @@ -390,15 +466,11 @@ static int dwc3_omap_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 390 | struct dwc3_omap *omap; | 466 | struct dwc3_omap *omap; |
| 391 | struct resource *res; | 467 | struct resource *res; |
| 392 | struct device *dev = &pdev->dev; | 468 | struct device *dev = &pdev->dev; |
| 393 | struct extcon_dev *edev; | ||
| 394 | struct regulator *vbus_reg = NULL; | 469 | struct regulator *vbus_reg = NULL; |
| 395 | 470 | ||
| 396 | int ret; | 471 | int ret; |
| 397 | int irq; | 472 | int irq; |
| 398 | 473 | ||
| 399 | int utmi_mode = 0; | ||
| 400 | int x_major; | ||
| 401 | |||
| 402 | u32 reg; | 474 | u32 reg; |
| 403 | 475 | ||
| 404 | void __iomem *base; | 476 | void __iomem *base; |
| @@ -448,58 +520,8 @@ static int dwc3_omap_probe(struct platform_device *pdev) · 43 unmodified lines | |||
| 448 | goto err0; | 520 | goto err0; |
| 449 | } | 521 | } |
| 450 | 522 | ||
| 451 | reg = dwc3_omap_readl(omap->base, USBOTGSS_REVISION); | 523 | dwc3_omap_map_offset(omap); |
| 452 | omap->revision = reg; | 524 | dwc3_omap_set_utmi_mode(omap); |
| 453 | x_major = USBOTGSS_REVISION_XMAJOR(reg); | ||
| 454 | |||
| 455 | /* Differentiate between OMAP5 and AM437x */ | ||
| 456 | switch (x_major) { | ||
| 457 | case USBOTGSS_REVISION_XMAJOR1: | ||
| 458 | case USBOTGSS_REVISION_XMAJOR2: | ||
| 459 | omap->irq_eoi_offset = 0; | ||
| 460 | omap->irq0_offset = 0; | ||
| 461 | omap->irqmisc_offset = 0; | ||
| 462 | omap->utmi_otg_offset = 0; | ||
| 463 | omap->debug_offset = 0; | ||
| 464 | break; | ||
| 465 | default: | ||
| 466 | /* Default to the latest revision */ | ||
| 467 | omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; | ||
| 468 | omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; | ||
| 469 | omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; | ||
| 470 | omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; | ||
| 471 | omap->debug_offset = USBOTGSS_DEBUG_OFFSET; | ||
| 472 | break; | ||
| 473 | } | ||
| 474 | |||
| 475 | /* For OMAP5(ES2.0) and AM437x x_major is 2 even though there are | ||
| 476 | * changes in wrapper registers, Using dt compatible for aegis | ||
| 477 | */ | ||
| 478 | |||
| 479 | if (of_device_is_compatible(node, "ti,am437x-dwc3")) { | ||
| 480 | omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; | ||
| 481 | omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; | ||
| 482 | omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; | ||
| 483 | omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; | ||
| 484 | omap->debug_offset = USBOTGSS_DEBUG_OFFSET; | ||
| 485 | } | ||
| 486 | |||
| 487 | reg = dwc3_omap_read_utmi_status(omap); | ||
| 488 | |||
| 489 | of_property_read_u32(node, "utmi-mode", &utmi_mode); | ||
| 490 | |||
| 491 | switch (utmi_mode) { | ||
| 492 | case DWC3_OMAP_UTMI_MODE_SW: | ||
| 493 | reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
| 494 | break; | ||
| 495 | case DWC3_OMAP_UTMI_MODE_HW: | ||
| 496 | reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
| 497 | break; | ||
| 498 | default: | ||
| 499 | dev_dbg(dev, "UNKNOWN utmi mode %d\n", utmi_mode); | ||
| 500 | } | ||
| 501 | |||
| 502 | dwc3_omap_write_utmi_status(omap, reg); | ||
| 503 | 525 | ||
| 504 | /* check the DMA Status */ | 526 | /* check the DMA Status */ |
| 505 | reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); | 527 | reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); |
| @@ -515,31 +537,9 @@ static int dwc3_omap_probe(struct platform_device *pdev) · 9 unmodified lines | |||
| 515 | 537 | ||
| 516 | dwc3_omap_enable_irqs(omap); | 538 | dwc3_omap_enable_irqs(omap); |
| 517 | 539 | ||
| 518 | if (of_property_read_bool(node, "extcon")) { | 540 | ret = dwc3_omap_extcon_register(omap); |
| 519 | edev = extcon_get_edev_by_phandle(dev, 0); | 541 | if (ret < 0) |
| 520 | if (IS_ERR(edev)) { | 542 | goto err2; |
| 521 | dev_vdbg(dev, "couldn't get extcon device\n"); | ||
| 522 | ret = -EPROBE_DEFER; | ||
| 523 | goto err2; | ||
| 524 | } | ||
| 525 | |||
| 526 | omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier; | ||
| 527 | ret = extcon_register_interest(&omap->extcon_vbus_dev, | ||
| 528 | edev->name, "USB", &omap->vbus_nb); | ||
| 529 | if (ret < 0) | ||
| 530 | dev_vdbg(dev, "failed to register notifier for USB\n"); | ||
| 531 | omap->id_nb.notifier_call = dwc3_omap_id_notifier; | ||
| 532 | ret = extcon_register_interest(&omap->extcon_id_dev, edev->name, | ||
| 533 | "USB-HOST", &omap->id_nb); | ||
| 534 | if (ret < 0) | ||
| 535 | dev_vdbg(dev, | ||
| 536 | "failed to register notifier for USB-HOST\n"); | ||
| 537 | |||
| 538 | if (extcon_get_cable_state(edev, "USB") == true) | ||
| 539 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); | ||
| 540 | if (extcon_get_cable_state(edev, "USB-HOST") == true) | ||
| 541 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); | ||
| 542 | } | ||
| 543 | 543 | ||
| 544 | ret = of_platform_populate(node, NULL, NULL, dev); | 544 | ret = of_platform_populate(node, NULL, NULL, dev); |
| 545 | if (ret) { | 545 | if (ret) { |
| @@ -1971,8 +1971,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, · 1970 unmodified lines | |||
| 1971 | } | 1971 | } |
| 1972 | 1972 | ||
| 1973 | static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, | 1973 | static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, |
| 1974 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event, | 1974 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event) |
| 1975 | int start_new) | ||
| 1976 | { | 1975 | { |
| 1977 | unsigned status = 0; | 1976 | unsigned status = 0; |
| 1978 | int clean_busy; | 1977 | int clean_busy; |
| @@ -2039,7 +2038,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, · 60 unmodified lines | |||
| 2039 | return; | 2038 | return; |
| 2040 | } | 2039 | } |
| 2041 | 2040 | ||
| 2042 | dwc3_endpoint_transfer_complete(dwc, dep, event, 1); | 2041 | dwc3_endpoint_transfer_complete(dwc, dep, event); |
| 2043 | break; | 2042 | break; |
| 2044 | case DWC3_DEPEVT_XFERINPROGRESS: | 2043 | case DWC3_DEPEVT_XFERINPROGRESS: |
| 2045 | if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 2044 | if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |
| @@ -2048,7 +2047,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, · 2 unmodified lines | |||
| 2048 | return; | 2047 | return; |
| 2049 | } | 2048 | } |
| 2050 | 2049 | ||
| 2051 | dwc3_endpoint_transfer_complete(dwc, dep, event, 0); | 2050 | dwc3_endpoint_transfer_complete(dwc, dep, event); |
| 2052 | break; | 2051 | break; |
| 2053 | case DWC3_DEPEVT_XFERNOTREADY: | 2052 | case DWC3_DEPEVT_XFERNOTREADY: |
| 2054 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 2053 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |
| @@ -127,368 +127,7 @@ config USB_GADGET_STORAGE_NUM_BUFFERS · 126 unmodified lines | |||
| 127 | a module parameter as well. | 127 | a module parameter as well. |
| 128 | If unsure, say 2. | 128 | If unsure, say 2. |
| 129 | 129 | ||
| 130 | # | 130 | source "drivers/usb/gadget/udc/Kconfig" |
| 131 | # USB Peripheral Controller Support | ||
| 132 | # | ||
| 133 | # The order here is alphabetical, except that integrated controllers go | ||
| 134 | # before discrete ones so they will be the initial/default value: | ||
| 135 | # - integrated/SOC controllers first | ||
| 136 | # - licensed IP used in both SOC and discrete versions | ||
| 137 | # - discrete ones (including all PCI-only controllers) | ||
| 138 | # - debug/dummy gadget+hcd is last. | ||
| 139 | # | ||
| 140 | menu "USB Peripheral Controller" | ||
| 141 | |||
| 142 | # | ||
| 143 | # Integrated controllers | ||
| 144 | # | ||
| 145 | |||
| 146 | config USB_AT91 | ||
| 147 | tristate "Atmel AT91 USB Device Port" | ||
| 148 | depends on ARCH_AT91 | ||
| 149 | help | ||
| 150 | Many Atmel AT91 processors (such as the AT91RM2000) have a | ||
| 151 | full speed USB Device Port with support for five configurable | ||
| 152 | endpoints (plus endpoint zero). | ||
| 153 | |||
| 154 | Say "y" to link the driver statically, or "m" to build a | ||
| 155 | dynamically linked module called "at91_udc" and force all | ||
| 156 | gadget drivers to also be dynamically linked. | ||
| 157 | |||
| 158 | config USB_LPC32XX | ||
| 159 | tristate "LPC32XX USB Peripheral Controller" | ||
| 160 | depends on ARCH_LPC32XX && I2C | ||
| 161 | select USB_ISP1301 | ||
| 162 | help | ||
| 163 | This option selects the USB device controller in the LPC32xx SoC. | ||
| 164 | |||
| 165 | Say "y" to link the driver statically, or "m" to build a | ||
| 166 | dynamically linked module called "lpc32xx_udc" and force all | ||
| 167 | gadget drivers to also be dynamically linked. | ||
| 168 | |||
| 169 | config USB_ATMEL_USBA | ||
| 170 | tristate "Atmel USBA" | ||
| 171 | depends on AVR32 || ARCH_AT91 | ||
| 172 | help | ||
| 173 | USBA is the integrated high-speed USB Device controller on | ||
| 174 | the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. | ||
| 175 | |||
| 176 | config USB_BCM63XX_UDC | ||
| 177 | tristate "Broadcom BCM63xx Peripheral Controller" | ||
| 178 | depends on BCM63XX | ||
| 179 | help | ||
| 180 | Many Broadcom BCM63xx chipsets (such as the BCM6328) have a | ||
| 181 | high speed USB Device Port with support for four fixed endpoints | ||
| 182 | (plus endpoint zero). | ||
| 183 | |||
| 184 | Say "y" to link the driver statically, or "m" to build a | ||
| 185 | dynamically linked module called "bcm63xx_udc". | ||
| 186 | |||
| 187 | config USB_FSL_USB2 | ||
| 188 | tristate "Freescale Highspeed USB DR Peripheral Controller" | ||
| 189 | depends on FSL_SOC || ARCH_MXC | ||
| 190 | select USB_FSL_MPH_DR_OF if OF | ||
| 191 | help | ||
| 192 | Some of Freescale PowerPC and i.MX processors have a High Speed | ||
| 193 | Dual-Role(DR) USB controller, which supports device mode. | ||
| 194 | |||
| 195 | The number of programmable endpoints is different through | ||
| 196 | SOC revisions. | ||
| 197 | |||
| 198 | Say "y" to link the driver statically, or "m" to build a | ||
| 199 | dynamically linked module called "fsl_usb2_udc" and force | ||
| 200 | all gadget drivers to also be dynamically linked. | ||
| 201 | |||
| 202 | config USB_FUSB300 | ||
| 203 | tristate "Faraday FUSB300 USB Peripheral Controller" | ||
| 204 | depends on !PHYS_ADDR_T_64BIT && HAS_DMA | ||
| 205 | help | ||
| 206 | Faraday usb device controller FUSB300 driver | ||
| 207 | |||
| 208 | config USB_FOTG210_UDC | ||
| 209 | depends on HAS_DMA | ||
| 210 | tristate "Faraday FOTG210 USB Peripheral Controller" | ||
| 211 | help | ||
| 212 | Faraday USB2.0 OTG controller which can be configured as | ||
| 213 | high speed or full speed USB device. This driver supppors | ||
| 214 | Bulk Transfer so far. | ||
| 215 | |||
| 216 | Say "y" to link the driver statically, or "m" to build a | ||
| 217 | dynamically linked module called "fotg210_udc". | ||
| 218 | |||
| 219 | config USB_GR_UDC | ||
| 220 | tristate "Aeroflex Gaisler GRUSBDC USB Peripheral Controller Driver" | ||
| 221 | depends on HAS_DMA | ||
| 222 | help | ||
| 223 | Select this to support Aeroflex Gaisler GRUSBDC cores from the GRLIB | ||
| 224 | VHDL IP core library. | ||
| 225 | |||
| 226 | config USB_OMAP | ||
| 227 | tristate "OMAP USB Device Controller" | ||
| 228 | depends on ARCH_OMAP1 | ||
| 229 | depends on ISP1301_OMAP || !(MACH_OMAP_H2 || MACH_OMAP_H3) | ||
| 230 | help | ||
| 231 | Many Texas Instruments OMAP processors have flexible full | ||
| 232 | speed USB device controllers, with support for up to 30 | ||
| 233 | endpoints (plus endpoint zero). This driver supports the | ||
| 234 | controller in the OMAP 1611, and should work with controllers | ||
| 235 | in other OMAP processors too, given minor tweaks. | ||
| 236 | |||
| 237 | Say "y" to link the driver statically, or "m" to build a | ||
| 238 | dynamically linked module called "omap_udc" and force all | ||
| 239 | gadget drivers to also be dynamically linked. | ||
| 240 | |||
| 241 | config USB_PXA25X | ||
| 242 | tristate "PXA 25x or IXP 4xx" | ||
| 243 | depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX | ||
| 244 | help | ||
| 245 | Intel's PXA 25x series XScale ARM-5TE processors include | ||
| 246 | an integrated full speed USB 1.1 device controller. The | ||
| 247 | controller in the IXP 4xx series is register-compatible. | ||
| 248 | |||
| 249 | It has fifteen fixed-function endpoints, as well as endpoint | ||
| 250 | zero (for control transfers). | ||
| 251 | |||
| 252 | Say "y" to link the driver statically, or "m" to build a | ||
| 253 | dynamically linked module called "pxa25x_udc" and force all | ||
| 254 | gadget drivers to also be dynamically linked. | ||
| 255 | |||
| 256 | # if there's only one gadget driver, using only two bulk endpoints, | ||
| 257 | # don't waste memory for the other endpoints | ||
| 258 | config USB_PXA25X_SMALL | ||
| 259 | depends on USB_PXA25X | ||
| 260 | bool | ||
| 261 | default n if USB_ETH_RNDIS | ||
| 262 | default y if USB_ZERO | ||
| 263 | default y if USB_ETH | ||
| 264 | default y if USB_G_SERIAL | ||
| 265 | |||
| 266 | config USB_R8A66597 | ||
| 267 | tristate "Renesas R8A66597 USB Peripheral Controller" | ||
| 268 | depends on HAS_DMA | ||
| 269 | help | ||
| 270 | R8A66597 is a discrete USB host and peripheral controller chip that | ||
| 271 | supports both full and high speed USB 2.0 data transfers. | ||
| 272 | It has nine configurable endpoints, and endpoint zero. | ||
| 273 | |||
| 274 | Say "y" to link the driver statically, or "m" to build a | ||
| 275 | dynamically linked module called "r8a66597_udc" and force all | ||
| 276 | gadget drivers to also be dynamically linked. | ||
| 277 | |||
| 278 | config USB_RENESAS_USBHS_UDC | ||
| 279 | tristate 'Renesas USBHS controller' | ||
| 280 | depends on USB_RENESAS_USBHS | ||
| 281 | help | ||
| 282 | Renesas USBHS is a discrete USB host and peripheral controller chip | ||
| 283 | that supports both full and high speed USB 2.0 data transfers. | ||
| 284 | It has nine or more configurable endpoints, and endpoint zero. | ||
| 285 | |||
| 286 | Say "y" to link the driver statically, or "m" to build a | ||
| 287 | dynamically linked module called "renesas_usbhs" and force all | ||
| 288 | gadget drivers to also be dynamically linked. | ||
| 289 | |||
| 290 | config USB_PXA27X | ||
| 291 | tristate "PXA 27x" | ||
| 292 | help | ||
| 293 | Intel's PXA 27x series XScale ARM v5TE processors include | ||
| 294 | an integrated full speed USB 1.1 device controller. | ||
| 295 | |||
| 296 | It has up to 23 endpoints, as well as endpoint zero (for | ||
| 297 | control transfers). | ||
| 298 | |||
| 299 | Say "y" to link the driver statically, or "m" to build a | ||
| 300 | dynamically linked module called "pxa27x_udc" and force all | ||
| 301 | gadget drivers to also be dynamically linked. | ||
| 302 | |||
| 303 | config USB_S3C2410 | ||
| 304 | tristate "S3C2410 USB Device Controller" | ||
| 305 | depends on ARCH_S3C24XX | ||
| 306 | help | ||
| 307 | Samsung's S3C2410 is an ARM-4 processor with an integrated | ||
| 308 | full speed USB 1.1 device controller. It has 4 configurable | ||
| 309 | endpoints, as well as endpoint zero (for control transfers). | ||
| 310 | |||
| 311 | This driver has been tested on the S3C2410, S3C2412, and | ||
| 312 | S3C2440 processors. | ||
| 313 | |||
| 314 | config USB_S3C2410_DEBUG | ||
| 315 | boolean "S3C2410 udc debug messages" | ||
| 316 | depends on USB_S3C2410 | ||
| 317 | |||
| 318 | config USB_S3C_HSUDC | ||
| 319 | tristate "S3C2416, S3C2443 and S3C2450 USB Device Controller" | ||
| 320 | depends on ARCH_S3C24XX | ||
| 321 | help | ||
| 322 | Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC | ||
| 323 | integrated with dual speed USB 2.0 device controller. It has | ||
| 324 | 8 endpoints, as well as endpoint zero. | ||
| 325 | |||
| 326 | This driver has been tested on S3C2416 and S3C2450 processors. | ||
| 327 | |||
| 328 | config USB_MV_UDC | ||
| 329 | tristate "Marvell USB2.0 Device Controller" | ||
| 330 | depends on HAS_DMA | ||
| 331 | help | ||
| 332 | Marvell Socs (including PXA and MMP series) include a high speed | ||
| 333 | USB2.0 OTG controller, which can be configured as high speed or | ||
| 334 | full speed USB peripheral. | ||
| 335 | |||
| 336 | config USB_MV_U3D | ||
| 337 | depends on HAS_DMA | ||
| 338 | tristate "MARVELL PXA2128 USB 3.0 controller" | ||
| 339 | help | ||
| 340 | MARVELL PXA2128 Processor series include a super speed USB3.0 device | ||
| 341 | controller, which support super speed USB peripheral. | ||
| 342 | |||
| 343 | # | ||
| 344 | # Controllers available in both integrated and discrete versions | ||
| 345 | # | ||
| 346 | |||
| 347 | config USB_M66592 | ||
| 348 | tristate "Renesas M66592 USB Peripheral Controller" | ||
| 349 | help | ||
| 350 | M66592 is a discrete USB peripheral controller chip that | ||
| 351 | supports both full and high speed USB 2.0 data transfers. | ||
| 352 | It has seven configurable endpoints, and endpoint zero. | ||
| 353 | |||
| 354 | Say "y" to link the driver statically, or "m" to build a | ||
| 355 | dynamically linked module called "m66592_udc" and force all | ||
| 356 | gadget drivers to also be dynamically linked. | ||
| 357 | |||
| 358 | # | ||
| 359 | # Controllers available only in discrete form (and all PCI controllers) | ||
| 360 | # | ||
| 361 | |||
| 362 | config USB_AMD5536UDC | ||
| 363 | tristate "AMD5536 UDC" | ||
| 364 | depends on PCI | ||
| 365 | help | ||
| 366 | The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. | ||
| 367 | It is a USB Highspeed DMA capable USB device controller. Beside ep0 | ||
| 368 | it provides 4 IN and 4 OUT endpoints (bulk or interrupt type). | ||
| 369 | The UDC port supports OTG operation, and may be used as a host port | ||
| 370 | if it's not being used to implement peripheral or OTG roles. | ||
| 371 | |||
| 372 | Say "y" to link the driver statically, or "m" to build a | ||
| 373 | dynamically linked module called "amd5536udc" and force all | ||
| 374 | gadget drivers to also be dynamically linked. | ||
| 375 | |||
| 376 | config USB_FSL_QE | ||
| 377 | tristate "Freescale QE/CPM USB Device Controller" | ||
| 378 | depends on FSL_SOC && (QUICC_ENGINE || CPM) | ||
| 379 | help | ||
| 380 | Some of Freescale PowerPC processors have a Full Speed | ||
| 381 | QE/CPM2 USB controller, which support device mode with 4 | ||
| 382 | programmable endpoints. This driver supports the | ||
| 383 | controller in the MPC8360 and MPC8272, and should work with | ||
| 384 | controllers having QE or CPM2, given minor tweaks. | ||
| 385 | |||
| 386 | Set CONFIG_USB_GADGET to "m" to build this driver as a | ||
| 387 | dynamically linked module called "fsl_qe_udc". | ||
| 388 | |||
| 389 | config USB_NET2272 | ||
| 390 | tristate "PLX NET2272" | ||
| 391 | help | ||
| 392 | PLX NET2272 is a USB peripheral controller which supports | ||
| 393 | both full and high speed USB 2.0 data transfers. | ||
| 394 | |||
| 395 | It has three configurable endpoints, as well as endpoint zero | ||
| 396 | (for control transfer). | ||
| 397 | Say "y" to link the driver statically, or "m" to build a | ||
| 398 | dynamically linked module called "net2272" and force all | ||
| 399 | gadget drivers to also be dynamically linked. | ||
| 400 | |||
| 401 | config USB_NET2272_DMA | ||
| 402 | boolean "Support external DMA controller" | ||
| 403 | depends on USB_NET2272 && HAS_DMA | ||
| 404 | help | ||
| 405 | The NET2272 part can optionally support an external DMA | ||
| 406 | controller, but your board has to have support in the | ||
| 407 | driver itself. | ||
| 408 | |||
| 409 | If unsure, say "N" here. The driver works fine in PIO mode. | ||
| 410 | |||
| 411 | config USB_NET2280 | ||
| 412 | tristate "NetChip 228x" | ||
| 413 | depends on PCI | ||
| 414 | help | ||
| 415 | NetChip 2280 / 2282 is a PCI based USB peripheral controller which | ||
| 416 | supports both full and high speed USB 2.0 data transfers. | ||
| 417 | |||
| 418 | It has six configurable endpoints, as well as endpoint zero | ||
| 419 | (for control transfers) and several endpoints with dedicated | ||
| 420 | functions. | ||
| 421 | |||
| 422 | Say "y" to link the driver statically, or "m" to build a | ||
| 423 | dynamically linked module called "net2280" and force all | ||
| 424 | gadget drivers to also be dynamically linked. | ||
| 425 | |||
| 426 | config USB_GOKU | ||
| 427 | tristate "Toshiba TC86C001 'Goku-S'" | ||
| 428 | depends on PCI | ||
| 429 | help | ||
| 430 | The Toshiba TC86C001 is a PCI device which includes controllers | ||
| 431 | for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI). | ||
| 432 | |||
| 433 | The device controller has three configurable (bulk or interrupt) | ||
| 434 | endpoints, plus endpoint zero (for control transfers). | ||
| 435 | |||
| 436 | Say "y" to link the driver statically, or "m" to build a | ||
| 437 | dynamically linked module called "goku_udc" and to force all | ||
| 438 | gadget drivers to also be dynamically linked. | ||
| 439 | |||
| 440 | config USB_EG20T | ||
| 441 | tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" | ||
| 442 | depends on PCI | ||
| 443 | help | ||
| 444 | This is a USB device driver for EG20T PCH. | ||
| 445 | EG20T PCH is the platform controller hub that is used in Intel's | ||
| 446 | general embedded platform. EG20T PCH has USB device interface. | ||
| 447 | Using this interface, it is able to access system devices connected | ||
| 448 | to USB device. | ||
| 449 | This driver enables USB device function. | ||
| 450 | USB device is a USB peripheral controller which | ||
| 451 | supports both full and high speed USB 2.0 data transfers. | ||
| 452 | This driver supports both control transfer and bulk transfer modes. | ||
| 453 | This driver dose not support interrupt transfer or isochronous | ||
| 454 | transfer modes. | ||
| 455 | |||
| 456 | This driver also can be used for LAPIS Semiconductor's ML7213 which is | ||
| 457 | for IVI(In-Vehicle Infotainment) use. | ||
| 458 | ML7831 is for general purpose use. | ||
| 459 | ML7213/ML7831 is companion chip for Intel Atom E6xx series. | ||
| 460 | ML7213/ML7831 is completely compatible for Intel EG20T PCH. | ||
| 461 | |||
| 462 | # | ||
| 463 | # LAST -- dummy/emulated controller | ||
| 464 | # | ||
| 465 | |||
| 466 | config USB_DUMMY_HCD | ||
| 467 | tristate "Dummy HCD (DEVELOPMENT)" | ||
| 468 | depends on USB=y || (USB=m && USB_GADGET=m) | ||
| 469 | help | ||
| 470 | This host controller driver emulates USB, looping all data transfer | ||
| 471 | requests back to a USB "gadget driver" in the same host. The host | ||
| 472 | side is the master; the gadget side is the slave. Gadget drivers | ||
| 473 | can be high, full, or low speed; and they have access to endpoints | ||
| 474 | like those from NET2280, PXA2xx, or SA1100 hardware. | ||
| 475 | |||
| 476 | This may help in some stages of creating a driver to embed in a | ||
| 477 | Linux device, since it lets you debug several parts of the gadget | ||
| 478 | driver without its hardware or drivers being involved. | ||
| 479 | |||
| 480 | Since such a gadget side driver needs to interoperate with a host | ||
| 481 | side Linux-USB device driver, this may help to debug both sides | ||
| 482 | of a USB protocol stack. | ||
| 483 | |||
| 484 | Say "y" to link the driver statically, or "m" to build a | ||
| 485 | dynamically linked module called "dummy_hcd" and force all | ||
| 486 | gadget drivers to also be dynamically linked. | ||
| 487 | |||
| 488 | # NOTE: Please keep dummy_hcd LAST so that "real hardware" appears | ||
| 489 | # first and will be selected by default. | ||
| 490 | |||
| 491 | endmenu | ||
| 492 | 131 | ||
| 493 | # | 132 | # |
| 494 | # USB Gadget Drivers | 133 | # USB Gadget Drivers |
| @@ -714,466 +353,7 @@ config USB_CONFIGFS_F_FS · 219 unmodified lines | |||
| 714 | implemented in kernel space (for instance Ethernet, serial or | 353 | implemented in kernel space (for instance Ethernet, serial or |
| 715 | mass storage) and other are implemented in user space. | 354 | mass storage) and other are implemented in user space. |
| 716 | 355 | ||
| 717 | config USB_ZERO | 356 | source "drivers/usb/gadget/legacy/Kconfig" |
| 718 | tristate "Gadget Zero (DEVELOPMENT)" | ||
| 719 | select USB_LIBCOMPOSITE | ||
| 720 | select USB_F_SS_LB | ||
| 721 | help | ||
| 722 | Gadget Zero is a two-configuration device. It either sinks and | ||
| 723 | sources bulk data; or it loops back a configurable number of | ||
| 724 | transfers. It also implements control requests, for "chapter 9" | ||
| 725 | conformance. The driver needs only two bulk-capable endpoints, so | ||
| 726 | it can work on top of most device-side usb controllers. It's | ||
| 727 | useful for testing, and is also a working example showing how | ||
| 728 | USB "gadget drivers" can be written. | ||
| 729 | |||
| 730 | Make this be the first driver you try using on top of any new | ||
| 731 | USB peripheral controller driver. Then you can use host-side | ||
| 732 | test software, like the "usbtest" driver, to put your hardware | ||
| 733 | and its driver through a basic set of functional tests. | ||
| 734 | |||
| 735 | Gadget Zero also works with the host-side "usb-skeleton" driver, | ||
| 736 | and with many kinds of host-side test software. You may need | ||
| 737 | to tweak product and vendor IDs before host software knows about | ||
| 738 | this device, and arrange to select an appropriate configuration. | ||
| 739 | |||
| 740 | Say "y" to link the driver statically, or "m" to build a | ||
| 741 | dynamically linked module called "g_zero". | ||
| 742 | |||
| 743 | config USB_ZERO_HNPTEST | ||
| 744 | boolean "HNP Test Device" | ||
| 745 | depends on USB_ZERO && USB_OTG | ||
| 746 | help | ||
| 747 | You can configure this device to enumerate using the device | ||
| 748 | identifiers of the USB-OTG test device. That means that when | ||
| 749 | this gadget connects to another OTG device, with this one using | ||
| 750 | the "B-Peripheral" role, that device will use HNP to let this | ||
| 751 | one serve as the USB host instead (in the "B-Host" role). | ||
| 752 | |||
| 753 | config USB_AUDIO | ||
| 754 | tristate "Audio Gadget" | ||
| 755 | depends on SND | ||
| 756 | select USB_LIBCOMPOSITE | ||
| 757 | select SND_PCM | ||
| 758 | help | ||
| 759 | This Gadget Audio driver is compatible with USB Audio Class | ||
| 760 | specification 2.0. It implements 1 AudioControl interface, | ||
| 761 | 1 AudioStreaming Interface each for USB-OUT and USB-IN. | ||
| 762 | Number of channels, sample rate and sample size can be | ||
| 763 | specified as module parameters. | ||
| 764 | This driver doesn't expect any real Audio codec to be present | ||
| 765 | on the device - the audio streams are simply sinked to and | ||
| 766 | sourced from a virtual ALSA sound card created. The user-space | ||
| 767 | application may choose to do whatever it wants with the data | ||
| 768 | received from the USB Host and choose to provide whatever it | ||
| 769 | wants as audio data to the USB Host. | ||
| 770 | |||
| 771 | Say "y" to link the driver statically, or "m" to build a | ||
| 772 | dynamically linked module called "g_audio". | ||
| 773 | |||
| 774 | config GADGET_UAC1 | ||
| 775 | bool "UAC 1.0 (Legacy)" | ||
| 776 | depends on USB_AUDIO | ||
| 777 | help | ||
| 778 | If you instead want older UAC Spec-1.0 driver that also has audio | ||
| 779 | paths hardwired to the Audio codec chip on-board and doesn't work | ||
| 780 | without one. | ||
| 781 | |||
| 782 | config USB_ETH | ||
| 783 | tristate "Ethernet Gadget (with CDC Ethernet support)" | ||
| 784 | depends on NET | ||
| 785 | select USB_LIBCOMPOSITE | ||
| 786 | select USB_U_ETHER | ||
| 787 | select USB_F_ECM | ||
| 788 | select USB_F_SUBSET | ||
| 789 | select CRC32 | ||
| 790 | help | ||
| 791 | This driver implements Ethernet style communication, in one of | ||
| 792 | several ways: | ||
| 793 | |||
| 794 | - The "Communication Device Class" (CDC) Ethernet Control Model. | ||
| 795 | That protocol is often avoided with pure Ethernet adapters, in | ||
| 796 | favor of simpler vendor-specific hardware, but is widely | ||
| 797 | supported by firmware for smart network devices. | ||
| 798 | |||
| 799 | - On hardware can't implement that protocol, a simple CDC subset | ||
| 800 | is used, placing fewer demands on USB. | ||
| 801 | |||
| 802 | - CDC Ethernet Emulation Model (EEM) is a newer standard that has | ||
| 803 | a simpler interface that can be used by more USB hardware. | ||
| 804 | |||
| 805 | RNDIS support is an additional option, more demanding than than | ||
| 806 | subset. | ||
| 807 | |||
| 808 | Within the USB device, this gadget driver exposes a network device | ||
| 809 | "usbX", where X depends on what other networking devices you have. | ||
| 810 | Treat it like a two-node Ethernet link: host, and gadget. | ||
| 811 | |||
| 812 | The Linux-USB host-side "usbnet" driver interoperates with this | ||
| 813 | driver, so that deep I/O queues can be supported. On 2.4 kernels, | ||
| 814 | use "CDCEther" instead, if you're using the CDC option. That CDC | ||
| 815 | mode should also interoperate with standard CDC Ethernet class | ||
| 816 | drivers on other host operating systems. | ||
| 817 | |||
| 818 | Say "y" to link the driver statically, or "m" to build a | ||
| 819 | dynamically linked module called "g_ether". | ||
| 820 | |||
| 821 | config USB_ETH_RNDIS | ||
| 822 | bool "RNDIS support" | ||
| 823 | depends on USB_ETH | ||
| 824 | select USB_LIBCOMPOSITE | ||
| 825 | select USB_F_RNDIS | ||
| 826 | default y | ||
| 827 | help | ||
| 828 | Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol, | ||
| 829 | and Microsoft provides redistributable binary RNDIS drivers for | ||
| 830 | older versions of Windows. | ||
| 831 | |||
| 832 | If you say "y" here, the Ethernet gadget driver will try to provide | ||
| 833 | a second device configuration, supporting RNDIS to talk to such | ||
| 834 | Microsoft USB hosts. | ||
| 835 | |||
| 836 | To make MS-Windows work with this, use Documentation/usb/linux.inf | ||
| 837 | as the "driver info file". For versions of MS-Windows older than | ||
| 838 | XP, you'll need to download drivers from Microsoft's website; a URL | ||
| 839 | is given in comments found in that info file. | ||
| 840 | |||
| 841 | config USB_ETH_EEM | ||
| 842 | bool "Ethernet Emulation Model (EEM) support" | ||
| 843 | depends on USB_ETH | ||
| 844 | select USB_LIBCOMPOSITE | ||
| 845 | select USB_F_EEM | ||
| 846 | default n | ||
| 847 | help | ||
| 848 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM | ||
| 849 | and therefore can be supported by more hardware. Technically ECM and | ||
| 850 | EEM are designed for different applications. The ECM model extends | ||
| 851 | the network interface to the target (e.g. a USB cable modem), and the | ||
| 852 | EEM model is for mobile devices to communicate with hosts using | ||
| 853 | ethernet over USB. For Linux gadgets, however, the interface with | ||
| 854 | the host is the same (a usbX device), so the differences are minimal. | ||
| 855 | |||
| 856 | If you say "y" here, the Ethernet gadget driver will use the EEM | ||
| 857 | protocol rather than ECM. If unsure, say "n". | ||
| 858 | |||
| 859 | config USB_G_NCM | ||
| 860 | tristate "Network Control Model (NCM) support" | ||
| 861 | depends on NET | ||
| 862 | select USB_LIBCOMPOSITE | ||
| 863 | select USB_U_ETHER | ||
| 864 | select USB_F_NCM | ||
| 865 | select CRC32 | ||
| 866 | help | ||
| 867 | This driver implements USB CDC NCM subclass standard. NCM is | ||
| 868 | an advanced protocol for Ethernet encapsulation, allows grouping | ||
| 869 | of several ethernet frames into one USB transfer and different | ||
| 870 | alignment possibilities. | ||
| 871 | |||
| 872 | Say "y" to link the driver statically, or "m" to build a | ||
| 873 | dynamically linked module called "g_ncm". | ||
| 874 | |||
| 875 | config USB_GADGETFS | ||
| 876 | tristate "Gadget Filesystem" | ||
| 877 | help | ||
| 878 | This driver provides a filesystem based API that lets user mode | ||
| 879 | programs implement a single-configuration USB device, including | ||
| 880 | endpoint I/O and control requests that don't relate to enumeration. | ||
| 881 | All endpoints, transfer speeds, and transfer types supported by | ||
| 882 | the hardware are available, through read() and write() calls. | ||
| 883 | |||
| 884 | Say "y" to link the driver statically, or "m" to build a | ||
| 885 | dynamically linked module called "gadgetfs". | ||
| 886 | |||
| 887 | config USB_FUNCTIONFS | ||
| 888 | tristate "Function Filesystem" | ||
| 889 | select USB_LIBCOMPOSITE | ||
| 890 | select USB_F_FS | ||
| 891 | select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS) | ||
| 892 | help | ||
| 893 | The Function Filesystem (FunctionFS) lets one create USB | ||
| 894 | composite functions in user space in the same way GadgetFS | ||
| 895 | lets one create USB gadgets in user space. This allows creation | ||
| 896 | of composite gadgets such that some of the functions are | ||
| 897 | implemented in kernel space (for instance Ethernet, serial or | ||
| 898 | mass storage) and other are implemented in user space. | ||
| 899 | |||
| 900 | If you say "y" or "m" here you will be able what kind of | ||
| 901 | configurations the gadget will provide. | ||
| 902 | |||
| 903 | Say "y" to link the driver statically, or "m" to build | ||
| 904 | a dynamically linked module called "g_ffs". | ||
| 905 | |||
| 906 | config USB_FUNCTIONFS_ETH | ||
| 907 | bool "Include configuration with CDC ECM (Ethernet)" | ||
| 908 | depends on USB_FUNCTIONFS && NET | ||
| 909 | select USB_U_ETHER | ||
| 910 | select USB_F_ECM | ||
| 911 | select USB_F_SUBSET | ||
| 912 | help | ||
| 913 | Include a configuration with CDC ECM function (Ethernet) and the | ||
| 914 | Function Filesystem. | ||
| 915 | |||
| 916 | config USB_FUNCTIONFS_RNDIS | ||
| 917 | bool "Include configuration with RNDIS (Ethernet)" | ||
| 918 | depends on USB_FUNCTIONFS && NET | ||
| 919 | select USB_U_ETHER | ||
| 920 | select USB_F_RNDIS | ||
| 921 | help | ||
| 922 | Include a configuration with RNDIS function (Ethernet) and the Filesystem. | ||
| 923 | |||
| 924 | config USB_FUNCTIONFS_GENERIC | ||
| 925 | bool "Include 'pure' configuration" | ||
| 926 | depends on USB_FUNCTIONFS | ||
| 927 | help | ||
| 928 | Include a configuration with the Function Filesystem alone with | ||
| 929 | no Ethernet interface. | ||
| 930 | |||
| 931 | config USB_MASS_STORAGE | ||
| 932 | tristate "Mass Storage Gadget" | ||
| 933 | depends on BLOCK | ||
| 934 | select USB_LIBCOMPOSITE | ||
| 935 | select USB_F_MASS_STORAGE | ||
| 936 | help | ||
| 937 | The Mass Storage Gadget acts as a USB Mass Storage disk drive. | ||
| 938 | As its storage repository it can use a regular file or a block | ||
| 939 | device (in much the same way as the "loop" device driver), | ||
| 940 | specified as a module parameter or sysfs option. | ||
| 941 | |||
| 942 | This driver is a replacement for now removed File-backed | ||
| 943 | Storage Gadget (g_file_storage). | ||
| 944 | |||
| 945 | Say "y" to link the driver statically, or "m" to build | ||
| 946 | a dynamically linked module called "g_mass_storage". | ||
| 947 | |||
| 948 | config USB_GADGET_TARGET | ||
| 949 | tristate "USB Gadget Target Fabric Module" | ||
| 950 | depends on TARGET_CORE | ||
| 951 | select USB_LIBCOMPOSITE | ||
| 952 | help | ||
| 953 | This fabric is an USB gadget. Two USB protocols are supported that is | ||
| 954 | BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is | ||
| 955 | advertised on alternative interface 0 (primary) and UAS is on | ||
| 956 | alternative interface 1. Both protocols can work on USB2.0 and USB3.0. | ||
| 957 | UAS utilizes the USB 3.0 feature called streams support. | ||
| 958 | |||
| 959 | config USB_G_SERIAL | ||
| 960 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" | ||
| 961 | depends on TTY | ||
| 962 | select USB_U_SERIAL | ||
| 963 | select USB_F_ACM | ||
| 964 | select USB_F_SERIAL | ||
| 965 | select USB_F_OBEX | ||
| 966 | select USB_LIBCOMPOSITE | ||
| 967 | help | ||
| 968 | The Serial Gadget talks to the Linux-USB generic serial driver. | ||
| 969 | This driver supports a CDC-ACM module option, which can be used | ||
| 970 | to interoperate with MS-Windows hosts or with the Linux-USB | ||
| 971 | "cdc-acm" driver. | ||
| 972 | |||
| 973 | This driver also supports a CDC-OBEX option. You will need a | ||
| 974 | user space OBEX server talking to /dev/ttyGS*, since the kernel | ||
| 975 | itself doesn't implement the OBEX protocol. | ||
| 976 | |||
| 977 | Say "y" to link the driver statically, or "m" to build a | ||
| 978 | dynamically linked module called "g_serial". | ||
| 979 | |||
| 980 | For more information, see Documentation/usb/gadget_serial.txt | ||
| 981 | which includes instructions and a "driver info file" needed to | ||
| 982 | make MS-Windows work with CDC ACM. | ||
| 983 | |||
| 984 | config USB_MIDI_GADGET | ||
| 985 | tristate "MIDI Gadget" | ||
| 986 | depends on SND | ||
| 987 | select USB_LIBCOMPOSITE | ||
| 988 | select SND_RAWMIDI | ||
| 989 | help | ||
| 990 | The MIDI Gadget acts as a USB Audio device, with one MIDI | ||
| 991 | input and one MIDI output. These MIDI jacks appear as | ||
| 992 | a sound "card" in the ALSA sound system. Other MIDI | ||
| 993 | connections can then be made on the gadget system, using | ||
| 994 | ALSA's aconnect utility etc. | ||
| 995 | |||
| 996 | Say "y" to link the driver statically, or "m" to build a | ||
| 997 | dynamically linked module called "g_midi". | ||
| 998 | |||
| 999 | config USB_G_PRINTER | ||
| 1000 | tristate "Printer Gadget" | ||
| 1001 | select USB_LIBCOMPOSITE | ||
| 1002 | help | ||
| 1003 | The Printer Gadget channels data between the USB host and a | ||
| 1004 | userspace program driving the print engine. The user space | ||
| 1005 | program reads and writes the device file /dev/g_printer to | ||
| 1006 | receive or send printer data. It can use ioctl calls to | ||
| 1007 | the device file to get or set printer status. | ||
| 1008 | |||
| 1009 | Say "y" to link the driver statically, or "m" to build a | ||
| 1010 | dynamically linked module called "g_printer". | ||
| 1011 | |||
| 1012 | For more information, see Documentation/usb/gadget_printer.txt | ||
| 1013 | which includes sample code for accessing the device file. | ||
| 1014 | |||
| 1015 | if TTY | ||
| 1016 | |||
| 1017 | config USB_CDC_COMPOSITE | ||
| 1018 | tristate "CDC Composite Device (Ethernet and ACM)" | ||
| 1019 | depends on NET | ||
| 1020 | select USB_LIBCOMPOSITE | ||
| 1021 | select USB_U_SERIAL | ||
| 1022 | select USB_U_ETHER | ||
| 1023 | select USB_F_ACM | ||
| 1024 | select USB_F_ECM | ||
| 1025 | help | ||
| 1026 | This driver provides two functions in one configuration: | ||
| 1027 | a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link. | ||
| 1028 | |||
| 1029 | This driver requires four bulk and two interrupt endpoints, | ||
| 1030 | plus the ability to handle altsettings. Not all peripheral | ||
| 1031 | controllers are that capable. | ||
| 1032 | |||
| 1033 | Say "y" to link the driver statically, or "m" to build a | ||
| 1034 | dynamically linked module. | ||
| 1035 | |||
| 1036 | config USB_G_NOKIA | ||
| 1037 | tristate "Nokia composite gadget" | ||
| 1038 | depends on PHONET | ||
| 1039 | select USB_LIBCOMPOSITE | ||
| 1040 | select USB_U_SERIAL | ||
| 1041 | select USB_U_ETHER | ||
| 1042 | select USB_F_ACM | ||
| 1043 | select USB_F_OBEX | ||
| 1044 | select USB_F_PHONET | ||
| 1045 | select USB_F_ECM | ||
| 1046 | help | ||
| 1047 | The Nokia composite gadget provides support for acm, obex | ||
| 1048 | and phonet in only one composite gadget driver. | ||
| 1049 | |||
| 1050 | It's only really useful for N900 hardware. If you're building | ||
| 1051 | a kernel for N900, say Y or M here. If unsure, say N. | ||
| 1052 | |||
| 1053 | config USB_G_ACM_MS | ||
| 1054 | tristate "CDC Composite Device (ACM and mass storage)" | ||
| 1055 | depends on BLOCK | ||
| 1056 | select USB_LIBCOMPOSITE | ||
| 1057 | select USB_U_SERIAL | ||
| 1058 | select USB_F_ACM | ||
| 1059 | select USB_F_MASS_STORAGE | ||
| 1060 | help | ||
| 1061 | This driver provides two functions in one configuration: | ||
| 1062 | a mass storage, and a CDC ACM (serial port) link. | ||
| 1063 | |||
| 1064 | Say "y" to link the driver statically, or "m" to build a | ||
| 1065 | dynamically linked module called "g_acm_ms". | ||
| 1066 | |||
| 1067 | config USB_G_MULTI | ||
| 1068 | tristate "Multifunction Composite Gadget" | ||
| 1069 | depends on BLOCK && NET | ||
| 1070 | select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS | ||
| 1071 | select USB_LIBCOMPOSITE | ||
| 1072 | select USB_U_SERIAL | ||
| 1073 | select USB_U_ETHER | ||
| 1074 | select USB_F_ACM | ||
| 1075 | select USB_F_MASS_STORAGE | ||
| 1076 | help | ||
| 1077 | The Multifunction Composite Gadget provides Ethernet (RNDIS | ||
| 1078 | and/or CDC Ethernet), mass storage and ACM serial link | ||
| 1079 | interfaces. | ||
| 1080 | |||
| 1081 | You will be asked to choose which of the two configurations is | ||
| 1082 | to be available in the gadget. At least one configuration must | ||
| 1083 | be chosen to make the gadget usable. Selecting more than one | ||
| 1084 | configuration will prevent Windows from automatically detecting | ||
| 1085 | the gadget as a composite gadget, so an INF file will be needed to | ||
| 1086 | use the gadget. | ||
| 1087 | |||
| 1088 | Say "y" to link the driver statically, or "m" to build a | ||
| 1089 | dynamically linked module called "g_multi". | ||
| 1090 | |||
| 1091 | config USB_G_MULTI_RNDIS | ||
| 1092 | bool "RNDIS + CDC Serial + Storage configuration" | ||
| 1093 | depends on USB_G_MULTI | ||
| 1094 | select USB_F_RNDIS | ||
| 1095 | default y | ||
| 1096 | help | ||
| 1097 | This option enables a configuration with RNDIS, CDC Serial and | ||
| 1098 | Mass Storage functions available in the Multifunction Composite | ||
| 1099 | Gadget. This is the configuration dedicated for Windows since RNDIS | ||
| 1100 | is Microsoft's protocol. | ||
| 1101 | |||
| 1102 | If unsure, say "y". | ||
| 1103 | |||
| 1104 | config USB_G_MULTI_CDC | ||
| 1105 | bool "CDC Ethernet + CDC Serial + Storage configuration" | ||
| 1106 | depends on USB_G_MULTI | ||
| 1107 | default n | ||
| 1108 | select USB_F_ECM | ||
| 1109 | help | ||
| 1110 | This option enables a configuration with CDC Ethernet (ECM), CDC | ||
| 1111 | Serial and Mass Storage functions available in the Multifunction | ||
| 1112 | Composite Gadget. | ||
| 1113 | |||
| 1114 | If unsure, say "y". | ||
| 1115 | |||
| 1116 | endif # TTY | ||
| 1117 | |||
| 1118 | config USB_G_HID | ||
| 1119 | tristate "HID Gadget" | ||
| 1120 | select USB_LIBCOMPOSITE | ||
| 1121 | help | ||
| 1122 | The HID gadget driver provides generic emulation of USB | ||
| 1123 | Human Interface Devices (HID). | ||
| 1124 | |||
| 1125 | For more information, see Documentation/usb/gadget_hid.txt which | ||
| 1126 | includes sample code for accessing the device files. | ||
| 1127 | |||
| 1128 | Say "y" to link the driver statically, or "m" to build a | ||
| 1129 | dynamically linked module called "g_hid". | ||
| 1130 | |||
| 1131 | # Standalone / single function gadgets | ||
| 1132 | config USB_G_DBGP | ||
| 1133 | tristate "EHCI Debug Device Gadget" | ||
| 1134 | depends on TTY | ||
| 1135 | select USB_LIBCOMPOSITE | ||
| 1136 | help | ||
| 1137 | This gadget emulates an EHCI Debug device. This is useful when you want | ||
| 1138 | to interact with an EHCI Debug Port. | ||
| 1139 | |||
| 1140 | Say "y" to link the driver statically, or "m" to build a | ||
| 1141 | dynamically linked module called "g_dbgp". | ||
| 1142 | |||
| 1143 | if USB_G_DBGP | ||
| 1144 | choice | ||
| 1145 | prompt "EHCI Debug Device mode" | ||
| 1146 | default USB_G_DBGP_SERIAL | ||
| 1147 | |||
| 1148 | config USB_G_DBGP_PRINTK | ||
| 1149 | depends on USB_G_DBGP | ||
| 1150 | bool "printk" | ||
| 1151 | help | ||
| 1152 | Directly printk() received data. No interaction. | ||
| 1153 | |||
| 1154 | config USB_G_DBGP_SERIAL | ||
| 1155 | depends on USB_G_DBGP | ||
| 1156 | select USB_U_SERIAL | ||
| 1157 | bool "serial" | ||
| 1158 | help | ||
| 1159 | Userland can interact using /dev/ttyGSxxx. | ||
| 1160 | endchoice | ||
| 1161 | endif | ||
| 1162 | |||
| 1163 | # put drivers that need isochronous transfer support (for audio | ||
| 1164 | # or video class gadget drivers), or specific hardware, here. | ||
| 1165 | config USB_G_WEBCAM | ||
| 1166 | tristate "USB Webcam Gadget" | ||
| 1167 | depends on VIDEO_DEV | ||
| 1168 | select USB_LIBCOMPOSITE | ||
| 1169 | select VIDEOBUF2_VMALLOC | ||
| 1170 | help | ||
| 1171 | The Webcam Gadget acts as a composite USB Audio and Video Class | ||
| 1172 | device. It provides a userspace API to process UVC control requests | ||
| 1173 | and stream video data to the host. | ||
| 1174 | |||
| 1175 | Say "y" to link the driver statically, or "m" to build a | ||
| 1176 | dynamically linked module called "g_webcam". | ||
| 1177 | 357 | ||
| 1178 | endchoice | 358 | endchoice |
| 1179 | 359 | ||
| @@ -1,105 +1,12 @@ | |||
| 1 | # | 1 | # |
| 2 | # USB peripheral controller drivers | 2 | # USB peripheral controller drivers |
| 3 | # | 3 | # |
| 4 | ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG | 4 | subdir-ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG |
| 5 | ccflags-$(CONFIG_USB_GADGET_VERBOSE) += -DVERBOSE_DEBUG | 5 | subdir-ccflags-$(CONFIG_USB_GADGET_VERBOSE) += -DVERBOSE_DEBUG |
| 6 | ccflags-y += -I$(PWD)/drivers/usb/gadget/udc | ||
| 6 | 7 | ||
| 7 | obj-$(CONFIG_USB_GADGET) += udc-core.o | ||
| 8 | obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o | 8 | obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o |
| 9 | libcomposite-y := usbstring.o config.o epautoconf.o | 9 | libcomposite-y := usbstring.o config.o epautoconf.o |
| 10 | libcomposite-y += composite.o functions.o configfs.o u_f.o | 10 | libcomposite-y += composite.o functions.o configfs.o u_f.o |
| 11 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o | ||
| 12 | obj-$(CONFIG_USB_NET2272) += net2272.o | ||
| 13 | obj-$(CONFIG_USB_NET2280) += net2280.o | ||
| 14 | obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o | ||
| 15 | obj-$(CONFIG_USB_PXA25X) += pxa25x_udc.o | ||
| 16 | obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o | ||
| 17 | obj-$(CONFIG_USB_GOKU) += goku_udc.o | ||
| 18 | obj-$(CONFIG_USB_OMAP) += omap_udc.o | ||
| 19 | obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o | ||
| 20 | obj-$(CONFIG_USB_AT91) += at91_udc.o | ||
| 21 | obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o | ||
| 22 | obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o | ||
| 23 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o | ||
| 24 | fsl_usb2_udc-y := fsl_udc_core.o | ||
| 25 | fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o | ||
| 26 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | ||
| 27 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o | ||
| 28 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o | ||
| 29 | obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o | ||
| 30 | obj-$(CONFIG_USB_LPC32XX) += lpc32xx_udc.o | ||
| 31 | obj-$(CONFIG_USB_EG20T) += pch_udc.o | ||
| 32 | obj-$(CONFIG_USB_MV_UDC) += mv_udc.o | ||
| 33 | mv_udc-y := mv_udc_core.o | ||
| 34 | obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o | ||
| 35 | obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o | ||
| 36 | obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o | ||
| 37 | obj-$(CONFIG_USB_GR_UDC) += gr_udc.o | ||
| 38 | 11 | ||
| 39 | # USB Functions | 12 | obj-$(CONFIG_USB_GADGET) += udc/ function/ legacy/ |
| 40 | usb_f_acm-y := f_acm.o | ||
| 41 | obj-$(CONFIG_USB_F_ACM) += usb_f_acm.o | ||
| 42 | usb_f_ss_lb-y := f_loopback.o f_sourcesink.o | ||
| 43 | obj-$(CONFIG_USB_F_SS_LB) += usb_f_ss_lb.o | ||
| 44 | obj-$(CONFIG_USB_U_SERIAL) += u_serial.o | ||
| 45 | usb_f_serial-y := f_serial.o | ||
| 46 | obj-$(CONFIG_USB_F_SERIAL) += usb_f_serial.o | ||
| 47 | usb_f_obex-y := f_obex.o | ||
| 48 | obj-$(CONFIG_USB_F_OBEX) += usb_f_obex.o | ||
| 49 | obj-$(CONFIG_USB_U_ETHER) += u_ether.o | ||
| 50 | usb_f_ncm-y := f_ncm.o | ||
| 51 | obj-$(CONFIG_USB_F_NCM) += usb_f_ncm.o | ||
| 52 | usb_f_ecm-y := f_ecm.o | ||
| 53 | obj-$(CONFIG_USB_F_ECM) += usb_f_ecm.o | ||
| 54 | usb_f_phonet-y := f_phonet.o | ||
| 55 | obj-$(CONFIG_USB_F_PHONET) += usb_f_phonet.o | ||
| 56 | usb_f_eem-y := f_eem.o | ||
| 57 | obj-$(CONFIG_USB_F_EEM) += usb_f_eem.o | ||
| 58 | usb_f_ecm_subset-y := f_subset.o | ||
| 59 | obj-$(CONFIG_USB_F_SUBSET) += usb_f_ecm_subset.o | ||
| 60 | usb_f_rndis-y := f_rndis.o rndis.o | ||
| 61 | obj-$(CONFIG_USB_F_RNDIS) += usb_f_rndis.o | ||
| 62 | usb_f_mass_storage-y := f_mass_storage.o storage_common.o | ||
| 63 | obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o | ||
| 64 | usb_f_fs-y := f_fs.o | ||
| 65 | obj-$(CONFIG_USB_F_FS) += usb_f_fs.o | ||
| 66 | |||
| 67 | # | ||
| 68 | # USB gadget drivers | ||
| 69 | # | ||
| 70 | g_zero-y := zero.o | ||
| 71 | g_audio-y := audio.o | ||
| 72 | g_ether-y := ether.o | ||
| 73 | g_serial-y := serial.o | ||
| 74 | g_midi-y := gmidi.o | ||
| 75 | gadgetfs-y := inode.o | ||
| 76 | g_mass_storage-y := mass_storage.o | ||
| 77 | g_printer-y := printer.o | ||
| 78 | g_cdc-y := cdc2.o | ||
| 79 | g_multi-y := multi.o | ||
| 80 | g_hid-y := hid.o | ||
| 81 | g_dbgp-y := dbgp.o | ||
| 82 | g_nokia-y := nokia.o | ||
| 83 | g_webcam-y := webcam.o | ||
| 84 | g_ncm-y := ncm.o | ||
| 85 | g_acm_ms-y := acm_ms.o | ||
| 86 | g_tcm_usb_gadget-y := tcm_usb_gadget.o | ||
| 87 | |||
| 88 | obj-$(CONFIG_USB_ZERO) += g_zero.o | ||
| 89 | obj-$(CONFIG_USB_AUDIO) += g_audio.o | ||
| 90 | obj-$(CONFIG_USB_ETH) += g_ether.o | ||
| 91 | obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o | ||
| 92 | obj-$(CONFIG_USB_FUNCTIONFS) += g_ffs.o | ||
| 93 | obj-$(CONFIG_USB_MASS_STORAGE) += g_mass_storage.o | ||
| 94 | obj-$(CONFIG_USB_G_SERIAL) += g_serial.o | ||
| 95 | obj-$(CONFIG_USB_G_PRINTER) += g_printer.o | ||
| 96 | obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o | ||
| 97 | obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o | ||
| 98 | obj-$(CONFIG_USB_G_HID) += g_hid.o | ||
| 99 | obj-$(CONFIG_USB_G_DBGP) += g_dbgp.o | ||
| 100 | obj-$(CONFIG_USB_G_MULTI) += g_multi.o | ||
| 101 | obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o | ||
| 102 | obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o | ||
| 103 | obj-$(CONFIG_USB_G_NCM) += g_ncm.o | ||
| 104 | obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o | ||
| 105 | obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o | ||
| @@ -1956,6 +1956,7 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) · 1955 unmodified lines | |||
| 1956 | } | 1956 | } |
| 1957 | if (cdev->req) { | 1957 | if (cdev->req) { |
| 1958 | kfree(cdev->req->buf); | 1958 | kfree(cdev->req->buf); |
| 1959 | usb_ep_dequeue(cdev->gadget->ep0, cdev->req); | ||
| 1959 | usb_ep_free_request(cdev->gadget->ep0, cdev->req); | 1960 | usb_ep_free_request(cdev->gadget->ep0, cdev->req); |
| 1960 | } | 1961 | } |
| 1961 | cdev->next_string_id = 0; | 1962 | cdev->next_string_id = 0; |
| @@ -1021,12 +1021,10 @@ static ssize_t ext_prop_data_store(struct usb_os_desc_ext_prop *ext_prop, · 1020 unmodified lines | |||
| 1021 | 1021 | ||
| 1022 | if (page[len - 1] == '\n' || page[len - 1] == '\0') | 1022 | if (page[len - 1] == '\n' || page[len - 1] == '\0') |
| 1023 | --len; | 1023 | --len; |
| 1024 | new_data = kzalloc(len, GFP_KERNEL); | 1024 | new_data = kmemdup(page, len, GFP_KERNEL); |
| 1025 | if (!new_data) | 1025 | if (!new_data) |
| 1026 | return -ENOMEM; | 1026 | return -ENOMEM; |
| 1027 | 1027 | ||
| 1028 | memcpy(new_data, page, len); | ||
| 1029 | |||
| 1030 | if (desc->opts_mutex) | 1028 | if (desc->opts_mutex) |
| 1031 | mutex_lock(desc->opts_mutex); | 1029 | mutex_lock(desc->opts_mutex); |
| 1032 | kfree(ext_prop->data); | 1030 | kfree(ext_prop->data); |
| @@ -0,0 +1,34 @@ | |||
| 1 | # | ||
| 2 | # USB peripheral controller drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | ccflags-y := -I$(PWD)/drivers/usb/gadget/ | ||
| 6 | ccflags-y += -I$(PWD)/drivers/usb/gadget/udc/ | ||
| 7 | |||
| 8 | # USB Functions | ||
| 9 | usb_f_acm-y := f_acm.o | ||
| 10 | obj-$(CONFIG_USB_F_ACM) += usb_f_acm.o | ||
| 11 | usb_f_ss_lb-y := f_loopback.o f_sourcesink.o | ||
| 12 | obj-$(CONFIG_USB_F_SS_LB) += usb_f_ss_lb.o | ||
| 13 | obj-$(CONFIG_USB_U_SERIAL) += u_serial.o | ||
| 14 | usb_f_serial-y := f_serial.o | ||
| 15 | obj-$(CONFIG_USB_F_SERIAL) += usb_f_serial.o | ||
| 16 | usb_f_obex-y := f_obex.o | ||
| 17 | obj-$(CONFIG_USB_F_OBEX) += usb_f_obex.o | ||
| 18 | obj-$(CONFIG_USB_U_ETHER) += u_ether.o | ||
| 19 | usb_f_ncm-y := f_ncm.o | ||
| 20 | obj-$(CONFIG_USB_F_NCM) += usb_f_ncm.o | ||
| 21 | usb_f_ecm-y := f_ecm.o | ||
| 22 | obj-$(CONFIG_USB_F_ECM) += usb_f_ecm.o | ||
| 23 | usb_f_phonet-y := f_phonet.o | ||
| 24 | obj-$(CONFIG_USB_F_PHONET) += usb_f_phonet.o | ||
| 25 | usb_f_eem-y := f_eem.o | ||
| 26 | obj-$(CONFIG_USB_F_EEM) += usb_f_eem.o | ||
| 27 | usb_f_ecm_subset-y := f_subset.o | ||
| 28 | obj-$(CONFIG_USB_F_SUBSET) += usb_f_ecm_subset.o | ||
| 29 | usb_f_rndis-y := f_rndis.o rndis.o | ||
| 30 | obj-$(CONFIG_USB_F_RNDIS) += usb_f_rndis.o | ||
| 31 | usb_f_mass_storage-y := f_mass_storage.o storage_common.o | ||
| 32 | obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o | ||
| 33 | usb_f_fs-y := f_fs.o | ||
| 34 | obj-$(CONFIG_USB_F_FS) += usb_f_fs.o | ||
File renamed without changes.
File renamed without changes.
| @@ -355,20 +355,18 @@ static struct sk_buff *eem_wrap(struct gether *port, struct sk_buff *skb) · 354 unmodified lines | |||
| 355 | int padlen = 0; | 355 | int padlen = 0; |
| 356 | u16 len = skb->len; | 356 | u16 len = skb->len; |
| 357 | 357 | ||
| 358 | if (!skb_cloned(skb)) { | 358 | int headroom = skb_headroom(skb); |
| 359 | int headroom = skb_headroom(skb); | 359 | int tailroom = skb_tailroom(skb); |
| 360 | int tailroom = skb_tailroom(skb); | ||
| 361 | 360 | ||
| 362 | /* When (len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) is 0, | 361 | /* When (len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) is 0, |
| 363 | * stick two bytes of zero-length EEM packet on the end. | 362 | * stick two bytes of zero-length EEM packet on the end. |
| 364 | */ | 363 | */ |
| 365 | if (((len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) == 0) | 364 | if (((len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) == 0) |
| 366 | padlen += 2; | 365 | padlen += 2; |
| 367 | 366 | ||
| 368 | if ((tailroom >= (ETH_FCS_LEN + padlen)) && | 367 | if ((tailroom >= (ETH_FCS_LEN + padlen)) && |
| 369 | (headroom >= EEM_HLEN)) | 368 | (headroom >= EEM_HLEN) && !skb_cloned(skb)) |
| 370 | goto done; | 369 | goto done; |
| 371 | } | ||
| 372 | 370 | ||
| 373 | skb2 = skb_copy_expand(skb, EEM_HLEN, ETH_FCS_LEN + padlen, GFP_ATOMIC); | 371 | skb2 = skb_copy_expand(skb, EEM_HLEN, ETH_FCS_LEN + padlen, GFP_ATOMIC); |
| 374 | dev_kfree_skb_any(skb); | 372 | dev_kfree_skb_any(skb); |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | 34 | ||
| 35 | #include "u_fs.h" | 35 | #include "u_fs.h" |
| 36 | #include "u_f.h" | 36 | #include "u_f.h" |
| 37 | #include "u_os_desc.h" | ||
| 37 | #include "configfs.h" | 38 | #include "configfs.h" |
| 38 | 39 | ||
| 39 | #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ | 40 | #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ |
| @@ -1646,13 +1647,22 @@ enum ffs_entity_type { · 1606 unmodified lines | |||
| 1646 | FFS_DESCRIPTOR, FFS_INTERFACE, FFS_STRING, FFS_ENDPOINT | 1647 | FFS_DESCRIPTOR, FFS_INTERFACE, FFS_STRING, FFS_ENDPOINT |
| 1647 | }; | 1648 | }; |
| 1648 | 1649 | ||
| 1650 | enum ffs_os_desc_type { | ||
| 1651 | FFS_OS_DESC, FFS_OS_DESC_EXT_COMPAT, FFS_OS_DESC_EXT_PROP | ||
| 1652 | }; | ||
| 1653 | |||
| 1649 | typedef int (*ffs_entity_callback)(enum ffs_entity_type entity, | 1654 | typedef int (*ffs_entity_callback)(enum ffs_entity_type entity, |
| 1650 | u8 *valuep, | 1655 | u8 *valuep, |
| 1651 | struct usb_descriptor_header *desc, | 1656 | struct usb_descriptor_header *desc, |
| 1652 | void *priv); | 1657 | void *priv); |
| 1653 | 1658 | ||
| 1654 | static int __must_check ffs_do_desc(char *data, unsigned len, | 1659 | typedef int (*ffs_os_desc_callback)(enum ffs_os_desc_type entity, |
| 1655 | ffs_entity_callback entity, void *priv) | 1660 | struct usb_os_desc_header *h, void *data, |
| 1661 | unsigned len, void *priv); | ||
| 1662 | |||
| 1663 | static int __must_check ffs_do_single_desc(char *data, unsigned len, | ||
| 1664 | ffs_entity_callback entity, | ||
| 1665 | void *priv) | ||
| 1656 | { | 1666 | { |
| 1657 | struct usb_descriptor_header *_ds = (void *)data; | 1667 | struct usb_descriptor_header *_ds = (void *)data; |
| 1658 | u8 length; | 1668 | u8 length; |
| @@ -1804,7 +1814,7 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len, · 145 unmodified lines | |||
| 1804 | if (!data) | 1814 | if (!data) |
| 1805 | return _len - len; | 1815 | return _len - len; |
| 1806 | 1816 | ||
| 1807 | ret = ffs_do_desc(data, len, entity, priv); | 1817 | ret = ffs_do_single_desc(data, len, entity, priv); |
| 1808 | if (unlikely(ret < 0)) { | 1818 | if (unlikely(ret < 0)) { |
| 1809 | pr_debug("%s returns %d\n", __func__, ret); | 1819 | pr_debug("%s returns %d\n", __func__, ret); |
| 1810 | return ret; | 1820 | return ret; |
| @@ -1857,11 +1867,191 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, · 46 unmodified lines | |||
| 1857 | return 0; | 1867 | return 0; |
| 1858 | } | 1868 | } |
| 1859 | 1869 | ||
| 1870 | static int __ffs_do_os_desc_header(enum ffs_os_desc_type *next_type, | ||
| 1871 | struct usb_os_desc_header *desc) | ||
| 1872 | { | ||
| 1873 | u16 bcd_version = le16_to_cpu(desc->bcdVersion); | ||
| 1874 | u16 w_index = le16_to_cpu(desc->wIndex); | ||
| 1875 | |||
| 1876 | if (bcd_version != 1) { | ||
| 1877 | pr_vdebug("unsupported os descriptors version: %d", | ||
| 1878 | bcd_version); | ||
| 1879 | return -EINVAL; | ||
| 1880 | } | ||
| 1881 | switch (w_index) { | ||
| 1882 | case 0x4: | ||
| 1883 | *next_type = FFS_OS_DESC_EXT_COMPAT; | ||
| 1884 | break; | ||
| 1885 | case 0x5: | ||
| 1886 | *next_type = FFS_OS_DESC_EXT_PROP; | ||
| 1887 | break; | ||
| 1888 | default: | ||
| 1889 | pr_vdebug("unsupported os descriptor type: %d", w_index); | ||
| 1890 | return -EINVAL; | ||
| 1891 | } | ||
| 1892 | |||
| 1893 | return sizeof(*desc); | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | /* | ||
| 1897 | * Process all extended compatibility/extended property descriptors | ||
| 1898 | * of a feature descriptor | ||
| 1899 | */ | ||
| 1900 | static int __must_check ffs_do_single_os_desc(char *data, unsigned len, | ||
| 1901 | enum ffs_os_desc_type type, | ||
| 1902 | u16 feature_count, | ||
| 1903 | ffs_os_desc_callback entity, | ||
| 1904 | void *priv, | ||
| 1905 | struct usb_os_desc_header *h) | ||
| 1906 | { | ||
| 1907 | int ret; | ||
| 1908 | const unsigned _len = len; | ||
| 1909 | |||
| 1910 | ENTER(); | ||
| 1911 | |||
| 1912 | /* loop over all ext compat/ext prop descriptors */ | ||
| 1913 | while (feature_count--) { | ||
| 1914 | ret = entity(type, h, data, len, priv); | ||
| 1915 | if (unlikely(ret < 0)) { | ||
| 1916 | pr_debug("bad OS descriptor, type: %d\n", type); | ||
| 1917 | return ret; | ||
| 1918 | } | ||
| 1919 | data += ret; | ||
| 1920 | len -= ret; | ||
| 1921 | } | ||
| 1922 | return _len - len; | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | /* Process a number of complete Feature Descriptors (Ext Compat or Ext Prop) */ | ||
| 1926 | static int __must_check ffs_do_os_descs(unsigned count, | ||
| 1927 | char *data, unsigned len, | ||
| 1928 | ffs_os_desc_callback entity, void *priv) | ||
| 1929 | { | ||
| 1930 | const unsigned _len = len; | ||
| 1931 | unsigned long num = 0; | ||
| 1932 | |||
| 1933 | ENTER(); | ||
| 1934 | |||
| 1935 | for (num = 0; num < count; ++num) { | ||
| 1936 | int ret; | ||
| 1937 | enum ffs_os_desc_type type; | ||
| 1938 | u16 feature_count; | ||
| 1939 | struct usb_os_desc_header *desc = (void *)data; | ||
| 1940 | |||
| 1941 | if (len < sizeof(*desc)) | ||
| 1942 | return -EINVAL; | ||
| 1943 | |||
| 1944 | /* | ||
| 1945 | * Record "descriptor" entity. | ||
| 1946 | * Process dwLength, bcdVersion, wIndex, get b/wCount. | ||
| 1947 | * Move the data pointer to the beginning of extended | ||
| 1948 | * compatibilities proper or extended properties proper | ||
| 1949 | * portions of the data | ||
| 1950 | */ | ||
| 1951 | if (le32_to_cpu(desc->dwLength) > len) | ||
| 1952 | return -EINVAL; | ||
| 1953 | |||
| 1954 | ret = __ffs_do_os_desc_header(&type, desc); | ||
| 1955 | if (unlikely(ret < 0)) { | ||
| 1956 | pr_debug("entity OS_DESCRIPTOR(%02lx); ret = %d\n", | ||
| 1957 | num, ret); | ||
| 1958 | return ret; | ||
| 1959 | } | ||
| 1960 | /* | ||
| 1961 | * 16-bit hex "?? 00" Little Endian looks like 8-bit hex "??" | ||
| 1962 | */ | ||
| 1963 | feature_count = le16_to_cpu(desc->wCount); | ||
| 1964 | if (type == FFS_OS_DESC_EXT_COMPAT && | ||
| 1965 | (feature_count > 255 || desc->Reserved)) | ||
| 1966 | return -EINVAL; | ||
| 1967 | len -= ret; | ||
| 1968 | data += ret; | ||
| 1969 | |||
| 1970 | /* | ||
| 1971 | * Process all function/property descriptors | ||
| 1972 | * of this Feature Descriptor | ||
| 1973 | */ | ||
| 1974 | ret = ffs_do_single_os_desc(data, len, type, | ||
| 1975 | feature_count, entity, priv, desc); | ||
| 1976 | if (unlikely(ret < 0)) { | ||
| 1977 | pr_debug("%s returns %d\n", __func__, ret); | ||
| 1978 | return ret; | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | len -= ret; | ||
| 1982 | data += ret; | ||
| 1983 | } | ||
| 1984 | return _len - len; | ||
| 1985 | } | ||
| 1986 | |||
| 1987 | /** | ||
| 1988 | * Validate contents of the buffer from userspace related to OS descriptors. | ||
| 1989 | */ | ||
| 1990 | static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, | ||
| 1991 | struct usb_os_desc_header *h, void *data, | ||
| 1992 | unsigned len, void *priv) | ||
| 1993 | { | ||
| 1994 | struct ffs_data *ffs = priv; | ||
| 1995 | u8 length; | ||
| 1996 | |||
| 1997 | ENTER(); | ||
| 1998 | |||
| 1999 | switch (type) { | ||
| 2000 | case FFS_OS_DESC_EXT_COMPAT: { | ||
| 2001 | struct usb_ext_compat_desc *d = data; | ||
| 2002 | int i; | ||
| 2003 | |||
| 2004 | if (len < sizeof(*d) || | ||
| 2005 | d->bFirstInterfaceNumber >= ffs->interfaces_count || | ||
| 2006 | d->Reserved1) | ||
| 2007 | return -EINVAL; | ||
| 2008 | for (i = 0; i < ARRAY_SIZE(d->Reserved2); ++i) | ||
| 2009 | if (d->Reserved2[i]) | ||
| 2010 | return -EINVAL; | ||
| 2011 | |||
| 2012 | length = sizeof(struct usb_ext_compat_desc); | ||
| 2013 | } | ||
| 2014 | break; | ||
| 2015 | case FFS_OS_DESC_EXT_PROP: { | ||
| 2016 | struct usb_ext_prop_desc *d = data; | ||
| 2017 | u32 type, pdl; | ||
| 2018 | u16 pnl; | ||
| 2019 | |||
| 2020 | if (len < sizeof(*d) || h->interface >= ffs->interfaces_count) | ||
| 2021 | return -EINVAL; | ||
| 2022 | length = le32_to_cpu(d->dwSize); | ||
| 2023 | type = le32_to_cpu(d->dwPropertyDataType); | ||
| 2024 | if (type < USB_EXT_PROP_UNICODE || | ||
| 2025 | type > USB_EXT_PROP_UNICODE_MULTI) { | ||
| 2026 | pr_vdebug("unsupported os descriptor property type: %d", | ||
| 2027 | type); | ||
| 2028 | return -EINVAL; | ||
| 2029 | } | ||
| 2030 | pnl = le16_to_cpu(d->wPropertyNameLength); | ||
| 2031 | pdl = le32_to_cpu(*(u32 *)((u8 *)data + 10 + pnl)); | ||
| 2032 | if (length != 14 + pnl + pdl) { | ||
| 2033 | pr_vdebug("invalid os descriptor length: %d pnl:%d pdl:%d (descriptor %d)\n", | ||
| 2034 | length, pnl, pdl, type); | ||
| 2035 | return -EINVAL; | ||
| 2036 | } | ||
| 2037 | ++ffs->ms_os_descs_ext_prop_count; | ||
| 2038 | /* property name reported to the host as "WCHAR"s */ | ||
| 2039 | ffs->ms_os_descs_ext_prop_name_len += pnl * 2; | ||
| 2040 | ffs->ms_os_descs_ext_prop_data_len += pdl; | ||
| 2041 | } | ||
| 2042 | break; | ||
| 2043 | default: | ||
| 2044 | pr_vdebug("unknown descriptor: %d\n", type); | ||
| 2045 | return -EINVAL; | ||
| 2046 | } | ||
| 2047 | return length; | ||
| 2048 | } | ||
| 2049 | |||
| 1860 | static int __ffs_data_got_descs(struct ffs_data *ffs, | 2050 | static int __ffs_data_got_descs(struct ffs_data *ffs, |
| 1861 | char *const _data, size_t len) | 2051 | char *const _data, size_t len) |
| 1862 | { | 2052 | { |
| 1863 | char *data = _data, *raw_descs; | 2053 | char *data = _data, *raw_descs; |
| 1864 | unsigned counts[3], flags; | 2054 | unsigned os_descs_count = 0, counts[3], flags; |
| 1865 | int ret = -EINVAL, i; | 2055 | int ret = -EINVAL, i; |
| 1866 | 2056 | ||
| 1867 | ENTER(); | 2057 | ENTER(); |
| @@ -1879,7 +2069,8 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, · 11 unmodified lines | |||
| 1879 | flags = get_unaligned_le32(data + 8); | 2069 | flags = get_unaligned_le32(data + 8); |
| 1880 | if (flags & ~(FUNCTIONFS_HAS_FS_DESC | | 2070 | if (flags & ~(FUNCTIONFS_HAS_FS_DESC | |
| 1881 | FUNCTIONFS_HAS_HS_DESC | | 2071 | FUNCTIONFS_HAS_HS_DESC | |
| 1882 | FUNCTIONFS_HAS_SS_DESC)) { | 2072 | FUNCTIONFS_HAS_SS_DESC | |
| 2073 | FUNCTIONFS_HAS_MS_OS_DESC)) { | ||
| 1883 | ret = -ENOSYS; | 2074 | ret = -ENOSYS; |
| 1884 | goto error; | 2075 | goto error; |
| 1885 | } | 2076 | } |
| @@ -1902,6 +2093,11 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, · 16 unmodified lines | |||
| 1902 | len -= 4; | 2093 | len -= 4; |
| 1903 | } | 2094 | } |
| 1904 | } | 2095 | } |
| 2096 | if (flags & (1 << i)) { | ||
| 2097 | os_descs_count = get_unaligned_le32(data); | ||
| 2098 | data += 4; | ||
| 2099 | len -= 4; | ||
| 2100 | }; | ||
| 1905 | 2101 | ||
| 1906 | /* Read descriptors */ | 2102 | /* Read descriptors */ |
| 1907 | raw_descs = data; | 2103 | raw_descs = data; |
| @@ -1915,6 +2111,14 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, · 7 unmodified lines | |||
| 1915 | data += ret; | 2111 | data += ret; |
| 1916 | len -= ret; | 2112 | len -= ret; |
| 1917 | } | 2113 | } |
| 2114 | if (os_descs_count) { | ||
| 2115 | ret = ffs_do_os_descs(os_descs_count, data, len, | ||
| 2116 | __ffs_data_do_os_desc, ffs); | ||
| 2117 | if (ret < 0) | ||
| 2118 | goto error; | ||
| 2119 | data += ret; | ||
| 2120 | len -= ret; | ||
| 2121 | } | ||
| 1918 | 2122 | ||
| 1919 | if (raw_descs == data || len) { | 2123 | if (raw_descs == data || len) { |
| 1920 | ret = -EINVAL; | 2124 | ret = -EINVAL; |
| @@ -1927,6 +2131,7 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, · 6 unmodified lines | |||
| 1927 | ffs->fs_descs_count = counts[0]; | 2131 | ffs->fs_descs_count = counts[0]; |
| 1928 | ffs->hs_descs_count = counts[1]; | 2132 | ffs->hs_descs_count = counts[1]; |
| 1929 | ffs->ss_descs_count = counts[2]; | 2133 | ffs->ss_descs_count = counts[2]; |
| 2134 | ffs->ms_os_descs_count = os_descs_count; | ||
| 1930 | 2135 | ||
| 1931 | return 0; | 2136 | return 0; |
| 1932 | 2137 | ||
| @@ -2268,6 +2473,85 @@ static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep, · 335 unmodified lines | |||
| 2268 | return 0; | 2473 | return 0; |
| 2269 | } | 2474 | } |
| 2270 | 2475 | ||
| 2476 | static int __ffs_func_bind_do_os_desc(enum ffs_os_desc_type type, | ||
| 2477 | struct usb_os_desc_header *h, void *data, | ||
| 2478 | unsigned len, void *priv) | ||
| 2479 | { | ||
| 2480 | struct ffs_function *func = priv; | ||
| 2481 | u8 length = 0; | ||
| 2482 | |||
| 2483 | switch (type) { | ||
| 2484 | case FFS_OS_DESC_EXT_COMPAT: { | ||
| 2485 | struct usb_ext_compat_desc *desc = data; | ||
| 2486 | struct usb_os_desc_table *t; | ||
| 2487 | |||
| 2488 | t = &func->function.os_desc_table[desc->bFirstInterfaceNumber]; | ||
| 2489 | t->if_id = func->interfaces_nums[desc->bFirstInterfaceNumber]; | ||
| 2490 | memcpy(t->os_desc->ext_compat_id, &desc->CompatibleID, | ||
| 2491 | ARRAY_SIZE(desc->CompatibleID) + | ||
| 2492 | ARRAY_SIZE(desc->SubCompatibleID)); | ||
| 2493 | length = sizeof(*desc); | ||
| 2494 | } | ||
| 2495 | break; | ||
| 2496 | case FFS_OS_DESC_EXT_PROP: { | ||
| 2497 | struct usb_ext_prop_desc *desc = data; | ||
| 2498 | struct usb_os_desc_table *t; | ||
| 2499 | struct usb_os_desc_ext_prop *ext_prop; | ||
| 2500 | char *ext_prop_name; | ||
| 2501 | char *ext_prop_data; | ||
| 2502 | |||
| 2503 | t = &func->function.os_desc_table[h->interface]; | ||
| 2504 | t->if_id = func->interfaces_nums[h->interface]; | ||
| 2505 | |||
| 2506 | ext_prop = func->ffs->ms_os_descs_ext_prop_avail; | ||
| 2507 | func->ffs->ms_os_descs_ext_prop_avail += sizeof(*ext_prop); | ||
| 2508 | |||
| 2509 | ext_prop->type = le32_to_cpu(desc->dwPropertyDataType); | ||
| 2510 | ext_prop->name_len = le16_to_cpu(desc->wPropertyNameLength); | ||
| 2511 | ext_prop->data_len = le32_to_cpu(*(u32 *) | ||
| 2512 | usb_ext_prop_data_len_ptr(data, ext_prop->name_len)); | ||
| 2513 | length = ext_prop->name_len + ext_prop->data_len + 14; | ||
| 2514 | |||
| 2515 | ext_prop_name = func->ffs->ms_os_descs_ext_prop_name_avail; | ||
| 2516 | func->ffs->ms_os_descs_ext_prop_name_avail += | ||
| 2517 | ext_prop->name_len; | ||
| 2518 | |||
| 2519 | ext_prop_data = func->ffs->ms_os_descs_ext_prop_data_avail; | ||
| 2520 | func->ffs->ms_os_descs_ext_prop_data_avail += | ||
| 2521 | ext_prop->data_len; | ||
| 2522 | memcpy(ext_prop_data, | ||
| 2523 | usb_ext_prop_data_ptr(data, ext_prop->name_len), | ||
| 2524 | ext_prop->data_len); | ||
| 2525 | /* unicode data reported to the host as "WCHAR"s */ | ||
| 2526 | switch (ext_prop->type) { | ||
| 2527 | case USB_EXT_PROP_UNICODE: | ||
| 2528 | case USB_EXT_PROP_UNICODE_ENV: | ||
| 2529 | case USB_EXT_PROP_UNICODE_LINK: | ||
| 2530 | case USB_EXT_PROP_UNICODE_MULTI: | ||
| 2531 | ext_prop->data_len *= 2; | ||
| 2532 | break; | ||
| 2533 | } | ||
| 2534 | ext_prop->data = ext_prop_data; | ||
| 2535 | |||
| 2536 | memcpy(ext_prop_name, usb_ext_prop_name_ptr(data), | ||
| 2537 | ext_prop->name_len); | ||
| 2538 | /* property name reported to the host as "WCHAR"s */ | ||
| 2539 | ext_prop->name_len *= 2; | ||
| 2540 | ext_prop->name = ext_prop_name; | ||
| 2541 | |||
| 2542 | t->os_desc->ext_prop_len += | ||
| 2543 | ext_prop->name_len + ext_prop->data_len + 14; | ||
| 2544 | ++t->os_desc->ext_prop_count; | ||
| 2545 | list_add_tail(&ext_prop->entry, &t->os_desc->ext_prop); | ||
| 2546 | } | ||
| 2547 | break; | ||
| 2548 | default: | ||
| 2549 | pr_vdebug("unknown descriptor: %d\n", type); | ||
| 2550 | } | ||
| 2551 | |||
| 2552 | return length; | ||
| 2553 | } | ||
| 2554 | |||
| 2271 | static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f, | 2555 | static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f, |
| 2272 | struct usb_configuration *c) | 2556 | struct usb_configuration *c) |
| 2273 | { | 2557 | { |
| @@ -2329,7 +2613,7 @@ static int _ffs_func_bind(struct usb_configuration *c, · 55 unmodified lines | |||
| 2329 | const int super = gadget_is_superspeed(func->gadget) && | 2613 | const int super = gadget_is_superspeed(func->gadget) && |
| 2330 | func->ffs->ss_descs_count; | 2614 | func->ffs->ss_descs_count; |
| 2331 | 2615 | ||
| 2332 | int fs_len, hs_len, ret; | 2616 | int fs_len, hs_len, ss_len, ret, i; |
| 2333 | 2617 | ||
| 2334 | /* Make it a single chunk, less management later on */ | 2618 | /* Make it a single chunk, less management later on */ |
| 2335 | vla_group(d); | 2619 | vla_group(d); |
| @@ -2341,6 +2625,18 @@ static int _ffs_func_bind(struct usb_configuration *c, · 5 unmodified lines | |||
| 2341 | vla_item_with_sz(d, struct usb_descriptor_header *, ss_descs, | 2625 | vla_item_with_sz(d, struct usb_descriptor_header *, ss_descs, |
| 2342 | super ? ffs->ss_descs_count + 1 : 0); | 2626 | super ? ffs->ss_descs_count + 1 : 0); |
| 2343 | vla_item_with_sz(d, short, inums, ffs->interfaces_count); | 2627 | vla_item_with_sz(d, short, inums, ffs->interfaces_count); |
| 2628 | vla_item_with_sz(d, struct usb_os_desc_table, os_desc_table, | ||
| 2629 | c->cdev->use_os_string ? ffs->interfaces_count : 0); | ||
| 2630 | vla_item_with_sz(d, char[16], ext_compat, | ||
| 2631 | c->cdev->use_os_string ? ffs->interfaces_count : 0); | ||
| 2632 | vla_item_with_sz(d, struct usb_os_desc, os_desc, | ||
| 2633 | c->cdev->use_os_string ? ffs->interfaces_count : 0); | ||
| 2634 | vla_item_with_sz(d, struct usb_os_desc_ext_prop, ext_prop, | ||
| 2635 | ffs->ms_os_descs_ext_prop_count); | ||
| 2636 | vla_item_with_sz(d, char, ext_prop_name, | ||
| 2637 | ffs->ms_os_descs_ext_prop_name_len); | ||
| 2638 | vla_item_with_sz(d, char, ext_prop_data, | ||
| 2639 | ffs->ms_os_descs_ext_prop_data_len); | ||
| 2344 | vla_item_with_sz(d, char, raw_descs, ffs->raw_descs_length); | 2640 | vla_item_with_sz(d, char, raw_descs, ffs->raw_descs_length); |
| 2345 | char *vlabuf; | 2641 | char *vlabuf; |
| 2346 | 2642 | ||
| @@ -2351,12 +2647,16 @@ static int _ffs_func_bind(struct usb_configuration *c, · 4 unmodified lines | |||
| 2351 | return -ENOTSUPP; | 2647 | return -ENOTSUPP; |
| 2352 | 2648 | ||
| 2353 | /* Allocate a single chunk, less management later on */ | 2649 | /* Allocate a single chunk, less management later on */ |
| 2354 | vlabuf = kmalloc(vla_group_size(d), GFP_KERNEL); | 2650 | vlabuf = kzalloc(vla_group_size(d), GFP_KERNEL); |
| 2355 | if (unlikely(!vlabuf)) | 2651 | if (unlikely(!vlabuf)) |
| 2356 | return -ENOMEM; | 2652 | return -ENOMEM; |
| 2357 | 2653 | ||
| 2358 | /* Zero */ | 2654 | ffs->ms_os_descs_ext_prop_avail = vla_ptr(vlabuf, d, ext_prop); |
| 2359 | memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz); | 2655 | ffs->ms_os_descs_ext_prop_name_avail = |
| 2656 | vla_ptr(vlabuf, d, ext_prop_name); | ||
| 2657 | ffs->ms_os_descs_ext_prop_data_avail = | ||
| 2658 | vla_ptr(vlabuf, d, ext_prop_data); | ||
| 2659 | |||
| 2360 | /* Copy descriptors */ | 2660 | /* Copy descriptors */ |
| 2361 | memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs, | 2661 | memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs, |
| 2362 | ffs->raw_descs_length); | 2662 | ffs->raw_descs_length); |
| @@ -2410,12 +2710,16 @@ static int _ffs_func_bind(struct usb_configuration *c, · 47 unmodified lines | |||
| 2410 | 2710 | ||
| 2411 | if (likely(super)) { | 2711 | if (likely(super)) { |
| 2412 | func->function.ss_descriptors = vla_ptr(vlabuf, d, ss_descs); | 2712 | func->function.ss_descriptors = vla_ptr(vlabuf, d, ss_descs); |
| 2413 | ret = ffs_do_descs(ffs->ss_descs_count, | 2713 | ss_len = ffs_do_descs(ffs->ss_descs_count, |
| 2414 | vla_ptr(vlabuf, d, raw_descs) + fs_len + hs_len, | 2714 | vla_ptr(vlabuf, d, raw_descs) + fs_len + hs_len, |
| 2415 | d_raw_descs__sz - fs_len - hs_len, | 2715 | d_raw_descs__sz - fs_len - hs_len, |
| 2416 | __ffs_func_bind_do_descs, func); | 2716 | __ffs_func_bind_do_descs, func); |
| 2417 | if (unlikely(ret < 0)) | 2717 | if (unlikely(ss_len < 0)) { |
| 2718 | ret = ss_len; | ||
| 2418 | goto error; | 2719 | goto error; |
| 2720 | } | ||
| 2721 | } else { | ||
| 2722 | ss_len = 0; | ||
| 2419 | } | 2723 | } |
| 2420 | 2724 | ||
| 2421 | /* | 2725 | /* |
| @@ -2431,6 +2735,28 @@ static int _ffs_func_bind(struct usb_configuration *c, · 9 unmodified lines | |||
| 2431 | if (unlikely(ret < 0)) | 2735 | if (unlikely(ret < 0)) |
| 2432 | goto error; | 2736 | goto error; |
| 2433 | 2737 | ||
| 2738 | func->function.os_desc_table = vla_ptr(vlabuf, d, os_desc_table); | ||
| 2739 | if (c->cdev->use_os_string) | ||
| 2740 | for (i = 0; i < ffs->interfaces_count; ++i) { | ||
| 2741 | struct usb_os_desc *desc; | ||
| 2742 | |||
| 2743 | desc = func->function.os_desc_table[i].os_desc = | ||
| 2744 | vla_ptr(vlabuf, d, os_desc) + | ||
| 2745 | i * sizeof(struct usb_os_desc); | ||
| 2746 | desc->ext_compat_id = | ||
| 2747 | vla_ptr(vlabuf, d, ext_compat) + i * 16; | ||
| 2748 | INIT_LIST_HEAD(&desc->ext_prop); | ||
| 2749 | } | ||
| 2750 | ret = ffs_do_os_descs(ffs->ms_os_descs_count, | ||
| 2751 | vla_ptr(vlabuf, d, raw_descs) + | ||
| 2752 | fs_len + hs_len + ss_len, | ||
| 2753 | d_raw_descs__sz - fs_len - hs_len - ss_len, | ||
| 2754 | __ffs_func_bind_do_os_desc, func); | ||
| 2755 | if (unlikely(ret < 0)) | ||
| 2756 | goto error; | ||
| 2757 | func->function.os_desc_n = | ||
| 2758 | c->cdev->use_os_string ? ffs->interfaces_count : 0; | ||
| 2759 | |||
| 2434 | /* And we're done */ | 2760 | /* And we're done */ |
| 2435 | ffs_event_add(ffs, FUNCTIONFS_BIND); | 2761 | ffs_event_add(ffs, FUNCTIONFS_BIND); |
| 2436 | return 0; | 2762 | return 0; |
| @@ -2901,12 +3227,12 @@ static void *ffs_acquire_dev(const char *dev_name) · 464 unmodified lines | |||
| 2901 | 3227 | ||
| 2902 | ffs_dev = _ffs_find_dev(dev_name); | 3228 | ffs_dev = _ffs_find_dev(dev_name); |
| 2903 | if (!ffs_dev) | 3229 | if (!ffs_dev) |
| 2904 | ffs_dev = ERR_PTR(-ENODEV); | 3230 | ffs_dev = ERR_PTR(-ENOENT); |
| 2905 | else if (ffs_dev->mounted) | 3231 | else if (ffs_dev->mounted) |
| 2906 | ffs_dev = ERR_PTR(-EBUSY); | 3232 | ffs_dev = ERR_PTR(-EBUSY); |
| 2907 | else if (ffs_dev->ffs_acquire_dev_callback && | 3233 | else if (ffs_dev->ffs_acquire_dev_callback && |
| 2908 | ffs_dev->ffs_acquire_dev_callback(ffs_dev)) | 3234 | ffs_dev->ffs_acquire_dev_callback(ffs_dev)) |
| 2909 | ffs_dev = ERR_PTR(-ENODEV); | 3235 | ffs_dev = ERR_PTR(-ENOENT); |
| 2910 | else | 3236 | else |
| 2911 | ffs_dev->mounted = true; | 3237 | ffs_dev->mounted = true; |
| 2912 | 3238 | ||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -68,6 +68,18 @@ struct f_ncm { · 67 unmodified lines | |||
| 68 | * callback and ethernet open/close | 68 | * callback and ethernet open/close |
| 69 | */ | 69 | */ |
| 70 | spinlock_t lock; | 70 | spinlock_t lock; |
| 71 | |||
| 72 | struct net_device *netdev; | ||
| 73 | |||
| 74 | /* For multi-frame NDP TX */ | ||
| 75 | struct sk_buff *skb_tx_data; | ||
| 76 | struct sk_buff *skb_tx_ndp; | ||
| 77 | u16 ndp_dgram_count; | ||
| 78 | bool timer_force_tx; | ||
| 79 | struct tasklet_struct tx_tasklet; | ||
| 80 | struct hrtimer task_timer; | ||
| 81 | |||
| 82 | bool timer_stopping; | ||
| 71 | }; | 83 | }; |
| 72 | 84 | ||
| 73 | static inline struct f_ncm *func_to_ncm(struct usb_function *f) | 85 | static inline struct f_ncm *func_to_ncm(struct usb_function *f) |
| @@ -92,15 +104,20 @@ static inline unsigned ncm_bitrate(struct usb_gadget *g) · 18 unmodified lines | |||
| 92 | * If the host can group frames, allow it to do that, 16K is selected, | 104 | * If the host can group frames, allow it to do that, 16K is selected, |
| 93 | * because it's used by default by the current linux host driver | 105 | * because it's used by default by the current linux host driver |
| 94 | */ | 106 | */ |
| 95 | #define NTB_DEFAULT_IN_SIZE USB_CDC_NCM_NTB_MIN_IN_SIZE | 107 | #define NTB_DEFAULT_IN_SIZE 16384 |
| 96 | #define NTB_OUT_SIZE 16384 | 108 | #define NTB_OUT_SIZE 16384 |
| 97 | 109 | ||
| 98 | /* | 110 | /* Allocation for storing the NDP, 32 should suffice for a |
| 99 | * skbs of size less than that will not be aligned | 111 | * 16k packet. This allows a maximum of 32 * 507 Byte packets to |
| 100 | * to NCM's dwNtbInMaxSize to save bus bandwidth | 112 | * be transmitted in a single 16kB skb, though when sending full size |
| 113 | * packets this limit will be plenty. | ||
| 114 | * Smaller packets are not likely to be trying to maximize the | ||
| 115 | * throughput and will be mstly sending smaller infrequent frames. | ||
| 101 | */ | 116 | */ |
| 117 | #define TX_MAX_NUM_DPE 32 | ||
| 102 | 118 | ||
| 103 | #define MAX_TX_NONFIXED (512 * 3) | 119 | /* Delay for the transmit to wait before sending an unfilled NTB frame. */ |
| 120 | #define TX_TIMEOUT_NSECS 300000 | ||
| 104 | 121 | ||
| 105 | #define FORMATS_SUPPORTED (USB_CDC_NCM_NTB16_SUPPORTED | \ | 122 | #define FORMATS_SUPPORTED (USB_CDC_NCM_NTB16_SUPPORTED | \ |
| 106 | USB_CDC_NCM_NTB32_SUPPORTED) | 123 | USB_CDC_NCM_NTB32_SUPPORTED) |
| @@ -355,14 +372,15 @@ struct ndp_parser_opts { · 248 unmodified lines | |||
| 355 | u32 ndp_sign; | 372 | u32 ndp_sign; |
| 356 | unsigned nth_size; | 373 | unsigned nth_size; |
| 357 | unsigned ndp_size; | 374 | unsigned ndp_size; |
| 375 | unsigned dpe_size; | ||
| 358 | unsigned ndplen_align; | 376 | unsigned ndplen_align; |
| 359 | /* sizes in u16 units */ | 377 | /* sizes in u16 units */ |
| 360 | unsigned dgram_item_len; /* index or length */ | 378 | unsigned dgram_item_len; /* index or length */ |
| 361 | unsigned block_length; | 379 | unsigned block_length; |
| 362 | unsigned fp_index; | 380 | unsigned ndp_index; |
| 363 | unsigned reserved1; | 381 | unsigned reserved1; |
| 364 | unsigned reserved2; | 382 | unsigned reserved2; |
| 365 | unsigned next_fp_index; | 383 | unsigned next_ndp_index; |
| 366 | }; | 384 | }; |
| 367 | 385 | ||
| 368 | #define INIT_NDP16_OPTS { \ | 386 | #define INIT_NDP16_OPTS { \ |
| @@ -370,13 +388,14 @@ struct ndp_parser_opts { · 1 unmodified line | |||
| 370 | .ndp_sign = USB_CDC_NCM_NDP16_NOCRC_SIGN, \ | 388 | .ndp_sign = USB_CDC_NCM_NDP16_NOCRC_SIGN, \ |
| 371 | .nth_size = sizeof(struct usb_cdc_ncm_nth16), \ | 389 | .nth_size = sizeof(struct usb_cdc_ncm_nth16), \ |
| 372 | .ndp_size = sizeof(struct usb_cdc_ncm_ndp16), \ | 390 | .ndp_size = sizeof(struct usb_cdc_ncm_ndp16), \ |
| 391 | .dpe_size = sizeof(struct usb_cdc_ncm_dpe16), \ | ||
| 373 | .ndplen_align = 4, \ | 392 | .ndplen_align = 4, \ |
| 374 | .dgram_item_len = 1, \ | 393 | .dgram_item_len = 1, \ |
| 375 | .block_length = 1, \ | 394 | .block_length = 1, \ |
| 376 | .fp_index = 1, \ | 395 | .ndp_index = 1, \ |
| 377 | .reserved1 = 0, \ | 396 | .reserved1 = 0, \ |
| 378 | .reserved2 = 0, \ | 397 | .reserved2 = 0, \ |
| 379 | .next_fp_index = 1, \ | 398 | .next_ndp_index = 1, \ |
| 380 | } | 399 | } |
| 381 | 400 | ||
| 382 | 401 | ||
| @@ -385,13 +404,14 @@ struct ndp_parser_opts { · 2 unmodified lines | |||
| 385 | .ndp_sign = USB_CDC_NCM_NDP32_NOCRC_SIGN, \ | 404 | .ndp_sign = USB_CDC_NCM_NDP32_NOCRC_SIGN, \ |
| 386 | .nth_size = sizeof(struct usb_cdc_ncm_nth32), \ | 405 | .nth_size = sizeof(struct usb_cdc_ncm_nth32), \ |
| 387 | .ndp_size = sizeof(struct usb_cdc_ncm_ndp32), \ | 406 | .ndp_size = sizeof(struct usb_cdc_ncm_ndp32), \ |
| 407 | .dpe_size = sizeof(struct usb_cdc_ncm_dpe32), \ | ||
| 388 | .ndplen_align = 8, \ | 408 | .ndplen_align = 8, \ |
| 389 | .dgram_item_len = 2, \ | 409 | .dgram_item_len = 2, \ |
| 390 | .block_length = 2, \ | 410 | .block_length = 2, \ |
| 391 | .fp_index = 2, \ | 411 | .ndp_index = 2, \ |
| 392 | .reserved1 = 1, \ | 412 | .reserved1 = 1, \ |
| 393 | .reserved2 = 2, \ | 413 | .reserved2 = 2, \ |
| 394 | .next_fp_index = 2, \ | 414 | .next_ndp_index = 2, \ |
| 395 | } | 415 | } |
| 396 | 416 | ||
| 397 | static const struct ndp_parser_opts ndp16_opts = INIT_NDP16_OPTS; | 417 | static const struct ndp_parser_opts ndp16_opts = INIT_NDP16_OPTS; |
| @@ -803,6 +823,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) · 405 unmodified lines | |||
| 803 | 823 | ||
| 804 | if (ncm->port.in_ep->driver_data) { | 824 | if (ncm->port.in_ep->driver_data) { |
| 805 | DBG(cdev, "reset ncm\n"); | 825 | DBG(cdev, "reset ncm\n"); |
| 826 | ncm->timer_stopping = true; | ||
| 827 | ncm->netdev = NULL; | ||
| 806 | gether_disconnect(&ncm->port); | 828 | gether_disconnect(&ncm->port); |
| 807 | ncm_reset_values(ncm); | 829 | ncm_reset_values(ncm); |
| 808 | } | 830 | } |
| @@ -839,6 +861,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) · 30 unmodified lines | |||
| 839 | net = gether_connect(&ncm->port); | 861 | net = gether_connect(&ncm->port); |
| 840 | if (IS_ERR(net)) | 862 | if (IS_ERR(net)) |
| 841 | return PTR_ERR(net); | 863 | return PTR_ERR(net); |
| 864 | ncm->netdev = net; | ||
| 865 | ncm->timer_stopping = false; | ||
| 842 | } | 866 | } |
| 843 | 867 | ||
| 844 | spin_lock(&ncm->lock); | 868 | spin_lock(&ncm->lock); |
| @@ -865,95 +889,232 @@ static int ncm_get_alt(struct usb_function *f, unsigned intf) · 20 unmodified lines | |||
| 865 | return ncm->port.in_ep->driver_data ? 1 : 0; | 889 | return ncm->port.in_ep->driver_data ? 1 : 0; |
| 866 | } | 890 | } |
| 867 | 891 | ||
| 892 | static struct sk_buff *package_for_tx(struct f_ncm *ncm) | ||
| 893 | { | ||
| 894 | __le16 *ntb_iter; | ||
| 895 | struct sk_buff *skb2 = NULL; | ||
| 896 | unsigned ndp_pad; | ||
| 897 | unsigned ndp_index; | ||
| 898 | unsigned new_len; | ||
| 899 | |||
| 900 | const struct ndp_parser_opts *opts = ncm->parser_opts; | ||
| 901 | const int ndp_align = le16_to_cpu(ntb_parameters.wNdpInAlignment); | ||
| 902 | const int dgram_idx_len = 2 * 2 * opts->dgram_item_len; | ||
| 903 | |||
| 904 | /* Stop the timer */ | ||
| 905 | hrtimer_try_to_cancel(&ncm->task_timer); | ||
| 906 | |||
| 907 | ndp_pad = ALIGN(ncm->skb_tx_data->len, ndp_align) - | ||
| 908 | ncm->skb_tx_data->len; | ||
| 909 | ndp_index = ncm->skb_tx_data->len + ndp_pad; | ||
| 910 | new_len = ndp_index + dgram_idx_len + ncm->skb_tx_ndp->len; | ||
| 911 | |||
| 912 | /* Set the final BlockLength and wNdpIndex */ | ||
| 913 | ntb_iter = (void *) ncm->skb_tx_data->data; | ||
| 914 | /* Increment pointer to BlockLength */ | ||
| 915 | ntb_iter += 2 + 1 + 1; | ||
| 916 | put_ncm(&ntb_iter, opts->block_length, new_len); | ||
| 917 | put_ncm(&ntb_iter, opts->ndp_index, ndp_index); | ||
| 918 | |||
| 919 | /* Set the final NDP wLength */ | ||
| 920 | new_len = opts->ndp_size + | ||
| 921 | (ncm->ndp_dgram_count * dgram_idx_len); | ||
| 922 | ncm->ndp_dgram_count = 0; | ||
| 923 | /* Increment from start to wLength */ | ||
| 924 | ntb_iter = (void *) ncm->skb_tx_ndp->data; | ||
| 925 | ntb_iter += 2; | ||
| 926 | put_unaligned_le16(new_len, ntb_iter); | ||
| 927 | |||
| 928 | /* Merge the skbs */ | ||
| 929 | swap(skb2, ncm->skb_tx_data); | ||
| 930 | if (ncm->skb_tx_data) { | ||
| 931 | dev_kfree_skb_any(ncm->skb_tx_data); | ||
| 932 | ncm->skb_tx_data = NULL; | ||
| 933 | } | ||
| 934 | |||
| 935 | /* Insert NDP alignment. */ | ||
| 936 | ntb_iter = (void *) skb_put(skb2, ndp_pad); | ||
| 937 | memset(ntb_iter, 0, ndp_pad); | ||
| 938 | |||
| 939 | /* Copy NTB across. */ | ||
| 940 | ntb_iter = (void *) skb_put(skb2, ncm->skb_tx_ndp->len); | ||
| 941 | memcpy(ntb_iter, ncm->skb_tx_ndp->data, ncm->skb_tx_ndp->len); | ||
| 942 | dev_kfree_skb_any(ncm->skb_tx_ndp); | ||
| 943 | ncm->skb_tx_ndp = NULL; | ||
| 944 | |||
| 945 | /* Insert zero'd datagram. */ | ||
| 946 | ntb_iter = (void *) skb_put(skb2, dgram_idx_len); | ||
| 947 | memset(ntb_iter, 0, dgram_idx_len); | ||
| 948 | |||
| 949 | return skb2; | ||
| 950 | } | ||
| 951 | |||
| 868 | static struct sk_buff *ncm_wrap_ntb(struct gether *port, | 952 | static struct sk_buff *ncm_wrap_ntb(struct gether *port, |
| 869 | struct sk_buff *skb) | 953 | struct sk_buff *skb) |
| 870 | { | 954 | { |
| 871 | struct f_ncm *ncm = func_to_ncm(&port->func); | 955 | struct f_ncm *ncm = func_to_ncm(&port->func); |
| 872 | struct sk_buff *skb2; | 956 | struct sk_buff *skb2 = NULL; |
| 873 | int ncb_len = 0; | 957 | int ncb_len = 0; |
| 874 | __le16 *tmp; | 958 | __le16 *ntb_data; |
| 875 | int div; | 959 | __le16 *ntb_ndp; |
| 876 | int rem; | 960 | int dgram_pad; |
| 877 | int pad; | 961 | |
| 878 | int ndp_align; | ||
| 879 | int ndp_pad; | ||
| 880 | unsigned max_size = ncm->port.fixed_in_len; | 962 | unsigned max_size = ncm->port.fixed_in_len; |
| 881 | const struct ndp_parser_opts *opts = ncm->parser_opts; | 963 | const struct ndp_parser_opts *opts = ncm->parser_opts; |
| 882 | unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; | 964 | const int ndp_align = le16_to_cpu(ntb_parameters.wNdpInAlignment); |
| 883 | 965 | const int div = le16_to_cpu(ntb_parameters.wNdpInDivisor); | |
| 884 | div = le16_to_cpu(ntb_parameters.wNdpInDivisor); | 966 | const int rem = le16_to_cpu(ntb_parameters.wNdpInPayloadRemainder); |
| 885 | rem = le16_to_cpu(ntb_parameters.wNdpInPayloadRemainder); | 967 | const int dgram_idx_len = 2 * 2 * opts->dgram_item_len; |
| 886 | ndp_align = le16_to_cpu(ntb_parameters.wNdpInAlignment); | ||
| 887 | 968 | ||
| 888 | ncb_len += opts->nth_size; | 969 | if (!skb && !ncm->skb_tx_data) |
| 889 | ndp_pad = ALIGN(ncb_len, ndp_align) - ncb_len; | ||
| 890 | ncb_len += ndp_pad; | ||
| 891 | ncb_len += opts->ndp_size; | ||
| 892 | ncb_len += 2 * 2 * opts->dgram_item_len; /* Datagram entry */ | ||
| 893 | ncb_len += 2 * 2 * opts->dgram_item_len; /* Zero datagram entry */ | ||
| 894 | pad = ALIGN(ncb_len, div) + rem - ncb_len; | ||
| 895 | ncb_len += pad; | ||
| 896 | |||
| 897 | if (ncb_len + skb->len + crc_len > max_size) { | ||
| 898 | dev_kfree_skb_any(skb); | ||
| 899 | return NULL; | 970 | return NULL; |
| 900 | } | ||
| 901 | 971 | ||
| 902 | skb2 = skb_copy_expand(skb, ncb_len, | 972 | if (skb) { |
| 903 | max_size - skb->len - ncb_len - crc_len, | 973 | /* Add the CRC if required up front */ |
| 904 | GFP_ATOMIC); | 974 | if (ncm->is_crc) { |
| 905 | dev_kfree_skb_any(skb); | 975 | uint32_t crc; |
| 906 | if (!skb2) | 976 | __le16 *crc_pos; |
| 907 | return NULL; | 977 | |
| 978 | crc = ~crc32_le(~0, | ||
| 979 | skb->data, | ||
| 980 | skb->len); | ||
| 981 | crc_pos = (void *) skb_put(skb, sizeof(uint32_t)); | ||
| 982 | put_unaligned_le32(crc, crc_pos); | ||
| 983 | } | ||
| 908 | 984 | ||
| 909 | skb = skb2; | 985 | /* If the new skb is too big for the current NCM NTB then |
| 986 | * set the current stored skb to be sent now and clear it | ||
| 987 | * ready for new data. | ||
| 988 | * NOTE: Assume maximum align for speed of calculation. | ||
| 989 | */ | ||
| 990 | if (ncm->skb_tx_data | ||
| 991 | && (ncm->ndp_dgram_count >= TX_MAX_NUM_DPE | ||
| 992 | || (ncm->skb_tx_data->len + | ||
| 993 | div + rem + skb->len + | ||
| 994 | ncm->skb_tx_ndp->len + ndp_align + (2 * dgram_idx_len)) | ||
| 995 | > max_size)) { | ||
| 996 | skb2 = package_for_tx(ncm); | ||
| 997 | if (!skb2) | ||
| 998 | goto err; | ||
| 999 | } | ||
| 910 | 1000 | ||
| 911 | tmp = (void *) skb_push(skb, ncb_len); | 1001 | if (!ncm->skb_tx_data) { |
| 912 | memset(tmp, 0, ncb_len); | 1002 | ncb_len = opts->nth_size; |
| 1003 | dgram_pad = ALIGN(ncb_len, div) + rem - ncb_len; | ||
| 1004 | ncb_len += dgram_pad; | ||
| 913 | 1005 | ||
| 914 | put_unaligned_le32(opts->nth_sign, tmp); /* dwSignature */ | 1006 | /* Create a new skb for the NTH and datagrams. */ |
| 915 | tmp += 2; | 1007 | ncm->skb_tx_data = alloc_skb(max_size, GFP_ATOMIC); |
| 916 | /* wHeaderLength */ | 1008 | if (!ncm->skb_tx_data) |
| 917 | put_unaligned_le16(opts->nth_size, tmp++); | 1009 | goto err; |
| 918 | tmp++; /* skip wSequence */ | ||
| 919 | put_ncm(&tmp, opts->block_length, skb->len); /* (d)wBlockLength */ | ||
| 920 | /* (d)wFpIndex */ | ||
| 921 | /* the first pointer is right after the NTH + align */ | ||
| 922 | put_ncm(&tmp, opts->fp_index, opts->nth_size + ndp_pad); | ||
| 923 | 1010 | ||
| 924 | tmp = (void *)tmp + ndp_pad; | 1011 | ntb_data = (void *) skb_put(ncm->skb_tx_data, ncb_len); |
| 1012 | memset(ntb_data, 0, ncb_len); | ||
| 1013 | /* dwSignature */ | ||
| 1014 | put_unaligned_le32(opts->nth_sign, ntb_data); | ||
| 1015 | ntb_data += 2; | ||
| 1016 | /* wHeaderLength */ | ||
| 1017 | put_unaligned_le16(opts->nth_size, ntb_data++); | ||
| 1018 | |||
| 1019 | /* Allocate an skb for storing the NDP, | ||
| 1020 | * TX_MAX_NUM_DPE should easily suffice for a | ||
| 1021 | * 16k packet. | ||
| 1022 | */ | ||
| 1023 | ncm->skb_tx_ndp = alloc_skb((int)(opts->ndp_size | ||
| 1024 | + opts->dpe_size | ||
| 1025 | * TX_MAX_NUM_DPE), | ||
| 1026 | GFP_ATOMIC); | ||
| 1027 | if (!ncm->skb_tx_ndp) | ||
| 1028 | goto err; | ||
| 1029 | ntb_ndp = (void *) skb_put(ncm->skb_tx_ndp, | ||
| 1030 | opts->ndp_size); | ||
| 1031 | memset(ntb_ndp, 0, ncb_len); | ||
| 1032 | /* dwSignature */ | ||
| 1033 | put_unaligned_le32(ncm->ndp_sign, ntb_ndp); | ||
| 1034 | ntb_ndp += 2; | ||
| 925 | 1035 | ||
| 926 | /* NDP */ | 1036 | /* There is always a zeroed entry */ |
| 927 | put_unaligned_le32(ncm->ndp_sign, tmp); /* dwSignature */ | 1037 | ncm->ndp_dgram_count = 1; |
| 928 | tmp += 2; | ||
| 929 | /* wLength */ | ||
| 930 | put_unaligned_le16(ncb_len - opts->nth_size - pad, tmp++); | ||
| 931 | 1038 | ||
| 932 | tmp += opts->reserved1; | 1039 | /* Note: we skip opts->next_ndp_index */ |
| 933 | tmp += opts->next_fp_index; /* skip reserved (d)wNextFpIndex */ | 1040 | } |
| 934 | tmp += opts->reserved2; | ||
| 935 | 1041 | ||
| 936 | if (ncm->is_crc) { | 1042 | /* Delay the timer. */ |
| 937 | uint32_t crc; | 1043 | hrtimer_start(&ncm->task_timer, |
| 1044 | ktime_set(0, TX_TIMEOUT_NSECS), | ||
| 1045 | HRTIMER_MODE_REL); | ||
| 1046 | |||
| 1047 | /* Add the datagram position entries */ | ||
| 1048 | ntb_ndp = (void *) skb_put(ncm->skb_tx_ndp, dgram_idx_len); | ||
| 1049 | memset(ntb_ndp, 0, dgram_idx_len); | ||
| 1050 | |||
| 1051 | ncb_len = ncm->skb_tx_data->len; | ||
| 1052 | dgram_pad = ALIGN(ncb_len, div) + rem - ncb_len; | ||
| 1053 | ncb_len += dgram_pad; | ||
| 1054 | |||
| 1055 | /* (d)wDatagramIndex */ | ||
| 1056 | put_ncm(&ntb_ndp, opts->dgram_item_len, ncb_len); | ||
| 1057 | /* (d)wDatagramLength */ | ||
| 1058 | put_ncm(&ntb_ndp, opts->dgram_item_len, skb->len); | ||
| 1059 | ncm->ndp_dgram_count++; | ||
| 1060 | |||
| 1061 | /* Add the new data to the skb */ | ||
| 1062 | ntb_data = (void *) skb_put(ncm->skb_tx_data, dgram_pad); | ||
| 1063 | memset(ntb_data, 0, dgram_pad); | ||
| 1064 | ntb_data = (void *) skb_put(ncm->skb_tx_data, skb->len); | ||
| 1065 | memcpy(ntb_data, skb->data, skb->len); | ||
| 1066 | dev_kfree_skb_any(skb); | ||
| 1067 | skb = NULL; | ||
| 938 | 1068 | ||
| 939 | crc = ~crc32_le(~0, | 1069 | } else if (ncm->skb_tx_data && ncm->timer_force_tx) { |
| 940 | skb->data + ncb_len, | 1070 | /* If the tx was requested because of a timeout then send */ |
| 941 | skb->len - ncb_len); | 1071 | skb2 = package_for_tx(ncm); |
| 942 | put_unaligned_le32(crc, skb->data + skb->len); | 1072 | if (!skb2) |
| 943 | skb_put(skb, crc_len); | 1073 | goto err; |
| 944 | } | 1074 | } |
| 945 | 1075 | ||
| 946 | /* (d)wDatagramIndex[0] */ | 1076 | return skb2; |
| 947 | put_ncm(&tmp, opts->dgram_item_len, ncb_len); | ||
| 948 | /* (d)wDatagramLength[0] */ | ||
| 949 | put_ncm(&tmp, opts->dgram_item_len, skb->len - ncb_len); | ||
| 950 | /* (d)wDatagramIndex[1] and (d)wDatagramLength[1] already zeroed */ | ||
| 951 | 1077 | ||
| 952 | if (skb->len > MAX_TX_NONFIXED) | 1078 | err: |
| 953 | memset(skb_put(skb, max_size - skb->len), | 1079 | ncm->netdev->stats.tx_dropped++; |
| 954 | 0, max_size - skb->len); | 1080 | |
| 1081 | if (skb) | ||
| 1082 | dev_kfree_skb_any(skb); | ||
| 1083 | if (ncm->skb_tx_data) | ||
| 1084 | dev_kfree_skb_any(ncm->skb_tx_data); | ||
| 1085 | if (ncm->skb_tx_ndp) | ||
| 1086 | dev_kfree_skb_any(ncm->skb_tx_ndp); | ||
| 955 | 1087 | ||
| 956 | return skb; | 1088 | return NULL; |
| 1089 | } | ||
| 1090 | |||
| 1091 | /* | ||
| 1092 | * This transmits the NTB if there are frames waiting. | ||
| 1093 | */ | ||
| 1094 | static void ncm_tx_tasklet(unsigned long data) | ||
| 1095 | { | ||
| 1096 | struct f_ncm *ncm = (void *)data; | ||
| 1097 | |||
| 1098 | if (ncm->timer_stopping) | ||
| 1099 | return; | ||
| 1100 | |||
| 1101 | /* Only send if data is available. */ | ||
| 1102 | if (ncm->skb_tx_data) { | ||
| 1103 | ncm->timer_force_tx = true; | ||
| 1104 | ncm->netdev->netdev_ops->ndo_start_xmit(NULL, ncm->netdev); | ||
| 1105 | ncm->timer_force_tx = false; | ||
| 1106 | } | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | /* | ||
| 1110 | * The transmit should only be run if no skb data has been sent | ||
| 1111 | * for a certain duration. | ||
| 1112 | */ | ||
| 1113 | static enum hrtimer_restart ncm_tx_timeout(struct hrtimer *data) | ||
| 1114 | { | ||
| 1115 | struct f_ncm *ncm = container_of(data, struct f_ncm, task_timer); | ||
| 1116 | tasklet_schedule(&ncm->tx_tasklet); | ||
| 1117 | return HRTIMER_NORESTART; | ||
| 957 | } | 1118 | } |
| 958 | 1119 | ||
| 959 | static int ncm_unwrap_ntb(struct gether *port, | 1120 | static int ncm_unwrap_ntb(struct gether *port, |
| @@ -963,6 +1124,7 @@ static int ncm_unwrap_ntb(struct gether *port, · 3 unmodified lines | |||
| 963 | struct f_ncm *ncm = func_to_ncm(&port->func); | 1124 | struct f_ncm *ncm = func_to_ncm(&port->func); |
| 964 | __le16 *tmp = (void *) skb->data; | 1125 | __le16 *tmp = (void *) skb->data; |
| 965 | unsigned index, index2; | 1126 | unsigned index, index2; |
| 1127 | int ndp_index; | ||
| 966 | unsigned dg_len, dg_len2; | 1128 | unsigned dg_len, dg_len2; |
| 967 | unsigned ndp_len; | 1129 | unsigned ndp_len; |
| 968 | struct sk_buff *skb2; | 1130 | struct sk_buff *skb2; |
| @@ -995,91 +1157,101 @@ static int ncm_unwrap_ntb(struct gether *port, · 26 unmodified lines | |||
| 995 | goto err; | 1157 | goto err; |
| 996 | } | 1158 | } |
| 997 | 1159 | ||
| 998 | index = get_ncm(&tmp, opts->fp_index); | 1160 | ndp_index = get_ncm(&tmp, opts->ndp_index); |
| 999 | /* NCM 3.2 */ | ||
| 1000 | if (((index % 4) != 0) && (index < opts->nth_size)) { | ||
| 1001 | INFO(port->func.config->cdev, "Bad index: %x\n", | ||
| 1002 | index); | ||
| 1003 | goto err; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | /* walk through NDP */ | ||
| 1007 | tmp = ((void *)skb->data) + index; | ||
| 1008 | if (get_unaligned_le32(tmp) != ncm->ndp_sign) { | ||
| 1009 | INFO(port->func.config->cdev, "Wrong NDP SIGN\n"); | ||
| 1010 | goto err; | ||
| 1011 | } | ||
| 1012 | tmp += 2; | ||
| 1013 | |||
| 1014 | ndp_len = get_unaligned_le16(tmp++); | ||
| 1015 | /* | ||
| 1016 | * NCM 3.3.1 | ||
| 1017 | * entry is 2 items | ||
| 1018 | * item size is 16/32 bits, opts->dgram_item_len * 2 bytes | ||
| 1019 | * minimal: struct usb_cdc_ncm_ndpX + normal entry + zero entry | ||
| 1020 | */ | ||
| 1021 | if ((ndp_len < opts->ndp_size + 2 * 2 * (opts->dgram_item_len * 2)) | ||
| 1022 | || (ndp_len % opts->ndplen_align != 0)) { | ||
| 1023 | INFO(port->func.config->cdev, "Bad NDP length: %x\n", ndp_len); | ||
| 1024 | goto err; | ||
| 1025 | } | ||
| 1026 | tmp += opts->reserved1; | ||
| 1027 | tmp += opts->next_fp_index; /* skip reserved (d)wNextFpIndex */ | ||
| 1028 | tmp += opts->reserved2; | ||
| 1029 | |||
| 1030 | ndp_len -= opts->ndp_size; | ||
| 1031 | index2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1032 | dg_len2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1033 | dgram_counter = 0; | ||
| 1034 | 1161 | ||
| 1162 | /* Run through all the NDP's in the NTB */ | ||
| 1035 | do { | 1163 | do { |
| 1036 | index = index2; | 1164 | /* NCM 3.2 */ |
| 1037 | dg_len = dg_len2; | 1165 | if (((ndp_index % 4) != 0) && |
| 1038 | if (dg_len < 14 + crc_len) { /* ethernet header + crc */ | 1166 | (ndp_index < opts->nth_size)) { |
| 1039 | INFO(port->func.config->cdev, "Bad dgram length: %x\n", | 1167 | INFO(port->func.config->cdev, "Bad index: %#X\n", |
| 1040 | dg_len); | 1168 | ndp_index); |
| 1041 | goto err; | 1169 | goto err; |
| 1042 | } | 1170 | } |
| 1043 | if (ncm->is_crc) { | 1171 | |
| 1044 | uint32_t crc, crc2; | 1172 | /* walk through NDP */ |
| 1045 | 1173 | tmp = (void *)(skb->data + ndp_index); | |
| 1046 | crc = get_unaligned_le32(skb->data + | 1174 | if (get_unaligned_le32(tmp) != ncm->ndp_sign) { |
| 1047 | index + dg_len - crc_len); | 1175 | INFO(port->func.config->cdev, "Wrong NDP SIGN\n"); |
| 1048 | crc2 = ~crc32_le(~0, | 1176 | goto err; |
| 1049 | skb->data + index, | ||
| 1050 | dg_len - crc_len); | ||
| 1051 | if (crc != crc2) { | ||
| 1052 | INFO(port->func.config->cdev, "Bad CRC\n"); | ||
| 1053 | goto err; | ||
| 1054 | } | ||
| 1055 | } | 1177 | } |
| 1178 | tmp += 2; | ||
| 1056 | 1179 | ||
| 1180 | ndp_len = get_unaligned_le16(tmp++); | ||
| 1181 | /* | ||
| 1182 | * NCM 3.3.1 | ||
| 1183 | * entry is 2 items | ||
| 1184 | * item size is 16/32 bits, opts->dgram_item_len * 2 bytes | ||
| 1185 | * minimal: struct usb_cdc_ncm_ndpX + normal entry + zero entry | ||
| 1186 | * Each entry is a dgram index and a dgram length. | ||
| 1187 | */ | ||
| 1188 | if ((ndp_len < opts->ndp_size | ||
| 1189 | + 2 * 2 * (opts->dgram_item_len * 2)) | ||
| 1190 | || (ndp_len % opts->ndplen_align != 0)) { | ||
| 1191 | INFO(port->func.config->cdev, "Bad NDP length: %#X\n", | ||
| 1192 | ndp_len); | ||
| 1193 | goto err; | ||
| 1194 | } | ||
| 1195 | tmp += opts->reserved1; | ||
| 1196 | /* Check for another NDP (d)wNextNdpIndex */ | ||
| 1197 | ndp_index = get_ncm(&tmp, opts->next_ndp_index); | ||
| 1198 | tmp += opts->reserved2; | ||
| 1199 | |||
| 1200 | ndp_len -= opts->ndp_size; | ||
| 1057 | index2 = get_ncm(&tmp, opts->dgram_item_len); | 1201 | index2 = get_ncm(&tmp, opts->dgram_item_len); |
| 1058 | dg_len2 = get_ncm(&tmp, opts->dgram_item_len); | 1202 | dg_len2 = get_ncm(&tmp, opts->dgram_item_len); |
| 1203 | dgram_counter = 0; | ||
| 1204 | |||
| 1205 | do { | ||
| 1206 | index = index2; | ||
| 1207 | dg_len = dg_len2; | ||
| 1208 | if (dg_len < 14 + crc_len) { /* ethernet hdr + crc */ | ||
| 1209 | INFO(port->func.config->cdev, | ||
| 1210 | "Bad dgram length: %#X\n", dg_len); | ||
| 1211 | goto err; | ||
| 1212 | } | ||
| 1213 | if (ncm->is_crc) { | ||
| 1214 | uint32_t crc, crc2; | ||
| 1215 | |||
| 1216 | crc = get_unaligned_le32(skb->data + | ||
| 1217 | index + dg_len - | ||
| 1218 | crc_len); | ||
| 1219 | crc2 = ~crc32_le(~0, | ||
| 1220 | skb->data + index, | ||
| 1221 | dg_len - crc_len); | ||
| 1222 | if (crc != crc2) { | ||
| 1223 | INFO(port->func.config->cdev, | ||
| 1224 | "Bad CRC\n"); | ||
| 1225 | goto err; | ||
| 1226 | } | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | index2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1230 | dg_len2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1059 | 1231 | ||
| 1060 | if (index2 == 0 || dg_len2 == 0) { | 1232 | /* |
| 1061 | skb2 = skb; | 1233 | * Copy the data into a new skb. |
| 1062 | } else { | 1234 | * This ensures the truesize is correct |
| 1063 | skb2 = skb_clone(skb, GFP_ATOMIC); | 1235 | */ |
| 1236 | skb2 = netdev_alloc_skb_ip_align(ncm->netdev, | ||
| 1237 | dg_len - crc_len); | ||
| 1064 | if (skb2 == NULL) | 1238 | if (skb2 == NULL) |
| 1065 | goto err; | 1239 | goto err; |
| 1066 | } | 1240 | memcpy(skb_put(skb2, dg_len - crc_len), |
| 1241 | skb->data + index, dg_len - crc_len); | ||
| 1067 | 1242 | ||
| 1068 | if (!skb_pull(skb2, index)) { | 1243 | skb_queue_tail(list, skb2); |
| 1069 | ret = -EOVERFLOW; | ||
| 1070 | goto err; | ||
| 1071 | } | ||
| 1072 | 1244 | ||
| 1073 | skb_trim(skb2, dg_len - crc_len); | 1245 | ndp_len -= 2 * (opts->dgram_item_len * 2); |
| 1074 | skb_queue_tail(list, skb2); | ||
| 1075 | 1246 | ||
| 1076 | ndp_len -= 2 * (opts->dgram_item_len * 2); | 1247 | dgram_counter++; |
| 1077 | 1248 | ||
| 1078 | dgram_counter++; | 1249 | if (index2 == 0 || dg_len2 == 0) |
| 1250 | break; | ||
| 1251 | } while (ndp_len > 2 * (opts->dgram_item_len * 2)); | ||
| 1252 | } while (ndp_index); | ||
| 1079 | 1253 | ||
| 1080 | if (index2 == 0 || dg_len2 == 0) | 1254 | dev_kfree_skb_any(skb); |
| 1081 | break; | ||
| 1082 | } while (ndp_len > 2 * (opts->dgram_item_len * 2)); /* zero entry */ | ||
| 1083 | 1255 | ||
| 1084 | VDBG(port->func.config->cdev, | 1256 | VDBG(port->func.config->cdev, |
| 1085 | "Parsed NTB with %d frames\n", dgram_counter); | 1257 | "Parsed NTB with %d frames\n", dgram_counter); |
| @@ -1097,8 +1269,11 @@ static void ncm_disable(struct usb_function *f) · 11 unmodified lines | |||
| 1097 | 1269 | ||
| 1098 | DBG(cdev, "ncm deactivated\n"); | 1270 | DBG(cdev, "ncm deactivated\n"); |
| 1099 | 1271 | ||
| 1100 | if (ncm->port.in_ep->driver_data) | 1272 | if (ncm->port.in_ep->driver_data) { |
| 1273 | ncm->timer_stopping = true; | ||
| 1274 | ncm->netdev = NULL; | ||
| 1101 | gether_disconnect(&ncm->port); | 1275 | gether_disconnect(&ncm->port); |
| 1276 | } | ||
| 1102 | 1277 | ||
| 1103 | if (ncm->notify->driver_data) { | 1278 | if (ncm->notify->driver_data) { |
| 1104 | usb_ep_disable(ncm->notify); | 1279 | usb_ep_disable(ncm->notify); |
| @@ -1267,6 +1442,10 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) · 162 unmodified lines | |||
| 1267 | ncm->port.open = ncm_open; | 1442 | ncm->port.open = ncm_open; |
| 1268 | ncm->port.close = ncm_close; | 1443 | ncm->port.close = ncm_close; |
| 1269 | 1444 | ||
| 1445 | tasklet_init(&ncm->tx_tasklet, ncm_tx_tasklet, (unsigned long) ncm); | ||
| 1446 | hrtimer_init(&ncm->task_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
| 1447 | ncm->task_timer.function = ncm_tx_timeout; | ||
| 1448 | |||
| 1270 | DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n", | 1449 | DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n", |
| 1271 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | 1450 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", |
| 1272 | ncm->port.in_ep->name, ncm->port.out_ep->name, | 1451 | ncm->port.in_ep->name, ncm->port.out_ep->name, |
| @@ -1380,6 +1559,10 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f) · 107 unmodified lines | |||
| 1380 | 1559 | ||
| 1381 | DBG(c->cdev, "ncm unbind\n"); | 1560 | DBG(c->cdev, "ncm unbind\n"); |
| 1382 | 1561 | ||
| 1562 | hrtimer_cancel(&ncm->task_timer); | ||
| 1563 | tasklet_kill(&ncm->tx_tasklet); | ||
| 1564 | |||
| 1565 | ncm_string_defs[0].id = 0; | ||
| 1383 | usb_free_all_descriptors(f); | 1566 | usb_free_all_descriptors(f); |
| 1384 | 1567 | ||
| 1385 | kfree(ncm->notify_req->buf); | 1568 | kfree(ncm->notify_req->buf); |
| @@ -1416,6 +1599,7 @@ static struct usb_function *ncm_alloc(struct usb_function_instance *fi) · 30 unmodified lines | |||
| 1416 | ncm->port.ioport = netdev_priv(opts->net); | 1599 | ncm->port.ioport = netdev_priv(opts->net); |
| 1417 | mutex_unlock(&opts->lock); | 1600 | mutex_unlock(&opts->lock); |
| 1418 | ncm->port.is_fixed = true; | 1601 | ncm->port.is_fixed = true; |
| 1602 | ncm->port.supports_multi_frame = true; | ||
| 1419 | 1603 | ||
| 1420 | ncm->port.func.name = "cdc_network"; | 1604 | ncm->port.func.name = "cdc_network"; |
| 1421 | /* descriptors are per-instance copies */ | 1605 | /* descriptors are per-instance copies */ |
File renamed without changes.
File renamed without changes.
| @@ -727,6 +727,10 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) · 726 unmodified lines | |||
| 727 | rndis_control_intf.bInterfaceNumber = status; | 727 | rndis_control_intf.bInterfaceNumber = status; |
| 728 | rndis_union_desc.bMasterInterface0 = status; | 728 | rndis_union_desc.bMasterInterface0 = status; |
| 729 | 729 | ||
| 730 | if (cdev->use_os_string) | ||
| 731 | f->os_desc_table[0].if_id = | ||
| 732 | rndis_iad_descriptor.bFirstInterface; | ||
| 733 | |||
| 730 | status = usb_interface_id(c, f); | 734 | status = usb_interface_id(c, f); |
| 731 | if (status < 0) | 735 | if (status < 0) |
| 732 | goto fail; | 736 | goto fail; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -348,14 +348,34 @@ static int uac2_pcm_open(struct snd_pcm_substream *substream) · 347 unmodified lines | |||
| 348 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 348 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 349 | spin_lock_init(&uac2->p_prm.lock); | 349 | spin_lock_init(&uac2->p_prm.lock); |
| 350 | runtime->hw.rate_min = p_srate; | 350 | runtime->hw.rate_min = p_srate; |
| 351 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; /* ! p_ssize ! */ | 351 | switch (p_ssize) { |
| 352 | case 3: | ||
| 353 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; | ||
| 354 | break; | ||
| 355 | case 4: | ||
| 356 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; | ||
| 357 | break; | ||
| 358 | default: | ||
| 359 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; | ||
| 360 | break; | ||
| 361 | } | ||
| 352 | runtime->hw.channels_min = num_channels(p_chmask); | 362 | runtime->hw.channels_min = num_channels(p_chmask); |
| 353 | runtime->hw.period_bytes_min = 2 * uac2->p_prm.max_psize | 363 | runtime->hw.period_bytes_min = 2 * uac2->p_prm.max_psize |
| 354 | / runtime->hw.periods_min; | 364 | / runtime->hw.periods_min; |
| 355 | } else { | 365 | } else { |
| 356 | spin_lock_init(&uac2->c_prm.lock); | 366 | spin_lock_init(&uac2->c_prm.lock); |
| 357 | runtime->hw.rate_min = c_srate; | 367 | runtime->hw.rate_min = c_srate; |
| 358 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; /* ! c_ssize ! */ | 368 | switch (c_ssize) { |
| 369 | case 3: | ||
| 370 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; | ||
| 371 | break; | ||
| 372 | case 4: | ||
| 373 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; | ||
| 374 | break; | ||
| 375 | default: | ||
| 376 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; | ||
| 377 | break; | ||
| 378 | } | ||
| 359 | runtime->hw.channels_min = num_channels(c_chmask); | 379 | runtime->hw.channels_min = num_channels(c_chmask); |
| 360 | runtime->hw.period_bytes_min = 2 * uac2->c_prm.max_psize | 380 | runtime->hw.period_bytes_min = 2 * uac2->c_prm.max_psize |
| 361 | / runtime->hw.periods_min; | 381 | / runtime->hw.periods_min; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -483,7 +483,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, · 482 unmodified lines | |||
| 483 | struct net_device *net) | 483 | struct net_device *net) |
| 484 | { | 484 | { |
| 485 | struct eth_dev *dev = netdev_priv(net); | 485 | struct eth_dev *dev = netdev_priv(net); |
| 486 | int length = skb->len; | 486 | int length = 0; |
| 487 | int retval; | 487 | int retval; |
| 488 | struct usb_request *req = NULL; | 488 | struct usb_request *req = NULL; |
| 489 | unsigned long flags; | 489 | unsigned long flags; |
| @@ -500,13 +500,13 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, · 10 unmodified lines | |||
| 500 | } | 500 | } |
| 501 | spin_unlock_irqrestore(&dev->lock, flags); | 501 | spin_unlock_irqrestore(&dev->lock, flags); |
| 502 | 502 | ||
| 503 | if (!in) { | 503 | if (skb && !in) { |
| 504 | dev_kfree_skb_any(skb); | 504 | dev_kfree_skb_any(skb); |
| 505 | return NETDEV_TX_OK; | 505 | return NETDEV_TX_OK; |
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | /* apply outgoing CDC or RNDIS filters */ | 508 | /* apply outgoing CDC or RNDIS filters */ |
| 509 | if (!is_promisc(cdc_filter)) { | 509 | if (skb && !is_promisc(cdc_filter)) { |
| 510 | u8 *dest = skb->data; | 510 | u8 *dest = skb->data; |
| 511 | 511 | ||
| 512 | if (is_multicast_ether_addr(dest)) { | 512 | if (is_multicast_ether_addr(dest)) { |
| @@ -557,11 +557,17 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, · 44 unmodified lines | |||
| 557 | if (dev->port_usb) | 557 | if (dev->port_usb) |
| 558 | skb = dev->wrap(dev->port_usb, skb); | 558 | skb = dev->wrap(dev->port_usb, skb); |
| 559 | spin_unlock_irqrestore(&dev->lock, flags); | 559 | spin_unlock_irqrestore(&dev->lock, flags); |
| 560 | if (!skb) | 560 | if (!skb) { |
| 561 | /* Multi frame CDC protocols may store the frame for | ||
| 562 | * later which is not a dropped frame. | ||
| 563 | */ | ||
| 564 | if (dev->port_usb->supports_multi_frame) | ||
| 565 | goto multiframe; | ||
| 561 | goto drop; | 566 | goto drop; |
| 562 | 567 | } | |
| 563 | length = skb->len; | ||
| 564 | } | 568 | } |
| 569 | |||
| 570 | length = skb->len; | ||
| 565 | req->buf = skb->data; | 571 | req->buf = skb->data; |
| 566 | req->context = skb; | 572 | req->context = skb; |
| 567 | req->complete = tx_complete; | 573 | req->complete = tx_complete; |
| @@ -604,6 +610,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, · 36 unmodified lines | |||
| 604 | dev_kfree_skb_any(skb); | 610 | dev_kfree_skb_any(skb); |
| 605 | drop: | 611 | drop: |
| 606 | dev->net->stats.tx_dropped++; | 612 | dev->net->stats.tx_dropped++; |
| 613 | multiframe: | ||
| 607 | spin_lock_irqsave(&dev->req_lock, flags); | 614 | spin_lock_irqsave(&dev->req_lock, flags); |
| 608 | if (list_empty(&dev->tx_reqs)) | 615 | if (list_empty(&dev->tx_reqs)) |
| 609 | netif_start_queue(net); | 616 | netif_start_queue(net); |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include <linux/if_ether.h> | 18 | #include <linux/if_ether.h> |
| 19 | #include <linux/usb/composite.h> | 19 | #include <linux/usb/composite.h> |
| 20 | #include <linux/usb/cdc.h> | 20 | #include <linux/usb/cdc.h> |
| 21 | #include <linux/netdevice.h> | ||
| 21 | 22 | ||
| 22 | #include "gadget_chips.h" | 23 | #include "gadget_chips.h" |
| 23 | 24 | ||
| @@ -74,6 +75,7 @@ struct gether { · 50 unmodified lines | |||
| 74 | bool is_fixed; | 75 | bool is_fixed; |
| 75 | u32 fixed_out_len; | 76 | u32 fixed_out_len; |
| 76 | u32 fixed_in_len; | 77 | u32 fixed_in_len; |
| 78 | bool supports_multi_frame; | ||
| 77 | struct sk_buff *(*wrap)(struct gether *port, | 79 | struct sk_buff *(*wrap)(struct gether *port, |
| 78 | struct sk_buff *skb); | 80 | struct sk_buff *skb); |
| 79 | int (*unwrap)(struct gether *port, | 81 | int (*unwrap)(struct gether *port, |
File renamed without changes.
| @@ -216,6 +216,13 @@ struct ffs_data { · 215 unmodified lines | |||
| 216 | unsigned fs_descs_count; | 216 | unsigned fs_descs_count; |
| 217 | unsigned hs_descs_count; | 217 | unsigned hs_descs_count; |
| 218 | unsigned ss_descs_count; | 218 | unsigned ss_descs_count; |
| 219 | unsigned ms_os_descs_count; | ||
| 220 | unsigned ms_os_descs_ext_prop_count; | ||
| 221 | unsigned ms_os_descs_ext_prop_name_len; | ||
| 222 | unsigned ms_os_descs_ext_prop_data_len; | ||
| 223 | void *ms_os_descs_ext_prop_avail; | ||
| 224 | void *ms_os_descs_ext_prop_name_avail; | ||
| 225 | void *ms_os_descs_ext_prop_data_avail; | ||
| 219 | 226 | ||
| 220 | unsigned short strings_count; | 227 | unsigned short strings_count; |
| 221 | unsigned short interfaces_count; | 228 | unsigned short interfaces_count; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -0,0 +1,475 @@ | |||
| 1 | # | ||
| 2 | # USB Gadget support on a system involves | ||
| 3 | # (a) a peripheral controller, and | ||
| 4 | # (b) the gadget driver using it. | ||
| 5 | # | ||
| 6 | # NOTE: Gadget support ** DOES NOT ** depend on host-side CONFIG_USB !! | ||
| 7 | # | ||
| 8 | # - Host systems (like PCs) need CONFIG_USB (with "A" jacks). | ||
| 9 | # - Peripherals (like PDAs) need CONFIG_USB_GADGET (with "B" jacks). | ||
| 10 | # - Some systems have both kinds of controllers. | ||
| 11 | # | ||
| 12 | # With help from a special transceiver and a "Mini-AB" jack, systems with | ||
| 13 | # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG). | ||
| 14 | # | ||
| 15 | |||
| 16 | config USB_ZERO | ||
| 17 | tristate "Gadget Zero (DEVELOPMENT)" | ||
| 18 | select USB_LIBCOMPOSITE | ||
| 19 | select USB_F_SS_LB | ||
| 20 | help | ||
| 21 | Gadget Zero is a two-configuration device. It either sinks and | ||
| 22 | sources bulk data; or it loops back a configurable number of | ||
| 23 | transfers. It also implements control requests, for "chapter 9" | ||
| 24 | conformance. The driver needs only two bulk-capable endpoints, so | ||
| 25 | it can work on top of most device-side usb controllers. It's | ||
| 26 | useful for testing, and is also a working example showing how | ||
| 27 | USB "gadget drivers" can be written. | ||
| 28 | |||
| 29 | Make this be the first driver you try using on top of any new | ||
| 30 | USB peripheral controller driver. Then you can use host-side | ||
| 31 | test software, like the "usbtest" driver, to put your hardware | ||
| 32 | and its driver through a basic set of functional tests. | ||
| 33 | |||
| 34 | Gadget Zero also works with the host-side "usb-skeleton" driver, | ||
| 35 | and with many kinds of host-side test software. You may need | ||
| 36 | to tweak product and vendor IDs before host software knows about | ||
| 37 | this device, and arrange to select an appropriate configuration. | ||
| 38 | |||
| 39 | Say "y" to link the driver statically, or "m" to build a | ||
| 40 | dynamically linked module called "g_zero". | ||
| 41 | |||
| 42 | config USB_ZERO_HNPTEST | ||
| 43 | boolean "HNP Test Device" | ||
| 44 | depends on USB_ZERO && USB_OTG | ||
| 45 | help | ||
| 46 | You can configure this device to enumerate using the device | ||
| 47 | identifiers of the USB-OTG test device. That means that when | ||
| 48 | this gadget connects to another OTG device, with this one using | ||
| 49 | the "B-Peripheral" role, that device will use HNP to let this | ||
| 50 | one serve as the USB host instead (in the "B-Host" role). | ||
| 51 | |||
| 52 | config USB_AUDIO | ||
| 53 | tristate "Audio Gadget" | ||
| 54 | depends on SND | ||
| 55 | select USB_LIBCOMPOSITE | ||
| 56 | select SND_PCM | ||
| 57 | help | ||
| 58 | This Gadget Audio driver is compatible with USB Audio Class | ||
| 59 | specification 2.0. It implements 1 AudioControl interface, | ||
| 60 | 1 AudioStreaming Interface each for USB-OUT and USB-IN. | ||
| 61 | Number of channels, sample rate and sample size can be | ||
| 62 | specified as module parameters. | ||
| 63 | This driver doesn't expect any real Audio codec to be present | ||
| 64 | on the device - the audio streams are simply sinked to and | ||
| 65 | sourced from a virtual ALSA sound card created. The user-space | ||
| 66 | application may choose to do whatever it wants with the data | ||
| 67 | received from the USB Host and choose to provide whatever it | ||
| 68 | wants as audio data to the USB Host. | ||
| 69 | |||
| 70 | Say "y" to link the driver statically, or "m" to build a | ||
| 71 | dynamically linked module called "g_audio". | ||
| 72 | |||
| 73 | config GADGET_UAC1 | ||
| 74 | bool "UAC 1.0 (Legacy)" | ||
| 75 | depends on USB_AUDIO | ||
| 76 | help | ||
| 77 | If you instead want older UAC Spec-1.0 driver that also has audio | ||
| 78 | paths hardwired to the Audio codec chip on-board and doesn't work | ||
| 79 | without one. | ||
| 80 | |||
| 81 | config USB_ETH | ||
| 82 | tristate "Ethernet Gadget (with CDC Ethernet support)" | ||
| 83 | depends on NET | ||
| 84 | select USB_LIBCOMPOSITE | ||
| 85 | select USB_U_ETHER | ||
| 86 | select USB_F_ECM | ||
| 87 | select USB_F_SUBSET | ||
| 88 | select CRC32 | ||
| 89 | help | ||
| 90 | This driver implements Ethernet style communication, in one of | ||
| 91 | several ways: | ||
| 92 | |||
| 93 | - The "Communication Device Class" (CDC) Ethernet Control Model. | ||
| 94 | That protocol is often avoided with pure Ethernet adapters, in | ||
| 95 | favor of simpler vendor-specific hardware, but is widely | ||
| 96 | supported by firmware for smart network devices. | ||
| 97 | |||
| 98 | - On hardware can't implement that protocol, a simple CDC subset | ||
| 99 | is used, placing fewer demands on USB. | ||
| 100 | |||
| 101 | - CDC Ethernet Emulation Model (EEM) is a newer standard that has | ||
| 102 | a simpler interface that can be used by more USB hardware. | ||
| 103 | |||
| 104 | RNDIS support is an additional option, more demanding than than | ||
| 105 | subset. | ||
| 106 | |||
| 107 | Within the USB device, this gadget driver exposes a network device | ||
| 108 | "usbX", where X depends on what other networking devices you have. | ||
| 109 | Treat it like a two-node Ethernet link: host, and gadget. | ||
| 110 | |||
| 111 | The Linux-USB host-side "usbnet" driver interoperates with this | ||
| 112 | driver, so that deep I/O queues can be supported. On 2.4 kernels, | ||
| 113 | use "CDCEther" instead, if you're using the CDC option. That CDC | ||
| 114 | mode should also interoperate with standard CDC Ethernet class | ||
| 115 | drivers on other host operating systems. | ||
| 116 | |||
| 117 | Say "y" to link the driver statically, or "m" to build a | ||
| 118 | dynamically linked module called "g_ether". | ||
| 119 | |||
| 120 | config USB_ETH_RNDIS | ||
| 121 | bool "RNDIS support" | ||
| 122 | depends on USB_ETH | ||
| 123 | select USB_LIBCOMPOSITE | ||
| 124 | select USB_F_RNDIS | ||
| 125 | default y | ||
| 126 | help | ||
| 127 | Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol, | ||
| 128 | and Microsoft provides redistributable binary RNDIS drivers for | ||
| 129 | older versions of Windows. | ||
| 130 | |||
| 131 | If you say "y" here, the Ethernet gadget driver will try to provide | ||
| 132 | a second device configuration, supporting RNDIS to talk to such | ||
| 133 | Microsoft USB hosts. | ||
| 134 | |||
| 135 | To make MS-Windows work with this, use Documentation/usb/linux.inf | ||
| 136 | as the "driver info file". For versions of MS-Windows older than | ||
| 137 | XP, you'll need to download drivers from Microsoft's website; a URL | ||
| 138 | is given in comments found in that info file. | ||
| 139 | |||
| 140 | config USB_ETH_EEM | ||
| 141 | bool "Ethernet Emulation Model (EEM) support" | ||
| 142 | depends on USB_ETH | ||
| 143 | select USB_LIBCOMPOSITE | ||
| 144 | select USB_F_EEM | ||
| 145 | default n | ||
| 146 | help | ||
| 147 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM | ||
| 148 | and therefore can be supported by more hardware. Technically ECM and | ||
| 149 | EEM are designed for different applications. The ECM model extends | ||
| 150 | the network interface to the target (e.g. a USB cable modem), and the | ||
| 151 | EEM model is for mobile devices to communicate with hosts using | ||
| 152 | ethernet over USB. For Linux gadgets, however, the interface with | ||
| 153 | the host is the same (a usbX device), so the differences are minimal. | ||
| 154 | |||
| 155 | If you say "y" here, the Ethernet gadget driver will use the EEM | ||
| 156 | protocol rather than ECM. If unsure, say "n". | ||
| 157 | |||
| 158 | config USB_G_NCM | ||
| 159 | tristate "Network Control Model (NCM) support" | ||
| 160 | depends on NET | ||
| 161 | select USB_LIBCOMPOSITE | ||
| 162 | select USB_U_ETHER | ||
| 163 | select USB_F_NCM | ||
| 164 | select CRC32 | ||
| 165 | help | ||
| 166 | This driver implements USB CDC NCM subclass standard. NCM is | ||
| 167 | an advanced protocol for Ethernet encapsulation, allows grouping | ||
| 168 | of several ethernet frames into one USB transfer and different | ||
| 169 | alignment possibilities. | ||
| 170 | |||
| 171 | Say "y" to link the driver statically, or "m" to build a | ||
| 172 | dynamically linked module called "g_ncm". | ||
| 173 | |||
| 174 | config USB_GADGETFS | ||
| 175 | tristate "Gadget Filesystem" | ||
| 176 | help | ||
| 177 | This driver provides a filesystem based API that lets user mode | ||
| 178 | programs implement a single-configuration USB device, including | ||
| 179 | endpoint I/O and control requests that don't relate to enumeration. | ||
| 180 | All endpoints, transfer speeds, and transfer types supported by | ||
| 181 | the hardware are available, through read() and write() calls. | ||
| 182 | |||
| 183 | Say "y" to link the driver statically, or "m" to build a | ||
| 184 | dynamically linked module called "gadgetfs". | ||
| 185 | |||
| 186 | config USB_FUNCTIONFS | ||
| 187 | tristate "Function Filesystem" | ||
| 188 | select USB_LIBCOMPOSITE | ||
| 189 | select USB_F_FS | ||
| 190 | select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS) | ||
| 191 | help | ||
| 192 | The Function Filesystem (FunctionFS) lets one create USB | ||
| 193 | composite functions in user space in the same way GadgetFS | ||
| 194 | lets one create USB gadgets in user space. This allows creation | ||
| 195 | of composite gadgets such that some of the functions are | ||
| 196 | implemented in kernel space (for instance Ethernet, serial or | ||
| 197 | mass storage) and other are implemented in user space. | ||
| 198 | |||
| 199 | If you say "y" or "m" here you will be able what kind of | ||
| 200 | configurations the gadget will provide. | ||
| 201 | |||
| 202 | Say "y" to link the driver statically, or "m" to build | ||
| 203 | a dynamically linked module called "g_ffs". | ||
| 204 | |||
| 205 | config USB_FUNCTIONFS_ETH | ||
| 206 | bool "Include configuration with CDC ECM (Ethernet)" | ||
| 207 | depends on USB_FUNCTIONFS && NET | ||
| 208 | select USB_U_ETHER | ||
| 209 | select USB_F_ECM | ||
| 210 | select USB_F_SUBSET | ||
| 211 | help | ||
| 212 | Include a configuration with CDC ECM function (Ethernet) and the | ||
| 213 | Function Filesystem. | ||
| 214 | |||
| 215 | config USB_FUNCTIONFS_RNDIS | ||
| 216 | bool "Include configuration with RNDIS (Ethernet)" | ||
| 217 | depends on USB_FUNCTIONFS && NET | ||
| 218 | select USB_U_ETHER | ||
| 219 | select USB_F_RNDIS | ||
| 220 | help | ||
| 221 | Include a configuration with RNDIS function (Ethernet) and the Filesystem. | ||
| 222 | |||
| 223 | config USB_FUNCTIONFS_GENERIC | ||
| 224 | bool "Include 'pure' configuration" | ||
| 225 | depends on USB_FUNCTIONFS | ||
| 226 | help | ||
| 227 | Include a configuration with the Function Filesystem alone with | ||
| 228 | no Ethernet interface. | ||
| 229 | |||
| 230 | config USB_MASS_STORAGE | ||
| 231 | tristate "Mass Storage Gadget" | ||
| 232 | depends on BLOCK | ||
| 233 | select USB_LIBCOMPOSITE | ||
| 234 | select USB_F_MASS_STORAGE | ||
| 235 | help | ||
| 236 | The Mass Storage Gadget acts as a USB Mass Storage disk drive. | ||
| 237 | As its storage repository it can use a regular file or a block | ||
| 238 | device (in much the same way as the "loop" device driver), | ||
| 239 | specified as a module parameter or sysfs option. | ||
| 240 | |||
| 241 | This driver is a replacement for now removed File-backed | ||
| 242 | Storage Gadget (g_file_storage). | ||
| 243 | |||
| 244 | Say "y" to link the driver statically, or "m" to build | ||
| 245 | a dynamically linked module called "g_mass_storage". | ||
| 246 | |||
| 247 | config USB_GADGET_TARGET | ||
| 248 | tristate "USB Gadget Target Fabric Module" | ||
| 249 | depends on TARGET_CORE | ||
| 250 | select USB_LIBCOMPOSITE | ||
| 251 | help | ||
| 252 | This fabric is an USB gadget. Two USB protocols are supported that is | ||
| 253 | BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is | ||
| 254 | advertised on alternative interface 0 (primary) and UAS is on | ||
| 255 | alternative interface 1. Both protocols can work on USB2.0 and USB3.0. | ||
| 256 | UAS utilizes the USB 3.0 feature called streams support. | ||
| 257 | |||
| 258 | config USB_G_SERIAL | ||
| 259 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" | ||
| 260 | depends on TTY | ||
| 261 | select USB_U_SERIAL | ||
| 262 | select USB_F_ACM | ||
| 263 | select USB_F_SERIAL | ||
| 264 | select USB_F_OBEX | ||
| 265 | select USB_LIBCOMPOSITE | ||
| 266 | help | ||
| 267 | The Serial Gadget talks to the Linux-USB generic serial driver. | ||
| 268 | This driver supports a CDC-ACM module option, which can be used | ||
| 269 | to interoperate with MS-Windows hosts or with the Linux-USB | ||
| 270 | "cdc-acm" driver. | ||
| 271 | |||
| 272 | This driver also supports a CDC-OBEX option. You will need a | ||
| 273 | user space OBEX server talking to /dev/ttyGS*, since the kernel | ||
| 274 | itself doesn't implement the OBEX protocol. | ||
| 275 | |||
| 276 | Say "y" to link the driver statically, or "m" to build a | ||
| 277 | dynamically linked module called "g_serial". | ||
| 278 | |||
| 279 | For more information, see Documentation/usb/gadget_serial.txt | ||
| 280 | which includes instructions and a "driver info file" needed to | ||
| 281 | make MS-Windows work with CDC ACM. | ||
| 282 | |||
| 283 | config USB_MIDI_GADGET | ||
| 284 | tristate "MIDI Gadget" | ||
| 285 | depends on SND | ||
| 286 | select USB_LIBCOMPOSITE | ||
| 287 | select SND_RAWMIDI | ||
| 288 | help | ||
| 289 | The MIDI Gadget acts as a USB Audio device, with one MIDI | ||
| 290 | input and one MIDI output. These MIDI jacks appear as | ||
| 291 | a sound "card" in the ALSA sound system. Other MIDI | ||
| 292 | connections can then be made on the gadget system, using | ||
| 293 | ALSA's aconnect utility etc. | ||
| 294 | |||
| 295 | Say "y" to link the driver statically, or "m" to build a | ||
| 296 | dynamically linked module called "g_midi". | ||
| 297 | |||
| 298 | config USB_G_PRINTER | ||
| 299 | tristate "Printer Gadget" | ||
| 300 | select USB_LIBCOMPOSITE | ||
| 301 | help | ||
| 302 | The Printer Gadget channels data between the USB host and a | ||
| 303 | userspace program driving the print engine. The user space | ||
| 304 | program reads and writes the device file /dev/g_printer to | ||
| 305 | receive or send printer data. It can use ioctl calls to | ||
| 306 | the device file to get or set printer status. | ||
| 307 | |||
| 308 | Say "y" to link the driver statically, or "m" to build a | ||
| 309 | dynamically linked module called "g_printer". | ||
| 310 | |||
| 311 | For more information, see Documentation/usb/gadget_printer.txt | ||
| 312 | which includes sample code for accessing the device file. | ||
| 313 | |||
| 314 | if TTY | ||
| 315 | |||
| 316 | config USB_CDC_COMPOSITE | ||
| 317 | tristate "CDC Composite Device (Ethernet and ACM)" | ||
| 318 | depends on NET | ||
| 319 | select USB_LIBCOMPOSITE | ||
| 320 | select USB_U_SERIAL | ||
| 321 | select USB_U_ETHER | ||
| 322 | select USB_F_ACM | ||
| 323 | select USB_F_ECM | ||
| 324 | help | ||
| 325 | This driver provides two functions in one configuration: | ||
| 326 | a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link. | ||
| 327 | |||
| 328 | This driver requires four bulk and two interrupt endpoints, | ||
| 329 | plus the ability to handle altsettings. Not all peripheral | ||
| 330 | controllers are that capable. | ||
| 331 | |||
| 332 | Say "y" to link the driver statically, or "m" to build a | ||
| 333 | dynamically linked module. | ||
| 334 | |||
| 335 | config USB_G_NOKIA | ||
| 336 | tristate "Nokia composite gadget" | ||
| 337 | depends on PHONET | ||
| 338 | select USB_LIBCOMPOSITE | ||
| 339 | select USB_U_SERIAL | ||
| 340 | select USB_U_ETHER | ||
| 341 | select USB_F_ACM | ||
| 342 | select USB_F_OBEX | ||
| 343 | select USB_F_PHONET | ||
| 344 | select USB_F_ECM | ||
| 345 | help | ||
| 346 | The Nokia composite gadget provides support for acm, obex | ||
| 347 | and phonet in only one composite gadget driver. | ||
| 348 | |||
| 349 | It's only really useful for N900 hardware. If you're building | ||
| 350 | a kernel for N900, say Y or M here. If unsure, say N. | ||
| 351 | |||
| 352 | config USB_G_ACM_MS | ||
| 353 | tristate "CDC Composite Device (ACM and mass storage)" | ||
| 354 | depends on BLOCK | ||
| 355 | select USB_LIBCOMPOSITE | ||
| 356 | select USB_U_SERIAL | ||
| 357 | select USB_F_ACM | ||
| 358 | select USB_F_MASS_STORAGE | ||
| 359 | help | ||
| 360 | This driver provides two functions in one configuration: | ||
| 361 | a mass storage, and a CDC ACM (serial port) link. | ||
| 362 | |||
| 363 | Say "y" to link the driver statically, or "m" to build a | ||
| 364 | dynamically linked module called "g_acm_ms". | ||
| 365 | |||
| 366 | config USB_G_MULTI | ||
| 367 | tristate "Multifunction Composite Gadget" | ||
| 368 | depends on BLOCK && NET | ||
| 369 | select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS | ||
| 370 | select USB_LIBCOMPOSITE | ||
| 371 | select USB_U_SERIAL | ||
| 372 | select USB_U_ETHER | ||
| 373 | select USB_F_ACM | ||
| 374 | select USB_F_MASS_STORAGE | ||
| 375 | help | ||
| 376 | The Multifunction Composite Gadget provides Ethernet (RNDIS | ||
| 377 | and/or CDC Ethernet), mass storage and ACM serial link | ||
| 378 | interfaces. | ||
| 379 | |||
| 380 | You will be asked to choose which of the two configurations is | ||
| 381 | to be available in the gadget. At least one configuration must | ||
| 382 | be chosen to make the gadget usable. Selecting more than one | ||
| 383 | configuration will prevent Windows from automatically detecting | ||
| 384 | the gadget as a composite gadget, so an INF file will be needed to | ||
| 385 | use the gadget. | ||
| 386 | |||
| 387 | Say "y" to link the driver statically, or "m" to build a | ||
| 388 | dynamically linked module called "g_multi". | ||
| 389 | |||
| 390 | config USB_G_MULTI_RNDIS | ||
| 391 | bool "RNDIS + CDC Serial + Storage configuration" | ||
| 392 | depends on USB_G_MULTI | ||
| 393 | select USB_F_RNDIS | ||
| 394 | default y | ||
| 395 | help | ||
| 396 | This option enables a configuration with RNDIS, CDC Serial and | ||
| 397 | Mass Storage functions available in the Multifunction Composite | ||
| 398 | Gadget. This is the configuration dedicated for Windows since RNDIS | ||
| 399 | is Microsoft's protocol. | ||
| 400 | |||
| 401 | If unsure, say "y". | ||
| 402 | |||
| 403 | config USB_G_MULTI_CDC | ||
| 404 | bool "CDC Ethernet + CDC Serial + Storage configuration" | ||
| 405 | depends on USB_G_MULTI | ||
| 406 | default n | ||
| 407 | select USB_F_ECM | ||
| 408 | help | ||
| 409 | This option enables a configuration with CDC Ethernet (ECM), CDC | ||
| 410 | Serial and Mass Storage functions available in the Multifunction | ||
| 411 | Composite Gadget. | ||
| 412 | |||
| 413 | If unsure, say "y". | ||
| 414 | |||
| 415 | endif # TTY | ||
| 416 | |||
| 417 | config USB_G_HID | ||
| 418 | tristate "HID Gadget" | ||
| 419 | select USB_LIBCOMPOSITE | ||
| 420 | help | ||
| 421 | The HID gadget driver provides generic emulation of USB | ||
| 422 | Human Interface Devices (HID). | ||
| 423 | |||
| 424 | For more information, see Documentation/usb/gadget_hid.txt which | ||
| 425 | includes sample code for accessing the device files. | ||
| 426 | |||
| 427 | Say "y" to link the driver statically, or "m" to build a | ||
| 428 | dynamically linked module called "g_hid". | ||
| 429 | |||
| 430 | # Standalone / single function gadgets | ||
| 431 | config USB_G_DBGP | ||
| 432 | tristate "EHCI Debug Device Gadget" | ||
| 433 | depends on TTY | ||
| 434 | select USB_LIBCOMPOSITE | ||
| 435 | help | ||
| 436 | This gadget emulates an EHCI Debug device. This is useful when you want | ||
| 437 | to interact with an EHCI Debug Port. | ||
| 438 | |||
| 439 | Say "y" to link the driver statically, or "m" to build a | ||
| 440 | dynamically linked module called "g_dbgp". | ||
| 441 | |||
| 442 | if USB_G_DBGP | ||
| 443 | choice | ||
| 444 | prompt "EHCI Debug Device mode" | ||
| 445 | default USB_G_DBGP_SERIAL | ||
| 446 | |||
| 447 | config USB_G_DBGP_PRINTK | ||
| 448 | depends on USB_G_DBGP | ||
| 449 | bool "printk" | ||
| 450 | help | ||
| 451 | Directly printk() received data. No interaction. | ||
| 452 | |||
| 453 | config USB_G_DBGP_SERIAL | ||
| 454 | depends on USB_G_DBGP | ||
| 455 | select USB_U_SERIAL | ||
| 456 | bool "serial" | ||
| 457 | help | ||
| 458 | Userland can interact using /dev/ttyGSxxx. | ||
| 459 | endchoice | ||
| 460 | endif | ||
| 461 | |||
| 462 | # put drivers that need isochronous transfer support (for audio | ||
| 463 | # or video class gadget drivers), or specific hardware, here. | ||
| 464 | config USB_G_WEBCAM | ||
| 465 | tristate "USB Webcam Gadget" | ||
| 466 | depends on VIDEO_DEV | ||
| 467 | select USB_LIBCOMPOSITE | ||
| 468 | select VIDEOBUF2_VMALLOC | ||
| 469 | help | ||
| 470 | The Webcam Gadget acts as a composite USB Audio and Video Class | ||
| 471 | device. It provides a userspace API to process UVC control requests | ||
| 472 | and stream video data to the host. | ||
| 473 | |||
| 474 | Say "y" to link the driver statically, or "m" to build a | ||
| 475 | dynamically linked module called "g_webcam". | ||
| @@ -0,0 +1,44 @@ | |||
| 1 | # | ||
| 2 | # USB gadget drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | ccflags-y := -I$(PWD)/drivers/usb/gadget/ | ||
| 6 | ccflags-y += -I$(PWD)/drivers/usb/gadget/udc/ | ||
| 7 | ccflags-y += -I$(PWD)/drivers/usb/gadget/function/ | ||
| 8 | |||
| 9 | g_zero-y := zero.o | ||
| 10 | g_audio-y := audio.o | ||
| 11 | g_ether-y := ether.o | ||
| 12 | g_serial-y := serial.o | ||
| 13 | g_midi-y := gmidi.o | ||
| 14 | gadgetfs-y := inode.o | ||
| 15 | g_mass_storage-y := mass_storage.o | ||
| 16 | g_printer-y := printer.o | ||
| 17 | g_cdc-y := cdc2.o | ||
| 18 | g_multi-y := multi.o | ||
| 19 | g_hid-y := hid.o | ||
| 20 | g_dbgp-y := dbgp.o | ||
| 21 | g_nokia-y := nokia.o | ||
| 22 | g_webcam-y := webcam.o | ||
| 23 | g_ncm-y := ncm.o | ||
| 24 | g_acm_ms-y := acm_ms.o | ||
| 25 | g_tcm_usb_gadget-y := tcm_usb_gadget.o | ||
| 26 | |||
| 27 | obj-$(CONFIG_USB_ZERO) += g_zero.o | ||
| 28 | obj-$(CONFIG_USB_AUDIO) += g_audio.o | ||
| 29 | obj-$(CONFIG_USB_ETH) += g_ether.o | ||
| 30 | obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o | ||
| 31 | obj-$(CONFIG_USB_FUNCTIONFS) += g_ffs.o | ||
| 32 | obj-$(CONFIG_USB_MASS_STORAGE) += g_mass_storage.o | ||
| 33 | obj-$(CONFIG_USB_G_SERIAL) += g_serial.o | ||
| 34 | obj-$(CONFIG_USB_G_PRINTER) += g_printer.o | ||
| 35 | obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o | ||
| 36 | obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o | ||
| 37 | obj-$(CONFIG_USB_G_HID) += g_hid.o | ||
| 38 | obj-$(CONFIG_USB_G_DBGP) += g_dbgp.o | ||
| 39 | obj-$(CONFIG_USB_G_MULTI) += g_multi.o | ||
| 40 | obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o | ||
| 41 | obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o | ||
| 42 | obj-$(CONFIG_USB_G_NCM) += g_ncm.o | ||
| 43 | obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o | ||
| 44 | obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o | ||
| @@ -267,18 +267,8 @@ static __refdata struct usb_composite_driver acm_ms_driver = { · 266 unmodified lines | |||
| 267 | .unbind = __exit_p(acm_ms_unbind), | 267 | .unbind = __exit_p(acm_ms_unbind), |
| 268 | }; | 268 | }; |
| 269 | 269 | ||
| 270 | module_usb_composite_driver(acm_ms_driver); | ||
| 271 | |||
| 270 | MODULE_DESCRIPTION(DRIVER_DESC); | 272 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 271 | MODULE_AUTHOR("Klaus Schwarzkopf <schwarzkopf@sensortherm.de>"); | 273 | MODULE_AUTHOR("Klaus Schwarzkopf <schwarzkopf@sensortherm.de>"); |
| 272 | MODULE_LICENSE("GPL v2"); | 274 | MODULE_LICENSE("GPL v2"); |
| 273 | |||
| 274 | static int __init init(void) | ||
| 275 | { | ||
| 276 | return usb_composite_probe(&acm_ms_driver); | ||
| 277 | } | ||
| 278 | module_init(init); | ||
| 279 | |||
| 280 | static void __exit cleanup(void) | ||
| 281 | { | ||
| 282 | usb_composite_unregister(&acm_ms_driver); | ||
| 283 | } | ||
| 284 | module_exit(cleanup); | ||
| @@ -172,17 +172,7 @@ static __refdata struct usb_composite_driver audio_driver = { · 171 unmodified lines | |||
| 172 | .unbind = __exit_p(audio_unbind), | 172 | .unbind = __exit_p(audio_unbind), |
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | static int __init init(void) | 175 | module_usb_composite_driver(audio_driver); |
| 176 | { | ||
| 177 | return usb_composite_probe(&audio_driver); | ||
| 178 | } | ||
| 179 | module_init(init); | ||
| 180 | |||
| 181 | static void __exit cleanup(void) | ||
| 182 | { | ||
| 183 | usb_composite_unregister(&audio_driver); | ||
| 184 | } | ||
| 185 | module_exit(cleanup); | ||
| 186 | 176 | ||
| 187 | MODULE_DESCRIPTION(DRIVER_DESC); | 177 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 188 | MODULE_AUTHOR("Bryan Wu <cooloney@kernel.org>"); | 178 | MODULE_AUTHOR("Bryan Wu <cooloney@kernel.org>"); |
| @@ -231,18 +231,8 @@ static __refdata struct usb_composite_driver cdc_driver = { · 230 unmodified lines | |||
| 231 | .unbind = __exit_p(cdc_unbind), | 231 | .unbind = __exit_p(cdc_unbind), |
| 232 | }; | 232 | }; |
| 233 | 233 | ||
| 234 | module_usb_composite_driver(cdc_driver); | ||
| 235 | |||
| 234 | MODULE_DESCRIPTION(DRIVER_DESC); | 236 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 235 | MODULE_AUTHOR("David Brownell"); | 237 | MODULE_AUTHOR("David Brownell"); |
| 236 | MODULE_LICENSE("GPL"); | 238 | MODULE_LICENSE("GPL"); |
| 237 | |||
| 238 | static int __init init(void) | ||
| 239 | { | ||
| 240 | return usb_composite_probe(&cdc_driver); | ||
| 241 | } | ||
| 242 | module_init(init); | ||
| 243 | |||
| 244 | static void __exit cleanup(void) | ||
| 245 | { | ||
| 246 | usb_composite_unregister(&cdc_driver); | ||
| 247 | } | ||
| 248 | module_exit(cleanup); | ||
File renamed without changes.
| @@ -475,18 +475,8 @@ static __refdata struct usb_composite_driver eth_driver = { · 474 unmodified lines | |||
| 475 | .unbind = __exit_p(eth_unbind), | 475 | .unbind = __exit_p(eth_unbind), |
| 476 | }; | 476 | }; |
| 477 | 477 | ||
| 478 | module_usb_composite_driver(eth_driver); | ||
| 479 | |||
| 478 | MODULE_DESCRIPTION(PREFIX DRIVER_DESC); | 480 | MODULE_DESCRIPTION(PREFIX DRIVER_DESC); |
| 479 | MODULE_AUTHOR("David Brownell, Benedikt Spanger"); | 481 | MODULE_AUTHOR("David Brownell, Benedikt Spanger"); |
| 480 | MODULE_LICENSE("GPL"); | 482 | MODULE_LICENSE("GPL"); |
| 481 | |||
| 482 | static int __init init(void) | ||
| 483 | { | ||
| 484 | return usb_composite_probe(ð_driver); | ||
| 485 | } | ||
| 486 | module_init(init); | ||
| 487 | |||
| 488 | static void __exit cleanup(void) | ||
| 489 | { | ||
| 490 | usb_composite_unregister(ð_driver); | ||
| 491 | } | ||
| 492 | module_exit(cleanup); | ||
| @@ -276,7 +276,7 @@ module_exit(gfs_exit); · 275 unmodified lines | |||
| 276 | static void *functionfs_acquire_dev(struct ffs_dev *dev) | 276 | static void *functionfs_acquire_dev(struct ffs_dev *dev) |
| 277 | { | 277 | { |
| 278 | if (!try_module_get(THIS_MODULE)) | 278 | if (!try_module_get(THIS_MODULE)) |
| 279 | return ERR_PTR(-ENODEV); | 279 | return ERR_PTR(-ENOENT); |
| 280 | 280 | ||
| 281 | return 0; | 281 | return 0; |
| 282 | } | 282 | } |
| @@ -163,15 +163,4 @@ static __refdata struct usb_composite_driver midi_driver = { · 162 unmodified lines | |||
| 163 | .unbind = __exit_p(midi_unbind), | 163 | .unbind = __exit_p(midi_unbind), |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | static int __init midi_init(void) | 166 | module_usb_composite_driver(midi_driver); |
| 167 | { | ||
| 168 | return usb_composite_probe(&midi_driver); | ||
| 169 | } | ||
| 170 | module_init(midi_init); | ||
| 171 | |||
| 172 | static void __exit midi_cleanup(void) | ||
| 173 | { | ||
| 174 | usb_composite_unregister(&midi_driver); | ||
| 175 | } | ||
| 176 | module_exit(midi_cleanup); | ||
| 177 | |||
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -507,15 +507,4 @@ static __refdata struct usb_composite_driver multi_driver = { · 506 unmodified lines | |||
| 507 | .needs_serial = 1, | 507 | .needs_serial = 1, |
| 508 | }; | 508 | }; |
| 509 | 509 | ||
| 510 | 510 | module_usb_composite_driver(multi_driver); | |
| 511 | static int __init multi_init(void) | ||
| 512 | { | ||
| 513 | return usb_composite_probe(&multi_driver); | ||
| 514 | } | ||
| 515 | module_init(multi_init); | ||
| 516 | |||
| 517 | static void __exit multi_exit(void) | ||
| 518 | { | ||
| 519 | usb_composite_unregister(&multi_driver); | ||
| 520 | } | ||
| 521 | module_exit(multi_exit); | ||
| @@ -204,18 +204,8 @@ static __refdata struct usb_composite_driver ncm_driver = { · 203 unmodified lines | |||
| 204 | .unbind = __exit_p(gncm_unbind), | 204 | .unbind = __exit_p(gncm_unbind), |
| 205 | }; | 205 | }; |
| 206 | 206 | ||
| 207 | module_usb_composite_driver(ncm_driver); | ||
| 208 | |||
| 207 | MODULE_DESCRIPTION(DRIVER_DESC); | 209 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 208 | MODULE_AUTHOR("Yauheni Kaliuta"); | 210 | MODULE_AUTHOR("Yauheni Kaliuta"); |
| 209 | MODULE_LICENSE("GPL"); | 211 | MODULE_LICENSE("GPL"); |
| 210 | |||
| 211 | static int __init init(void) | ||
| 212 | { | ||
| 213 | return usb_composite_probe(&ncm_driver); | ||
| 214 | } | ||
| 215 | module_init(init); | ||
| 216 | |||
| 217 | static void __exit cleanup(void) | ||
| 218 | { | ||
| 219 | usb_composite_unregister(&ncm_driver); | ||
| 220 | } | ||
| 221 | module_exit(cleanup); | ||
| @@ -347,14 +347,4 @@ static __refdata struct usb_composite_driver nokia_driver = { · 346 unmodified lines | |||
| 347 | .unbind = __exit_p(nokia_unbind), | 347 | .unbind = __exit_p(nokia_unbind), |
| 348 | }; | 348 | }; |
| 349 | 349 | ||
| 350 | static int __init nokia_init(void) | 350 | module_usb_composite_driver(nokia_driver); |
| 351 | { | ||
| 352 | return usb_composite_probe(&nokia_driver); | ||
| 353 | } | ||
| 354 | module_init(nokia_init); | ||
| 355 | |||
| 356 | static void __exit nokia_cleanup(void) | ||
| 357 | { | ||
| 358 | usb_composite_unregister(&nokia_driver); | ||
| 359 | } | ||
| 360 | module_exit(nokia_cleanup); | ||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -390,20 +390,7 @@ static __refdata struct usb_composite_driver webcam_driver = { · 389 unmodified lines | |||
| 390 | .unbind = webcam_unbind, | 390 | .unbind = webcam_unbind, |
| 391 | }; | 391 | }; |
| 392 | 392 | ||
| 393 | static int __init | 393 | module_usb_composite_driver(webcam_driver); |
| 394 | webcam_init(void) | ||
| 395 | { | ||
| 396 | return usb_composite_probe(&webcam_driver); | ||
| 397 | } | ||
| 398 | |||
| 399 | static void __exit | ||
| 400 | webcam_cleanup(void) | ||
| 401 | { | ||
| 402 | usb_composite_unregister(&webcam_driver); | ||
| 403 | } | ||
| 404 | |||
| 405 | module_init(webcam_init); | ||
| 406 | module_exit(webcam_cleanup); | ||
| 407 | 394 | ||
| 408 | MODULE_AUTHOR("Laurent Pinchart"); | 395 | MODULE_AUTHOR("Laurent Pinchart"); |
| 409 | MODULE_DESCRIPTION("Webcam Video Gadget"); | 396 | MODULE_DESCRIPTION("Webcam Video Gadget"); |
| @@ -411,17 +411,7 @@ static __refdata struct usb_composite_driver zero_driver = { · 410 unmodified lines | |||
| 411 | .resume = zero_resume, | 411 | .resume = zero_resume, |
| 412 | }; | 412 | }; |
| 413 | 413 | ||
| 414 | module_usb_composite_driver(zero_driver); | ||
| 415 | |||
| 414 | MODULE_AUTHOR("David Brownell"); | 416 | MODULE_AUTHOR("David Brownell"); |
| 415 | MODULE_LICENSE("GPL"); | 417 | MODULE_LICENSE("GPL"); |
| 416 | |||
| 417 | static int __init init(void) | ||
| 418 | { | ||
| 419 | return usb_composite_probe(&zero_driver); | ||
| 420 | } | ||
| 421 | module_init(init); | ||
| 422 | |||
| 423 | static void __exit cleanup(void) | ||
| 424 | { | ||
| 425 | usb_composite_unregister(&zero_driver); | ||
| 426 | } | ||
| 427 | module_exit(cleanup); | ||
| @@ -1,2905 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Driver for the PLX NET2280 USB device controller. | ||
| 3 | * Specs and errata are available from <http://www.plxtech.com>. | ||
| 4 | * | ||
| 5 | * PLX Technology Inc. (formerly NetChip Technology) supported the | ||
| 6 | * development of this driver. | ||
| 7 | * | ||
| 8 | * | ||
| 9 | * CODE STATUS HIGHLIGHTS | ||
| 10 | * | ||
| 11 | * This driver should work well with most "gadget" drivers, including | ||
| 12 | * the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers | ||
| 13 | * as well as Gadget Zero and Gadgetfs. | ||
| 14 | * | ||
| 15 | * DMA is enabled by default. Drivers using transfer queues might use | ||
| 16 | * DMA chaining to remove IRQ latencies between transfers. (Except when | ||
| 17 | * short OUT transfers happen.) Drivers can use the req->no_interrupt | ||
| 18 | * hint to completely eliminate some IRQs, if a later IRQ is guaranteed | ||
| 19 | * and DMA chaining is enabled. | ||
| 20 | * | ||
| 21 | * Note that almost all the errata workarounds here are only needed for | ||
| 22 | * rev1 chips. Rev1a silicon (0110) fixes almost all of them. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Copyright (C) 2003 David Brownell | ||
| 27 | * Copyright (C) 2003-2005 PLX Technology, Inc. | ||
| 28 | * | ||
| 29 | * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility | ||
| 30 | * with 2282 chip | ||
| 31 | * | ||
| 32 | * This program is free software; you can redistribute it and/or modify | ||
| 33 | * it under the terms of the GNU General Public License as published by | ||
| 34 | * the Free Software Foundation; either version 2 of the License, or | ||
| 35 | * (at your option) any later version. | ||
| 36 | */ | ||
| 37 | |||
| 38 | #undef DEBUG /* messages on error and most fault paths */ | ||
| 39 | #undef VERBOSE /* extra debug messages (success too) */ | ||
| 40 | |||
| 41 | #include <linux/module.h> | ||
| 42 | #include <linux/pci.h> | ||
| 43 | #include <linux/dma-mapping.h> | ||
| 44 | #include <linux/kernel.h> | ||
| 45 | #include <linux/delay.h> | ||
| 46 | #include <linux/ioport.h> | ||
| 47 | #include <linux/slab.h> | ||
| 48 | #include <linux/errno.h> | ||
| 49 | #include <linux/init.h> | ||
| 50 | #include <linux/timer.h> | ||
| 51 | #include <linux/list.h> | ||
| 52 | #include <linux/interrupt.h> | ||
| 53 | #include <linux/moduleparam.h> | ||
| 54 | #include <linux/device.h> | ||
| 55 | #include <linux/usb/ch9.h> | ||
| 56 | #include <linux/usb/gadget.h> | ||
| 57 | #include <linux/prefetch.h> | ||
| 58 | |||
| 59 | #include <asm/byteorder.h> | ||
| 60 | #include <asm/io.h> | ||
| 61 | #include <asm/irq.h> | ||
| 62 | #include <asm/unaligned.h> | ||
| 63 | |||
| 64 | |||
| 65 | #define DRIVER_DESC "PLX NET228x USB Peripheral Controller" | ||
| 66 | #define DRIVER_VERSION "2005 Sept 27" | ||
| 67 | |||
| 68 | #define EP_DONTUSE 13 /* nonzero */ | ||
| 69 | |||
| 70 | #define USE_RDK_LEDS /* GPIO pins control three LEDs */ | ||
| 71 | |||
| 72 | |||
| 73 | static const char driver_name [] = "net2280"; | ||
| 74 | static const char driver_desc [] = DRIVER_DESC; | ||
| 75 | |||
| 76 | static const char ep0name [] = "ep0"; | ||
| 77 | static const char *const ep_name [] = { | ||
| 78 | ep0name, | ||
| 79 | "ep-a", "ep-b", "ep-c", "ep-d", | ||
| 80 | "ep-e", "ep-f", | ||
| 81 | }; | ||
| 82 | |||
| 83 | /* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO) | ||
| 84 | * use_dma_chaining -- dma descriptor queueing gives even more irq reduction | ||
| 85 | * | ||
| 86 | * The net2280 DMA engines are not tightly integrated with their FIFOs; | ||
| 87 | * not all cases are (yet) handled well in this driver or the silicon. | ||
| 88 | * Some gadget drivers work better with the dma support here than others. | ||
| 89 | * These two parameters let you use PIO or more aggressive DMA. | ||
| 90 | */ | ||
| 91 | static bool use_dma = 1; | ||
| 92 | static bool use_dma_chaining = 0; | ||
| 93 | |||
| 94 | /* "modprobe net2280 use_dma=n" etc */ | ||
| 95 | module_param (use_dma, bool, S_IRUGO); | ||
| 96 | module_param (use_dma_chaining, bool, S_IRUGO); | ||
| 97 | |||
| 98 | |||
| 99 | /* mode 0 == ep-{a,b,c,d} 1K fifo each | ||
| 100 | * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable | ||
| 101 | * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable | ||
| 102 | */ | ||
| 103 | static ushort fifo_mode = 0; | ||
| 104 | |||
| 105 | /* "modprobe net2280 fifo_mode=1" etc */ | ||
| 106 | module_param (fifo_mode, ushort, 0644); | ||
| 107 | |||
| 108 | /* enable_suspend -- When enabled, the driver will respond to | ||
| 109 | * USB suspend requests by powering down the NET2280. Otherwise, | ||
| 110 | * USB suspend requests will be ignored. This is acceptable for | ||
| 111 | * self-powered devices | ||
| 112 | */ | ||
| 113 | static bool enable_suspend = 0; | ||
| 114 | |||
| 115 | /* "modprobe net2280 enable_suspend=1" etc */ | ||
| 116 | module_param (enable_suspend, bool, S_IRUGO); | ||
| 117 | |||
| 118 | /* force full-speed operation */ | ||
| 119 | static bool full_speed; | ||
| 120 | module_param(full_speed, bool, 0444); | ||
| 121 | MODULE_PARM_DESC(full_speed, "force full-speed mode -- for testing only!"); | ||
| 122 | |||
| 123 | #define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out") | ||
| 124 | |||
| 125 | #if defined(CONFIG_USB_GADGET_DEBUG_FILES) || defined (DEBUG) | ||
| 126 | static char *type_string (u8 bmAttributes) | ||
| 127 | { | ||
| 128 | switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) { | ||
| 129 | case USB_ENDPOINT_XFER_BULK: return "bulk"; | ||
| 130 | case USB_ENDPOINT_XFER_ISOC: return "iso"; | ||
| 131 | case USB_ENDPOINT_XFER_INT: return "intr"; | ||
| 132 | } | ||
| 133 | return "control"; | ||
| 134 | } | ||
| 135 | #endif | ||
| 136 | |||
| 137 | #include "net2280.h" | ||
| 138 | |||
| 139 | #define valid_bit cpu_to_le32 (1 << VALID_BIT) | ||
| 140 | #define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE) | ||
| 141 | |||
| 142 | /*-------------------------------------------------------------------------*/ | ||
| 143 | |||
| 144 | static int | ||
| 145 | net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | ||
| 146 | { | ||
| 147 | struct net2280 *dev; | ||
| 148 | struct net2280_ep *ep; | ||
| 149 | u32 max, tmp; | ||
| 150 | unsigned long flags; | ||
| 151 | |||
| 152 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 153 | if (!_ep || !desc || ep->desc || _ep->name == ep0name | ||
| 154 | || desc->bDescriptorType != USB_DT_ENDPOINT) | ||
| 155 | return -EINVAL; | ||
| 156 | dev = ep->dev; | ||
| 157 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 158 | return -ESHUTDOWN; | ||
| 159 | |||
| 160 | /* erratum 0119 workaround ties up an endpoint number */ | ||
| 161 | if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) | ||
| 162 | return -EDOM; | ||
| 163 | |||
| 164 | /* sanity check ep-e/ep-f since their fifos are small */ | ||
| 165 | max = usb_endpoint_maxp (desc) & 0x1fff; | ||
| 166 | if (ep->num > 4 && max > 64) | ||
| 167 | return -ERANGE; | ||
| 168 | |||
| 169 | spin_lock_irqsave (&dev->lock, flags); | ||
| 170 | _ep->maxpacket = max & 0x7ff; | ||
| 171 | ep->desc = desc; | ||
| 172 | |||
| 173 | /* ep_reset() has already been called */ | ||
| 174 | ep->stopped = 0; | ||
| 175 | ep->wedged = 0; | ||
| 176 | ep->out_overflow = 0; | ||
| 177 | |||
| 178 | /* set speed-dependent max packet; may kick in high bandwidth */ | ||
| 179 | set_idx_reg (dev->regs, REG_EP_MAXPKT (dev, ep->num), max); | ||
| 180 | |||
| 181 | /* FIFO lines can't go to different packets. PIO is ok, so | ||
| 182 | * use it instead of troublesome (non-bulk) multi-packet DMA. | ||
| 183 | */ | ||
| 184 | if (ep->dma && (max % 4) != 0 && use_dma_chaining) { | ||
| 185 | DEBUG (ep->dev, "%s, no dma for maxpacket %d\n", | ||
| 186 | ep->ep.name, ep->ep.maxpacket); | ||
| 187 | ep->dma = NULL; | ||
| 188 | } | ||
| 189 | |||
| 190 | /* set type, direction, address; reset fifo counters */ | ||
| 191 | writel ((1 << FIFO_FLUSH), &ep->regs->ep_stat); | ||
| 192 | tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | ||
| 193 | if (tmp == USB_ENDPOINT_XFER_INT) { | ||
| 194 | /* erratum 0105 workaround prevents hs NYET */ | ||
| 195 | if (dev->chiprev == 0100 | ||
| 196 | && dev->gadget.speed == USB_SPEED_HIGH | ||
| 197 | && !(desc->bEndpointAddress & USB_DIR_IN)) | ||
| 198 | writel ((1 << CLEAR_NAK_OUT_PACKETS_MODE), | ||
| 199 | &ep->regs->ep_rsp); | ||
| 200 | } else if (tmp == USB_ENDPOINT_XFER_BULK) { | ||
| 201 | /* catch some particularly blatant driver bugs */ | ||
| 202 | if ((dev->gadget.speed == USB_SPEED_HIGH | ||
| 203 | && max != 512) | ||
| 204 | || (dev->gadget.speed == USB_SPEED_FULL | ||
| 205 | && max > 64)) { | ||
| 206 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 207 | return -ERANGE; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0; | ||
| 211 | tmp <<= ENDPOINT_TYPE; | ||
| 212 | tmp |= desc->bEndpointAddress; | ||
| 213 | tmp |= (4 << ENDPOINT_BYTE_COUNT); /* default full fifo lines */ | ||
| 214 | tmp |= 1 << ENDPOINT_ENABLE; | ||
| 215 | wmb (); | ||
| 216 | |||
| 217 | /* for OUT transfers, block the rx fifo until a read is posted */ | ||
| 218 | ep->is_in = (tmp & USB_DIR_IN) != 0; | ||
| 219 | if (!ep->is_in) | ||
| 220 | writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 221 | else if (dev->pdev->device != 0x2280) { | ||
| 222 | /* Added for 2282, Don't use nak packets on an in endpoint, | ||
| 223 | * this was ignored on 2280 | ||
| 224 | */ | ||
| 225 | writel ((1 << CLEAR_NAK_OUT_PACKETS) | ||
| 226 | | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); | ||
| 227 | } | ||
| 228 | |||
| 229 | writel (tmp, &ep->regs->ep_cfg); | ||
| 230 | |||
| 231 | /* enable irqs */ | ||
| 232 | if (!ep->dma) { /* pio, per-packet */ | ||
| 233 | tmp = (1 << ep->num) | readl (&dev->regs->pciirqenb0); | ||
| 234 | writel (tmp, &dev->regs->pciirqenb0); | ||
| 235 | |||
| 236 | tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) | ||
| 237 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE); | ||
| 238 | if (dev->pdev->device == 0x2280) | ||
| 239 | tmp |= readl (&ep->regs->ep_irqenb); | ||
| 240 | writel (tmp, &ep->regs->ep_irqenb); | ||
| 241 | } else { /* dma, per-request */ | ||
| 242 | tmp = (1 << (8 + ep->num)); /* completion */ | ||
| 243 | tmp |= readl (&dev->regs->pciirqenb1); | ||
| 244 | writel (tmp, &dev->regs->pciirqenb1); | ||
| 245 | |||
| 246 | /* for short OUT transfers, dma completions can't | ||
| 247 | * advance the queue; do it pio-style, by hand. | ||
| 248 | * NOTE erratum 0112 workaround #2 | ||
| 249 | */ | ||
| 250 | if ((desc->bEndpointAddress & USB_DIR_IN) == 0) { | ||
| 251 | tmp = (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE); | ||
| 252 | writel (tmp, &ep->regs->ep_irqenb); | ||
| 253 | |||
| 254 | tmp = (1 << ep->num) | readl (&dev->regs->pciirqenb0); | ||
| 255 | writel (tmp, &dev->regs->pciirqenb0); | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 259 | tmp = desc->bEndpointAddress; | ||
| 260 | DEBUG (dev, "enabled %s (ep%d%s-%s) %s max %04x\n", | ||
| 261 | _ep->name, tmp & 0x0f, DIR_STRING (tmp), | ||
| 262 | type_string (desc->bmAttributes), | ||
| 263 | ep->dma ? "dma" : "pio", max); | ||
| 264 | |||
| 265 | /* pci writes may still be posted */ | ||
| 266 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 267 | return 0; | ||
| 268 | } | ||
| 269 | |||
| 270 | static int handshake (u32 __iomem *ptr, u32 mask, u32 done, int usec) | ||
| 271 | { | ||
| 272 | u32 result; | ||
| 273 | |||
| 274 | do { | ||
| 275 | result = readl (ptr); | ||
| 276 | if (result == ~(u32)0) /* "device unplugged" */ | ||
| 277 | return -ENODEV; | ||
| 278 | result &= mask; | ||
| 279 | if (result == done) | ||
| 280 | return 0; | ||
| 281 | udelay (1); | ||
| 282 | usec--; | ||
| 283 | } while (usec > 0); | ||
| 284 | return -ETIMEDOUT; | ||
| 285 | } | ||
| 286 | |||
| 287 | static const struct usb_ep_ops net2280_ep_ops; | ||
| 288 | |||
| 289 | static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep) | ||
| 290 | { | ||
| 291 | u32 tmp; | ||
| 292 | |||
| 293 | ep->desc = NULL; | ||
| 294 | INIT_LIST_HEAD (&ep->queue); | ||
| 295 | |||
| 296 | usb_ep_set_maxpacket_limit(&ep->ep, ~0); | ||
| 297 | ep->ep.ops = &net2280_ep_ops; | ||
| 298 | |||
| 299 | /* disable the dma, irqs, endpoint... */ | ||
| 300 | if (ep->dma) { | ||
| 301 | writel (0, &ep->dma->dmactl); | ||
| 302 | writel ( (1 << DMA_SCATTER_GATHER_DONE_INTERRUPT) | ||
| 303 | | (1 << DMA_TRANSACTION_DONE_INTERRUPT) | ||
| 304 | | (1 << DMA_ABORT) | ||
| 305 | , &ep->dma->dmastat); | ||
| 306 | |||
| 307 | tmp = readl (®s->pciirqenb0); | ||
| 308 | tmp &= ~(1 << ep->num); | ||
| 309 | writel (tmp, ®s->pciirqenb0); | ||
| 310 | } else { | ||
| 311 | tmp = readl (®s->pciirqenb1); | ||
| 312 | tmp &= ~(1 << (8 + ep->num)); /* completion */ | ||
| 313 | writel (tmp, ®s->pciirqenb1); | ||
| 314 | } | ||
| 315 | writel (0, &ep->regs->ep_irqenb); | ||
| 316 | |||
| 317 | /* init to our chosen defaults, notably so that we NAK OUT | ||
| 318 | * packets until the driver queues a read (+note erratum 0112) | ||
| 319 | */ | ||
| 320 | if (!ep->is_in || ep->dev->pdev->device == 0x2280) { | ||
| 321 | tmp = (1 << SET_NAK_OUT_PACKETS_MODE) | ||
| 322 | | (1 << SET_NAK_OUT_PACKETS) | ||
| 323 | | (1 << CLEAR_EP_HIDE_STATUS_PHASE) | ||
| 324 | | (1 << CLEAR_INTERRUPT_MODE); | ||
| 325 | } else { | ||
| 326 | /* added for 2282 */ | ||
| 327 | tmp = (1 << CLEAR_NAK_OUT_PACKETS_MODE) | ||
| 328 | | (1 << CLEAR_NAK_OUT_PACKETS) | ||
| 329 | | (1 << CLEAR_EP_HIDE_STATUS_PHASE) | ||
| 330 | | (1 << CLEAR_INTERRUPT_MODE); | ||
| 331 | } | ||
| 332 | |||
| 333 | if (ep->num != 0) { | ||
| 334 | tmp |= (1 << CLEAR_ENDPOINT_TOGGLE) | ||
| 335 | | (1 << CLEAR_ENDPOINT_HALT); | ||
| 336 | } | ||
| 337 | writel (tmp, &ep->regs->ep_rsp); | ||
| 338 | |||
| 339 | /* scrub most status bits, and flush any fifo state */ | ||
| 340 | if (ep->dev->pdev->device == 0x2280) | ||
| 341 | tmp = (1 << FIFO_OVERFLOW) | ||
| 342 | | (1 << FIFO_UNDERFLOW); | ||
| 343 | else | ||
| 344 | tmp = 0; | ||
| 345 | |||
| 346 | writel (tmp | (1 << TIMEOUT) | ||
| 347 | | (1 << USB_STALL_SENT) | ||
| 348 | | (1 << USB_IN_NAK_SENT) | ||
| 349 | | (1 << USB_IN_ACK_RCVD) | ||
| 350 | | (1 << USB_OUT_PING_NAK_SENT) | ||
| 351 | | (1 << USB_OUT_ACK_SENT) | ||
| 352 | | (1 << FIFO_FLUSH) | ||
| 353 | | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | ||
| 354 | | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | ||
| 355 | | (1 << DATA_PACKET_RECEIVED_INTERRUPT) | ||
| 356 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT) | ||
| 357 | | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 358 | | (1 << DATA_IN_TOKEN_INTERRUPT) | ||
| 359 | , &ep->regs->ep_stat); | ||
| 360 | |||
| 361 | /* fifo size is handled separately */ | ||
| 362 | } | ||
| 363 | |||
| 364 | static void nuke (struct net2280_ep *); | ||
| 365 | |||
| 366 | static int net2280_disable (struct usb_ep *_ep) | ||
| 367 | { | ||
| 368 | struct net2280_ep *ep; | ||
| 369 | unsigned long flags; | ||
| 370 | |||
| 371 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 372 | if (!_ep || !ep->desc || _ep->name == ep0name) | ||
| 373 | return -EINVAL; | ||
| 374 | |||
| 375 | spin_lock_irqsave (&ep->dev->lock, flags); | ||
| 376 | nuke (ep); | ||
| 377 | ep_reset (ep->dev->regs, ep); | ||
| 378 | |||
| 379 | VDEBUG (ep->dev, "disabled %s %s\n", | ||
| 380 | ep->dma ? "dma" : "pio", _ep->name); | ||
| 381 | |||
| 382 | /* synch memory views with the device */ | ||
| 383 | (void) readl (&ep->regs->ep_cfg); | ||
| 384 | |||
| 385 | if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4) | ||
| 386 | ep->dma = &ep->dev->dma [ep->num - 1]; | ||
| 387 | |||
| 388 | spin_unlock_irqrestore (&ep->dev->lock, flags); | ||
| 389 | return 0; | ||
| 390 | } | ||
| 391 | |||
| 392 | /*-------------------------------------------------------------------------*/ | ||
| 393 | |||
| 394 | static struct usb_request * | ||
| 395 | net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) | ||
| 396 | { | ||
| 397 | struct net2280_ep *ep; | ||
| 398 | struct net2280_request *req; | ||
| 399 | |||
| 400 | if (!_ep) | ||
| 401 | return NULL; | ||
| 402 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 403 | |||
| 404 | req = kzalloc(sizeof(*req), gfp_flags); | ||
| 405 | if (!req) | ||
| 406 | return NULL; | ||
| 407 | |||
| 408 | INIT_LIST_HEAD (&req->queue); | ||
| 409 | |||
| 410 | /* this dma descriptor may be swapped with the previous dummy */ | ||
| 411 | if (ep->dma) { | ||
| 412 | struct net2280_dma *td; | ||
| 413 | |||
| 414 | td = pci_pool_alloc (ep->dev->requests, gfp_flags, | ||
| 415 | &req->td_dma); | ||
| 416 | if (!td) { | ||
| 417 | kfree (req); | ||
| 418 | return NULL; | ||
| 419 | } | ||
| 420 | td->dmacount = 0; /* not VALID */ | ||
| 421 | td->dmadesc = td->dmaaddr; | ||
| 422 | req->td = td; | ||
| 423 | } | ||
| 424 | return &req->req; | ||
| 425 | } | ||
| 426 | |||
| 427 | static void | ||
| 428 | net2280_free_request (struct usb_ep *_ep, struct usb_request *_req) | ||
| 429 | { | ||
| 430 | struct net2280_ep *ep; | ||
| 431 | struct net2280_request *req; | ||
| 432 | |||
| 433 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 434 | if (!_ep || !_req) | ||
| 435 | return; | ||
| 436 | |||
| 437 | req = container_of (_req, struct net2280_request, req); | ||
| 438 | WARN_ON (!list_empty (&req->queue)); | ||
| 439 | if (req->td) | ||
| 440 | pci_pool_free (ep->dev->requests, req->td, req->td_dma); | ||
| 441 | kfree (req); | ||
| 442 | } | ||
| 443 | |||
| 444 | /*-------------------------------------------------------------------------*/ | ||
| 445 | |||
| 446 | /* load a packet into the fifo we use for usb IN transfers. | ||
| 447 | * works for all endpoints. | ||
| 448 | * | ||
| 449 | * NOTE: pio with ep-a..ep-d could stuff multiple packets into the fifo | ||
| 450 | * at a time, but this code is simpler because it knows it only writes | ||
| 451 | * one packet. ep-a..ep-d should use dma instead. | ||
| 452 | */ | ||
| 453 | static void | ||
| 454 | write_fifo (struct net2280_ep *ep, struct usb_request *req) | ||
| 455 | { | ||
| 456 | struct net2280_ep_regs __iomem *regs = ep->regs; | ||
| 457 | u8 *buf; | ||
| 458 | u32 tmp; | ||
| 459 | unsigned count, total; | ||
| 460 | |||
| 461 | /* INVARIANT: fifo is currently empty. (testable) */ | ||
| 462 | |||
| 463 | if (req) { | ||
| 464 | buf = req->buf + req->actual; | ||
| 465 | prefetch (buf); | ||
| 466 | total = req->length - req->actual; | ||
| 467 | } else { | ||
| 468 | total = 0; | ||
| 469 | buf = NULL; | ||
| 470 | } | ||
| 471 | |||
| 472 | /* write just one packet at a time */ | ||
| 473 | count = ep->ep.maxpacket; | ||
| 474 | if (count > total) /* min() cannot be used on a bitfield */ | ||
| 475 | count = total; | ||
| 476 | |||
| 477 | VDEBUG (ep->dev, "write %s fifo (IN) %d bytes%s req %p\n", | ||
| 478 | ep->ep.name, count, | ||
| 479 | (count != ep->ep.maxpacket) ? " (short)" : "", | ||
| 480 | req); | ||
| 481 | while (count >= 4) { | ||
| 482 | /* NOTE be careful if you try to align these. fifo lines | ||
| 483 | * should normally be full (4 bytes) and successive partial | ||
| 484 | * lines are ok only in certain cases. | ||
| 485 | */ | ||
| 486 | tmp = get_unaligned ((u32 *)buf); | ||
| 487 | cpu_to_le32s (&tmp); | ||
| 488 | writel (tmp, ®s->ep_data); | ||
| 489 | buf += 4; | ||
| 490 | count -= 4; | ||
| 491 | } | ||
| 492 | |||
| 493 | /* last fifo entry is "short" unless we wrote a full packet. | ||
| 494 | * also explicitly validate last word in (periodic) transfers | ||
| 495 | * when maxpacket is not a multiple of 4 bytes. | ||
| 496 | */ | ||
| 497 | if (count || total < ep->ep.maxpacket) { | ||
| 498 | tmp = count ? get_unaligned ((u32 *)buf) : count; | ||
| 499 | cpu_to_le32s (&tmp); | ||
| 500 | set_fifo_bytecount (ep, count & 0x03); | ||
| 501 | writel (tmp, ®s->ep_data); | ||
| 502 | } | ||
| 503 | |||
| 504 | /* pci writes may still be posted */ | ||
| 505 | } | ||
| 506 | |||
| 507 | /* work around erratum 0106: PCI and USB race over the OUT fifo. | ||
| 508 | * caller guarantees chiprev 0100, out endpoint is NAKing, and | ||
| 509 | * there's no real data in the fifo. | ||
| 510 | * | ||
| 511 | * NOTE: also used in cases where that erratum doesn't apply: | ||
| 512 | * where the host wrote "too much" data to us. | ||
| 513 | */ | ||
| 514 | static void out_flush (struct net2280_ep *ep) | ||
| 515 | { | ||
| 516 | u32 __iomem *statp; | ||
| 517 | u32 tmp; | ||
| 518 | |||
| 519 | ASSERT_OUT_NAKING (ep); | ||
| 520 | |||
| 521 | statp = &ep->regs->ep_stat; | ||
| 522 | writel ( (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 523 | | (1 << DATA_PACKET_RECEIVED_INTERRUPT) | ||
| 524 | , statp); | ||
| 525 | writel ((1 << FIFO_FLUSH), statp); | ||
| 526 | mb (); | ||
| 527 | tmp = readl (statp); | ||
| 528 | if (tmp & (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 529 | /* high speed did bulk NYET; fifo isn't filling */ | ||
| 530 | && ep->dev->gadget.speed == USB_SPEED_FULL) { | ||
| 531 | unsigned usec; | ||
| 532 | |||
| 533 | usec = 50; /* 64 byte bulk/interrupt */ | ||
| 534 | handshake (statp, (1 << USB_OUT_PING_NAK_SENT), | ||
| 535 | (1 << USB_OUT_PING_NAK_SENT), usec); | ||
| 536 | /* NAK done; now CLEAR_NAK_OUT_PACKETS is safe */ | ||
| 537 | } | ||
| 538 | } | ||
| 539 | |||
| 540 | /* unload packet(s) from the fifo we use for usb OUT transfers. | ||
| 541 | * returns true iff the request completed, because of short packet | ||
| 542 | * or the request buffer having filled with full packets. | ||
| 543 | * | ||
| 544 | * for ep-a..ep-d this will read multiple packets out when they | ||
| 545 | * have been accepted. | ||
| 546 | */ | ||
| 547 | static int | ||
| 548 | read_fifo (struct net2280_ep *ep, struct net2280_request *req) | ||
| 549 | { | ||
| 550 | struct net2280_ep_regs __iomem *regs = ep->regs; | ||
| 551 | u8 *buf = req->req.buf + req->req.actual; | ||
| 552 | unsigned count, tmp, is_short; | ||
| 553 | unsigned cleanup = 0, prevent = 0; | ||
| 554 | |||
| 555 | /* erratum 0106 ... packets coming in during fifo reads might | ||
| 556 | * be incompletely rejected. not all cases have workarounds. | ||
| 557 | */ | ||
| 558 | if (ep->dev->chiprev == 0x0100 | ||
| 559 | && ep->dev->gadget.speed == USB_SPEED_FULL) { | ||
| 560 | udelay (1); | ||
| 561 | tmp = readl (&ep->regs->ep_stat); | ||
| 562 | if ((tmp & (1 << NAK_OUT_PACKETS))) | ||
| 563 | cleanup = 1; | ||
| 564 | else if ((tmp & (1 << FIFO_FULL))) { | ||
| 565 | start_out_naking (ep); | ||
| 566 | prevent = 1; | ||
| 567 | } | ||
| 568 | /* else: hope we don't see the problem */ | ||
| 569 | } | ||
| 570 | |||
| 571 | /* never overflow the rx buffer. the fifo reads packets until | ||
| 572 | * it sees a short one; we might not be ready for them all. | ||
| 573 | */ | ||
| 574 | prefetchw (buf); | ||
| 575 | count = readl (®s->ep_avail); | ||
| 576 | if (unlikely (count == 0)) { | ||
| 577 | udelay (1); | ||
| 578 | tmp = readl (&ep->regs->ep_stat); | ||
| 579 | count = readl (®s->ep_avail); | ||
| 580 | /* handled that data already? */ | ||
| 581 | if (count == 0 && (tmp & (1 << NAK_OUT_PACKETS)) == 0) | ||
| 582 | return 0; | ||
| 583 | } | ||
| 584 | |||
| 585 | tmp = req->req.length - req->req.actual; | ||
| 586 | if (count > tmp) { | ||
| 587 | /* as with DMA, data overflow gets flushed */ | ||
| 588 | if ((tmp % ep->ep.maxpacket) != 0) { | ||
| 589 | ERROR (ep->dev, | ||
| 590 | "%s out fifo %d bytes, expected %d\n", | ||
| 591 | ep->ep.name, count, tmp); | ||
| 592 | req->req.status = -EOVERFLOW; | ||
| 593 | cleanup = 1; | ||
| 594 | /* NAK_OUT_PACKETS will be set, so flushing is safe; | ||
| 595 | * the next read will start with the next packet | ||
| 596 | */ | ||
| 597 | } /* else it's a ZLP, no worries */ | ||
| 598 | count = tmp; | ||
| 599 | } | ||
| 600 | req->req.actual += count; | ||
| 601 | |||
| 602 | is_short = (count == 0) || ((count % ep->ep.maxpacket) != 0); | ||
| 603 | |||
| 604 | VDEBUG (ep->dev, "read %s fifo (OUT) %d bytes%s%s%s req %p %d/%d\n", | ||
| 605 | ep->ep.name, count, is_short ? " (short)" : "", | ||
| 606 | cleanup ? " flush" : "", prevent ? " nak" : "", | ||
| 607 | req, req->req.actual, req->req.length); | ||
| 608 | |||
| 609 | while (count >= 4) { | ||
| 610 | tmp = readl (®s->ep_data); | ||
| 611 | cpu_to_le32s (&tmp); | ||
| 612 | put_unaligned (tmp, (u32 *)buf); | ||
| 613 | buf += 4; | ||
| 614 | count -= 4; | ||
| 615 | } | ||
| 616 | if (count) { | ||
| 617 | tmp = readl (®s->ep_data); | ||
| 618 | /* LE conversion is implicit here: */ | ||
| 619 | do { | ||
| 620 | *buf++ = (u8) tmp; | ||
| 621 | tmp >>= 8; | ||
| 622 | } while (--count); | ||
| 623 | } | ||
| 624 | if (cleanup) | ||
| 625 | out_flush (ep); | ||
| 626 | if (prevent) { | ||
| 627 | writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 628 | (void) readl (&ep->regs->ep_rsp); | ||
| 629 | } | ||
| 630 | |||
| 631 | return is_short || ((req->req.actual == req->req.length) | ||
| 632 | && !req->req.zero); | ||
| 633 | } | ||
| 634 | |||
| 635 | /* fill out dma descriptor to match a given request */ | ||
| 636 | static void | ||
| 637 | fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid) | ||
| 638 | { | ||
| 639 | struct net2280_dma *td = req->td; | ||
| 640 | u32 dmacount = req->req.length; | ||
| 641 | |||
| 642 | /* don't let DMA continue after a short OUT packet, | ||
| 643 | * so overruns can't affect the next transfer. | ||
| 644 | * in case of overruns on max-size packets, we can't | ||
| 645 | * stop the fifo from filling but we can flush it. | ||
| 646 | */ | ||
| 647 | if (ep->is_in) | ||
| 648 | dmacount |= (1 << DMA_DIRECTION); | ||
| 649 | if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) | ||
| 650 | || ep->dev->pdev->device != 0x2280) | ||
| 651 | dmacount |= (1 << END_OF_CHAIN); | ||
| 652 | |||
| 653 | req->valid = valid; | ||
| 654 | if (valid) | ||
| 655 | dmacount |= (1 << VALID_BIT); | ||
| 656 | if (likely(!req->req.no_interrupt || !use_dma_chaining)) | ||
| 657 | dmacount |= (1 << DMA_DONE_INTERRUPT_ENABLE); | ||
| 658 | |||
| 659 | /* td->dmadesc = previously set by caller */ | ||
| 660 | td->dmaaddr = cpu_to_le32 (req->req.dma); | ||
| 661 | |||
| 662 | /* 2280 may be polling VALID_BIT through ep->dma->dmadesc */ | ||
| 663 | wmb (); | ||
| 664 | td->dmacount = cpu_to_le32(dmacount); | ||
| 665 | } | ||
| 666 | |||
| 667 | static const u32 dmactl_default = | ||
| 668 | (1 << DMA_SCATTER_GATHER_DONE_INTERRUPT) | ||
| 669 | | (1 << DMA_CLEAR_COUNT_ENABLE) | ||
| 670 | /* erratum 0116 workaround part 1 (use POLLING) */ | ||
| 671 | | (POLL_100_USEC << DESCRIPTOR_POLLING_RATE) | ||
| 672 | | (1 << DMA_VALID_BIT_POLLING_ENABLE) | ||
| 673 | | (1 << DMA_VALID_BIT_ENABLE) | ||
| 674 | | (1 << DMA_SCATTER_GATHER_ENABLE) | ||
| 675 | /* erratum 0116 workaround part 2 (no AUTOSTART) */ | ||
| 676 | | (1 << DMA_ENABLE); | ||
| 677 | |||
| 678 | static inline void spin_stop_dma (struct net2280_dma_regs __iomem *dma) | ||
| 679 | { | ||
| 680 | handshake (&dma->dmactl, (1 << DMA_ENABLE), 0, 50); | ||
| 681 | } | ||
| 682 | |||
| 683 | static inline void stop_dma (struct net2280_dma_regs __iomem *dma) | ||
| 684 | { | ||
| 685 | writel (readl (&dma->dmactl) & ~(1 << DMA_ENABLE), &dma->dmactl); | ||
| 686 | spin_stop_dma (dma); | ||
| 687 | } | ||
| 688 | |||
| 689 | static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma) | ||
| 690 | { | ||
| 691 | struct net2280_dma_regs __iomem *dma = ep->dma; | ||
| 692 | unsigned int tmp = (1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION); | ||
| 693 | |||
| 694 | if (ep->dev->pdev->device != 0x2280) | ||
| 695 | tmp |= (1 << END_OF_CHAIN); | ||
| 696 | |||
| 697 | writel (tmp, &dma->dmacount); | ||
| 698 | writel (readl (&dma->dmastat), &dma->dmastat); | ||
| 699 | |||
| 700 | writel (td_dma, &dma->dmadesc); | ||
| 701 | writel (dmactl, &dma->dmactl); | ||
| 702 | |||
| 703 | /* erratum 0116 workaround part 3: pci arbiter away from net2280 */ | ||
| 704 | (void) readl (&ep->dev->pci->pcimstctl); | ||
| 705 | |||
| 706 | writel ((1 << DMA_START), &dma->dmastat); | ||
| 707 | |||
| 708 | if (!ep->is_in) | ||
| 709 | stop_out_naking (ep); | ||
| 710 | } | ||
| 711 | |||
| 712 | static void start_dma (struct net2280_ep *ep, struct net2280_request *req) | ||
| 713 | { | ||
| 714 | u32 tmp; | ||
| 715 | struct net2280_dma_regs __iomem *dma = ep->dma; | ||
| 716 | |||
| 717 | /* FIXME can't use DMA for ZLPs */ | ||
| 718 | |||
| 719 | /* on this path we "know" there's no dma active (yet) */ | ||
| 720 | WARN_ON (readl (&dma->dmactl) & (1 << DMA_ENABLE)); | ||
| 721 | writel (0, &ep->dma->dmactl); | ||
| 722 | |||
| 723 | /* previous OUT packet might have been short */ | ||
| 724 | if (!ep->is_in && ((tmp = readl (&ep->regs->ep_stat)) | ||
| 725 | & (1 << NAK_OUT_PACKETS)) != 0) { | ||
| 726 | writel ((1 << SHORT_PACKET_TRANSFERRED_INTERRUPT), | ||
| 727 | &ep->regs->ep_stat); | ||
| 728 | |||
| 729 | tmp = readl (&ep->regs->ep_avail); | ||
| 730 | if (tmp) { | ||
| 731 | writel (readl (&dma->dmastat), &dma->dmastat); | ||
| 732 | |||
| 733 | /* transfer all/some fifo data */ | ||
| 734 | writel (req->req.dma, &dma->dmaaddr); | ||
| 735 | tmp = min (tmp, req->req.length); | ||
| 736 | |||
| 737 | /* dma irq, faking scatterlist status */ | ||
| 738 | req->td->dmacount = cpu_to_le32 (req->req.length - tmp); | ||
| 739 | writel ((1 << DMA_DONE_INTERRUPT_ENABLE) | ||
| 740 | | tmp, &dma->dmacount); | ||
| 741 | req->td->dmadesc = 0; | ||
| 742 | req->valid = 1; | ||
| 743 | |||
| 744 | writel ((1 << DMA_ENABLE), &dma->dmactl); | ||
| 745 | writel ((1 << DMA_START), &dma->dmastat); | ||
| 746 | return; | ||
| 747 | } | ||
| 748 | } | ||
| 749 | |||
| 750 | tmp = dmactl_default; | ||
| 751 | |||
| 752 | /* force packet boundaries between dma requests, but prevent the | ||
| 753 | * controller from automagically writing a last "short" packet | ||
| 754 | * (zero length) unless the driver explicitly said to do that. | ||
| 755 | */ | ||
| 756 | if (ep->is_in) { | ||
| 757 | if (likely ((req->req.length % ep->ep.maxpacket) != 0 | ||
| 758 | || req->req.zero)) { | ||
| 759 | tmp |= (1 << DMA_FIFO_VALIDATE); | ||
| 760 | ep->in_fifo_validate = 1; | ||
| 761 | } else | ||
| 762 | ep->in_fifo_validate = 0; | ||
| 763 | } | ||
| 764 | |||
| 765 | /* init req->td, pointing to the current dummy */ | ||
| 766 | req->td->dmadesc = cpu_to_le32 (ep->td_dma); | ||
| 767 | fill_dma_desc (ep, req, 1); | ||
| 768 | |||
| 769 | if (!use_dma_chaining) | ||
| 770 | req->td->dmacount |= cpu_to_le32 (1 << END_OF_CHAIN); | ||
| 771 | |||
| 772 | start_queue (ep, tmp, req->td_dma); | ||
| 773 | } | ||
| 774 | |||
| 775 | static inline void | ||
| 776 | queue_dma (struct net2280_ep *ep, struct net2280_request *req, int valid) | ||
| 777 | { | ||
| 778 | struct net2280_dma *end; | ||
| 779 | dma_addr_t tmp; | ||
| 780 | |||
| 781 | /* swap new dummy for old, link; fill and maybe activate */ | ||
| 782 | end = ep->dummy; | ||
| 783 | ep->dummy = req->td; | ||
| 784 | req->td = end; | ||
| 785 | |||
| 786 | tmp = ep->td_dma; | ||
| 787 | ep->td_dma = req->td_dma; | ||
| 788 | req->td_dma = tmp; | ||
| 789 | |||
| 790 | end->dmadesc = cpu_to_le32 (ep->td_dma); | ||
| 791 | |||
| 792 | fill_dma_desc (ep, req, valid); | ||
| 793 | } | ||
| 794 | |||
| 795 | static void | ||
| 796 | done (struct net2280_ep *ep, struct net2280_request *req, int status) | ||
| 797 | { | ||
| 798 | struct net2280 *dev; | ||
| 799 | unsigned stopped = ep->stopped; | ||
| 800 | |||
| 801 | list_del_init (&req->queue); | ||
| 802 | |||
| 803 | if (req->req.status == -EINPROGRESS) | ||
| 804 | req->req.status = status; | ||
| 805 | else | ||
| 806 | status = req->req.status; | ||
| 807 | |||
| 808 | dev = ep->dev; | ||
| 809 | if (ep->dma) | ||
| 810 | usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in); | ||
| 811 | |||
| 812 | if (status && status != -ESHUTDOWN) | ||
| 813 | VDEBUG (dev, "complete %s req %p stat %d len %u/%u\n", | ||
| 814 | ep->ep.name, &req->req, status, | ||
| 815 | req->req.actual, req->req.length); | ||
| 816 | |||
| 817 | /* don't modify queue heads during completion callback */ | ||
| 818 | ep->stopped = 1; | ||
| 819 | spin_unlock (&dev->lock); | ||
| 820 | req->req.complete (&ep->ep, &req->req); | ||
| 821 | spin_lock (&dev->lock); | ||
| 822 | ep->stopped = stopped; | ||
| 823 | } | ||
| 824 | |||
| 825 | /*-------------------------------------------------------------------------*/ | ||
| 826 | |||
| 827 | static int | ||
| 828 | net2280_queue (struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | ||
| 829 | { | ||
| 830 | struct net2280_request *req; | ||
| 831 | struct net2280_ep *ep; | ||
| 832 | struct net2280 *dev; | ||
| 833 | unsigned long flags; | ||
| 834 | |||
| 835 | /* we always require a cpu-view buffer, so that we can | ||
| 836 | * always use pio (as fallback or whatever). | ||
| 837 | */ | ||
| 838 | req = container_of (_req, struct net2280_request, req); | ||
| 839 | if (!_req || !_req->complete || !_req->buf | ||
| 840 | || !list_empty (&req->queue)) | ||
| 841 | return -EINVAL; | ||
| 842 | if (_req->length > (~0 & DMA_BYTE_COUNT_MASK)) | ||
| 843 | return -EDOM; | ||
| 844 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 845 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 846 | return -EINVAL; | ||
| 847 | dev = ep->dev; | ||
| 848 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 849 | return -ESHUTDOWN; | ||
| 850 | |||
| 851 | /* FIXME implement PIO fallback for ZLPs with DMA */ | ||
| 852 | if (ep->dma && _req->length == 0) | ||
| 853 | return -EOPNOTSUPP; | ||
| 854 | |||
| 855 | /* set up dma mapping in case the caller didn't */ | ||
| 856 | if (ep->dma) { | ||
| 857 | int ret; | ||
| 858 | |||
| 859 | ret = usb_gadget_map_request(&dev->gadget, _req, | ||
| 860 | ep->is_in); | ||
| 861 | if (ret) | ||
| 862 | return ret; | ||
| 863 | } | ||
| 864 | |||
| 865 | #if 0 | ||
| 866 | VDEBUG (dev, "%s queue req %p, len %d buf %p\n", | ||
| 867 | _ep->name, _req, _req->length, _req->buf); | ||
| 868 | #endif | ||
| 869 | |||
| 870 | spin_lock_irqsave (&dev->lock, flags); | ||
| 871 | |||
| 872 | _req->status = -EINPROGRESS; | ||
| 873 | _req->actual = 0; | ||
| 874 | |||
| 875 | /* kickstart this i/o queue? */ | ||
| 876 | if (list_empty (&ep->queue) && !ep->stopped) { | ||
| 877 | /* use DMA if the endpoint supports it, else pio */ | ||
| 878 | if (ep->dma) | ||
| 879 | start_dma (ep, req); | ||
| 880 | else { | ||
| 881 | /* maybe there's no control data, just status ack */ | ||
| 882 | if (ep->num == 0 && _req->length == 0) { | ||
| 883 | allow_status (ep); | ||
| 884 | done (ep, req, 0); | ||
| 885 | VDEBUG (dev, "%s status ack\n", ep->ep.name); | ||
| 886 | goto done; | ||
| 887 | } | ||
| 888 | |||
| 889 | /* PIO ... stuff the fifo, or unblock it. */ | ||
| 890 | if (ep->is_in) | ||
| 891 | write_fifo (ep, _req); | ||
| 892 | else if (list_empty (&ep->queue)) { | ||
| 893 | u32 s; | ||
| 894 | |||
| 895 | /* OUT FIFO might have packet(s) buffered */ | ||
| 896 | s = readl (&ep->regs->ep_stat); | ||
| 897 | if ((s & (1 << FIFO_EMPTY)) == 0) { | ||
| 898 | /* note: _req->short_not_ok is | ||
| 899 | * ignored here since PIO _always_ | ||
| 900 | * stops queue advance here, and | ||
| 901 | * _req->status doesn't change for | ||
| 902 | * short reads (only _req->actual) | ||
| 903 | */ | ||
| 904 | if (read_fifo (ep, req)) { | ||
| 905 | done (ep, req, 0); | ||
| 906 | if (ep->num == 0) | ||
| 907 | allow_status (ep); | ||
| 908 | /* don't queue it */ | ||
| 909 | req = NULL; | ||
| 910 | } else | ||
| 911 | s = readl (&ep->regs->ep_stat); | ||
| 912 | } | ||
| 913 | |||
| 914 | /* don't NAK, let the fifo fill */ | ||
| 915 | if (req && (s & (1 << NAK_OUT_PACKETS))) | ||
| 916 | writel ((1 << CLEAR_NAK_OUT_PACKETS), | ||
| 917 | &ep->regs->ep_rsp); | ||
| 918 | } | ||
| 919 | } | ||
| 920 | |||
| 921 | } else if (ep->dma) { | ||
| 922 | int valid = 1; | ||
| 923 | |||
| 924 | if (ep->is_in) { | ||
| 925 | int expect; | ||
| 926 | |||
| 927 | /* preventing magic zlps is per-engine state, not | ||
| 928 | * per-transfer; irq logic must recover hiccups. | ||
| 929 | */ | ||
| 930 | expect = likely (req->req.zero | ||
| 931 | || (req->req.length % ep->ep.maxpacket) != 0); | ||
| 932 | if (expect != ep->in_fifo_validate) | ||
| 933 | valid = 0; | ||
| 934 | } | ||
| 935 | queue_dma (ep, req, valid); | ||
| 936 | |||
| 937 | } /* else the irq handler advances the queue. */ | ||
| 938 | |||
| 939 | ep->responded = 1; | ||
| 940 | if (req) | ||
| 941 | list_add_tail (&req->queue, &ep->queue); | ||
| 942 | done: | ||
| 943 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 944 | |||
| 945 | /* pci writes may still be posted */ | ||
| 946 | return 0; | ||
| 947 | } | ||
| 948 | |||
| 949 | static inline void | ||
| 950 | dma_done ( | ||
| 951 | struct net2280_ep *ep, | ||
| 952 | struct net2280_request *req, | ||
| 953 | u32 dmacount, | ||
| 954 | int status | ||
| 955 | ) | ||
| 956 | { | ||
| 957 | req->req.actual = req->req.length - (DMA_BYTE_COUNT_MASK & dmacount); | ||
| 958 | done (ep, req, status); | ||
| 959 | } | ||
| 960 | |||
| 961 | static void restart_dma (struct net2280_ep *ep); | ||
| 962 | |||
| 963 | static void scan_dma_completions (struct net2280_ep *ep) | ||
| 964 | { | ||
| 965 | /* only look at descriptors that were "naturally" retired, | ||
| 966 | * so fifo and list head state won't matter | ||
| 967 | */ | ||
| 968 | while (!list_empty (&ep->queue)) { | ||
| 969 | struct net2280_request *req; | ||
| 970 | u32 tmp; | ||
| 971 | |||
| 972 | req = list_entry (ep->queue.next, | ||
| 973 | struct net2280_request, queue); | ||
| 974 | if (!req->valid) | ||
| 975 | break; | ||
| 976 | rmb (); | ||
| 977 | tmp = le32_to_cpup (&req->td->dmacount); | ||
| 978 | if ((tmp & (1 << VALID_BIT)) != 0) | ||
| 979 | break; | ||
| 980 | |||
| 981 | /* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short" | ||
| 982 | * cases where DMA must be aborted; this code handles | ||
| 983 | * all non-abort DMA completions. | ||
| 984 | */ | ||
| 985 | if (unlikely (req->td->dmadesc == 0)) { | ||
| 986 | /* paranoia */ | ||
| 987 | tmp = readl (&ep->dma->dmacount); | ||
| 988 | if (tmp & DMA_BYTE_COUNT_MASK) | ||
| 989 | break; | ||
| 990 | /* single transfer mode */ | ||
| 991 | dma_done (ep, req, tmp, 0); | ||
| 992 | break; | ||
| 993 | } else if (!ep->is_in | ||
| 994 | && (req->req.length % ep->ep.maxpacket) != 0) { | ||
| 995 | tmp = readl (&ep->regs->ep_stat); | ||
| 996 | |||
| 997 | /* AVOID TROUBLE HERE by not issuing short reads from | ||
| 998 | * your gadget driver. That helps avoids errata 0121, | ||
| 999 | * 0122, and 0124; not all cases trigger the warning. | ||
| 1000 | */ | ||
| 1001 | if ((tmp & (1 << NAK_OUT_PACKETS)) == 0) { | ||
| 1002 | WARNING (ep->dev, "%s lost packet sync!\n", | ||
| 1003 | ep->ep.name); | ||
| 1004 | req->req.status = -EOVERFLOW; | ||
| 1005 | } else if ((tmp = readl (&ep->regs->ep_avail)) != 0) { | ||
| 1006 | /* fifo gets flushed later */ | ||
| 1007 | ep->out_overflow = 1; | ||
| 1008 | DEBUG (ep->dev, "%s dma, discard %d len %d\n", | ||
| 1009 | ep->ep.name, tmp, | ||
| 1010 | req->req.length); | ||
| 1011 | req->req.status = -EOVERFLOW; | ||
| 1012 | } | ||
| 1013 | } | ||
| 1014 | dma_done (ep, req, tmp, 0); | ||
| 1015 | } | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | static void restart_dma (struct net2280_ep *ep) | ||
| 1019 | { | ||
| 1020 | struct net2280_request *req; | ||
| 1021 | u32 dmactl = dmactl_default; | ||
| 1022 | |||
| 1023 | if (ep->stopped) | ||
| 1024 | return; | ||
| 1025 | req = list_entry (ep->queue.next, struct net2280_request, queue); | ||
| 1026 | |||
| 1027 | if (!use_dma_chaining) { | ||
| 1028 | start_dma (ep, req); | ||
| 1029 | return; | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | /* the 2280 will be processing the queue unless queue hiccups after | ||
| 1033 | * the previous transfer: | ||
| 1034 | * IN: wanted automagic zlp, head doesn't (or vice versa) | ||
| 1035 | * DMA_FIFO_VALIDATE doesn't init from dma descriptors. | ||
| 1036 | * OUT: was "usb-short", we must restart. | ||
| 1037 | */ | ||
| 1038 | if (ep->is_in && !req->valid) { | ||
| 1039 | struct net2280_request *entry, *prev = NULL; | ||
| 1040 | int reqmode, done = 0; | ||
| 1041 | |||
| 1042 | DEBUG (ep->dev, "%s dma hiccup td %p\n", ep->ep.name, req->td); | ||
| 1043 | ep->in_fifo_validate = likely (req->req.zero | ||
| 1044 | || (req->req.length % ep->ep.maxpacket) != 0); | ||
| 1045 | if (ep->in_fifo_validate) | ||
| 1046 | dmactl |= (1 << DMA_FIFO_VALIDATE); | ||
| 1047 | list_for_each_entry (entry, &ep->queue, queue) { | ||
| 1048 | __le32 dmacount; | ||
| 1049 | |||
| 1050 | if (entry == req) | ||
| 1051 | continue; | ||
| 1052 | dmacount = entry->td->dmacount; | ||
| 1053 | if (!done) { | ||
| 1054 | reqmode = likely (entry->req.zero | ||
| 1055 | || (entry->req.length | ||
| 1056 | % ep->ep.maxpacket) != 0); | ||
| 1057 | if (reqmode == ep->in_fifo_validate) { | ||
| 1058 | entry->valid = 1; | ||
| 1059 | dmacount |= valid_bit; | ||
| 1060 | entry->td->dmacount = dmacount; | ||
| 1061 | prev = entry; | ||
| 1062 | continue; | ||
| 1063 | } else { | ||
| 1064 | /* force a hiccup */ | ||
| 1065 | prev->td->dmacount |= dma_done_ie; | ||
| 1066 | done = 1; | ||
| 1067 | } | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | /* walk the rest of the queue so unlinks behave */ | ||
| 1071 | entry->valid = 0; | ||
| 1072 | dmacount &= ~valid_bit; | ||
| 1073 | entry->td->dmacount = dmacount; | ||
| 1074 | prev = entry; | ||
| 1075 | } | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | writel (0, &ep->dma->dmactl); | ||
| 1079 | start_queue (ep, dmactl, req->td_dma); | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | static void abort_dma (struct net2280_ep *ep) | ||
| 1083 | { | ||
| 1084 | /* abort the current transfer */ | ||
| 1085 | if (likely (!list_empty (&ep->queue))) { | ||
| 1086 | /* FIXME work around errata 0121, 0122, 0124 */ | ||
| 1087 | writel ((1 << DMA_ABORT), &ep->dma->dmastat); | ||
| 1088 | spin_stop_dma (ep->dma); | ||
| 1089 | } else | ||
| 1090 | stop_dma (ep->dma); | ||
| 1091 | scan_dma_completions (ep); | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | /* dequeue ALL requests */ | ||
| 1095 | static void nuke (struct net2280_ep *ep) | ||
| 1096 | { | ||
| 1097 | struct net2280_request *req; | ||
| 1098 | |||
| 1099 | /* called with spinlock held */ | ||
| 1100 | ep->stopped = 1; | ||
| 1101 | if (ep->dma) | ||
| 1102 | abort_dma (ep); | ||
| 1103 | while (!list_empty (&ep->queue)) { | ||
| 1104 | req = list_entry (ep->queue.next, | ||
| 1105 | struct net2280_request, | ||
| 1106 | queue); | ||
| 1107 | done (ep, req, -ESHUTDOWN); | ||
| 1108 | } | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | /* dequeue JUST ONE request */ | ||
| 1112 | static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req) | ||
| 1113 | { | ||
| 1114 | struct net2280_ep *ep; | ||
| 1115 | struct net2280_request *req; | ||
| 1116 | unsigned long flags; | ||
| 1117 | u32 dmactl; | ||
| 1118 | int stopped; | ||
| 1119 | |||
| 1120 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 1121 | if (!_ep || (!ep->desc && ep->num != 0) || !_req) | ||
| 1122 | return -EINVAL; | ||
| 1123 | |||
| 1124 | spin_lock_irqsave (&ep->dev->lock, flags); | ||
| 1125 | stopped = ep->stopped; | ||
| 1126 | |||
| 1127 | /* quiesce dma while we patch the queue */ | ||
| 1128 | dmactl = 0; | ||
| 1129 | ep->stopped = 1; | ||
| 1130 | if (ep->dma) { | ||
| 1131 | dmactl = readl (&ep->dma->dmactl); | ||
| 1132 | /* WARNING erratum 0127 may kick in ... */ | ||
| 1133 | stop_dma (ep->dma); | ||
| 1134 | scan_dma_completions (ep); | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | /* make sure it's still queued on this endpoint */ | ||
| 1138 | list_for_each_entry (req, &ep->queue, queue) { | ||
| 1139 | if (&req->req == _req) | ||
| 1140 | break; | ||
| 1141 | } | ||
| 1142 | if (&req->req != _req) { | ||
| 1143 | spin_unlock_irqrestore (&ep->dev->lock, flags); | ||
| 1144 | return -EINVAL; | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | /* queue head may be partially complete. */ | ||
| 1148 | if (ep->queue.next == &req->queue) { | ||
| 1149 | if (ep->dma) { | ||
| 1150 | DEBUG (ep->dev, "unlink (%s) dma\n", _ep->name); | ||
| 1151 | _req->status = -ECONNRESET; | ||
| 1152 | abort_dma (ep); | ||
| 1153 | if (likely (ep->queue.next == &req->queue)) { | ||
| 1154 | // NOTE: misreports single-transfer mode | ||
| 1155 | req->td->dmacount = 0; /* invalidate */ | ||
| 1156 | dma_done (ep, req, | ||
| 1157 | readl (&ep->dma->dmacount), | ||
| 1158 | -ECONNRESET); | ||
| 1159 | } | ||
| 1160 | } else { | ||
| 1161 | DEBUG (ep->dev, "unlink (%s) pio\n", _ep->name); | ||
| 1162 | done (ep, req, -ECONNRESET); | ||
| 1163 | } | ||
| 1164 | req = NULL; | ||
| 1165 | |||
| 1166 | /* patch up hardware chaining data */ | ||
| 1167 | } else if (ep->dma && use_dma_chaining) { | ||
| 1168 | if (req->queue.prev == ep->queue.next) { | ||
| 1169 | writel (le32_to_cpu (req->td->dmadesc), | ||
| 1170 | &ep->dma->dmadesc); | ||
| 1171 | if (req->td->dmacount & dma_done_ie) | ||
| 1172 | writel (readl (&ep->dma->dmacount) | ||
| 1173 | | le32_to_cpu(dma_done_ie), | ||
| 1174 | &ep->dma->dmacount); | ||
| 1175 | } else { | ||
| 1176 | struct net2280_request *prev; | ||
| 1177 | |||
| 1178 | prev = list_entry (req->queue.prev, | ||
| 1179 | struct net2280_request, queue); | ||
| 1180 | prev->td->dmadesc = req->td->dmadesc; | ||
| 1181 | if (req->td->dmacount & dma_done_ie) | ||
| 1182 | prev->td->dmacount |= dma_done_ie; | ||
| 1183 | } | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | if (req) | ||
| 1187 | done (ep, req, -ECONNRESET); | ||
| 1188 | ep->stopped = stopped; | ||
| 1189 | |||
| 1190 | if (ep->dma) { | ||
| 1191 | /* turn off dma on inactive queues */ | ||
| 1192 | if (list_empty (&ep->queue)) | ||
| 1193 | stop_dma (ep->dma); | ||
| 1194 | else if (!ep->stopped) { | ||
| 1195 | /* resume current request, or start new one */ | ||
| 1196 | if (req) | ||
| 1197 | writel (dmactl, &ep->dma->dmactl); | ||
| 1198 | else | ||
| 1199 | start_dma (ep, list_entry (ep->queue.next, | ||
| 1200 | struct net2280_request, queue)); | ||
| 1201 | } | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | spin_unlock_irqrestore (&ep->dev->lock, flags); | ||
| 1205 | return 0; | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | /*-------------------------------------------------------------------------*/ | ||
| 1209 | |||
| 1210 | static int net2280_fifo_status (struct usb_ep *_ep); | ||
| 1211 | |||
| 1212 | static int | ||
| 1213 | net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) | ||
| 1214 | { | ||
| 1215 | struct net2280_ep *ep; | ||
| 1216 | unsigned long flags; | ||
| 1217 | int retval = 0; | ||
| 1218 | |||
| 1219 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 1220 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1221 | return -EINVAL; | ||
| 1222 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1223 | return -ESHUTDOWN; | ||
| 1224 | if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03) | ||
| 1225 | == USB_ENDPOINT_XFER_ISOC) | ||
| 1226 | return -EINVAL; | ||
| 1227 | |||
| 1228 | spin_lock_irqsave (&ep->dev->lock, flags); | ||
| 1229 | if (!list_empty (&ep->queue)) | ||
| 1230 | retval = -EAGAIN; | ||
| 1231 | else if (ep->is_in && value && net2280_fifo_status (_ep) != 0) | ||
| 1232 | retval = -EAGAIN; | ||
| 1233 | else { | ||
| 1234 | VDEBUG (ep->dev, "%s %s %s\n", _ep->name, | ||
| 1235 | value ? "set" : "clear", | ||
| 1236 | wedged ? "wedge" : "halt"); | ||
| 1237 | /* set/clear, then synch memory views with the device */ | ||
| 1238 | if (value) { | ||
| 1239 | if (ep->num == 0) | ||
| 1240 | ep->dev->protocol_stall = 1; | ||
| 1241 | else | ||
| 1242 | set_halt (ep); | ||
| 1243 | if (wedged) | ||
| 1244 | ep->wedged = 1; | ||
| 1245 | } else { | ||
| 1246 | clear_halt (ep); | ||
| 1247 | ep->wedged = 0; | ||
| 1248 | } | ||
| 1249 | (void) readl (&ep->regs->ep_rsp); | ||
| 1250 | } | ||
| 1251 | spin_unlock_irqrestore (&ep->dev->lock, flags); | ||
| 1252 | |||
| 1253 | return retval; | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | static int | ||
| 1257 | net2280_set_halt(struct usb_ep *_ep, int value) | ||
| 1258 | { | ||
| 1259 | return net2280_set_halt_and_wedge(_ep, value, 0); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | static int | ||
| 1263 | net2280_set_wedge(struct usb_ep *_ep) | ||
| 1264 | { | ||
| 1265 | if (!_ep || _ep->name == ep0name) | ||
| 1266 | return -EINVAL; | ||
| 1267 | return net2280_set_halt_and_wedge(_ep, 1, 1); | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | static int | ||
| 1271 | net2280_fifo_status (struct usb_ep *_ep) | ||
| 1272 | { | ||
| 1273 | struct net2280_ep *ep; | ||
| 1274 | u32 avail; | ||
| 1275 | |||
| 1276 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 1277 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1278 | return -ENODEV; | ||
| 1279 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1280 | return -ESHUTDOWN; | ||
| 1281 | |||
| 1282 | avail = readl (&ep->regs->ep_avail) & ((1 << 12) - 1); | ||
| 1283 | if (avail > ep->fifo_size) | ||
| 1284 | return -EOVERFLOW; | ||
| 1285 | if (ep->is_in) | ||
| 1286 | avail = ep->fifo_size - avail; | ||
| 1287 | return avail; | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | static void | ||
| 1291 | net2280_fifo_flush (struct usb_ep *_ep) | ||
| 1292 | { | ||
| 1293 | struct net2280_ep *ep; | ||
| 1294 | |||
| 1295 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 1296 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1297 | return; | ||
| 1298 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1299 | return; | ||
| 1300 | |||
| 1301 | writel ((1 << FIFO_FLUSH), &ep->regs->ep_stat); | ||
| 1302 | (void) readl (&ep->regs->ep_rsp); | ||
| 1303 | } | ||
| 1304 | |||
| 1305 | static const struct usb_ep_ops net2280_ep_ops = { | ||
| 1306 | .enable = net2280_enable, | ||
| 1307 | .disable = net2280_disable, | ||
| 1308 | |||
| 1309 | .alloc_request = net2280_alloc_request, | ||
| 1310 | .free_request = net2280_free_request, | ||
| 1311 | |||
| 1312 | .queue = net2280_queue, | ||
| 1313 | .dequeue = net2280_dequeue, | ||
| 1314 | |||
| 1315 | .set_halt = net2280_set_halt, | ||
| 1316 | .set_wedge = net2280_set_wedge, | ||
| 1317 | .fifo_status = net2280_fifo_status, | ||
| 1318 | .fifo_flush = net2280_fifo_flush, | ||
| 1319 | }; | ||
| 1320 | |||
| 1321 | /*-------------------------------------------------------------------------*/ | ||
| 1322 | |||
| 1323 | static int net2280_get_frame (struct usb_gadget *_gadget) | ||
| 1324 | { | ||
| 1325 | struct net2280 *dev; | ||
| 1326 | unsigned long flags; | ||
| 1327 | u16 retval; | ||
| 1328 | |||
| 1329 | if (!_gadget) | ||
| 1330 | return -ENODEV; | ||
| 1331 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1332 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1333 | retval = get_idx_reg (dev->regs, REG_FRAME) & 0x03ff; | ||
| 1334 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1335 | return retval; | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | static int net2280_wakeup (struct usb_gadget *_gadget) | ||
| 1339 | { | ||
| 1340 | struct net2280 *dev; | ||
| 1341 | u32 tmp; | ||
| 1342 | unsigned long flags; | ||
| 1343 | |||
| 1344 | if (!_gadget) | ||
| 1345 | return 0; | ||
| 1346 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1347 | |||
| 1348 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1349 | tmp = readl (&dev->usb->usbctl); | ||
| 1350 | if (tmp & (1 << DEVICE_REMOTE_WAKEUP_ENABLE)) | ||
| 1351 | writel (1 << GENERATE_RESUME, &dev->usb->usbstat); | ||
| 1352 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1353 | |||
| 1354 | /* pci writes may still be posted */ | ||
| 1355 | return 0; | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | static int net2280_set_selfpowered (struct usb_gadget *_gadget, int value) | ||
| 1359 | { | ||
| 1360 | struct net2280 *dev; | ||
| 1361 | u32 tmp; | ||
| 1362 | unsigned long flags; | ||
| 1363 | |||
| 1364 | if (!_gadget) | ||
| 1365 | return 0; | ||
| 1366 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1367 | |||
| 1368 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1369 | tmp = readl (&dev->usb->usbctl); | ||
| 1370 | if (value) | ||
| 1371 | tmp |= (1 << SELF_POWERED_STATUS); | ||
| 1372 | else | ||
| 1373 | tmp &= ~(1 << SELF_POWERED_STATUS); | ||
| 1374 | writel (tmp, &dev->usb->usbctl); | ||
| 1375 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1376 | |||
| 1377 | return 0; | ||
| 1378 | } | ||
| 1379 | |||
| 1380 | static int net2280_pullup(struct usb_gadget *_gadget, int is_on) | ||
| 1381 | { | ||
| 1382 | struct net2280 *dev; | ||
| 1383 | u32 tmp; | ||
| 1384 | unsigned long flags; | ||
| 1385 | |||
| 1386 | if (!_gadget) | ||
| 1387 | return -ENODEV; | ||
| 1388 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1389 | |||
| 1390 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1391 | tmp = readl (&dev->usb->usbctl); | ||
| 1392 | dev->softconnect = (is_on != 0); | ||
| 1393 | if (is_on) | ||
| 1394 | tmp |= (1 << USB_DETECT_ENABLE); | ||
| 1395 | else | ||
| 1396 | tmp &= ~(1 << USB_DETECT_ENABLE); | ||
| 1397 | writel (tmp, &dev->usb->usbctl); | ||
| 1398 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1399 | |||
| 1400 | return 0; | ||
| 1401 | } | ||
| 1402 | |||
| 1403 | static int net2280_start(struct usb_gadget *_gadget, | ||
| 1404 | struct usb_gadget_driver *driver); | ||
| 1405 | static int net2280_stop(struct usb_gadget *_gadget, | ||
| 1406 | struct usb_gadget_driver *driver); | ||
| 1407 | |||
| 1408 | static const struct usb_gadget_ops net2280_ops = { | ||
| 1409 | .get_frame = net2280_get_frame, | ||
| 1410 | .wakeup = net2280_wakeup, | ||
| 1411 | .set_selfpowered = net2280_set_selfpowered, | ||
| 1412 | .pullup = net2280_pullup, | ||
| 1413 | .udc_start = net2280_start, | ||
| 1414 | .udc_stop = net2280_stop, | ||
| 1415 | }; | ||
| 1416 | |||
| 1417 | /*-------------------------------------------------------------------------*/ | ||
| 1418 | |||
| 1419 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
| 1420 | |||
| 1421 | /* FIXME move these into procfs, and use seq_file. | ||
| 1422 | * Sysfs _still_ doesn't behave for arbitrarily sized files, | ||
| 1423 | * and also doesn't help products using this with 2.4 kernels. | ||
| 1424 | */ | ||
| 1425 | |||
| 1426 | /* "function" sysfs attribute */ | ||
| 1427 | static ssize_t function_show(struct device *_dev, struct device_attribute *attr, | ||
| 1428 | char *buf) | ||
| 1429 | { | ||
| 1430 | struct net2280 *dev = dev_get_drvdata (_dev); | ||
| 1431 | |||
| 1432 | if (!dev->driver | ||
| 1433 | || !dev->driver->function | ||
| 1434 | || strlen (dev->driver->function) > PAGE_SIZE) | ||
| 1435 | return 0; | ||
| 1436 | return scnprintf (buf, PAGE_SIZE, "%s\n", dev->driver->function); | ||
| 1437 | } | ||
| 1438 | static DEVICE_ATTR_RO(function); | ||
| 1439 | |||
| 1440 | static ssize_t registers_show(struct device *_dev, | ||
| 1441 | struct device_attribute *attr, char *buf) | ||
| 1442 | { | ||
| 1443 | struct net2280 *dev; | ||
| 1444 | char *next; | ||
| 1445 | unsigned size, t; | ||
| 1446 | unsigned long flags; | ||
| 1447 | int i; | ||
| 1448 | u32 t1, t2; | ||
| 1449 | const char *s; | ||
| 1450 | |||
| 1451 | dev = dev_get_drvdata (_dev); | ||
| 1452 | next = buf; | ||
| 1453 | size = PAGE_SIZE; | ||
| 1454 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1455 | |||
| 1456 | if (dev->driver) | ||
| 1457 | s = dev->driver->driver.name; | ||
| 1458 | else | ||
| 1459 | s = "(none)"; | ||
| 1460 | |||
| 1461 | /* Main Control Registers */ | ||
| 1462 | t = scnprintf (next, size, "%s version " DRIVER_VERSION | ||
| 1463 | ", chiprev %04x, dma %s\n\n" | ||
| 1464 | "devinit %03x fifoctl %08x gadget '%s'\n" | ||
| 1465 | "pci irqenb0 %02x irqenb1 %08x " | ||
| 1466 | "irqstat0 %04x irqstat1 %08x\n", | ||
| 1467 | driver_name, dev->chiprev, | ||
| 1468 | use_dma | ||
| 1469 | ? (use_dma_chaining ? "chaining" : "enabled") | ||
| 1470 | : "disabled", | ||
| 1471 | readl (&dev->regs->devinit), | ||
| 1472 | readl (&dev->regs->fifoctl), | ||
| 1473 | s, | ||
| 1474 | readl (&dev->regs->pciirqenb0), | ||
| 1475 | readl (&dev->regs->pciirqenb1), | ||
| 1476 | readl (&dev->regs->irqstat0), | ||
| 1477 | readl (&dev->regs->irqstat1)); | ||
| 1478 | size -= t; | ||
| 1479 | next += t; | ||
| 1480 | |||
| 1481 | /* USB Control Registers */ | ||
| 1482 | t1 = readl (&dev->usb->usbctl); | ||
| 1483 | t2 = readl (&dev->usb->usbstat); | ||
| 1484 | if (t1 & (1 << VBUS_PIN)) { | ||
| 1485 | if (t2 & (1 << HIGH_SPEED)) | ||
| 1486 | s = "high speed"; | ||
| 1487 | else if (dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1488 | s = "powered"; | ||
| 1489 | else | ||
| 1490 | s = "full speed"; | ||
| 1491 | /* full speed bit (6) not working?? */ | ||
| 1492 | } else | ||
| 1493 | s = "not attached"; | ||
| 1494 | t = scnprintf (next, size, | ||
| 1495 | "stdrsp %08x usbctl %08x usbstat %08x " | ||
| 1496 | "addr 0x%02x (%s)\n", | ||
| 1497 | readl (&dev->usb->stdrsp), t1, t2, | ||
| 1498 | readl (&dev->usb->ouraddr), s); | ||
| 1499 | size -= t; | ||
| 1500 | next += t; | ||
| 1501 | |||
| 1502 | /* PCI Master Control Registers */ | ||
| 1503 | |||
| 1504 | /* DMA Control Registers */ | ||
| 1505 | |||
| 1506 | /* Configurable EP Control Registers */ | ||
| 1507 | for (i = 0; i < 7; i++) { | ||
| 1508 | struct net2280_ep *ep; | ||
| 1509 | |||
| 1510 | ep = &dev->ep [i]; | ||
| 1511 | if (i && !ep->desc) | ||
| 1512 | continue; | ||
| 1513 | |||
| 1514 | t1 = readl (&ep->regs->ep_cfg); | ||
| 1515 | t2 = readl (&ep->regs->ep_rsp) & 0xff; | ||
| 1516 | t = scnprintf (next, size, | ||
| 1517 | "\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s" | ||
| 1518 | "irqenb %02x\n", | ||
| 1519 | ep->ep.name, t1, t2, | ||
| 1520 | (t2 & (1 << CLEAR_NAK_OUT_PACKETS)) | ||
| 1521 | ? "NAK " : "", | ||
| 1522 | (t2 & (1 << CLEAR_EP_HIDE_STATUS_PHASE)) | ||
| 1523 | ? "hide " : "", | ||
| 1524 | (t2 & (1 << CLEAR_EP_FORCE_CRC_ERROR)) | ||
| 1525 | ? "CRC " : "", | ||
| 1526 | (t2 & (1 << CLEAR_INTERRUPT_MODE)) | ||
| 1527 | ? "interrupt " : "", | ||
| 1528 | (t2 & (1<<CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)) | ||
| 1529 | ? "status " : "", | ||
| 1530 | (t2 & (1 << CLEAR_NAK_OUT_PACKETS_MODE)) | ||
| 1531 | ? "NAKmode " : "", | ||
| 1532 | (t2 & (1 << CLEAR_ENDPOINT_TOGGLE)) | ||
| 1533 | ? "DATA1 " : "DATA0 ", | ||
| 1534 | (t2 & (1 << CLEAR_ENDPOINT_HALT)) | ||
| 1535 | ? "HALT " : "", | ||
| 1536 | readl (&ep->regs->ep_irqenb)); | ||
| 1537 | size -= t; | ||
| 1538 | next += t; | ||
| 1539 | |||
| 1540 | t = scnprintf (next, size, | ||
| 1541 | "\tstat %08x avail %04x " | ||
| 1542 | "(ep%d%s-%s)%s\n", | ||
| 1543 | readl (&ep->regs->ep_stat), | ||
| 1544 | readl (&ep->regs->ep_avail), | ||
| 1545 | t1 & 0x0f, DIR_STRING (t1), | ||
| 1546 | type_string (t1 >> 8), | ||
| 1547 | ep->stopped ? "*" : ""); | ||
| 1548 | size -= t; | ||
| 1549 | next += t; | ||
| 1550 | |||
| 1551 | if (!ep->dma) | ||
| 1552 | continue; | ||
| 1553 | |||
| 1554 | t = scnprintf (next, size, | ||
| 1555 | " dma\tctl %08x stat %08x count %08x\n" | ||
| 1556 | "\taddr %08x desc %08x\n", | ||
| 1557 | readl (&ep->dma->dmactl), | ||
| 1558 | readl (&ep->dma->dmastat), | ||
| 1559 | readl (&ep->dma->dmacount), | ||
| 1560 | readl (&ep->dma->dmaaddr), | ||
| 1561 | readl (&ep->dma->dmadesc)); | ||
| 1562 | size -= t; | ||
| 1563 | next += t; | ||
| 1564 | |||
| 1565 | } | ||
| 1566 | |||
| 1567 | /* Indexed Registers */ | ||
| 1568 | // none yet | ||
| 1569 | |||
| 1570 | /* Statistics */ | ||
| 1571 | t = scnprintf (next, size, "\nirqs: "); | ||
| 1572 | size -= t; | ||
| 1573 | next += t; | ||
| 1574 | for (i = 0; i < 7; i++) { | ||
| 1575 | struct net2280_ep *ep; | ||
| 1576 | |||
| 1577 | ep = &dev->ep [i]; | ||
| 1578 | if (i && !ep->irqs) | ||
| 1579 | continue; | ||
| 1580 | t = scnprintf (next, size, " %s/%lu", ep->ep.name, ep->irqs); | ||
| 1581 | size -= t; | ||
| 1582 | next += t; | ||
| 1583 | |||
| 1584 | } | ||
| 1585 | t = scnprintf (next, size, "\n"); | ||
| 1586 | size -= t; | ||
| 1587 | next += t; | ||
| 1588 | |||
| 1589 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1590 | |||
| 1591 | return PAGE_SIZE - size; | ||
| 1592 | } | ||
| 1593 | static DEVICE_ATTR_RO(registers); | ||
| 1594 | |||
| 1595 | static ssize_t queues_show(struct device *_dev, struct device_attribute *attr, | ||
| 1596 | char *buf) | ||
| 1597 | { | ||
| 1598 | struct net2280 *dev; | ||
| 1599 | char *next; | ||
| 1600 | unsigned size; | ||
| 1601 | unsigned long flags; | ||
| 1602 | int i; | ||
| 1603 | |||
| 1604 | dev = dev_get_drvdata (_dev); | ||
| 1605 | next = buf; | ||
| 1606 | size = PAGE_SIZE; | ||
| 1607 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1608 | |||
| 1609 | for (i = 0; i < 7; i++) { | ||
| 1610 | struct net2280_ep *ep = &dev->ep [i]; | ||
| 1611 | struct net2280_request *req; | ||
| 1612 | int t; | ||
| 1613 | |||
| 1614 | if (i != 0) { | ||
| 1615 | const struct usb_endpoint_descriptor *d; | ||
| 1616 | |||
| 1617 | d = ep->desc; | ||
| 1618 | if (!d) | ||
| 1619 | continue; | ||
| 1620 | t = d->bEndpointAddress; | ||
| 1621 | t = scnprintf (next, size, | ||
| 1622 | "\n%s (ep%d%s-%s) max %04x %s fifo %d\n", | ||
| 1623 | ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK, | ||
| 1624 | (t & USB_DIR_IN) ? "in" : "out", | ||
| 1625 | ({ char *val; | ||
| 1626 | switch (d->bmAttributes & 0x03) { | ||
| 1627 | case USB_ENDPOINT_XFER_BULK: | ||
| 1628 | val = "bulk"; break; | ||
| 1629 | case USB_ENDPOINT_XFER_INT: | ||
| 1630 | val = "intr"; break; | ||
| 1631 | default: | ||
| 1632 | val = "iso"; break; | ||
| 1633 | } val; }), | ||
| 1634 | usb_endpoint_maxp (d) & 0x1fff, | ||
| 1635 | ep->dma ? "dma" : "pio", ep->fifo_size | ||
| 1636 | ); | ||
| 1637 | } else /* ep0 should only have one transfer queued */ | ||
| 1638 | t = scnprintf (next, size, "ep0 max 64 pio %s\n", | ||
| 1639 | ep->is_in ? "in" : "out"); | ||
| 1640 | if (t <= 0 || t > size) | ||
| 1641 | goto done; | ||
| 1642 | size -= t; | ||
| 1643 | next += t; | ||
| 1644 | |||
| 1645 | if (list_empty (&ep->queue)) { | ||
| 1646 | t = scnprintf (next, size, "\t(nothing queued)\n"); | ||
| 1647 | if (t <= 0 || t > size) | ||
| 1648 | goto done; | ||
| 1649 | size -= t; | ||
| 1650 | next += t; | ||
| 1651 | continue; | ||
| 1652 | } | ||
| 1653 | list_for_each_entry (req, &ep->queue, queue) { | ||
| 1654 | if (ep->dma && req->td_dma == readl (&ep->dma->dmadesc)) | ||
| 1655 | t = scnprintf (next, size, | ||
| 1656 | "\treq %p len %d/%d " | ||
| 1657 | "buf %p (dmacount %08x)\n", | ||
| 1658 | &req->req, req->req.actual, | ||
| 1659 | req->req.length, req->req.buf, | ||
| 1660 | readl (&ep->dma->dmacount)); | ||
| 1661 | else | ||
| 1662 | t = scnprintf (next, size, | ||
| 1663 | "\treq %p len %d/%d buf %p\n", | ||
| 1664 | &req->req, req->req.actual, | ||
| 1665 | req->req.length, req->req.buf); | ||
| 1666 | if (t <= 0 || t > size) | ||
| 1667 | goto done; | ||
| 1668 | size -= t; | ||
| 1669 | next += t; | ||
| 1670 | |||
| 1671 | if (ep->dma) { | ||
| 1672 | struct net2280_dma *td; | ||
| 1673 | |||
| 1674 | td = req->td; | ||
| 1675 | t = scnprintf (next, size, "\t td %08x " | ||
| 1676 | " count %08x buf %08x desc %08x\n", | ||
| 1677 | (u32) req->td_dma, | ||
| 1678 | le32_to_cpu (td->dmacount), | ||
| 1679 | le32_to_cpu (td->dmaaddr), | ||
| 1680 | le32_to_cpu (td->dmadesc)); | ||
| 1681 | if (t <= 0 || t > size) | ||
| 1682 | goto done; | ||
| 1683 | size -= t; | ||
| 1684 | next += t; | ||
| 1685 | } | ||
| 1686 | } | ||
| 1687 | } | ||
| 1688 | |||
| 1689 | done: | ||
| 1690 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1691 | return PAGE_SIZE - size; | ||
| 1692 | } | ||
| 1693 | static DEVICE_ATTR_RO(queues); | ||
| 1694 | |||
| 1695 | |||
| 1696 | #else | ||
| 1697 | |||
| 1698 | #define device_create_file(a,b) (0) | ||
| 1699 | #define device_remove_file(a,b) do { } while (0) | ||
| 1700 | |||
| 1701 | #endif | ||
| 1702 | |||
| 1703 | /*-------------------------------------------------------------------------*/ | ||
| 1704 | |||
| 1705 | /* another driver-specific mode might be a request type doing dma | ||
| 1706 | * to/from another device fifo instead of to/from memory. | ||
| 1707 | */ | ||
| 1708 | |||
| 1709 | static void set_fifo_mode (struct net2280 *dev, int mode) | ||
| 1710 | { | ||
| 1711 | /* keeping high bits preserves BAR2 */ | ||
| 1712 | writel ((0xffff << PCI_BASE2_RANGE) | mode, &dev->regs->fifoctl); | ||
| 1713 | |||
| 1714 | /* always ep-{a,b,e,f} ... maybe not ep-c or ep-d */ | ||
| 1715 | INIT_LIST_HEAD (&dev->gadget.ep_list); | ||
| 1716 | list_add_tail (&dev->ep [1].ep.ep_list, &dev->gadget.ep_list); | ||
| 1717 | list_add_tail (&dev->ep [2].ep.ep_list, &dev->gadget.ep_list); | ||
| 1718 | switch (mode) { | ||
| 1719 | case 0: | ||
| 1720 | list_add_tail (&dev->ep [3].ep.ep_list, &dev->gadget.ep_list); | ||
| 1721 | list_add_tail (&dev->ep [4].ep.ep_list, &dev->gadget.ep_list); | ||
| 1722 | dev->ep [1].fifo_size = dev->ep [2].fifo_size = 1024; | ||
| 1723 | break; | ||
| 1724 | case 1: | ||
| 1725 | dev->ep [1].fifo_size = dev->ep [2].fifo_size = 2048; | ||
| 1726 | break; | ||
| 1727 | case 2: | ||
| 1728 | list_add_tail (&dev->ep [3].ep.ep_list, &dev->gadget.ep_list); | ||
| 1729 | dev->ep [1].fifo_size = 2048; | ||
| 1730 | dev->ep [2].fifo_size = 1024; | ||
| 1731 | break; | ||
| 1732 | } | ||
| 1733 | /* fifo sizes for ep0, ep-c, ep-d, ep-e, and ep-f never change */ | ||
| 1734 | list_add_tail (&dev->ep [5].ep.ep_list, &dev->gadget.ep_list); | ||
| 1735 | list_add_tail (&dev->ep [6].ep.ep_list, &dev->gadget.ep_list); | ||
| 1736 | } | ||
| 1737 | |||
| 1738 | /* keeping it simple: | ||
| 1739 | * - one bus driver, initted first; | ||
| 1740 | * - one function driver, initted second | ||
| 1741 | * | ||
| 1742 | * most of the work to support multiple net2280 controllers would | ||
| 1743 | * be to associate this gadget driver (yes?) with all of them, or | ||
| 1744 | * perhaps to bind specific drivers to specific devices. | ||
| 1745 | */ | ||
| 1746 | |||
| 1747 | static void usb_reset (struct net2280 *dev) | ||
| 1748 | { | ||
| 1749 | u32 tmp; | ||
| 1750 | |||
| 1751 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1752 | (void) readl (&dev->usb->usbctl); | ||
| 1753 | |||
| 1754 | net2280_led_init (dev); | ||
| 1755 | |||
| 1756 | /* disable automatic responses, and irqs */ | ||
| 1757 | writel (0, &dev->usb->stdrsp); | ||
| 1758 | writel (0, &dev->regs->pciirqenb0); | ||
| 1759 | writel (0, &dev->regs->pciirqenb1); | ||
| 1760 | |||
| 1761 | /* clear old dma and irq state */ | ||
| 1762 | for (tmp = 0; tmp < 4; tmp++) { | ||
| 1763 | struct net2280_ep *ep = &dev->ep [tmp + 1]; | ||
| 1764 | |||
| 1765 | if (ep->dma) | ||
| 1766 | abort_dma (ep); | ||
| 1767 | } | ||
| 1768 | writel (~0, &dev->regs->irqstat0), | ||
| 1769 | writel (~(1 << SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1), | ||
| 1770 | |||
| 1771 | /* reset, and enable pci */ | ||
| 1772 | tmp = readl (&dev->regs->devinit) | ||
| 1773 | | (1 << PCI_ENABLE) | ||
| 1774 | | (1 << FIFO_SOFT_RESET) | ||
| 1775 | | (1 << USB_SOFT_RESET) | ||
| 1776 | | (1 << M8051_RESET); | ||
| 1777 | writel (tmp, &dev->regs->devinit); | ||
| 1778 | |||
| 1779 | /* standard fifo and endpoint allocations */ | ||
| 1780 | set_fifo_mode (dev, (fifo_mode <= 2) ? fifo_mode : 0); | ||
| 1781 | } | ||
| 1782 | |||
| 1783 | static void usb_reinit (struct net2280 *dev) | ||
| 1784 | { | ||
| 1785 | u32 tmp; | ||
| 1786 | int init_dma; | ||
| 1787 | |||
| 1788 | /* use_dma changes are ignored till next device re-init */ | ||
| 1789 | init_dma = use_dma; | ||
| 1790 | |||
| 1791 | /* basic endpoint init */ | ||
| 1792 | for (tmp = 0; tmp < 7; tmp++) { | ||
| 1793 | struct net2280_ep *ep = &dev->ep [tmp]; | ||
| 1794 | |||
| 1795 | ep->ep.name = ep_name [tmp]; | ||
| 1796 | ep->dev = dev; | ||
| 1797 | ep->num = tmp; | ||
| 1798 | |||
| 1799 | if (tmp > 0 && tmp <= 4) { | ||
| 1800 | ep->fifo_size = 1024; | ||
| 1801 | if (init_dma) | ||
| 1802 | ep->dma = &dev->dma [tmp - 1]; | ||
| 1803 | } else | ||
| 1804 | ep->fifo_size = 64; | ||
| 1805 | ep->regs = &dev->epregs [tmp]; | ||
| 1806 | ep_reset (dev->regs, ep); | ||
| 1807 | } | ||
| 1808 | usb_ep_set_maxpacket_limit(&dev->ep [0].ep, 64); | ||
| 1809 | usb_ep_set_maxpacket_limit(&dev->ep [5].ep, 64); | ||
| 1810 | usb_ep_set_maxpacket_limit(&dev->ep [6].ep, 64); | ||
| 1811 | |||
| 1812 | dev->gadget.ep0 = &dev->ep [0].ep; | ||
| 1813 | dev->ep [0].stopped = 0; | ||
| 1814 | INIT_LIST_HEAD (&dev->gadget.ep0->ep_list); | ||
| 1815 | |||
| 1816 | /* we want to prevent lowlevel/insecure access from the USB host, | ||
| 1817 | * but erratum 0119 means this enable bit is ignored | ||
| 1818 | */ | ||
| 1819 | for (tmp = 0; tmp < 5; tmp++) | ||
| 1820 | writel (EP_DONTUSE, &dev->dep [tmp].dep_cfg); | ||
| 1821 | } | ||
| 1822 | |||
| 1823 | static void ep0_start (struct net2280 *dev) | ||
| 1824 | { | ||
| 1825 | writel ( (1 << CLEAR_EP_HIDE_STATUS_PHASE) | ||
| 1826 | | (1 << CLEAR_NAK_OUT_PACKETS) | ||
| 1827 | | (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) | ||
| 1828 | , &dev->epregs [0].ep_rsp); | ||
| 1829 | |||
| 1830 | /* | ||
| 1831 | * hardware optionally handles a bunch of standard requests | ||
| 1832 | * that the API hides from drivers anyway. have it do so. | ||
| 1833 | * endpoint status/features are handled in software, to | ||
| 1834 | * help pass tests for some dubious behavior. | ||
| 1835 | */ | ||
| 1836 | writel ( (1 << SET_TEST_MODE) | ||
| 1837 | | (1 << SET_ADDRESS) | ||
| 1838 | | (1 << DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP) | ||
| 1839 | | (1 << GET_DEVICE_STATUS) | ||
| 1840 | | (1 << GET_INTERFACE_STATUS) | ||
| 1841 | , &dev->usb->stdrsp); | ||
| 1842 | writel ( (1 << USB_ROOT_PORT_WAKEUP_ENABLE) | ||
| 1843 | | (1 << SELF_POWERED_USB_DEVICE) | ||
| 1844 | | (1 << REMOTE_WAKEUP_SUPPORT) | ||
| 1845 | | (dev->softconnect << USB_DETECT_ENABLE) | ||
| 1846 | | (1 << SELF_POWERED_STATUS) | ||
| 1847 | , &dev->usb->usbctl); | ||
| 1848 | |||
| 1849 | /* enable irqs so we can see ep0 and general operation */ | ||
| 1850 | writel ( (1 << SETUP_PACKET_INTERRUPT_ENABLE) | ||
| 1851 | | (1 << ENDPOINT_0_INTERRUPT_ENABLE) | ||
| 1852 | , &dev->regs->pciirqenb0); | ||
| 1853 | writel ( (1 << PCI_INTERRUPT_ENABLE) | ||
| 1854 | | (1 << PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE) | ||
| 1855 | | (1 << PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE) | ||
| 1856 | | (1 << PCI_RETRY_ABORT_INTERRUPT_ENABLE) | ||
| 1857 | | (1 << VBUS_INTERRUPT_ENABLE) | ||
| 1858 | | (1 << ROOT_PORT_RESET_INTERRUPT_ENABLE) | ||
| 1859 | | (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE) | ||
| 1860 | , &dev->regs->pciirqenb1); | ||
| 1861 | |||
| 1862 | /* don't leave any writes posted */ | ||
| 1863 | (void) readl (&dev->usb->usbctl); | ||
| 1864 | } | ||
| 1865 | |||
| 1866 | /* when a driver is successfully registered, it will receive | ||
| 1867 | * control requests including set_configuration(), which enables | ||
| 1868 | * non-control requests. then usb traffic follows until a | ||
| 1869 | * disconnect is reported. then a host may connect again, or | ||
| 1870 | * the driver might get unbound. | ||
| 1871 | */ | ||
| 1872 | static int net2280_start(struct usb_gadget *_gadget, | ||
| 1873 | struct usb_gadget_driver *driver) | ||
| 1874 | { | ||
| 1875 | struct net2280 *dev; | ||
| 1876 | int retval; | ||
| 1877 | unsigned i; | ||
| 1878 | |||
| 1879 | /* insist on high speed support from the driver, since | ||
| 1880 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) | ||
| 1881 | * "must not be used in normal operation" | ||
| 1882 | */ | ||
| 1883 | if (!driver || driver->max_speed < USB_SPEED_HIGH | ||
| 1884 | || !driver->setup) | ||
| 1885 | return -EINVAL; | ||
| 1886 | |||
| 1887 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1888 | |||
| 1889 | for (i = 0; i < 7; i++) | ||
| 1890 | dev->ep [i].irqs = 0; | ||
| 1891 | |||
| 1892 | /* hook up the driver ... */ | ||
| 1893 | dev->softconnect = 1; | ||
| 1894 | driver->driver.bus = NULL; | ||
| 1895 | dev->driver = driver; | ||
| 1896 | |||
| 1897 | retval = device_create_file (&dev->pdev->dev, &dev_attr_function); | ||
| 1898 | if (retval) goto err_unbind; | ||
| 1899 | retval = device_create_file (&dev->pdev->dev, &dev_attr_queues); | ||
| 1900 | if (retval) goto err_func; | ||
| 1901 | |||
| 1902 | /* Enable force-full-speed testing mode, if desired */ | ||
| 1903 | if (full_speed) | ||
| 1904 | writel(1 << FORCE_FULL_SPEED_MODE, &dev->usb->xcvrdiag); | ||
| 1905 | |||
| 1906 | /* ... then enable host detection and ep0; and we're ready | ||
| 1907 | * for set_configuration as well as eventual disconnect. | ||
| 1908 | */ | ||
| 1909 | net2280_led_active (dev, 1); | ||
| 1910 | ep0_start (dev); | ||
| 1911 | |||
| 1912 | DEBUG (dev, "%s ready, usbctl %08x stdrsp %08x\n", | ||
| 1913 | driver->driver.name, | ||
| 1914 | readl (&dev->usb->usbctl), | ||
| 1915 | readl (&dev->usb->stdrsp)); | ||
| 1916 | |||
| 1917 | /* pci writes may still be posted */ | ||
| 1918 | return 0; | ||
| 1919 | |||
| 1920 | err_func: | ||
| 1921 | device_remove_file (&dev->pdev->dev, &dev_attr_function); | ||
| 1922 | err_unbind: | ||
| 1923 | dev->driver = NULL; | ||
| 1924 | return retval; | ||
| 1925 | } | ||
| 1926 | |||
| 1927 | static void | ||
| 1928 | stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver) | ||
| 1929 | { | ||
| 1930 | int i; | ||
| 1931 | |||
| 1932 | /* don't disconnect if it's not connected */ | ||
| 1933 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1934 | driver = NULL; | ||
| 1935 | |||
| 1936 | /* stop hardware; prevent new request submissions; | ||
| 1937 | * and kill any outstanding requests. | ||
| 1938 | */ | ||
| 1939 | usb_reset (dev); | ||
| 1940 | for (i = 0; i < 7; i++) | ||
| 1941 | nuke (&dev->ep [i]); | ||
| 1942 | |||
| 1943 | /* report disconnect; the driver is already quiesced */ | ||
| 1944 | if (driver) { | ||
| 1945 | spin_unlock(&dev->lock); | ||
| 1946 | driver->disconnect(&dev->gadget); | ||
| 1947 | spin_lock(&dev->lock); | ||
| 1948 | } | ||
| 1949 | |||
| 1950 | usb_reinit (dev); | ||
| 1951 | } | ||
| 1952 | |||
| 1953 | static int net2280_stop(struct usb_gadget *_gadget, | ||
| 1954 | struct usb_gadget_driver *driver) | ||
| 1955 | { | ||
| 1956 | struct net2280 *dev; | ||
| 1957 | unsigned long flags; | ||
| 1958 | |||
| 1959 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1960 | |||
| 1961 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1962 | stop_activity (dev, driver); | ||
| 1963 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1964 | |||
| 1965 | dev->driver = NULL; | ||
| 1966 | |||
| 1967 | net2280_led_active (dev, 0); | ||
| 1968 | |||
| 1969 | /* Disable full-speed test mode */ | ||
| 1970 | writel(0, &dev->usb->xcvrdiag); | ||
| 1971 | |||
| 1972 | device_remove_file (&dev->pdev->dev, &dev_attr_function); | ||
| 1973 | device_remove_file (&dev->pdev->dev, &dev_attr_queues); | ||
| 1974 | |||
| 1975 | DEBUG(dev, "unregistered driver '%s'\n", | ||
| 1976 | driver ? driver->driver.name : ""); | ||
| 1977 | |||
| 1978 | return 0; | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | /*-------------------------------------------------------------------------*/ | ||
| 1982 | |||
| 1983 | /* handle ep0, ep-e, ep-f with 64 byte packets: packet per irq. | ||
| 1984 | * also works for dma-capable endpoints, in pio mode or just | ||
| 1985 | * to manually advance the queue after short OUT transfers. | ||
| 1986 | */ | ||
| 1987 | static void handle_ep_small (struct net2280_ep *ep) | ||
| 1988 | { | ||
| 1989 | struct net2280_request *req; | ||
| 1990 | u32 t; | ||
| 1991 | /* 0 error, 1 mid-data, 2 done */ | ||
| 1992 | int mode = 1; | ||
| 1993 | |||
| 1994 | if (!list_empty (&ep->queue)) | ||
| 1995 | req = list_entry (ep->queue.next, | ||
| 1996 | struct net2280_request, queue); | ||
| 1997 | else | ||
| 1998 | req = NULL; | ||
| 1999 | |||
| 2000 | /* ack all, and handle what we care about */ | ||
| 2001 | t = readl (&ep->regs->ep_stat); | ||
| 2002 | ep->irqs++; | ||
| 2003 | #if 0 | ||
| 2004 | VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n", | ||
| 2005 | ep->ep.name, t, req ? &req->req : 0); | ||
| 2006 | #endif | ||
| 2007 | if (!ep->is_in || ep->dev->pdev->device == 0x2280) | ||
| 2008 | writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); | ||
| 2009 | else | ||
| 2010 | /* Added for 2282 */ | ||
| 2011 | writel (t, &ep->regs->ep_stat); | ||
| 2012 | |||
| 2013 | /* for ep0, monitor token irqs to catch data stage length errors | ||
| 2014 | * and to synchronize on status. | ||
| 2015 | * | ||
| 2016 | * also, to defer reporting of protocol stalls ... here's where | ||
| 2017 | * data or status first appears, handling stalls here should never | ||
| 2018 | * cause trouble on the host side.. | ||
| 2019 | * | ||
| 2020 | * control requests could be slightly faster without token synch for | ||
| 2021 | * status, but status can jam up that way. | ||
| 2022 | */ | ||
| 2023 | if (unlikely (ep->num == 0)) { | ||
| 2024 | if (ep->is_in) { | ||
| 2025 | /* status; stop NAKing */ | ||
| 2026 | if (t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)) { | ||
| 2027 | if (ep->dev->protocol_stall) { | ||
| 2028 | ep->stopped = 1; | ||
| 2029 | set_halt (ep); | ||
| 2030 | } | ||
| 2031 | if (!req) | ||
| 2032 | allow_status (ep); | ||
| 2033 | mode = 2; | ||
| 2034 | /* reply to extra IN data tokens with a zlp */ | ||
| 2035 | } else if (t & (1 << DATA_IN_TOKEN_INTERRUPT)) { | ||
| 2036 | if (ep->dev->protocol_stall) { | ||
| 2037 | ep->stopped = 1; | ||
| 2038 | set_halt (ep); | ||
| 2039 | mode = 2; | ||
| 2040 | } else if (ep->responded && | ||
| 2041 | !req && !ep->stopped) | ||
| 2042 | write_fifo (ep, NULL); | ||
| 2043 | } | ||
| 2044 | } else { | ||
| 2045 | /* status; stop NAKing */ | ||
| 2046 | if (t & (1 << DATA_IN_TOKEN_INTERRUPT)) { | ||
| 2047 | if (ep->dev->protocol_stall) { | ||
| 2048 | ep->stopped = 1; | ||
| 2049 | set_halt (ep); | ||
| 2050 | } | ||
| 2051 | mode = 2; | ||
| 2052 | /* an extra OUT token is an error */ | ||
| 2053 | } else if (((t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)) | ||
| 2054 | && req | ||
| 2055 | && req->req.actual == req->req.length) | ||
| 2056 | || (ep->responded && !req)) { | ||
| 2057 | ep->dev->protocol_stall = 1; | ||
| 2058 | set_halt (ep); | ||
| 2059 | ep->stopped = 1; | ||
| 2060 | if (req) | ||
| 2061 | done (ep, req, -EOVERFLOW); | ||
| 2062 | req = NULL; | ||
| 2063 | } | ||
| 2064 | } | ||
| 2065 | } | ||
| 2066 | |||
| 2067 | if (unlikely (!req)) | ||
| 2068 | return; | ||
| 2069 | |||
| 2070 | /* manual DMA queue advance after short OUT */ | ||
| 2071 | if (likely (ep->dma)) { | ||
| 2072 | if (t & (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)) { | ||
| 2073 | u32 count; | ||
| 2074 | int stopped = ep->stopped; | ||
| 2075 | |||
| 2076 | /* TRANSFERRED works around OUT_DONE erratum 0112. | ||
| 2077 | * we expect (N <= maxpacket) bytes; host wrote M. | ||
| 2078 | * iff (M < N) we won't ever see a DMA interrupt. | ||
| 2079 | */ | ||
| 2080 | ep->stopped = 1; | ||
| 2081 | for (count = 0; ; t = readl (&ep->regs->ep_stat)) { | ||
| 2082 | |||
| 2083 | /* any preceding dma transfers must finish. | ||
| 2084 | * dma handles (M >= N), may empty the queue | ||
| 2085 | */ | ||
| 2086 | scan_dma_completions (ep); | ||
| 2087 | if (unlikely (list_empty (&ep->queue) | ||
| 2088 | || ep->out_overflow)) { | ||
| 2089 | req = NULL; | ||
| 2090 | break; | ||
| 2091 | } | ||
| 2092 | req = list_entry (ep->queue.next, | ||
| 2093 | struct net2280_request, queue); | ||
| 2094 | |||
| 2095 | /* here either (M < N), a "real" short rx; | ||
| 2096 | * or (M == N) and the queue didn't empty | ||
| 2097 | */ | ||
| 2098 | if (likely (t & (1 << FIFO_EMPTY))) { | ||
| 2099 | count = readl (&ep->dma->dmacount); | ||
| 2100 | count &= DMA_BYTE_COUNT_MASK; | ||
| 2101 | if (readl (&ep->dma->dmadesc) | ||
| 2102 | != req->td_dma) | ||
| 2103 | req = NULL; | ||
| 2104 | break; | ||
| 2105 | } | ||
| 2106 | udelay(1); | ||
| 2107 | } | ||
| 2108 | |||
| 2109 | /* stop DMA, leave ep NAKing */ | ||
| 2110 | writel ((1 << DMA_ABORT), &ep->dma->dmastat); | ||
| 2111 | spin_stop_dma (ep->dma); | ||
| 2112 | |||
| 2113 | if (likely (req)) { | ||
| 2114 | req->td->dmacount = 0; | ||
| 2115 | t = readl (&ep->regs->ep_avail); | ||
| 2116 | dma_done (ep, req, count, | ||
| 2117 | (ep->out_overflow || t) | ||
| 2118 | ? -EOVERFLOW : 0); | ||
| 2119 | } | ||
| 2120 | |||
| 2121 | /* also flush to prevent erratum 0106 trouble */ | ||
| 2122 | if (unlikely (ep->out_overflow | ||
| 2123 | || (ep->dev->chiprev == 0x0100 | ||
| 2124 | && ep->dev->gadget.speed | ||
| 2125 | == USB_SPEED_FULL))) { | ||
| 2126 | out_flush (ep); | ||
| 2127 | ep->out_overflow = 0; | ||
| 2128 | } | ||
| 2129 | |||
| 2130 | /* (re)start dma if needed, stop NAKing */ | ||
| 2131 | ep->stopped = stopped; | ||
| 2132 | if (!list_empty (&ep->queue)) | ||
| 2133 | restart_dma (ep); | ||
| 2134 | } else | ||
| 2135 | DEBUG (ep->dev, "%s dma ep_stat %08x ??\n", | ||
| 2136 | ep->ep.name, t); | ||
| 2137 | return; | ||
| 2138 | |||
| 2139 | /* data packet(s) received (in the fifo, OUT) */ | ||
| 2140 | } else if (t & (1 << DATA_PACKET_RECEIVED_INTERRUPT)) { | ||
| 2141 | if (read_fifo (ep, req) && ep->num != 0) | ||
| 2142 | mode = 2; | ||
| 2143 | |||
| 2144 | /* data packet(s) transmitted (IN) */ | ||
| 2145 | } else if (t & (1 << DATA_PACKET_TRANSMITTED_INTERRUPT)) { | ||
| 2146 | unsigned len; | ||
| 2147 | |||
| 2148 | len = req->req.length - req->req.actual; | ||
| 2149 | if (len > ep->ep.maxpacket) | ||
| 2150 | len = ep->ep.maxpacket; | ||
| 2151 | req->req.actual += len; | ||
| 2152 | |||
| 2153 | /* if we wrote it all, we're usually done */ | ||
| 2154 | if (req->req.actual == req->req.length) { | ||
| 2155 | if (ep->num == 0) { | ||
| 2156 | /* send zlps until the status stage */ | ||
| 2157 | } else if (!req->req.zero || len != ep->ep.maxpacket) | ||
| 2158 | mode = 2; | ||
| 2159 | } | ||
| 2160 | |||
| 2161 | /* there was nothing to do ... */ | ||
| 2162 | } else if (mode == 1) | ||
| 2163 | return; | ||
| 2164 | |||
| 2165 | /* done */ | ||
| 2166 | if (mode == 2) { | ||
| 2167 | /* stream endpoints often resubmit/unlink in completion */ | ||
| 2168 | done (ep, req, 0); | ||
| 2169 | |||
| 2170 | /* maybe advance queue to next request */ | ||
| 2171 | if (ep->num == 0) { | ||
| 2172 | /* NOTE: net2280 could let gadget driver start the | ||
| 2173 | * status stage later. since not all controllers let | ||
| 2174 | * them control that, the api doesn't (yet) allow it. | ||
| 2175 | */ | ||
| 2176 | if (!ep->stopped) | ||
| 2177 | allow_status (ep); | ||
| 2178 | req = NULL; | ||
| 2179 | } else { | ||
| 2180 | if (!list_empty (&ep->queue) && !ep->stopped) | ||
| 2181 | req = list_entry (ep->queue.next, | ||
| 2182 | struct net2280_request, queue); | ||
| 2183 | else | ||
| 2184 | req = NULL; | ||
| 2185 | if (req && !ep->is_in) | ||
| 2186 | stop_out_naking (ep); | ||
| 2187 | } | ||
| 2188 | } | ||
| 2189 | |||
| 2190 | /* is there a buffer for the next packet? | ||
| 2191 | * for best streaming performance, make sure there is one. | ||
| 2192 | */ | ||
| 2193 | if (req && !ep->stopped) { | ||
| 2194 | |||
| 2195 | /* load IN fifo with next packet (may be zlp) */ | ||
| 2196 | if (t & (1 << DATA_PACKET_TRANSMITTED_INTERRUPT)) | ||
| 2197 | write_fifo (ep, &req->req); | ||
| 2198 | } | ||
| 2199 | } | ||
| 2200 | |||
| 2201 | static struct net2280_ep * | ||
| 2202 | get_ep_by_addr (struct net2280 *dev, u16 wIndex) | ||
| 2203 | { | ||
| 2204 | struct net2280_ep *ep; | ||
| 2205 | |||
| 2206 | if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0) | ||
| 2207 | return &dev->ep [0]; | ||
| 2208 | list_for_each_entry (ep, &dev->gadget.ep_list, ep.ep_list) { | ||
| 2209 | u8 bEndpointAddress; | ||
| 2210 | |||
| 2211 | if (!ep->desc) | ||
| 2212 | continue; | ||
| 2213 | bEndpointAddress = ep->desc->bEndpointAddress; | ||
| 2214 | if ((wIndex ^ bEndpointAddress) & USB_DIR_IN) | ||
| 2215 | continue; | ||
| 2216 | if ((wIndex & 0x0f) == (bEndpointAddress & 0x0f)) | ||
| 2217 | return ep; | ||
| 2218 | } | ||
| 2219 | return NULL; | ||
| 2220 | } | ||
| 2221 | |||
| 2222 | static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | ||
| 2223 | { | ||
| 2224 | struct net2280_ep *ep; | ||
| 2225 | u32 num, scratch; | ||
| 2226 | |||
| 2227 | /* most of these don't need individual acks */ | ||
| 2228 | stat &= ~(1 << INTA_ASSERTED); | ||
| 2229 | if (!stat) | ||
| 2230 | return; | ||
| 2231 | // DEBUG (dev, "irqstat0 %04x\n", stat); | ||
| 2232 | |||
| 2233 | /* starting a control request? */ | ||
| 2234 | if (unlikely (stat & (1 << SETUP_PACKET_INTERRUPT))) { | ||
| 2235 | union { | ||
| 2236 | u32 raw [2]; | ||
| 2237 | struct usb_ctrlrequest r; | ||
| 2238 | } u; | ||
| 2239 | int tmp; | ||
| 2240 | struct net2280_request *req; | ||
| 2241 | |||
| 2242 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) { | ||
| 2243 | if (readl (&dev->usb->usbstat) & (1 << HIGH_SPEED)) | ||
| 2244 | dev->gadget.speed = USB_SPEED_HIGH; | ||
| 2245 | else | ||
| 2246 | dev->gadget.speed = USB_SPEED_FULL; | ||
| 2247 | net2280_led_speed (dev, dev->gadget.speed); | ||
| 2248 | DEBUG(dev, "%s\n", usb_speed_string(dev->gadget.speed)); | ||
| 2249 | } | ||
| 2250 | |||
| 2251 | ep = &dev->ep [0]; | ||
| 2252 | ep->irqs++; | ||
| 2253 | |||
| 2254 | /* make sure any leftover request state is cleared */ | ||
| 2255 | stat &= ~(1 << ENDPOINT_0_INTERRUPT); | ||
| 2256 | while (!list_empty (&ep->queue)) { | ||
| 2257 | req = list_entry (ep->queue.next, | ||
| 2258 | struct net2280_request, queue); | ||
| 2259 | done (ep, req, (req->req.actual == req->req.length) | ||
| 2260 | ? 0 : -EPROTO); | ||
| 2261 | } | ||
| 2262 | ep->stopped = 0; | ||
| 2263 | dev->protocol_stall = 0; | ||
| 2264 | |||
| 2265 | if (ep->dev->pdev->device == 0x2280) | ||
| 2266 | tmp = (1 << FIFO_OVERFLOW) | ||
| 2267 | | (1 << FIFO_UNDERFLOW); | ||
| 2268 | else | ||
| 2269 | tmp = 0; | ||
| 2270 | |||
| 2271 | writel (tmp | (1 << TIMEOUT) | ||
| 2272 | | (1 << USB_STALL_SENT) | ||
| 2273 | | (1 << USB_IN_NAK_SENT) | ||
| 2274 | | (1 << USB_IN_ACK_RCVD) | ||
| 2275 | | (1 << USB_OUT_PING_NAK_SENT) | ||
| 2276 | | (1 << USB_OUT_ACK_SENT) | ||
| 2277 | | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | ||
| 2278 | | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | ||
| 2279 | | (1 << DATA_PACKET_RECEIVED_INTERRUPT) | ||
| 2280 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT) | ||
| 2281 | | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 2282 | | (1 << DATA_IN_TOKEN_INTERRUPT) | ||
| 2283 | , &ep->regs->ep_stat); | ||
| 2284 | u.raw [0] = readl (&dev->usb->setup0123); | ||
| 2285 | u.raw [1] = readl (&dev->usb->setup4567); | ||
| 2286 | |||
| 2287 | cpu_to_le32s (&u.raw [0]); | ||
| 2288 | cpu_to_le32s (&u.raw [1]); | ||
| 2289 | |||
| 2290 | tmp = 0; | ||
| 2291 | |||
| 2292 | #define w_value le16_to_cpu(u.r.wValue) | ||
| 2293 | #define w_index le16_to_cpu(u.r.wIndex) | ||
| 2294 | #define w_length le16_to_cpu(u.r.wLength) | ||
| 2295 | |||
| 2296 | /* ack the irq */ | ||
| 2297 | writel (1 << SETUP_PACKET_INTERRUPT, &dev->regs->irqstat0); | ||
| 2298 | stat ^= (1 << SETUP_PACKET_INTERRUPT); | ||
| 2299 | |||
| 2300 | /* watch control traffic at the token level, and force | ||
| 2301 | * synchronization before letting the status stage happen. | ||
| 2302 | * FIXME ignore tokens we'll NAK, until driver responds. | ||
| 2303 | * that'll mean a lot less irqs for some drivers. | ||
| 2304 | */ | ||
| 2305 | ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0; | ||
| 2306 | if (ep->is_in) { | ||
| 2307 | scratch = (1 << DATA_PACKET_TRANSMITTED_INTERRUPT) | ||
| 2308 | | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 2309 | | (1 << DATA_IN_TOKEN_INTERRUPT); | ||
| 2310 | stop_out_naking (ep); | ||
| 2311 | } else | ||
| 2312 | scratch = (1 << DATA_PACKET_RECEIVED_INTERRUPT) | ||
| 2313 | | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 2314 | | (1 << DATA_IN_TOKEN_INTERRUPT); | ||
| 2315 | writel (scratch, &dev->epregs [0].ep_irqenb); | ||
| 2316 | |||
| 2317 | /* we made the hardware handle most lowlevel requests; | ||
| 2318 | * everything else goes uplevel to the gadget code. | ||
| 2319 | */ | ||
| 2320 | ep->responded = 1; | ||
| 2321 | switch (u.r.bRequest) { | ||
| 2322 | case USB_REQ_GET_STATUS: { | ||
| 2323 | struct net2280_ep *e; | ||
| 2324 | __le32 status; | ||
| 2325 | |||
| 2326 | /* hw handles device and interface status */ | ||
| 2327 | if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT)) | ||
| 2328 | goto delegate; | ||
| 2329 | if ((e = get_ep_by_addr (dev, w_index)) == NULL | ||
| 2330 | || w_length > 2) | ||
| 2331 | goto do_stall; | ||
| 2332 | |||
| 2333 | if (readl (&e->regs->ep_rsp) | ||
| 2334 | & (1 << SET_ENDPOINT_HALT)) | ||
| 2335 | status = cpu_to_le32 (1); | ||
| 2336 | else | ||
| 2337 | status = cpu_to_le32 (0); | ||
| 2338 | |||
| 2339 | /* don't bother with a request object! */ | ||
| 2340 | writel (0, &dev->epregs [0].ep_irqenb); | ||
| 2341 | set_fifo_bytecount (ep, w_length); | ||
| 2342 | writel ((__force u32)status, &dev->epregs [0].ep_data); | ||
| 2343 | allow_status (ep); | ||
| 2344 | VDEBUG (dev, "%s stat %02x\n", ep->ep.name, status); | ||
| 2345 | goto next_endpoints; | ||
| 2346 | } | ||
| 2347 | break; | ||
| 2348 | case USB_REQ_CLEAR_FEATURE: { | ||
| 2349 | struct net2280_ep *e; | ||
| 2350 | |||
| 2351 | /* hw handles device features */ | ||
| 2352 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) | ||
| 2353 | goto delegate; | ||
| 2354 | if (w_value != USB_ENDPOINT_HALT | ||
| 2355 | || w_length != 0) | ||
| 2356 | goto do_stall; | ||
| 2357 | if ((e = get_ep_by_addr (dev, w_index)) == NULL) | ||
| 2358 | goto do_stall; | ||
| 2359 | if (e->wedged) { | ||
| 2360 | VDEBUG(dev, "%s wedged, halt not cleared\n", | ||
| 2361 | ep->ep.name); | ||
| 2362 | } else { | ||
| 2363 | VDEBUG(dev, "%s clear halt\n", ep->ep.name); | ||
| 2364 | clear_halt(e); | ||
| 2365 | } | ||
| 2366 | allow_status (ep); | ||
| 2367 | goto next_endpoints; | ||
| 2368 | } | ||
| 2369 | break; | ||
| 2370 | case USB_REQ_SET_FEATURE: { | ||
| 2371 | struct net2280_ep *e; | ||
| 2372 | |||
| 2373 | /* hw handles device features */ | ||
| 2374 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) | ||
| 2375 | goto delegate; | ||
| 2376 | if (w_value != USB_ENDPOINT_HALT | ||
| 2377 | || w_length != 0) | ||
| 2378 | goto do_stall; | ||
| 2379 | if ((e = get_ep_by_addr (dev, w_index)) == NULL) | ||
| 2380 | goto do_stall; | ||
| 2381 | if (e->ep.name == ep0name) | ||
| 2382 | goto do_stall; | ||
| 2383 | set_halt (e); | ||
| 2384 | allow_status (ep); | ||
| 2385 | VDEBUG (dev, "%s set halt\n", ep->ep.name); | ||
| 2386 | goto next_endpoints; | ||
| 2387 | } | ||
| 2388 | break; | ||
| 2389 | default: | ||
| 2390 | delegate: | ||
| 2391 | VDEBUG (dev, "setup %02x.%02x v%04x i%04x l%04x " | ||
| 2392 | "ep_cfg %08x\n", | ||
| 2393 | u.r.bRequestType, u.r.bRequest, | ||
| 2394 | w_value, w_index, w_length, | ||
| 2395 | readl (&ep->regs->ep_cfg)); | ||
| 2396 | ep->responded = 0; | ||
| 2397 | spin_unlock (&dev->lock); | ||
| 2398 | tmp = dev->driver->setup (&dev->gadget, &u.r); | ||
| 2399 | spin_lock (&dev->lock); | ||
| 2400 | } | ||
| 2401 | |||
| 2402 | /* stall ep0 on error */ | ||
| 2403 | if (tmp < 0) { | ||
| 2404 | do_stall: | ||
| 2405 | VDEBUG (dev, "req %02x.%02x protocol STALL; stat %d\n", | ||
| 2406 | u.r.bRequestType, u.r.bRequest, tmp); | ||
| 2407 | dev->protocol_stall = 1; | ||
| 2408 | } | ||
| 2409 | |||
| 2410 | /* some in/out token irq should follow; maybe stall then. | ||
| 2411 | * driver must queue a request (even zlp) or halt ep0 | ||
| 2412 | * before the host times out. | ||
| 2413 | */ | ||
| 2414 | } | ||
| 2415 | |||
| 2416 | #undef w_value | ||
| 2417 | #undef w_index | ||
| 2418 | #undef w_length | ||
| 2419 | |||
| 2420 | next_endpoints: | ||
| 2421 | /* endpoint data irq ? */ | ||
| 2422 | scratch = stat & 0x7f; | ||
| 2423 | stat &= ~0x7f; | ||
| 2424 | for (num = 0; scratch; num++) { | ||
| 2425 | u32 t; | ||
| 2426 | |||
| 2427 | /* do this endpoint's FIFO and queue need tending? */ | ||
| 2428 | t = 1 << num; | ||
| 2429 | if ((scratch & t) == 0) | ||
| 2430 | continue; | ||
| 2431 | scratch ^= t; | ||
| 2432 | |||
| 2433 | ep = &dev->ep [num]; | ||
| 2434 | handle_ep_small (ep); | ||
| 2435 | } | ||
| 2436 | |||
| 2437 | if (stat) | ||
| 2438 | DEBUG (dev, "unhandled irqstat0 %08x\n", stat); | ||
| 2439 | } | ||
| 2440 | |||
| 2441 | #define DMA_INTERRUPTS ( \ | ||
| 2442 | (1 << DMA_D_INTERRUPT) \ | ||
| 2443 | | (1 << DMA_C_INTERRUPT) \ | ||
| 2444 | | (1 << DMA_B_INTERRUPT) \ | ||
| 2445 | | (1 << DMA_A_INTERRUPT)) | ||
| 2446 | #define PCI_ERROR_INTERRUPTS ( \ | ||
| 2447 | (1 << PCI_MASTER_ABORT_RECEIVED_INTERRUPT) \ | ||
| 2448 | | (1 << PCI_TARGET_ABORT_RECEIVED_INTERRUPT) \ | ||
| 2449 | | (1 << PCI_RETRY_ABORT_INTERRUPT)) | ||
| 2450 | |||
| 2451 | static void handle_stat1_irqs (struct net2280 *dev, u32 stat) | ||
| 2452 | { | ||
| 2453 | struct net2280_ep *ep; | ||
| 2454 | u32 tmp, num, mask, scratch; | ||
| 2455 | |||
| 2456 | /* after disconnect there's nothing else to do! */ | ||
| 2457 | tmp = (1 << VBUS_INTERRUPT) | (1 << ROOT_PORT_RESET_INTERRUPT); | ||
| 2458 | mask = (1 << HIGH_SPEED) | (1 << FULL_SPEED); | ||
| 2459 | |||
| 2460 | /* VBUS disconnect is indicated by VBUS_PIN and VBUS_INTERRUPT set. | ||
| 2461 | * Root Port Reset is indicated by ROOT_PORT_RESET_INTERRUPT set and | ||
| 2462 | * both HIGH_SPEED and FULL_SPEED clear (as ROOT_PORT_RESET_INTERRUPT | ||
| 2463 | * only indicates a change in the reset state). | ||
| 2464 | */ | ||
| 2465 | if (stat & tmp) { | ||
| 2466 | writel (tmp, &dev->regs->irqstat1); | ||
| 2467 | if ((((stat & (1 << ROOT_PORT_RESET_INTERRUPT)) | ||
| 2468 | && ((readl (&dev->usb->usbstat) & mask) | ||
| 2469 | == 0)) | ||
| 2470 | || ((readl (&dev->usb->usbctl) | ||
| 2471 | & (1 << VBUS_PIN)) == 0) | ||
| 2472 | ) && ( dev->gadget.speed != USB_SPEED_UNKNOWN)) { | ||
| 2473 | DEBUG (dev, "disconnect %s\n", | ||
| 2474 | dev->driver->driver.name); | ||
| 2475 | stop_activity (dev, dev->driver); | ||
| 2476 | ep0_start (dev); | ||
| 2477 | return; | ||
| 2478 | } | ||
| 2479 | stat &= ~tmp; | ||
| 2480 | |||
| 2481 | /* vBUS can bounce ... one of many reasons to ignore the | ||
| 2482 | * notion of hotplug events on bus connect/disconnect! | ||
| 2483 | */ | ||
| 2484 | if (!stat) | ||
| 2485 | return; | ||
| 2486 | } | ||
| 2487 | |||
| 2488 | /* NOTE: chip stays in PCI D0 state for now, but it could | ||
| 2489 | * enter D1 to save more power | ||
| 2490 | */ | ||
| 2491 | tmp = (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT); | ||
| 2492 | if (stat & tmp) { | ||
| 2493 | writel (tmp, &dev->regs->irqstat1); | ||
| 2494 | if (stat & (1 << SUSPEND_REQUEST_INTERRUPT)) { | ||
| 2495 | if (dev->driver->suspend) | ||
| 2496 | dev->driver->suspend (&dev->gadget); | ||
| 2497 | if (!enable_suspend) | ||
| 2498 | stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT); | ||
| 2499 | } else { | ||
| 2500 | if (dev->driver->resume) | ||
| 2501 | dev->driver->resume (&dev->gadget); | ||
| 2502 | /* at high speed, note erratum 0133 */ | ||
| 2503 | } | ||
| 2504 | stat &= ~tmp; | ||
| 2505 | } | ||
| 2506 | |||
| 2507 | /* clear any other status/irqs */ | ||
| 2508 | if (stat) | ||
| 2509 | writel (stat, &dev->regs->irqstat1); | ||
| 2510 | |||
| 2511 | /* some status we can just ignore */ | ||
| 2512 | if (dev->pdev->device == 0x2280) | ||
| 2513 | stat &= ~((1 << CONTROL_STATUS_INTERRUPT) | ||
| 2514 | | (1 << SUSPEND_REQUEST_INTERRUPT) | ||
| 2515 | | (1 << RESUME_INTERRUPT) | ||
| 2516 | | (1 << SOF_INTERRUPT)); | ||
| 2517 | else | ||
| 2518 | stat &= ~((1 << CONTROL_STATUS_INTERRUPT) | ||
| 2519 | | (1 << RESUME_INTERRUPT) | ||
| 2520 | | (1 << SOF_DOWN_INTERRUPT) | ||
| 2521 | | (1 << SOF_INTERRUPT)); | ||
| 2522 | |||
| 2523 | if (!stat) | ||
| 2524 | return; | ||
| 2525 | // DEBUG (dev, "irqstat1 %08x\n", stat); | ||
| 2526 | |||
| 2527 | /* DMA status, for ep-{a,b,c,d} */ | ||
| 2528 | scratch = stat & DMA_INTERRUPTS; | ||
| 2529 | stat &= ~DMA_INTERRUPTS; | ||
| 2530 | scratch >>= 9; | ||
| 2531 | for (num = 0; scratch; num++) { | ||
| 2532 | struct net2280_dma_regs __iomem *dma; | ||
| 2533 | |||
| 2534 | tmp = 1 << num; | ||
| 2535 | if ((tmp & scratch) == 0) | ||
| 2536 | continue; | ||
| 2537 | scratch ^= tmp; | ||
| 2538 | |||
| 2539 | ep = &dev->ep [num + 1]; | ||
| 2540 | dma = ep->dma; | ||
| 2541 | |||
| 2542 | if (!dma) | ||
| 2543 | continue; | ||
| 2544 | |||
| 2545 | /* clear ep's dma status */ | ||
| 2546 | tmp = readl (&dma->dmastat); | ||
| 2547 | writel (tmp, &dma->dmastat); | ||
| 2548 | |||
| 2549 | /* chaining should stop on abort, short OUT from fifo, | ||
| 2550 | * or (stat0 codepath) short OUT transfer. | ||
| 2551 | */ | ||
| 2552 | if (!use_dma_chaining) { | ||
| 2553 | if ((tmp & (1 << DMA_TRANSACTION_DONE_INTERRUPT)) | ||
| 2554 | == 0) { | ||
| 2555 | DEBUG (ep->dev, "%s no xact done? %08x\n", | ||
| 2556 | ep->ep.name, tmp); | ||
| 2557 | continue; | ||
| 2558 | } | ||
| 2559 | stop_dma (ep->dma); | ||
| 2560 | } | ||
| 2561 | |||
| 2562 | /* OUT transfers terminate when the data from the | ||
| 2563 | * host is in our memory. Process whatever's done. | ||
| 2564 | * On this path, we know transfer's last packet wasn't | ||
| 2565 | * less than req->length. NAK_OUT_PACKETS may be set, | ||
| 2566 | * or the FIFO may already be holding new packets. | ||
| 2567 | * | ||
| 2568 | * IN transfers can linger in the FIFO for a very | ||
| 2569 | * long time ... we ignore that for now, accounting | ||
| 2570 | * precisely (like PIO does) needs per-packet irqs | ||
| 2571 | */ | ||
| 2572 | scan_dma_completions (ep); | ||
| 2573 | |||
| 2574 | /* disable dma on inactive queues; else maybe restart */ | ||
| 2575 | if (list_empty (&ep->queue)) { | ||
| 2576 | if (use_dma_chaining) | ||
| 2577 | stop_dma (ep->dma); | ||
| 2578 | } else { | ||
| 2579 | tmp = readl (&dma->dmactl); | ||
| 2580 | if (!use_dma_chaining | ||
| 2581 | || (tmp & (1 << DMA_ENABLE)) == 0) | ||
| 2582 | restart_dma (ep); | ||
| 2583 | else if (ep->is_in && use_dma_chaining) { | ||
| 2584 | struct net2280_request *req; | ||
| 2585 | __le32 dmacount; | ||
| 2586 | |||
| 2587 | /* the descriptor at the head of the chain | ||
| 2588 | * may still have VALID_BIT clear; that's | ||
| 2589 | * used to trigger changing DMA_FIFO_VALIDATE | ||
| 2590 | * (affects automagic zlp writes). | ||
| 2591 | */ | ||
| 2592 | req = list_entry (ep->queue.next, | ||
| 2593 | struct net2280_request, queue); | ||
| 2594 | dmacount = req->td->dmacount; | ||
| 2595 | dmacount &= cpu_to_le32 ( | ||
| 2596 | (1 << VALID_BIT) | ||
| 2597 | | DMA_BYTE_COUNT_MASK); | ||
| 2598 | if (dmacount && (dmacount & valid_bit) == 0) | ||
| 2599 | restart_dma (ep); | ||
| 2600 | } | ||
| 2601 | } | ||
| 2602 | ep->irqs++; | ||
| 2603 | } | ||
| 2604 | |||
| 2605 | /* NOTE: there are other PCI errors we might usefully notice. | ||
| 2606 | * if they appear very often, here's where to try recovering. | ||
| 2607 | */ | ||
| 2608 | if (stat & PCI_ERROR_INTERRUPTS) { | ||
| 2609 | ERROR (dev, "pci dma error; stat %08x\n", stat); | ||
| 2610 | stat &= ~PCI_ERROR_INTERRUPTS; | ||
| 2611 | /* these are fatal errors, but "maybe" they won't | ||
| 2612 | * happen again ... | ||
| 2613 | */ | ||
| 2614 | stop_activity (dev, dev->driver); | ||
| 2615 | ep0_start (dev); | ||
| 2616 | stat = 0; | ||
| 2617 | } | ||
| 2618 | |||
| 2619 | if (stat) | ||
| 2620 | DEBUG (dev, "unhandled irqstat1 %08x\n", stat); | ||
| 2621 | } | ||
| 2622 | |||
| 2623 | static irqreturn_t net2280_irq (int irq, void *_dev) | ||
| 2624 | { | ||
| 2625 | struct net2280 *dev = _dev; | ||
| 2626 | |||
| 2627 | /* shared interrupt, not ours */ | ||
| 2628 | if (!(readl(&dev->regs->irqstat0) & (1 << INTA_ASSERTED))) | ||
| 2629 | return IRQ_NONE; | ||
| 2630 | |||
| 2631 | spin_lock (&dev->lock); | ||
| 2632 | |||
| 2633 | /* handle disconnect, dma, and more */ | ||
| 2634 | handle_stat1_irqs (dev, readl (&dev->regs->irqstat1)); | ||
| 2635 | |||
| 2636 | /* control requests and PIO */ | ||
| 2637 | handle_stat0_irqs (dev, readl (&dev->regs->irqstat0)); | ||
| 2638 | |||
| 2639 | spin_unlock (&dev->lock); | ||
| 2640 | |||
| 2641 | return IRQ_HANDLED; | ||
| 2642 | } | ||
| 2643 | |||
| 2644 | /*-------------------------------------------------------------------------*/ | ||
| 2645 | |||
| 2646 | static void gadget_release (struct device *_dev) | ||
| 2647 | { | ||
| 2648 | struct net2280 *dev = dev_get_drvdata (_dev); | ||
| 2649 | |||
| 2650 | kfree (dev); | ||
| 2651 | } | ||
| 2652 | |||
| 2653 | /* tear down the binding between this driver and the pci device */ | ||
| 2654 | |||
| 2655 | static void net2280_remove (struct pci_dev *pdev) | ||
| 2656 | { | ||
| 2657 | struct net2280 *dev = pci_get_drvdata (pdev); | ||
| 2658 | |||
| 2659 | usb_del_gadget_udc(&dev->gadget); | ||
| 2660 | |||
| 2661 | BUG_ON(dev->driver); | ||
| 2662 | |||
| 2663 | /* then clean up the resources we allocated during probe() */ | ||
| 2664 | net2280_led_shutdown (dev); | ||
| 2665 | if (dev->requests) { | ||
| 2666 | int i; | ||
| 2667 | for (i = 1; i < 5; i++) { | ||
| 2668 | if (!dev->ep [i].dummy) | ||
| 2669 | continue; | ||
| 2670 | pci_pool_free (dev->requests, dev->ep [i].dummy, | ||
| 2671 | dev->ep [i].td_dma); | ||
| 2672 | } | ||
| 2673 | pci_pool_destroy (dev->requests); | ||
| 2674 | } | ||
| 2675 | if (dev->got_irq) | ||
| 2676 | free_irq (pdev->irq, dev); | ||
| 2677 | if (dev->regs) | ||
| 2678 | iounmap (dev->regs); | ||
| 2679 | if (dev->region) | ||
| 2680 | release_mem_region (pci_resource_start (pdev, 0), | ||
| 2681 | pci_resource_len (pdev, 0)); | ||
| 2682 | if (dev->enabled) | ||
| 2683 | pci_disable_device (pdev); | ||
| 2684 | device_remove_file (&pdev->dev, &dev_attr_registers); | ||
| 2685 | |||
| 2686 | INFO (dev, "unbind\n"); | ||
| 2687 | } | ||
| 2688 | |||
| 2689 | /* wrap this driver around the specified device, but | ||
| 2690 | * don't respond over USB until a gadget driver binds to us. | ||
| 2691 | */ | ||
| 2692 | |||
| 2693 | static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | ||
| 2694 | { | ||
| 2695 | struct net2280 *dev; | ||
| 2696 | unsigned long resource, len; | ||
| 2697 | void __iomem *base = NULL; | ||
| 2698 | int retval, i; | ||
| 2699 | |||
| 2700 | /* alloc, and start init */ | ||
| 2701 | dev = kzalloc (sizeof *dev, GFP_KERNEL); | ||
| 2702 | if (dev == NULL){ | ||
| 2703 | retval = -ENOMEM; | ||
| 2704 | goto done; | ||
| 2705 | } | ||
| 2706 | |||
| 2707 | pci_set_drvdata (pdev, dev); | ||
| 2708 | spin_lock_init (&dev->lock); | ||
| 2709 | dev->pdev = pdev; | ||
| 2710 | dev->gadget.ops = &net2280_ops; | ||
| 2711 | dev->gadget.max_speed = USB_SPEED_HIGH; | ||
| 2712 | |||
| 2713 | /* the "gadget" abstracts/virtualizes the controller */ | ||
| 2714 | dev->gadget.name = driver_name; | ||
| 2715 | |||
| 2716 | /* now all the pci goodies ... */ | ||
| 2717 | if (pci_enable_device (pdev) < 0) { | ||
| 2718 | retval = -ENODEV; | ||
| 2719 | goto done; | ||
| 2720 | } | ||
| 2721 | dev->enabled = 1; | ||
| 2722 | |||
| 2723 | /* BAR 0 holds all the registers | ||
| 2724 | * BAR 1 is 8051 memory; unused here (note erratum 0103) | ||
| 2725 | * BAR 2 is fifo memory; unused here | ||
| 2726 | */ | ||
| 2727 | resource = pci_resource_start (pdev, 0); | ||
| 2728 | len = pci_resource_len (pdev, 0); | ||
| 2729 | if (!request_mem_region (resource, len, driver_name)) { | ||
| 2730 | DEBUG (dev, "controller already in use\n"); | ||
| 2731 | retval = -EBUSY; | ||
| 2732 | goto done; | ||
| 2733 | } | ||
| 2734 | dev->region = 1; | ||
| 2735 | |||
| 2736 | /* FIXME provide firmware download interface to put | ||
| 2737 | * 8051 code into the chip, e.g. to turn on PCI PM. | ||
| 2738 | */ | ||
| 2739 | |||
| 2740 | base = ioremap_nocache (resource, len); | ||
| 2741 | if (base == NULL) { | ||
| 2742 | DEBUG (dev, "can't map memory\n"); | ||
| 2743 | retval = -EFAULT; | ||
| 2744 | goto done; | ||
| 2745 | } | ||
| 2746 | dev->regs = (struct net2280_regs __iomem *) base; | ||
| 2747 | dev->usb = (struct net2280_usb_regs __iomem *) (base + 0x0080); | ||
| 2748 | dev->pci = (struct net2280_pci_regs __iomem *) (base + 0x0100); | ||
| 2749 | dev->dma = (struct net2280_dma_regs __iomem *) (base + 0x0180); | ||
| 2750 | dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200); | ||
| 2751 | dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300); | ||
| 2752 | |||
| 2753 | /* put into initial config, link up all endpoints */ | ||
| 2754 | writel (0, &dev->usb->usbctl); | ||
| 2755 | usb_reset (dev); | ||
| 2756 | usb_reinit (dev); | ||
| 2757 | |||
| 2758 | /* irq setup after old hardware is cleaned up */ | ||
| 2759 | if (!pdev->irq) { | ||
| 2760 | ERROR (dev, "No IRQ. Check PCI setup!\n"); | ||
| 2761 | retval = -ENODEV; | ||
| 2762 | goto done; | ||
| 2763 | } | ||
| 2764 | |||
| 2765 | if (request_irq (pdev->irq, net2280_irq, IRQF_SHARED, driver_name, dev) | ||
| 2766 | != 0) { | ||
| 2767 | ERROR (dev, "request interrupt %d failed\n", pdev->irq); | ||
| 2768 | retval = -EBUSY; | ||
| 2769 | goto done; | ||
| 2770 | } | ||
| 2771 | dev->got_irq = 1; | ||
| 2772 | |||
| 2773 | /* DMA setup */ | ||
| 2774 | /* NOTE: we know only the 32 LSBs of dma addresses may be nonzero */ | ||
| 2775 | dev->requests = pci_pool_create ("requests", pdev, | ||
| 2776 | sizeof (struct net2280_dma), | ||
| 2777 | 0 /* no alignment requirements */, | ||
| 2778 | 0 /* or page-crossing issues */); | ||
| 2779 | if (!dev->requests) { | ||
| 2780 | DEBUG (dev, "can't get request pool\n"); | ||
| 2781 | retval = -ENOMEM; | ||
| 2782 | goto done; | ||
| 2783 | } | ||
| 2784 | for (i = 1; i < 5; i++) { | ||
| 2785 | struct net2280_dma *td; | ||
| 2786 | |||
| 2787 | td = pci_pool_alloc (dev->requests, GFP_KERNEL, | ||
| 2788 | &dev->ep [i].td_dma); | ||
| 2789 | if (!td) { | ||
| 2790 | DEBUG (dev, "can't get dummy %d\n", i); | ||
| 2791 | retval = -ENOMEM; | ||
| 2792 | goto done; | ||
| 2793 | } | ||
| 2794 | td->dmacount = 0; /* not VALID */ | ||
| 2795 | td->dmadesc = td->dmaaddr; | ||
| 2796 | dev->ep [i].dummy = td; | ||
| 2797 | } | ||
| 2798 | |||
| 2799 | /* enable lower-overhead pci memory bursts during DMA */ | ||
| 2800 | writel ( (1 << DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) | ||
| 2801 | // 256 write retries may not be enough... | ||
| 2802 | // | (1 << PCI_RETRY_ABORT_ENABLE) | ||
| 2803 | | (1 << DMA_READ_MULTIPLE_ENABLE) | ||
| 2804 | | (1 << DMA_READ_LINE_ENABLE) | ||
| 2805 | , &dev->pci->pcimstctl); | ||
| 2806 | /* erratum 0115 shouldn't appear: Linux inits PCI_LATENCY_TIMER */ | ||
| 2807 | pci_set_master (pdev); | ||
| 2808 | pci_try_set_mwi (pdev); | ||
| 2809 | |||
| 2810 | /* ... also flushes any posted pci writes */ | ||
| 2811 | dev->chiprev = get_idx_reg (dev->regs, REG_CHIPREV) & 0xffff; | ||
| 2812 | |||
| 2813 | /* done */ | ||
| 2814 | INFO (dev, "%s\n", driver_desc); | ||
| 2815 | INFO (dev, "irq %d, pci mem %p, chip rev %04x\n", | ||
| 2816 | pdev->irq, base, dev->chiprev); | ||
| 2817 | INFO (dev, "version: " DRIVER_VERSION "; dma %s\n", | ||
| 2818 | use_dma | ||
| 2819 | ? (use_dma_chaining ? "chaining" : "enabled") | ||
| 2820 | : "disabled"); | ||
| 2821 | retval = device_create_file (&pdev->dev, &dev_attr_registers); | ||
| 2822 | if (retval) goto done; | ||
| 2823 | |||
| 2824 | retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget, | ||
| 2825 | gadget_release); | ||
| 2826 | if (retval) | ||
| 2827 | goto done; | ||
| 2828 | return 0; | ||
| 2829 | |||
| 2830 | done: | ||
| 2831 | if (dev) | ||
| 2832 | net2280_remove (pdev); | ||
| 2833 | return retval; | ||
| 2834 | } | ||
| 2835 | |||
| 2836 | /* make sure the board is quiescent; otherwise it will continue | ||
| 2837 | * generating IRQs across the upcoming reboot. | ||
| 2838 | */ | ||
| 2839 | |||
| 2840 | static void net2280_shutdown (struct pci_dev *pdev) | ||
| 2841 | { | ||
| 2842 | struct net2280 *dev = pci_get_drvdata (pdev); | ||
| 2843 | |||
| 2844 | /* disable IRQs */ | ||
| 2845 | writel (0, &dev->regs->pciirqenb0); | ||
| 2846 | writel (0, &dev->regs->pciirqenb1); | ||
| 2847 | |||
| 2848 | /* disable the pullup so the host will think we're gone */ | ||
| 2849 | writel (0, &dev->usb->usbctl); | ||
| 2850 | |||
| 2851 | /* Disable full-speed test mode */ | ||
| 2852 | writel(0, &dev->usb->xcvrdiag); | ||
| 2853 | } | ||
| 2854 | |||
| 2855 | |||
| 2856 | /*-------------------------------------------------------------------------*/ | ||
| 2857 | |||
| 2858 | static const struct pci_device_id pci_ids [] = { { | ||
| 2859 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 2860 | .class_mask = ~0, | ||
| 2861 | .vendor = 0x17cc, | ||
| 2862 | .device = 0x2280, | ||
| 2863 | .subvendor = PCI_ANY_ID, | ||
| 2864 | .subdevice = PCI_ANY_ID, | ||
| 2865 | }, { | ||
| 2866 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 2867 | .class_mask = ~0, | ||
| 2868 | .vendor = 0x17cc, | ||
| 2869 | .device = 0x2282, | ||
| 2870 | .subvendor = PCI_ANY_ID, | ||
| 2871 | .subdevice = PCI_ANY_ID, | ||
| 2872 | |||
| 2873 | }, { /* end: all zeroes */ } | ||
| 2874 | }; | ||
| 2875 | MODULE_DEVICE_TABLE (pci, pci_ids); | ||
| 2876 | |||
| 2877 | /* pci driver glue; this is a "new style" PCI driver module */ | ||
| 2878 | static struct pci_driver net2280_pci_driver = { | ||
| 2879 | .name = (char *) driver_name, | ||
| 2880 | .id_table = pci_ids, | ||
| 2881 | |||
| 2882 | .probe = net2280_probe, | ||
| 2883 | .remove = net2280_remove, | ||
| 2884 | .shutdown = net2280_shutdown, | ||
| 2885 | |||
| 2886 | /* FIXME add power management support */ | ||
| 2887 | }; | ||
| 2888 | |||
| 2889 | MODULE_DESCRIPTION (DRIVER_DESC); | ||
| 2890 | MODULE_AUTHOR ("David Brownell"); | ||
| 2891 | MODULE_LICENSE ("GPL"); | ||
| 2892 | |||
| 2893 | static int __init init (void) | ||
| 2894 | { | ||
| 2895 | if (!use_dma) | ||
| 2896 | use_dma_chaining = 0; | ||
| 2897 | return pci_register_driver (&net2280_pci_driver); | ||
| 2898 | } | ||
| 2899 | module_init (init); | ||
| 2900 | |||
| 2901 | static void __exit cleanup (void) | ||
| 2902 | { | ||
| 2903 | pci_unregister_driver (&net2280_pci_driver); | ||
| 2904 | } | ||
| 2905 | module_exit (cleanup); | ||
| @@ -1,308 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * NetChip 2280 high/full speed USB device controller. | ||
| 3 | * Unlike many such controllers, this one talks PCI. | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* | ||
| 7 | * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) | ||
| 8 | * Copyright (C) 2003 David Brownell | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/usb/net2280.h> | ||
| 17 | |||
| 18 | /*-------------------------------------------------------------------------*/ | ||
| 19 | |||
| 20 | #ifdef __KERNEL__ | ||
| 21 | |||
| 22 | /* indexed registers [11.10] are accessed indirectly | ||
| 23 | * caller must own the device lock. | ||
| 24 | */ | ||
| 25 | |||
| 26 | static inline u32 | ||
| 27 | get_idx_reg (struct net2280_regs __iomem *regs, u32 index) | ||
| 28 | { | ||
| 29 | writel (index, ®s->idxaddr); | ||
| 30 | /* NOTE: synchs device/cpu memory views */ | ||
| 31 | return readl (®s->idxdata); | ||
| 32 | } | ||
| 33 | |||
| 34 | static inline void | ||
| 35 | set_idx_reg (struct net2280_regs __iomem *regs, u32 index, u32 value) | ||
| 36 | { | ||
| 37 | writel (index, ®s->idxaddr); | ||
| 38 | writel (value, ®s->idxdata); | ||
| 39 | /* posted, may not be visible yet */ | ||
| 40 | } | ||
| 41 | |||
| 42 | #endif /* __KERNEL__ */ | ||
| 43 | |||
| 44 | |||
| 45 | #define REG_DIAG 0x0 | ||
| 46 | #define RETRY_COUNTER 16 | ||
| 47 | #define FORCE_PCI_SERR 11 | ||
| 48 | #define FORCE_PCI_INTERRUPT 10 | ||
| 49 | #define FORCE_USB_INTERRUPT 9 | ||
| 50 | #define FORCE_CPU_INTERRUPT 8 | ||
| 51 | #define ILLEGAL_BYTE_ENABLES 5 | ||
| 52 | #define FAST_TIMES 4 | ||
| 53 | #define FORCE_RECEIVE_ERROR 2 | ||
| 54 | #define FORCE_TRANSMIT_CRC_ERROR 0 | ||
| 55 | #define REG_FRAME 0x02 /* from last sof */ | ||
| 56 | #define REG_CHIPREV 0x03 /* in bcd */ | ||
| 57 | #define REG_HS_NAK_RATE 0x0a /* NAK per N uframes */ | ||
| 58 | |||
| 59 | #define CHIPREV_1 0x0100 | ||
| 60 | #define CHIPREV_1A 0x0110 | ||
| 61 | |||
| 62 | #ifdef __KERNEL__ | ||
| 63 | |||
| 64 | /* ep a-f highspeed and fullspeed maxpacket, addresses | ||
| 65 | * computed from ep->num | ||
| 66 | */ | ||
| 67 | #define REG_EP_MAXPKT(dev,num) (((num) + 1) * 0x10 + \ | ||
| 68 | (((dev)->gadget.speed == USB_SPEED_HIGH) ? 0 : 1)) | ||
| 69 | |||
| 70 | /*-------------------------------------------------------------------------*/ | ||
| 71 | |||
| 72 | /* [8.3] for scatter/gather i/o | ||
| 73 | * use struct net2280_dma_regs bitfields | ||
| 74 | */ | ||
| 75 | struct net2280_dma { | ||
| 76 | __le32 dmacount; | ||
| 77 | __le32 dmaaddr; /* the buffer */ | ||
| 78 | __le32 dmadesc; /* next dma descriptor */ | ||
| 79 | __le32 _reserved; | ||
| 80 | } __attribute__ ((aligned (16))); | ||
| 81 | |||
| 82 | /*-------------------------------------------------------------------------*/ | ||
| 83 | |||
| 84 | /* DRIVER DATA STRUCTURES and UTILITIES */ | ||
| 85 | |||
| 86 | struct net2280_ep { | ||
| 87 | struct usb_ep ep; | ||
| 88 | struct net2280_ep_regs __iomem *regs; | ||
| 89 | struct net2280_dma_regs __iomem *dma; | ||
| 90 | struct net2280_dma *dummy; | ||
| 91 | dma_addr_t td_dma; /* of dummy */ | ||
| 92 | struct net2280 *dev; | ||
| 93 | unsigned long irqs; | ||
| 94 | |||
| 95 | /* analogous to a host-side qh */ | ||
| 96 | struct list_head queue; | ||
| 97 | const struct usb_endpoint_descriptor *desc; | ||
| 98 | unsigned num : 8, | ||
| 99 | fifo_size : 12, | ||
| 100 | in_fifo_validate : 1, | ||
| 101 | out_overflow : 1, | ||
| 102 | stopped : 1, | ||
| 103 | wedged : 1, | ||
| 104 | is_in : 1, | ||
| 105 | is_iso : 1, | ||
| 106 | responded : 1; | ||
| 107 | }; | ||
| 108 | |||
| 109 | static inline void allow_status (struct net2280_ep *ep) | ||
| 110 | { | ||
| 111 | /* ep0 only */ | ||
| 112 | writel ( (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) | ||
| 113 | | (1 << CLEAR_NAK_OUT_PACKETS) | ||
| 114 | | (1 << CLEAR_NAK_OUT_PACKETS_MODE) | ||
| 115 | , &ep->regs->ep_rsp); | ||
| 116 | ep->stopped = 1; | ||
| 117 | } | ||
| 118 | |||
| 119 | /* count (<= 4) bytes in the next fifo write will be valid */ | ||
| 120 | static inline void set_fifo_bytecount (struct net2280_ep *ep, unsigned count) | ||
| 121 | { | ||
| 122 | writeb (count, 2 + (u8 __iomem *) &ep->regs->ep_cfg); | ||
| 123 | } | ||
| 124 | |||
| 125 | struct net2280_request { | ||
| 126 | struct usb_request req; | ||
| 127 | struct net2280_dma *td; | ||
| 128 | dma_addr_t td_dma; | ||
| 129 | struct list_head queue; | ||
| 130 | unsigned mapped : 1, | ||
| 131 | valid : 1; | ||
| 132 | }; | ||
| 133 | |||
| 134 | struct net2280 { | ||
| 135 | /* each pci device provides one gadget, several endpoints */ | ||
| 136 | struct usb_gadget gadget; | ||
| 137 | spinlock_t lock; | ||
| 138 | struct net2280_ep ep [7]; | ||
| 139 | struct usb_gadget_driver *driver; | ||
| 140 | unsigned enabled : 1, | ||
| 141 | protocol_stall : 1, | ||
| 142 | softconnect : 1, | ||
| 143 | got_irq : 1, | ||
| 144 | region : 1; | ||
| 145 | u16 chiprev; | ||
| 146 | |||
| 147 | /* pci state used to access those endpoints */ | ||
| 148 | struct pci_dev *pdev; | ||
| 149 | struct net2280_regs __iomem *regs; | ||
| 150 | struct net2280_usb_regs __iomem *usb; | ||
| 151 | struct net2280_pci_regs __iomem *pci; | ||
| 152 | struct net2280_dma_regs __iomem *dma; | ||
| 153 | struct net2280_dep_regs __iomem *dep; | ||
| 154 | struct net2280_ep_regs __iomem *epregs; | ||
| 155 | |||
| 156 | struct pci_pool *requests; | ||
| 157 | // statistics... | ||
| 158 | }; | ||
| 159 | |||
| 160 | static inline void set_halt (struct net2280_ep *ep) | ||
| 161 | { | ||
| 162 | /* ep0 and bulk/intr endpoints */ | ||
| 163 | writel ( (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) | ||
| 164 | /* set NAK_OUT for erratum 0114 */ | ||
| 165 | | ((ep->dev->chiprev == CHIPREV_1) << SET_NAK_OUT_PACKETS) | ||
| 166 | | (1 << SET_ENDPOINT_HALT) | ||
| 167 | , &ep->regs->ep_rsp); | ||
| 168 | } | ||
| 169 | |||
| 170 | static inline void clear_halt (struct net2280_ep *ep) | ||
| 171 | { | ||
| 172 | /* ep0 and bulk/intr endpoints */ | ||
| 173 | writel ( (1 << CLEAR_ENDPOINT_HALT) | ||
| 174 | | (1 << CLEAR_ENDPOINT_TOGGLE) | ||
| 175 | /* unless the gadget driver left a short packet in the | ||
| 176 | * fifo, this reverses the erratum 0114 workaround. | ||
| 177 | */ | ||
| 178 | | ((ep->dev->chiprev == CHIPREV_1) << CLEAR_NAK_OUT_PACKETS) | ||
| 179 | , &ep->regs->ep_rsp); | ||
| 180 | } | ||
| 181 | |||
| 182 | #ifdef USE_RDK_LEDS | ||
| 183 | |||
| 184 | static inline void net2280_led_init (struct net2280 *dev) | ||
| 185 | { | ||
| 186 | /* LED3 (green) is on during USB activity. note erratum 0113. */ | ||
| 187 | writel ((1 << GPIO3_LED_SELECT) | ||
| 188 | | (1 << GPIO3_OUTPUT_ENABLE) | ||
| 189 | | (1 << GPIO2_OUTPUT_ENABLE) | ||
| 190 | | (1 << GPIO1_OUTPUT_ENABLE) | ||
| 191 | | (1 << GPIO0_OUTPUT_ENABLE) | ||
| 192 | , &dev->regs->gpioctl); | ||
| 193 | } | ||
| 194 | |||
| 195 | /* indicate speed with bi-color LED 0/1 */ | ||
| 196 | static inline | ||
| 197 | void net2280_led_speed (struct net2280 *dev, enum usb_device_speed speed) | ||
| 198 | { | ||
| 199 | u32 val = readl (&dev->regs->gpioctl); | ||
| 200 | switch (speed) { | ||
| 201 | case USB_SPEED_HIGH: /* green */ | ||
| 202 | val &= ~(1 << GPIO0_DATA); | ||
| 203 | val |= (1 << GPIO1_DATA); | ||
| 204 | break; | ||
| 205 | case USB_SPEED_FULL: /* red */ | ||
| 206 | val &= ~(1 << GPIO1_DATA); | ||
| 207 | val |= (1 << GPIO0_DATA); | ||
| 208 | break; | ||
| 209 | default: /* (off/black) */ | ||
| 210 | val &= ~((1 << GPIO1_DATA) | (1 << GPIO0_DATA)); | ||
| 211 | break; | ||
| 212 | } | ||
| 213 | writel (val, &dev->regs->gpioctl); | ||
| 214 | } | ||
| 215 | |||
| 216 | /* indicate power with LED 2 */ | ||
| 217 | static inline void net2280_led_active (struct net2280 *dev, int is_active) | ||
| 218 | { | ||
| 219 | u32 val = readl (&dev->regs->gpioctl); | ||
| 220 | |||
| 221 | // FIXME this LED never seems to turn on. | ||
| 222 | if (is_active) | ||
| 223 | val |= GPIO2_DATA; | ||
| 224 | else | ||
| 225 | val &= ~GPIO2_DATA; | ||
| 226 | writel (val, &dev->regs->gpioctl); | ||
| 227 | } | ||
| 228 | static inline void net2280_led_shutdown (struct net2280 *dev) | ||
| 229 | { | ||
| 230 | /* turn off all four GPIO*_DATA bits */ | ||
| 231 | writel (readl (&dev->regs->gpioctl) & ~0x0f, | ||
| 232 | &dev->regs->gpioctl); | ||
| 233 | } | ||
| 234 | |||
| 235 | #else | ||
| 236 | |||
| 237 | #define net2280_led_init(dev) do { } while (0) | ||
| 238 | #define net2280_led_speed(dev, speed) do { } while (0) | ||
| 239 | #define net2280_led_shutdown(dev) do { } while (0) | ||
| 240 | |||
| 241 | #endif | ||
| 242 | |||
| 243 | /*-------------------------------------------------------------------------*/ | ||
| 244 | |||
| 245 | #define xprintk(dev,level,fmt,args...) \ | ||
| 246 | printk(level "%s %s: " fmt , driver_name , \ | ||
| 247 | pci_name(dev->pdev) , ## args) | ||
| 248 | |||
| 249 | #ifdef DEBUG | ||
| 250 | #undef DEBUG | ||
| 251 | #define DEBUG(dev,fmt,args...) \ | ||
| 252 | xprintk(dev , KERN_DEBUG , fmt , ## args) | ||
| 253 | #else | ||
| 254 | #define DEBUG(dev,fmt,args...) \ | ||
| 255 | do { } while (0) | ||
| 256 | #endif /* DEBUG */ | ||
| 257 | |||
| 258 | #ifdef VERBOSE | ||
| 259 | #define VDEBUG DEBUG | ||
| 260 | #else | ||
| 261 | #define VDEBUG(dev,fmt,args...) \ | ||
| 262 | do { } while (0) | ||
| 263 | #endif /* VERBOSE */ | ||
| 264 | |||
| 265 | #define ERROR(dev,fmt,args...) \ | ||
| 266 | xprintk(dev , KERN_ERR , fmt , ## args) | ||
| 267 | #define WARNING(dev,fmt,args...) \ | ||
| 268 | xprintk(dev , KERN_WARNING , fmt , ## args) | ||
| 269 | #define INFO(dev,fmt,args...) \ | ||
| 270 | xprintk(dev , KERN_INFO , fmt , ## args) | ||
| 271 | |||
| 272 | /*-------------------------------------------------------------------------*/ | ||
| 273 | |||
| 274 | static inline void start_out_naking (struct net2280_ep *ep) | ||
| 275 | { | ||
| 276 | /* NOTE: hardware races lurk here, and PING protocol issues */ | ||
| 277 | writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 278 | /* synch with device */ | ||
| 279 | readl (&ep->regs->ep_rsp); | ||
| 280 | } | ||
| 281 | |||
| 282 | #ifdef DEBUG | ||
| 283 | static inline void assert_out_naking (struct net2280_ep *ep, const char *where) | ||
| 284 | { | ||
| 285 | u32 tmp = readl (&ep->regs->ep_stat); | ||
| 286 | |||
| 287 | if ((tmp & (1 << NAK_OUT_PACKETS)) == 0) { | ||
| 288 | DEBUG (ep->dev, "%s %s %08x !NAK\n", | ||
| 289 | ep->ep.name, where, tmp); | ||
| 290 | writel ((1 << SET_NAK_OUT_PACKETS), | ||
| 291 | &ep->regs->ep_rsp); | ||
| 292 | } | ||
| 293 | } | ||
| 294 | #define ASSERT_OUT_NAKING(ep) assert_out_naking(ep,__func__) | ||
| 295 | #else | ||
| 296 | #define ASSERT_OUT_NAKING(ep) do {} while (0) | ||
| 297 | #endif | ||
| 298 | |||
| 299 | static inline void stop_out_naking (struct net2280_ep *ep) | ||
| 300 | { | ||
| 301 | u32 tmp; | ||
| 302 | |||
| 303 | tmp = readl (&ep->regs->ep_stat); | ||
| 304 | if ((tmp & (1 << NAK_OUT_PACKETS)) != 0) | ||
| 305 | writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 306 | } | ||
| 307 | |||
| 308 | #endif /* __KERNEL__ */ | ||
| @@ -35,27 +35,63 @@ · 34 unmodified lines | |||
| 35 | #define USB_EXT_PROP_UNICODE_LINK 6 | 35 | #define USB_EXT_PROP_UNICODE_LINK 6 |
| 36 | #define USB_EXT_PROP_UNICODE_MULTI 7 | 36 | #define USB_EXT_PROP_UNICODE_MULTI 7 |
| 37 | 37 | ||
| 38 | static inline u8 *__usb_ext_prop_ptr(u8 *buf, size_t offset) | ||
| 39 | { | ||
| 40 | return buf + offset; | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline u8 *usb_ext_prop_size_ptr(u8 *buf) | ||
| 44 | { | ||
| 45 | return __usb_ext_prop_ptr(buf, USB_EXT_PROP_DW_SIZE); | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline u8 *usb_ext_prop_type_ptr(u8 *buf) | ||
| 49 | { | ||
| 50 | return __usb_ext_prop_ptr(buf, USB_EXT_PROP_DW_PROPERTY_DATA_TYPE); | ||
| 51 | } | ||
| 52 | |||
| 53 | static inline u8 *usb_ext_prop_name_len_ptr(u8 *buf) | ||
| 54 | { | ||
| 55 | return __usb_ext_prop_ptr(buf, USB_EXT_PROP_W_PROPERTY_NAME_LENGTH); | ||
| 56 | } | ||
| 57 | |||
| 58 | static inline u8 *usb_ext_prop_name_ptr(u8 *buf) | ||
| 59 | { | ||
| 60 | return __usb_ext_prop_ptr(buf, USB_EXT_PROP_B_PROPERTY_NAME); | ||
| 61 | } | ||
| 62 | |||
| 63 | static inline u8 *usb_ext_prop_data_len_ptr(u8 *buf, size_t off) | ||
| 64 | { | ||
| 65 | return __usb_ext_prop_ptr(buf, | ||
| 66 | USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + off); | ||
| 67 | } | ||
| 68 | |||
| 69 | static inline u8 *usb_ext_prop_data_ptr(u8 *buf, size_t off) | ||
| 70 | { | ||
| 71 | return __usb_ext_prop_ptr(buf, USB_EXT_PROP_B_PROPERTY_DATA + off); | ||
| 72 | } | ||
| 73 | |||
| 38 | static inline void usb_ext_prop_put_size(u8 *buf, int dw_size) | 74 | static inline void usb_ext_prop_put_size(u8 *buf, int dw_size) |
| 39 | { | 75 | { |
| 40 | put_unaligned_le32(dw_size, &buf[USB_EXT_PROP_DW_SIZE]); | 76 | put_unaligned_le32(dw_size, usb_ext_prop_size_ptr(buf)); |
| 41 | } | 77 | } |
| 42 | 78 | ||
| 43 | static inline void usb_ext_prop_put_type(u8 *buf, int type) | 79 | static inline void usb_ext_prop_put_type(u8 *buf, int type) |
| 44 | { | 80 | { |
| 45 | put_unaligned_le32(type, &buf[USB_EXT_PROP_DW_PROPERTY_DATA_TYPE]); | 81 | put_unaligned_le32(type, usb_ext_prop_type_ptr(buf)); |
| 46 | } | 82 | } |
| 47 | 83 | ||
| 48 | static inline int usb_ext_prop_put_name(u8 *buf, const char *name, int pnl) | 84 | static inline int usb_ext_prop_put_name(u8 *buf, const char *name, int pnl) |
| 49 | { | 85 | { |
| 50 | int result; | 86 | int result; |
| 51 | 87 | ||
| 52 | put_unaligned_le16(pnl, &buf[USB_EXT_PROP_W_PROPERTY_NAME_LENGTH]); | 88 | put_unaligned_le16(pnl, usb_ext_prop_name_len_ptr(buf)); |
| 53 | result = utf8s_to_utf16s(name, strlen(name), UTF16_LITTLE_ENDIAN, | 89 | result = utf8s_to_utf16s(name, strlen(name), UTF16_LITTLE_ENDIAN, |
| 54 | (wchar_t *) &buf[USB_EXT_PROP_B_PROPERTY_NAME], pnl - 2); | 90 | (wchar_t *) usb_ext_prop_name_ptr(buf), pnl - 2); |
| 55 | if (result < 0) | 91 | if (result < 0) |
| 56 | return result; | 92 | return result; |
| 57 | 93 | ||
| 58 | put_unaligned_le16(0, &buf[USB_EXT_PROP_B_PROPERTY_NAME + pnl]); | 94 | put_unaligned_le16(0, &buf[USB_EXT_PROP_B_PROPERTY_NAME + pnl - 2]); |
| 59 | 95 | ||
| 60 | return pnl; | 96 | return pnl; |
| 61 | } | 97 | } |
| @@ -63,26 +99,23 @@ static inline int usb_ext_prop_put_name(u8 *buf, const char *name, int pnl) · 1 unmodified line | |||
| 63 | static inline void usb_ext_prop_put_binary(u8 *buf, int pnl, const u8 *data, | 99 | static inline void usb_ext_prop_put_binary(u8 *buf, int pnl, const u8 *data, |
| 64 | int data_len) | 100 | int data_len) |
| 65 | { | 101 | { |
| 66 | put_unaligned_le32(data_len, | 102 | put_unaligned_le32(data_len, usb_ext_prop_data_len_ptr(buf, pnl)); |
| 67 | &buf[USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + pnl]); | 103 | memcpy(usb_ext_prop_data_ptr(buf, pnl), data, data_len); |
| 68 | memcpy(&buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl], data, data_len); | ||
| 69 | } | 104 | } |
| 70 | 105 | ||
| 71 | static inline int usb_ext_prop_put_unicode(u8 *buf, int pnl, const char *string, | 106 | static inline int usb_ext_prop_put_unicode(u8 *buf, int pnl, const char *string, |
| 72 | int data_len) | 107 | int data_len) |
| 73 | { | 108 | { |
| 74 | int result; | 109 | int result; |
| 75 | put_unaligned_le32(data_len, | 110 | put_unaligned_le32(data_len, usb_ext_prop_data_len_ptr(buf, pnl)); |
| 76 | &buf[USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + pnl]); | ||
| 77 | |||
| 78 | result = utf8s_to_utf16s(string, data_len >> 1, UTF16_LITTLE_ENDIAN, | 111 | result = utf8s_to_utf16s(string, data_len >> 1, UTF16_LITTLE_ENDIAN, |
| 79 | (wchar_t *) &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl], | 112 | (wchar_t *) usb_ext_prop_data_ptr(buf, pnl), |
| 80 | data_len - 2); | 113 | data_len - 2); |
| 81 | if (result < 0) | 114 | if (result < 0) |
| 82 | return result; | 115 | return result; |
| 83 | 116 | ||
| 84 | put_unaligned_le16(0, | 117 | put_unaligned_le16(0, |
| 85 | &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl + data_len]); | 118 | &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl + data_len - 2]); |
| 86 | 119 | ||
| 87 | return data_len; | 120 | return data_len; |
| 88 | } | 121 | } |
| @@ -0,0 +1,385 @@ | |||
| 1 | # | ||
| 2 | # USB Gadget support on a system involves | ||
| 3 | # (a) a peripheral controller, and | ||
| 4 | # (b) the gadget driver using it. | ||
| 5 | # | ||
| 6 | # NOTE: Gadget support ** DOES NOT ** depend on host-side CONFIG_USB !! | ||
| 7 | # | ||
| 8 | # - Host systems (like PCs) need CONFIG_USB (with "A" jacks). | ||
| 9 | # - Peripherals (like PDAs) need CONFIG_USB_GADGET (with "B" jacks). | ||
| 10 | # - Some systems have both kinds of controllers. | ||
| 11 | # | ||
| 12 | # With help from a special transceiver and a "Mini-AB" jack, systems with | ||
| 13 | # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG). | ||
| 14 | # | ||
| 15 | |||
| 16 | # | ||
| 17 | # USB Peripheral Controller Support | ||
| 18 | # | ||
| 19 | # The order here is alphabetical, except that integrated controllers go | ||
| 20 | # before discrete ones so they will be the initial/default value: | ||
| 21 | # - integrated/SOC controllers first | ||
| 22 | # - licensed IP used in both SOC and discrete versions | ||
| 23 | # - discrete ones (including all PCI-only controllers) | ||
| 24 | # - debug/dummy gadget+hcd is last. | ||
| 25 | # | ||
| 26 | menu "USB Peripheral Controller" | ||
| 27 | |||
| 28 | # | ||
| 29 | # Integrated controllers | ||
| 30 | # | ||
| 31 | |||
| 32 | config USB_AT91 | ||
| 33 | tristate "Atmel AT91 USB Device Port" | ||
| 34 | depends on ARCH_AT91 | ||
| 35 | help | ||
| 36 | Many Atmel AT91 processors (such as the AT91RM2000) have a | ||
| 37 | full speed USB Device Port with support for five configurable | ||
| 38 | endpoints (plus endpoint zero). | ||
| 39 | |||
| 40 | Say "y" to link the driver statically, or "m" to build a | ||
| 41 | dynamically linked module called "at91_udc" and force all | ||
| 42 | gadget drivers to also be dynamically linked. | ||
| 43 | |||
| 44 | config USB_LPC32XX | ||
| 45 | tristate "LPC32XX USB Peripheral Controller" | ||
| 46 | depends on ARCH_LPC32XX && I2C | ||
| 47 | select USB_ISP1301 | ||
| 48 | help | ||
| 49 | This option selects the USB device controller in the LPC32xx SoC. | ||
| 50 | |||
| 51 | Say "y" to link the driver statically, or "m" to build a | ||
| 52 | dynamically linked module called "lpc32xx_udc" and force all | ||
| 53 | gadget drivers to also be dynamically linked. | ||
| 54 | |||
| 55 | config USB_ATMEL_USBA | ||
| 56 | tristate "Atmel USBA" | ||
| 57 | depends on AVR32 || ARCH_AT91 | ||
| 58 | help | ||
| 59 | USBA is the integrated high-speed USB Device controller on | ||
| 60 | the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. | ||
| 61 | |||
| 62 | config USB_BCM63XX_UDC | ||
| 63 | tristate "Broadcom BCM63xx Peripheral Controller" | ||
| 64 | depends on BCM63XX | ||
| 65 | help | ||
| 66 | Many Broadcom BCM63xx chipsets (such as the BCM6328) have a | ||
| 67 | high speed USB Device Port with support for four fixed endpoints | ||
| 68 | (plus endpoint zero). | ||
| 69 | |||
| 70 | Say "y" to link the driver statically, or "m" to build a | ||
| 71 | dynamically linked module called "bcm63xx_udc". | ||
| 72 | |||
| 73 | config USB_FSL_USB2 | ||
| 74 | tristate "Freescale Highspeed USB DR Peripheral Controller" | ||
| 75 | depends on FSL_SOC || ARCH_MXC | ||
| 76 | select USB_FSL_MPH_DR_OF if OF | ||
| 77 | help | ||
| 78 | Some of Freescale PowerPC and i.MX processors have a High Speed | ||
| 79 | Dual-Role(DR) USB controller, which supports device mode. | ||
| 80 | |||
| 81 | The number of programmable endpoints is different through | ||
| 82 | SOC revisions. | ||
| 83 | |||
| 84 | Say "y" to link the driver statically, or "m" to build a | ||
| 85 | dynamically linked module called "fsl_usb2_udc" and force | ||
| 86 | all gadget drivers to also be dynamically linked. | ||
| 87 | |||
| 88 | config USB_FUSB300 | ||
| 89 | tristate "Faraday FUSB300 USB Peripheral Controller" | ||
| 90 | depends on !PHYS_ADDR_T_64BIT && HAS_DMA | ||
| 91 | help | ||
| 92 | Faraday usb device controller FUSB300 driver | ||
| 93 | |||
| 94 | config USB_FOTG210_UDC | ||
| 95 | depends on HAS_DMA | ||
| 96 | tristate "Faraday FOTG210 USB Peripheral Controller" | ||
| 97 | help | ||
| 98 | Faraday USB2.0 OTG controller which can be configured as | ||
| 99 | high speed or full speed USB device. This driver supppors | ||
| 100 | Bulk Transfer so far. | ||
| 101 | |||
| 102 | Say "y" to link the driver statically, or "m" to build a | ||
| 103 | dynamically linked module called "fotg210_udc". | ||
| 104 | |||
| 105 | config USB_GR_UDC | ||
| 106 | tristate "Aeroflex Gaisler GRUSBDC USB Peripheral Controller Driver" | ||
| 107 | depends on HAS_DMA | ||
| 108 | help | ||
| 109 | Select this to support Aeroflex Gaisler GRUSBDC cores from the GRLIB | ||
| 110 | VHDL IP core library. | ||
| 111 | |||
| 112 | config USB_OMAP | ||
| 113 | tristate "OMAP USB Device Controller" | ||
| 114 | depends on ARCH_OMAP1 | ||
| 115 | depends on ISP1301_OMAP || !(MACH_OMAP_H2 || MACH_OMAP_H3) | ||
| 116 | help | ||
| 117 | Many Texas Instruments OMAP processors have flexible full | ||
| 118 | speed USB device controllers, with support for up to 30 | ||
| 119 | endpoints (plus endpoint zero). This driver supports the | ||
| 120 | controller in the OMAP 1611, and should work with controllers | ||
| 121 | in other OMAP processors too, given minor tweaks. | ||
| 122 | |||
| 123 | Say "y" to link the driver statically, or "m" to build a | ||
| 124 | dynamically linked module called "omap_udc" and force all | ||
| 125 | gadget drivers to also be dynamically linked. | ||
| 126 | |||
| 127 | config USB_PXA25X | ||
| 128 | tristate "PXA 25x or IXP 4xx" | ||
| 129 | depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX | ||
| 130 | help | ||
| 131 | Intel's PXA 25x series XScale ARM-5TE processors include | ||
| 132 | an integrated full speed USB 1.1 device controller. The | ||
| 133 | controller in the IXP 4xx series is register-compatible. | ||
| 134 | |||
| 135 | It has fifteen fixed-function endpoints, as well as endpoint | ||
| 136 | zero (for control transfers). | ||
| 137 | |||
| 138 | Say "y" to link the driver statically, or "m" to build a | ||
| 139 | dynamically linked module called "pxa25x_udc" and force all | ||
| 140 | gadget drivers to also be dynamically linked. | ||
| 141 | |||
| 142 | # if there's only one gadget driver, using only two bulk endpoints, | ||
| 143 | # don't waste memory for the other endpoints | ||
| 144 | config USB_PXA25X_SMALL | ||
| 145 | depends on USB_PXA25X | ||
| 146 | bool | ||
| 147 | default n if USB_ETH_RNDIS | ||
| 148 | default y if USB_ZERO | ||
| 149 | default y if USB_ETH | ||
| 150 | default y if USB_G_SERIAL | ||
| 151 | |||
| 152 | config USB_R8A66597 | ||
| 153 | tristate "Renesas R8A66597 USB Peripheral Controller" | ||
| 154 | depends on HAS_DMA | ||
| 155 | help | ||
| 156 | R8A66597 is a discrete USB host and peripheral controller chip that | ||
| 157 | supports both full and high speed USB 2.0 data transfers. | ||
| 158 | It has nine configurable endpoints, and endpoint zero. | ||
| 159 | |||
| 160 | Say "y" to link the driver statically, or "m" to build a | ||
| 161 | dynamically linked module called "r8a66597_udc" and force all | ||
| 162 | gadget drivers to also be dynamically linked. | ||
| 163 | |||
| 164 | config USB_RENESAS_USBHS_UDC | ||
| 165 | tristate 'Renesas USBHS controller' | ||
| 166 | depends on USB_RENESAS_USBHS | ||
| 167 | help | ||
| 168 | Renesas USBHS is a discrete USB host and peripheral controller chip | ||
| 169 | that supports both full and high speed USB 2.0 data transfers. | ||
| 170 | It has nine or more configurable endpoints, and endpoint zero. | ||
| 171 | |||
| 172 | Say "y" to link the driver statically, or "m" to build a | ||
| 173 | dynamically linked module called "renesas_usbhs" and force all | ||
| 174 | gadget drivers to also be dynamically linked. | ||
| 175 | |||
| 176 | config USB_PXA27X | ||
| 177 | tristate "PXA 27x" | ||
| 178 | help | ||
| 179 | Intel's PXA 27x series XScale ARM v5TE processors include | ||
| 180 | an integrated full speed USB 1.1 device controller. | ||
| 181 | |||
| 182 | It has up to 23 endpoints, as well as endpoint zero (for | ||
| 183 | control transfers). | ||
| 184 | |||
| 185 | Say "y" to link the driver statically, or "m" to build a | ||
| 186 | dynamically linked module called "pxa27x_udc" and force all | ||
| 187 | gadget drivers to also be dynamically linked. | ||
| 188 | |||
| 189 | config USB_S3C2410 | ||
| 190 | tristate "S3C2410 USB Device Controller" | ||
| 191 | depends on ARCH_S3C24XX | ||
| 192 | help | ||
| 193 | Samsung's S3C2410 is an ARM-4 processor with an integrated | ||
| 194 | full speed USB 1.1 device controller. It has 4 configurable | ||
| 195 | endpoints, as well as endpoint zero (for control transfers). | ||
| 196 | |||
| 197 | This driver has been tested on the S3C2410, S3C2412, and | ||
| 198 | S3C2440 processors. | ||
| 199 | |||
| 200 | config USB_S3C2410_DEBUG | ||
| 201 | boolean "S3C2410 udc debug messages" | ||
| 202 | depends on USB_S3C2410 | ||
| 203 | |||
| 204 | config USB_S3C_HSUDC | ||
| 205 | tristate "S3C2416, S3C2443 and S3C2450 USB Device Controller" | ||
| 206 | depends on ARCH_S3C24XX | ||
| 207 | help | ||
| 208 | Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC | ||
| 209 | integrated with dual speed USB 2.0 device controller. It has | ||
| 210 | 8 endpoints, as well as endpoint zero. | ||
| 211 | |||
| 212 | This driver has been tested on S3C2416 and S3C2450 processors. | ||
| 213 | |||
| 214 | config USB_MV_UDC | ||
| 215 | tristate "Marvell USB2.0 Device Controller" | ||
| 216 | depends on HAS_DMA | ||
| 217 | help | ||
| 218 | Marvell Socs (including PXA and MMP series) include a high speed | ||
| 219 | USB2.0 OTG controller, which can be configured as high speed or | ||
| 220 | full speed USB peripheral. | ||
| 221 | |||
| 222 | config USB_MV_U3D | ||
| 223 | depends on HAS_DMA | ||
| 224 | tristate "MARVELL PXA2128 USB 3.0 controller" | ||
| 225 | help | ||
| 226 | MARVELL PXA2128 Processor series include a super speed USB3.0 device | ||
| 227 | controller, which support super speed USB peripheral. | ||
| 228 | |||
| 229 | # | ||
| 230 | # Controllers available in both integrated and discrete versions | ||
| 231 | # | ||
| 232 | |||
| 233 | config USB_M66592 | ||
| 234 | tristate "Renesas M66592 USB Peripheral Controller" | ||
| 235 | help | ||
| 236 | M66592 is a discrete USB peripheral controller chip that | ||
| 237 | supports both full and high speed USB 2.0 data transfers. | ||
| 238 | It has seven configurable endpoints, and endpoint zero. | ||
| 239 | |||
| 240 | Say "y" to link the driver statically, or "m" to build a | ||
| 241 | dynamically linked module called "m66592_udc" and force all | ||
| 242 | gadget drivers to also be dynamically linked. | ||
| 243 | |||
| 244 | # | ||
| 245 | # Controllers available only in discrete form (and all PCI controllers) | ||
| 246 | # | ||
| 247 | |||
| 248 | config USB_AMD5536UDC | ||
| 249 | tristate "AMD5536 UDC" | ||
| 250 | depends on PCI | ||
| 251 | help | ||
| 252 | The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. | ||
| 253 | It is a USB Highspeed DMA capable USB device controller. Beside ep0 | ||
| 254 | it provides 4 IN and 4 OUT endpoints (bulk or interrupt type). | ||
| 255 | The UDC port supports OTG operation, and may be used as a host port | ||
| 256 | if it's not being used to implement peripheral or OTG roles. | ||
| 257 | |||
| 258 | Say "y" to link the driver statically, or "m" to build a | ||
| 259 | dynamically linked module called "amd5536udc" and force all | ||
| 260 | gadget drivers to also be dynamically linked. | ||
| 261 | |||
| 262 | config USB_FSL_QE | ||
| 263 | tristate "Freescale QE/CPM USB Device Controller" | ||
| 264 | depends on FSL_SOC && (QUICC_ENGINE || CPM) | ||
| 265 | help | ||
| 266 | Some of Freescale PowerPC processors have a Full Speed | ||
| 267 | QE/CPM2 USB controller, which support device mode with 4 | ||
| 268 | programmable endpoints. This driver supports the | ||
| 269 | controller in the MPC8360 and MPC8272, and should work with | ||
| 270 | controllers having QE or CPM2, given minor tweaks. | ||
| 271 | |||
| 272 | Set CONFIG_USB_GADGET to "m" to build this driver as a | ||
| 273 | dynamically linked module called "fsl_qe_udc". | ||
| 274 | |||
| 275 | config USB_NET2272 | ||
| 276 | tristate "PLX NET2272" | ||
| 277 | help | ||
| 278 | PLX NET2272 is a USB peripheral controller which supports | ||
| 279 | both full and high speed USB 2.0 data transfers. | ||
| 280 | |||
| 281 | It has three configurable endpoints, as well as endpoint zero | ||
| 282 | (for control transfer). | ||
| 283 | Say "y" to link the driver statically, or "m" to build a | ||
| 284 | dynamically linked module called "net2272" and force all | ||
| 285 | gadget drivers to also be dynamically linked. | ||
| 286 | |||
| 287 | config USB_NET2272_DMA | ||
| 288 | boolean "Support external DMA controller" | ||
| 289 | depends on USB_NET2272 && HAS_DMA | ||
| 290 | help | ||
| 291 | The NET2272 part can optionally support an external DMA | ||
| 292 | controller, but your board has to have support in the | ||
| 293 | driver itself. | ||
| 294 | |||
| 295 | If unsure, say "N" here. The driver works fine in PIO mode. | ||
| 296 | |||
| 297 | config USB_NET2280 | ||
| 298 | tristate "NetChip 228x / PLX USB338x" | ||
| 299 | depends on PCI | ||
| 300 | help | ||
| 301 | NetChip 2280 / 2282 is a PCI based USB peripheral controller which | ||
| 302 | supports both full and high speed USB 2.0 data transfers. | ||
| 303 | |||
| 304 | It has six configurable endpoints, as well as endpoint zero | ||
| 305 | (for control transfers) and several endpoints with dedicated | ||
| 306 | functions. | ||
| 307 | |||
| 308 | PLX 3380 / 3382 is a PCIe based USB peripheral controller which | ||
| 309 | supports full, high speed USB 2.0 and super speed USB 3.0 | ||
| 310 | data transfers. | ||
| 311 | |||
| 312 | It has eight configurable endpoints, as well as endpoint zero | ||
| 313 | (for control transfers) and several endpoints with dedicated | ||
| 314 | functions. | ||
| 315 | |||
| 316 | Say "y" to link the driver statically, or "m" to build a | ||
| 317 | dynamically linked module called "net2280" and force all | ||
| 318 | gadget drivers to also be dynamically linked. | ||
| 319 | |||
| 320 | config USB_GOKU | ||
| 321 | tristate "Toshiba TC86C001 'Goku-S'" | ||
| 322 | depends on PCI | ||
| 323 | help | ||
| 324 | The Toshiba TC86C001 is a PCI device which includes controllers | ||
| 325 | for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI). | ||
| 326 | |||
| 327 | The device controller has three configurable (bulk or interrupt) | ||
| 328 | endpoints, plus endpoint zero (for control transfers). | ||
| 329 | |||
| 330 | Say "y" to link the driver statically, or "m" to build a | ||
| 331 | dynamically linked module called "goku_udc" and to force all | ||
| 332 | gadget drivers to also be dynamically linked. | ||
| 333 | |||
| 334 | config USB_EG20T | ||
| 335 | tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" | ||
| 336 | depends on PCI | ||
| 337 | help | ||
| 338 | This is a USB device driver for EG20T PCH. | ||
| 339 | EG20T PCH is the platform controller hub that is used in Intel's | ||
| 340 | general embedded platform. EG20T PCH has USB device interface. | ||
| 341 | Using this interface, it is able to access system devices connected | ||
| 342 | to USB device. | ||
| 343 | This driver enables USB device function. | ||
| 344 | USB device is a USB peripheral controller which | ||
| 345 | supports both full and high speed USB 2.0 data transfers. | ||
| 346 | This driver supports both control transfer and bulk transfer modes. | ||
| 347 | This driver dose not support interrupt transfer or isochronous | ||
| 348 | transfer modes. | ||
| 349 | |||
| 350 | This driver also can be used for LAPIS Semiconductor's ML7213 which is | ||
| 351 | for IVI(In-Vehicle Infotainment) use. | ||
| 352 | ML7831 is for general purpose use. | ||
| 353 | ML7213/ML7831 is companion chip for Intel Atom E6xx series. | ||
| 354 | ML7213/ML7831 is completely compatible for Intel EG20T PCH. | ||
| 355 | |||
| 356 | # | ||
| 357 | # LAST -- dummy/emulated controller | ||
| 358 | # | ||
| 359 | |||
| 360 | config USB_DUMMY_HCD | ||
| 361 | tristate "Dummy HCD (DEVELOPMENT)" | ||
| 362 | depends on USB=y || (USB=m && USB_GADGET=m) | ||
| 363 | help | ||
| 364 | This host controller driver emulates USB, looping all data transfer | ||
| 365 | requests back to a USB "gadget driver" in the same host. The host | ||
| 366 | side is the master; the gadget side is the slave. Gadget drivers | ||
| 367 | can be high, full, or low speed; and they have access to endpoints | ||
| 368 | like those from NET2280, PXA2xx, or SA1100 hardware. | ||
| 369 | |||
| 370 | This may help in some stages of creating a driver to embed in a | ||
| 371 | Linux device, since it lets you debug several parts of the gadget | ||
| 372 | driver without its hardware or drivers being involved. | ||
| 373 | |||
| 374 | Since such a gadget side driver needs to interoperate with a host | ||
| 375 | side Linux-USB device driver, this may help to debug both sides | ||
| 376 | of a USB protocol stack. | ||
| 377 | |||
| 378 | Say "y" to link the driver statically, or "m" to build a | ||
| 379 | dynamically linked module called "dummy_hcd" and force all | ||
| 380 | gadget drivers to also be dynamically linked. | ||
| 381 | |||
| 382 | # NOTE: Please keep dummy_hcd LAST so that "real hardware" appears | ||
| 383 | # first and will be selected by default. | ||
| 384 | |||
| 385 | endmenu | ||
| @@ -0,0 +1,31 @@ | |||
| 1 | # | ||
| 2 | # USB peripheral controller drivers | ||
| 3 | # | ||
| 4 | obj-$(CONFIG_USB_GADGET) += udc-core.o | ||
| 5 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o | ||
| 6 | obj-$(CONFIG_USB_NET2272) += net2272.o | ||
| 7 | obj-$(CONFIG_USB_NET2280) += net2280.o | ||
| 8 | obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o | ||
| 9 | obj-$(CONFIG_USB_PXA25X) += pxa25x_udc.o | ||
| 10 | obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o | ||
| 11 | obj-$(CONFIG_USB_GOKU) += goku_udc.o | ||
| 12 | obj-$(CONFIG_USB_OMAP) += omap_udc.o | ||
| 13 | obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o | ||
| 14 | obj-$(CONFIG_USB_AT91) += at91_udc.o | ||
| 15 | obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o | ||
| 16 | obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o | ||
| 17 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o | ||
| 18 | fsl_usb2_udc-y := fsl_udc_core.o | ||
| 19 | fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o | ||
| 20 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | ||
| 21 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o | ||
| 22 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o | ||
| 23 | obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o | ||
| 24 | obj-$(CONFIG_USB_LPC32XX) += lpc32xx_udc.o | ||
| 25 | obj-$(CONFIG_USB_EG20T) += pch_udc.o | ||
| 26 | obj-$(CONFIG_USB_MV_UDC) += mv_udc.o | ||
| 27 | mv_udc-y := mv_udc_core.o | ||
| 28 | obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o | ||
| 29 | obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o | ||
| 30 | obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o | ||
| 31 | obj-$(CONFIG_USB_GR_UDC) += gr_udc.o | ||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -1979,7 +1979,7 @@ static struct usba_ep * usba_udc_pdata(struct platform_device *pdev, · 1978 unmodified lines | |||
| 1979 | return eps; | 1979 | return eps; |
| 1980 | } | 1980 | } |
| 1981 | 1981 | ||
| 1982 | static int __init usba_udc_probe(struct platform_device *pdev) | 1982 | static int usba_udc_probe(struct platform_device *pdev) |
| 1983 | { | 1983 | { |
| 1984 | struct resource *regs, *fifo; | 1984 | struct resource *regs, *fifo; |
| 1985 | struct clk *pclk, *hclk; | 1985 | struct clk *pclk, *hclk; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
| 20 | 20 | ||
| 21 | #include "fsl_usb2_udc.h" | ||
| 22 | |||
| 21 | static struct clk *mxc_ahb_clk; | 23 | static struct clk *mxc_ahb_clk; |
| 22 | static struct clk *mxc_per_clk; | 24 | static struct clk *mxc_per_clk; |
| 23 | static struct clk *mxc_ipg_clk; | 25 | static struct clk *mxc_ipg_clk; |
| @@ -2539,7 +2539,7 @@ static int qe_udc_probe(struct platform_device *ofdev) · 2538 unmodified lines | |||
| 2539 | goto err2; | 2539 | goto err2; |
| 2540 | 2540 | ||
| 2541 | /* create a buf for ZLP send, need to remain zeroed */ | 2541 | /* create a buf for ZLP send, need to remain zeroed */ |
| 2542 | udc->nullbuf = kzalloc(256, GFP_KERNEL); | 2542 | udc->nullbuf = devm_kzalloc(&ofdev->dev, 256, GFP_KERNEL); |
| 2543 | if (udc->nullbuf == NULL) { | 2543 | if (udc->nullbuf == NULL) { |
| 2544 | dev_err(udc->dev, "cannot alloc nullbuf\n"); | 2544 | dev_err(udc->dev, "cannot alloc nullbuf\n"); |
| 2545 | ret = -ENOMEM; | 2545 | ret = -ENOMEM; |
| @@ -2547,10 +2547,10 @@ static int qe_udc_probe(struct platform_device *ofdev) · 1 unmodified line | |||
| 2547 | } | 2547 | } |
| 2548 | 2548 | ||
| 2549 | /* buffer for data of get_status request */ | 2549 | /* buffer for data of get_status request */ |
| 2550 | udc->statusbuf = kzalloc(2, GFP_KERNEL); | 2550 | udc->statusbuf = devm_kzalloc(&ofdev->dev, 2, GFP_KERNEL); |
| 2551 | if (udc->statusbuf == NULL) { | 2551 | if (udc->statusbuf == NULL) { |
| 2552 | ret = -ENOMEM; | 2552 | ret = -ENOMEM; |
| 2553 | goto err4; | 2553 | goto err3; |
| 2554 | } | 2554 | } |
| 2555 | 2555 | ||
| 2556 | udc->nullp = virt_to_phys((void *)udc->nullbuf); | 2556 | udc->nullp = virt_to_phys((void *)udc->nullbuf); |
| @@ -2581,13 +2581,13 @@ static int qe_udc_probe(struct platform_device *ofdev) · 24 unmodified lines | |||
| 2581 | if (ret) { | 2581 | if (ret) { |
| 2582 | dev_err(udc->dev, "cannot request irq %d err %d\n", | 2582 | dev_err(udc->dev, "cannot request irq %d err %d\n", |
| 2583 | udc->usb_irq, ret); | 2583 | udc->usb_irq, ret); |
| 2584 | goto err5; | 2584 | goto err4; |
| 2585 | } | 2585 | } |
| 2586 | 2586 | ||
| 2587 | ret = usb_add_gadget_udc_release(&ofdev->dev, &udc->gadget, | 2587 | ret = usb_add_gadget_udc_release(&ofdev->dev, &udc->gadget, |
| 2588 | qe_udc_release); | 2588 | qe_udc_release); |
| 2589 | if (ret) | 2589 | if (ret) |
| 2590 | goto err6; | 2590 | goto err5; |
| 2591 | 2591 | ||
| 2592 | platform_set_drvdata(ofdev, udc); | 2592 | platform_set_drvdata(ofdev, udc); |
| 2593 | dev_info(udc->dev, | 2593 | dev_info(udc->dev, |
| @@ -2595,9 +2595,9 @@ static int qe_udc_probe(struct platform_device *ofdev) · 1 unmodified line | |||
| 2595 | (udc->soc_type == PORT_QE) ? "QE" : "CPM"); | 2595 | (udc->soc_type == PORT_QE) ? "QE" : "CPM"); |
| 2596 | return 0; | 2596 | return 0; |
| 2597 | 2597 | ||
| 2598 | err6: | ||
| 2599 | free_irq(udc->usb_irq, udc); | ||
| 2600 | err5: | 2598 | err5: |
| 2599 | free_irq(udc->usb_irq, udc); | ||
| 2600 | err4: | ||
| 2601 | irq_dispose_mapping(udc->usb_irq); | 2601 | irq_dispose_mapping(udc->usb_irq); |
| 2602 | err_noirq: | 2602 | err_noirq: |
| 2603 | if (udc->nullmap) { | 2603 | if (udc->nullmap) { |
| @@ -2610,9 +2610,6 @@ err_noirq: · 6 unmodified lines | |||
| 2610 | udc->nullp, 256, | 2610 | udc->nullp, 256, |
| 2611 | DMA_TO_DEVICE); | 2611 | DMA_TO_DEVICE); |
| 2612 | } | 2612 | } |
| 2613 | kfree(udc->statusbuf); | ||
| 2614 | err4: | ||
| 2615 | kfree(udc->nullbuf); | ||
| 2616 | err3: | 2613 | err3: |
| 2617 | ep = &udc->eps[0]; | 2614 | ep = &udc->eps[0]; |
| 2618 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); | 2615 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); |
| @@ -2660,8 +2657,6 @@ static int qe_udc_remove(struct platform_device *ofdev) · 41 unmodified lines | |||
| 2660 | udc->nullp, 256, | 2657 | udc->nullp, 256, |
| 2661 | DMA_TO_DEVICE); | 2658 | DMA_TO_DEVICE); |
| 2662 | } | 2659 | } |
| 2663 | kfree(udc->statusbuf); | ||
| 2664 | kfree(udc->nullbuf); | ||
| 2665 | 2660 | ||
| 2666 | ep = &udc->eps[0]; | 2661 | ep = &udc->eps[0]; |
| 2667 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); | 2662 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); |
File renamed without changes.
| @@ -59,9 +59,9 @@ · 58 unmodified lines | |||
| 59 | static const char driver_name[] = "fsl-usb2-udc"; | 59 | static const char driver_name[] = "fsl-usb2-udc"; |
| 60 | static const char driver_desc[] = DRIVER_DESC; | 60 | static const char driver_desc[] = DRIVER_DESC; |
| 61 | 61 | ||
| 62 | static struct usb_dr_device *dr_regs; | 62 | static struct usb_dr_device __iomem *dr_regs; |
| 63 | 63 | ||
| 64 | static struct usb_sys_interface *usb_sys_regs; | 64 | static struct usb_sys_interface __iomem *usb_sys_regs; |
| 65 | 65 | ||
| 66 | /* it is initialized in probe() */ | 66 | /* it is initialized in probe() */ |
| 67 | static struct fsl_udc *udc_controller = NULL; | 67 | static struct fsl_udc *udc_controller = NULL; |
| @@ -159,6 +159,8 @@ static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata) {} · 91 unmodified lines | |||
| 159 | * request is still in progress. | 159 | * request is still in progress. |
| 160 | *--------------------------------------------------------------*/ | 160 | *--------------------------------------------------------------*/ |
| 161 | static void done(struct fsl_ep *ep, struct fsl_req *req, int status) | 161 | static void done(struct fsl_ep *ep, struct fsl_req *req, int status) |
| 162 | __releases(ep->udc->lock) | ||
| 163 | __acquires(ep->udc->lock) | ||
| 162 | { | 164 | { |
| 163 | struct fsl_udc *udc = NULL; | 165 | struct fsl_udc *udc = NULL; |
| 164 | unsigned char stopped = ep->stopped; | 166 | unsigned char stopped = ep->stopped; |
| @@ -1392,6 +1394,8 @@ stall: · 1227 unmodified lines | |||
| 1392 | 1394 | ||
| 1393 | static void setup_received_irq(struct fsl_udc *udc, | 1395 | static void setup_received_irq(struct fsl_udc *udc, |
| 1394 | struct usb_ctrlrequest *setup) | 1396 | struct usb_ctrlrequest *setup) |
| 1397 | __releases(udc->lock) | ||
| 1398 | __acquires(udc->lock) | ||
| 1395 | { | 1399 | { |
| 1396 | u16 wValue = le16_to_cpu(setup->wValue); | 1400 | u16 wValue = le16_to_cpu(setup->wValue); |
| 1397 | u16 wIndex = le16_to_cpu(setup->wIndex); | 1401 | u16 wIndex = le16_to_cpu(setup->wIndex); |
| @@ -1957,8 +1961,7 @@ static int fsl_udc_start(struct usb_gadget *g, · 559 unmodified lines | |||
| 1957 | &udc_controller->gadget); | 1961 | &udc_controller->gadget); |
| 1958 | if (retval < 0) { | 1962 | if (retval < 0) { |
| 1959 | ERR("can't bind to transceiver\n"); | 1963 | ERR("can't bind to transceiver\n"); |
| 1960 | driver->unbind(&udc_controller->gadget); | 1964 | udc_controller->driver = NULL; |
| 1961 | udc_controller->driver = 0; | ||
| 1962 | return retval; | 1965 | return retval; |
| 1963 | } | 1966 | } |
| 1964 | } | 1967 | } |
| @@ -2246,7 +2249,7 @@ static void fsl_udc_release(struct device *dev) · 281 unmodified lines | |||
| 2246 | * init resource for globle controller | 2249 | * init resource for globle controller |
| 2247 | * Return the udc handle on success or NULL on failure | 2250 | * Return the udc handle on success or NULL on failure |
| 2248 | ------------------------------------------------------------------*/ | 2251 | ------------------------------------------------------------------*/ |
| 2249 | static int __init struct_udc_setup(struct fsl_udc *udc, | 2252 | static int struct_udc_setup(struct fsl_udc *udc, |
| 2250 | struct platform_device *pdev) | 2253 | struct platform_device *pdev) |
| 2251 | { | 2254 | { |
| 2252 | struct fsl_usb2_platform_data *pdata; | 2255 | struct fsl_usb2_platform_data *pdata; |
| @@ -2298,7 +2301,7 @@ static int __init struct_udc_setup(struct fsl_udc *udc, · 45 unmodified lines | |||
| 2298 | * ep0out is not used so do nothing here | 2301 | * ep0out is not used so do nothing here |
| 2299 | * ep0in should be taken care | 2302 | * ep0in should be taken care |
| 2300 | *--------------------------------------------------------------*/ | 2303 | *--------------------------------------------------------------*/ |
| 2301 | static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, | 2304 | static int struct_ep_setup(struct fsl_udc *udc, unsigned char index, |
| 2302 | char *name, int link) | 2305 | char *name, int link) |
| 2303 | { | 2306 | { |
| 2304 | struct fsl_ep *ep = &udc->eps[index]; | 2307 | struct fsl_ep *ep = &udc->eps[index]; |
| @@ -2331,7 +2334,7 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, · 26 unmodified lines | |||
| 2331 | * all intialization operations implemented here except enabling usb_intr reg | 2334 | * all intialization operations implemented here except enabling usb_intr reg |
| 2332 | * board setup should have been done in the platform code | 2335 | * board setup should have been done in the platform code |
| 2333 | */ | 2336 | */ |
| 2334 | static int __init fsl_udc_probe(struct platform_device *pdev) | 2337 | static int fsl_udc_probe(struct platform_device *pdev) |
| 2335 | { | 2338 | { |
| 2336 | struct fsl_usb2_platform_data *pdata; | 2339 | struct fsl_usb2_platform_data *pdata; |
| 2337 | struct resource *res; | 2340 | struct resource *res; |
| @@ -2380,7 +2383,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) · 42 unmodified lines | |||
| 2380 | goto err_release_mem_region; | 2383 | goto err_release_mem_region; |
| 2381 | } | 2384 | } |
| 2382 | 2385 | ||
| 2383 | pdata->regs = (void *)dr_regs; | 2386 | pdata->regs = (void __iomem *)dr_regs; |
| 2384 | 2387 | ||
| 2385 | /* | 2388 | /* |
| 2386 | * do platform specific init: check the clock, grab/config pins, etc. | 2389 | * do platform specific init: check the clock, grab/config pins, etc. |
| @@ -12,6 +12,9 @@ · 11 unmodified lines | |||
| 12 | #ifndef __FSL_USB2_UDC_H | 12 | #ifndef __FSL_USB2_UDC_H |
| 13 | #define __FSL_USB2_UDC_H | 13 | #define __FSL_USB2_UDC_H |
| 14 | 14 | ||
| 15 | #include <linux/usb/ch9.h> | ||
| 16 | #include <linux/usb/gadget.h> | ||
| 17 | |||
| 15 | /* ### define USB registers here | 18 | /* ### define USB registers here |
| 16 | */ | 19 | */ |
| 17 | #define USB_MAX_CTRL_PAYLOAD 64 | 20 | #define USB_MAX_CTRL_PAYLOAD 64 |
| @@ -1325,8 +1325,6 @@ static int fusb300_udc_stop(struct usb_gadget *g, · 1324 unmodified lines | |||
| 1325 | { | 1325 | { |
| 1326 | struct fusb300 *fusb300 = to_fusb300(g); | 1326 | struct fusb300 *fusb300 = to_fusb300(g); |
| 1327 | 1327 | ||
| 1328 | driver->unbind(&fusb300->gadget); | ||
| 1329 | |||
| 1330 | init_controller(fusb300); | 1328 | init_controller(fusb300); |
| 1331 | fusb300->driver = NULL; | 1329 | fusb300->driver = NULL; |
| 1332 | 1330 | ||
| @@ -1359,7 +1357,7 @@ static int __exit fusb300_remove(struct platform_device *pdev) · 26 unmodified lines | |||
| 1359 | return 0; | 1357 | return 0; |
| 1360 | } | 1358 | } |
| 1361 | 1359 | ||
| 1362 | static int __init fusb300_probe(struct platform_device *pdev) | 1360 | static int fusb300_probe(struct platform_device *pdev) |
| 1363 | { | 1361 | { |
| 1364 | struct resource *res, *ires, *ires1; | 1362 | struct resource *res, *ires, *ires1; |
| 1365 | void __iomem *reg = NULL; | 1363 | void __iomem *reg = NULL; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -2213,7 +2213,7 @@ out: · 2212 unmodified lines | |||
| 2213 | return retval; | 2213 | return retval; |
| 2214 | } | 2214 | } |
| 2215 | 2215 | ||
| 2216 | static struct of_device_id gr_match[] = { | 2216 | static const struct of_device_id gr_match[] = { |
| 2217 | {.name = "GAISLER_USBDC"}, | 2217 | {.name = "GAISLER_USBDC"}, |
| 2218 | {.name = "01_021"}, | 2218 | {.name = "01_021"}, |
| 2219 | {}, | 2219 | {}, |
File renamed without changes.
| @@ -3036,7 +3036,7 @@ struct lpc32xx_usbd_cfg lpc32xx_usbddata = { · 3035 unmodified lines | |||
| 3036 | 3036 | ||
| 3037 | static u64 lpc32xx_usbd_dmamask = ~(u32) 0x7F; | 3037 | static u64 lpc32xx_usbd_dmamask = ~(u32) 0x7F; |
| 3038 | 3038 | ||
| 3039 | static int __init lpc32xx_udc_probe(struct platform_device *pdev) | 3039 | static int lpc32xx_udc_probe(struct platform_device *pdev) |
| 3040 | { | 3040 | { |
| 3041 | struct device *dev = &pdev->dev; | 3041 | struct device *dev = &pdev->dev; |
| 3042 | struct lpc32xx_udc *udc; | 3042 | struct lpc32xx_udc *udc; |
| @@ -3045,11 +3045,10 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 3045 | dma_addr_t dma_handle; | 3045 | dma_addr_t dma_handle; |
| 3046 | struct device_node *isp1301_node; | 3046 | struct device_node *isp1301_node; |
| 3047 | 3047 | ||
| 3048 | udc = kzalloc(sizeof(*udc), GFP_KERNEL); | 3048 | udc = kmemdup(&controller_template, sizeof(*udc), GFP_KERNEL); |
| 3049 | if (!udc) | 3049 | if (!udc) |
| 3050 | return -ENOMEM; | 3050 | return -ENOMEM; |
| 3051 | 3051 | ||
| 3052 | memcpy(udc, &controller_template, sizeof(*udc)); | ||
| 3053 | for (i = 0; i <= 15; i++) | 3052 | for (i = 0; i <= 15; i++) |
| 3054 | udc->ep[i].udc = udc; | 3053 | udc->ep[i].udc = udc; |
| 3055 | udc->gadget.ep0 = &udc->ep[0].ep; | 3054 | udc->gadget.ep0 = &udc->ep[0].ep; |
| @@ -3397,7 +3396,7 @@ static int lpc32xx_udc_resume(struct platform_device *pdev) · 341 unmodified lines | |||
| 3397 | #endif | 3396 | #endif |
| 3398 | 3397 | ||
| 3399 | #ifdef CONFIG_OF | 3398 | #ifdef CONFIG_OF |
| 3400 | static struct of_device_id lpc32xx_udc_of_match[] = { | 3399 | static const struct of_device_id lpc32xx_udc_of_match[] = { |
| 3401 | { .compatible = "nxp,lpc3220-udc", }, | 3400 | { .compatible = "nxp,lpc3220-udc", }, |
| 3402 | { }, | 3401 | { }, |
| 3403 | }; | 3402 | }; |
| @@ -1492,8 +1492,6 @@ static int m66592_udc_stop(struct usb_gadget *g, · 1491 unmodified lines | |||
| 1492 | 1492 | ||
| 1493 | m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); | 1493 | m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); |
| 1494 | 1494 | ||
| 1495 | driver->unbind(&m66592->gadget); | ||
| 1496 | |||
| 1497 | init_controller(m66592); | 1495 | init_controller(m66592); |
| 1498 | disable_controller(m66592); | 1496 | disable_controller(m66592); |
| 1499 | 1497 | ||
| @@ -1553,7 +1551,7 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r) · 53 unmodified lines | |||
| 1553 | { | 1551 | { |
| 1554 | } | 1552 | } |
| 1555 | 1553 | ||
| 1556 | static int __init m66592_probe(struct platform_device *pdev) | 1554 | static int m66592_probe(struct platform_device *pdev) |
| 1557 | { | 1555 | { |
| 1558 | struct resource *res, *ires; | 1556 | struct resource *res, *ires; |
| 1559 | void __iomem *reg = NULL; | 1557 | void __iomem *reg = NULL; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -1453,7 +1453,7 @@ static int net2272_start(struct usb_gadget *_gadget, · 1452 unmodified lines | |||
| 1453 | struct net2272 *dev; | 1453 | struct net2272 *dev; |
| 1454 | unsigned i; | 1454 | unsigned i; |
| 1455 | 1455 | ||
| 1456 | if (!driver || !driver->unbind || !driver->setup || | 1456 | if (!driver || !driver->setup || |
| 1457 | driver->max_speed != USB_SPEED_HIGH) | 1457 | driver->max_speed != USB_SPEED_HIGH) |
| 1458 | return -EINVAL; | 1458 | return -EINVAL; |
| 1459 | 1459 | ||
File renamed without changes.
| @@ -0,0 +1,3827 @@ | |||
| 1 | /* | ||
| 2 | * Driver for the PLX NET2280 USB device controller. | ||
| 3 | * Specs and errata are available from <http://www.plxtech.com>. | ||
| 4 | * | ||
| 5 | * PLX Technology Inc. (formerly NetChip Technology) supported the | ||
| 6 | * development of this driver. | ||
| 7 | * | ||
| 8 | * | ||
| 9 | * CODE STATUS HIGHLIGHTS | ||
| 10 | * | ||
| 11 | * This driver should work well with most "gadget" drivers, including | ||
| 12 | * the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers | ||
| 13 | * as well as Gadget Zero and Gadgetfs. | ||
| 14 | * | ||
| 15 | * DMA is enabled by default. Drivers using transfer queues might use | ||
| 16 | * DMA chaining to remove IRQ latencies between transfers. (Except when | ||
| 17 | * short OUT transfers happen.) Drivers can use the req->no_interrupt | ||
| 18 | * hint to completely eliminate some IRQs, if a later IRQ is guaranteed | ||
| 19 | * and DMA chaining is enabled. | ||
| 20 | * | ||
| 21 | * MSI is enabled by default. The legacy IRQ is used if MSI couldn't | ||
| 22 | * be enabled. | ||
| 23 | * | ||
| 24 | * Note that almost all the errata workarounds here are only needed for | ||
| 25 | * rev1 chips. Rev1a silicon (0110) fixes almost all of them. | ||
| 26 | */ | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Copyright (C) 2003 David Brownell | ||
| 30 | * Copyright (C) 2003-2005 PLX Technology, Inc. | ||
| 31 | * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS | ||
| 32 | * | ||
| 33 | * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility | ||
| 34 | * with 2282 chip | ||
| 35 | * | ||
| 36 | * Modified Ricardo Ribalda Qtechnology AS to provide compatibility | ||
| 37 | * with usb 338x chip. Based on PLX driver | ||
| 38 | * | ||
| 39 | * This program is free software; you can redistribute it and/or modify | ||
| 40 | * it under the terms of the GNU General Public License as published by | ||
| 41 | * the Free Software Foundation; either version 2 of the License, or | ||
| 42 | * (at your option) any later version. | ||
| 43 | */ | ||
| 44 | |||
| 45 | #include <linux/module.h> | ||
| 46 | #include <linux/pci.h> | ||
| 47 | #include <linux/dma-mapping.h> | ||
| 48 | #include <linux/kernel.h> | ||
| 49 | #include <linux/delay.h> | ||
| 50 | #include <linux/ioport.h> | ||
| 51 | #include <linux/slab.h> | ||
| 52 | #include <linux/errno.h> | ||
| 53 | #include <linux/init.h> | ||
| 54 | #include <linux/timer.h> | ||
| 55 | #include <linux/list.h> | ||
| 56 | #include <linux/interrupt.h> | ||
| 57 | #include <linux/moduleparam.h> | ||
| 58 | #include <linux/device.h> | ||
| 59 | #include <linux/usb/ch9.h> | ||
| 60 | #include <linux/usb/gadget.h> | ||
| 61 | #include <linux/prefetch.h> | ||
| 62 | #include <linux/io.h> | ||
| 63 | |||
| 64 | #include <asm/byteorder.h> | ||
| 65 | #include <asm/irq.h> | ||
| 66 | #include <asm/unaligned.h> | ||
| 67 | |||
| 68 | #define DRIVER_DESC "PLX NET228x/USB338x USB Peripheral Controller" | ||
| 69 | #define DRIVER_VERSION "2005 Sept 27/v3.0" | ||
| 70 | |||
| 71 | #define EP_DONTUSE 13 /* nonzero */ | ||
| 72 | |||
| 73 | #define USE_RDK_LEDS /* GPIO pins control three LEDs */ | ||
| 74 | |||
| 75 | |||
| 76 | static const char driver_name[] = "net2280"; | ||
| 77 | static const char driver_desc[] = DRIVER_DESC; | ||
| 78 | |||
| 79 | static const u32 ep_bit[9] = { 0, 17, 2, 19, 4, 1, 18, 3, 20 }; | ||
| 80 | static const char ep0name[] = "ep0"; | ||
| 81 | static const char *const ep_name[] = { | ||
| 82 | ep0name, | ||
| 83 | "ep-a", "ep-b", "ep-c", "ep-d", | ||
| 84 | "ep-e", "ep-f", "ep-g", "ep-h", | ||
| 85 | }; | ||
| 86 | |||
| 87 | /* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO) | ||
| 88 | * use_dma_chaining -- dma descriptor queueing gives even more irq reduction | ||
| 89 | * | ||
| 90 | * The net2280 DMA engines are not tightly integrated with their FIFOs; | ||
| 91 | * not all cases are (yet) handled well in this driver or the silicon. | ||
| 92 | * Some gadget drivers work better with the dma support here than others. | ||
| 93 | * These two parameters let you use PIO or more aggressive DMA. | ||
| 94 | */ | ||
| 95 | static bool use_dma = true; | ||
| 96 | static bool use_dma_chaining; | ||
| 97 | static bool use_msi = true; | ||
| 98 | |||
| 99 | /* "modprobe net2280 use_dma=n" etc */ | ||
| 100 | module_param(use_dma, bool, 0444); | ||
| 101 | module_param(use_dma_chaining, bool, 0444); | ||
| 102 | module_param(use_msi, bool, 0444); | ||
| 103 | |||
| 104 | /* mode 0 == ep-{a,b,c,d} 1K fifo each | ||
| 105 | * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable | ||
| 106 | * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable | ||
| 107 | */ | ||
| 108 | static ushort fifo_mode; | ||
| 109 | |||
| 110 | /* "modprobe net2280 fifo_mode=1" etc */ | ||
| 111 | module_param(fifo_mode, ushort, 0644); | ||
| 112 | |||
| 113 | /* enable_suspend -- When enabled, the driver will respond to | ||
| 114 | * USB suspend requests by powering down the NET2280. Otherwise, | ||
| 115 | * USB suspend requests will be ignored. This is acceptable for | ||
| 116 | * self-powered devices | ||
| 117 | */ | ||
| 118 | static bool enable_suspend; | ||
| 119 | |||
| 120 | /* "modprobe net2280 enable_suspend=1" etc */ | ||
| 121 | module_param(enable_suspend, bool, 0444); | ||
| 122 | |||
| 123 | /* force full-speed operation */ | ||
| 124 | static bool full_speed; | ||
| 125 | module_param(full_speed, bool, 0444); | ||
| 126 | MODULE_PARM_DESC(full_speed, "force full-speed mode -- for testing only!"); | ||
| 127 | |||
| 128 | #define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out") | ||
| 129 | |||
| 130 | static char *type_string(u8 bmAttributes) | ||
| 131 | { | ||
| 132 | switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) { | ||
| 133 | case USB_ENDPOINT_XFER_BULK: return "bulk"; | ||
| 134 | case USB_ENDPOINT_XFER_ISOC: return "iso"; | ||
| 135 | case USB_ENDPOINT_XFER_INT: return "intr"; | ||
| 136 | } | ||
| 137 | return "control"; | ||
| 138 | } | ||
| 139 | |||
| 140 | #include "net2280.h" | ||
| 141 | |||
| 142 | #define valid_bit cpu_to_le32(BIT(VALID_BIT)) | ||
| 143 | #define dma_done_ie cpu_to_le32(BIT(DMA_DONE_INTERRUPT_ENABLE)) | ||
| 144 | |||
| 145 | /*-------------------------------------------------------------------------*/ | ||
| 146 | static inline void enable_pciirqenb(struct net2280_ep *ep) | ||
| 147 | { | ||
| 148 | u32 tmp = readl(&ep->dev->regs->pciirqenb0); | ||
| 149 | |||
| 150 | if (ep->dev->quirks & PLX_LEGACY) | ||
| 151 | tmp |= BIT(ep->num); | ||
| 152 | else | ||
| 153 | tmp |= BIT(ep_bit[ep->num]); | ||
| 154 | writel(tmp, &ep->dev->regs->pciirqenb0); | ||
| 155 | |||
| 156 | return; | ||
| 157 | } | ||
| 158 | |||
| 159 | static int | ||
| 160 | net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | ||
| 161 | { | ||
| 162 | struct net2280 *dev; | ||
| 163 | struct net2280_ep *ep; | ||
| 164 | u32 max, tmp; | ||
| 165 | unsigned long flags; | ||
| 166 | static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 }; | ||
| 167 | |||
| 168 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 169 | if (!_ep || !desc || ep->desc || _ep->name == ep0name || | ||
| 170 | desc->bDescriptorType != USB_DT_ENDPOINT) | ||
| 171 | return -EINVAL; | ||
| 172 | dev = ep->dev; | ||
| 173 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 174 | return -ESHUTDOWN; | ||
| 175 | |||
| 176 | /* erratum 0119 workaround ties up an endpoint number */ | ||
| 177 | if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) | ||
| 178 | return -EDOM; | ||
| 179 | |||
| 180 | if (dev->quirks & PLX_SUPERSPEED) { | ||
| 181 | if ((desc->bEndpointAddress & 0x0f) >= 0x0c) | ||
| 182 | return -EDOM; | ||
| 183 | ep->is_in = !!usb_endpoint_dir_in(desc); | ||
| 184 | if (dev->enhanced_mode && ep->is_in && ep_key[ep->num]) | ||
| 185 | return -EINVAL; | ||
| 186 | } | ||
| 187 | |||
| 188 | /* sanity check ep-e/ep-f since their fifos are small */ | ||
| 189 | max = usb_endpoint_maxp(desc) & 0x1fff; | ||
| 190 | if (ep->num > 4 && max > 64 && (dev->quirks & PLX_LEGACY)) | ||
| 191 | return -ERANGE; | ||
| 192 | |||
| 193 | spin_lock_irqsave(&dev->lock, flags); | ||
| 194 | _ep->maxpacket = max & 0x7ff; | ||
| 195 | ep->desc = desc; | ||
| 196 | |||
| 197 | /* ep_reset() has already been called */ | ||
| 198 | ep->stopped = 0; | ||
| 199 | ep->wedged = 0; | ||
| 200 | ep->out_overflow = 0; | ||
| 201 | |||
| 202 | /* set speed-dependent max packet; may kick in high bandwidth */ | ||
| 203 | set_max_speed(ep, max); | ||
| 204 | |||
| 205 | /* FIFO lines can't go to different packets. PIO is ok, so | ||
| 206 | * use it instead of troublesome (non-bulk) multi-packet DMA. | ||
| 207 | */ | ||
| 208 | if (ep->dma && (max % 4) != 0 && use_dma_chaining) { | ||
| 209 | ep_dbg(ep->dev, "%s, no dma for maxpacket %d\n", | ||
| 210 | ep->ep.name, ep->ep.maxpacket); | ||
| 211 | ep->dma = NULL; | ||
| 212 | } | ||
| 213 | |||
| 214 | /* set type, direction, address; reset fifo counters */ | ||
| 215 | writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); | ||
| 216 | tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | ||
| 217 | if (tmp == USB_ENDPOINT_XFER_INT) { | ||
| 218 | /* erratum 0105 workaround prevents hs NYET */ | ||
| 219 | if (dev->chiprev == 0100 && | ||
| 220 | dev->gadget.speed == USB_SPEED_HIGH && | ||
| 221 | !(desc->bEndpointAddress & USB_DIR_IN)) | ||
| 222 | writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE), | ||
| 223 | &ep->regs->ep_rsp); | ||
| 224 | } else if (tmp == USB_ENDPOINT_XFER_BULK) { | ||
| 225 | /* catch some particularly blatant driver bugs */ | ||
| 226 | if ((dev->gadget.speed == USB_SPEED_SUPER && max != 1024) || | ||
| 227 | (dev->gadget.speed == USB_SPEED_HIGH && max != 512) || | ||
| 228 | (dev->gadget.speed == USB_SPEED_FULL && max > 64)) { | ||
| 229 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 230 | return -ERANGE; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC); | ||
| 234 | /* Enable this endpoint */ | ||
| 235 | if (dev->quirks & PLX_LEGACY) { | ||
| 236 | tmp <<= ENDPOINT_TYPE; | ||
| 237 | tmp |= desc->bEndpointAddress; | ||
| 238 | /* default full fifo lines */ | ||
| 239 | tmp |= (4 << ENDPOINT_BYTE_COUNT); | ||
| 240 | tmp |= BIT(ENDPOINT_ENABLE); | ||
| 241 | ep->is_in = (tmp & USB_DIR_IN) != 0; | ||
| 242 | } else { | ||
| 243 | /* In Legacy mode, only OUT endpoints are used */ | ||
| 244 | if (dev->enhanced_mode && ep->is_in) { | ||
| 245 | tmp <<= IN_ENDPOINT_TYPE; | ||
| 246 | tmp |= BIT(IN_ENDPOINT_ENABLE); | ||
| 247 | /* Not applicable to Legacy */ | ||
| 248 | tmp |= BIT(ENDPOINT_DIRECTION); | ||
| 249 | } else { | ||
| 250 | tmp <<= OUT_ENDPOINT_TYPE; | ||
| 251 | tmp |= BIT(OUT_ENDPOINT_ENABLE); | ||
| 252 | tmp |= (ep->is_in << ENDPOINT_DIRECTION); | ||
| 253 | } | ||
| 254 | |||
| 255 | tmp |= usb_endpoint_num(desc); | ||
| 256 | tmp |= (ep->ep.maxburst << MAX_BURST_SIZE); | ||
| 257 | } | ||
| 258 | |||
| 259 | /* Make sure all the registers are written before ep_rsp*/ | ||
| 260 | wmb(); | ||
| 261 | |||
| 262 | /* for OUT transfers, block the rx fifo until a read is posted */ | ||
| 263 | if (!ep->is_in) | ||
| 264 | writel(BIT(SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 265 | else if (!(dev->quirks & PLX_2280)) { | ||
| 266 | /* Added for 2282, Don't use nak packets on an in endpoint, | ||
| 267 | * this was ignored on 2280 | ||
| 268 | */ | ||
| 269 | writel(BIT(CLEAR_NAK_OUT_PACKETS) | | ||
| 270 | BIT(CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); | ||
| 271 | } | ||
| 272 | |||
| 273 | writel(tmp, &ep->cfg->ep_cfg); | ||
| 274 | |||
| 275 | /* enable irqs */ | ||
| 276 | if (!ep->dma) { /* pio, per-packet */ | ||
| 277 | enable_pciirqenb(ep); | ||
| 278 | |||
| 279 | tmp = BIT(DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) | | ||
| 280 | BIT(DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE); | ||
| 281 | if (dev->quirks & PLX_2280) | ||
| 282 | tmp |= readl(&ep->regs->ep_irqenb); | ||
| 283 | writel(tmp, &ep->regs->ep_irqenb); | ||
| 284 | } else { /* dma, per-request */ | ||
| 285 | tmp = BIT((8 + ep->num)); /* completion */ | ||
| 286 | tmp |= readl(&dev->regs->pciirqenb1); | ||
| 287 | writel(tmp, &dev->regs->pciirqenb1); | ||
| 288 | |||
| 289 | /* for short OUT transfers, dma completions can't | ||
| 290 | * advance the queue; do it pio-style, by hand. | ||
| 291 | * NOTE erratum 0112 workaround #2 | ||
| 292 | */ | ||
| 293 | if ((desc->bEndpointAddress & USB_DIR_IN) == 0) { | ||
| 294 | tmp = BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE); | ||
| 295 | writel(tmp, &ep->regs->ep_irqenb); | ||
| 296 | |||
| 297 | enable_pciirqenb(ep); | ||
| 298 | } | ||
| 299 | } | ||
| 300 | |||
| 301 | tmp = desc->bEndpointAddress; | ||
| 302 | ep_dbg(dev, "enabled %s (ep%d%s-%s) %s max %04x\n", | ||
| 303 | _ep->name, tmp & 0x0f, DIR_STRING(tmp), | ||
| 304 | type_string(desc->bmAttributes), | ||
| 305 | ep->dma ? "dma" : "pio", max); | ||
| 306 | |||
| 307 | /* pci writes may still be posted */ | ||
| 308 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 309 | return 0; | ||
| 310 | } | ||
| 311 | |||
| 312 | static int handshake(u32 __iomem *ptr, u32 mask, u32 done, int usec) | ||
| 313 | { | ||
| 314 | u32 result; | ||
| 315 | |||
| 316 | do { | ||
| 317 | result = readl(ptr); | ||
| 318 | if (result == ~(u32)0) /* "device unplugged" */ | ||
| 319 | return -ENODEV; | ||
| 320 | result &= mask; | ||
| 321 | if (result == done) | ||
| 322 | return 0; | ||
| 323 | udelay(1); | ||
| 324 | usec--; | ||
| 325 | } while (usec > 0); | ||
| 326 | return -ETIMEDOUT; | ||
| 327 | } | ||
| 328 | |||
| 329 | static const struct usb_ep_ops net2280_ep_ops; | ||
| 330 | |||
| 331 | static void ep_reset_228x(struct net2280_regs __iomem *regs, | ||
| 332 | struct net2280_ep *ep) | ||
| 333 | { | ||
| 334 | u32 tmp; | ||
| 335 | |||
| 336 | ep->desc = NULL; | ||
| 337 | INIT_LIST_HEAD(&ep->queue); | ||
| 338 | |||
| 339 | usb_ep_set_maxpacket_limit(&ep->ep, ~0); | ||
| 340 | ep->ep.ops = &net2280_ep_ops; | ||
| 341 | |||
| 342 | /* disable the dma, irqs, endpoint... */ | ||
| 343 | if (ep->dma) { | ||
| 344 | writel(0, &ep->dma->dmactl); | ||
| 345 | writel(BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) | | ||
| 346 | BIT(DMA_TRANSACTION_DONE_INTERRUPT) | | ||
| 347 | BIT(DMA_ABORT), | ||
| 348 | &ep->dma->dmastat); | ||
| 349 | |||
| 350 | tmp = readl(®s->pciirqenb0); | ||
| 351 | tmp &= ~BIT(ep->num); | ||
| 352 | writel(tmp, ®s->pciirqenb0); | ||
| 353 | } else { | ||
| 354 | tmp = readl(®s->pciirqenb1); | ||
| 355 | tmp &= ~BIT((8 + ep->num)); /* completion */ | ||
| 356 | writel(tmp, ®s->pciirqenb1); | ||
| 357 | } | ||
| 358 | writel(0, &ep->regs->ep_irqenb); | ||
| 359 | |||
| 360 | /* init to our chosen defaults, notably so that we NAK OUT | ||
| 361 | * packets until the driver queues a read (+note erratum 0112) | ||
| 362 | */ | ||
| 363 | if (!ep->is_in || (ep->dev->quirks & PLX_2280)) { | ||
| 364 | tmp = BIT(SET_NAK_OUT_PACKETS_MODE) | | ||
| 365 | BIT(SET_NAK_OUT_PACKETS) | | ||
| 366 | BIT(CLEAR_EP_HIDE_STATUS_PHASE) | | ||
| 367 | BIT(CLEAR_INTERRUPT_MODE); | ||
| 368 | } else { | ||
| 369 | /* added for 2282 */ | ||
| 370 | tmp = BIT(CLEAR_NAK_OUT_PACKETS_MODE) | | ||
| 371 | BIT(CLEAR_NAK_OUT_PACKETS) | | ||
| 372 | BIT(CLEAR_EP_HIDE_STATUS_PHASE) | | ||
| 373 | BIT(CLEAR_INTERRUPT_MODE); | ||
| 374 | } | ||
| 375 | |||
| 376 | if (ep->num != 0) { | ||
| 377 | tmp |= BIT(CLEAR_ENDPOINT_TOGGLE) | | ||
| 378 | BIT(CLEAR_ENDPOINT_HALT); | ||
| 379 | } | ||
| 380 | writel(tmp, &ep->regs->ep_rsp); | ||
| 381 | |||
| 382 | /* scrub most status bits, and flush any fifo state */ | ||
| 383 | if (ep->dev->quirks & PLX_2280) | ||
| 384 | tmp = BIT(FIFO_OVERFLOW) | | ||
| 385 | BIT(FIFO_UNDERFLOW); | ||
| 386 | else | ||
| 387 | tmp = 0; | ||
| 388 | |||
| 389 | writel(tmp | BIT(TIMEOUT) | | ||
| 390 | BIT(USB_STALL_SENT) | | ||
| 391 | BIT(USB_IN_NAK_SENT) | | ||
| 392 | BIT(USB_IN_ACK_RCVD) | | ||
| 393 | BIT(USB_OUT_PING_NAK_SENT) | | ||
| 394 | BIT(USB_OUT_ACK_SENT) | | ||
| 395 | BIT(FIFO_FLUSH) | | ||
| 396 | BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) | | ||
| 397 | BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) | | ||
| 398 | BIT(DATA_PACKET_RECEIVED_INTERRUPT) | | ||
| 399 | BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) | | ||
| 400 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 401 | BIT(DATA_IN_TOKEN_INTERRUPT), | ||
| 402 | &ep->regs->ep_stat); | ||
| 403 | |||
| 404 | /* fifo size is handled separately */ | ||
| 405 | } | ||
| 406 | |||
| 407 | static void ep_reset_338x(struct net2280_regs __iomem *regs, | ||
| 408 | struct net2280_ep *ep) | ||
| 409 | { | ||
| 410 | u32 tmp, dmastat; | ||
| 411 | |||
| 412 | ep->desc = NULL; | ||
| 413 | INIT_LIST_HEAD(&ep->queue); | ||
| 414 | |||
| 415 | usb_ep_set_maxpacket_limit(&ep->ep, ~0); | ||
| 416 | ep->ep.ops = &net2280_ep_ops; | ||
| 417 | |||
| 418 | /* disable the dma, irqs, endpoint... */ | ||
| 419 | if (ep->dma) { | ||
| 420 | writel(0, &ep->dma->dmactl); | ||
| 421 | writel(BIT(DMA_ABORT_DONE_INTERRUPT) | | ||
| 422 | BIT(DMA_PAUSE_DONE_INTERRUPT) | | ||
| 423 | BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) | | ||
| 424 | BIT(DMA_TRANSACTION_DONE_INTERRUPT), | ||
| 425 | /* | BIT(DMA_ABORT), */ | ||
| 426 | &ep->dma->dmastat); | ||
| 427 | |||
| 428 | dmastat = readl(&ep->dma->dmastat); | ||
| 429 | if (dmastat == 0x5002) { | ||
| 430 | ep_warn(ep->dev, "The dmastat return = %x!!\n", | ||
| 431 | dmastat); | ||
| 432 | writel(0x5a, &ep->dma->dmastat); | ||
| 433 | } | ||
| 434 | |||
| 435 | tmp = readl(®s->pciirqenb0); | ||
| 436 | tmp &= ~BIT(ep_bit[ep->num]); | ||
| 437 | writel(tmp, ®s->pciirqenb0); | ||
| 438 | } else { | ||
| 439 | if (ep->num < 5) { | ||
| 440 | tmp = readl(®s->pciirqenb1); | ||
| 441 | tmp &= ~BIT((8 + ep->num)); /* completion */ | ||
| 442 | writel(tmp, ®s->pciirqenb1); | ||
| 443 | } | ||
| 444 | } | ||
| 445 | writel(0, &ep->regs->ep_irqenb); | ||
| 446 | |||
| 447 | writel(BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) | | ||
| 448 | BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) | | ||
| 449 | BIT(FIFO_OVERFLOW) | | ||
| 450 | BIT(DATA_PACKET_RECEIVED_INTERRUPT) | | ||
| 451 | BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) | | ||
| 452 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 453 | BIT(DATA_IN_TOKEN_INTERRUPT), &ep->regs->ep_stat); | ||
| 454 | } | ||
| 455 | |||
| 456 | static void nuke(struct net2280_ep *); | ||
| 457 | |||
| 458 | static int net2280_disable(struct usb_ep *_ep) | ||
| 459 | { | ||
| 460 | struct net2280_ep *ep; | ||
| 461 | unsigned long flags; | ||
| 462 | |||
| 463 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 464 | if (!_ep || !ep->desc || _ep->name == ep0name) | ||
| 465 | return -EINVAL; | ||
| 466 | |||
| 467 | spin_lock_irqsave(&ep->dev->lock, flags); | ||
| 468 | nuke(ep); | ||
| 469 | |||
| 470 | if (ep->dev->quirks & PLX_SUPERSPEED) | ||
| 471 | ep_reset_338x(ep->dev->regs, ep); | ||
| 472 | else | ||
| 473 | ep_reset_228x(ep->dev->regs, ep); | ||
| 474 | |||
| 475 | ep_vdbg(ep->dev, "disabled %s %s\n", | ||
| 476 | ep->dma ? "dma" : "pio", _ep->name); | ||
| 477 | |||
| 478 | /* synch memory views with the device */ | ||
| 479 | (void)readl(&ep->cfg->ep_cfg); | ||
| 480 | |||
| 481 | if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4) | ||
| 482 | ep->dma = &ep->dev->dma[ep->num - 1]; | ||
| 483 | |||
| 484 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | /*-------------------------------------------------------------------------*/ | ||
| 489 | |||
| 490 | static struct usb_request | ||
| 491 | *net2280_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) | ||
| 492 | { | ||
| 493 | struct net2280_ep *ep; | ||
| 494 | struct net2280_request *req; | ||
| 495 | |||
| 496 | if (!_ep) | ||
| 497 | return NULL; | ||
| 498 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 499 | |||
| 500 | req = kzalloc(sizeof(*req), gfp_flags); | ||
| 501 | if (!req) | ||
| 502 | return NULL; | ||
| 503 | |||
| 504 | INIT_LIST_HEAD(&req->queue); | ||
| 505 | |||
| 506 | /* this dma descriptor may be swapped with the previous dummy */ | ||
| 507 | if (ep->dma) { | ||
| 508 | struct net2280_dma *td; | ||
| 509 | |||
| 510 | td = pci_pool_alloc(ep->dev->requests, gfp_flags, | ||
| 511 | &req->td_dma); | ||
| 512 | if (!td) { | ||
| 513 | kfree(req); | ||
| 514 | return NULL; | ||
| 515 | } | ||
| 516 | td->dmacount = 0; /* not VALID */ | ||
| 517 | td->dmadesc = td->dmaaddr; | ||
| 518 | req->td = td; | ||
| 519 | } | ||
| 520 | return &req->req; | ||
| 521 | } | ||
| 522 | |||
| 523 | static void net2280_free_request(struct usb_ep *_ep, struct usb_request *_req) | ||
| 524 | { | ||
| 525 | struct net2280_ep *ep; | ||
| 526 | struct net2280_request *req; | ||
| 527 | |||
| 528 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 529 | if (!_ep || !_req) | ||
| 530 | return; | ||
| 531 | |||
| 532 | req = container_of(_req, struct net2280_request, req); | ||
| 533 | WARN_ON(!list_empty(&req->queue)); | ||
| 534 | if (req->td) | ||
| 535 | pci_pool_free(ep->dev->requests, req->td, req->td_dma); | ||
| 536 | kfree(req); | ||
| 537 | } | ||
| 538 | |||
| 539 | /*-------------------------------------------------------------------------*/ | ||
| 540 | |||
| 541 | /* load a packet into the fifo we use for usb IN transfers. | ||
| 542 | * works for all endpoints. | ||
| 543 | * | ||
| 544 | * NOTE: pio with ep-a..ep-d could stuff multiple packets into the fifo | ||
| 545 | * at a time, but this code is simpler because it knows it only writes | ||
| 546 | * one packet. ep-a..ep-d should use dma instead. | ||
| 547 | */ | ||
| 548 | static void write_fifo(struct net2280_ep *ep, struct usb_request *req) | ||
| 549 | { | ||
| 550 | struct net2280_ep_regs __iomem *regs = ep->regs; | ||
| 551 | u8 *buf; | ||
| 552 | u32 tmp; | ||
| 553 | unsigned count, total; | ||
| 554 | |||
| 555 | /* INVARIANT: fifo is currently empty. (testable) */ | ||
| 556 | |||
| 557 | if (req) { | ||
| 558 | buf = req->buf + req->actual; | ||
| 559 | prefetch(buf); | ||
| 560 | total = req->length - req->actual; | ||
| 561 | } else { | ||
| 562 | total = 0; | ||
| 563 | buf = NULL; | ||
| 564 | } | ||
| 565 | |||
| 566 | /* write just one packet at a time */ | ||
| 567 | count = ep->ep.maxpacket; | ||
| 568 | if (count > total) /* min() cannot be used on a bitfield */ | ||
| 569 | count = total; | ||
| 570 | |||
| 571 | ep_vdbg(ep->dev, "write %s fifo (IN) %d bytes%s req %p\n", | ||
| 572 | ep->ep.name, count, | ||
| 573 | (count != ep->ep.maxpacket) ? " (short)" : "", | ||
| 574 | req); | ||
| 575 | while (count >= 4) { | ||
| 576 | /* NOTE be careful if you try to align these. fifo lines | ||
| 577 | * should normally be full (4 bytes) and successive partial | ||
| 578 | * lines are ok only in certain cases. | ||
| 579 | */ | ||
| 580 | tmp = get_unaligned((u32 *)buf); | ||
| 581 | cpu_to_le32s(&tmp); | ||
| 582 | writel(tmp, ®s->ep_data); | ||
| 583 | buf += 4; | ||
| 584 | count -= 4; | ||
| 585 | } | ||
| 586 | |||
| 587 | /* last fifo entry is "short" unless we wrote a full packet. | ||
| 588 | * also explicitly validate last word in (periodic) transfers | ||
| 589 | * when maxpacket is not a multiple of 4 bytes. | ||
| 590 | */ | ||
| 591 | if (count || total < ep->ep.maxpacket) { | ||
| 592 | tmp = count ? get_unaligned((u32 *)buf) : count; | ||
| 593 | cpu_to_le32s(&tmp); | ||
| 594 | set_fifo_bytecount(ep, count & 0x03); | ||
| 595 | writel(tmp, ®s->ep_data); | ||
| 596 | } | ||
| 597 | |||
| 598 | /* pci writes may still be posted */ | ||
| 599 | } | ||
| 600 | |||
| 601 | /* work around erratum 0106: PCI and USB race over the OUT fifo. | ||
| 602 | * caller guarantees chiprev 0100, out endpoint is NAKing, and | ||
| 603 | * there's no real data in the fifo. | ||
| 604 | * | ||
| 605 | * NOTE: also used in cases where that erratum doesn't apply: | ||
| 606 | * where the host wrote "too much" data to us. | ||
| 607 | */ | ||
| 608 | static void out_flush(struct net2280_ep *ep) | ||
| 609 | { | ||
| 610 | u32 __iomem *statp; | ||
| 611 | u32 tmp; | ||
| 612 | |||
| 613 | ASSERT_OUT_NAKING(ep); | ||
| 614 | |||
| 615 | statp = &ep->regs->ep_stat; | ||
| 616 | writel(BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 617 | BIT(DATA_PACKET_RECEIVED_INTERRUPT), | ||
| 618 | statp); | ||
| 619 | writel(BIT(FIFO_FLUSH), statp); | ||
| 620 | /* Make sure that stap is written */ | ||
| 621 | mb(); | ||
| 622 | tmp = readl(statp); | ||
| 623 | if (tmp & BIT(DATA_OUT_PING_TOKEN_INTERRUPT) && | ||
| 624 | /* high speed did bulk NYET; fifo isn't filling */ | ||
| 625 | ep->dev->gadget.speed == USB_SPEED_FULL) { | ||
| 626 | unsigned usec; | ||
| 627 | |||
| 628 | usec = 50; /* 64 byte bulk/interrupt */ | ||
| 629 | handshake(statp, BIT(USB_OUT_PING_NAK_SENT), | ||
| 630 | BIT(USB_OUT_PING_NAK_SENT), usec); | ||
| 631 | /* NAK done; now CLEAR_NAK_OUT_PACKETS is safe */ | ||
| 632 | } | ||
| 633 | } | ||
| 634 | |||
| 635 | /* unload packet(s) from the fifo we use for usb OUT transfers. | ||
| 636 | * returns true iff the request completed, because of short packet | ||
| 637 | * or the request buffer having filled with full packets. | ||
| 638 | * | ||
| 639 | * for ep-a..ep-d this will read multiple packets out when they | ||
| 640 | * have been accepted. | ||
| 641 | */ | ||
| 642 | static int read_fifo(struct net2280_ep *ep, struct net2280_request *req) | ||
| 643 | { | ||
| 644 | struct net2280_ep_regs __iomem *regs = ep->regs; | ||
| 645 | u8 *buf = req->req.buf + req->req.actual; | ||
| 646 | unsigned count, tmp, is_short; | ||
| 647 | unsigned cleanup = 0, prevent = 0; | ||
| 648 | |||
| 649 | /* erratum 0106 ... packets coming in during fifo reads might | ||
| 650 | * be incompletely rejected. not all cases have workarounds. | ||
| 651 | */ | ||
| 652 | if (ep->dev->chiprev == 0x0100 && | ||
| 653 | ep->dev->gadget.speed == USB_SPEED_FULL) { | ||
| 654 | udelay(1); | ||
| 655 | tmp = readl(&ep->regs->ep_stat); | ||
| 656 | if ((tmp & BIT(NAK_OUT_PACKETS))) | ||
| 657 | cleanup = 1; | ||
| 658 | else if ((tmp & BIT(FIFO_FULL))) { | ||
| 659 | start_out_naking(ep); | ||
| 660 | prevent = 1; | ||
| 661 | } | ||
| 662 | /* else: hope we don't see the problem */ | ||
| 663 | } | ||
| 664 | |||
| 665 | /* never overflow the rx buffer. the fifo reads packets until | ||
| 666 | * it sees a short one; we might not be ready for them all. | ||
| 667 | */ | ||
| 668 | prefetchw(buf); | ||
| 669 | count = readl(®s->ep_avail); | ||
| 670 | if (unlikely(count == 0)) { | ||
| 671 | udelay(1); | ||
| 672 | tmp = readl(&ep->regs->ep_stat); | ||
| 673 | count = readl(®s->ep_avail); | ||
| 674 | /* handled that data already? */ | ||
| 675 | if (count == 0 && (tmp & BIT(NAK_OUT_PACKETS)) == 0) | ||
| 676 | return 0; | ||
| 677 | } | ||
| 678 | |||
| 679 | tmp = req->req.length - req->req.actual; | ||
| 680 | if (count > tmp) { | ||
| 681 | /* as with DMA, data overflow gets flushed */ | ||
| 682 | if ((tmp % ep->ep.maxpacket) != 0) { | ||
| 683 | ep_err(ep->dev, | ||
| 684 | "%s out fifo %d bytes, expected %d\n", | ||
| 685 | ep->ep.name, count, tmp); | ||
| 686 | req->req.status = -EOVERFLOW; | ||
| 687 | cleanup = 1; | ||
| 688 | /* NAK_OUT_PACKETS will be set, so flushing is safe; | ||
| 689 | * the next read will start with the next packet | ||
| 690 | */ | ||
| 691 | } /* else it's a ZLP, no worries */ | ||
| 692 | count = tmp; | ||
| 693 | } | ||
| 694 | req->req.actual += count; | ||
| 695 | |||
| 696 | is_short = (count == 0) || ((count % ep->ep.maxpacket) != 0); | ||
| 697 | |||
| 698 | ep_vdbg(ep->dev, "read %s fifo (OUT) %d bytes%s%s%s req %p %d/%d\n", | ||
| 699 | ep->ep.name, count, is_short ? " (short)" : "", | ||
| 700 | cleanup ? " flush" : "", prevent ? " nak" : "", | ||
| 701 | req, req->req.actual, req->req.length); | ||
| 702 | |||
| 703 | while (count >= 4) { | ||
| 704 | tmp = readl(®s->ep_data); | ||
| 705 | cpu_to_le32s(&tmp); | ||
| 706 | put_unaligned(tmp, (u32 *)buf); | ||
| 707 | buf += 4; | ||
| 708 | count -= 4; | ||
| 709 | } | ||
| 710 | if (count) { | ||
| 711 | tmp = readl(®s->ep_data); | ||
| 712 | /* LE conversion is implicit here: */ | ||
| 713 | do { | ||
| 714 | *buf++ = (u8) tmp; | ||
| 715 | tmp >>= 8; | ||
| 716 | } while (--count); | ||
| 717 | } | ||
| 718 | if (cleanup) | ||
| 719 | out_flush(ep); | ||
| 720 | if (prevent) { | ||
| 721 | writel(BIT(CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 722 | (void) readl(&ep->regs->ep_rsp); | ||
| 723 | } | ||
| 724 | |||
| 725 | return is_short || ((req->req.actual == req->req.length) && | ||
| 726 | !req->req.zero); | ||
| 727 | } | ||
| 728 | |||
| 729 | /* fill out dma descriptor to match a given request */ | ||
| 730 | static void fill_dma_desc(struct net2280_ep *ep, | ||
| 731 | struct net2280_request *req, int valid) | ||
| 732 | { | ||
| 733 | struct net2280_dma *td = req->td; | ||
| 734 | u32 dmacount = req->req.length; | ||
| 735 | |||
| 736 | /* don't let DMA continue after a short OUT packet, | ||
| 737 | * so overruns can't affect the next transfer. | ||
| 738 | * in case of overruns on max-size packets, we can't | ||
| 739 | * stop the fifo from filling but we can flush it. | ||
| 740 | */ | ||
| 741 | if (ep->is_in) | ||
| 742 | dmacount |= BIT(DMA_DIRECTION); | ||
| 743 | if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) || | ||
| 744 | !(ep->dev->quirks & PLX_2280)) | ||
| 745 | dmacount |= BIT(END_OF_CHAIN); | ||
| 746 | |||
| 747 | req->valid = valid; | ||
| 748 | if (valid) | ||
| 749 | dmacount |= BIT(VALID_BIT); | ||
| 750 | if (likely(!req->req.no_interrupt || !use_dma_chaining)) | ||
| 751 | dmacount |= BIT(DMA_DONE_INTERRUPT_ENABLE); | ||
| 752 | |||
| 753 | /* td->dmadesc = previously set by caller */ | ||
| 754 | td->dmaaddr = cpu_to_le32 (req->req.dma); | ||
| 755 | |||
| 756 | /* 2280 may be polling VALID_BIT through ep->dma->dmadesc */ | ||
| 757 | wmb(); | ||
| 758 | td->dmacount = cpu_to_le32(dmacount); | ||
| 759 | } | ||
| 760 | |||
| 761 | static const u32 dmactl_default = | ||
| 762 | BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) | | ||
| 763 | BIT(DMA_CLEAR_COUNT_ENABLE) | | ||
| 764 | /* erratum 0116 workaround part 1 (use POLLING) */ | ||
| 765 | (POLL_100_USEC << DESCRIPTOR_POLLING_RATE) | | ||
| 766 | BIT(DMA_VALID_BIT_POLLING_ENABLE) | | ||
| 767 | BIT(DMA_VALID_BIT_ENABLE) | | ||
| 768 | BIT(DMA_SCATTER_GATHER_ENABLE) | | ||
| 769 | /* erratum 0116 workaround part 2 (no AUTOSTART) */ | ||
| 770 | BIT(DMA_ENABLE); | ||
| 771 | |||
| 772 | static inline void spin_stop_dma(struct net2280_dma_regs __iomem *dma) | ||
| 773 | { | ||
| 774 | handshake(&dma->dmactl, BIT(DMA_ENABLE), 0, 50); | ||
| 775 | } | ||
| 776 | |||
| 777 | static inline void stop_dma(struct net2280_dma_regs __iomem *dma) | ||
| 778 | { | ||
| 779 | writel(readl(&dma->dmactl) & ~BIT(DMA_ENABLE), &dma->dmactl); | ||
| 780 | spin_stop_dma(dma); | ||
| 781 | } | ||
| 782 | |||
| 783 | static void start_queue(struct net2280_ep *ep, u32 dmactl, u32 td_dma) | ||
| 784 | { | ||
| 785 | struct net2280_dma_regs __iomem *dma = ep->dma; | ||
| 786 | unsigned int tmp = BIT(VALID_BIT) | (ep->is_in << DMA_DIRECTION); | ||
| 787 | |||
| 788 | if (!(ep->dev->quirks & PLX_2280)) | ||
| 789 | tmp |= BIT(END_OF_CHAIN); | ||
| 790 | |||
| 791 | writel(tmp, &dma->dmacount); | ||
| 792 | writel(readl(&dma->dmastat), &dma->dmastat); | ||
| 793 | |||
| 794 | writel(td_dma, &dma->dmadesc); | ||
| 795 | if (ep->dev->quirks & PLX_SUPERSPEED) | ||
| 796 | dmactl |= BIT(DMA_REQUEST_OUTSTANDING); | ||
| 797 | writel(dmactl, &dma->dmactl); | ||
| 798 | |||
| 799 | /* erratum 0116 workaround part 3: pci arbiter away from net2280 */ | ||
| 800 | (void) readl(&ep->dev->pci->pcimstctl); | ||
| 801 | |||
| 802 | writel(BIT(DMA_START), &dma->dmastat); | ||
| 803 | |||
| 804 | if (!ep->is_in) | ||
| 805 | stop_out_naking(ep); | ||
| 806 | } | ||
| 807 | |||
| 808 | static void start_dma(struct net2280_ep *ep, struct net2280_request *req) | ||
| 809 | { | ||
| 810 | u32 tmp; | ||
| 811 | struct net2280_dma_regs __iomem *dma = ep->dma; | ||
| 812 | |||
| 813 | /* FIXME can't use DMA for ZLPs */ | ||
| 814 | |||
| 815 | /* on this path we "know" there's no dma active (yet) */ | ||
| 816 | WARN_ON(readl(&dma->dmactl) & BIT(DMA_ENABLE)); | ||
| 817 | writel(0, &ep->dma->dmactl); | ||
| 818 | |||
| 819 | /* previous OUT packet might have been short */ | ||
| 820 | if (!ep->is_in && (readl(&ep->regs->ep_stat) & | ||
| 821 | BIT(NAK_OUT_PACKETS))) { | ||
| 822 | writel(BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT), | ||
| 823 | &ep->regs->ep_stat); | ||
| 824 | |||
| 825 | tmp = readl(&ep->regs->ep_avail); | ||
| 826 | if (tmp) { | ||
| 827 | writel(readl(&dma->dmastat), &dma->dmastat); | ||
| 828 | |||
| 829 | /* transfer all/some fifo data */ | ||
| 830 | writel(req->req.dma, &dma->dmaaddr); | ||
| 831 | tmp = min(tmp, req->req.length); | ||
| 832 | |||
| 833 | /* dma irq, faking scatterlist status */ | ||
| 834 | req->td->dmacount = cpu_to_le32(req->req.length - tmp); | ||
| 835 | writel(BIT(DMA_DONE_INTERRUPT_ENABLE) | tmp, | ||
| 836 | &dma->dmacount); | ||
| 837 | req->td->dmadesc = 0; | ||
| 838 | req->valid = 1; | ||
| 839 | |||
| 840 | writel(BIT(DMA_ENABLE), &dma->dmactl); | ||
| 841 | writel(BIT(DMA_START), &dma->dmastat); | ||
| 842 | return; | ||
| 843 | } | ||
| 844 | } | ||
| 845 | |||
| 846 | tmp = dmactl_default; | ||
| 847 | |||
| 848 | /* force packet boundaries between dma requests, but prevent the | ||
| 849 | * controller from automagically writing a last "short" packet | ||
| 850 | * (zero length) unless the driver explicitly said to do that. | ||
| 851 | */ | ||
| 852 | if (ep->is_in) { | ||
| 853 | if (likely((req->req.length % ep->ep.maxpacket) || | ||
| 854 | req->req.zero)){ | ||
| 855 | tmp |= BIT(DMA_FIFO_VALIDATE); | ||
| 856 | ep->in_fifo_validate = 1; | ||
| 857 | } else | ||
| 858 | ep->in_fifo_validate = 0; | ||
| 859 | } | ||
| 860 | |||
| 861 | /* init req->td, pointing to the current dummy */ | ||
| 862 | req->td->dmadesc = cpu_to_le32 (ep->td_dma); | ||
| 863 | fill_dma_desc(ep, req, 1); | ||
| 864 | |||
| 865 | if (!use_dma_chaining) | ||
| 866 | req->td->dmacount |= cpu_to_le32(BIT(END_OF_CHAIN)); | ||
| 867 | |||
| 868 | start_queue(ep, tmp, req->td_dma); | ||
| 869 | } | ||
| 870 | |||
| 871 | static inline void resume_dma(struct net2280_ep *ep) | ||
| 872 | { | ||
| 873 | writel(readl(&ep->dma->dmactl) | BIT(DMA_ENABLE), &ep->dma->dmactl); | ||
| 874 | |||
| 875 | ep->dma_started = true; | ||
| 876 | } | ||
| 877 | |||
| 878 | static inline void ep_stop_dma(struct net2280_ep *ep) | ||
| 879 | { | ||
| 880 | writel(readl(&ep->dma->dmactl) & ~BIT(DMA_ENABLE), &ep->dma->dmactl); | ||
| 881 | spin_stop_dma(ep->dma); | ||
| 882 | |||
| 883 | ep->dma_started = false; | ||
| 884 | } | ||
| 885 | |||
| 886 | static inline void | ||
| 887 | queue_dma(struct net2280_ep *ep, struct net2280_request *req, int valid) | ||
| 888 | { | ||
| 889 | struct net2280_dma *end; | ||
| 890 | dma_addr_t tmp; | ||
| 891 | |||
| 892 | /* swap new dummy for old, link; fill and maybe activate */ | ||
| 893 | end = ep->dummy; | ||
| 894 | ep->dummy = req->td; | ||
| 895 | req->td = end; | ||
| 896 | |||
| 897 | tmp = ep->td_dma; | ||
| 898 | ep->td_dma = req->td_dma; | ||
| 899 | req->td_dma = tmp; | ||
| 900 | |||
| 901 | end->dmadesc = cpu_to_le32 (ep->td_dma); | ||
| 902 | |||
| 903 | fill_dma_desc(ep, req, valid); | ||
| 904 | } | ||
| 905 | |||
| 906 | static void | ||
| 907 | done(struct net2280_ep *ep, struct net2280_request *req, int status) | ||
| 908 | { | ||
| 909 | struct net2280 *dev; | ||
| 910 | unsigned stopped = ep->stopped; | ||
| 911 | |||
| 912 | list_del_init(&req->queue); | ||
| 913 | |||
| 914 | if (req->req.status == -EINPROGRESS) | ||
| 915 | req->req.status = status; | ||
| 916 | else | ||
| 917 | status = req->req.status; | ||
| 918 | |||
| 919 | dev = ep->dev; | ||
| 920 | if (ep->dma) | ||
| 921 | usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in); | ||
| 922 | |||
| 923 | if (status && status != -ESHUTDOWN) | ||
| 924 | ep_vdbg(dev, "complete %s req %p stat %d len %u/%u\n", | ||
| 925 | ep->ep.name, &req->req, status, | ||
| 926 | req->req.actual, req->req.length); | ||
| 927 | |||
| 928 | /* don't modify queue heads during completion callback */ | ||
| 929 | ep->stopped = 1; | ||
| 930 | spin_unlock(&dev->lock); | ||
| 931 | req->req.complete(&ep->ep, &req->req); | ||
| 932 | spin_lock(&dev->lock); | ||
| 933 | ep->stopped = stopped; | ||
| 934 | } | ||
| 935 | |||
| 936 | /*-------------------------------------------------------------------------*/ | ||
| 937 | |||
| 938 | static int | ||
| 939 | net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | ||
| 940 | { | ||
| 941 | struct net2280_request *req; | ||
| 942 | struct net2280_ep *ep; | ||
| 943 | struct net2280 *dev; | ||
| 944 | unsigned long flags; | ||
| 945 | |||
| 946 | /* we always require a cpu-view buffer, so that we can | ||
| 947 | * always use pio (as fallback or whatever). | ||
| 948 | */ | ||
| 949 | req = container_of(_req, struct net2280_request, req); | ||
| 950 | if (!_req || !_req->complete || !_req->buf || | ||
| 951 | !list_empty(&req->queue)) | ||
| 952 | return -EINVAL; | ||
| 953 | if (_req->length > (~0 & DMA_BYTE_COUNT_MASK)) | ||
| 954 | return -EDOM; | ||
| 955 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 956 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 957 | return -EINVAL; | ||
| 958 | dev = ep->dev; | ||
| 959 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 960 | return -ESHUTDOWN; | ||
| 961 | |||
| 962 | /* FIXME implement PIO fallback for ZLPs with DMA */ | ||
| 963 | if (ep->dma && _req->length == 0) | ||
| 964 | return -EOPNOTSUPP; | ||
| 965 | |||
| 966 | /* set up dma mapping in case the caller didn't */ | ||
| 967 | if (ep->dma) { | ||
| 968 | int ret; | ||
| 969 | |||
| 970 | ret = usb_gadget_map_request(&dev->gadget, _req, | ||
| 971 | ep->is_in); | ||
| 972 | if (ret) | ||
| 973 | return ret; | ||
| 974 | } | ||
| 975 | |||
| 976 | #if 0 | ||
| 977 | ep_vdbg(dev, "%s queue req %p, len %d buf %p\n", | ||
| 978 | _ep->name, _req, _req->length, _req->buf); | ||
| 979 | #endif | ||
| 980 | |||
| 981 | spin_lock_irqsave(&dev->lock, flags); | ||
| 982 | |||
| 983 | _req->status = -EINPROGRESS; | ||
| 984 | _req->actual = 0; | ||
| 985 | |||
| 986 | /* kickstart this i/o queue? */ | ||
| 987 | if (list_empty(&ep->queue) && !ep->stopped) { | ||
| 988 | /* DMA request while EP halted */ | ||
| 989 | if (ep->dma && | ||
| 990 | (readl(&ep->regs->ep_rsp) & BIT(CLEAR_ENDPOINT_HALT)) && | ||
| 991 | (dev->quirks & PLX_SUPERSPEED)) { | ||
| 992 | int valid = 1; | ||
| 993 | if (ep->is_in) { | ||
| 994 | int expect; | ||
| 995 | expect = likely(req->req.zero || | ||
| 996 | ((req->req.length % | ||
| 997 | ep->ep.maxpacket) != 0)); | ||
| 998 | if (expect != ep->in_fifo_validate) | ||
| 999 | valid = 0; | ||
| 1000 | } | ||
| 1001 | queue_dma(ep, req, valid); | ||
| 1002 | } | ||
| 1003 | /* use DMA if the endpoint supports it, else pio */ | ||
| 1004 | else if (ep->dma) | ||
| 1005 | start_dma(ep, req); | ||
| 1006 | else { | ||
| 1007 | /* maybe there's no control data, just status ack */ | ||
| 1008 | if (ep->num == 0 && _req->length == 0) { | ||
| 1009 | allow_status(ep); | ||
| 1010 | done(ep, req, 0); | ||
| 1011 | ep_vdbg(dev, "%s status ack\n", ep->ep.name); | ||
| 1012 | goto done; | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | /* PIO ... stuff the fifo, or unblock it. */ | ||
| 1016 | if (ep->is_in) | ||
| 1017 | write_fifo(ep, _req); | ||
| 1018 | else if (list_empty(&ep->queue)) { | ||
| 1019 | u32 s; | ||
| 1020 | |||
| 1021 | /* OUT FIFO might have packet(s) buffered */ | ||
| 1022 | s = readl(&ep->regs->ep_stat); | ||
| 1023 | if ((s & BIT(FIFO_EMPTY)) == 0) { | ||
| 1024 | /* note: _req->short_not_ok is | ||
| 1025 | * ignored here since PIO _always_ | ||
| 1026 | * stops queue advance here, and | ||
| 1027 | * _req->status doesn't change for | ||
| 1028 | * short reads (only _req->actual) | ||
| 1029 | */ | ||
| 1030 | if (read_fifo(ep, req) && | ||
| 1031 | ep->num == 0) { | ||
| 1032 | done(ep, req, 0); | ||
| 1033 | allow_status(ep); | ||
| 1034 | /* don't queue it */ | ||
| 1035 | req = NULL; | ||
| 1036 | } else if (read_fifo(ep, req) && | ||
| 1037 | ep->num != 0) { | ||
| 1038 | done(ep, req, 0); | ||
| 1039 | req = NULL; | ||
| 1040 | } else | ||
| 1041 | s = readl(&ep->regs->ep_stat); | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | /* don't NAK, let the fifo fill */ | ||
| 1045 | if (req && (s & BIT(NAK_OUT_PACKETS))) | ||
| 1046 | writel(BIT(CLEAR_NAK_OUT_PACKETS), | ||
| 1047 | &ep->regs->ep_rsp); | ||
| 1048 | } | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | } else if (ep->dma) { | ||
| 1052 | int valid = 1; | ||
| 1053 | |||
| 1054 | if (ep->is_in) { | ||
| 1055 | int expect; | ||
| 1056 | |||
| 1057 | /* preventing magic zlps is per-engine state, not | ||
| 1058 | * per-transfer; irq logic must recover hiccups. | ||
| 1059 | */ | ||
| 1060 | expect = likely(req->req.zero || | ||
| 1061 | (req->req.length % ep->ep.maxpacket)); | ||
| 1062 | if (expect != ep->in_fifo_validate) | ||
| 1063 | valid = 0; | ||
| 1064 | } | ||
| 1065 | queue_dma(ep, req, valid); | ||
| 1066 | |||
| 1067 | } /* else the irq handler advances the queue. */ | ||
| 1068 | |||
| 1069 | ep->responded = 1; | ||
| 1070 | if (req) | ||
| 1071 | list_add_tail(&req->queue, &ep->queue); | ||
| 1072 | done: | ||
| 1073 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1074 | |||
| 1075 | /* pci writes may still be posted */ | ||
| 1076 | return 0; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | static inline void | ||
| 1080 | dma_done(struct net2280_ep *ep, struct net2280_request *req, u32 dmacount, | ||
| 1081 | int status) | ||
| 1082 | { | ||
| 1083 | req->req.actual = req->req.length - (DMA_BYTE_COUNT_MASK & dmacount); | ||
| 1084 | done(ep, req, status); | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | static void restart_dma(struct net2280_ep *ep); | ||
| 1088 | |||
| 1089 | static void scan_dma_completions(struct net2280_ep *ep) | ||
| 1090 | { | ||
| 1091 | /* only look at descriptors that were "naturally" retired, | ||
| 1092 | * so fifo and list head state won't matter | ||
| 1093 | */ | ||
| 1094 | while (!list_empty(&ep->queue)) { | ||
| 1095 | struct net2280_request *req; | ||
| 1096 | u32 tmp; | ||
| 1097 | |||
| 1098 | req = list_entry(ep->queue.next, | ||
| 1099 | struct net2280_request, queue); | ||
| 1100 | if (!req->valid) | ||
| 1101 | break; | ||
| 1102 | rmb(); | ||
| 1103 | tmp = le32_to_cpup(&req->td->dmacount); | ||
| 1104 | if ((tmp & BIT(VALID_BIT)) != 0) | ||
| 1105 | break; | ||
| 1106 | |||
| 1107 | /* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short" | ||
| 1108 | * cases where DMA must be aborted; this code handles | ||
| 1109 | * all non-abort DMA completions. | ||
| 1110 | */ | ||
| 1111 | if (unlikely(req->td->dmadesc == 0)) { | ||
| 1112 | /* paranoia */ | ||
| 1113 | tmp = readl(&ep->dma->dmacount); | ||
| 1114 | if (tmp & DMA_BYTE_COUNT_MASK) | ||
| 1115 | break; | ||
| 1116 | /* single transfer mode */ | ||
| 1117 | dma_done(ep, req, tmp, 0); | ||
| 1118 | break; | ||
| 1119 | } else if (!ep->is_in && | ||
| 1120 | (req->req.length % ep->ep.maxpacket) != 0) { | ||
| 1121 | tmp = readl(&ep->regs->ep_stat); | ||
| 1122 | if (ep->dev->quirks & PLX_SUPERSPEED) | ||
| 1123 | return dma_done(ep, req, tmp, 0); | ||
| 1124 | |||
| 1125 | /* AVOID TROUBLE HERE by not issuing short reads from | ||
| 1126 | * your gadget driver. That helps avoids errata 0121, | ||
| 1127 | * 0122, and 0124; not all cases trigger the warning. | ||
| 1128 | */ | ||
| 1129 | if ((tmp & BIT(NAK_OUT_PACKETS)) == 0) { | ||
| 1130 | ep_warn(ep->dev, "%s lost packet sync!\n", | ||
| 1131 | ep->ep.name); | ||
| 1132 | req->req.status = -EOVERFLOW; | ||
| 1133 | } else { | ||
| 1134 | tmp = readl(&ep->regs->ep_avail); | ||
| 1135 | if (tmp) { | ||
| 1136 | /* fifo gets flushed later */ | ||
| 1137 | ep->out_overflow = 1; | ||
| 1138 | ep_dbg(ep->dev, | ||
| 1139 | "%s dma, discard %d len %d\n", | ||
| 1140 | ep->ep.name, tmp, | ||
| 1141 | req->req.length); | ||
| 1142 | req->req.status = -EOVERFLOW; | ||
| 1143 | } | ||
| 1144 | } | ||
| 1145 | } | ||
| 1146 | dma_done(ep, req, tmp, 0); | ||
| 1147 | } | ||
| 1148 | } | ||
| 1149 | |||
| 1150 | static void restart_dma(struct net2280_ep *ep) | ||
| 1151 | { | ||
| 1152 | struct net2280_request *req; | ||
| 1153 | u32 dmactl = dmactl_default; | ||
| 1154 | |||
| 1155 | if (ep->stopped) | ||
| 1156 | return; | ||
| 1157 | req = list_entry(ep->queue.next, struct net2280_request, queue); | ||
| 1158 | |||
| 1159 | if (!use_dma_chaining) { | ||
| 1160 | start_dma(ep, req); | ||
| 1161 | return; | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | /* the 2280 will be processing the queue unless queue hiccups after | ||
| 1165 | * the previous transfer: | ||
| 1166 | * IN: wanted automagic zlp, head doesn't (or vice versa) | ||
| 1167 | * DMA_FIFO_VALIDATE doesn't init from dma descriptors. | ||
| 1168 | * OUT: was "usb-short", we must restart. | ||
| 1169 | */ | ||
| 1170 | if (ep->is_in && !req->valid) { | ||
| 1171 | struct net2280_request *entry, *prev = NULL; | ||
| 1172 | int reqmode, done = 0; | ||
| 1173 | |||
| 1174 | ep_dbg(ep->dev, "%s dma hiccup td %p\n", ep->ep.name, req->td); | ||
| 1175 | ep->in_fifo_validate = likely(req->req.zero || | ||
| 1176 | (req->req.length % ep->ep.maxpacket) != 0); | ||
| 1177 | if (ep->in_fifo_validate) | ||
| 1178 | dmactl |= BIT(DMA_FIFO_VALIDATE); | ||
| 1179 | list_for_each_entry(entry, &ep->queue, queue) { | ||
| 1180 | __le32 dmacount; | ||
| 1181 | |||
| 1182 | if (entry == req) | ||
| 1183 | continue; | ||
| 1184 | dmacount = entry->td->dmacount; | ||
| 1185 | if (!done) { | ||
| 1186 | reqmode = likely(entry->req.zero || | ||
| 1187 | (entry->req.length % ep->ep.maxpacket)); | ||
| 1188 | if (reqmode == ep->in_fifo_validate) { | ||
| 1189 | entry->valid = 1; | ||
| 1190 | dmacount |= valid_bit; | ||
| 1191 | entry->td->dmacount = dmacount; | ||
| 1192 | prev = entry; | ||
| 1193 | continue; | ||
| 1194 | } else { | ||
| 1195 | /* force a hiccup */ | ||
| 1196 | prev->td->dmacount |= dma_done_ie; | ||
| 1197 | done = 1; | ||
| 1198 | } | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | /* walk the rest of the queue so unlinks behave */ | ||
| 1202 | entry->valid = 0; | ||
| 1203 | dmacount &= ~valid_bit; | ||
| 1204 | entry->td->dmacount = dmacount; | ||
| 1205 | prev = entry; | ||
| 1206 | } | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | writel(0, &ep->dma->dmactl); | ||
| 1210 | start_queue(ep, dmactl, req->td_dma); | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | static void abort_dma_228x(struct net2280_ep *ep) | ||
| 1214 | { | ||
| 1215 | /* abort the current transfer */ | ||
| 1216 | if (likely(!list_empty(&ep->queue))) { | ||
| 1217 | /* FIXME work around errata 0121, 0122, 0124 */ | ||
| 1218 | writel(BIT(DMA_ABORT), &ep->dma->dmastat); | ||
| 1219 | spin_stop_dma(ep->dma); | ||
| 1220 | } else | ||
| 1221 | stop_dma(ep->dma); | ||
| 1222 | scan_dma_completions(ep); | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | static void abort_dma_338x(struct net2280_ep *ep) | ||
| 1226 | { | ||
| 1227 | writel(BIT(DMA_ABORT), &ep->dma->dmastat); | ||
| 1228 | spin_stop_dma(ep->dma); | ||
| 1229 | } | ||
| 1230 | |||
| 1231 | static void abort_dma(struct net2280_ep *ep) | ||
| 1232 | { | ||
| 1233 | if (ep->dev->quirks & PLX_LEGACY) | ||
| 1234 | return abort_dma_228x(ep); | ||
| 1235 | return abort_dma_338x(ep); | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | /* dequeue ALL requests */ | ||
| 1239 | static void nuke(struct net2280_ep *ep) | ||
| 1240 | { | ||
| 1241 | struct net2280_request *req; | ||
| 1242 | |||
| 1243 | /* called with spinlock held */ | ||
| 1244 | ep->stopped = 1; | ||
| 1245 | if (ep->dma) | ||
| 1246 | abort_dma(ep); | ||
| 1247 | while (!list_empty(&ep->queue)) { | ||
| 1248 | req = list_entry(ep->queue.next, | ||
| 1249 | struct net2280_request, | ||
| 1250 | queue); | ||
| 1251 | done(ep, req, -ESHUTDOWN); | ||
| 1252 | } | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | /* dequeue JUST ONE request */ | ||
| 1256 | static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
| 1257 | { | ||
| 1258 | struct net2280_ep *ep; | ||
| 1259 | struct net2280_request *req; | ||
| 1260 | unsigned long flags; | ||
| 1261 | u32 dmactl; | ||
| 1262 | int stopped; | ||
| 1263 | |||
| 1264 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 1265 | if (!_ep || (!ep->desc && ep->num != 0) || !_req) | ||
| 1266 | return -EINVAL; | ||
| 1267 | |||
| 1268 | spin_lock_irqsave(&ep->dev->lock, flags); | ||
| 1269 | stopped = ep->stopped; | ||
| 1270 | |||
| 1271 | /* quiesce dma while we patch the queue */ | ||
| 1272 | dmactl = 0; | ||
| 1273 | ep->stopped = 1; | ||
| 1274 | if (ep->dma) { | ||
| 1275 | dmactl = readl(&ep->dma->dmactl); | ||
| 1276 | /* WARNING erratum 0127 may kick in ... */ | ||
| 1277 | stop_dma(ep->dma); | ||
| 1278 | scan_dma_completions(ep); | ||
| 1279 | } | ||
| 1280 | |||
| 1281 | /* make sure it's still queued on this endpoint */ | ||
| 1282 | list_for_each_entry(req, &ep->queue, queue) { | ||
| 1283 | if (&req->req == _req) | ||
| 1284 | break; | ||
| 1285 | } | ||
| 1286 | if (&req->req != _req) { | ||
| 1287 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
| 1288 | return -EINVAL; | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | /* queue head may be partially complete. */ | ||
| 1292 | if (ep->queue.next == &req->queue) { | ||
| 1293 | if (ep->dma) { | ||
| 1294 | ep_dbg(ep->dev, "unlink (%s) dma\n", _ep->name); | ||
| 1295 | _req->status = -ECONNRESET; | ||
| 1296 | abort_dma(ep); | ||
| 1297 | if (likely(ep->queue.next == &req->queue)) { | ||
| 1298 | /* NOTE: misreports single-transfer mode*/ | ||
| 1299 | req->td->dmacount = 0; /* invalidate */ | ||
| 1300 | dma_done(ep, req, | ||
| 1301 | readl(&ep->dma->dmacount), | ||
| 1302 | -ECONNRESET); | ||
| 1303 | } | ||
| 1304 | } else { | ||
| 1305 | ep_dbg(ep->dev, "unlink (%s) pio\n", _ep->name); | ||
| 1306 | done(ep, req, -ECONNRESET); | ||
| 1307 | } | ||
| 1308 | req = NULL; | ||
| 1309 | |||
| 1310 | /* patch up hardware chaining data */ | ||
| 1311 | } else if (ep->dma && use_dma_chaining) { | ||
| 1312 | if (req->queue.prev == ep->queue.next) { | ||
| 1313 | writel(le32_to_cpu(req->td->dmadesc), | ||
| 1314 | &ep->dma->dmadesc); | ||
| 1315 | if (req->td->dmacount & dma_done_ie) | ||
| 1316 | writel(readl(&ep->dma->dmacount) | | ||
| 1317 | le32_to_cpu(dma_done_ie), | ||
| 1318 | &ep->dma->dmacount); | ||
| 1319 | } else { | ||
| 1320 | struct net2280_request *prev; | ||
| 1321 | |||
| 1322 | prev = list_entry(req->queue.prev, | ||
| 1323 | struct net2280_request, queue); | ||
| 1324 | prev->td->dmadesc = req->td->dmadesc; | ||
| 1325 | if (req->td->dmacount & dma_done_ie) | ||
| 1326 | prev->td->dmacount |= dma_done_ie; | ||
| 1327 | } | ||
| 1328 | } | ||
| 1329 | |||
| 1330 | if (req) | ||
| 1331 | done(ep, req, -ECONNRESET); | ||
| 1332 | ep->stopped = stopped; | ||
| 1333 | |||
| 1334 | if (ep->dma) { | ||
| 1335 | /* turn off dma on inactive queues */ | ||
| 1336 | if (list_empty(&ep->queue)) | ||
| 1337 | stop_dma(ep->dma); | ||
| 1338 | else if (!ep->stopped) { | ||
| 1339 | /* resume current request, or start new one */ | ||
| 1340 | if (req) | ||
| 1341 | writel(dmactl, &ep->dma->dmactl); | ||
| 1342 | else | ||
| 1343 | start_dma(ep, list_entry(ep->queue.next, | ||
| 1344 | struct net2280_request, queue)); | ||
| 1345 | } | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
| 1349 | return 0; | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | /*-------------------------------------------------------------------------*/ | ||
| 1353 | |||
| 1354 | static int net2280_fifo_status(struct usb_ep *_ep); | ||
| 1355 | |||
| 1356 | static int | ||
| 1357 | net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) | ||
| 1358 | { | ||
| 1359 | struct net2280_ep *ep; | ||
| 1360 | unsigned long flags; | ||
| 1361 | int retval = 0; | ||
| 1362 | |||
| 1363 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 1364 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1365 | return -EINVAL; | ||
| 1366 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1367 | return -ESHUTDOWN; | ||
| 1368 | if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03) | ||
| 1369 | == USB_ENDPOINT_XFER_ISOC) | ||
| 1370 | return -EINVAL; | ||
| 1371 | |||
| 1372 | spin_lock_irqsave(&ep->dev->lock, flags); | ||
| 1373 | if (!list_empty(&ep->queue)) | ||
| 1374 | retval = -EAGAIN; | ||
| 1375 | else if (ep->is_in && value && net2280_fifo_status(_ep) != 0) | ||
| 1376 | retval = -EAGAIN; | ||
| 1377 | else { | ||
| 1378 | ep_vdbg(ep->dev, "%s %s %s\n", _ep->name, | ||
| 1379 | value ? "set" : "clear", | ||
| 1380 | wedged ? "wedge" : "halt"); | ||
| 1381 | /* set/clear, then synch memory views with the device */ | ||
| 1382 | if (value) { | ||
| 1383 | if (ep->num == 0) | ||
| 1384 | ep->dev->protocol_stall = 1; | ||
| 1385 | else | ||
| 1386 | set_halt(ep); | ||
| 1387 | if (wedged) | ||
| 1388 | ep->wedged = 1; | ||
| 1389 | } else { | ||
| 1390 | clear_halt(ep); | ||
| 1391 | if (ep->dev->quirks & PLX_SUPERSPEED && | ||
| 1392 | !list_empty(&ep->queue) && ep->td_dma) | ||
| 1393 | restart_dma(ep); | ||
| 1394 | ep->wedged = 0; | ||
| 1395 | } | ||
| 1396 | (void) readl(&ep->regs->ep_rsp); | ||
| 1397 | } | ||
| 1398 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
| 1399 | |||
| 1400 | return retval; | ||
| 1401 | } | ||
| 1402 | |||
| 1403 | static int net2280_set_halt(struct usb_ep *_ep, int value) | ||
| 1404 | { | ||
| 1405 | return net2280_set_halt_and_wedge(_ep, value, 0); | ||
| 1406 | } | ||
| 1407 | |||
| 1408 | static int net2280_set_wedge(struct usb_ep *_ep) | ||
| 1409 | { | ||
| 1410 | if (!_ep || _ep->name == ep0name) | ||
| 1411 | return -EINVAL; | ||
| 1412 | return net2280_set_halt_and_wedge(_ep, 1, 1); | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | static int net2280_fifo_status(struct usb_ep *_ep) | ||
| 1416 | { | ||
| 1417 | struct net2280_ep *ep; | ||
| 1418 | u32 avail; | ||
| 1419 | |||
| 1420 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 1421 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1422 | return -ENODEV; | ||
| 1423 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1424 | return -ESHUTDOWN; | ||
| 1425 | |||
| 1426 | avail = readl(&ep->regs->ep_avail) & (BIT(12) - 1); | ||
| 1427 | if (avail > ep->fifo_size) | ||
| 1428 | return -EOVERFLOW; | ||
| 1429 | if (ep->is_in) | ||
| 1430 | avail = ep->fifo_size - avail; | ||
| 1431 | return avail; | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | static void net2280_fifo_flush(struct usb_ep *_ep) | ||
| 1435 | { | ||
| 1436 | struct net2280_ep *ep; | ||
| 1437 | |||
| 1438 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 1439 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1440 | return; | ||
| 1441 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1442 | return; | ||
| 1443 | |||
| 1444 | writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); | ||
| 1445 | (void) readl(&ep->regs->ep_rsp); | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | static const struct usb_ep_ops net2280_ep_ops = { | ||
| 1449 | .enable = net2280_enable, | ||
| 1450 | .disable = net2280_disable, | ||
| 1451 | |||
| 1452 | .alloc_request = net2280_alloc_request, | ||
| 1453 | .free_request = net2280_free_request, | ||
| 1454 | |||
| 1455 | .queue = net2280_queue, | ||
| 1456 | .dequeue = net2280_dequeue, | ||
| 1457 | |||
| 1458 | .set_halt = net2280_set_halt, | ||
| 1459 | .set_wedge = net2280_set_wedge, | ||
| 1460 | .fifo_status = net2280_fifo_status, | ||
| 1461 | .fifo_flush = net2280_fifo_flush, | ||
| 1462 | }; | ||
| 1463 | |||
| 1464 | /*-------------------------------------------------------------------------*/ | ||
| 1465 | |||
| 1466 | static int net2280_get_frame(struct usb_gadget *_gadget) | ||
| 1467 | { | ||
| 1468 | struct net2280 *dev; | ||
| 1469 | unsigned long flags; | ||
| 1470 | u16 retval; | ||
| 1471 | |||
| 1472 | if (!_gadget) | ||
| 1473 | return -ENODEV; | ||
| 1474 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 1475 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1476 | retval = get_idx_reg(dev->regs, REG_FRAME) & 0x03ff; | ||
| 1477 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1478 | return retval; | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | static int net2280_wakeup(struct usb_gadget *_gadget) | ||
| 1482 | { | ||
| 1483 | struct net2280 *dev; | ||
| 1484 | u32 tmp; | ||
| 1485 | unsigned long flags; | ||
| 1486 | |||
| 1487 | if (!_gadget) | ||
| 1488 | return 0; | ||
| 1489 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 1490 | |||
| 1491 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1492 | tmp = readl(&dev->usb->usbctl); | ||
| 1493 | if (tmp & BIT(DEVICE_REMOTE_WAKEUP_ENABLE)) | ||
| 1494 | writel(BIT(GENERATE_RESUME), &dev->usb->usbstat); | ||
| 1495 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1496 | |||
| 1497 | /* pci writes may still be posted */ | ||
| 1498 | return 0; | ||
| 1499 | } | ||
| 1500 | |||
| 1501 | static int net2280_set_selfpowered(struct usb_gadget *_gadget, int value) | ||
| 1502 | { | ||
| 1503 | struct net2280 *dev; | ||
| 1504 | u32 tmp; | ||
| 1505 | unsigned long flags; | ||
| 1506 | |||
| 1507 | if (!_gadget) | ||
| 1508 | return 0; | ||
| 1509 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 1510 | |||
| 1511 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1512 | tmp = readl(&dev->usb->usbctl); | ||
| 1513 | if (value) { | ||
| 1514 | tmp |= BIT(SELF_POWERED_STATUS); | ||
| 1515 | dev->selfpowered = 1; | ||
| 1516 | } else { | ||
| 1517 | tmp &= ~BIT(SELF_POWERED_STATUS); | ||
| 1518 | dev->selfpowered = 0; | ||
| 1519 | } | ||
| 1520 | writel(tmp, &dev->usb->usbctl); | ||
| 1521 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1522 | |||
| 1523 | return 0; | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | static int net2280_pullup(struct usb_gadget *_gadget, int is_on) | ||
| 1527 | { | ||
| 1528 | struct net2280 *dev; | ||
| 1529 | u32 tmp; | ||
| 1530 | unsigned long flags; | ||
| 1531 | |||
| 1532 | if (!_gadget) | ||
| 1533 | return -ENODEV; | ||
| 1534 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 1535 | |||
| 1536 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1537 | tmp = readl(&dev->usb->usbctl); | ||
| 1538 | dev->softconnect = (is_on != 0); | ||
| 1539 | if (is_on) | ||
| 1540 | tmp |= BIT(USB_DETECT_ENABLE); | ||
| 1541 | else | ||
| 1542 | tmp &= ~BIT(USB_DETECT_ENABLE); | ||
| 1543 | writel(tmp, &dev->usb->usbctl); | ||
| 1544 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1545 | |||
| 1546 | return 0; | ||
| 1547 | } | ||
| 1548 | |||
| 1549 | static int net2280_start(struct usb_gadget *_gadget, | ||
| 1550 | struct usb_gadget_driver *driver); | ||
| 1551 | static int net2280_stop(struct usb_gadget *_gadget, | ||
| 1552 | struct usb_gadget_driver *driver); | ||
| 1553 | |||
| 1554 | static const struct usb_gadget_ops net2280_ops = { | ||
| 1555 | .get_frame = net2280_get_frame, | ||
| 1556 | .wakeup = net2280_wakeup, | ||
| 1557 | .set_selfpowered = net2280_set_selfpowered, | ||
| 1558 | .pullup = net2280_pullup, | ||
| 1559 | .udc_start = net2280_start, | ||
| 1560 | .udc_stop = net2280_stop, | ||
| 1561 | }; | ||
| 1562 | |||
| 1563 | /*-------------------------------------------------------------------------*/ | ||
| 1564 | |||
| 1565 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
| 1566 | |||
| 1567 | /* FIXME move these into procfs, and use seq_file. | ||
| 1568 | * Sysfs _still_ doesn't behave for arbitrarily sized files, | ||
| 1569 | * and also doesn't help products using this with 2.4 kernels. | ||
| 1570 | */ | ||
| 1571 | |||
| 1572 | /* "function" sysfs attribute */ | ||
| 1573 | static ssize_t function_show(struct device *_dev, struct device_attribute *attr, | ||
| 1574 | char *buf) | ||
| 1575 | { | ||
| 1576 | struct net2280 *dev = dev_get_drvdata(_dev); | ||
| 1577 | |||
| 1578 | if (!dev->driver || !dev->driver->function || | ||
| 1579 | strlen(dev->driver->function) > PAGE_SIZE) | ||
| 1580 | return 0; | ||
| 1581 | return scnprintf(buf, PAGE_SIZE, "%s\n", dev->driver->function); | ||
| 1582 | } | ||
| 1583 | static DEVICE_ATTR_RO(function); | ||
| 1584 | |||
| 1585 | static ssize_t registers_show(struct device *_dev, | ||
| 1586 | struct device_attribute *attr, char *buf) | ||
| 1587 | { | ||
| 1588 | struct net2280 *dev; | ||
| 1589 | char *next; | ||
| 1590 | unsigned size, t; | ||
| 1591 | unsigned long flags; | ||
| 1592 | int i; | ||
| 1593 | u32 t1, t2; | ||
| 1594 | const char *s; | ||
| 1595 | |||
| 1596 | dev = dev_get_drvdata(_dev); | ||
| 1597 | next = buf; | ||
| 1598 | size = PAGE_SIZE; | ||
| 1599 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1600 | |||
| 1601 | if (dev->driver) | ||
| 1602 | s = dev->driver->driver.name; | ||
| 1603 | else | ||
| 1604 | s = "(none)"; | ||
| 1605 | |||
| 1606 | /* Main Control Registers */ | ||
| 1607 | t = scnprintf(next, size, "%s version " DRIVER_VERSION | ||
| 1608 | ", chiprev %04x, dma %s\n\n" | ||
| 1609 | "devinit %03x fifoctl %08x gadget '%s'\n" | ||
| 1610 | "pci irqenb0 %02x irqenb1 %08x " | ||
| 1611 | "irqstat0 %04x irqstat1 %08x\n", | ||
| 1612 | driver_name, dev->chiprev, | ||
| 1613 | use_dma | ||
| 1614 | ? (use_dma_chaining ? "chaining" : "enabled") | ||
| 1615 | : "disabled", | ||
| 1616 | readl(&dev->regs->devinit), | ||
| 1617 | readl(&dev->regs->fifoctl), | ||
| 1618 | s, | ||
| 1619 | readl(&dev->regs->pciirqenb0), | ||
| 1620 | readl(&dev->regs->pciirqenb1), | ||
| 1621 | readl(&dev->regs->irqstat0), | ||
| 1622 | readl(&dev->regs->irqstat1)); | ||
| 1623 | size -= t; | ||
| 1624 | next += t; | ||
| 1625 | |||
| 1626 | /* USB Control Registers */ | ||
| 1627 | t1 = readl(&dev->usb->usbctl); | ||
| 1628 | t2 = readl(&dev->usb->usbstat); | ||
| 1629 | if (t1 & BIT(VBUS_PIN)) { | ||
| 1630 | if (t2 & BIT(HIGH_SPEED)) | ||
| 1631 | s = "high speed"; | ||
| 1632 | else if (dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1633 | s = "powered"; | ||
| 1634 | else | ||
| 1635 | s = "full speed"; | ||
| 1636 | /* full speed bit (6) not working?? */ | ||
| 1637 | } else | ||
| 1638 | s = "not attached"; | ||
| 1639 | t = scnprintf(next, size, | ||
| 1640 | "stdrsp %08x usbctl %08x usbstat %08x " | ||
| 1641 | "addr 0x%02x (%s)\n", | ||
| 1642 | readl(&dev->usb->stdrsp), t1, t2, | ||
| 1643 | readl(&dev->usb->ouraddr), s); | ||
| 1644 | size -= t; | ||
| 1645 | next += t; | ||
| 1646 | |||
| 1647 | /* PCI Master Control Registers */ | ||
| 1648 | |||
| 1649 | /* DMA Control Registers */ | ||
| 1650 | |||
| 1651 | /* Configurable EP Control Registers */ | ||
| 1652 | for (i = 0; i < dev->n_ep; i++) { | ||
| 1653 | struct net2280_ep *ep; | ||
| 1654 | |||
| 1655 | ep = &dev->ep[i]; | ||
| 1656 | if (i && !ep->desc) | ||
| 1657 | continue; | ||
| 1658 | |||
| 1659 | t1 = readl(&ep->cfg->ep_cfg); | ||
| 1660 | t2 = readl(&ep->regs->ep_rsp) & 0xff; | ||
| 1661 | t = scnprintf(next, size, | ||
| 1662 | "\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s" | ||
| 1663 | "irqenb %02x\n", | ||
| 1664 | ep->ep.name, t1, t2, | ||
| 1665 | (t2 & BIT(CLEAR_NAK_OUT_PACKETS)) | ||
| 1666 | ? "NAK " : "", | ||
| 1667 | (t2 & BIT(CLEAR_EP_HIDE_STATUS_PHASE)) | ||
| 1668 | ? "hide " : "", | ||
| 1669 | (t2 & BIT(CLEAR_EP_FORCE_CRC_ERROR)) | ||
| 1670 | ? "CRC " : "", | ||
| 1671 | (t2 & BIT(CLEAR_INTERRUPT_MODE)) | ||
| 1672 | ? "interrupt " : "", | ||
| 1673 | (t2 & BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)) | ||
| 1674 | ? "status " : "", | ||
| 1675 | (t2 & BIT(CLEAR_NAK_OUT_PACKETS_MODE)) | ||
| 1676 | ? "NAKmode " : "", | ||
| 1677 | (t2 & BIT(CLEAR_ENDPOINT_TOGGLE)) | ||
| 1678 | ? "DATA1 " : "DATA0 ", | ||
| 1679 | (t2 & BIT(CLEAR_ENDPOINT_HALT)) | ||
| 1680 | ? "HALT " : "", | ||
| 1681 | readl(&ep->regs->ep_irqenb)); | ||
| 1682 | size -= t; | ||
| 1683 | next += t; | ||
| 1684 | |||
| 1685 | t = scnprintf(next, size, | ||
| 1686 | "\tstat %08x avail %04x " | ||
| 1687 | "(ep%d%s-%s)%s\n", | ||
| 1688 | readl(&ep->regs->ep_stat), | ||
| 1689 | readl(&ep->regs->ep_avail), | ||
| 1690 | t1 & 0x0f, DIR_STRING(t1), | ||
| 1691 | type_string(t1 >> 8), | ||
| 1692 | ep->stopped ? "*" : ""); | ||
| 1693 | size -= t; | ||
| 1694 | next += t; | ||
| 1695 | |||
| 1696 | if (!ep->dma) | ||
| 1697 | continue; | ||
| 1698 | |||
| 1699 | t = scnprintf(next, size, | ||
| 1700 | " dma\tctl %08x stat %08x count %08x\n" | ||
| 1701 | "\taddr %08x desc %08x\n", | ||
| 1702 | readl(&ep->dma->dmactl), | ||
| 1703 | readl(&ep->dma->dmastat), | ||
| 1704 | readl(&ep->dma->dmacount), | ||
| 1705 | readl(&ep->dma->dmaaddr), | ||
| 1706 | readl(&ep->dma->dmadesc)); | ||
| 1707 | size -= t; | ||
| 1708 | next += t; | ||
| 1709 | |||
| 1710 | } | ||
| 1711 | |||
| 1712 | /* Indexed Registers (none yet) */ | ||
| 1713 | |||
| 1714 | /* Statistics */ | ||
| 1715 | t = scnprintf(next, size, "\nirqs: "); | ||
| 1716 | size -= t; | ||
| 1717 | next += t; | ||
| 1718 | for (i = 0; i < dev->n_ep; i++) { | ||
| 1719 | struct net2280_ep *ep; | ||
| 1720 | |||
| 1721 | ep = &dev->ep[i]; | ||
| 1722 | if (i && !ep->irqs) | ||
| 1723 | continue; | ||
| 1724 | t = scnprintf(next, size, " %s/%lu", ep->ep.name, ep->irqs); | ||
| 1725 | size -= t; | ||
| 1726 | next += t; | ||
| 1727 | |||
| 1728 | } | ||
| 1729 | t = scnprintf(next, size, "\n"); | ||
| 1730 | size -= t; | ||
| 1731 | next += t; | ||
| 1732 | |||
| 1733 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1734 | |||
| 1735 | return PAGE_SIZE - size; | ||
| 1736 | } | ||
| 1737 | static DEVICE_ATTR_RO(registers); | ||
| 1738 | |||
| 1739 | static ssize_t queues_show(struct device *_dev, struct device_attribute *attr, | ||
| 1740 | char *buf) | ||
| 1741 | { | ||
| 1742 | struct net2280 *dev; | ||
| 1743 | char *next; | ||
| 1744 | unsigned size; | ||
| 1745 | unsigned long flags; | ||
| 1746 | int i; | ||
| 1747 | |||
| 1748 | dev = dev_get_drvdata(_dev); | ||
| 1749 | next = buf; | ||
| 1750 | size = PAGE_SIZE; | ||
| 1751 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1752 | |||
| 1753 | for (i = 0; i < dev->n_ep; i++) { | ||
| 1754 | struct net2280_ep *ep = &dev->ep[i]; | ||
| 1755 | struct net2280_request *req; | ||
| 1756 | int t; | ||
| 1757 | |||
| 1758 | if (i != 0) { | ||
| 1759 | const struct usb_endpoint_descriptor *d; | ||
| 1760 | |||
| 1761 | d = ep->desc; | ||
| 1762 | if (!d) | ||
| 1763 | continue; | ||
| 1764 | t = d->bEndpointAddress; | ||
| 1765 | t = scnprintf(next, size, | ||
| 1766 | "\n%s (ep%d%s-%s) max %04x %s fifo %d\n", | ||
| 1767 | ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK, | ||
| 1768 | (t & USB_DIR_IN) ? "in" : "out", | ||
| 1769 | type_string(d->bmAttributes), | ||
| 1770 | usb_endpoint_maxp(d) & 0x1fff, | ||
| 1771 | ep->dma ? "dma" : "pio", ep->fifo_size | ||
| 1772 | ); | ||
| 1773 | } else /* ep0 should only have one transfer queued */ | ||
| 1774 | t = scnprintf(next, size, "ep0 max 64 pio %s\n", | ||
| 1775 | ep->is_in ? "in" : "out"); | ||
| 1776 | if (t <= 0 || t > size) | ||
| 1777 | goto done; | ||
| 1778 | size -= t; | ||
| 1779 | next += t; | ||
| 1780 | |||
| 1781 | if (list_empty(&ep->queue)) { | ||
| 1782 | t = scnprintf(next, size, "\t(nothing queued)\n"); | ||
| 1783 | if (t <= 0 || t > size) | ||
| 1784 | goto done; | ||
| 1785 | size -= t; | ||
| 1786 | next += t; | ||
| 1787 | continue; | ||
| 1788 | } | ||
| 1789 | list_for_each_entry(req, &ep->queue, queue) { | ||
| 1790 | if (ep->dma && req->td_dma == readl(&ep->dma->dmadesc)) | ||
| 1791 | t = scnprintf(next, size, | ||
| 1792 | "\treq %p len %d/%d " | ||
| 1793 | "buf %p (dmacount %08x)\n", | ||
| 1794 | &req->req, req->req.actual, | ||
| 1795 | req->req.length, req->req.buf, | ||
| 1796 | readl(&ep->dma->dmacount)); | ||
| 1797 | else | ||
| 1798 | t = scnprintf(next, size, | ||
| 1799 | "\treq %p len %d/%d buf %p\n", | ||
| 1800 | &req->req, req->req.actual, | ||
| 1801 | req->req.length, req->req.buf); | ||
| 1802 | if (t <= 0 || t > size) | ||
| 1803 | goto done; | ||
| 1804 | size -= t; | ||
| 1805 | next += t; | ||
| 1806 | |||
| 1807 | if (ep->dma) { | ||
| 1808 | struct net2280_dma *td; | ||
| 1809 | |||
| 1810 | td = req->td; | ||
| 1811 | t = scnprintf(next, size, "\t td %08x " | ||
| 1812 | " count %08x buf %08x desc %08x\n", | ||
| 1813 | (u32) req->td_dma, | ||
| 1814 | le32_to_cpu(td->dmacount), | ||
| 1815 | le32_to_cpu(td->dmaaddr), | ||
| 1816 | le32_to_cpu(td->dmadesc)); | ||
| 1817 | if (t <= 0 || t > size) | ||
| 1818 | goto done; | ||
| 1819 | size -= t; | ||
| 1820 | next += t; | ||
| 1821 | } | ||
| 1822 | } | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | done: | ||
| 1826 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1827 | return PAGE_SIZE - size; | ||
| 1828 | } | ||
| 1829 | static DEVICE_ATTR_RO(queues); | ||
| 1830 | |||
| 1831 | |||
| 1832 | #else | ||
| 1833 | |||
| 1834 | #define device_create_file(a, b) (0) | ||
| 1835 | #define device_remove_file(a, b) do { } while (0) | ||
| 1836 | |||
| 1837 | #endif | ||
| 1838 | |||
| 1839 | /*-------------------------------------------------------------------------*/ | ||
| 1840 | |||
| 1841 | /* another driver-specific mode might be a request type doing dma | ||
| 1842 | * to/from another device fifo instead of to/from memory. | ||
| 1843 | */ | ||
| 1844 | |||
| 1845 | static void set_fifo_mode(struct net2280 *dev, int mode) | ||
| 1846 | { | ||
| 1847 | /* keeping high bits preserves BAR2 */ | ||
| 1848 | writel((0xffff << PCI_BASE2_RANGE) | mode, &dev->regs->fifoctl); | ||
| 1849 | |||
| 1850 | /* always ep-{a,b,e,f} ... maybe not ep-c or ep-d */ | ||
| 1851 | INIT_LIST_HEAD(&dev->gadget.ep_list); | ||
| 1852 | list_add_tail(&dev->ep[1].ep.ep_list, &dev->gadget.ep_list); | ||
| 1853 | list_add_tail(&dev->ep[2].ep.ep_list, &dev->gadget.ep_list); | ||
| 1854 | switch (mode) { | ||
| 1855 | case 0: | ||
| 1856 | list_add_tail(&dev->ep[3].ep.ep_list, &dev->gadget.ep_list); | ||
| 1857 | list_add_tail(&dev->ep[4].ep.ep_list, &dev->gadget.ep_list); | ||
| 1858 | dev->ep[1].fifo_size = dev->ep[2].fifo_size = 1024; | ||
| 1859 | break; | ||
| 1860 | case 1: | ||
| 1861 | dev->ep[1].fifo_size = dev->ep[2].fifo_size = 2048; | ||
| 1862 | break; | ||
| 1863 | case 2: | ||
| 1864 | list_add_tail(&dev->ep[3].ep.ep_list, &dev->gadget.ep_list); | ||
| 1865 | dev->ep[1].fifo_size = 2048; | ||
| 1866 | dev->ep[2].fifo_size = 1024; | ||
| 1867 | break; | ||
| 1868 | } | ||
| 1869 | /* fifo sizes for ep0, ep-c, ep-d, ep-e, and ep-f never change */ | ||
| 1870 | list_add_tail(&dev->ep[5].ep.ep_list, &dev->gadget.ep_list); | ||
| 1871 | list_add_tail(&dev->ep[6].ep.ep_list, &dev->gadget.ep_list); | ||
| 1872 | } | ||
| 1873 | |||
| 1874 | static void defect7374_disable_data_eps(struct net2280 *dev) | ||
| 1875 | { | ||
| 1876 | /* | ||
| 1877 | * For Defect 7374, disable data EPs (and more): | ||
| 1878 | * - This phase undoes the earlier phase of the Defect 7374 workaround, | ||
| 1879 | * returing ep regs back to normal. | ||
| 1880 | */ | ||
| 1881 | struct net2280_ep *ep; | ||
| 1882 | int i; | ||
| 1883 | unsigned char ep_sel; | ||
| 1884 | u32 tmp_reg; | ||
| 1885 | |||
| 1886 | for (i = 1; i < 5; i++) { | ||
| 1887 | ep = &dev->ep[i]; | ||
| 1888 | writel(0, &ep->cfg->ep_cfg); | ||
| 1889 | } | ||
| 1890 | |||
| 1891 | /* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */ | ||
| 1892 | for (i = 0; i < 6; i++) | ||
| 1893 | writel(0, &dev->dep[i].dep_cfg); | ||
| 1894 | |||
| 1895 | for (ep_sel = 0; ep_sel <= 21; ep_sel++) { | ||
| 1896 | /* Select an endpoint for subsequent operations: */ | ||
| 1897 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
| 1898 | writel(((tmp_reg & ~0x1f) | ep_sel), &dev->plregs->pl_ep_ctrl); | ||
| 1899 | |||
| 1900 | if (ep_sel < 2 || (ep_sel > 9 && ep_sel < 14) || | ||
| 1901 | ep_sel == 18 || ep_sel == 20) | ||
| 1902 | continue; | ||
| 1903 | |||
| 1904 | /* Change settings on some selected endpoints */ | ||
| 1905 | tmp_reg = readl(&dev->plregs->pl_ep_cfg_4); | ||
| 1906 | tmp_reg &= ~BIT(NON_CTRL_IN_TOLERATE_BAD_DIR); | ||
| 1907 | writel(tmp_reg, &dev->plregs->pl_ep_cfg_4); | ||
| 1908 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
| 1909 | tmp_reg |= BIT(EP_INITIALIZED); | ||
| 1910 | writel(tmp_reg, &dev->plregs->pl_ep_ctrl); | ||
| 1911 | } | ||
| 1912 | } | ||
| 1913 | |||
| 1914 | static void defect7374_enable_data_eps_zero(struct net2280 *dev) | ||
| 1915 | { | ||
| 1916 | u32 tmp = 0, tmp_reg; | ||
| 1917 | u32 fsmvalue, scratch; | ||
| 1918 | int i; | ||
| 1919 | unsigned char ep_sel; | ||
| 1920 | |||
| 1921 | scratch = get_idx_reg(dev->regs, SCRATCH); | ||
| 1922 | fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD); | ||
| 1923 | scratch &= ~(0xf << DEFECT7374_FSM_FIELD); | ||
| 1924 | |||
| 1925 | /*See if firmware needs to set up for workaround*/ | ||
| 1926 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) { | ||
| 1927 | ep_warn(dev, "Operate Defect 7374 workaround soft this time"); | ||
| 1928 | ep_warn(dev, "It will operate on cold-reboot and SS connect"); | ||
| 1929 | |||
| 1930 | /*GPEPs:*/ | ||
| 1931 | tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) | | ||
| 1932 | (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) | | ||
| 1933 | ((dev->enhanced_mode) ? | ||
| 1934 | BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) | | ||
| 1935 | BIT(IN_ENDPOINT_ENABLE)); | ||
| 1936 | |||
| 1937 | for (i = 1; i < 5; i++) | ||
| 1938 | writel(tmp, &dev->ep[i].cfg->ep_cfg); | ||
| 1939 | |||
| 1940 | /* CSRIN, PCIIN, STATIN, RCIN*/ | ||
| 1941 | tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE)); | ||
| 1942 | writel(tmp, &dev->dep[1].dep_cfg); | ||
| 1943 | writel(tmp, &dev->dep[3].dep_cfg); | ||
| 1944 | writel(tmp, &dev->dep[4].dep_cfg); | ||
| 1945 | writel(tmp, &dev->dep[5].dep_cfg); | ||
| 1946 | |||
| 1947 | /*Implemented for development and debug. | ||
| 1948 | * Can be refined/tuned later.*/ | ||
| 1949 | for (ep_sel = 0; ep_sel <= 21; ep_sel++) { | ||
| 1950 | /* Select an endpoint for subsequent operations: */ | ||
| 1951 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
| 1952 | writel(((tmp_reg & ~0x1f) | ep_sel), | ||
| 1953 | &dev->plregs->pl_ep_ctrl); | ||
| 1954 | |||
| 1955 | if (ep_sel == 1) { | ||
| 1956 | tmp = | ||
| 1957 | (readl(&dev->plregs->pl_ep_ctrl) | | ||
| 1958 | BIT(CLEAR_ACK_ERROR_CODE) | 0); | ||
| 1959 | writel(tmp, &dev->plregs->pl_ep_ctrl); | ||
| 1960 | continue; | ||
| 1961 | } | ||
| 1962 | |||
| 1963 | if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) || | ||
| 1964 | ep_sel == 18 || ep_sel == 20) | ||
| 1965 | continue; | ||
| 1966 | |||
| 1967 | tmp = (readl(&dev->plregs->pl_ep_cfg_4) | | ||
| 1968 | BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0); | ||
| 1969 | writel(tmp, &dev->plregs->pl_ep_cfg_4); | ||
| 1970 | |||
| 1971 | tmp = readl(&dev->plregs->pl_ep_ctrl) & | ||
| 1972 | ~BIT(EP_INITIALIZED); | ||
| 1973 | writel(tmp, &dev->plregs->pl_ep_ctrl); | ||
| 1974 | |||
| 1975 | } | ||
| 1976 | |||
| 1977 | /* Set FSM to focus on the first Control Read: | ||
| 1978 | * - Tip: Connection speed is known upon the first | ||
| 1979 | * setup request.*/ | ||
| 1980 | scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ; | ||
| 1981 | set_idx_reg(dev->regs, SCRATCH, scratch); | ||
| 1982 | |||
| 1983 | } else{ | ||
| 1984 | ep_warn(dev, "Defect 7374 workaround soft will NOT operate"); | ||
| 1985 | ep_warn(dev, "It will operate on cold-reboot and SS connect"); | ||
| 1986 | } | ||
| 1987 | } | ||
| 1988 | |||
| 1989 | /* keeping it simple: | ||
| 1990 | * - one bus driver, initted first; | ||
| 1991 | * - one function driver, initted second | ||
| 1992 | * | ||
| 1993 | * most of the work to support multiple net2280 controllers would | ||
| 1994 | * be to associate this gadget driver (yes?) with all of them, or | ||
| 1995 | * perhaps to bind specific drivers to specific devices. | ||
| 1996 | */ | ||
| 1997 | |||
| 1998 | static void usb_reset_228x(struct net2280 *dev) | ||
| 1999 | { | ||
| 2000 | u32 tmp; | ||
| 2001 | |||
| 2002 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 2003 | (void) readl(&dev->usb->usbctl); | ||
| 2004 | |||
| 2005 | net2280_led_init(dev); | ||
| 2006 | |||
| 2007 | /* disable automatic responses, and irqs */ | ||
| 2008 | writel(0, &dev->usb->stdrsp); | ||
| 2009 | writel(0, &dev->regs->pciirqenb0); | ||
| 2010 | writel(0, &dev->regs->pciirqenb1); | ||
| 2011 | |||
| 2012 | /* clear old dma and irq state */ | ||
| 2013 | for (tmp = 0; tmp < 4; tmp++) { | ||
| 2014 | struct net2280_ep *ep = &dev->ep[tmp + 1]; | ||
| 2015 | if (ep->dma) | ||
| 2016 | abort_dma(ep); | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | writel(~0, &dev->regs->irqstat0), | ||
| 2020 | writel(~(u32)BIT(SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1), | ||
| 2021 | |||
| 2022 | /* reset, and enable pci */ | ||
| 2023 | tmp = readl(&dev->regs->devinit) | | ||
| 2024 | BIT(PCI_ENABLE) | | ||
| 2025 | BIT(FIFO_SOFT_RESET) | | ||
| 2026 | BIT(USB_SOFT_RESET) | | ||
| 2027 | BIT(M8051_RESET); | ||
| 2028 | writel(tmp, &dev->regs->devinit); | ||
| 2029 | |||
| 2030 | /* standard fifo and endpoint allocations */ | ||
| 2031 | set_fifo_mode(dev, (fifo_mode <= 2) ? fifo_mode : 0); | ||
| 2032 | } | ||
| 2033 | |||
| 2034 | static void usb_reset_338x(struct net2280 *dev) | ||
| 2035 | { | ||
| 2036 | u32 tmp; | ||
| 2037 | u32 fsmvalue; | ||
| 2038 | |||
| 2039 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 2040 | (void)readl(&dev->usb->usbctl); | ||
| 2041 | |||
| 2042 | net2280_led_init(dev); | ||
| 2043 | |||
| 2044 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
| 2045 | (0xf << DEFECT7374_FSM_FIELD); | ||
| 2046 | |||
| 2047 | /* See if firmware needs to set up for workaround: */ | ||
| 2048 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) { | ||
| 2049 | ep_info(dev, "%s: Defect 7374 FsmValue 0x%08x\n", __func__, | ||
| 2050 | fsmvalue); | ||
| 2051 | } else { | ||
| 2052 | /* disable automatic responses, and irqs */ | ||
| 2053 | writel(0, &dev->usb->stdrsp); | ||
| 2054 | writel(0, &dev->regs->pciirqenb0); | ||
| 2055 | writel(0, &dev->regs->pciirqenb1); | ||
| 2056 | } | ||
| 2057 | |||
| 2058 | /* clear old dma and irq state */ | ||
| 2059 | for (tmp = 0; tmp < 4; tmp++) { | ||
| 2060 | struct net2280_ep *ep = &dev->ep[tmp + 1]; | ||
| 2061 | |||
| 2062 | if (ep->dma) | ||
| 2063 | abort_dma(ep); | ||
| 2064 | } | ||
| 2065 | |||
| 2066 | writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1); | ||
| 2067 | |||
| 2068 | if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) { | ||
| 2069 | /* reset, and enable pci */ | ||
| 2070 | tmp = readl(&dev->regs->devinit) | | ||
| 2071 | BIT(PCI_ENABLE) | | ||
| 2072 | BIT(FIFO_SOFT_RESET) | | ||
| 2073 | BIT(USB_SOFT_RESET) | | ||
| 2074 | BIT(M8051_RESET); | ||
| 2075 | |||
| 2076 | writel(tmp, &dev->regs->devinit); | ||
| 2077 | } | ||
| 2078 | |||
| 2079 | /* always ep-{1,2,3,4} ... maybe not ep-3 or ep-4 */ | ||
| 2080 | INIT_LIST_HEAD(&dev->gadget.ep_list); | ||
| 2081 | |||
| 2082 | for (tmp = 1; tmp < dev->n_ep; tmp++) | ||
| 2083 | list_add_tail(&dev->ep[tmp].ep.ep_list, &dev->gadget.ep_list); | ||
| 2084 | |||
| 2085 | } | ||
| 2086 | |||
| 2087 | static void usb_reset(struct net2280 *dev) | ||
| 2088 | { | ||
| 2089 | if (dev->quirks & PLX_LEGACY) | ||
| 2090 | return usb_reset_228x(dev); | ||
| 2091 | return usb_reset_338x(dev); | ||
| 2092 | } | ||
| 2093 | |||
| 2094 | static void usb_reinit_228x(struct net2280 *dev) | ||
| 2095 | { | ||
| 2096 | u32 tmp; | ||
| 2097 | int init_dma; | ||
| 2098 | |||
| 2099 | /* use_dma changes are ignored till next device re-init */ | ||
| 2100 | init_dma = use_dma; | ||
| 2101 | |||
| 2102 | /* basic endpoint init */ | ||
| 2103 | for (tmp = 0; tmp < 7; tmp++) { | ||
| 2104 | struct net2280_ep *ep = &dev->ep[tmp]; | ||
| 2105 | |||
| 2106 | ep->ep.name = ep_name[tmp]; | ||
| 2107 | ep->dev = dev; | ||
| 2108 | ep->num = tmp; | ||
| 2109 | |||
| 2110 | if (tmp > 0 && tmp <= 4) { | ||
| 2111 | ep->fifo_size = 1024; | ||
| 2112 | if (init_dma) | ||
| 2113 | ep->dma = &dev->dma[tmp - 1]; | ||
| 2114 | } else | ||
| 2115 | ep->fifo_size = 64; | ||
| 2116 | ep->regs = &dev->epregs[tmp]; | ||
| 2117 | ep->cfg = &dev->epregs[tmp]; | ||
| 2118 | ep_reset_228x(dev->regs, ep); | ||
| 2119 | } | ||
| 2120 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 64); | ||
| 2121 | usb_ep_set_maxpacket_limit(&dev->ep[5].ep, 64); | ||
| 2122 | usb_ep_set_maxpacket_limit(&dev->ep[6].ep, 64); | ||
| 2123 | |||
| 2124 | dev->gadget.ep0 = &dev->ep[0].ep; | ||
| 2125 | dev->ep[0].stopped = 0; | ||
| 2126 | INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); | ||
| 2127 | |||
| 2128 | /* we want to prevent lowlevel/insecure access from the USB host, | ||
| 2129 | * but erratum 0119 means this enable bit is ignored | ||
| 2130 | */ | ||
| 2131 | for (tmp = 0; tmp < 5; tmp++) | ||
| 2132 | writel(EP_DONTUSE, &dev->dep[tmp].dep_cfg); | ||
| 2133 | } | ||
| 2134 | |||
| 2135 | static void usb_reinit_338x(struct net2280 *dev) | ||
| 2136 | { | ||
| 2137 | int init_dma; | ||
| 2138 | int i; | ||
| 2139 | u32 tmp, val; | ||
| 2140 | u32 fsmvalue; | ||
| 2141 | static const u32 ne[9] = { 0, 1, 2, 3, 4, 1, 2, 3, 4 }; | ||
| 2142 | static const u32 ep_reg_addr[9] = { 0x00, 0xC0, 0x00, 0xC0, 0x00, | ||
| 2143 | 0x00, 0xC0, 0x00, 0xC0 }; | ||
| 2144 | |||
| 2145 | /* use_dma changes are ignored till next device re-init */ | ||
| 2146 | init_dma = use_dma; | ||
| 2147 | |||
| 2148 | /* basic endpoint init */ | ||
| 2149 | for (i = 0; i < dev->n_ep; i++) { | ||
| 2150 | struct net2280_ep *ep = &dev->ep[i]; | ||
| 2151 | |||
| 2152 | ep->ep.name = ep_name[i]; | ||
| 2153 | ep->dev = dev; | ||
| 2154 | ep->num = i; | ||
| 2155 | |||
| 2156 | if (i > 0 && i <= 4 && init_dma) | ||
| 2157 | ep->dma = &dev->dma[i - 1]; | ||
| 2158 | |||
| 2159 | if (dev->enhanced_mode) { | ||
| 2160 | ep->cfg = &dev->epregs[ne[i]]; | ||
| 2161 | ep->regs = (struct net2280_ep_regs __iomem *) | ||
| 2162 | (((void __iomem *)&dev->epregs[ne[i]]) + | ||
| 2163 | ep_reg_addr[i]); | ||
| 2164 | ep->fiforegs = &dev->fiforegs[i]; | ||
| 2165 | } else { | ||
| 2166 | ep->cfg = &dev->epregs[i]; | ||
| 2167 | ep->regs = &dev->epregs[i]; | ||
| 2168 | ep->fiforegs = &dev->fiforegs[i]; | ||
| 2169 | } | ||
| 2170 | |||
| 2171 | ep->fifo_size = (i != 0) ? 2048 : 512; | ||
| 2172 | |||
| 2173 | ep_reset_338x(dev->regs, ep); | ||
| 2174 | } | ||
| 2175 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 512); | ||
| 2176 | |||
| 2177 | dev->gadget.ep0 = &dev->ep[0].ep; | ||
| 2178 | dev->ep[0].stopped = 0; | ||
| 2179 | |||
| 2180 | /* Link layer set up */ | ||
| 2181 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
| 2182 | (0xf << DEFECT7374_FSM_FIELD); | ||
| 2183 | |||
| 2184 | /* See if driver needs to set up for workaround: */ | ||
| 2185 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) | ||
| 2186 | ep_info(dev, "%s: Defect 7374 FsmValue %08x\n", | ||
| 2187 | __func__, fsmvalue); | ||
| 2188 | else { | ||
| 2189 | tmp = readl(&dev->usb_ext->usbctl2) & | ||
| 2190 | ~(BIT(U1_ENABLE) | BIT(U2_ENABLE) | BIT(LTM_ENABLE)); | ||
| 2191 | writel(tmp, &dev->usb_ext->usbctl2); | ||
| 2192 | } | ||
| 2193 | |||
| 2194 | /* Hardware Defect and Workaround */ | ||
| 2195 | val = readl(&dev->ll_lfps_regs->ll_lfps_5); | ||
| 2196 | val &= ~(0xf << TIMER_LFPS_6US); | ||
| 2197 | val |= 0x5 << TIMER_LFPS_6US; | ||
| 2198 | writel(val, &dev->ll_lfps_regs->ll_lfps_5); | ||
| 2199 | |||
| 2200 | val = readl(&dev->ll_lfps_regs->ll_lfps_6); | ||
| 2201 | val &= ~(0xffff << TIMER_LFPS_80US); | ||
| 2202 | val |= 0x0100 << TIMER_LFPS_80US; | ||
| 2203 | writel(val, &dev->ll_lfps_regs->ll_lfps_6); | ||
| 2204 | |||
| 2205 | /* | ||
| 2206 | * AA_AB Errata. Issue 4. Workaround for SuperSpeed USB | ||
| 2207 | * Hot Reset Exit Handshake may Fail in Specific Case using | ||
| 2208 | * Default Register Settings. Workaround for Enumeration test. | ||
| 2209 | */ | ||
| 2210 | val = readl(&dev->ll_tsn_regs->ll_tsn_counters_2); | ||
| 2211 | val &= ~(0x1f << HOT_TX_NORESET_TS2); | ||
| 2212 | val |= 0x10 << HOT_TX_NORESET_TS2; | ||
| 2213 | writel(val, &dev->ll_tsn_regs->ll_tsn_counters_2); | ||
| 2214 | |||
| 2215 | val = readl(&dev->ll_tsn_regs->ll_tsn_counters_3); | ||
| 2216 | val &= ~(0x1f << HOT_RX_RESET_TS2); | ||
| 2217 | val |= 0x3 << HOT_RX_RESET_TS2; | ||
| 2218 | writel(val, &dev->ll_tsn_regs->ll_tsn_counters_3); | ||
| 2219 | |||
| 2220 | /* | ||
| 2221 | * Set Recovery Idle to Recover bit: | ||
| 2222 | * - On SS connections, setting Recovery Idle to Recover Fmw improves | ||
| 2223 | * link robustness with various hosts and hubs. | ||
| 2224 | * - It is safe to set for all connection speeds; all chip revisions. | ||
| 2225 | * - R-M-W to leave other bits undisturbed. | ||
| 2226 | * - Reference PLX TT-7372 | ||
| 2227 | */ | ||
| 2228 | val = readl(&dev->ll_chicken_reg->ll_tsn_chicken_bit); | ||
| 2229 | val |= BIT(RECOVERY_IDLE_TO_RECOVER_FMW); | ||
| 2230 | writel(val, &dev->ll_chicken_reg->ll_tsn_chicken_bit); | ||
| 2231 | |||
| 2232 | INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); | ||
| 2233 | |||
| 2234 | /* disable dedicated endpoints */ | ||
| 2235 | writel(0x0D, &dev->dep[0].dep_cfg); | ||
| 2236 | writel(0x0D, &dev->dep[1].dep_cfg); | ||
| 2237 | writel(0x0E, &dev->dep[2].dep_cfg); | ||
| 2238 | writel(0x0E, &dev->dep[3].dep_cfg); | ||
| 2239 | writel(0x0F, &dev->dep[4].dep_cfg); | ||
| 2240 | writel(0x0C, &dev->dep[5].dep_cfg); | ||
| 2241 | } | ||
| 2242 | |||
| 2243 | static void usb_reinit(struct net2280 *dev) | ||
| 2244 | { | ||
| 2245 | if (dev->quirks & PLX_LEGACY) | ||
| 2246 | return usb_reinit_228x(dev); | ||
| 2247 | return usb_reinit_338x(dev); | ||
| 2248 | } | ||
| 2249 | |||
| 2250 | static void ep0_start_228x(struct net2280 *dev) | ||
| 2251 | { | ||
| 2252 | writel(BIT(CLEAR_EP_HIDE_STATUS_PHASE) | | ||
| 2253 | BIT(CLEAR_NAK_OUT_PACKETS) | | ||
| 2254 | BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE), | ||
| 2255 | &dev->epregs[0].ep_rsp); | ||
| 2256 | |||
| 2257 | /* | ||
| 2258 | * hardware optionally handles a bunch of standard requests | ||
| 2259 | * that the API hides from drivers anyway. have it do so. | ||
| 2260 | * endpoint status/features are handled in software, to | ||
| 2261 | * help pass tests for some dubious behavior. | ||
| 2262 | */ | ||
| 2263 | writel(BIT(SET_TEST_MODE) | | ||
| 2264 | BIT(SET_ADDRESS) | | ||
| 2265 | BIT(DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP) | | ||
| 2266 | BIT(GET_DEVICE_STATUS) | | ||
| 2267 | BIT(GET_INTERFACE_STATUS), | ||
| 2268 | &dev->usb->stdrsp); | ||
| 2269 | writel(BIT(USB_ROOT_PORT_WAKEUP_ENABLE) | | ||
| 2270 | BIT(SELF_POWERED_USB_DEVICE) | | ||
| 2271 | BIT(REMOTE_WAKEUP_SUPPORT) | | ||
| 2272 | (dev->softconnect << USB_DETECT_ENABLE) | | ||
| 2273 | BIT(SELF_POWERED_STATUS), | ||
| 2274 | &dev->usb->usbctl); | ||
| 2275 | |||
| 2276 | /* enable irqs so we can see ep0 and general operation */ | ||
| 2277 | writel(BIT(SETUP_PACKET_INTERRUPT_ENABLE) | | ||
| 2278 | BIT(ENDPOINT_0_INTERRUPT_ENABLE), | ||
| 2279 | &dev->regs->pciirqenb0); | ||
| 2280 | writel(BIT(PCI_INTERRUPT_ENABLE) | | ||
| 2281 | BIT(PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE) | | ||
| 2282 | BIT(PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE) | | ||
| 2283 | BIT(PCI_RETRY_ABORT_INTERRUPT_ENABLE) | | ||
| 2284 | BIT(VBUS_INTERRUPT_ENABLE) | | ||
| 2285 | BIT(ROOT_PORT_RESET_INTERRUPT_ENABLE) | | ||
| 2286 | BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE), | ||
| 2287 | &dev->regs->pciirqenb1); | ||
| 2288 | |||
| 2289 | /* don't leave any writes posted */ | ||
| 2290 | (void) readl(&dev->usb->usbctl); | ||
| 2291 | } | ||
| 2292 | |||
| 2293 | static void ep0_start_338x(struct net2280 *dev) | ||
| 2294 | { | ||
| 2295 | u32 fsmvalue; | ||
| 2296 | |||
| 2297 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
| 2298 | (0xf << DEFECT7374_FSM_FIELD); | ||
| 2299 | |||
| 2300 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) | ||
| 2301 | ep_info(dev, "%s: Defect 7374 FsmValue %08x\n", __func__, | ||
| 2302 | fsmvalue); | ||
| 2303 | else | ||
| 2304 | writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE) | | ||
| 2305 | BIT(SET_EP_HIDE_STATUS_PHASE), | ||
| 2306 | &dev->epregs[0].ep_rsp); | ||
| 2307 | |||
| 2308 | /* | ||
| 2309 | * hardware optionally handles a bunch of standard requests | ||
| 2310 | * that the API hides from drivers anyway. have it do so. | ||
| 2311 | * endpoint status/features are handled in software, to | ||
| 2312 | * help pass tests for some dubious behavior. | ||
| 2313 | */ | ||
| 2314 | writel(BIT(SET_ISOCHRONOUS_DELAY) | | ||
| 2315 | BIT(SET_SEL) | | ||
| 2316 | BIT(SET_TEST_MODE) | | ||
| 2317 | BIT(SET_ADDRESS) | | ||
| 2318 | BIT(GET_INTERFACE_STATUS) | | ||
| 2319 | BIT(GET_DEVICE_STATUS), | ||
| 2320 | &dev->usb->stdrsp); | ||
| 2321 | dev->wakeup_enable = 1; | ||
| 2322 | writel(BIT(USB_ROOT_PORT_WAKEUP_ENABLE) | | ||
| 2323 | (dev->softconnect << USB_DETECT_ENABLE) | | ||
| 2324 | BIT(DEVICE_REMOTE_WAKEUP_ENABLE), | ||
| 2325 | &dev->usb->usbctl); | ||
| 2326 | |||
| 2327 | /* enable irqs so we can see ep0 and general operation */ | ||
| 2328 | writel(BIT(SETUP_PACKET_INTERRUPT_ENABLE) | | ||
| 2329 | BIT(ENDPOINT_0_INTERRUPT_ENABLE), | ||
| 2330 | &dev->regs->pciirqenb0); | ||
| 2331 | writel(BIT(PCI_INTERRUPT_ENABLE) | | ||
| 2332 | BIT(ROOT_PORT_RESET_INTERRUPT_ENABLE) | | ||
| 2333 | BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE) | | ||
| 2334 | BIT(VBUS_INTERRUPT_ENABLE), | ||
| 2335 | &dev->regs->pciirqenb1); | ||
| 2336 | |||
| 2337 | /* don't leave any writes posted */ | ||
| 2338 | (void)readl(&dev->usb->usbctl); | ||
| 2339 | } | ||
| 2340 | |||
| 2341 | static void ep0_start(struct net2280 *dev) | ||
| 2342 | { | ||
| 2343 | if (dev->quirks & PLX_LEGACY) | ||
| 2344 | return ep0_start_228x(dev); | ||
| 2345 | return ep0_start_338x(dev); | ||
| 2346 | } | ||
| 2347 | |||
| 2348 | /* when a driver is successfully registered, it will receive | ||
| 2349 | * control requests including set_configuration(), which enables | ||
| 2350 | * non-control requests. then usb traffic follows until a | ||
| 2351 | * disconnect is reported. then a host may connect again, or | ||
| 2352 | * the driver might get unbound. | ||
| 2353 | */ | ||
| 2354 | static int net2280_start(struct usb_gadget *_gadget, | ||
| 2355 | struct usb_gadget_driver *driver) | ||
| 2356 | { | ||
| 2357 | struct net2280 *dev; | ||
| 2358 | int retval; | ||
| 2359 | unsigned i; | ||
| 2360 | |||
| 2361 | /* insist on high speed support from the driver, since | ||
| 2362 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) | ||
| 2363 | * "must not be used in normal operation" | ||
| 2364 | */ | ||
| 2365 | if (!driver || driver->max_speed < USB_SPEED_HIGH || | ||
| 2366 | !driver->setup) | ||
| 2367 | return -EINVAL; | ||
| 2368 | |||
| 2369 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 2370 | |||
| 2371 | for (i = 0; i < dev->n_ep; i++) | ||
| 2372 | dev->ep[i].irqs = 0; | ||
| 2373 | |||
| 2374 | /* hook up the driver ... */ | ||
| 2375 | dev->softconnect = 1; | ||
| 2376 | driver->driver.bus = NULL; | ||
| 2377 | dev->driver = driver; | ||
| 2378 | |||
| 2379 | retval = device_create_file(&dev->pdev->dev, &dev_attr_function); | ||
| 2380 | if (retval) | ||
| 2381 | goto err_unbind; | ||
| 2382 | retval = device_create_file(&dev->pdev->dev, &dev_attr_queues); | ||
| 2383 | if (retval) | ||
| 2384 | goto err_func; | ||
| 2385 | |||
| 2386 | /* Enable force-full-speed testing mode, if desired */ | ||
| 2387 | if (full_speed && (dev->quirks & PLX_LEGACY)) | ||
| 2388 | writel(BIT(FORCE_FULL_SPEED_MODE), &dev->usb->xcvrdiag); | ||
| 2389 | |||
| 2390 | /* ... then enable host detection and ep0; and we're ready | ||
| 2391 | * for set_configuration as well as eventual disconnect. | ||
| 2392 | */ | ||
| 2393 | net2280_led_active(dev, 1); | ||
| 2394 | |||
| 2395 | if (dev->quirks & PLX_SUPERSPEED) | ||
| 2396 | defect7374_enable_data_eps_zero(dev); | ||
| 2397 | |||
| 2398 | ep0_start(dev); | ||
| 2399 | |||
| 2400 | ep_dbg(dev, "%s ready, usbctl %08x stdrsp %08x\n", | ||
| 2401 | driver->driver.name, | ||
| 2402 | readl(&dev->usb->usbctl), | ||
| 2403 | readl(&dev->usb->stdrsp)); | ||
| 2404 | |||
| 2405 | /* pci writes may still be posted */ | ||
| 2406 | return 0; | ||
| 2407 | |||
| 2408 | err_func: | ||
| 2409 | device_remove_file(&dev->pdev->dev, &dev_attr_function); | ||
| 2410 | err_unbind: | ||
| 2411 | dev->driver = NULL; | ||
| 2412 | return retval; | ||
| 2413 | } | ||
| 2414 | |||
| 2415 | static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver) | ||
| 2416 | { | ||
| 2417 | int i; | ||
| 2418 | |||
| 2419 | /* don't disconnect if it's not connected */ | ||
| 2420 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 2421 | driver = NULL; | ||
| 2422 | |||
| 2423 | /* stop hardware; prevent new request submissions; | ||
| 2424 | * and kill any outstanding requests. | ||
| 2425 | */ | ||
| 2426 | usb_reset(dev); | ||
| 2427 | for (i = 0; i < dev->n_ep; i++) | ||
| 2428 | nuke(&dev->ep[i]); | ||
| 2429 | |||
| 2430 | /* report disconnect; the driver is already quiesced */ | ||
| 2431 | if (driver) { | ||
| 2432 | spin_unlock(&dev->lock); | ||
| 2433 | driver->disconnect(&dev->gadget); | ||
| 2434 | spin_lock(&dev->lock); | ||
| 2435 | } | ||
| 2436 | |||
| 2437 | usb_reinit(dev); | ||
| 2438 | } | ||
| 2439 | |||
| 2440 | static int net2280_stop(struct usb_gadget *_gadget, | ||
| 2441 | struct usb_gadget_driver *driver) | ||
| 2442 | { | ||
| 2443 | struct net2280 *dev; | ||
| 2444 | unsigned long flags; | ||
| 2445 | |||
| 2446 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 2447 | |||
| 2448 | spin_lock_irqsave(&dev->lock, flags); | ||
| 2449 | stop_activity(dev, driver); | ||
| 2450 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 2451 | |||
| 2452 | dev->driver = NULL; | ||
| 2453 | |||
| 2454 | net2280_led_active(dev, 0); | ||
| 2455 | |||
| 2456 | /* Disable full-speed test mode */ | ||
| 2457 | if (dev->quirks & PLX_LEGACY) | ||
| 2458 | writel(0, &dev->usb->xcvrdiag); | ||
| 2459 | |||
| 2460 | device_remove_file(&dev->pdev->dev, &dev_attr_function); | ||
| 2461 | device_remove_file(&dev->pdev->dev, &dev_attr_queues); | ||
| 2462 | |||
| 2463 | ep_dbg(dev, "unregistered driver '%s'\n", | ||
| 2464 | driver ? driver->driver.name : ""); | ||
| 2465 | |||
| 2466 | return 0; | ||
| 2467 | } | ||
| 2468 | |||
| 2469 | /*-------------------------------------------------------------------------*/ | ||
| 2470 | |||
| 2471 | /* handle ep0, ep-e, ep-f with 64 byte packets: packet per irq. | ||
| 2472 | * also works for dma-capable endpoints, in pio mode or just | ||
| 2473 | * to manually advance the queue after short OUT transfers. | ||
| 2474 | */ | ||
| 2475 | static void handle_ep_small(struct net2280_ep *ep) | ||
| 2476 | { | ||
| 2477 | struct net2280_request *req; | ||
| 2478 | u32 t; | ||
| 2479 | /* 0 error, 1 mid-data, 2 done */ | ||
| 2480 | int mode = 1; | ||
| 2481 | |||
| 2482 | if (!list_empty(&ep->queue)) | ||
| 2483 | req = list_entry(ep->queue.next, | ||
| 2484 | struct net2280_request, queue); | ||
| 2485 | else | ||
| 2486 | req = NULL; | ||
| 2487 | |||
| 2488 | /* ack all, and handle what we care about */ | ||
| 2489 | t = readl(&ep->regs->ep_stat); | ||
| 2490 | ep->irqs++; | ||
| 2491 | #if 0 | ||
| 2492 | ep_vdbg(ep->dev, "%s ack ep_stat %08x, req %p\n", | ||
| 2493 | ep->ep.name, t, req ? &req->req : 0); | ||
| 2494 | #endif | ||
| 2495 | if (!ep->is_in || (ep->dev->quirks & PLX_2280)) | ||
| 2496 | writel(t & ~BIT(NAK_OUT_PACKETS), &ep->regs->ep_stat); | ||
| 2497 | else | ||
| 2498 | /* Added for 2282 */ | ||
| 2499 | writel(t, &ep->regs->ep_stat); | ||
| 2500 | |||
| 2501 | /* for ep0, monitor token irqs to catch data stage length errors | ||
| 2502 | * and to synchronize on status. | ||
| 2503 | * | ||
| 2504 | * also, to defer reporting of protocol stalls ... here's where | ||
| 2505 | * data or status first appears, handling stalls here should never | ||
| 2506 | * cause trouble on the host side.. | ||
| 2507 | * | ||
| 2508 | * control requests could be slightly faster without token synch for | ||
| 2509 | * status, but status can jam up that way. | ||
| 2510 | */ | ||
| 2511 | if (unlikely(ep->num == 0)) { | ||
| 2512 | if (ep->is_in) { | ||
| 2513 | /* status; stop NAKing */ | ||
| 2514 | if (t & BIT(DATA_OUT_PING_TOKEN_INTERRUPT)) { | ||
| 2515 | if (ep->dev->protocol_stall) { | ||
| 2516 | ep->stopped = 1; | ||
| 2517 | set_halt(ep); | ||
| 2518 | } | ||
| 2519 | if (!req) | ||
| 2520 | allow_status(ep); | ||
| 2521 | mode = 2; | ||
| 2522 | /* reply to extra IN data tokens with a zlp */ | ||
| 2523 | } else if (t & BIT(DATA_IN_TOKEN_INTERRUPT)) { | ||
| 2524 | if (ep->dev->protocol_stall) { | ||
| 2525 | ep->stopped = 1; | ||
| 2526 | set_halt(ep); | ||
| 2527 | mode = 2; | ||
| 2528 | } else if (ep->responded && | ||
| 2529 | !req && !ep->stopped) | ||
| 2530 | write_fifo(ep, NULL); | ||
| 2531 | } | ||
| 2532 | } else { | ||
| 2533 | /* status; stop NAKing */ | ||
| 2534 | if (t & BIT(DATA_IN_TOKEN_INTERRUPT)) { | ||
| 2535 | if (ep->dev->protocol_stall) { | ||
| 2536 | ep->stopped = 1; | ||
| 2537 | set_halt(ep); | ||
| 2538 | } | ||
| 2539 | mode = 2; | ||
| 2540 | /* an extra OUT token is an error */ | ||
| 2541 | } else if (((t & BIT(DATA_OUT_PING_TOKEN_INTERRUPT)) && | ||
| 2542 | req && | ||
| 2543 | req->req.actual == req->req.length) || | ||
| 2544 | (ep->responded && !req)) { | ||
| 2545 | ep->dev->protocol_stall = 1; | ||
| 2546 | set_halt(ep); | ||
| 2547 | ep->stopped = 1; | ||
| 2548 | if (req) | ||
| 2549 | done(ep, req, -EOVERFLOW); | ||
| 2550 | req = NULL; | ||
| 2551 | } | ||
| 2552 | } | ||
| 2553 | } | ||
| 2554 | |||
| 2555 | if (unlikely(!req)) | ||
| 2556 | return; | ||
| 2557 | |||
| 2558 | /* manual DMA queue advance after short OUT */ | ||
| 2559 | if (likely(ep->dma)) { | ||
| 2560 | if (t & BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT)) { | ||
| 2561 | u32 count; | ||
| 2562 | int stopped = ep->stopped; | ||
| 2563 | |||
| 2564 | /* TRANSFERRED works around OUT_DONE erratum 0112. | ||
| 2565 | * we expect (N <= maxpacket) bytes; host wrote M. | ||
| 2566 | * iff (M < N) we won't ever see a DMA interrupt. | ||
| 2567 | */ | ||
| 2568 | ep->stopped = 1; | ||
| 2569 | for (count = 0; ; t = readl(&ep->regs->ep_stat)) { | ||
| 2570 | |||
| 2571 | /* any preceding dma transfers must finish. | ||
| 2572 | * dma handles (M >= N), may empty the queue | ||
| 2573 | */ | ||
| 2574 | scan_dma_completions(ep); | ||
| 2575 | if (unlikely(list_empty(&ep->queue) || | ||
| 2576 | ep->out_overflow)) { | ||
| 2577 | req = NULL; | ||
| 2578 | break; | ||
| 2579 | } | ||
| 2580 | req = list_entry(ep->queue.next, | ||
| 2581 | struct net2280_request, queue); | ||
| 2582 | |||
| 2583 | /* here either (M < N), a "real" short rx; | ||
| 2584 | * or (M == N) and the queue didn't empty | ||
| 2585 | */ | ||
| 2586 | if (likely(t & BIT(FIFO_EMPTY))) { | ||
| 2587 | count = readl(&ep->dma->dmacount); | ||
| 2588 | count &= DMA_BYTE_COUNT_MASK; | ||
| 2589 | if (readl(&ep->dma->dmadesc) | ||
| 2590 | != req->td_dma) | ||
| 2591 | req = NULL; | ||
| 2592 | break; | ||
| 2593 | } | ||
| 2594 | udelay(1); | ||
| 2595 | } | ||
| 2596 | |||
| 2597 | /* stop DMA, leave ep NAKing */ | ||
| 2598 | writel(BIT(DMA_ABORT), &ep->dma->dmastat); | ||
| 2599 | spin_stop_dma(ep->dma); | ||
| 2600 | |||
| 2601 | if (likely(req)) { | ||
| 2602 | req->td->dmacount = 0; | ||
| 2603 | t = readl(&ep->regs->ep_avail); | ||
| 2604 | dma_done(ep, req, count, | ||
| 2605 | (ep->out_overflow || t) | ||
| 2606 | ? -EOVERFLOW : 0); | ||
| 2607 | } | ||
| 2608 | |||
| 2609 | /* also flush to prevent erratum 0106 trouble */ | ||
| 2610 | if (unlikely(ep->out_overflow || | ||
| 2611 | (ep->dev->chiprev == 0x0100 && | ||
| 2612 | ep->dev->gadget.speed | ||
| 2613 | == USB_SPEED_FULL))) { | ||
| 2614 | out_flush(ep); | ||
| 2615 | ep->out_overflow = 0; | ||
| 2616 | } | ||
| 2617 | |||
| 2618 | /* (re)start dma if needed, stop NAKing */ | ||
| 2619 | ep->stopped = stopped; | ||
| 2620 | if (!list_empty(&ep->queue)) | ||
| 2621 | restart_dma(ep); | ||
| 2622 | } else | ||
| 2623 | ep_dbg(ep->dev, "%s dma ep_stat %08x ??\n", | ||
| 2624 | ep->ep.name, t); | ||
| 2625 | return; | ||
| 2626 | |||
| 2627 | /* data packet(s) received (in the fifo, OUT) */ | ||
| 2628 | } else if (t & BIT(DATA_PACKET_RECEIVED_INTERRUPT)) { | ||
| 2629 | if (read_fifo(ep, req) && ep->num != 0) | ||
| 2630 | mode = 2; | ||
| 2631 | |||
| 2632 | /* data packet(s) transmitted (IN) */ | ||
| 2633 | } else if (t & BIT(DATA_PACKET_TRANSMITTED_INTERRUPT)) { | ||
| 2634 | unsigned len; | ||
| 2635 | |||
| 2636 | len = req->req.length - req->req.actual; | ||
| 2637 | if (len > ep->ep.maxpacket) | ||
| 2638 | len = ep->ep.maxpacket; | ||
| 2639 | req->req.actual += len; | ||
| 2640 | |||
| 2641 | /* if we wrote it all, we're usually done */ | ||
| 2642 | /* send zlps until the status stage */ | ||
| 2643 | if ((req->req.actual == req->req.length) && | ||
| 2644 | (!req->req.zero || len != ep->ep.maxpacket) && ep->num) | ||
| 2645 | mode = 2; | ||
| 2646 | |||
| 2647 | /* there was nothing to do ... */ | ||
| 2648 | } else if (mode == 1) | ||
| 2649 | return; | ||
| 2650 | |||
| 2651 | /* done */ | ||
| 2652 | if (mode == 2) { | ||
| 2653 | /* stream endpoints often resubmit/unlink in completion */ | ||
| 2654 | done(ep, req, 0); | ||
| 2655 | |||
| 2656 | /* maybe advance queue to next request */ | ||
| 2657 | if (ep->num == 0) { | ||
| 2658 | /* NOTE: net2280 could let gadget driver start the | ||
| 2659 | * status stage later. since not all controllers let | ||
| 2660 | * them control that, the api doesn't (yet) allow it. | ||
| 2661 | */ | ||
| 2662 | if (!ep->stopped) | ||
| 2663 | allow_status(ep); | ||
| 2664 | req = NULL; | ||
| 2665 | } else { | ||
| 2666 | if (!list_empty(&ep->queue) && !ep->stopped) | ||
| 2667 | req = list_entry(ep->queue.next, | ||
| 2668 | struct net2280_request, queue); | ||
| 2669 | else | ||
| 2670 | req = NULL; | ||
| 2671 | if (req && !ep->is_in) | ||
| 2672 | stop_out_naking(ep); | ||
| 2673 | } | ||
| 2674 | } | ||
| 2675 | |||
| 2676 | /* is there a buffer for the next packet? | ||
| 2677 | * for best streaming performance, make sure there is one. | ||
| 2678 | */ | ||
| 2679 | if (req && !ep->stopped) { | ||
| 2680 | |||
| 2681 | /* load IN fifo with next packet (may be zlp) */ | ||
| 2682 | if (t & BIT(DATA_PACKET_TRANSMITTED_INTERRUPT)) | ||
| 2683 | write_fifo(ep, &req->req); | ||
| 2684 | } | ||
| 2685 | } | ||
| 2686 | |||
| 2687 | static struct net2280_ep *get_ep_by_addr(struct net2280 *dev, u16 wIndex) | ||
| 2688 | { | ||
| 2689 | struct net2280_ep *ep; | ||
| 2690 | |||
| 2691 | if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0) | ||
| 2692 | return &dev->ep[0]; | ||
| 2693 | list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) { | ||
| 2694 | u8 bEndpointAddress; | ||
| 2695 | |||
| 2696 | if (!ep->desc) | ||
| 2697 | continue; | ||
| 2698 | bEndpointAddress = ep->desc->bEndpointAddress; | ||
| 2699 | if ((wIndex ^ bEndpointAddress) & USB_DIR_IN) | ||
| 2700 | continue; | ||
| 2701 | if ((wIndex & 0x0f) == (bEndpointAddress & 0x0f)) | ||
| 2702 | return ep; | ||
| 2703 | } | ||
| 2704 | return NULL; | ||
| 2705 | } | ||
| 2706 | |||
| 2707 | static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r) | ||
| 2708 | { | ||
| 2709 | u32 scratch, fsmvalue; | ||
| 2710 | u32 ack_wait_timeout, state; | ||
| 2711 | |||
| 2712 | /* Workaround for Defect 7374 (U1/U2 erroneously rejected): */ | ||
| 2713 | scratch = get_idx_reg(dev->regs, SCRATCH); | ||
| 2714 | fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD); | ||
| 2715 | scratch &= ~(0xf << DEFECT7374_FSM_FIELD); | ||
| 2716 | |||
| 2717 | if (!((fsmvalue == DEFECT7374_FSM_WAITING_FOR_CONTROL_READ) && | ||
| 2718 | (r.bRequestType & USB_DIR_IN))) | ||
| 2719 | return; | ||
| 2720 | |||
| 2721 | /* This is the first Control Read for this connection: */ | ||
| 2722 | if (!(readl(&dev->usb->usbstat) & BIT(SUPER_SPEED_MODE))) { | ||
| 2723 | /* | ||
| 2724 | * Connection is NOT SS: | ||
| 2725 | * - Connection must be FS or HS. | ||
| 2726 | * - This FSM state should allow workaround software to | ||
| 2727 | * run after the next USB connection. | ||
| 2728 | */ | ||
| 2729 | scratch |= DEFECT7374_FSM_NON_SS_CONTROL_READ; | ||
| 2730 | goto restore_data_eps; | ||
| 2731 | } | ||
| 2732 | |||
| 2733 | /* Connection is SS: */ | ||
| 2734 | for (ack_wait_timeout = 0; | ||
| 2735 | ack_wait_timeout < DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS; | ||
| 2736 | ack_wait_timeout++) { | ||
| 2737 | |||
| 2738 | state = readl(&dev->plregs->pl_ep_status_1) | ||
| 2739 | & (0xff << STATE); | ||
| 2740 | if ((state >= (ACK_GOOD_NORMAL << STATE)) && | ||
| 2741 | (state <= (ACK_GOOD_MORE_ACKS_TO_COME << STATE))) { | ||
| 2742 | scratch |= DEFECT7374_FSM_SS_CONTROL_READ; | ||
| 2743 | break; | ||
| 2744 | } | ||
| 2745 | |||
| 2746 | /* | ||
| 2747 | * We have not yet received host's Data Phase ACK | ||
| 2748 | * - Wait and try again. | ||
| 2749 | */ | ||
| 2750 | udelay(DEFECT_7374_PROCESSOR_WAIT_TIME); | ||
| 2751 | |||
| 2752 | continue; | ||
| 2753 | } | ||
| 2754 | |||
| 2755 | |||
| 2756 | if (ack_wait_timeout >= DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS) { | ||
| 2757 | ep_err(dev, "FAIL: Defect 7374 workaround waited but failed " | ||
| 2758 | "to detect SS host's data phase ACK."); | ||
| 2759 | ep_err(dev, "PL_EP_STATUS_1(23:16):.Expected from 0x11 to 0x16" | ||
| 2760 | "got 0x%2.2x.\n", state >> STATE); | ||
| 2761 | } else { | ||
| 2762 | ep_warn(dev, "INFO: Defect 7374 workaround waited about\n" | ||
| 2763 | "%duSec for Control Read Data Phase ACK\n", | ||
| 2764 | DEFECT_7374_PROCESSOR_WAIT_TIME * ack_wait_timeout); | ||
| 2765 | } | ||
| 2766 | |||
| 2767 | restore_data_eps: | ||
| 2768 | /* | ||
| 2769 | * Restore data EPs to their pre-workaround settings (disabled, | ||
| 2770 | * initialized, and other details). | ||
| 2771 | */ | ||
| 2772 | defect7374_disable_data_eps(dev); | ||
| 2773 | |||
| 2774 | set_idx_reg(dev->regs, SCRATCH, scratch); | ||
| 2775 | |||
| 2776 | return; | ||
| 2777 | } | ||
| 2778 | |||
| 2779 | static void ep_stall(struct net2280_ep *ep, int stall) | ||
| 2780 | { | ||
| 2781 | struct net2280 *dev = ep->dev; | ||
| 2782 | u32 val; | ||
| 2783 | static const u32 ep_pl[9] = { 0, 3, 4, 7, 8, 2, 5, 6, 9 }; | ||
| 2784 | |||
| 2785 | if (stall) { | ||
| 2786 | writel(BIT(SET_ENDPOINT_HALT) | | ||
| 2787 | /* BIT(SET_NAK_PACKETS) | */ | ||
| 2788 | BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE), | ||
| 2789 | &ep->regs->ep_rsp); | ||
| 2790 | ep->is_halt = 1; | ||
| 2791 | } else { | ||
| 2792 | if (dev->gadget.speed == USB_SPEED_SUPER) { | ||
| 2793 | /* | ||
| 2794 | * Workaround for SS SeqNum not cleared via | ||
| 2795 | * Endpoint Halt (Clear) bit. select endpoint | ||
| 2796 | */ | ||
| 2797 | val = readl(&dev->plregs->pl_ep_ctrl); | ||
| 2798 | val = (val & ~0x1f) | ep_pl[ep->num]; | ||
| 2799 | writel(val, &dev->plregs->pl_ep_ctrl); | ||
| 2800 | |||
| 2801 | val |= BIT(SEQUENCE_NUMBER_RESET); | ||
| 2802 | writel(val, &dev->plregs->pl_ep_ctrl); | ||
| 2803 | } | ||
| 2804 | val = readl(&ep->regs->ep_rsp); | ||
| 2805 | val |= BIT(CLEAR_ENDPOINT_HALT) | | ||
| 2806 | BIT(CLEAR_ENDPOINT_TOGGLE); | ||
| 2807 | writel(val, | ||
| 2808 | /* | BIT(CLEAR_NAK_PACKETS),*/ | ||
| 2809 | &ep->regs->ep_rsp); | ||
| 2810 | ep->is_halt = 0; | ||
| 2811 | val = readl(&ep->regs->ep_rsp); | ||
| 2812 | } | ||
| 2813 | } | ||
| 2814 | |||
| 2815 | static void ep_stdrsp(struct net2280_ep *ep, int value, int wedged) | ||
| 2816 | { | ||
| 2817 | /* set/clear, then synch memory views with the device */ | ||
| 2818 | if (value) { | ||
| 2819 | ep->stopped = 1; | ||
| 2820 | if (ep->num == 0) | ||
| 2821 | ep->dev->protocol_stall = 1; | ||
| 2822 | else { | ||
| 2823 | if (ep->dma) | ||
| 2824 | ep_stop_dma(ep); | ||
| 2825 | ep_stall(ep, true); | ||
| 2826 | } | ||
| 2827 | |||
| 2828 | if (wedged) | ||
| 2829 | ep->wedged = 1; | ||
| 2830 | } else { | ||
| 2831 | ep->stopped = 0; | ||
| 2832 | ep->wedged = 0; | ||
| 2833 | |||
| 2834 | ep_stall(ep, false); | ||
| 2835 | |||
| 2836 | /* Flush the queue */ | ||
| 2837 | if (!list_empty(&ep->queue)) { | ||
| 2838 | struct net2280_request *req = | ||
| 2839 | list_entry(ep->queue.next, struct net2280_request, | ||
| 2840 | queue); | ||
| 2841 | if (ep->dma) | ||
| 2842 | resume_dma(ep); | ||
| 2843 | else { | ||
| 2844 | if (ep->is_in) | ||
| 2845 | write_fifo(ep, &req->req); | ||
| 2846 | else { | ||
| 2847 | if (read_fifo(ep, req)) | ||
| 2848 | done(ep, req, 0); | ||
| 2849 | } | ||
| 2850 | } | ||
| 2851 | } | ||
| 2852 | } | ||
| 2853 | } | ||
| 2854 | |||
| 2855 | static void handle_stat0_irqs_superspeed(struct net2280 *dev, | ||
| 2856 | struct net2280_ep *ep, struct usb_ctrlrequest r) | ||
| 2857 | { | ||
| 2858 | int tmp = 0; | ||
| 2859 | |||
| 2860 | #define w_value le16_to_cpu(r.wValue) | ||
| 2861 | #define w_index le16_to_cpu(r.wIndex) | ||
| 2862 | #define w_length le16_to_cpu(r.wLength) | ||
| 2863 | |||
| 2864 | switch (r.bRequest) { | ||
| 2865 | struct net2280_ep *e; | ||
| 2866 | u16 status; | ||
| 2867 | |||
| 2868 | case USB_REQ_SET_CONFIGURATION: | ||
| 2869 | dev->addressed_state = !w_value; | ||
| 2870 | goto usb3_delegate; | ||
| 2871 | |||
| 2872 | case USB_REQ_GET_STATUS: | ||
| 2873 | switch (r.bRequestType) { | ||
| 2874 | case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE): | ||
| 2875 | status = dev->wakeup_enable ? 0x02 : 0x00; | ||
| 2876 | if (dev->selfpowered) | ||
| 2877 | status |= BIT(0); | ||
| 2878 | status |= (dev->u1_enable << 2 | dev->u2_enable << 3 | | ||
| 2879 | dev->ltm_enable << 4); | ||
| 2880 | writel(0, &dev->epregs[0].ep_irqenb); | ||
| 2881 | set_fifo_bytecount(ep, sizeof(status)); | ||
| 2882 | writel((__force u32) status, &dev->epregs[0].ep_data); | ||
| 2883 | allow_status_338x(ep); | ||
| 2884 | break; | ||
| 2885 | |||
| 2886 | case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT): | ||
| 2887 | e = get_ep_by_addr(dev, w_index); | ||
| 2888 | if (!e) | ||
| 2889 | goto do_stall3; | ||
| 2890 | status = readl(&e->regs->ep_rsp) & | ||
| 2891 | BIT(CLEAR_ENDPOINT_HALT); | ||
| 2892 | writel(0, &dev->epregs[0].ep_irqenb); | ||
| 2893 | set_fifo_bytecount(ep, sizeof(status)); | ||
| 2894 | writel((__force u32) status, &dev->epregs[0].ep_data); | ||
| 2895 | allow_status_338x(ep); | ||
| 2896 | break; | ||
| 2897 | |||
| 2898 | default: | ||
| 2899 | goto usb3_delegate; | ||
| 2900 | } | ||
| 2901 | break; | ||
| 2902 | |||
| 2903 | case USB_REQ_CLEAR_FEATURE: | ||
| 2904 | switch (r.bRequestType) { | ||
| 2905 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE): | ||
| 2906 | if (!dev->addressed_state) { | ||
| 2907 | switch (w_value) { | ||
| 2908 | case USB_DEVICE_U1_ENABLE: | ||
| 2909 | dev->u1_enable = 0; | ||
| 2910 | writel(readl(&dev->usb_ext->usbctl2) & | ||
| 2911 | ~BIT(U1_ENABLE), | ||
| 2912 | &dev->usb_ext->usbctl2); | ||
| 2913 | allow_status_338x(ep); | ||
| 2914 | goto next_endpoints3; | ||
| 2915 | |||
| 2916 | case USB_DEVICE_U2_ENABLE: | ||
| 2917 | dev->u2_enable = 0; | ||
| 2918 | writel(readl(&dev->usb_ext->usbctl2) & | ||
| 2919 | ~BIT(U2_ENABLE), | ||
| 2920 | &dev->usb_ext->usbctl2); | ||
| 2921 | allow_status_338x(ep); | ||
| 2922 | goto next_endpoints3; | ||
| 2923 | |||
| 2924 | case USB_DEVICE_LTM_ENABLE: | ||
| 2925 | dev->ltm_enable = 0; | ||
| 2926 | writel(readl(&dev->usb_ext->usbctl2) & | ||
| 2927 | ~BIT(LTM_ENABLE), | ||
| 2928 | &dev->usb_ext->usbctl2); | ||
| 2929 | allow_status_338x(ep); | ||
| 2930 | goto next_endpoints3; | ||
| 2931 | |||
| 2932 | default: | ||
| 2933 | break; | ||
| 2934 | } | ||
| 2935 | } | ||
| 2936 | if (w_value == USB_DEVICE_REMOTE_WAKEUP) { | ||
| 2937 | dev->wakeup_enable = 0; | ||
| 2938 | writel(readl(&dev->usb->usbctl) & | ||
| 2939 | ~BIT(DEVICE_REMOTE_WAKEUP_ENABLE), | ||
| 2940 | &dev->usb->usbctl); | ||
| 2941 | allow_status_338x(ep); | ||
| 2942 | break; | ||
| 2943 | } | ||
| 2944 | goto usb3_delegate; | ||
| 2945 | |||
| 2946 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT): | ||
| 2947 | e = get_ep_by_addr(dev, w_index); | ||
| 2948 | if (!e) | ||
| 2949 | goto do_stall3; | ||
| 2950 | if (w_value != USB_ENDPOINT_HALT) | ||
| 2951 | goto do_stall3; | ||
| 2952 | ep_vdbg(dev, "%s clear halt\n", e->ep.name); | ||
| 2953 | ep_stall(e, false); | ||
| 2954 | if (!list_empty(&e->queue) && e->td_dma) | ||
| 2955 | restart_dma(e); | ||
| 2956 | allow_status(ep); | ||
| 2957 | ep->stopped = 1; | ||
| 2958 | break; | ||
| 2959 | |||
| 2960 | default: | ||
| 2961 | goto usb3_delegate; | ||
| 2962 | } | ||
| 2963 | break; | ||
| 2964 | case USB_REQ_SET_FEATURE: | ||
| 2965 | switch (r.bRequestType) { | ||
| 2966 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE): | ||
| 2967 | if (!dev->addressed_state) { | ||
| 2968 | switch (w_value) { | ||
| 2969 | case USB_DEVICE_U1_ENABLE: | ||
| 2970 | dev->u1_enable = 1; | ||
| 2971 | writel(readl(&dev->usb_ext->usbctl2) | | ||
| 2972 | BIT(U1_ENABLE), | ||
| 2973 | &dev->usb_ext->usbctl2); | ||
| 2974 | allow_status_338x(ep); | ||
| 2975 | goto next_endpoints3; | ||
| 2976 | |||
| 2977 | case USB_DEVICE_U2_ENABLE: | ||
| 2978 | dev->u2_enable = 1; | ||
| 2979 | writel(readl(&dev->usb_ext->usbctl2) | | ||
| 2980 | BIT(U2_ENABLE), | ||
| 2981 | &dev->usb_ext->usbctl2); | ||
| 2982 | allow_status_338x(ep); | ||
| 2983 | goto next_endpoints3; | ||
| 2984 | |||
| 2985 | case USB_DEVICE_LTM_ENABLE: | ||
| 2986 | dev->ltm_enable = 1; | ||
| 2987 | writel(readl(&dev->usb_ext->usbctl2) | | ||
| 2988 | BIT(LTM_ENABLE), | ||
| 2989 | &dev->usb_ext->usbctl2); | ||
| 2990 | allow_status_338x(ep); | ||
| 2991 | goto next_endpoints3; | ||
| 2992 | default: | ||
| 2993 | break; | ||
| 2994 | } | ||
| 2995 | } | ||
| 2996 | |||
| 2997 | if (w_value == USB_DEVICE_REMOTE_WAKEUP) { | ||
| 2998 | dev->wakeup_enable = 1; | ||
| 2999 | writel(readl(&dev->usb->usbctl) | | ||
| 3000 | BIT(DEVICE_REMOTE_WAKEUP_ENABLE), | ||
| 3001 | &dev->usb->usbctl); | ||
| 3002 | allow_status_338x(ep); | ||
| 3003 | break; | ||
| 3004 | } | ||
| 3005 | goto usb3_delegate; | ||
| 3006 | |||
| 3007 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT): | ||
| 3008 | e = get_ep_by_addr(dev, w_index); | ||
| 3009 | if (!e || (w_value != USB_ENDPOINT_HALT)) | ||
| 3010 | goto do_stall3; | ||
| 3011 | ep_stdrsp(e, true, false); | ||
| 3012 | allow_status_338x(ep); | ||
| 3013 | break; | ||
| 3014 | |||
| 3015 | default: | ||
| 3016 | goto usb3_delegate; | ||
| 3017 | } | ||
| 3018 | |||
| 3019 | break; | ||
| 3020 | default: | ||
| 3021 | |||
| 3022 | usb3_delegate: | ||
| 3023 | ep_vdbg(dev, "setup %02x.%02x v%04x i%04x l%04x ep_cfg %08x\n", | ||
| 3024 | r.bRequestType, r.bRequest, | ||
| 3025 | w_value, w_index, w_length, | ||
| 3026 | readl(&ep->cfg->ep_cfg)); | ||
| 3027 | |||
| 3028 | ep->responded = 0; | ||
| 3029 | spin_unlock(&dev->lock); | ||
| 3030 | tmp = dev->driver->setup(&dev->gadget, &r); | ||
| 3031 | spin_lock(&dev->lock); | ||
| 3032 | } | ||
| 3033 | do_stall3: | ||
| 3034 | if (tmp < 0) { | ||
| 3035 | ep_vdbg(dev, "req %02x.%02x protocol STALL; stat %d\n", | ||
| 3036 | r.bRequestType, r.bRequest, tmp); | ||
| 3037 | dev->protocol_stall = 1; | ||
| 3038 | /* TD 9.9 Halt Endpoint test. TD 9.22 Set feature test */ | ||
| 3039 | ep_stall(ep, true); | ||
| 3040 | } | ||
| 3041 | |||
| 3042 | next_endpoints3: | ||
| 3043 | |||
| 3044 | #undef w_value | ||
| 3045 | #undef w_index | ||
| 3046 | #undef w_length | ||
| 3047 | |||
| 3048 | return; | ||
| 3049 | } | ||
| 3050 | |||
| 3051 | static void handle_stat0_irqs(struct net2280 *dev, u32 stat) | ||
| 3052 | { | ||
| 3053 | struct net2280_ep *ep; | ||
| 3054 | u32 num, scratch; | ||
| 3055 | |||
| 3056 | /* most of these don't need individual acks */ | ||
| 3057 | stat &= ~BIT(INTA_ASSERTED); | ||
| 3058 | if (!stat) | ||
| 3059 | return; | ||
| 3060 | /* ep_dbg(dev, "irqstat0 %04x\n", stat); */ | ||
| 3061 | |||
| 3062 | /* starting a control request? */ | ||
| 3063 | if (unlikely(stat & BIT(SETUP_PACKET_INTERRUPT))) { | ||
| 3064 | union { | ||
| 3065 | u32 raw[2]; | ||
| 3066 | struct usb_ctrlrequest r; | ||
| 3067 | } u; | ||
| 3068 | int tmp; | ||
| 3069 | struct net2280_request *req; | ||
| 3070 | |||
| 3071 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) { | ||
| 3072 | u32 val = readl(&dev->usb->usbstat); | ||
| 3073 | if (val & BIT(SUPER_SPEED)) { | ||
| 3074 | dev->gadget.speed = USB_SPEED_SUPER; | ||
| 3075 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, | ||
| 3076 | EP0_SS_MAX_PACKET_SIZE); | ||
| 3077 | } else if (val & BIT(HIGH_SPEED)) { | ||
| 3078 | dev->gadget.speed = USB_SPEED_HIGH; | ||
| 3079 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, | ||
| 3080 | EP0_HS_MAX_PACKET_SIZE); | ||
| 3081 | } else { | ||
| 3082 | dev->gadget.speed = USB_SPEED_FULL; | ||
| 3083 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, | ||
| 3084 | EP0_HS_MAX_PACKET_SIZE); | ||
| 3085 | } | ||
| 3086 | net2280_led_speed(dev, dev->gadget.speed); | ||
| 3087 | ep_dbg(dev, "%s\n", | ||
| 3088 | usb_speed_string(dev->gadget.speed)); | ||
| 3089 | } | ||
| 3090 | |||
| 3091 | ep = &dev->ep[0]; | ||
| 3092 | ep->irqs++; | ||
| 3093 | |||
| 3094 | /* make sure any leftover request state is cleared */ | ||
| 3095 | stat &= ~BIT(ENDPOINT_0_INTERRUPT); | ||
| 3096 | while (!list_empty(&ep->queue)) { | ||
| 3097 | req = list_entry(ep->queue.next, | ||
| 3098 | struct net2280_request, queue); | ||
| 3099 | done(ep, req, (req->req.actual == req->req.length) | ||
| 3100 | ? 0 : -EPROTO); | ||
| 3101 | } | ||
| 3102 | ep->stopped = 0; | ||
| 3103 | dev->protocol_stall = 0; | ||
| 3104 | if (dev->quirks & PLX_SUPERSPEED) | ||
| 3105 | ep->is_halt = 0; | ||
| 3106 | else{ | ||
| 3107 | if (ep->dev->quirks & PLX_2280) | ||
| 3108 | tmp = BIT(FIFO_OVERFLOW) | | ||
| 3109 | BIT(FIFO_UNDERFLOW); | ||
| 3110 | else | ||
| 3111 | tmp = 0; | ||
| 3112 | |||
| 3113 | writel(tmp | BIT(TIMEOUT) | | ||
| 3114 | BIT(USB_STALL_SENT) | | ||
| 3115 | BIT(USB_IN_NAK_SENT) | | ||
| 3116 | BIT(USB_IN_ACK_RCVD) | | ||
| 3117 | BIT(USB_OUT_PING_NAK_SENT) | | ||
| 3118 | BIT(USB_OUT_ACK_SENT) | | ||
| 3119 | BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) | | ||
| 3120 | BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) | | ||
| 3121 | BIT(DATA_PACKET_RECEIVED_INTERRUPT) | | ||
| 3122 | BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) | | ||
| 3123 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 3124 | BIT(DATA_IN_TOKEN_INTERRUPT), | ||
| 3125 | &ep->regs->ep_stat); | ||
| 3126 | } | ||
| 3127 | u.raw[0] = readl(&dev->usb->setup0123); | ||
| 3128 | u.raw[1] = readl(&dev->usb->setup4567); | ||
| 3129 | |||
| 3130 | cpu_to_le32s(&u.raw[0]); | ||
| 3131 | cpu_to_le32s(&u.raw[1]); | ||
| 3132 | |||
| 3133 | if (dev->quirks & PLX_SUPERSPEED) | ||
| 3134 | defect7374_workaround(dev, u.r); | ||
| 3135 | |||
| 3136 | tmp = 0; | ||
| 3137 | |||
| 3138 | #define w_value le16_to_cpu(u.r.wValue) | ||
| 3139 | #define w_index le16_to_cpu(u.r.wIndex) | ||
| 3140 | #define w_length le16_to_cpu(u.r.wLength) | ||
| 3141 | |||
| 3142 | /* ack the irq */ | ||
| 3143 | writel(BIT(SETUP_PACKET_INTERRUPT), &dev->regs->irqstat0); | ||
| 3144 | stat ^= BIT(SETUP_PACKET_INTERRUPT); | ||
| 3145 | |||
| 3146 | /* watch control traffic at the token level, and force | ||
| 3147 | * synchronization before letting the status stage happen. | ||
| 3148 | * FIXME ignore tokens we'll NAK, until driver responds. | ||
| 3149 | * that'll mean a lot less irqs for some drivers. | ||
| 3150 | */ | ||
| 3151 | ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0; | ||
| 3152 | if (ep->is_in) { | ||
| 3153 | scratch = BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) | | ||
| 3154 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 3155 | BIT(DATA_IN_TOKEN_INTERRUPT); | ||
| 3156 | stop_out_naking(ep); | ||
| 3157 | } else | ||
| 3158 | scratch = BIT(DATA_PACKET_RECEIVED_INTERRUPT) | | ||
| 3159 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 3160 | BIT(DATA_IN_TOKEN_INTERRUPT); | ||
| 3161 | writel(scratch, &dev->epregs[0].ep_irqenb); | ||
| 3162 | |||
| 3163 | /* we made the hardware handle most lowlevel requests; | ||
| 3164 | * everything else goes uplevel to the gadget code. | ||
| 3165 | */ | ||
| 3166 | ep->responded = 1; | ||
| 3167 | |||
| 3168 | if (dev->gadget.speed == USB_SPEED_SUPER) { | ||
| 3169 | handle_stat0_irqs_superspeed(dev, ep, u.r); | ||
| 3170 | goto next_endpoints; | ||
| 3171 | } | ||
| 3172 | |||
| 3173 | switch (u.r.bRequest) { | ||
| 3174 | case USB_REQ_GET_STATUS: { | ||
| 3175 | struct net2280_ep *e; | ||
| 3176 | __le32 status; | ||
| 3177 | |||
| 3178 | /* hw handles device and interface status */ | ||
| 3179 | if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT)) | ||
| 3180 | goto delegate; | ||
| 3181 | e = get_ep_by_addr(dev, w_index); | ||
| 3182 | if (!e || w_length > 2) | ||
| 3183 | goto do_stall; | ||
| 3184 | |||
| 3185 | if (readl(&e->regs->ep_rsp) & BIT(SET_ENDPOINT_HALT)) | ||
| 3186 | status = cpu_to_le32(1); | ||
| 3187 | else | ||
| 3188 | status = cpu_to_le32(0); | ||
| 3189 | |||
| 3190 | /* don't bother with a request object! */ | ||
| 3191 | writel(0, &dev->epregs[0].ep_irqenb); | ||
| 3192 | set_fifo_bytecount(ep, w_length); | ||
| 3193 | writel((__force u32)status, &dev->epregs[0].ep_data); | ||
| 3194 | allow_status(ep); | ||
| 3195 | ep_vdbg(dev, "%s stat %02x\n", ep->ep.name, status); | ||
| 3196 | goto next_endpoints; | ||
| 3197 | } | ||
| 3198 | break; | ||
| 3199 | case USB_REQ_CLEAR_FEATURE: { | ||
| 3200 | struct net2280_ep *e; | ||
| 3201 | |||
| 3202 | /* hw handles device features */ | ||
| 3203 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) | ||
| 3204 | goto delegate; | ||
| 3205 | if (w_value != USB_ENDPOINT_HALT || w_length != 0) | ||
| 3206 | goto do_stall; | ||
| 3207 | e = get_ep_by_addr(dev, w_index); | ||
| 3208 | if (!e) | ||
| 3209 | goto do_stall; | ||
| 3210 | if (e->wedged) { | ||
| 3211 | ep_vdbg(dev, "%s wedged, halt not cleared\n", | ||
| 3212 | ep->ep.name); | ||
| 3213 | } else { | ||
| 3214 | ep_vdbg(dev, "%s clear halt\n", e->ep.name); | ||
| 3215 | clear_halt(e); | ||
| 3216 | if ((ep->dev->quirks & PLX_SUPERSPEED) && | ||
| 3217 | !list_empty(&e->queue) && e->td_dma) | ||
| 3218 | restart_dma(e); | ||
| 3219 | } | ||
| 3220 | allow_status(ep); | ||
| 3221 | goto next_endpoints; | ||
| 3222 | } | ||
| 3223 | break; | ||
| 3224 | case USB_REQ_SET_FEATURE: { | ||
| 3225 | struct net2280_ep *e; | ||
| 3226 | |||
| 3227 | /* hw handles device features */ | ||
| 3228 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) | ||
| 3229 | goto delegate; | ||
| 3230 | if (w_value != USB_ENDPOINT_HALT || w_length != 0) | ||
| 3231 | goto do_stall; | ||
| 3232 | e = get_ep_by_addr(dev, w_index); | ||
| 3233 | if (!e) | ||
| 3234 | goto do_stall; | ||
| 3235 | if (e->ep.name == ep0name) | ||
| 3236 | goto do_stall; | ||
| 3237 | set_halt(e); | ||
| 3238 | if ((dev->quirks & PLX_SUPERSPEED) && e->dma) | ||
| 3239 | abort_dma(e); | ||
| 3240 | allow_status(ep); | ||
| 3241 | ep_vdbg(dev, "%s set halt\n", ep->ep.name); | ||
| 3242 | goto next_endpoints; | ||
| 3243 | } | ||
| 3244 | break; | ||
| 3245 | default: | ||
| 3246 | delegate: | ||
| 3247 | ep_vdbg(dev, "setup %02x.%02x v%04x i%04x l%04x " | ||
| 3248 | "ep_cfg %08x\n", | ||
| 3249 | u.r.bRequestType, u.r.bRequest, | ||
| 3250 | w_value, w_index, w_length, | ||
| 3251 | readl(&ep->cfg->ep_cfg)); | ||
| 3252 | ep->responded = 0; | ||
| 3253 | spin_unlock(&dev->lock); | ||
| 3254 | tmp = dev->driver->setup(&dev->gadget, &u.r); | ||
| 3255 | spin_lock(&dev->lock); | ||
| 3256 | } | ||
| 3257 | |||
| 3258 | /* stall ep0 on error */ | ||
| 3259 | if (tmp < 0) { | ||
| 3260 | do_stall: | ||
| 3261 | ep_vdbg(dev, "req %02x.%02x protocol STALL; stat %d\n", | ||
| 3262 | u.r.bRequestType, u.r.bRequest, tmp); | ||
| 3263 | dev->protocol_stall = 1; | ||
| 3264 | } | ||
| 3265 | |||
| 3266 | /* some in/out token irq should follow; maybe stall then. | ||
| 3267 | * driver must queue a request (even zlp) or halt ep0 | ||
| 3268 | * before the host times out. | ||
| 3269 | */ | ||
| 3270 | } | ||
| 3271 | |||
| 3272 | #undef w_value | ||
| 3273 | #undef w_index | ||
| 3274 | #undef w_length | ||
| 3275 | |||
| 3276 | next_endpoints: | ||
| 3277 | /* endpoint data irq ? */ | ||
| 3278 | scratch = stat & 0x7f; | ||
| 3279 | stat &= ~0x7f; | ||
| 3280 | for (num = 0; scratch; num++) { | ||
| 3281 | u32 t; | ||
| 3282 | |||
| 3283 | /* do this endpoint's FIFO and queue need tending? */ | ||
| 3284 | t = BIT(num); | ||
| 3285 | if ((scratch & t) == 0) | ||
| 3286 | continue; | ||
| 3287 | scratch ^= t; | ||
| 3288 | |||
| 3289 | ep = &dev->ep[num]; | ||
| 3290 | handle_ep_small(ep); | ||
| 3291 | } | ||
| 3292 | |||
| 3293 | if (stat) | ||
| 3294 | ep_dbg(dev, "unhandled irqstat0 %08x\n", stat); | ||
| 3295 | } | ||
| 3296 | |||
| 3297 | #define DMA_INTERRUPTS (BIT(DMA_D_INTERRUPT) | \ | ||
| 3298 | BIT(DMA_C_INTERRUPT) | \ | ||
| 3299 | BIT(DMA_B_INTERRUPT) | \ | ||
| 3300 | BIT(DMA_A_INTERRUPT)) | ||
| 3301 | #define PCI_ERROR_INTERRUPTS ( \ | ||
| 3302 | BIT(PCI_MASTER_ABORT_RECEIVED_INTERRUPT) | \ | ||
| 3303 | BIT(PCI_TARGET_ABORT_RECEIVED_INTERRUPT) | \ | ||
| 3304 | BIT(PCI_RETRY_ABORT_INTERRUPT)) | ||
| 3305 | |||
| 3306 | static void handle_stat1_irqs(struct net2280 *dev, u32 stat) | ||
| 3307 | { | ||
| 3308 | struct net2280_ep *ep; | ||
| 3309 | u32 tmp, num, mask, scratch; | ||
| 3310 | |||
| 3311 | /* after disconnect there's nothing else to do! */ | ||
| 3312 | tmp = BIT(VBUS_INTERRUPT) | BIT(ROOT_PORT_RESET_INTERRUPT); | ||
| 3313 | mask = BIT(SUPER_SPEED) | BIT(HIGH_SPEED) | BIT(FULL_SPEED); | ||
| 3314 | |||
| 3315 | /* VBUS disconnect is indicated by VBUS_PIN and VBUS_INTERRUPT set. | ||
| 3316 | * Root Port Reset is indicated by ROOT_PORT_RESET_INTERRUPT set and | ||
| 3317 | * both HIGH_SPEED and FULL_SPEED clear (as ROOT_PORT_RESET_INTERRUPT | ||
| 3318 | * only indicates a change in the reset state). | ||
| 3319 | */ | ||
| 3320 | if (stat & tmp) { | ||
| 3321 | writel(tmp, &dev->regs->irqstat1); | ||
| 3322 | if ((((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) && | ||
| 3323 | (readl(&dev->usb->usbstat) & mask)) || | ||
| 3324 | ((readl(&dev->usb->usbctl) & | ||
| 3325 | BIT(VBUS_PIN)) == 0)) && | ||
| 3326 | (dev->gadget.speed != USB_SPEED_UNKNOWN)) { | ||
| 3327 | ep_dbg(dev, "disconnect %s\n", | ||
| 3328 | dev->driver->driver.name); | ||
| 3329 | stop_activity(dev, dev->driver); | ||
| 3330 | ep0_start(dev); | ||
| 3331 | return; | ||
| 3332 | } | ||
| 3333 | stat &= ~tmp; | ||
| 3334 | |||
| 3335 | /* vBUS can bounce ... one of many reasons to ignore the | ||
| 3336 | * notion of hotplug events on bus connect/disconnect! | ||
| 3337 | */ | ||
| 3338 | if (!stat) | ||
| 3339 | return; | ||
| 3340 | } | ||
| 3341 | |||
| 3342 | /* NOTE: chip stays in PCI D0 state for now, but it could | ||
| 3343 | * enter D1 to save more power | ||
| 3344 | */ | ||
| 3345 | tmp = BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT); | ||
| 3346 | if (stat & tmp) { | ||
| 3347 | writel(tmp, &dev->regs->irqstat1); | ||
| 3348 | if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) { | ||
| 3349 | if (dev->driver->suspend) | ||
| 3350 | dev->driver->suspend(&dev->gadget); | ||
| 3351 | if (!enable_suspend) | ||
| 3352 | stat &= ~BIT(SUSPEND_REQUEST_INTERRUPT); | ||
| 3353 | } else { | ||
| 3354 | if (dev->driver->resume) | ||
| 3355 | dev->driver->resume(&dev->gadget); | ||
| 3356 | /* at high speed, note erratum 0133 */ | ||
| 3357 | } | ||
| 3358 | stat &= ~tmp; | ||
| 3359 | } | ||
| 3360 | |||
| 3361 | /* clear any other status/irqs */ | ||
| 3362 | if (stat) | ||
| 3363 | writel(stat, &dev->regs->irqstat1); | ||
| 3364 | |||
| 3365 | /* some status we can just ignore */ | ||
| 3366 | if (dev->quirks & PLX_2280) | ||
| 3367 | stat &= ~(BIT(CONTROL_STATUS_INTERRUPT) | | ||
| 3368 | BIT(SUSPEND_REQUEST_INTERRUPT) | | ||
| 3369 | BIT(RESUME_INTERRUPT) | | ||
| 3370 | BIT(SOF_INTERRUPT)); | ||
| 3371 | else | ||
| 3372 | stat &= ~(BIT(CONTROL_STATUS_INTERRUPT) | | ||
| 3373 | BIT(RESUME_INTERRUPT) | | ||
| 3374 | BIT(SOF_DOWN_INTERRUPT) | | ||
| 3375 | BIT(SOF_INTERRUPT)); | ||
| 3376 | |||
| 3377 | if (!stat) | ||
| 3378 | return; | ||
| 3379 | /* ep_dbg(dev, "irqstat1 %08x\n", stat);*/ | ||
| 3380 | |||
| 3381 | /* DMA status, for ep-{a,b,c,d} */ | ||
| 3382 | scratch = stat & DMA_INTERRUPTS; | ||
| 3383 | stat &= ~DMA_INTERRUPTS; | ||
| 3384 | scratch >>= 9; | ||
| 3385 | for (num = 0; scratch; num++) { | ||
| 3386 | struct net2280_dma_regs __iomem *dma; | ||
| 3387 | |||
| 3388 | tmp = BIT(num); | ||
| 3389 | if ((tmp & scratch) == 0) | ||
| 3390 | continue; | ||
| 3391 | scratch ^= tmp; | ||
| 3392 | |||
| 3393 | ep = &dev->ep[num + 1]; | ||
| 3394 | dma = ep->dma; | ||
| 3395 | |||
| 3396 | if (!dma) | ||
| 3397 | continue; | ||
| 3398 | |||
| 3399 | /* clear ep's dma status */ | ||
| 3400 | tmp = readl(&dma->dmastat); | ||
| 3401 | writel(tmp, &dma->dmastat); | ||
| 3402 | |||
| 3403 | /* dma sync*/ | ||
| 3404 | if (dev->quirks & PLX_SUPERSPEED) { | ||
| 3405 | u32 r_dmacount = readl(&dma->dmacount); | ||
| 3406 | if (!ep->is_in && (r_dmacount & 0x00FFFFFF) && | ||
| 3407 | (tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) | ||
| 3408 | continue; | ||
| 3409 | } | ||
| 3410 | |||
| 3411 | /* chaining should stop on abort, short OUT from fifo, | ||
| 3412 | * or (stat0 codepath) short OUT transfer. | ||
| 3413 | */ | ||
| 3414 | if (!use_dma_chaining) { | ||
| 3415 | if (!(tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) { | ||
| 3416 | ep_dbg(ep->dev, "%s no xact done? %08x\n", | ||
| 3417 | ep->ep.name, tmp); | ||
| 3418 | continue; | ||
| 3419 | } | ||
| 3420 | stop_dma(ep->dma); | ||
| 3421 | } | ||
| 3422 | |||
| 3423 | /* OUT transfers terminate when the data from the | ||
| 3424 | * host is in our memory. Process whatever's done. | ||
| 3425 | * On this path, we know transfer's last packet wasn't | ||
| 3426 | * less than req->length. NAK_OUT_PACKETS may be set, | ||
| 3427 | * or the FIFO may already be holding new packets. | ||
| 3428 | * | ||
| 3429 | * IN transfers can linger in the FIFO for a very | ||
| 3430 | * long time ... we ignore that for now, accounting | ||
| 3431 | * precisely (like PIO does) needs per-packet irqs | ||
| 3432 | */ | ||
| 3433 | scan_dma_completions(ep); | ||
| 3434 | |||
| 3435 | /* disable dma on inactive queues; else maybe restart */ | ||
| 3436 | if (list_empty(&ep->queue)) { | ||
| 3437 | if (use_dma_chaining) | ||
| 3438 | stop_dma(ep->dma); | ||
| 3439 | } else { | ||
| 3440 | tmp = readl(&dma->dmactl); | ||
| 3441 | if (!use_dma_chaining || (tmp & BIT(DMA_ENABLE)) == 0) | ||
| 3442 | restart_dma(ep); | ||
| 3443 | else if (ep->is_in && use_dma_chaining) { | ||
| 3444 | struct net2280_request *req; | ||
| 3445 | __le32 dmacount; | ||
| 3446 | |||
| 3447 | /* the descriptor at the head of the chain | ||
| 3448 | * may still have VALID_BIT clear; that's | ||
| 3449 | * used to trigger changing DMA_FIFO_VALIDATE | ||
| 3450 | * (affects automagic zlp writes). | ||
| 3451 | */ | ||
| 3452 | req = list_entry(ep->queue.next, | ||
| 3453 | struct net2280_request, queue); | ||
| 3454 | dmacount = req->td->dmacount; | ||
| 3455 | dmacount &= cpu_to_le32(BIT(VALID_BIT) | | ||
| 3456 | DMA_BYTE_COUNT_MASK); | ||
| 3457 | if (dmacount && (dmacount & valid_bit) == 0) | ||
| 3458 | restart_dma(ep); | ||
| 3459 | } | ||
| 3460 | } | ||
| 3461 | ep->irqs++; | ||
| 3462 | } | ||
| 3463 | |||
| 3464 | /* NOTE: there are other PCI errors we might usefully notice. | ||
| 3465 | * if they appear very often, here's where to try recovering. | ||
| 3466 | */ | ||
| 3467 | if (stat & PCI_ERROR_INTERRUPTS) { | ||
| 3468 | ep_err(dev, "pci dma error; stat %08x\n", stat); | ||
| 3469 | stat &= ~PCI_ERROR_INTERRUPTS; | ||
| 3470 | /* these are fatal errors, but "maybe" they won't | ||
| 3471 | * happen again ... | ||
| 3472 | */ | ||
| 3473 | stop_activity(dev, dev->driver); | ||
| 3474 | ep0_start(dev); | ||
| 3475 | stat = 0; | ||
| 3476 | } | ||
| 3477 | |||
| 3478 | if (stat) | ||
| 3479 | ep_dbg(dev, "unhandled irqstat1 %08x\n", stat); | ||
| 3480 | } | ||
| 3481 | |||
| 3482 | static irqreturn_t net2280_irq(int irq, void *_dev) | ||
| 3483 | { | ||
| 3484 | struct net2280 *dev = _dev; | ||
| 3485 | |||
| 3486 | /* shared interrupt, not ours */ | ||
| 3487 | if ((dev->quirks & PLX_LEGACY) && | ||
| 3488 | (!(readl(&dev->regs->irqstat0) & BIT(INTA_ASSERTED)))) | ||
| 3489 | return IRQ_NONE; | ||
| 3490 | |||
| 3491 | spin_lock(&dev->lock); | ||
| 3492 | |||
| 3493 | /* handle disconnect, dma, and more */ | ||
| 3494 | handle_stat1_irqs(dev, readl(&dev->regs->irqstat1)); | ||
| 3495 | |||
| 3496 | /* control requests and PIO */ | ||
| 3497 | handle_stat0_irqs(dev, readl(&dev->regs->irqstat0)); | ||
| 3498 | |||
| 3499 | if (dev->quirks & PLX_SUPERSPEED) { | ||
| 3500 | /* re-enable interrupt to trigger any possible new interrupt */ | ||
| 3501 | u32 pciirqenb1 = readl(&dev->regs->pciirqenb1); | ||
| 3502 | writel(pciirqenb1 & 0x7FFFFFFF, &dev->regs->pciirqenb1); | ||
| 3503 | writel(pciirqenb1, &dev->regs->pciirqenb1); | ||
| 3504 | } | ||
| 3505 | |||
| 3506 | spin_unlock(&dev->lock); | ||
| 3507 | |||
| 3508 | return IRQ_HANDLED; | ||
| 3509 | } | ||
| 3510 | |||
| 3511 | /*-------------------------------------------------------------------------*/ | ||
| 3512 | |||
| 3513 | static void gadget_release(struct device *_dev) | ||
| 3514 | { | ||
| 3515 | struct net2280 *dev = dev_get_drvdata(_dev); | ||
| 3516 | |||
| 3517 | kfree(dev); | ||
| 3518 | } | ||
| 3519 | |||
| 3520 | /* tear down the binding between this driver and the pci device */ | ||
| 3521 | |||
| 3522 | static void net2280_remove(struct pci_dev *pdev) | ||
| 3523 | { | ||
| 3524 | struct net2280 *dev = pci_get_drvdata(pdev); | ||
| 3525 | |||
| 3526 | usb_del_gadget_udc(&dev->gadget); | ||
| 3527 | |||
| 3528 | BUG_ON(dev->driver); | ||
| 3529 | |||
| 3530 | /* then clean up the resources we allocated during probe() */ | ||
| 3531 | net2280_led_shutdown(dev); | ||
| 3532 | if (dev->requests) { | ||
| 3533 | int i; | ||
| 3534 | for (i = 1; i < 5; i++) { | ||
| 3535 | if (!dev->ep[i].dummy) | ||
| 3536 | continue; | ||
| 3537 | pci_pool_free(dev->requests, dev->ep[i].dummy, | ||
| 3538 | dev->ep[i].td_dma); | ||
| 3539 | } | ||
| 3540 | pci_pool_destroy(dev->requests); | ||
| 3541 | } | ||
| 3542 | if (dev->got_irq) | ||
| 3543 | free_irq(pdev->irq, dev); | ||
| 3544 | if (use_msi && dev->quirks & PLX_SUPERSPEED) | ||
| 3545 | pci_disable_msi(pdev); | ||
| 3546 | if (dev->regs) | ||
| 3547 | iounmap(dev->regs); | ||
| 3548 | if (dev->region) | ||
| 3549 | release_mem_region(pci_resource_start(pdev, 0), | ||
| 3550 | pci_resource_len(pdev, 0)); | ||
| 3551 | if (dev->enabled) | ||
| 3552 | pci_disable_device(pdev); | ||
| 3553 | device_remove_file(&pdev->dev, &dev_attr_registers); | ||
| 3554 | |||
| 3555 | ep_info(dev, "unbind\n"); | ||
| 3556 | } | ||
| 3557 | |||
| 3558 | /* wrap this driver around the specified device, but | ||
| 3559 | * don't respond over USB until a gadget driver binds to us. | ||
| 3560 | */ | ||
| 3561 | |||
| 3562 | static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id) | ||
| 3563 | { | ||
| 3564 | struct net2280 *dev; | ||
| 3565 | unsigned long resource, len; | ||
| 3566 | void __iomem *base = NULL; | ||
| 3567 | int retval, i; | ||
| 3568 | |||
| 3569 | if (!use_dma) | ||
| 3570 | use_dma_chaining = 0; | ||
| 3571 | |||
| 3572 | /* alloc, and start init */ | ||
| 3573 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 3574 | if (dev == NULL) { | ||
| 3575 | retval = -ENOMEM; | ||
| 3576 | goto done; | ||
| 3577 | } | ||
| 3578 | |||
| 3579 | pci_set_drvdata(pdev, dev); | ||
| 3580 | spin_lock_init(&dev->lock); | ||
| 3581 | dev->quirks = id->driver_data; | ||
| 3582 | dev->pdev = pdev; | ||
| 3583 | dev->gadget.ops = &net2280_ops; | ||
| 3584 | dev->gadget.max_speed = (dev->quirks & PLX_SUPERSPEED) ? | ||
| 3585 | USB_SPEED_SUPER : USB_SPEED_HIGH; | ||
| 3586 | |||
| 3587 | /* the "gadget" abstracts/virtualizes the controller */ | ||
| 3588 | dev->gadget.name = driver_name; | ||
| 3589 | |||
| 3590 | /* now all the pci goodies ... */ | ||
| 3591 | if (pci_enable_device(pdev) < 0) { | ||
| 3592 | retval = -ENODEV; | ||
| 3593 | goto done; | ||
| 3594 | } | ||
| 3595 | dev->enabled = 1; | ||
| 3596 | |||
| 3597 | /* BAR 0 holds all the registers | ||
| 3598 | * BAR 1 is 8051 memory; unused here (note erratum 0103) | ||
| 3599 | * BAR 2 is fifo memory; unused here | ||
| 3600 | */ | ||
| 3601 | resource = pci_resource_start(pdev, 0); | ||
| 3602 | len = pci_resource_len(pdev, 0); | ||
| 3603 | if (!request_mem_region(resource, len, driver_name)) { | ||
| 3604 | ep_dbg(dev, "controller already in use\n"); | ||
| 3605 | retval = -EBUSY; | ||
| 3606 | goto done; | ||
| 3607 | } | ||
| 3608 | dev->region = 1; | ||
| 3609 | |||
| 3610 | /* FIXME provide firmware download interface to put | ||
| 3611 | * 8051 code into the chip, e.g. to turn on PCI PM. | ||
| 3612 | */ | ||
| 3613 | |||
| 3614 | base = ioremap_nocache(resource, len); | ||
| 3615 | if (base == NULL) { | ||
| 3616 | ep_dbg(dev, "can't map memory\n"); | ||
| 3617 | retval = -EFAULT; | ||
| 3618 | goto done; | ||
| 3619 | } | ||
| 3620 | dev->regs = (struct net2280_regs __iomem *) base; | ||
| 3621 | dev->usb = (struct net2280_usb_regs __iomem *) (base + 0x0080); | ||
| 3622 | dev->pci = (struct net2280_pci_regs __iomem *) (base + 0x0100); | ||
| 3623 | dev->dma = (struct net2280_dma_regs __iomem *) (base + 0x0180); | ||
| 3624 | dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200); | ||
| 3625 | dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300); | ||
| 3626 | |||
| 3627 | if (dev->quirks & PLX_SUPERSPEED) { | ||
| 3628 | u32 fsmvalue; | ||
| 3629 | u32 usbstat; | ||
| 3630 | dev->usb_ext = (struct usb338x_usb_ext_regs __iomem *) | ||
| 3631 | (base + 0x00b4); | ||
| 3632 | dev->fiforegs = (struct usb338x_fifo_regs __iomem *) | ||
| 3633 | (base + 0x0500); | ||
| 3634 | dev->llregs = (struct usb338x_ll_regs __iomem *) | ||
| 3635 | (base + 0x0700); | ||
| 3636 | dev->ll_lfps_regs = (struct usb338x_ll_lfps_regs __iomem *) | ||
| 3637 | (base + 0x0748); | ||
| 3638 | dev->ll_tsn_regs = (struct usb338x_ll_tsn_regs __iomem *) | ||
| 3639 | (base + 0x077c); | ||
| 3640 | dev->ll_chicken_reg = (struct usb338x_ll_chi_regs __iomem *) | ||
| 3641 | (base + 0x079c); | ||
| 3642 | dev->plregs = (struct usb338x_pl_regs __iomem *) | ||
| 3643 | (base + 0x0800); | ||
| 3644 | usbstat = readl(&dev->usb->usbstat); | ||
| 3645 | dev->enhanced_mode = !!(usbstat & BIT(11)); | ||
| 3646 | dev->n_ep = (dev->enhanced_mode) ? 9 : 5; | ||
| 3647 | /* put into initial config, link up all endpoints */ | ||
| 3648 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
| 3649 | (0xf << DEFECT7374_FSM_FIELD); | ||
| 3650 | /* See if firmware needs to set up for workaround: */ | ||
| 3651 | if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) | ||
| 3652 | writel(0, &dev->usb->usbctl); | ||
| 3653 | } else{ | ||
| 3654 | dev->enhanced_mode = 0; | ||
| 3655 | dev->n_ep = 7; | ||
| 3656 | /* put into initial config, link up all endpoints */ | ||
| 3657 | writel(0, &dev->usb->usbctl); | ||
| 3658 | } | ||
| 3659 | |||
| 3660 | usb_reset(dev); | ||
| 3661 | usb_reinit(dev); | ||
| 3662 | |||
| 3663 | /* irq setup after old hardware is cleaned up */ | ||
| 3664 | if (!pdev->irq) { | ||
| 3665 | ep_err(dev, "No IRQ. Check PCI setup!\n"); | ||
| 3666 | retval = -ENODEV; | ||
| 3667 | goto done; | ||
| 3668 | } | ||
| 3669 | |||
| 3670 | if (use_msi && (dev->quirks & PLX_SUPERSPEED)) | ||
| 3671 | if (pci_enable_msi(pdev)) | ||
| 3672 | ep_err(dev, "Failed to enable MSI mode\n"); | ||
| 3673 | |||
| 3674 | if (request_irq(pdev->irq, net2280_irq, IRQF_SHARED, | ||
| 3675 | driver_name, dev)) { | ||
| 3676 | ep_err(dev, "request interrupt %d failed\n", pdev->irq); | ||
| 3677 | retval = -EBUSY; | ||
| 3678 | goto done; | ||
| 3679 | } | ||
| 3680 | dev->got_irq = 1; | ||
| 3681 | |||
| 3682 | /* DMA setup */ | ||
| 3683 | /* NOTE: we know only the 32 LSBs of dma addresses may be nonzero */ | ||
| 3684 | dev->requests = pci_pool_create("requests", pdev, | ||
| 3685 | sizeof(struct net2280_dma), | ||
| 3686 | 0 /* no alignment requirements */, | ||
| 3687 | 0 /* or page-crossing issues */); | ||
| 3688 | if (!dev->requests) { | ||
| 3689 | ep_dbg(dev, "can't get request pool\n"); | ||
| 3690 | retval = -ENOMEM; | ||
| 3691 | goto done; | ||
| 3692 | } | ||
| 3693 | for (i = 1; i < 5; i++) { | ||
| 3694 | struct net2280_dma *td; | ||
| 3695 | |||
| 3696 | td = pci_pool_alloc(dev->requests, GFP_KERNEL, | ||
| 3697 | &dev->ep[i].td_dma); | ||
| 3698 | if (!td) { | ||
| 3699 | ep_dbg(dev, "can't get dummy %d\n", i); | ||
| 3700 | retval = -ENOMEM; | ||
| 3701 | goto done; | ||
| 3702 | } | ||
| 3703 | td->dmacount = 0; /* not VALID */ | ||
| 3704 | td->dmadesc = td->dmaaddr; | ||
| 3705 | dev->ep[i].dummy = td; | ||
| 3706 | } | ||
| 3707 | |||
| 3708 | /* enable lower-overhead pci memory bursts during DMA */ | ||
| 3709 | if (dev->quirks & PLX_LEGACY) | ||
| 3710 | writel(BIT(DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) | | ||
| 3711 | /* | ||
| 3712 | * 256 write retries may not be enough... | ||
| 3713 | BIT(PCI_RETRY_ABORT_ENABLE) | | ||
| 3714 | */ | ||
| 3715 | BIT(DMA_READ_MULTIPLE_ENABLE) | | ||
| 3716 | BIT(DMA_READ_LINE_ENABLE), | ||
| 3717 | &dev->pci->pcimstctl); | ||
| 3718 | /* erratum 0115 shouldn't appear: Linux inits PCI_LATENCY_TIMER */ | ||
| 3719 | pci_set_master(pdev); | ||
| 3720 | pci_try_set_mwi(pdev); | ||
| 3721 | |||
| 3722 | /* ... also flushes any posted pci writes */ | ||
| 3723 | dev->chiprev = get_idx_reg(dev->regs, REG_CHIPREV) & 0xffff; | ||
| 3724 | |||
| 3725 | /* done */ | ||
| 3726 | ep_info(dev, "%s\n", driver_desc); | ||
| 3727 | ep_info(dev, "irq %d, pci mem %p, chip rev %04x\n", | ||
| 3728 | pdev->irq, base, dev->chiprev); | ||
| 3729 | ep_info(dev, "version: " DRIVER_VERSION "; dma %s %s\n", | ||
| 3730 | use_dma ? (use_dma_chaining ? "chaining" : "enabled") | ||
| 3731 | : "disabled", | ||
| 3732 | dev->enhanced_mode ? "enhanced mode" : "legacy mode"); | ||
| 3733 | retval = device_create_file(&pdev->dev, &dev_attr_registers); | ||
| 3734 | if (retval) | ||
| 3735 | goto done; | ||
| 3736 | |||
| 3737 | retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget, | ||
| 3738 | gadget_release); | ||
| 3739 | if (retval) | ||
| 3740 | goto done; | ||
| 3741 | return 0; | ||
| 3742 | |||
| 3743 | done: | ||
| 3744 | if (dev) | ||
| 3745 | net2280_remove(pdev); | ||
| 3746 | return retval; | ||
| 3747 | } | ||
| 3748 | |||
| 3749 | /* make sure the board is quiescent; otherwise it will continue | ||
| 3750 | * generating IRQs across the upcoming reboot. | ||
| 3751 | */ | ||
| 3752 | |||
| 3753 | static void net2280_shutdown(struct pci_dev *pdev) | ||
| 3754 | { | ||
| 3755 | struct net2280 *dev = pci_get_drvdata(pdev); | ||
| 3756 | |||
| 3757 | /* disable IRQs */ | ||
| 3758 | writel(0, &dev->regs->pciirqenb0); | ||
| 3759 | writel(0, &dev->regs->pciirqenb1); | ||
| 3760 | |||
| 3761 | /* disable the pullup so the host will think we're gone */ | ||
| 3762 | writel(0, &dev->usb->usbctl); | ||
| 3763 | |||
| 3764 | /* Disable full-speed test mode */ | ||
| 3765 | if (dev->quirks & PLX_LEGACY) | ||
| 3766 | writel(0, &dev->usb->xcvrdiag); | ||
| 3767 | } | ||
| 3768 | |||
| 3769 | |||
| 3770 | /*-------------------------------------------------------------------------*/ | ||
| 3771 | |||
| 3772 | static const struct pci_device_id pci_ids[] = { { | ||
| 3773 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 3774 | .class_mask = ~0, | ||
| 3775 | .vendor = PCI_VENDOR_ID_PLX_LEGACY, | ||
| 3776 | .device = 0x2280, | ||
| 3777 | .subvendor = PCI_ANY_ID, | ||
| 3778 | .subdevice = PCI_ANY_ID, | ||
| 3779 | .driver_data = PLX_LEGACY | PLX_2280, | ||
| 3780 | }, { | ||
| 3781 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 3782 | .class_mask = ~0, | ||
| 3783 | .vendor = PCI_VENDOR_ID_PLX_LEGACY, | ||
| 3784 | .device = 0x2282, | ||
| 3785 | .subvendor = PCI_ANY_ID, | ||
| 3786 | .subdevice = PCI_ANY_ID, | ||
| 3787 | .driver_data = PLX_LEGACY, | ||
| 3788 | }, | ||
| 3789 | { | ||
| 3790 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 3791 | .class_mask = ~0, | ||
| 3792 | .vendor = PCI_VENDOR_ID_PLX, | ||
| 3793 | .device = 0x3380, | ||
| 3794 | .subvendor = PCI_ANY_ID, | ||
| 3795 | .subdevice = PCI_ANY_ID, | ||
| 3796 | .driver_data = PLX_SUPERSPEED, | ||
| 3797 | }, | ||
| 3798 | { | ||
| 3799 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 3800 | .class_mask = ~0, | ||
| 3801 | .vendor = PCI_VENDOR_ID_PLX, | ||
| 3802 | .device = 0x3382, | ||
| 3803 | .subvendor = PCI_ANY_ID, | ||
| 3804 | .subdevice = PCI_ANY_ID, | ||
| 3805 | .driver_data = PLX_SUPERSPEED, | ||
| 3806 | }, | ||
| 3807 | { /* end: all zeroes */ } | ||
| 3808 | }; | ||
| 3809 | MODULE_DEVICE_TABLE(pci, pci_ids); | ||
| 3810 | |||
| 3811 | /* pci driver glue; this is a "new style" PCI driver module */ | ||
| 3812 | static struct pci_driver net2280_pci_driver = { | ||
| 3813 | .name = (char *) driver_name, | ||
| 3814 | .id_table = pci_ids, | ||
| 3815 | |||
| 3816 | .probe = net2280_probe, | ||
| 3817 | .remove = net2280_remove, | ||
| 3818 | .shutdown = net2280_shutdown, | ||
| 3819 | |||
| 3820 | /* FIXME add power management support */ | ||
| 3821 | }; | ||
| 3822 | |||
| 3823 | module_pci_driver(net2280_pci_driver); | ||
| 3824 | |||
| 3825 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 3826 | MODULE_AUTHOR("David Brownell"); | ||
| 3827 | MODULE_LICENSE("GPL"); | ||
| @@ -0,0 +1,403 @@ | |||
| 1 | /* | ||
| 2 | * NetChip 2280 high/full speed USB device controller. | ||
| 3 | * Unlike many such controllers, this one talks PCI. | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* | ||
| 7 | * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) | ||
| 8 | * Copyright (C) 2003 David Brownell | ||
| 9 | * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/usb/net2280.h> | ||
| 18 | #include <linux/usb/usb338x.h> | ||
| 19 | |||
| 20 | /*-------------------------------------------------------------------------*/ | ||
| 21 | |||
| 22 | #ifdef __KERNEL__ | ||
| 23 | |||
| 24 | /* indexed registers [11.10] are accessed indirectly | ||
| 25 | * caller must own the device lock. | ||
| 26 | */ | ||
| 27 | |||
| 28 | static inline u32 get_idx_reg(struct net2280_regs __iomem *regs, u32 index) | ||
| 29 | { | ||
| 30 | writel(index, ®s->idxaddr); | ||
| 31 | /* NOTE: synchs device/cpu memory views */ | ||
| 32 | return readl(®s->idxdata); | ||
| 33 | } | ||
| 34 | |||
| 35 | static inline void | ||
| 36 | set_idx_reg(struct net2280_regs __iomem *regs, u32 index, u32 value) | ||
| 37 | { | ||
| 38 | writel(index, ®s->idxaddr); | ||
| 39 | writel(value, ®s->idxdata); | ||
| 40 | /* posted, may not be visible yet */ | ||
| 41 | } | ||
| 42 | |||
| 43 | #endif /* __KERNEL__ */ | ||
| 44 | |||
| 45 | #define PCI_VENDOR_ID_PLX_LEGACY 0x17cc | ||
| 46 | |||
| 47 | #define PLX_LEGACY BIT(0) | ||
| 48 | #define PLX_2280 BIT(1) | ||
| 49 | #define PLX_SUPERSPEED BIT(2) | ||
| 50 | |||
| 51 | #define REG_DIAG 0x0 | ||
| 52 | #define RETRY_COUNTER 16 | ||
| 53 | #define FORCE_PCI_SERR 11 | ||
| 54 | #define FORCE_PCI_INTERRUPT 10 | ||
| 55 | #define FORCE_USB_INTERRUPT 9 | ||
| 56 | #define FORCE_CPU_INTERRUPT 8 | ||
| 57 | #define ILLEGAL_BYTE_ENABLES 5 | ||
| 58 | #define FAST_TIMES 4 | ||
| 59 | #define FORCE_RECEIVE_ERROR 2 | ||
| 60 | #define FORCE_TRANSMIT_CRC_ERROR 0 | ||
| 61 | #define REG_FRAME 0x02 /* from last sof */ | ||
| 62 | #define REG_CHIPREV 0x03 /* in bcd */ | ||
| 63 | #define REG_HS_NAK_RATE 0x0a /* NAK per N uframes */ | ||
| 64 | |||
| 65 | #define CHIPREV_1 0x0100 | ||
| 66 | #define CHIPREV_1A 0x0110 | ||
| 67 | |||
| 68 | /* DEFECT 7374 */ | ||
| 69 | #define DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS 200 | ||
| 70 | #define DEFECT_7374_PROCESSOR_WAIT_TIME 10 | ||
| 71 | |||
| 72 | /* ep0 max packet size */ | ||
| 73 | #define EP0_SS_MAX_PACKET_SIZE 0x200 | ||
| 74 | #define EP0_HS_MAX_PACKET_SIZE 0x40 | ||
| 75 | #ifdef __KERNEL__ | ||
| 76 | |||
| 77 | /*-------------------------------------------------------------------------*/ | ||
| 78 | |||
| 79 | /* [8.3] for scatter/gather i/o | ||
| 80 | * use struct net2280_dma_regs bitfields | ||
| 81 | */ | ||
| 82 | struct net2280_dma { | ||
| 83 | __le32 dmacount; | ||
| 84 | __le32 dmaaddr; /* the buffer */ | ||
| 85 | __le32 dmadesc; /* next dma descriptor */ | ||
| 86 | __le32 _reserved; | ||
| 87 | } __aligned(16); | ||
| 88 | |||
| 89 | /*-------------------------------------------------------------------------*/ | ||
| 90 | |||
| 91 | /* DRIVER DATA STRUCTURES and UTILITIES */ | ||
| 92 | |||
| 93 | struct net2280_ep { | ||
| 94 | struct usb_ep ep; | ||
| 95 | struct net2280_ep_regs __iomem *cfg; | ||
| 96 | struct net2280_ep_regs __iomem *regs; | ||
| 97 | struct net2280_dma_regs __iomem *dma; | ||
| 98 | struct net2280_dma *dummy; | ||
| 99 | struct usb338x_fifo_regs __iomem *fiforegs; | ||
| 100 | dma_addr_t td_dma; /* of dummy */ | ||
| 101 | struct net2280 *dev; | ||
| 102 | unsigned long irqs; | ||
| 103 | unsigned is_halt:1, dma_started:1; | ||
| 104 | |||
| 105 | /* analogous to a host-side qh */ | ||
| 106 | struct list_head queue; | ||
| 107 | const struct usb_endpoint_descriptor *desc; | ||
| 108 | unsigned num : 8, | ||
| 109 | fifo_size : 12, | ||
| 110 | in_fifo_validate : 1, | ||
| 111 | out_overflow : 1, | ||
| 112 | stopped : 1, | ||
| 113 | wedged : 1, | ||
| 114 | is_in : 1, | ||
| 115 | is_iso : 1, | ||
| 116 | responded : 1; | ||
| 117 | }; | ||
| 118 | |||
| 119 | static inline void allow_status(struct net2280_ep *ep) | ||
| 120 | { | ||
| 121 | /* ep0 only */ | ||
| 122 | writel(BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) | | ||
| 123 | BIT(CLEAR_NAK_OUT_PACKETS) | | ||
| 124 | BIT(CLEAR_NAK_OUT_PACKETS_MODE), | ||
| 125 | &ep->regs->ep_rsp); | ||
| 126 | ep->stopped = 1; | ||
| 127 | } | ||
| 128 | |||
| 129 | static void allow_status_338x(struct net2280_ep *ep) | ||
| 130 | { | ||
| 131 | /* | ||
| 132 | * Control Status Phase Handshake was set by the chip when the setup | ||
| 133 | * packet arrived. While set, the chip automatically NAKs the host's | ||
| 134 | * Status Phase tokens. | ||
| 135 | */ | ||
| 136 | writel(BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE), &ep->regs->ep_rsp); | ||
| 137 | |||
| 138 | ep->stopped = 1; | ||
| 139 | |||
| 140 | /* TD 9.9 Halt Endpoint test. TD 9.22 set feature test. */ | ||
| 141 | ep->responded = 0; | ||
| 142 | } | ||
| 143 | |||
| 144 | struct net2280_request { | ||
| 145 | struct usb_request req; | ||
| 146 | struct net2280_dma *td; | ||
| 147 | dma_addr_t td_dma; | ||
| 148 | struct list_head queue; | ||
| 149 | unsigned mapped : 1, | ||
| 150 | valid : 1; | ||
| 151 | }; | ||
| 152 | |||
| 153 | struct net2280 { | ||
| 154 | /* each pci device provides one gadget, several endpoints */ | ||
| 155 | struct usb_gadget gadget; | ||
| 156 | spinlock_t lock; | ||
| 157 | struct net2280_ep ep[9]; | ||
| 158 | struct usb_gadget_driver *driver; | ||
| 159 | unsigned enabled : 1, | ||
| 160 | protocol_stall : 1, | ||
| 161 | softconnect : 1, | ||
| 162 | got_irq : 1, | ||
| 163 | region:1, | ||
| 164 | u1_enable:1, | ||
| 165 | u2_enable:1, | ||
| 166 | ltm_enable:1, | ||
| 167 | wakeup_enable:1, | ||
| 168 | selfpowered:1, | ||
| 169 | addressed_state:1; | ||
| 170 | u16 chiprev; | ||
| 171 | int enhanced_mode; | ||
| 172 | int n_ep; | ||
| 173 | kernel_ulong_t quirks; | ||
| 174 | |||
| 175 | |||
| 176 | /* pci state used to access those endpoints */ | ||
| 177 | struct pci_dev *pdev; | ||
| 178 | struct net2280_regs __iomem *regs; | ||
| 179 | struct net2280_usb_regs __iomem *usb; | ||
| 180 | struct usb338x_usb_ext_regs __iomem *usb_ext; | ||
| 181 | struct net2280_pci_regs __iomem *pci; | ||
| 182 | struct net2280_dma_regs __iomem *dma; | ||
| 183 | struct net2280_dep_regs __iomem *dep; | ||
| 184 | struct net2280_ep_regs __iomem *epregs; | ||
| 185 | struct usb338x_fifo_regs __iomem *fiforegs; | ||
| 186 | struct usb338x_ll_regs __iomem *llregs; | ||
| 187 | struct usb338x_ll_lfps_regs __iomem *ll_lfps_regs; | ||
| 188 | struct usb338x_ll_tsn_regs __iomem *ll_tsn_regs; | ||
| 189 | struct usb338x_ll_chi_regs __iomem *ll_chicken_reg; | ||
| 190 | struct usb338x_pl_regs __iomem *plregs; | ||
| 191 | |||
| 192 | struct pci_pool *requests; | ||
| 193 | /* statistics...*/ | ||
| 194 | }; | ||
| 195 | |||
| 196 | static inline void set_halt(struct net2280_ep *ep) | ||
| 197 | { | ||
| 198 | /* ep0 and bulk/intr endpoints */ | ||
| 199 | writel(BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) | | ||
| 200 | /* set NAK_OUT for erratum 0114 */ | ||
| 201 | ((ep->dev->chiprev == CHIPREV_1) << SET_NAK_OUT_PACKETS) | | ||
| 202 | BIT(SET_ENDPOINT_HALT), | ||
| 203 | &ep->regs->ep_rsp); | ||
| 204 | } | ||
| 205 | |||
| 206 | static inline void clear_halt(struct net2280_ep *ep) | ||
| 207 | { | ||
| 208 | /* ep0 and bulk/intr endpoints */ | ||
| 209 | writel(BIT(CLEAR_ENDPOINT_HALT) | | ||
| 210 | BIT(CLEAR_ENDPOINT_TOGGLE) | | ||
| 211 | /* | ||
| 212 | * unless the gadget driver left a short packet in the | ||
| 213 | * fifo, this reverses the erratum 0114 workaround. | ||
| 214 | */ | ||
| 215 | ((ep->dev->chiprev == CHIPREV_1) << CLEAR_NAK_OUT_PACKETS), | ||
| 216 | &ep->regs->ep_rsp); | ||
| 217 | } | ||
| 218 | |||
| 219 | /* | ||
| 220 | * FSM value for Defect 7374 (U1U2 Test) is managed in | ||
| 221 | * chip's SCRATCH register: | ||
| 222 | */ | ||
| 223 | #define DEFECT7374_FSM_FIELD 28 | ||
| 224 | |||
| 225 | /* Waiting for Control Read: | ||
| 226 | * - A transition to this state indicates a fresh USB connection, | ||
| 227 | * before the first Setup Packet. The connection speed is not | ||
| 228 | * known. Firmware is waiting for the first Control Read. | ||
| 229 | * - Starting state: This state can be thought of as the FSM's typical | ||
| 230 | * starting state. | ||
| 231 | * - Tip: Upon the first SS Control Read the FSM never | ||
| 232 | * returns to this state. | ||
| 233 | */ | ||
| 234 | #define DEFECT7374_FSM_WAITING_FOR_CONTROL_READ BIT(DEFECT7374_FSM_FIELD) | ||
| 235 | |||
| 236 | /* Non-SS Control Read: | ||
| 237 | * - A transition to this state indicates detection of the first HS | ||
| 238 | * or FS Control Read. | ||
| 239 | * - Tip: Upon the first SS Control Read the FSM never | ||
| 240 | * returns to this state. | ||
| 241 | */ | ||
| 242 | #define DEFECT7374_FSM_NON_SS_CONTROL_READ (2 << DEFECT7374_FSM_FIELD) | ||
| 243 | |||
| 244 | /* SS Control Read: | ||
| 245 | * - A transition to this state indicates detection of the | ||
| 246 | * first SS Control Read. | ||
| 247 | * - This state indicates workaround completion. Workarounds no longer | ||
| 248 | * need to be applied (as long as the chip remains powered up). | ||
| 249 | * - Tip: Once in this state the FSM state does not change (until | ||
| 250 | * the chip's power is lost and restored). | ||
| 251 | * - This can be thought of as the final state of the FSM; | ||
| 252 | * the FSM 'locks-up' in this state until the chip loses power. | ||
| 253 | */ | ||
| 254 | #define DEFECT7374_FSM_SS_CONTROL_READ (3 << DEFECT7374_FSM_FIELD) | ||
| 255 | |||
| 256 | #ifdef USE_RDK_LEDS | ||
| 257 | |||
| 258 | static inline void net2280_led_init(struct net2280 *dev) | ||
| 259 | { | ||
| 260 | /* LED3 (green) is on during USB activity. note erratum 0113. */ | ||
| 261 | writel(BIT(GPIO3_LED_SELECT) | | ||
| 262 | BIT(GPIO3_OUTPUT_ENABLE) | | ||
| 263 | BIT(GPIO2_OUTPUT_ENABLE) | | ||
| 264 | BIT(GPIO1_OUTPUT_ENABLE) | | ||
| 265 | BIT(GPIO0_OUTPUT_ENABLE), | ||
| 266 | &dev->regs->gpioctl); | ||
| 267 | } | ||
| 268 | |||
| 269 | /* indicate speed with bi-color LED 0/1 */ | ||
| 270 | static inline | ||
| 271 | void net2280_led_speed(struct net2280 *dev, enum usb_device_speed speed) | ||
| 272 | { | ||
| 273 | u32 val = readl(&dev->regs->gpioctl); | ||
| 274 | switch (speed) { | ||
| 275 | case USB_SPEED_SUPER: /* green + red */ | ||
| 276 | val |= BIT(GPIO0_DATA) | BIT(GPIO1_DATA); | ||
| 277 | break; | ||
| 278 | case USB_SPEED_HIGH: /* green */ | ||
| 279 | val &= ~BIT(GPIO0_DATA); | ||
| 280 | val |= BIT(GPIO1_DATA); | ||
| 281 | break; | ||
| 282 | case USB_SPEED_FULL: /* red */ | ||
| 283 | val &= ~BIT(GPIO1_DATA); | ||
| 284 | val |= BIT(GPIO0_DATA); | ||
| 285 | break; | ||
| 286 | default: /* (off/black) */ | ||
| 287 | val &= ~(BIT(GPIO1_DATA) | BIT(GPIO0_DATA)); | ||
| 288 | break; | ||
| 289 | } | ||
| 290 | writel(val, &dev->regs->gpioctl); | ||
| 291 | } | ||
| 292 | |||
| 293 | /* indicate power with LED 2 */ | ||
| 294 | static inline void net2280_led_active(struct net2280 *dev, int is_active) | ||
| 295 | { | ||
| 296 | u32 val = readl(&dev->regs->gpioctl); | ||
| 297 | |||
| 298 | /* FIXME this LED never seems to turn on.*/ | ||
| 299 | if (is_active) | ||
| 300 | val |= GPIO2_DATA; | ||
| 301 | else | ||
| 302 | val &= ~GPIO2_DATA; | ||
| 303 | writel(val, &dev->regs->gpioctl); | ||
| 304 | } | ||
| 305 | |||
| 306 | static inline void net2280_led_shutdown(struct net2280 *dev) | ||
| 307 | { | ||
| 308 | /* turn off all four GPIO*_DATA bits */ | ||
| 309 | writel(readl(&dev->regs->gpioctl) & ~0x0f, | ||
| 310 | &dev->regs->gpioctl); | ||
| 311 | } | ||
| 312 | |||
| 313 | #else | ||
| 314 | |||
| 315 | #define net2280_led_init(dev) do { } while (0) | ||
| 316 | #define net2280_led_speed(dev, speed) do { } while (0) | ||
| 317 | #define net2280_led_shutdown(dev) do { } while (0) | ||
| 318 | |||
| 319 | #endif | ||
| 320 | |||
| 321 | /*-------------------------------------------------------------------------*/ | ||
| 322 | |||
| 323 | #define ep_dbg(ndev, fmt, args...) \ | ||
| 324 | dev_dbg((&((ndev)->pdev->dev)), fmt, ##args) | ||
| 325 | |||
| 326 | #define ep_vdbg(ndev, fmt, args...) \ | ||
| 327 | dev_vdbg((&((ndev)->pdev->dev)), fmt, ##args) | ||
| 328 | |||
| 329 | #define ep_info(ndev, fmt, args...) \ | ||
| 330 | dev_info((&((ndev)->pdev->dev)), fmt, ##args) | ||
| 331 | |||
| 332 | #define ep_warn(ndev, fmt, args...) \ | ||
| 333 | dev_warn((&((ndev)->pdev->dev)), fmt, ##args) | ||
| 334 | |||
| 335 | #define ep_err(ndev, fmt, args...) \ | ||
| 336 | dev_err((&((ndev)->pdev->dev)), fmt, ##args) | ||
| 337 | |||
| 338 | /*-------------------------------------------------------------------------*/ | ||
| 339 | |||
| 340 | static inline void set_fifo_bytecount(struct net2280_ep *ep, unsigned count) | ||
| 341 | { | ||
| 342 | if (ep->dev->pdev->vendor == 0x17cc) | ||
| 343 | writeb(count, 2 + (u8 __iomem *) &ep->regs->ep_cfg); | ||
| 344 | else{ | ||
| 345 | u32 tmp = readl(&ep->cfg->ep_cfg) & | ||
| 346 | (~(0x07 << EP_FIFO_BYTE_COUNT)); | ||
| 347 | writel(tmp | (count << EP_FIFO_BYTE_COUNT), &ep->cfg->ep_cfg); | ||
| 348 | } | ||
| 349 | } | ||
| 350 | |||
| 351 | static inline void start_out_naking(struct net2280_ep *ep) | ||
| 352 | { | ||
| 353 | /* NOTE: hardware races lurk here, and PING protocol issues */ | ||
| 354 | writel(BIT(SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 355 | /* synch with device */ | ||
| 356 | readl(&ep->regs->ep_rsp); | ||
| 357 | } | ||
| 358 | |||
| 359 | #ifdef DEBUG | ||
| 360 | static inline void assert_out_naking(struct net2280_ep *ep, const char *where) | ||
| 361 | { | ||
| 362 | u32 tmp = readl(&ep->regs->ep_stat); | ||
| 363 | |||
| 364 | if ((tmp & BIT(NAK_OUT_PACKETS)) == 0) { | ||
| 365 | ep_dbg(ep->dev, "%s %s %08x !NAK\n", | ||
| 366 | ep->ep.name, where, tmp); | ||
| 367 | writel(BIT(SET_NAK_OUT_PACKETS), | ||
| 368 | &ep->regs->ep_rsp); | ||
| 369 | } | ||
| 370 | } | ||
| 371 | #define ASSERT_OUT_NAKING(ep) assert_out_naking(ep, __func__) | ||
| 372 | #else | ||
| 373 | #define ASSERT_OUT_NAKING(ep) do {} while (0) | ||
| 374 | #endif | ||
| 375 | |||
| 376 | static inline void stop_out_naking(struct net2280_ep *ep) | ||
| 377 | { | ||
| 378 | u32 tmp; | ||
| 379 | |||
| 380 | tmp = readl(&ep->regs->ep_stat); | ||
| 381 | if ((tmp & BIT(NAK_OUT_PACKETS)) != 0) | ||
| 382 | writel(BIT(CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 383 | } | ||
| 384 | |||
| 385 | |||
| 386 | static inline void set_max_speed(struct net2280_ep *ep, u32 max) | ||
| 387 | { | ||
| 388 | u32 reg; | ||
| 389 | static const u32 ep_enhanced[9] = { 0x10, 0x60, 0x30, 0x80, | ||
| 390 | 0x50, 0x20, 0x70, 0x40, 0x90 }; | ||
| 391 | |||
| 392 | if (ep->dev->enhanced_mode) | ||
| 393 | reg = ep_enhanced[ep->num]; | ||
| 394 | else{ | ||
| 395 | reg = (ep->num + 1) * 0x10; | ||
| 396 | if (ep->dev->gadget.speed != USB_SPEED_HIGH) | ||
| 397 | reg += 1; | ||
| 398 | } | ||
| 399 | |||
| 400 | set_idx_reg(ep->dev->regs, reg, max); | ||
| 401 | } | ||
| 402 | |||
| 403 | #endif /* __KERNEL__ */ | ||
| @@ -2079,10 +2079,7 @@ static int omap_udc_start(struct usb_gadget *g, · 2078 unmodified lines | |||
| 2079 | &udc->gadget); | 2079 | &udc->gadget); |
| 2080 | if (status < 0) { | 2080 | if (status < 0) { |
| 2081 | ERR("can't bind to transceiver\n"); | 2081 | ERR("can't bind to transceiver\n"); |
| 2082 | if (driver->unbind) { | 2082 | udc->driver = NULL; |
| 2083 | driver->unbind(&udc->gadget); | ||
| 2084 | udc->driver = NULL; | ||
| 2085 | } | ||
| 2086 | goto done; | 2083 | goto done; |
| 2087 | } | 2084 | } |
| 2088 | } else { | 2085 | } else { |
File renamed without changes.
File renamed without changes.
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | /* #define VERBOSE_DEBUG */ | 16 | /* #define VERBOSE_DEBUG */ |
| 17 | 17 | ||
| 18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
| 19 | #include <linux/gpio.h> | ||
| 19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 21 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
| @@ -40,7 +41,6 @@ · 18 unmodified lines | |||
| 40 | 41 | ||
| 41 | #include <asm/byteorder.h> | 42 | #include <asm/byteorder.h> |
| 42 | #include <asm/dma.h> | 43 | #include <asm/dma.h> |
| 43 | #include <asm/gpio.h> | ||
| 44 | #include <asm/mach-types.h> | 44 | #include <asm/mach-types.h> |
| 45 | #include <asm/unaligned.h> | 45 | #include <asm/unaligned.h> |
| 46 | 46 | ||
| @@ -2105,11 +2105,9 @@ static int pxa25x_udc_probe(struct platform_device *pdev) · 2058 unmodified lines | |||
| 2105 | if (irq < 0) | 2105 | if (irq < 0) |
| 2106 | return -ENODEV; | 2106 | return -ENODEV; |
| 2107 | 2107 | ||
| 2108 | dev->clk = clk_get(&pdev->dev, NULL); | 2108 | dev->clk = devm_clk_get(&pdev->dev, NULL); |
| 2109 | if (IS_ERR(dev->clk)) { | 2109 | if (IS_ERR(dev->clk)) |
| 2110 | retval = PTR_ERR(dev->clk); | 2110 | return PTR_ERR(dev->clk); |
| 2111 | goto err_clk; | ||
| 2112 | } | ||
| 2113 | 2111 | ||
| 2114 | pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, | 2112 | pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, |
| 2115 | dev->has_cfr ? "" : " (!cfr)", | 2113 | dev->has_cfr ? "" : " (!cfr)", |
| @@ -2120,15 +2118,16 @@ static int pxa25x_udc_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 2120 | dev->dev = &pdev->dev; | 2118 | dev->dev = &pdev->dev; |
| 2121 | dev->mach = dev_get_platdata(&pdev->dev); | 2119 | dev->mach = dev_get_platdata(&pdev->dev); |
| 2122 | 2120 | ||
| 2123 | dev->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); | 2121 | dev->transceiver = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); |
| 2124 | 2122 | ||
| 2125 | if (gpio_is_valid(dev->mach->gpio_pullup)) { | 2123 | if (gpio_is_valid(dev->mach->gpio_pullup)) { |
| 2126 | if ((retval = gpio_request(dev->mach->gpio_pullup, | 2124 | retval = devm_gpio_request(&pdev->dev, dev->mach->gpio_pullup, |
| 2127 | "pca25x_udc GPIO PULLUP"))) { | 2125 | "pca25x_udc GPIO PULLUP"); |
| 2126 | if (retval) { | ||
| 2128 | dev_dbg(&pdev->dev, | 2127 | dev_dbg(&pdev->dev, |
| 2129 | "can't get pullup gpio %d, err: %d\n", | 2128 | "can't get pullup gpio %d, err: %d\n", |
| 2130 | dev->mach->gpio_pullup, retval); | 2129 | dev->mach->gpio_pullup, retval); |
| 2131 | goto err_gpio_pullup; | 2130 | goto err; |
| 2132 | } | 2131 | } |
| 2133 | gpio_direction_output(dev->mach->gpio_pullup, 0); | 2132 | gpio_direction_output(dev->mach->gpio_pullup, 0); |
| 2134 | } | 2133 | } |
| @@ -2146,30 +2145,32 @@ static int pxa25x_udc_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 2146 | dev->vbus = 0; | 2145 | dev->vbus = 0; |
| 2147 | 2146 | ||
| 2148 | /* irq setup after old hardware state is cleaned up */ | 2147 | /* irq setup after old hardware state is cleaned up */ |
| 2149 | retval = request_irq(irq, pxa25x_udc_irq, | 2148 | retval = devm_request_irq(&pdev->dev, irq, pxa25x_udc_irq, 0, |
| 2150 | 0, driver_name, dev); | 2149 | driver_name, dev); |
| 2151 | if (retval != 0) { | 2150 | if (retval != 0) { |
| 2152 | pr_err("%s: can't get irq %d, err %d\n", | 2151 | pr_err("%s: can't get irq %d, err %d\n", |
| 2153 | driver_name, irq, retval); | 2152 | driver_name, irq, retval); |
| 2154 | goto err_irq1; | 2153 | goto err; |
| 2155 | } | 2154 | } |
| 2156 | dev->got_irq = 1; | 2155 | dev->got_irq = 1; |
| 2157 | 2156 | ||
| 2158 | #ifdef CONFIG_ARCH_LUBBOCK | 2157 | #ifdef CONFIG_ARCH_LUBBOCK |
| 2159 | if (machine_is_lubbock()) { | 2158 | if (machine_is_lubbock()) { |
| 2160 | retval = request_irq(LUBBOCK_USB_DISC_IRQ, lubbock_vbus_irq, | 2159 | retval = devm_request_irq(&pdev->dev, LUBBOCK_USB_DISC_IRQ, |
| 2161 | 0, driver_name, dev); | 2160 | lubbock_vbus_irq, 0, driver_name, |
| 2161 | dev); | ||
| 2162 | if (retval != 0) { | 2162 | if (retval != 0) { |
| 2163 | pr_err("%s: can't get irq %i, err %d\n", | 2163 | pr_err("%s: can't get irq %i, err %d\n", |
| 2164 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); | 2164 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); |
| 2165 | goto err_irq_lub; | 2165 | goto err; |
| 2166 | } | 2166 | } |
| 2167 | retval = request_irq(LUBBOCK_USB_IRQ, lubbock_vbus_irq, | 2167 | retval = devm_request_irq(&pdev->dev, LUBBOCK_USB_IRQ, |
| 2168 | 0, driver_name, dev); | 2168 | lubbock_vbus_irq, 0, driver_name, |
| 2169 | dev); | ||
| 2169 | if (retval != 0) { | 2170 | if (retval != 0) { |
| 2170 | pr_err("%s: can't get irq %i, err %d\n", | 2171 | pr_err("%s: can't get irq %i, err %d\n", |
| 2171 | driver_name, LUBBOCK_USB_IRQ, retval); | 2172 | driver_name, LUBBOCK_USB_IRQ, retval); |
| 2172 | goto lubbock_fail0; | 2173 | goto err; |
| 2173 | } | 2174 | } |
| 2174 | } else | 2175 | } else |
| 2175 | #endif | 2176 | #endif |
| @@ -2180,22 +2181,9 @@ static int pxa25x_udc_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 2180 | return retval; | 2181 | return retval; |
| 2181 | 2182 | ||
| 2182 | remove_debug_files(dev); | 2183 | remove_debug_files(dev); |
| 2183 | #ifdef CONFIG_ARCH_LUBBOCK | 2184 | err: |
| 2184 | lubbock_fail0: | 2185 | if (!IS_ERR_OR_NULL(dev->transceiver)) |
| 2185 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); | ||
| 2186 | err_irq_lub: | ||
| 2187 | free_irq(irq, dev); | ||
| 2188 | #endif | ||
| 2189 | err_irq1: | ||
| 2190 | if (gpio_is_valid(dev->mach->gpio_pullup)) | ||
| 2191 | gpio_free(dev->mach->gpio_pullup); | ||
| 2192 | err_gpio_pullup: | ||
| 2193 | if (!IS_ERR_OR_NULL(dev->transceiver)) { | ||
| 2194 | usb_put_phy(dev->transceiver); | ||
| 2195 | dev->transceiver = NULL; | 2186 | dev->transceiver = NULL; |
| 2196 | } | ||
| 2197 | clk_put(dev->clk); | ||
| 2198 | err_clk: | ||
| 2199 | return retval; | 2187 | return retval; |
| 2200 | } | 2188 | } |
| 2201 | 2189 | ||
| @@ -2217,25 +2205,8 @@ static int pxa25x_udc_remove(struct platform_device *pdev) · 15 unmodified lines | |||
| 2217 | 2205 | ||
| 2218 | remove_debug_files(dev); | 2206 | remove_debug_files(dev); |
| 2219 | 2207 | ||
| 2220 | if (dev->got_irq) { | 2208 | if (!IS_ERR_OR_NULL(dev->transceiver)) |
| 2221 | free_irq(platform_get_irq(pdev, 0), dev); | ||
| 2222 | dev->got_irq = 0; | ||
| 2223 | } | ||
| 2224 | #ifdef CONFIG_ARCH_LUBBOCK | ||
| 2225 | if (machine_is_lubbock()) { | ||
| 2226 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); | ||
| 2227 | free_irq(LUBBOCK_USB_IRQ, dev); | ||
| 2228 | } | ||
| 2229 | #endif | ||
| 2230 | if (gpio_is_valid(dev->mach->gpio_pullup)) | ||
| 2231 | gpio_free(dev->mach->gpio_pullup); | ||
| 2232 | |||
| 2233 | clk_put(dev->clk); | ||
| 2234 | |||
| 2235 | if (!IS_ERR_OR_NULL(dev->transceiver)) { | ||
| 2236 | usb_put_phy(dev->transceiver); | ||
| 2237 | dev->transceiver = NULL; | 2209 | dev->transceiver = NULL; |
| 2238 | } | ||
| 2239 | 2210 | ||
| 2240 | the_controller = NULL; | 2211 | the_controller = NULL; |
| 2241 | return 0; | 2212 | return 0; |
File renamed without changes.
| @@ -2446,6 +2446,9 @@ static int pxa_udc_probe(struct platform_device *pdev) · 2445 unmodified lines | |||
| 2446 | retval = PTR_ERR(udc->clk); | 2446 | retval = PTR_ERR(udc->clk); |
| 2447 | goto err_clk; | 2447 | goto err_clk; |
| 2448 | } | 2448 | } |
| 2449 | retval = clk_prepare(udc->clk); | ||
| 2450 | if (retval) | ||
| 2451 | goto err_clk_prepare; | ||
| 2449 | 2452 | ||
| 2450 | retval = -ENOMEM; | 2453 | retval = -ENOMEM; |
| 2451 | udc->regs = ioremap(regs->start, resource_size(regs)); | 2454 | udc->regs = ioremap(regs->start, resource_size(regs)); |
| @@ -2483,6 +2486,8 @@ err_add_udc: · 31 unmodified lines | |||
| 2483 | err_irq: | 2486 | err_irq: |
| 2484 | iounmap(udc->regs); | 2487 | iounmap(udc->regs); |
| 2485 | err_map: | 2488 | err_map: |
| 2489 | clk_unprepare(udc->clk); | ||
| 2490 | err_clk_prepare: | ||
| 2486 | clk_put(udc->clk); | 2491 | clk_put(udc->clk); |
| 2487 | udc->clk = NULL; | 2492 | udc->clk = NULL; |
| 2488 | err_clk: | 2493 | err_clk: |
| @@ -2509,6 +2514,7 @@ static int pxa_udc_remove(struct platform_device *_dev) · 20 unmodified lines | |||
| 2509 | 2514 | ||
| 2510 | udc->transceiver = NULL; | 2515 | udc->transceiver = NULL; |
| 2511 | the_controller = NULL; | 2516 | the_controller = NULL; |
| 2517 | clk_unprepare(udc->clk); | ||
| 2512 | clk_put(udc->clk); | 2518 | clk_put(udc->clk); |
| 2513 | iounmap(udc->regs); | 2519 | iounmap(udc->regs); |
| 2514 | 2520 | ||
File renamed without changes.
| @@ -1826,18 +1826,12 @@ static int __exit r8a66597_remove(struct platform_device *pdev) · 1825 unmodified lines | |||
| 1826 | 1826 | ||
| 1827 | usb_del_gadget_udc(&r8a66597->gadget); | 1827 | usb_del_gadget_udc(&r8a66597->gadget); |
| 1828 | del_timer_sync(&r8a66597->timer); | 1828 | del_timer_sync(&r8a66597->timer); |
| 1829 | iounmap(r8a66597->reg); | ||
| 1830 | if (r8a66597->pdata->sudmac) | ||
| 1831 | iounmap(r8a66597->sudmac_reg); | ||
| 1832 | free_irq(platform_get_irq(pdev, 0), r8a66597); | ||
| 1833 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); | 1829 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); |
| 1834 | 1830 | ||
| 1835 | if (r8a66597->pdata->on_chip) { | 1831 | if (r8a66597->pdata->on_chip) { |
| 1836 | clk_disable_unprepare(r8a66597->clk); | 1832 | clk_disable_unprepare(r8a66597->clk); |
| 1837 | clk_put(r8a66597->clk); | ||
| 1838 | } | 1833 | } |
| 1839 | 1834 | ||
| 1840 | kfree(r8a66597); | ||
| 1841 | return 0; | 1835 | return 0; |
| 1842 | } | 1836 | } |
| 1843 | 1837 | ||
| @@ -1845,28 +1839,24 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r) · 1 unmodified line | |||
| 1845 | { | 1839 | { |
| 1846 | } | 1840 | } |
| 1847 | 1841 | ||
| 1848 | static int __init r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597, | 1842 | static int r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597, |
| 1849 | struct platform_device *pdev) | 1843 | struct platform_device *pdev) |
| 1850 | { | 1844 | { |
| 1851 | struct resource *res; | 1845 | struct resource *res; |
| 1852 | 1846 | ||
| 1853 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sudmac"); | 1847 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sudmac"); |
| 1854 | if (!res) { | 1848 | r8a66597->sudmac_reg = devm_ioremap_resource(&pdev->dev, res); |
| 1855 | dev_err(&pdev->dev, "platform_get_resource error(sudmac).\n"); | 1849 | if (IS_ERR(r8a66597->sudmac_reg)) { |
| 1856 | return -ENODEV; | ||
| 1857 | } | ||
| 1858 | |||
| 1859 | r8a66597->sudmac_reg = ioremap(res->start, resource_size(res)); | ||
| 1860 | if (r8a66597->sudmac_reg == NULL) { | ||
| 1861 | dev_err(&pdev->dev, "ioremap error(sudmac).\n"); | 1850 | dev_err(&pdev->dev, "ioremap error(sudmac).\n"); |
| 1862 | return -ENOMEM; | 1851 | return PTR_ERR(r8a66597->sudmac_reg); |
| 1863 | } | 1852 | } |
| 1864 | 1853 | ||
| 1865 | return 0; | 1854 | return 0; |
| 1866 | } | 1855 | } |
| 1867 | 1856 | ||
| 1868 | static int __init r8a66597_probe(struct platform_device *pdev) | 1857 | static int r8a66597_probe(struct platform_device *pdev) |
| 1869 | { | 1858 | { |
| 1859 | struct device *dev = &pdev->dev; | ||
| 1870 | char clk_name[8]; | 1860 | char clk_name[8]; |
| 1871 | struct resource *res, *ires; | 1861 | struct resource *res, *ires; |
| 1872 | int irq; | 1862 | int irq; |
| @@ -1877,39 +1867,27 @@ static int __init r8a66597_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 1877 | unsigned long irq_trigger; | 1867 | unsigned long irq_trigger; |
| 1878 | 1868 | ||
| 1879 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1869 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1880 | if (!res) { | 1870 | reg = devm_ioremap_resource(&pdev->dev, res); |
| 1881 | ret = -ENODEV; | 1871 | if (!reg) |
| 1882 | dev_err(&pdev->dev, "platform_get_resource error.\n"); | 1872 | return -ENODEV; |
| 1883 | goto clean_up; | ||
| 1884 | } | ||
| 1885 | 1873 | ||
| 1886 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1874 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| 1887 | irq = ires->start; | 1875 | irq = ires->start; |
| 1888 | irq_trigger = ires->flags & IRQF_TRIGGER_MASK; | 1876 | irq_trigger = ires->flags & IRQF_TRIGGER_MASK; |
| 1889 | 1877 | ||
| 1890 | if (irq < 0) { | 1878 | if (irq < 0) { |
| 1891 | ret = -ENODEV; | 1879 | dev_err(dev, "platform_get_irq error.\n"); |
| 1892 | dev_err(&pdev->dev, "platform_get_irq error.\n"); | 1880 | return -ENODEV; |
| 1893 | goto clean_up; | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | reg = ioremap(res->start, resource_size(res)); | ||
| 1897 | if (reg == NULL) { | ||
| 1898 | ret = -ENOMEM; | ||
| 1899 | dev_err(&pdev->dev, "ioremap error.\n"); | ||
| 1900 | goto clean_up; | ||
| 1901 | } | 1881 | } |
| 1902 | 1882 | ||
| 1903 | /* initialize ucd */ | 1883 | /* initialize ucd */ |
| 1904 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); | 1884 | r8a66597 = devm_kzalloc(dev, sizeof(struct r8a66597), GFP_KERNEL); |
| 1905 | if (r8a66597 == NULL) { | 1885 | if (r8a66597 == NULL) |
| 1906 | ret = -ENOMEM; | 1886 | return -ENOMEM; |
| 1907 | goto clean_up; | ||
| 1908 | } | ||
| 1909 | 1887 | ||
| 1910 | spin_lock_init(&r8a66597->lock); | 1888 | spin_lock_init(&r8a66597->lock); |
| 1911 | platform_set_drvdata(pdev, r8a66597); | 1889 | platform_set_drvdata(pdev, r8a66597); |
| 1912 | r8a66597->pdata = dev_get_platdata(&pdev->dev); | 1890 | r8a66597->pdata = dev_get_platdata(dev); |
| 1913 | r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW; | 1891 | r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW; |
| 1914 | 1892 | ||
| 1915 | r8a66597->gadget.ops = &r8a66597_gadget_ops; | 1893 | r8a66597->gadget.ops = &r8a66597_gadget_ops; |
| @@ -1923,12 +1901,10 @@ static int __init r8a66597_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 1923 | 1901 | ||
| 1924 | if (r8a66597->pdata->on_chip) { | 1902 | if (r8a66597->pdata->on_chip) { |
| 1925 | snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id); | 1903 | snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id); |
| 1926 | r8a66597->clk = clk_get(&pdev->dev, clk_name); | 1904 | r8a66597->clk = devm_clk_get(dev, clk_name); |
| 1927 | if (IS_ERR(r8a66597->clk)) { | 1905 | if (IS_ERR(r8a66597->clk)) { |
| 1928 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", | 1906 | dev_err(dev, "cannot get clock \"%s\"\n", clk_name); |
| 1929 | clk_name); | 1907 | return PTR_ERR(r8a66597->clk); |
| 1930 | ret = PTR_ERR(r8a66597->clk); | ||
| 1931 | goto clean_up; | ||
| 1932 | } | 1908 | } |
| 1933 | clk_prepare_enable(r8a66597->clk); | 1909 | clk_prepare_enable(r8a66597->clk); |
| 1934 | } | 1910 | } |
| @@ -1941,10 +1917,10 @@ static int __init r8a66597_probe(struct platform_device *pdev) · 6 unmodified lines | |||
| 1941 | 1917 | ||
| 1942 | disable_controller(r8a66597); /* make sure controller is disabled */ | 1918 | disable_controller(r8a66597); /* make sure controller is disabled */ |
| 1943 | 1919 | ||
| 1944 | ret = request_irq(irq, r8a66597_irq, IRQF_SHARED, | 1920 | ret = devm_request_irq(dev, irq, r8a66597_irq, IRQF_SHARED, |
| 1945 | udc_name, r8a66597); | 1921 | udc_name, r8a66597); |
| 1946 | if (ret < 0) { | 1922 | if (ret < 0) { |
| 1947 | dev_err(&pdev->dev, "request_irq error (%d)\n", ret); | 1923 | dev_err(dev, "request_irq error (%d)\n", ret); |
| 1948 | goto clean_up2; | 1924 | goto clean_up2; |
| 1949 | } | 1925 | } |
| 1950 | 1926 | ||
| @@ -1978,37 +1954,25 @@ static int __init r8a66597_probe(struct platform_device *pdev) · 27 unmodified lines | |||
| 1978 | GFP_KERNEL); | 1954 | GFP_KERNEL); |
| 1979 | if (r8a66597->ep0_req == NULL) { | 1955 | if (r8a66597->ep0_req == NULL) { |
| 1980 | ret = -ENOMEM; | 1956 | ret = -ENOMEM; |
| 1981 | goto clean_up3; | 1957 | goto clean_up2; |
| 1982 | } | 1958 | } |
| 1983 | r8a66597->ep0_req->complete = nop_completion; | 1959 | r8a66597->ep0_req->complete = nop_completion; |
| 1984 | 1960 | ||
| 1985 | ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget); | 1961 | ret = usb_add_gadget_udc(dev, &r8a66597->gadget); |
| 1986 | if (ret) | 1962 | if (ret) |
| 1987 | goto err_add_udc; | 1963 | goto err_add_udc; |
| 1988 | 1964 | ||
| 1989 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); | 1965 | dev_info(dev, "version %s\n", DRIVER_VERSION); |
| 1990 | return 0; | 1966 | return 0; |
| 1991 | 1967 | ||
| 1992 | err_add_udc: | 1968 | err_add_udc: |
| 1993 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); | 1969 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); |
| 1994 | clean_up3: | ||
| 1995 | free_irq(irq, r8a66597); | ||
| 1996 | clean_up2: | 1970 | clean_up2: |
| 1997 | if (r8a66597->pdata->on_chip) { | 1971 | if (r8a66597->pdata->on_chip) |
| 1998 | clk_disable_unprepare(r8a66597->clk); | 1972 | clk_disable_unprepare(r8a66597->clk); |
| 1999 | clk_put(r8a66597->clk); | 1973 | |
| 2000 | } | 1974 | if (r8a66597->ep0_req) |
| 2001 | clean_up: | 1975 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); |
| 2002 | if (r8a66597) { | ||
| 2003 | if (r8a66597->sudmac_reg) | ||
| 2004 | iounmap(r8a66597->sudmac_reg); | ||
| 2005 | if (r8a66597->ep0_req) | ||
| 2006 | r8a66597_free_request(&r8a66597->ep[0].ep, | ||
| 2007 | r8a66597->ep0_req); | ||
| 2008 | kfree(r8a66597); | ||
| 2009 | } | ||
| 2010 | if (reg) | ||
| 2011 | iounmap(reg); | ||
| 2012 | 1976 | ||
| 2013 | return ret; | 1977 | return ret; |
| 2014 | } | 1978 | } |
File renamed without changes.
File renamed without changes.
| @@ -1788,7 +1788,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) · 1787 unmodified lines | |||
| 1788 | return PTR_ERR(usb_bus_clock); | 1788 | return PTR_ERR(usb_bus_clock); |
| 1789 | } | 1789 | } |
| 1790 | 1790 | ||
| 1791 | clk_enable(usb_bus_clock); | 1791 | clk_prepare_enable(usb_bus_clock); |
| 1792 | 1792 | ||
| 1793 | udc_clock = clk_get(NULL, "usb-device"); | 1793 | udc_clock = clk_get(NULL, "usb-device"); |
| 1794 | if (IS_ERR(udc_clock)) { | 1794 | if (IS_ERR(udc_clock)) { |
| @@ -1796,7 +1796,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 1796 | return PTR_ERR(udc_clock); | 1796 | return PTR_ERR(udc_clock); |
| 1797 | } | 1797 | } |
| 1798 | 1798 | ||
| 1799 | clk_enable(udc_clock); | 1799 | clk_prepare_enable(udc_clock); |
| 1800 | 1800 | ||
| 1801 | mdelay(10); | 1801 | mdelay(10); |
| 1802 | 1802 | ||
| @@ -1952,13 +1952,13 @@ static int s3c2410_udc_remove(struct platform_device *pdev) · 149 unmodified lines | |||
| 1952 | release_mem_region(rsrc_start, rsrc_len); | 1952 | release_mem_region(rsrc_start, rsrc_len); |
| 1953 | 1953 | ||
| 1954 | if (!IS_ERR(udc_clock) && udc_clock != NULL) { | 1954 | if (!IS_ERR(udc_clock) && udc_clock != NULL) { |
| 1955 | clk_disable(udc_clock); | 1955 | clk_disable_unprepare(udc_clock); |
| 1956 | clk_put(udc_clock); | 1956 | clk_put(udc_clock); |
| 1957 | udc_clock = NULL; | 1957 | udc_clock = NULL; |
| 1958 | } | 1958 | } |
| 1959 | 1959 | ||
| 1960 | if (!IS_ERR(usb_bus_clock) && usb_bus_clock != NULL) { | 1960 | if (!IS_ERR(usb_bus_clock) && usb_bus_clock != NULL) { |
| 1961 | clk_disable(usb_bus_clock); | 1961 | clk_disable_unprepare(usb_bus_clock); |
| 1962 | clk_put(usb_bus_clock); | 1962 | clk_put(usb_bus_clock); |
| 1963 | usb_bus_clock = NULL; | 1963 | usb_bus_clock = NULL; |
| 1964 | } | 1964 | } |
File renamed without changes.
File renamed without changes.
| @@ -455,7 +455,7 @@ static int bfin_probe(struct platform_device *pdev) · 454 unmodified lines | |||
| 455 | 455 | ||
| 456 | int ret = -ENOMEM; | 456 | int ret = -ENOMEM; |
| 457 | 457 | ||
| 458 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 458 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
| 459 | if (!glue) { | 459 | if (!glue) { |
| 460 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | 460 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
| 461 | goto err0; | 461 | goto err0; |
| @@ -464,7 +464,7 @@ static int bfin_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 464 | musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); | 464 | musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); |
| 465 | if (!musb) { | 465 | if (!musb) { |
| 466 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | 466 | dev_err(&pdev->dev, "failed to allocate musb device\n"); |
| 467 | goto err1; | 467 | goto err0; |
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | musb->dev.parent = &pdev->dev; | 470 | musb->dev.parent = &pdev->dev; |
| @@ -478,7 +478,7 @@ static int bfin_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 478 | 478 | ||
| 479 | glue->phy = usb_phy_generic_register(); | 479 | glue->phy = usb_phy_generic_register(); |
| 480 | if (IS_ERR(glue->phy)) | 480 | if (IS_ERR(glue->phy)) |
| 481 | goto err2; | 481 | goto err1; |
| 482 | platform_set_drvdata(pdev, glue); | 482 | platform_set_drvdata(pdev, glue); |
| 483 | 483 | ||
| 484 | memset(musb_resources, 0x00, sizeof(*musb_resources) * | 484 | memset(musb_resources, 0x00, sizeof(*musb_resources) * |
| @@ -498,31 +498,28 @@ static int bfin_probe(struct platform_device *pdev) · 13 unmodified lines | |||
| 498 | ARRAY_SIZE(musb_resources)); | 498 | ARRAY_SIZE(musb_resources)); |
| 499 | if (ret) { | 499 | if (ret) { |
| 500 | dev_err(&pdev->dev, "failed to add resources\n"); | 500 | dev_err(&pdev->dev, "failed to add resources\n"); |
| 501 | goto err3; | 501 | goto err2; |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | 504 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); |
| 505 | if (ret) { | 505 | if (ret) { |
| 506 | dev_err(&pdev->dev, "failed to add platform_data\n"); | 506 | dev_err(&pdev->dev, "failed to add platform_data\n"); |
| 507 | goto err3; | 507 | goto err2; |
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | ret = platform_device_add(musb); | 510 | ret = platform_device_add(musb); |
| 511 | if (ret) { | 511 | if (ret) { |
| 512 | dev_err(&pdev->dev, "failed to register musb device\n"); | 512 | dev_err(&pdev->dev, "failed to register musb device\n"); |
| 513 | goto err3; | 513 | goto err2; |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | return 0; | 516 | return 0; |
| 517 | 517 | ||
| 518 | err3: | ||
| 519 | usb_phy_generic_unregister(glue->phy); | ||
| 520 | |||
| 521 | err2: | 518 | err2: |
| 522 | platform_device_put(musb); | 519 | usb_phy_generic_unregister(glue->phy); |
| 523 | 520 | ||
| 524 | err1: | 521 | err1: |
| 525 | kfree(glue); | 522 | platform_device_put(musb); |
| 526 | 523 | ||
| 527 | err0: | 524 | err0: |
| 528 | return ret; | 525 | return ret; |
| @@ -534,7 +531,6 @@ static int bfin_remove(struct platform_device *pdev) · 5 unmodified lines | |||
| 534 | 531 | ||
| 535 | platform_device_unregister(glue->musb); | 532 | platform_device_unregister(glue->musb); |
| 536 | usb_phy_generic_unregister(glue->phy); | 533 | usb_phy_generic_unregister(glue->phy); |
| 537 | kfree(glue); | ||
| 538 | 534 | ||
| 539 | return 0; | 535 | return 0; |
| 540 | } | 536 | } |
| @@ -519,23 +519,23 @@ static int davinci_probe(struct platform_device *pdev) · 518 unmodified lines | |||
| 519 | 519 | ||
| 520 | int ret = -ENOMEM; | 520 | int ret = -ENOMEM; |
| 521 | 521 | ||
| 522 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 522 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
| 523 | if (!glue) { | 523 | if (!glue) { |
| 524 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | 524 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
| 525 | goto err0; | 525 | goto err0; |
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | clk = clk_get(&pdev->dev, "usb"); | 528 | clk = devm_clk_get(&pdev->dev, "usb"); |
| 529 | if (IS_ERR(clk)) { | 529 | if (IS_ERR(clk)) { |
| 530 | dev_err(&pdev->dev, "failed to get clock\n"); | 530 | dev_err(&pdev->dev, "failed to get clock\n"); |
| 531 | ret = PTR_ERR(clk); | 531 | ret = PTR_ERR(clk); |
| 532 | goto err3; | 532 | goto err0; |
| 533 | } | 533 | } |
| 534 | 534 | ||
| 535 | ret = clk_enable(clk); | 535 | ret = clk_enable(clk); |
| 536 | if (ret) { | 536 | if (ret) { |
| 537 | dev_err(&pdev->dev, "failed to enable clock\n"); | 537 | dev_err(&pdev->dev, "failed to enable clock\n"); |
| 538 | goto err4; | 538 | goto err0; |
| 539 | } | 539 | } |
| 540 | 540 | ||
| 541 | glue->dev = &pdev->dev; | 541 | glue->dev = &pdev->dev; |
| @@ -579,20 +579,14 @@ static int davinci_probe(struct platform_device *pdev) · 37 unmodified lines | |||
| 579 | if (IS_ERR(musb)) { | 579 | if (IS_ERR(musb)) { |
| 580 | ret = PTR_ERR(musb); | 580 | ret = PTR_ERR(musb); |
| 581 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); | 581 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); |
| 582 | goto err5; | 582 | goto err1; |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | return 0; | 585 | return 0; |
| 586 | 586 | ||
| 587 | err5: | 587 | err1: |
| 588 | clk_disable(clk); | 588 | clk_disable(clk); |
| 589 | 589 | ||
| 590 | err4: | ||
| 591 | clk_put(clk); | ||
| 592 | |||
| 593 | err3: | ||
| 594 | kfree(glue); | ||
| 595 | |||
| 596 | err0: | 590 | err0: |
| 597 | return ret; | 591 | return ret; |
| 598 | } | 592 | } |
| @@ -604,8 +598,6 @@ static int davinci_remove(struct platform_device *pdev) · 5 unmodified lines | |||
| 604 | platform_device_unregister(glue->musb); | 598 | platform_device_unregister(glue->musb); |
| 605 | usb_phy_generic_unregister(); | 599 | usb_phy_generic_unregister(); |
| 606 | clk_disable(glue->clk); | 600 | clk_disable(glue->clk); |
| 607 | clk_put(glue->clk); | ||
| 608 | kfree(glue); | ||
| 609 | 601 | ||
| 610 | return 0; | 602 | return 0; |
| 611 | } | 603 | } |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/usb/usb_phy_generic.h> | ||
| 22 | 23 | ||
| 23 | #include "musb_core.h" | 24 | #include "musb_core.h" |
| 24 | 25 | ||
| @@ -80,6 +81,7 @@ static struct musb_hdrc_platform_data jz4740_musb_platform_data = { · 55 unmodified lines | |||
| 80 | 81 | ||
| 81 | static int jz4740_musb_init(struct musb *musb) | 82 | static int jz4740_musb_init(struct musb *musb) |
| 82 | { | 83 | { |
| 84 | usb_phy_generic_register(); | ||
| 83 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 85 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
| 84 | if (!musb->xceiv) { | 86 | if (!musb->xceiv) { |
| 85 | pr_err("HS UDC: no transceiver configured\n"); | 87 | pr_err("HS UDC: no transceiver configured\n"); |
| @@ -182,6 +184,7 @@ static int jz4740_remove(struct platform_device *pdev) · 96 unmodified lines | |||
| 182 | struct jz4740_glue *glue = platform_get_drvdata(pdev); | 184 | struct jz4740_glue *glue = platform_get_drvdata(pdev); |
| 183 | 185 | ||
| 184 | platform_device_unregister(glue->musb); | 186 | platform_device_unregister(glue->musb); |
| 187 | usb_phy_generic_unregister(pdev); | ||
| 185 | clk_disable_unprepare(glue->clk); | 188 | clk_disable_unprepare(glue->clk); |
| 186 | 189 | ||
| 187 | return 0; | 190 | return 0; |
| @@ -850,7 +850,8 @@ b_host: · 849 unmodified lines | |||
| 850 | 850 | ||
| 851 | /* handle babble condition */ | 851 | /* handle babble condition */ |
| 852 | if (int_usb & MUSB_INTR_BABBLE && is_host_active(musb)) | 852 | if (int_usb & MUSB_INTR_BABBLE && is_host_active(musb)) |
| 853 | schedule_work(&musb->recover_work); | 853 | schedule_delayed_work(&musb->recover_work, |
| 854 | msecs_to_jiffies(100)); | ||
| 854 | 855 | ||
| 855 | #if 0 | 856 | #if 0 |
| 856 | /* REVISIT ... this would be for multiplexing periodic endpoints, or | 857 | /* REVISIT ... this would be for multiplexing periodic endpoints, or |
| @@ -1517,7 +1518,7 @@ irqreturn_t musb_interrupt(struct musb *musb) · 660 unmodified lines | |||
| 1517 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 1518 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
| 1518 | 1519 | ||
| 1519 | dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n", | 1520 | dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n", |
| 1520 | (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", | 1521 | is_host_active(musb) ? "host" : "peripheral", |
| 1521 | musb->int_usb, musb->int_tx, musb->int_rx); | 1522 | musb->int_usb, musb->int_tx, musb->int_rx); |
| 1522 | 1523 | ||
| 1523 | /* the core can interrupt us for multiple reasons; docs have | 1524 | /* the core can interrupt us for multiple reasons; docs have |
| @@ -1531,7 +1532,7 @@ irqreturn_t musb_interrupt(struct musb *musb) · 7 unmodified lines | |||
| 1531 | 1532 | ||
| 1532 | /* handle endpoint 0 first */ | 1533 | /* handle endpoint 0 first */ |
| 1533 | if (musb->int_tx & 1) { | 1534 | if (musb->int_tx & 1) { |
| 1534 | if (devctl & MUSB_DEVCTL_HM) | 1535 | if (is_host_active(musb)) |
| 1535 | retval |= musb_h_ep0_irq(musb); | 1536 | retval |= musb_h_ep0_irq(musb); |
| 1536 | else | 1537 | else |
| 1537 | retval |= musb_g_ep0_irq(musb); | 1538 | retval |= musb_g_ep0_irq(musb); |
| @@ -1545,7 +1546,7 @@ irqreturn_t musb_interrupt(struct musb *musb) · 7 unmodified lines | |||
| 1545 | /* musb_ep_select(musb->mregs, ep_num); */ | 1546 | /* musb_ep_select(musb->mregs, ep_num); */ |
| 1546 | /* REVISIT just retval = ep->rx_irq(...) */ | 1547 | /* REVISIT just retval = ep->rx_irq(...) */ |
| 1547 | retval = IRQ_HANDLED; | 1548 | retval = IRQ_HANDLED; |
| 1548 | if (devctl & MUSB_DEVCTL_HM) | 1549 | if (is_host_active(musb)) |
| 1549 | musb_host_rx(musb, ep_num); | 1550 | musb_host_rx(musb, ep_num); |
| 1550 | else | 1551 | else |
| 1551 | musb_g_rx(musb, ep_num); | 1552 | musb_g_rx(musb, ep_num); |
| @@ -1563,7 +1564,7 @@ irqreturn_t musb_interrupt(struct musb *musb) · 11 unmodified lines | |||
| 1563 | /* musb_ep_select(musb->mregs, ep_num); */ | 1564 | /* musb_ep_select(musb->mregs, ep_num); */ |
| 1564 | /* REVISIT just retval |= ep->tx_irq(...) */ | 1565 | /* REVISIT just retval |= ep->tx_irq(...) */ |
| 1565 | retval = IRQ_HANDLED; | 1566 | retval = IRQ_HANDLED; |
| 1566 | if (devctl & MUSB_DEVCTL_HM) | 1567 | if (is_host_active(musb)) |
| 1567 | musb_host_tx(musb, ep_num); | 1568 | musb_host_tx(musb, ep_num); |
| 1568 | else | 1569 | else |
| 1569 | musb_g_tx(musb, ep_num); | 1570 | musb_g_tx(musb, ep_num); |
| @@ -1585,15 +1586,13 @@ MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); · 15 unmodified lines | |||
| 1585 | 1586 | ||
| 1586 | void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) | 1587 | void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) |
| 1587 | { | 1588 | { |
| 1588 | u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
| 1589 | |||
| 1590 | /* called with controller lock already held */ | 1589 | /* called with controller lock already held */ |
| 1591 | 1590 | ||
| 1592 | if (!epnum) { | 1591 | if (!epnum) { |
| 1593 | #ifndef CONFIG_USB_TUSB_OMAP_DMA | 1592 | #ifndef CONFIG_USB_TUSB_OMAP_DMA |
| 1594 | if (!is_cppi_enabled()) { | 1593 | if (!is_cppi_enabled()) { |
| 1595 | /* endpoint 0 */ | 1594 | /* endpoint 0 */ |
| 1596 | if (devctl & MUSB_DEVCTL_HM) | 1595 | if (is_host_active(musb)) |
| 1597 | musb_h_ep0_irq(musb); | 1596 | musb_h_ep0_irq(musb); |
| 1598 | else | 1597 | else |
| 1599 | musb_g_ep0_irq(musb); | 1598 | musb_g_ep0_irq(musb); |
| @@ -1602,13 +1601,13 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) · 2 unmodified lines | |||
| 1602 | } else { | 1601 | } else { |
| 1603 | /* endpoints 1..15 */ | 1602 | /* endpoints 1..15 */ |
| 1604 | if (transmit) { | 1603 | if (transmit) { |
| 1605 | if (devctl & MUSB_DEVCTL_HM) | 1604 | if (is_host_active(musb)) |
| 1606 | musb_host_tx(musb, epnum); | 1605 | musb_host_tx(musb, epnum); |
| 1607 | else | 1606 | else |
| 1608 | musb_g_tx(musb, epnum); | 1607 | musb_g_tx(musb, epnum); |
| 1609 | } else { | 1608 | } else { |
| 1610 | /* receive */ | 1609 | /* receive */ |
| 1611 | if (devctl & MUSB_DEVCTL_HM) | 1610 | if (is_host_active(musb)) |
| 1612 | musb_host_rx(musb, epnum); | 1611 | musb_host_rx(musb, epnum); |
| 1613 | else | 1612 | else |
| 1614 | musb_g_rx(musb, epnum); | 1613 | musb_g_rx(musb, epnum); |
| @@ -1753,20 +1752,22 @@ static void musb_irq_work(struct work_struct *data) · 138 unmodified lines | |||
| 1753 | /* Recover from babble interrupt conditions */ | 1752 | /* Recover from babble interrupt conditions */ |
| 1754 | static void musb_recover_work(struct work_struct *data) | 1753 | static void musb_recover_work(struct work_struct *data) |
| 1755 | { | 1754 | { |
| 1756 | struct musb *musb = container_of(data, struct musb, recover_work); | 1755 | struct musb *musb = container_of(data, struct musb, recover_work.work); |
| 1757 | int status; | 1756 | int status, ret; |
| 1758 | 1757 | ||
| 1759 | musb_platform_reset(musb); | 1758 | ret = musb_platform_reset(musb); |
| 1759 | if (ret) | ||
| 1760 | return; | ||
| 1760 | 1761 | ||
| 1761 | usb_phy_vbus_off(musb->xceiv); | 1762 | usb_phy_vbus_off(musb->xceiv); |
| 1762 | udelay(100); | 1763 | usleep_range(100, 200); |
| 1763 | 1764 | ||
| 1764 | usb_phy_vbus_on(musb->xceiv); | 1765 | usb_phy_vbus_on(musb->xceiv); |
| 1765 | udelay(100); | 1766 | usleep_range(100, 200); |
| 1766 | 1767 | ||
| 1767 | /* | 1768 | /* |
| 1768 | * When a babble condition occurs, the musb controller removes the | 1769 | * When a babble condition occurs, the musb controller |
| 1769 | * session bit and the endpoint config is lost. | 1770 | * removes the session bit and the endpoint config is lost. |
| 1770 | */ | 1771 | */ |
| 1771 | if (musb->dyn_fifo) | 1772 | if (musb->dyn_fifo) |
| 1772 | status = ep_config_from_table(musb); | 1773 | status = ep_config_from_table(musb); |
| @@ -1945,7 +1946,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) · 172 unmodified lines | |||
| 1945 | 1946 | ||
| 1946 | /* Init IRQ workqueue before request_irq */ | 1947 | /* Init IRQ workqueue before request_irq */ |
| 1947 | INIT_WORK(&musb->irq_work, musb_irq_work); | 1948 | INIT_WORK(&musb->irq_work, musb_irq_work); |
| 1948 | INIT_WORK(&musb->recover_work, musb_recover_work); | 1949 | INIT_DELAYED_WORK(&musb->recover_work, musb_recover_work); |
| 1949 | INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset); | 1950 | INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset); |
| 1950 | INIT_DELAYED_WORK(&musb->finish_resume_work, musb_host_finish_resume); | 1951 | INIT_DELAYED_WORK(&musb->finish_resume_work, musb_host_finish_resume); |
| 1951 | 1952 | ||
| @@ -2041,7 +2042,7 @@ fail4: · 89 unmodified lines | |||
| 2041 | 2042 | ||
| 2042 | fail3: | 2043 | fail3: |
| 2043 | cancel_work_sync(&musb->irq_work); | 2044 | cancel_work_sync(&musb->irq_work); |
| 2044 | cancel_work_sync(&musb->recover_work); | 2045 | cancel_delayed_work_sync(&musb->recover_work); |
| 2045 | cancel_delayed_work_sync(&musb->finish_resume_work); | 2046 | cancel_delayed_work_sync(&musb->finish_resume_work); |
| 2046 | cancel_delayed_work_sync(&musb->deassert_reset_work); | 2047 | cancel_delayed_work_sync(&musb->deassert_reset_work); |
| 2047 | if (musb->dma_controller) | 2048 | if (musb->dma_controller) |
| @@ -2107,7 +2108,7 @@ static int musb_remove(struct platform_device *pdev) · 59 unmodified lines | |||
| 2107 | dma_controller_destroy(musb->dma_controller); | 2108 | dma_controller_destroy(musb->dma_controller); |
| 2108 | 2109 | ||
| 2109 | cancel_work_sync(&musb->irq_work); | 2110 | cancel_work_sync(&musb->irq_work); |
| 2110 | cancel_work_sync(&musb->recover_work); | 2111 | cancel_delayed_work_sync(&musb->recover_work); |
| 2111 | cancel_delayed_work_sync(&musb->finish_resume_work); | 2112 | cancel_delayed_work_sync(&musb->finish_resume_work); |
| 2112 | cancel_delayed_work_sync(&musb->deassert_reset_work); | 2113 | cancel_delayed_work_sync(&musb->deassert_reset_work); |
| 2113 | musb_free(musb); | 2114 | musb_free(musb); |
| @@ -192,7 +192,7 @@ struct musb_platform_ops { · 191 unmodified lines | |||
| 192 | 192 | ||
| 193 | int (*set_mode)(struct musb *musb, u8 mode); | 193 | int (*set_mode)(struct musb *musb, u8 mode); |
| 194 | void (*try_idle)(struct musb *musb, unsigned long timeout); | 194 | void (*try_idle)(struct musb *musb, unsigned long timeout); |
| 195 | void (*reset)(struct musb *musb); | 195 | int (*reset)(struct musb *musb); |
| 196 | 196 | ||
| 197 | int (*vbus_status)(struct musb *musb); | 197 | int (*vbus_status)(struct musb *musb); |
| 198 | void (*set_vbus)(struct musb *musb, int on); | 198 | void (*set_vbus)(struct musb *musb, int on); |
| @@ -297,7 +297,7 @@ struct musb { · 98 unmodified lines | |||
| 297 | 297 | ||
| 298 | irqreturn_t (*isr)(int, void *); | 298 | irqreturn_t (*isr)(int, void *); |
| 299 | struct work_struct irq_work; | 299 | struct work_struct irq_work; |
| 300 | struct work_struct recover_work; | 300 | struct delayed_work recover_work; |
| 301 | struct delayed_work deassert_reset_work; | 301 | struct delayed_work deassert_reset_work; |
| 302 | struct delayed_work finish_resume_work; | 302 | struct delayed_work finish_resume_work; |
| 303 | u16 hwvers; | 303 | u16 hwvers; |
| @@ -555,10 +555,12 @@ static inline void musb_platform_try_idle(struct musb *musb, · 251 unmodified lines | |||
| 555 | musb->ops->try_idle(musb, timeout); | 555 | musb->ops->try_idle(musb, timeout); |
| 556 | } | 556 | } |
| 557 | 557 | ||
| 558 | static inline void musb_platform_reset(struct musb *musb) | 558 | static inline int musb_platform_reset(struct musb *musb) |
| 559 | { | 559 | { |
| 560 | if (musb->ops->reset) | 560 | if (!musb->ops->reset) |
| 561 | musb->ops->reset(musb); | 561 | return -EINVAL; |
| 562 | |||
| 563 | return musb->ops->reset(musb); | ||
| 562 | } | 564 | } |
| 563 | 565 | ||
| 564 | static inline int musb_platform_get_vbus_status(struct musb *musb) | 566 | static inline int musb_platform_get_vbus_status(struct musb *musb) |
| @@ -39,7 +39,6 @@ struct cppi41_dma_channel { · 38 unmodified lines | |||
| 39 | u32 transferred; | 39 | u32 transferred; |
| 40 | u32 packet_sz; | 40 | u32 packet_sz; |
| 41 | struct list_head tx_check; | 41 | struct list_head tx_check; |
| 42 | struct work_struct dma_completion; | ||
| 43 | }; | 42 | }; |
| 44 | 43 | ||
| 45 | #define MUSB_DMA_NUM_CHANNELS 15 | 44 | #define MUSB_DMA_NUM_CHANNELS 15 |
| @@ -74,15 +73,18 @@ static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel) · 28 unmodified lines | |||
| 74 | 73 | ||
| 75 | static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel) | 74 | static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel) |
| 76 | { | 75 | { |
| 76 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | ||
| 77 | struct musb *musb = hw_ep->musb; | ||
| 77 | u16 csr; | 78 | u16 csr; |
| 78 | u8 toggle; | 79 | u8 toggle; |
| 79 | 80 | ||
| 80 | if (cppi41_channel->is_tx) | 81 | if (cppi41_channel->is_tx) |
| 81 | return; | 82 | return; |
| 82 | if (!is_host_active(cppi41_channel->controller->musb)) | 83 | if (!is_host_active(musb)) |
| 83 | return; | 84 | return; |
| 84 | 85 | ||
| 85 | csr = musb_readw(cppi41_channel->hw_ep->regs, MUSB_RXCSR); | 86 | musb_ep_select(musb->mregs, hw_ep->epnum); |
| 87 | csr = musb_readw(hw_ep->regs, MUSB_RXCSR); | ||
| 86 | toggle = csr & MUSB_RXCSR_H_DATATOGGLE ? 1 : 0; | 88 | toggle = csr & MUSB_RXCSR_H_DATATOGGLE ? 1 : 0; |
| 87 | 89 | ||
| 88 | /* | 90 | /* |
| @@ -107,24 +109,13 @@ static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep) · 18 unmodified lines | |||
| 107 | void __iomem *epio = musb->endpoints[epnum].regs; | 109 | void __iomem *epio = musb->endpoints[epnum].regs; |
| 108 | u16 csr; | 110 | u16 csr; |
| 109 | 111 | ||
| 112 | musb_ep_select(musb->mregs, hw_ep->epnum); | ||
| 110 | csr = musb_readw(epio, MUSB_TXCSR); | 113 | csr = musb_readw(epio, MUSB_TXCSR); |
| 111 | if (csr & MUSB_TXCSR_TXPKTRDY) | 114 | if (csr & MUSB_TXCSR_TXPKTRDY) |
| 112 | return false; | 115 | return false; |
| 113 | return true; | 116 | return true; |
| 114 | } | 117 | } |
| 115 | 118 | ||
| 116 | static bool is_isoc(struct musb_hw_ep *hw_ep, bool in) | ||
| 117 | { | ||
| 118 | if (in && hw_ep->in_qh) { | ||
| 119 | if (hw_ep->in_qh->type == USB_ENDPOINT_XFER_ISOC) | ||
| 120 | return true; | ||
| 121 | } else if (hw_ep->out_qh) { | ||
| 122 | if (hw_ep->out_qh->type == USB_ENDPOINT_XFER_ISOC) | ||
| 123 | return true; | ||
| 124 | } | ||
| 125 | return false; | ||
| 126 | } | ||
| 127 | |||
| 128 | static void cppi41_dma_callback(void *private_data); | 119 | static void cppi41_dma_callback(void *private_data); |
| 129 | 120 | ||
| 130 | static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | 121 | static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) |
| @@ -139,6 +130,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) · 8 unmodified lines | |||
| 139 | cppi41_channel->channel.actual_len = | 130 | cppi41_channel->channel.actual_len = |
| 140 | cppi41_channel->transferred; | 131 | cppi41_channel->transferred; |
| 141 | cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; | 132 | cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; |
| 133 | cppi41_channel->channel.rx_packet_done = true; | ||
| 142 | musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); | 134 | musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); |
| 143 | } else { | 135 | } else { |
| 144 | /* next iteration, reload */ | 136 | /* next iteration, reload */ |
| @@ -172,6 +164,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) · 27 unmodified lines | |||
| 172 | dma_async_issue_pending(dc); | 164 | dma_async_issue_pending(dc); |
| 173 | 165 | ||
| 174 | if (!cppi41_channel->is_tx) { | 166 | if (!cppi41_channel->is_tx) { |
| 167 | musb_ep_select(musb->mregs, hw_ep->epnum); | ||
| 175 | csr = musb_readw(epio, MUSB_RXCSR); | 168 | csr = musb_readw(epio, MUSB_RXCSR); |
| 176 | csr |= MUSB_RXCSR_H_REQPKT; | 169 | csr |= MUSB_RXCSR_H_REQPKT; |
| 177 | musb_writew(epio, MUSB_RXCSR, csr); | 170 | musb_writew(epio, MUSB_RXCSR, csr); |
| @@ -179,32 +172,6 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) · 1 unmodified line | |||
| 179 | } | 172 | } |
| 180 | } | 173 | } |
| 181 | 174 | ||
| 182 | static void cppi_trans_done_work(struct work_struct *work) | ||
| 183 | { | ||
| 184 | unsigned long flags; | ||
| 185 | struct cppi41_dma_channel *cppi41_channel = | ||
| 186 | container_of(work, struct cppi41_dma_channel, dma_completion); | ||
| 187 | struct cppi41_dma_controller *controller = cppi41_channel->controller; | ||
| 188 | struct musb *musb = controller->musb; | ||
| 189 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | ||
| 190 | bool empty; | ||
| 191 | |||
| 192 | if (!cppi41_channel->is_tx && is_isoc(hw_ep, 1)) { | ||
| 193 | spin_lock_irqsave(&musb->lock, flags); | ||
| 194 | cppi41_trans_done(cppi41_channel); | ||
| 195 | spin_unlock_irqrestore(&musb->lock, flags); | ||
| 196 | } else { | ||
| 197 | empty = musb_is_tx_fifo_empty(hw_ep); | ||
| 198 | if (empty) { | ||
| 199 | spin_lock_irqsave(&musb->lock, flags); | ||
| 200 | cppi41_trans_done(cppi41_channel); | ||
| 201 | spin_unlock_irqrestore(&musb->lock, flags); | ||
| 202 | } else { | ||
| 203 | schedule_work(&cppi41_channel->dma_completion); | ||
| 204 | } | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) | 175 | static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) |
| 209 | { | 176 | { |
| 210 | struct cppi41_dma_controller *controller; | 177 | struct cppi41_dma_controller *controller; |
| @@ -233,7 +200,7 @@ static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) · 22 unmodified lines | |||
| 233 | if (!list_empty(&controller->early_tx_list)) { | 200 | if (!list_empty(&controller->early_tx_list)) { |
| 234 | ret = HRTIMER_RESTART; | 201 | ret = HRTIMER_RESTART; |
| 235 | hrtimer_forward_now(&controller->early_tx, | 202 | hrtimer_forward_now(&controller->early_tx, |
| 236 | ktime_set(0, 150 * NSEC_PER_USEC)); | 203 | ktime_set(0, 50 * NSEC_PER_USEC)); |
| 237 | } | 204 | } |
| 238 | 205 | ||
| 239 | spin_unlock_irqrestore(&musb->lock, flags); | 206 | spin_unlock_irqrestore(&musb->lock, flags); |
| @@ -268,14 +235,6 @@ static void cppi41_dma_callback(void *private_data) · 28 unmodified lines | |||
| 268 | transferred < cppi41_channel->packet_sz) | 235 | transferred < cppi41_channel->packet_sz) |
| 269 | cppi41_channel->prog_len = 0; | 236 | cppi41_channel->prog_len = 0; |
| 270 | 237 | ||
| 271 | if (!cppi41_channel->is_tx) { | ||
| 272 | if (is_isoc(hw_ep, 1)) | ||
| 273 | schedule_work(&cppi41_channel->dma_completion); | ||
| 274 | else | ||
| 275 | cppi41_trans_done(cppi41_channel); | ||
| 276 | goto out; | ||
| 277 | } | ||
| 278 | |||
| 279 | empty = musb_is_tx_fifo_empty(hw_ep); | 238 | empty = musb_is_tx_fifo_empty(hw_ep); |
| 280 | if (empty) { | 239 | if (empty) { |
| 281 | cppi41_trans_done(cppi41_channel); | 240 | cppi41_trans_done(cppi41_channel); |
| @@ -312,15 +271,13 @@ static void cppi41_dma_callback(void *private_data) · 30 unmodified lines | |||
| 312 | goto out; | 271 | goto out; |
| 313 | } | 272 | } |
| 314 | } | 273 | } |
| 315 | if (is_isoc(hw_ep, 0)) { | ||
| 316 | schedule_work(&cppi41_channel->dma_completion); | ||
| 317 | goto out; | ||
| 318 | } | ||
| 319 | list_add_tail(&cppi41_channel->tx_check, | 274 | list_add_tail(&cppi41_channel->tx_check, |
| 320 | &controller->early_tx_list); | 275 | &controller->early_tx_list); |
| 321 | if (!hrtimer_is_queued(&controller->early_tx)) { | 276 | if (!hrtimer_is_queued(&controller->early_tx)) { |
| 277 | unsigned long usecs = cppi41_channel->total_len / 10; | ||
| 278 | |||
| 322 | hrtimer_start_range_ns(&controller->early_tx, | 279 | hrtimer_start_range_ns(&controller->early_tx, |
| 323 | ktime_set(0, 140 * NSEC_PER_USEC), | 280 | ktime_set(0, usecs * NSEC_PER_USEC), |
| 324 | 40 * NSEC_PER_USEC, | 281 | 40 * NSEC_PER_USEC, |
| 325 | HRTIMER_MODE_REL); | 282 | HRTIMER_MODE_REL); |
| 326 | } | 283 | } |
| @@ -450,6 +407,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, · 123 unmodified lines | |||
| 450 | dma_desc->callback = cppi41_dma_callback; | 407 | dma_desc->callback = cppi41_dma_callback; |
| 451 | dma_desc->callback_param = channel; | 408 | dma_desc->callback_param = channel; |
| 452 | cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); | 409 | cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); |
| 410 | cppi41_channel->channel.rx_packet_done = false; | ||
| 453 | 411 | ||
| 454 | save_rx_toggle(cppi41_channel); | 412 | save_rx_toggle(cppi41_channel); |
| 455 | dma_async_issue_pending(dc); | 413 | dma_async_issue_pending(dc); |
| @@ -672,8 +630,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) · 216 unmodified lines | |||
| 672 | cppi41_channel->port_num = port; | 630 | cppi41_channel->port_num = port; |
| 673 | cppi41_channel->is_tx = is_tx; | 631 | cppi41_channel->is_tx = is_tx; |
| 674 | INIT_LIST_HEAD(&cppi41_channel->tx_check); | 632 | INIT_LIST_HEAD(&cppi41_channel->tx_check); |
| 675 | INIT_WORK(&cppi41_channel->dma_completion, | ||
| 676 | cppi_trans_done_work); | ||
| 677 | 633 | ||
| 678 | musb_dma = &cppi41_channel->channel; | 634 | musb_dma = &cppi41_channel->channel; |
| 679 | musb_dma->private_data = cppi41_channel; | 635 | musb_dma->private_data = cppi41_channel; |
| @@ -129,6 +129,7 @@ struct dma_channel { · 128 unmodified lines | |||
| 129 | size_t actual_len; | 129 | size_t actual_len; |
| 130 | enum dma_channel_status status; | 130 | enum dma_channel_status status; |
| 131 | bool desired_mode; | 131 | bool desired_mode; |
| 132 | bool rx_packet_done; | ||
| 132 | }; | 133 | }; |
| 133 | 134 | ||
| 134 | /* | 135 | /* |
| @@ -56,16 +56,24 @@ static const struct of_device_id musb_dsps_of_match[]; · 55 unmodified lines | |||
| 56 | * dependent on musb core layer symbols. | 56 | * dependent on musb core layer symbols. |
| 57 | */ | 57 | */ |
| 58 | static inline u8 dsps_readb(const void __iomem *addr, unsigned offset) | 58 | static inline u8 dsps_readb(const void __iomem *addr, unsigned offset) |
| 59 | { return __raw_readb(addr + offset); } | 59 | { |
| 60 | return __raw_readb(addr + offset); | ||
| 61 | } | ||
| 60 | 62 | ||
| 61 | static inline u32 dsps_readl(const void __iomem *addr, unsigned offset) | 63 | static inline u32 dsps_readl(const void __iomem *addr, unsigned offset) |
| 62 | { return __raw_readl(addr + offset); } | 64 | { |
| 65 | return __raw_readl(addr + offset); | ||
| 66 | } | ||
| 63 | 67 | ||
| 64 | static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data) | 68 | static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data) |
| 65 | { __raw_writeb(data, addr + offset); } | 69 | { |
| 70 | __raw_writeb(data, addr + offset); | ||
| 71 | } | ||
| 66 | 72 | ||
| 67 | static inline void dsps_writel(void __iomem *addr, unsigned offset, u32 data) | 73 | static inline void dsps_writel(void __iomem *addr, unsigned offset, u32 data) |
| 68 | { __raw_writel(data, addr + offset); } | 74 | { |
| 75 | __raw_writel(data, addr + offset); | ||
| 76 | } | ||
| 69 | 77 | ||
| 70 | /** | 78 | /** |
| 71 | * DSPS musb wrapper register offset. | 79 | * DSPS musb wrapper register offset. |
| @@ -136,6 +144,7 @@ struct dsps_glue { · 64 unmodified lines | |||
| 136 | const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ | 144 | const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ |
| 137 | struct timer_list timer; /* otg_workaround timer */ | 145 | struct timer_list timer; /* otg_workaround timer */ |
| 138 | unsigned long last_timer; /* last timer data for each instance */ | 146 | unsigned long last_timer; /* last timer data for each instance */ |
| 147 | bool sw_babble_enabled; | ||
| 139 | 148 | ||
| 140 | struct dsps_context context; | 149 | struct dsps_context context; |
| 141 | struct debugfs_regset32 regset; | 150 | struct debugfs_regset32 regset; |
| @@ -469,6 +478,19 @@ static int dsps_musb_init(struct musb *musb) · 327 unmodified lines | |||
| 469 | val &= ~(1 << wrp->otg_disable); | 478 | val &= ~(1 << wrp->otg_disable); |
| 470 | dsps_writel(musb->ctrl_base, wrp->phy_utmi, val); | 479 | dsps_writel(musb->ctrl_base, wrp->phy_utmi, val); |
| 471 | 480 | ||
| 481 | /* | ||
| 482 | * Check whether the dsps version has babble control enabled. | ||
| 483 | * In latest silicon revision the babble control logic is enabled. | ||
| 484 | * If MUSB_BABBLE_CTL returns 0x4 then we have the babble control | ||
| 485 | * logic enabled. | ||
| 486 | */ | ||
| 487 | val = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); | ||
| 488 | if (val == MUSB_BABBLE_RCV_DISABLE) { | ||
| 489 | glue->sw_babble_enabled = true; | ||
| 490 | val |= MUSB_BABBLE_SW_SESSION_CTRL; | ||
| 491 | dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val); | ||
| 492 | } | ||
| 493 | |||
| 472 | ret = dsps_musb_dbg_init(musb, glue); | 494 | ret = dsps_musb_dbg_init(musb, glue); |
| 473 | if (ret) | 495 | if (ret) |
| 474 | return ret; | 496 | return ret; |
| @@ -535,14 +557,82 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) · 60 unmodified lines | |||
| 535 | return 0; | 557 | return 0; |
| 536 | } | 558 | } |
| 537 | 559 | ||
| 538 | static void dsps_musb_reset(struct musb *musb) | 560 | static bool sw_babble_control(struct musb *musb) |
| 561 | { | ||
| 562 | u8 babble_ctl; | ||
| 563 | bool session_restart = false; | ||
| 564 | |||
| 565 | babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); | ||
| 566 | dev_dbg(musb->controller, "babble: MUSB_BABBLE_CTL value %x\n", | ||
| 567 | babble_ctl); | ||
| 568 | /* | ||
| 569 | * check line monitor flag to check whether babble is | ||
| 570 | * due to noise | ||
| 571 | */ | ||
| 572 | dev_dbg(musb->controller, "STUCK_J is %s\n", | ||
| 573 | babble_ctl & MUSB_BABBLE_STUCK_J ? "set" : "reset"); | ||
| 574 | |||
| 575 | if (babble_ctl & MUSB_BABBLE_STUCK_J) { | ||
| 576 | int timeout = 10; | ||
| 577 | |||
| 578 | /* | ||
| 579 | * babble is due to noise, then set transmit idle (d7 bit) | ||
| 580 | * to resume normal operation | ||
| 581 | */ | ||
| 582 | babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); | ||
| 583 | babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE; | ||
| 584 | dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, babble_ctl); | ||
| 585 | |||
| 586 | /* wait till line monitor flag cleared */ | ||
| 587 | dev_dbg(musb->controller, "Set TXIDLE, wait J to clear\n"); | ||
| 588 | do { | ||
| 589 | babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); | ||
| 590 | udelay(1); | ||
| 591 | } while ((babble_ctl & MUSB_BABBLE_STUCK_J) && timeout--); | ||
| 592 | |||
| 593 | /* check whether stuck_at_j bit cleared */ | ||
| 594 | if (babble_ctl & MUSB_BABBLE_STUCK_J) { | ||
| 595 | /* | ||
| 596 | * real babble condition has occurred | ||
| 597 | * restart the controller to start the | ||
| 598 | * session again | ||
| 599 | */ | ||
| 600 | dev_dbg(musb->controller, "J not cleared, misc (%x)\n", | ||
| 601 | babble_ctl); | ||
| 602 | session_restart = true; | ||
| 603 | } | ||
| 604 | } else { | ||
| 605 | session_restart = true; | ||
| 606 | } | ||
| 607 | |||
| 608 | return session_restart; | ||
| 609 | } | ||
| 610 | |||
| 611 | static int dsps_musb_reset(struct musb *musb) | ||
| 539 | { | 612 | { |
| 540 | struct device *dev = musb->controller; | 613 | struct device *dev = musb->controller; |
| 541 | struct dsps_glue *glue = dev_get_drvdata(dev->parent); | 614 | struct dsps_glue *glue = dev_get_drvdata(dev->parent); |
| 542 | const struct dsps_musb_wrapper *wrp = glue->wrp; | 615 | const struct dsps_musb_wrapper *wrp = glue->wrp; |
| 616 | int session_restart = 0; | ||
| 617 | |||
| 618 | if (glue->sw_babble_enabled) | ||
| 619 | session_restart = sw_babble_control(musb); | ||
| 620 | /* | ||
| 621 | * In case of new silicon version babble condition can be recovered | ||
| 622 | * without resetting the MUSB. But for older silicon versions, MUSB | ||
| 623 | * reset is needed | ||
| 624 | */ | ||
| 625 | if (session_restart || !glue->sw_babble_enabled) { | ||
| 626 | dev_info(musb->controller, "Restarting MUSB to recover from Babble\n"); | ||
| 627 | dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); | ||
| 628 | usleep_range(100, 200); | ||
| 629 | usb_phy_shutdown(musb->xceiv); | ||
| 630 | usleep_range(100, 200); | ||
| 631 | usb_phy_init(musb->xceiv); | ||
| 632 | session_restart = 1; | ||
| 633 | } | ||
| 543 | 634 | ||
| 544 | dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); | 635 | return !session_restart; |
| 545 | udelay(100); | ||
| 546 | } | 636 | } |
| 547 | 637 | ||
| 548 | static struct musb_platform_ops dsps_ops = { | 638 | static struct musb_platform_ops dsps_ops = { |
| @@ -120,7 +120,7 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) · 119 unmodified lines | |||
| 120 | if (csr != lastcsr) | 120 | if (csr != lastcsr) |
| 121 | dev_dbg(musb->controller, "Host TX FIFONOTEMPTY csr: %02x\n", csr); | 121 | dev_dbg(musb->controller, "Host TX FIFONOTEMPTY csr: %02x\n", csr); |
| 122 | lastcsr = csr; | 122 | lastcsr = csr; |
| 123 | csr |= MUSB_TXCSR_FLUSHFIFO; | 123 | csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_TXPKTRDY; |
| 124 | musb_writew(epio, MUSB_TXCSR, csr); | 124 | musb_writew(epio, MUSB_TXCSR, csr); |
| 125 | csr = musb_readw(epio, MUSB_TXCSR); | 125 | csr = musb_readw(epio, MUSB_TXCSR); |
| 126 | if (WARN(retries-- < 1, | 126 | if (WARN(retries-- < 1, |
| @@ -1295,7 +1295,7 @@ done: · 1168 unmodified lines | |||
| 1295 | if (status) { | 1295 | if (status) { |
| 1296 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | 1296 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { |
| 1297 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; | 1297 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; |
| 1298 | (void) musb->dma_controller->channel_abort(dma); | 1298 | musb->dma_controller->channel_abort(dma); |
| 1299 | } | 1299 | } |
| 1300 | 1300 | ||
| 1301 | /* do the proper sequence to abort the transfer in the | 1301 | /* do the proper sequence to abort the transfer in the |
| @@ -1640,7 +1640,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) · 338 unmodified lines | |||
| 1640 | /* clean up dma and collect transfer count */ | 1640 | /* clean up dma and collect transfer count */ |
| 1641 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | 1641 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { |
| 1642 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; | 1642 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; |
| 1643 | (void) musb->dma_controller->channel_abort(dma); | 1643 | musb->dma_controller->channel_abort(dma); |
| 1644 | xfer_len = dma->actual_len; | 1644 | xfer_len = dma->actual_len; |
| 1645 | } | 1645 | } |
| 1646 | musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG); | 1646 | musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG); |
| @@ -1671,7 +1671,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) · 24 unmodified lines | |||
| 1671 | */ | 1671 | */ |
| 1672 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | 1672 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { |
| 1673 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; | 1673 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; |
| 1674 | (void) musb->dma_controller->channel_abort(dma); | 1674 | musb->dma_controller->channel_abort(dma); |
| 1675 | xfer_len = dma->actual_len; | 1675 | xfer_len = dma->actual_len; |
| 1676 | done = true; | 1676 | done = true; |
| 1677 | } | 1677 | } |
| @@ -1734,10 +1734,11 @@ void musb_host_rx(struct musb *musb, u8 epnum) · 56 unmodified lines | |||
| 1734 | } | 1734 | } |
| 1735 | 1735 | ||
| 1736 | } else { | 1736 | } else { |
| 1737 | /* done if urb buffer is full or short packet is recd */ | 1737 | /* done if urb buffer is full or short packet is recd */ |
| 1738 | done = (urb->actual_length + xfer_len >= | 1738 | done = (urb->actual_length + xfer_len >= |
| 1739 | urb->transfer_buffer_length | 1739 | urb->transfer_buffer_length |
| 1740 | || dma->actual_len < qh->maxpacket); | 1740 | || dma->actual_len < qh->maxpacket |
| 1741 | || dma->rx_packet_done); | ||
| 1741 | } | 1742 | } |
| 1742 | 1743 | ||
| 1743 | /* send IN token for next packet, without AUTOREQ */ | 1744 | /* send IN token for next packet, without AUTOREQ */ |
| @@ -1957,7 +1958,7 @@ static int musb_schedule( · 213 unmodified lines | |||
| 1957 | struct musb_qh *qh, | 1958 | struct musb_qh *qh, |
| 1958 | int is_in) | 1959 | int is_in) |
| 1959 | { | 1960 | { |
| 1960 | int idle; | 1961 | int idle = 0; |
| 1961 | int best_diff; | 1962 | int best_diff; |
| 1962 | int best_end, epnum; | 1963 | int best_end, epnum; |
| 1963 | struct musb_hw_ep *hw_ep = NULL; | 1964 | struct musb_hw_ep *hw_ep = NULL; |
| @@ -72,6 +72,12 @@ · 71 unmodified lines | |||
| 72 | #define MUSB_DEVCTL_HR 0x02 | 72 | #define MUSB_DEVCTL_HR 0x02 |
| 73 | #define MUSB_DEVCTL_SESSION 0x01 | 73 | #define MUSB_DEVCTL_SESSION 0x01 |
| 74 | 74 | ||
| 75 | /* BABBLE_CTL */ | ||
| 76 | #define MUSB_BABBLE_FORCE_TXIDLE 0x80 | ||
| 77 | #define MUSB_BABBLE_SW_SESSION_CTRL 0x40 | ||
| 78 | #define MUSB_BABBLE_STUCK_J 0x20 | ||
| 79 | #define MUSB_BABBLE_RCV_DISABLE 0x04 | ||
| 80 | |||
| 75 | /* MUSB ULPI VBUSCONTROL */ | 81 | /* MUSB ULPI VBUSCONTROL */ |
| 76 | #define MUSB_ULPI_USE_EXTVBUS 0x01 | 82 | #define MUSB_ULPI_USE_EXTVBUS 0x01 |
| 77 | #define MUSB_ULPI_USE_EXTVBUSIND 0x02 | 83 | #define MUSB_ULPI_USE_EXTVBUSIND 0x02 |
| @@ -246,6 +252,7 @@ · 168 unmodified lines | |||
| 246 | */ | 252 | */ |
| 247 | 253 | ||
| 248 | #define MUSB_DEVCTL 0x60 /* 8 bit */ | 254 | #define MUSB_DEVCTL 0x60 /* 8 bit */ |
| 255 | #define MUSB_BABBLE_CTL 0x61 /* 8 bit */ | ||
| 249 | 256 | ||
| 250 | /* These are always controlled through the INDEX register */ | 257 | /* These are always controlled through the INDEX register */ |
| 251 | #define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */ | 258 | #define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */ |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
| 23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
| 24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
| 25 | #include <linux/device.h> | ||
| 25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
| 26 | #include <linux/dma-mapping.h> | 27 | #include <linux/dma-mapping.h> |
| 27 | #include <linux/usb/usb_phy_generic.h> | 28 | #include <linux/usb/usb_phy_generic.h> |
| @@ -1160,12 +1161,12 @@ static int tusb_probe(struct platform_device *pdev) · 1132 unmodified lines | |||
| 1160 | struct platform_device *musb; | 1161 | struct platform_device *musb; |
| 1161 | struct tusb6010_glue *glue; | 1162 | struct tusb6010_glue *glue; |
| 1162 | struct platform_device_info pinfo; | 1163 | struct platform_device_info pinfo; |
| 1163 | int ret = -ENOMEM; | 1164 | int ret; |
| 1164 | 1165 | ||
| 1165 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 1166 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
| 1166 | if (!glue) { | 1167 | if (!glue) { |
| 1167 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | 1168 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
| 1168 | goto err0; | 1169 | return -ENOMEM; |
| 1169 | } | 1170 | } |
| 1170 | 1171 | ||
| 1171 | glue->dev = &pdev->dev; | 1172 | glue->dev = &pdev->dev; |
| @@ -1204,16 +1205,10 @@ static int tusb_probe(struct platform_device *pdev) · 32 unmodified lines | |||
| 1204 | if (IS_ERR(musb)) { | 1205 | if (IS_ERR(musb)) { |
| 1205 | ret = PTR_ERR(musb); | 1206 | ret = PTR_ERR(musb); |
| 1206 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); | 1207 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); |
| 1207 | goto err3; | 1208 | return ret; |
| 1208 | } | 1209 | } |
| 1209 | 1210 | ||
| 1210 | return 0; | 1211 | return 0; |
| 1211 | |||
| 1212 | err3: | ||
| 1213 | kfree(glue); | ||
| 1214 | |||
| 1215 | err0: | ||
| 1216 | return ret; | ||
| 1217 | } | 1212 | } |
| 1218 | 1213 | ||
| 1219 | static int tusb_remove(struct platform_device *pdev) | 1214 | static int tusb_remove(struct platform_device *pdev) |
| @@ -1222,7 +1217,6 @@ static int tusb_remove(struct platform_device *pdev) · 2 unmodified lines | |||
| 1222 | 1217 | ||
| 1223 | platform_device_unregister(glue->musb); | 1218 | platform_device_unregister(glue->musb); |
| 1224 | usb_phy_generic_unregister(glue->phy); | 1219 | usb_phy_generic_unregister(glue->phy); |
| 1225 | kfree(glue); | ||
| 1226 | 1220 | ||
| 1227 | return 0; | 1221 | return 0; |
| 1228 | } | 1222 | } |
| @@ -246,7 +246,7 @@ static int ux500_probe(struct platform_device *pdev) · 245 unmodified lines | |||
| 246 | } | 246 | } |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 249 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
| 250 | if (!glue) { | 250 | if (!glue) { |
| 251 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | 251 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
| 252 | goto err0; | 252 | goto err0; |
| @@ -255,20 +255,20 @@ static int ux500_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 255 | musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); | 255 | musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); |
| 256 | if (!musb) { | 256 | if (!musb) { |
| 257 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | 257 | dev_err(&pdev->dev, "failed to allocate musb device\n"); |
| 258 | goto err1; | 258 | goto err0; |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | clk = clk_get(&pdev->dev, NULL); | 261 | clk = devm_clk_get(&pdev->dev, NULL); |
| 262 | if (IS_ERR(clk)) { | 262 | if (IS_ERR(clk)) { |
| 263 | dev_err(&pdev->dev, "failed to get clock\n"); | 263 | dev_err(&pdev->dev, "failed to get clock\n"); |
| 264 | ret = PTR_ERR(clk); | 264 | ret = PTR_ERR(clk); |
| 265 | goto err3; | 265 | goto err1; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | ret = clk_prepare_enable(clk); | 268 | ret = clk_prepare_enable(clk); |
| 269 | if (ret) { | 269 | if (ret) { |
| 270 | dev_err(&pdev->dev, "failed to enable clock\n"); | 270 | dev_err(&pdev->dev, "failed to enable clock\n"); |
| 271 | goto err4; | 271 | goto err1; |
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | musb->dev.parent = &pdev->dev; | 274 | musb->dev.parent = &pdev->dev; |
| @@ -301,34 +301,28 @@ static int ux500_probe(struct platform_device *pdev) · 26 unmodified lines | |||
| 301 | ARRAY_SIZE(musb_resources)); | 301 | ARRAY_SIZE(musb_resources)); |
| 302 | if (ret) { | 302 | if (ret) { |
| 303 | dev_err(&pdev->dev, "failed to add resources\n"); | 303 | dev_err(&pdev->dev, "failed to add resources\n"); |
| 304 | goto err5; | 304 | goto err2; |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | 307 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); |
| 308 | if (ret) { | 308 | if (ret) { |
| 309 | dev_err(&pdev->dev, "failed to add platform_data\n"); | 309 | dev_err(&pdev->dev, "failed to add platform_data\n"); |
| 310 | goto err5; | 310 | goto err2; |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | ret = platform_device_add(musb); | 313 | ret = platform_device_add(musb); |
| 314 | if (ret) { | 314 | if (ret) { |
| 315 | dev_err(&pdev->dev, "failed to register musb device\n"); | 315 | dev_err(&pdev->dev, "failed to register musb device\n"); |
| 316 | goto err5; | 316 | goto err2; |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | return 0; | 319 | return 0; |
| 320 | 320 | ||
| 321 | err5: | 321 | err2: |
| 322 | clk_disable_unprepare(clk); | 322 | clk_disable_unprepare(clk); |
| 323 | 323 | ||
| 324 | err4: | ||
| 325 | clk_put(clk); | ||
| 326 | |||
| 327 | err3: | ||
| 328 | platform_device_put(musb); | ||
| 329 | |||
| 330 | err1: | 324 | err1: |
| 331 | kfree(glue); | 325 | platform_device_put(musb); |
| 332 | 326 | ||
| 333 | err0: | 327 | err0: |
| 334 | return ret; | 328 | return ret; |
| @@ -340,8 +334,6 @@ static int ux500_remove(struct platform_device *pdev) · 5 unmodified lines | |||
| 340 | 334 | ||
| 341 | platform_device_unregister(glue->musb); | 335 | platform_device_unregister(glue->musb); |
| 342 | clk_disable_unprepare(glue->clk); | 336 | clk_disable_unprepare(glue->clk); |
| 343 | clk_put(glue->clk); | ||
| 344 | kfree(glue); | ||
| 345 | 337 | ||
| 346 | return 0; | 338 | return 0; |
| 347 | } | 339 | } |
| @@ -122,16 +122,10 @@ static int am335x_phy_resume(struct device *dev) · 121 unmodified lines | |||
| 122 | 122 | ||
| 123 | return 0; | 123 | return 0; |
| 124 | } | 124 | } |
| 125 | |||
| 126 | static const struct dev_pm_ops am335x_pm_ops = { | ||
| 127 | SET_SYSTEM_SLEEP_PM_OPS(am335x_phy_suspend, am335x_phy_resume) | ||
| 128 | }; | ||
| 129 | |||
| 130 | #define DEV_PM_OPS (&am335x_pm_ops) | ||
| 131 | #else | ||
| 132 | #define DEV_PM_OPS NULL | ||
| 133 | #endif | 125 | #endif |
| 134 | 126 | ||
| 127 | static SIMPLE_DEV_PM_OPS(am335x_pm_ops, am335x_phy_suspend, am335x_phy_resume); | ||
| 128 | |||
| 135 | static const struct of_device_id am335x_phy_ids[] = { | 129 | static const struct of_device_id am335x_phy_ids[] = { |
| 136 | { .compatible = "ti,am335x-usb-phy" }, | 130 | { .compatible = "ti,am335x-usb-phy" }, |
| 137 | { } | 131 | { } |
| @@ -144,7 +138,7 @@ static struct platform_driver am335x_phy_driver = { · 6 unmodified lines | |||
| 144 | .driver = { | 138 | .driver = { |
| 145 | .name = "am335x-phy-driver", | 139 | .name = "am335x-phy-driver", |
| 146 | .owner = THIS_MODULE, | 140 | .owner = THIS_MODULE, |
| 147 | .pm = DEV_PM_OPS, | 141 | .pm = &am335x_pm_ops, |
| 148 | .of_match_table = am335x_phy_ids, | 142 | .of_match_table = am335x_phy_ids, |
| 149 | }, | 143 | }, |
| 150 | }; | 144 | }; |
| @@ -253,11 +253,13 @@ static int gpio_vbus_probe(struct platform_device *pdev) · 252 unmodified lines | |||
| 253 | return -EINVAL; | 253 | return -EINVAL; |
| 254 | gpio = pdata->gpio_vbus; | 254 | gpio = pdata->gpio_vbus; |
| 255 | 255 | ||
| 256 | gpio_vbus = kzalloc(sizeof(struct gpio_vbus_data), GFP_KERNEL); | 256 | gpio_vbus = devm_kzalloc(&pdev->dev, sizeof(struct gpio_vbus_data), |
| 257 | GFP_KERNEL); | ||
| 257 | if (!gpio_vbus) | 258 | if (!gpio_vbus) |
| 258 | return -ENOMEM; | 259 | return -ENOMEM; |
| 259 | 260 | ||
| 260 | gpio_vbus->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); | 261 | gpio_vbus->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), |
| 262 | GFP_KERNEL); | ||
| 261 | if (!gpio_vbus->phy.otg) { | 263 | if (!gpio_vbus->phy.otg) { |
| 262 | kfree(gpio_vbus); | 264 | kfree(gpio_vbus); |
| 263 | return -ENOMEM; | 265 | return -ENOMEM; |
| @@ -274,11 +276,11 @@ static int gpio_vbus_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 274 | gpio_vbus->phy.otg->phy = &gpio_vbus->phy; | 276 | gpio_vbus->phy.otg->phy = &gpio_vbus->phy; |
| 275 | gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; | 277 | gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; |
| 276 | 278 | ||
| 277 | err = gpio_request(gpio, "vbus_detect"); | 279 | err = devm_gpio_request(&pdev->dev, gpio, "vbus_detect"); |
| 278 | if (err) { | 280 | if (err) { |
| 279 | dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", | 281 | dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", |
| 280 | gpio, err); | 282 | gpio, err); |
| 281 | goto err_gpio; | 283 | return err; |
| 282 | } | 284 | } |
| 283 | gpio_direction_input(gpio); | 285 | gpio_direction_input(gpio); |
| 284 | 286 | ||
| @@ -296,27 +298,27 @@ static int gpio_vbus_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 296 | /* if data line pullup is in use, initialize it to "not pulling up" */ | 298 | /* if data line pullup is in use, initialize it to "not pulling up" */ |
| 297 | gpio = pdata->gpio_pullup; | 299 | gpio = pdata->gpio_pullup; |
| 298 | if (gpio_is_valid(gpio)) { | 300 | if (gpio_is_valid(gpio)) { |
| 299 | err = gpio_request(gpio, "udc_pullup"); | 301 | err = devm_gpio_request(&pdev->dev, gpio, "udc_pullup"); |
| 300 | if (err) { | 302 | if (err) { |
| 301 | dev_err(&pdev->dev, | 303 | dev_err(&pdev->dev, |
| 302 | "can't request pullup gpio %d, err: %d\n", | 304 | "can't request pullup gpio %d, err: %d\n", |
| 303 | gpio, err); | 305 | gpio, err); |
| 304 | gpio_free(pdata->gpio_vbus); | 306 | return err; |
| 305 | goto err_gpio; | ||
| 306 | } | 307 | } |
| 307 | gpio_direction_output(gpio, pdata->gpio_pullup_inverted); | 308 | gpio_direction_output(gpio, pdata->gpio_pullup_inverted); |
| 308 | } | 309 | } |
| 309 | 310 | ||
| 310 | err = request_irq(irq, gpio_vbus_irq, irqflags, "vbus_detect", pdev); | 311 | err = devm_request_irq(&pdev->dev, irq, gpio_vbus_irq, irqflags, |
| 312 | "vbus_detect", pdev); | ||
| 311 | if (err) { | 313 | if (err) { |
| 312 | dev_err(&pdev->dev, "can't request irq %i, err: %d\n", | 314 | dev_err(&pdev->dev, "can't request irq %i, err: %d\n", |
| 313 | irq, err); | 315 | irq, err); |
| 314 | goto err_irq; | 316 | return err; |
| 315 | } | 317 | } |
| 316 | 318 | ||
| 317 | INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work); | 319 | INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work); |
| 318 | 320 | ||
| 319 | gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); | 321 | gpio_vbus->vbus_draw = devm_regulator_get(&pdev->dev, "vbus_draw"); |
| 320 | if (IS_ERR(gpio_vbus->vbus_draw)) { | 322 | if (IS_ERR(gpio_vbus->vbus_draw)) { |
| 321 | dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", | 323 | dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", |
| 322 | PTR_ERR(gpio_vbus->vbus_draw)); | 324 | PTR_ERR(gpio_vbus->vbus_draw)); |
| @@ -328,44 +330,23 @@ static int gpio_vbus_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 328 | if (err) { | 330 | if (err) { |
| 329 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", | 331 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", |
| 330 | err); | 332 | err); |
| 331 | goto err_otg; | 333 | return err; |
| 332 | } | 334 | } |
| 333 | 335 | ||
| 334 | device_init_wakeup(&pdev->dev, pdata->wakeup); | 336 | device_init_wakeup(&pdev->dev, pdata->wakeup); |
| 335 | 337 | ||
| 336 | return 0; | 338 | return 0; |
| 337 | err_otg: | ||
| 338 | regulator_put(gpio_vbus->vbus_draw); | ||
| 339 | free_irq(irq, pdev); | ||
| 340 | err_irq: | ||
| 341 | if (gpio_is_valid(pdata->gpio_pullup)) | ||
| 342 | gpio_free(pdata->gpio_pullup); | ||
| 343 | gpio_free(pdata->gpio_vbus); | ||
| 344 | err_gpio: | ||
| 345 | kfree(gpio_vbus->phy.otg); | ||
| 346 | kfree(gpio_vbus); | ||
| 347 | return err; | ||
| 348 | } | 339 | } |
| 349 | 340 | ||
| 350 | static int gpio_vbus_remove(struct platform_device *pdev) | 341 | static int gpio_vbus_remove(struct platform_device *pdev) |
| 351 | { | 342 | { |
| 352 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); | 343 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); |
| 353 | struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev); | ||
| 354 | int gpio = pdata->gpio_vbus; | ||
| 355 | 344 | ||
| 356 | device_init_wakeup(&pdev->dev, 0); | 345 | device_init_wakeup(&pdev->dev, 0); |
| 357 | cancel_delayed_work_sync(&gpio_vbus->work); | 346 | cancel_delayed_work_sync(&gpio_vbus->work); |
| 358 | regulator_put(gpio_vbus->vbus_draw); | ||
| 359 | 347 | ||
| 360 | usb_remove_phy(&gpio_vbus->phy); | 348 | usb_remove_phy(&gpio_vbus->phy); |
| 361 | 349 | ||
| 362 | free_irq(gpio_vbus->irq, pdev); | ||
| 363 | if (gpio_is_valid(pdata->gpio_pullup)) | ||
| 364 | gpio_free(pdata->gpio_pullup); | ||
| 365 | gpio_free(gpio); | ||
| 366 | kfree(gpio_vbus->phy.otg); | ||
| 367 | kfree(gpio_vbus); | ||
| 368 | |||
| 369 | return 0; | 350 | return 0; |
| 370 | } | 351 | } |
| 371 | 352 | ||
| @@ -279,11 +279,11 @@ static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) · 278 unmodified lines | |||
| 279 | 279 | ||
| 280 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) | 280 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) |
| 281 | { | 281 | { |
| 282 | int ret; | 282 | int ret = 0; |
| 283 | 283 | ||
| 284 | if (motg->pdata->phy_clk_reset) | 284 | if (motg->pdata->phy_clk_reset && motg->phy_reset_clk) |
| 285 | ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); | 285 | ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); |
| 286 | else | 286 | else if (motg->phy_rst) |
| 287 | ret = reset_control_reset(motg->phy_rst); | 287 | ret = reset_control_reset(motg->phy_rst); |
| 288 | 288 | ||
| 289 | if (ret) | 289 | if (ret) |
| @@ -1429,7 +1429,7 @@ static void msm_otg_debugfs_cleanup(void) · 1139 unmodified lines | |||
| 1429 | debugfs_remove(msm_otg_dbg_root); | 1429 | debugfs_remove(msm_otg_dbg_root); |
| 1430 | } | 1430 | } |
| 1431 | 1431 | ||
| 1432 | static struct of_device_id msm_otg_dt_match[] = { | 1432 | static const struct of_device_id msm_otg_dt_match[] = { |
| 1433 | { | 1433 | { |
| 1434 | .compatible = "qcom,usb-otg-ci", | 1434 | .compatible = "qcom,usb-otg-ci", |
| 1435 | .data = (void *) CI_45NM_INTEGRATED_PHY | 1435 | .data = (void *) CI_45NM_INTEGRATED_PHY |
| @@ -1466,7 +1466,7 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) · 30 unmodified lines | |||
| 1466 | 1466 | ||
| 1467 | motg->phy_rst = devm_reset_control_get(&pdev->dev, "phy"); | 1467 | motg->phy_rst = devm_reset_control_get(&pdev->dev, "phy"); |
| 1468 | if (IS_ERR(motg->phy_rst)) | 1468 | if (IS_ERR(motg->phy_rst)) |
| 1469 | return PTR_ERR(motg->phy_rst); | 1469 | motg->phy_rst = NULL; |
| 1470 | 1470 | ||
| 1471 | pdata->mode = of_usb_get_dr_mode(node); | 1471 | pdata->mode = of_usb_get_dr_mode(node); |
| 1472 | if (pdata->mode == USB_DR_MODE_UNKNOWN) | 1472 | if (pdata->mode == USB_DR_MODE_UNKNOWN) |
| @@ -1558,7 +1558,7 @@ static int msm_otg_probe(struct platform_device *pdev) · 85 unmodified lines | |||
| 1558 | np ? "phy" : "usb_phy_clk"); | 1558 | np ? "phy" : "usb_phy_clk"); |
| 1559 | if (IS_ERR(motg->phy_reset_clk)) { | 1559 | if (IS_ERR(motg->phy_reset_clk)) { |
| 1560 | dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); | 1560 | dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); |
| 1561 | return PTR_ERR(motg->phy_reset_clk); | 1561 | motg->phy_reset_clk = NULL; |
| 1562 | } | 1562 | } |
| 1563 | 1563 | ||
| 1564 | motg->clk = devm_clk_get(&pdev->dev, np ? "core" : "usb_hs_clk"); | 1564 | motg->clk = devm_clk_get(&pdev->dev, np ? "core" : "usb_hs_clk"); |
| @@ -962,7 +962,7 @@ static const struct tegra_phy_soc_config tegra30_soc_config = { · 961 unmodified lines | |||
| 962 | .requires_extra_tuning_parameters = true, | 962 | .requires_extra_tuning_parameters = true, |
| 963 | }; | 963 | }; |
| 964 | 964 | ||
| 965 | static struct of_device_id tegra_usb_phy_id_table[] = { | 965 | static const struct of_device_id tegra_usb_phy_id_table[] = { |
| 966 | { .compatible = "nvidia,tegra30-usb-phy", .data = &tegra30_soc_config }, | 966 | { .compatible = "nvidia,tegra30-usb-phy", .data = &tegra30_soc_config }, |
| 967 | { .compatible = "nvidia,tegra20-usb-phy", .data = &tegra20_soc_config }, | 967 | { .compatible = "nvidia,tegra20-usb-phy", .data = &tegra20_soc_config }, |
| 968 | { }, | 968 | { }, |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o | 5 | obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o |
| 6 | 6 | ||
| 7 | renesas_usbhs-y := common.o mod.o pipe.o fifo.o | 7 | renesas_usbhs-y := common.o mod.o pipe.o fifo.o rcar2.o |
| 8 | 8 | ||
| 9 | ifneq ($(CONFIG_USB_RENESAS_USBHS_HCD),) | 9 | ifneq ($(CONFIG_USB_RENESAS_USBHS_HCD),) |
| 10 | renesas_usbhs-y += mod_host.o | 10 | renesas_usbhs-y += mod_host.o |
| @@ -15,12 +15,14 @@ · 14 unmodified lines | |||
| 15 | * | 15 | * |
| 16 | */ | 16 | */ |
| 17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
| 18 | #include <linux/gpio.h> | ||
| 18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
| 19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 20 | #include <linux/pm_runtime.h> | 21 | #include <linux/pm_runtime.h> |
| 21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 22 | #include <linux/sysfs.h> | 23 | #include <linux/sysfs.h> |
| 23 | #include "common.h" | 24 | #include "common.h" |
| 25 | #include "rcar2.h" | ||
| 24 | 26 | ||
| 25 | /* | 27 | /* |
| 26 | * image of renesas_usbhs | 28 | * image of renesas_usbhs |
| @@ -284,6 +286,8 @@ static void usbhsc_set_buswait(struct usbhs_priv *priv) · 257 unmodified lines | |||
| 284 | /* | 286 | /* |
| 285 | * platform default param | 287 | * platform default param |
| 286 | */ | 288 | */ |
| 289 | |||
| 290 | /* commonly used on old SH-Mobile SoCs */ | ||
| 287 | static u32 usbhsc_default_pipe_type[] = { | 291 | static u32 usbhsc_default_pipe_type[] = { |
| 288 | USB_ENDPOINT_XFER_CONTROL, | 292 | USB_ENDPOINT_XFER_CONTROL, |
| 289 | USB_ENDPOINT_XFER_ISOC, | 293 | USB_ENDPOINT_XFER_ISOC, |
| @@ -297,6 +301,26 @@ static u32 usbhsc_default_pipe_type[] = { · 7 unmodified lines | |||
| 297 | USB_ENDPOINT_XFER_INT, | 301 | USB_ENDPOINT_XFER_INT, |
| 298 | }; | 302 | }; |
| 299 | 303 | ||
| 304 | /* commonly used on newer SH-Mobile and R-Car SoCs */ | ||
| 305 | static u32 usbhsc_new_pipe_type[] = { | ||
| 306 | USB_ENDPOINT_XFER_CONTROL, | ||
| 307 | USB_ENDPOINT_XFER_ISOC, | ||
| 308 | USB_ENDPOINT_XFER_ISOC, | ||
| 309 | USB_ENDPOINT_XFER_BULK, | ||
| 310 | USB_ENDPOINT_XFER_BULK, | ||
| 311 | USB_ENDPOINT_XFER_BULK, | ||
| 312 | USB_ENDPOINT_XFER_INT, | ||
| 313 | USB_ENDPOINT_XFER_INT, | ||
| 314 | USB_ENDPOINT_XFER_INT, | ||
| 315 | USB_ENDPOINT_XFER_BULK, | ||
| 316 | USB_ENDPOINT_XFER_BULK, | ||
| 317 | USB_ENDPOINT_XFER_BULK, | ||
| 318 | USB_ENDPOINT_XFER_BULK, | ||
| 319 | USB_ENDPOINT_XFER_BULK, | ||
| 320 | USB_ENDPOINT_XFER_BULK, | ||
| 321 | USB_ENDPOINT_XFER_BULK, | ||
| 322 | }; | ||
| 323 | |||
| 300 | /* | 324 | /* |
| 301 | * power control | 325 | * power control |
| 302 | */ | 326 | */ |
| @@ -423,8 +447,7 @@ static int usbhs_probe(struct platform_device *pdev) · 120 unmodified lines | |||
| 423 | int ret; | 447 | int ret; |
| 424 | 448 | ||
| 425 | /* check platform information */ | 449 | /* check platform information */ |
| 426 | if (!info || | 450 | if (!info) { |
| 427 | !info->platform_callback.get_id) { | ||
| 428 | dev_err(&pdev->dev, "no platform information\n"); | 451 | dev_err(&pdev->dev, "no platform information\n"); |
| 429 | return -EINVAL; | 452 | return -EINVAL; |
| 430 | } | 453 | } |
| @@ -451,13 +474,32 @@ static int usbhs_probe(struct platform_device *pdev) · 20 unmodified lines | |||
| 451 | /* | 474 | /* |
| 452 | * care platform info | 475 | * care platform info |
| 453 | */ | 476 | */ |
| 454 | memcpy(&priv->pfunc, | 477 | |
| 455 | &info->platform_callback, | ||
| 456 | sizeof(struct renesas_usbhs_platform_callback)); | ||
| 457 | memcpy(&priv->dparam, | 478 | memcpy(&priv->dparam, |
| 458 | &info->driver_param, | 479 | &info->driver_param, |
| 459 | sizeof(struct renesas_usbhs_driver_param)); | 480 | sizeof(struct renesas_usbhs_driver_param)); |
| 460 | 481 | ||
| 482 | switch (priv->dparam.type) { | ||
| 483 | case USBHS_TYPE_R8A7790: | ||
| 484 | case USBHS_TYPE_R8A7791: | ||
| 485 | priv->pfunc = usbhs_rcar2_ops; | ||
| 486 | if (!priv->dparam.pipe_type) { | ||
| 487 | priv->dparam.pipe_type = usbhsc_new_pipe_type; | ||
| 488 | priv->dparam.pipe_size = | ||
| 489 | ARRAY_SIZE(usbhsc_new_pipe_type); | ||
| 490 | } | ||
| 491 | break; | ||
| 492 | default: | ||
| 493 | if (!info->platform_callback.get_id) { | ||
| 494 | dev_err(&pdev->dev, "no platform callbacks"); | ||
| 495 | return -EINVAL; | ||
| 496 | } | ||
| 497 | memcpy(&priv->pfunc, | ||
| 498 | &info->platform_callback, | ||
| 499 | sizeof(struct renesas_usbhs_platform_callback)); | ||
| 500 | break; | ||
| 501 | } | ||
| 502 | |||
| 461 | /* set driver callback functions for platform */ | 503 | /* set driver callback functions for platform */ |
| 462 | dfunc = &info->driver_callback; | 504 | dfunc = &info->driver_callback; |
| 463 | dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug; | 505 | dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug; |
| @@ -507,6 +549,20 @@ static int usbhs_probe(struct platform_device *pdev) · 43 unmodified lines | |||
| 507 | */ | 549 | */ |
| 508 | usbhs_sys_clock_ctrl(priv, 0); | 550 | usbhs_sys_clock_ctrl(priv, 0); |
| 509 | 551 | ||
| 552 | /* check GPIO determining if USB function should be enabled */ | ||
| 553 | if (priv->dparam.enable_gpio) { | ||
| 554 | gpio_request_one(priv->dparam.enable_gpio, GPIOF_IN, NULL); | ||
| 555 | ret = !gpio_get_value(priv->dparam.enable_gpio); | ||
| 556 | gpio_free(priv->dparam.enable_gpio); | ||
| 557 | if (ret) { | ||
| 558 | dev_warn(&pdev->dev, | ||
| 559 | "USB function not selected (GPIO %d)\n", | ||
| 560 | priv->dparam.enable_gpio); | ||
| 561 | ret = -ENOTSUPP; | ||
| 562 | goto probe_end_mod_exit; | ||
| 563 | } | ||
| 564 | } | ||
| 565 | |||
| 510 | /* | 566 | /* |
| 511 | * platform call | 567 | * platform call |
| 512 | * | 568 | * |
| @@ -268,6 +268,8 @@ struct usbhs_priv { · 267 unmodified lines | |||
| 268 | * fifo control | 268 | * fifo control |
| 269 | */ | 269 | */ |
| 270 | struct usbhs_fifo_info fifo_info; | 270 | struct usbhs_fifo_info fifo_info; |
| 271 | |||
| 272 | struct usb_phy *phy; | ||
| 271 | }; | 273 | }; |
| 272 | 274 | ||
| 273 | /* | 275 | /* |
| @@ -600,8 +600,10 @@ static int usbhsg_ep_enable(struct usb_ep *ep, · 599 unmodified lines | |||
| 600 | static int usbhsg_ep_disable(struct usb_ep *ep) | 600 | static int usbhsg_ep_disable(struct usb_ep *ep) |
| 601 | { | 601 | { |
| 602 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); | 602 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); |
| 603 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
| 603 | 604 | ||
| 604 | usbhsg_pipe_disable(uep); | 605 | usbhsg_pipe_disable(uep); |
| 606 | usbhs_pipe_free(pipe); | ||
| 605 | 607 | ||
| 606 | uep->pipe->mod_private = NULL; | 608 | uep->pipe->mod_private = NULL; |
| 607 | uep->pipe = NULL; | 609 | uep->pipe = NULL; |
| @@ -640,6 +640,11 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type) · 639 unmodified lines | |||
| 640 | return pipe; | 640 | return pipe; |
| 641 | } | 641 | } |
| 642 | 642 | ||
| 643 | static void usbhsp_put_pipe(struct usbhs_pipe *pipe) | ||
| 644 | { | ||
| 645 | usbhsp_flags_init(pipe); | ||
| 646 | } | ||
| 647 | |||
| 643 | void usbhs_pipe_init(struct usbhs_priv *priv, | 648 | void usbhs_pipe_init(struct usbhs_priv *priv, |
| 644 | int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map)) | 649 | int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map)) |
| 645 | { | 650 | { |
| @@ -710,6 +715,7 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, · 64 unmodified lines | |||
| 710 | usbhsp_pipe_select(pipe); | 715 | usbhsp_pipe_select(pipe); |
| 711 | usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg); | 716 | usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg); |
| 712 | usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf); | 717 | usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf); |
| 718 | usbhs_pipe_clear(pipe); | ||
| 713 | 719 | ||
| 714 | usbhs_pipe_sequence_data0(pipe); | 720 | usbhs_pipe_sequence_data0(pipe); |
| 715 | 721 | ||
| @@ -726,6 +732,11 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, · 10 unmodified lines | |||
| 726 | return pipe; | 732 | return pipe; |
| 727 | } | 733 | } |
| 728 | 734 | ||
| 735 | void usbhs_pipe_free(struct usbhs_pipe *pipe) | ||
| 736 | { | ||
| 737 | usbhsp_put_pipe(pipe); | ||
| 738 | } | ||
| 739 | |||
| 729 | void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo) | 740 | void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo) |
| 730 | { | 741 | { |
| 731 | if (pipe->fifo) | 742 | if (pipe->fifo) |
| @@ -75,6 +75,7 @@ struct usbhs_pipe_info { · 74 unmodified lines | |||
| 75 | char *usbhs_pipe_name(struct usbhs_pipe *pipe); | 75 | char *usbhs_pipe_name(struct usbhs_pipe *pipe); |
| 76 | struct usbhs_pipe | 76 | struct usbhs_pipe |
| 77 | *usbhs_pipe_malloc(struct usbhs_priv *priv, int endpoint_type, int dir_in); | 77 | *usbhs_pipe_malloc(struct usbhs_priv *priv, int endpoint_type, int dir_in); |
| 78 | void usbhs_pipe_free(struct usbhs_pipe *pipe); | ||
| 78 | int usbhs_pipe_probe(struct usbhs_priv *priv); | 79 | int usbhs_pipe_probe(struct usbhs_priv *priv); |
| 79 | void usbhs_pipe_remove(struct usbhs_priv *priv); | 80 | void usbhs_pipe_remove(struct usbhs_priv *priv); |
| 80 | int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); | 81 | int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); |
| @@ -0,0 +1,77 @@ | |||
| 1 | /* | ||
| 2 | * Renesas USB driver R-Car Gen. 2 initialization and power control | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Ulrich Hecht | ||
| 5 | * | ||
| 6 | * This program is distributed in the hope that it will be useful, | ||
| 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 9 | * GNU General Public License for more details. | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/gpio.h> | ||
| 14 | #include <linux/of_gpio.h> | ||
| 15 | #include <linux/platform_data/gpio-rcar.h> | ||
| 16 | #include <linux/usb/phy.h> | ||
| 17 | #include "common.h" | ||
| 18 | #include "rcar2.h" | ||
| 19 | |||
| 20 | static int usbhs_rcar2_hardware_init(struct platform_device *pdev) | ||
| 21 | { | ||
| 22 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); | ||
| 23 | struct usb_phy *phy; | ||
| 24 | |||
| 25 | phy = usb_get_phy_dev(&pdev->dev, 0); | ||
| 26 | if (IS_ERR(phy)) | ||
| 27 | return PTR_ERR(phy); | ||
| 28 | |||
| 29 | priv->phy = phy; | ||
| 30 | return 0; | ||
| 31 | } | ||
| 32 | |||
| 33 | static int usbhs_rcar2_hardware_exit(struct platform_device *pdev) | ||
| 34 | { | ||
| 35 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); | ||
| 36 | |||
| 37 | if (!priv->phy) | ||
| 38 | return 0; | ||
| 39 | |||
| 40 | usb_put_phy(priv->phy); | ||
| 41 | priv->phy = NULL; | ||
| 42 | |||
| 43 | return 0; | ||
| 44 | } | ||
| 45 | |||
| 46 | static int usbhs_rcar2_power_ctrl(struct platform_device *pdev, | ||
| 47 | void __iomem *base, int enable) | ||
| 48 | { | ||
| 49 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); | ||
| 50 | |||
| 51 | if (!priv->phy) | ||
| 52 | return -ENODEV; | ||
| 53 | |||
| 54 | if (enable) { | ||
| 55 | int retval = usb_phy_init(priv->phy); | ||
| 56 | |||
| 57 | if (!retval) | ||
| 58 | retval = usb_phy_set_suspend(priv->phy, 0); | ||
| 59 | return retval; | ||
| 60 | } | ||
| 61 | |||
| 62 | usb_phy_set_suspend(priv->phy, 1); | ||
| 63 | usb_phy_shutdown(priv->phy); | ||
| 64 | return 0; | ||
| 65 | } | ||
| 66 | |||
| 67 | static int usbhs_rcar2_get_id(struct platform_device *pdev) | ||
| 68 | { | ||
| 69 | return USBHS_GADGET; | ||
| 70 | } | ||
| 71 | |||
| 72 | const struct renesas_usbhs_platform_callback usbhs_rcar2_ops = { | ||
| 73 | .hardware_init = usbhs_rcar2_hardware_init, | ||
| 74 | .hardware_exit = usbhs_rcar2_hardware_exit, | ||
| 75 | .power_ctrl = usbhs_rcar2_power_ctrl, | ||
| 76 | .get_id = usbhs_rcar2_get_id, | ||
| 77 | }; | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | extern const struct renesas_usbhs_platform_callback | ||
| 4 | usbhs_rcar2_ops; | ||
| @@ -386,6 +386,21 @@ struct usb_composite_driver { · 385 unmodified lines | |||
| 386 | 386 | ||
| 387 | extern int usb_composite_probe(struct usb_composite_driver *driver); | 387 | extern int usb_composite_probe(struct usb_composite_driver *driver); |
| 388 | extern void usb_composite_unregister(struct usb_composite_driver *driver); | 388 | extern void usb_composite_unregister(struct usb_composite_driver *driver); |
| 389 | |||
| 390 | /** | ||
| 391 | * module_usb_composite_driver() - Helper macro for registering a USB gadget | ||
| 392 | * composite driver | ||
| 393 | * @__usb_composite_driver: usb_composite_driver struct | ||
| 394 | * | ||
| 395 | * Helper macro for USB gadget composite drivers which do not do anything | ||
| 396 | * special in module init/exit. This eliminates a lot of boilerplate. Each | ||
| 397 | * module may only use this macro once, and calling it replaces module_init() | ||
| 398 | * and module_exit() | ||
| 399 | */ | ||
| 400 | #define module_usb_composite_driver(__usb_composite_driver) \ | ||
| 401 | module_driver(__usb_composite_driver, usb_composite_probe, \ | ||
| 402 | usb_composite_unregister) | ||
| 403 | |||
| 389 | extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); | 404 | extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); |
| 390 | extern int composite_dev_prepare(struct usb_composite_driver *composite, | 405 | extern int composite_dev_prepare(struct usb_composite_driver *composite, |
| 391 | struct usb_composite_dev *cdev); | 406 | struct usb_composite_dev *cdev); |
| @@ -153,6 +153,9 @@ struct renesas_usbhs_driver_param { · 152 unmodified lines | |||
| 153 | */ | 153 | */ |
| 154 | int pio_dma_border; /* default is 64byte */ | 154 | int pio_dma_border; /* default is 64byte */ |
| 155 | 155 | ||
| 156 | u32 type; | ||
| 157 | u32 enable_gpio; | ||
| 158 | |||
| 156 | /* | 159 | /* |
| 157 | * option: | 160 | * option: |
| 158 | */ | 161 | */ |
| @@ -160,6 +163,9 @@ struct renesas_usbhs_driver_param { · 1 unmodified line | |||
| 160 | u32 has_sudmac:1; /* for SUDMAC */ | 163 | u32 has_sudmac:1; /* for SUDMAC */ |
| 161 | }; | 164 | }; |
| 162 | 165 | ||
| 166 | #define USBHS_TYPE_R8A7790 1 | ||
| 167 | #define USBHS_TYPE_R8A7791 2 | ||
| 168 | |||
| 163 | /* | 169 | /* |
| 164 | * option: | 170 | * option: |
| 165 | * | 171 | * |
| @@ -0,0 +1,199 @@ | |||
| 1 | /* | ||
| 2 | * USB 338x super/high/full speed USB device controller. | ||
| 3 | * Unlike many such controllers, this one talks PCI. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) | ||
| 6 | * Copyright (C) 2003 David Brownell | ||
| 7 | * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __LINUX_USB_USB338X_H | ||
| 22 | #define __LINUX_USB_USB338X_H | ||
| 23 | |||
| 24 | #include <linux/usb/net2280.h> | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Extra defined bits for net2280 registers | ||
| 28 | */ | ||
| 29 | #define SCRATCH 0x0b | ||
| 30 | |||
| 31 | #define DEFECT7374_FSM_FIELD 28 | ||
| 32 | #define SUPER_SPEED 8 | ||
| 33 | #define DMA_REQUEST_OUTSTANDING 5 | ||
| 34 | #define DMA_PAUSE_DONE_INTERRUPT 26 | ||
| 35 | #define SET_ISOCHRONOUS_DELAY 24 | ||
| 36 | #define SET_SEL 22 | ||
| 37 | #define SUPER_SPEED_MODE 8 | ||
| 38 | |||
| 39 | /*ep_cfg*/ | ||
| 40 | #define MAX_BURST_SIZE 24 | ||
| 41 | #define EP_FIFO_BYTE_COUNT 16 | ||
| 42 | #define IN_ENDPOINT_ENABLE 14 | ||
| 43 | #define IN_ENDPOINT_TYPE 12 | ||
| 44 | #define OUT_ENDPOINT_ENABLE 10 | ||
| 45 | #define OUT_ENDPOINT_TYPE 8 | ||
| 46 | |||
| 47 | struct usb338x_usb_ext_regs { | ||
| 48 | u32 usbclass; | ||
| 49 | #define DEVICE_PROTOCOL 16 | ||
| 50 | #define DEVICE_SUB_CLASS 8 | ||
| 51 | #define DEVICE_CLASS 0 | ||
| 52 | u32 ss_sel; | ||
| 53 | #define U2_SYSTEM_EXIT_LATENCY 8 | ||
| 54 | #define U1_SYSTEM_EXIT_LATENCY 0 | ||
| 55 | u32 ss_del; | ||
| 56 | #define U2_DEVICE_EXIT_LATENCY 8 | ||
| 57 | #define U1_DEVICE_EXIT_LATENCY 0 | ||
| 58 | u32 usb2lpm; | ||
| 59 | #define USB_L1_LPM_HIRD 2 | ||
| 60 | #define USB_L1_LPM_REMOTE_WAKE 1 | ||
| 61 | #define USB_L1_LPM_SUPPORT 0 | ||
| 62 | u32 usb3belt; | ||
| 63 | #define BELT_MULTIPLIER 10 | ||
| 64 | #define BEST_EFFORT_LATENCY_TOLERANCE 0 | ||
| 65 | u32 usbctl2; | ||
| 66 | #define LTM_ENABLE 7 | ||
| 67 | #define U2_ENABLE 6 | ||
| 68 | #define U1_ENABLE 5 | ||
| 69 | #define FUNCTION_SUSPEND 4 | ||
| 70 | #define USB3_CORE_ENABLE 3 | ||
| 71 | #define USB2_CORE_ENABLE 2 | ||
| 72 | #define SERIAL_NUMBER_STRING_ENABLE 0 | ||
| 73 | u32 in_timeout; | ||
| 74 | #define GPEP3_TIMEOUT 19 | ||
| 75 | #define GPEP2_TIMEOUT 18 | ||
| 76 | #define GPEP1_TIMEOUT 17 | ||
| 77 | #define GPEP0_TIMEOUT 16 | ||
| 78 | #define GPEP3_TIMEOUT_VALUE 13 | ||
| 79 | #define GPEP3_TIMEOUT_ENABLE 12 | ||
| 80 | #define GPEP2_TIMEOUT_VALUE 9 | ||
| 81 | #define GPEP2_TIMEOUT_ENABLE 8 | ||
| 82 | #define GPEP1_TIMEOUT_VALUE 5 | ||
| 83 | #define GPEP1_TIMEOUT_ENABLE 4 | ||
| 84 | #define GPEP0_TIMEOUT_VALUE 1 | ||
| 85 | #define GPEP0_TIMEOUT_ENABLE 0 | ||
| 86 | u32 isodelay; | ||
| 87 | #define ISOCHRONOUS_DELAY 0 | ||
| 88 | } __packed; | ||
| 89 | |||
| 90 | struct usb338x_fifo_regs { | ||
| 91 | /* offset 0x0500, 0x0520, 0x0540, 0x0560, 0x0580 */ | ||
| 92 | u32 ep_fifo_size_base; | ||
| 93 | #define IN_FIFO_BASE_ADDRESS 22 | ||
| 94 | #define IN_FIFO_SIZE 16 | ||
| 95 | #define OUT_FIFO_BASE_ADDRESS 6 | ||
| 96 | #define OUT_FIFO_SIZE 0 | ||
| 97 | u32 ep_fifo_out_wrptr; | ||
| 98 | u32 ep_fifo_out_rdptr; | ||
| 99 | u32 ep_fifo_in_wrptr; | ||
| 100 | u32 ep_fifo_in_rdptr; | ||
| 101 | u32 unused[3]; | ||
| 102 | } __packed; | ||
| 103 | |||
| 104 | |||
| 105 | /* Link layer */ | ||
| 106 | struct usb338x_ll_regs { | ||
| 107 | /* offset 0x700 */ | ||
| 108 | u32 ll_ltssm_ctrl1; | ||
| 109 | u32 ll_ltssm_ctrl2; | ||
| 110 | u32 ll_ltssm_ctrl3; | ||
| 111 | u32 unused[2]; | ||
| 112 | u32 ll_general_ctrl0; | ||
| 113 | u32 ll_general_ctrl1; | ||
| 114 | #define PM_U3_AUTO_EXIT 29 | ||
| 115 | #define PM_U2_AUTO_EXIT 28 | ||
| 116 | #define PM_U1_AUTO_EXIT 27 | ||
| 117 | #define PM_FORCE_U2_ENTRY 26 | ||
| 118 | #define PM_FORCE_U1_ENTRY 25 | ||
| 119 | #define PM_LGO_COLLISION_SEND_LAU 24 | ||
| 120 | #define PM_DIR_LINK_REJECT 23 | ||
| 121 | #define PM_FORCE_LINK_ACCEPT 22 | ||
| 122 | #define PM_DIR_ENTRY_U3 20 | ||
| 123 | #define PM_DIR_ENTRY_U2 19 | ||
| 124 | #define PM_DIR_ENTRY_U1 18 | ||
| 125 | #define PM_U2_ENABLE 17 | ||
| 126 | #define PM_U1_ENABLE 16 | ||
| 127 | #define SKP_THRESHOLD_ADJUST_FMW 8 | ||
| 128 | #define RESEND_DPP_ON_LRTY_FMW 7 | ||
| 129 | #define DL_BIT_VALUE_FMW 6 | ||
| 130 | #define FORCE_DL_BIT 5 | ||
| 131 | u32 ll_general_ctrl2; | ||
| 132 | #define SELECT_INVERT_LANE_POLARITY 7 | ||
| 133 | #define FORCE_INVERT_LANE_POLARITY 6 | ||
| 134 | u32 ll_general_ctrl3; | ||
| 135 | u32 ll_general_ctrl4; | ||
| 136 | u32 ll_error_gen; | ||
| 137 | } __packed; | ||
| 138 | |||
| 139 | struct usb338x_ll_lfps_regs { | ||
| 140 | /* offset 0x748 */ | ||
| 141 | u32 ll_lfps_5; | ||
| 142 | #define TIMER_LFPS_6US 16 | ||
| 143 | u32 ll_lfps_6; | ||
| 144 | #define TIMER_LFPS_80US 0 | ||
| 145 | } __packed; | ||
| 146 | |||
| 147 | struct usb338x_ll_tsn_regs { | ||
| 148 | /* offset 0x77C */ | ||
| 149 | u32 ll_tsn_counters_2; | ||
| 150 | #define HOT_TX_NORESET_TS2 24 | ||
| 151 | u32 ll_tsn_counters_3; | ||
| 152 | #define HOT_RX_RESET_TS2 0 | ||
| 153 | } __packed; | ||
| 154 | |||
| 155 | struct usb338x_ll_chi_regs { | ||
| 156 | /* offset 0x79C */ | ||
| 157 | u32 ll_tsn_chicken_bit; | ||
| 158 | #define RECOVERY_IDLE_TO_RECOVER_FMW 3 | ||
| 159 | } __packed; | ||
| 160 | |||
| 161 | /* protocol layer */ | ||
| 162 | struct usb338x_pl_regs { | ||
| 163 | /* offset 0x800 */ | ||
| 164 | u32 pl_reg_1; | ||
| 165 | u32 pl_reg_2; | ||
| 166 | u32 pl_reg_3; | ||
| 167 | u32 pl_reg_4; | ||
| 168 | u32 pl_ep_ctrl; | ||
| 169 | /* Protocol Layer Endpoint Control*/ | ||
| 170 | #define PL_EP_CTRL 0x810 | ||
| 171 | #define ENDPOINT_SELECT 0 | ||
| 172 | /* [4:0] */ | ||
| 173 | #define EP_INITIALIZED 16 | ||
| 174 | #define SEQUENCE_NUMBER_RESET 17 | ||
| 175 | #define CLEAR_ACK_ERROR_CODE 20 | ||
| 176 | u32 pl_reg_6; | ||
| 177 | u32 pl_reg_7; | ||
| 178 | u32 pl_reg_8; | ||
| 179 | u32 pl_ep_status_1; | ||
| 180 | /* Protocol Layer Endpoint Status 1*/ | ||
| 181 | #define PL_EP_STATUS_1 0x820 | ||
| 182 | #define STATE 16 | ||
| 183 | #define ACK_GOOD_NORMAL 0x11 | ||
| 184 | #define ACK_GOOD_MORE_ACKS_TO_COME 0x16 | ||
| 185 | u32 pl_ep_status_2; | ||
| 186 | u32 pl_ep_status_3; | ||
| 187 | /* Protocol Layer Endpoint Status 3*/ | ||
| 188 | #define PL_EP_STATUS_3 0x828 | ||
| 189 | #define SEQUENCE_NUMBER 0 | ||
| 190 | u32 pl_ep_status_4; | ||
| 191 | /* Protocol Layer Endpoint Status 4*/ | ||
| 192 | #define PL_EP_STATUS_4 0x82c | ||
| 193 | u32 pl_ep_cfg_4; | ||
| 194 | /* Protocol Layer Endpoint Configuration 4*/ | ||
| 195 | #define PL_EP_CFG_4 0x830 | ||
| 196 | #define NON_CTRL_IN_TOLERATE_BAD_DIR 6 | ||
| 197 | } __packed; | ||
| 198 | |||
| 199 | #endif /* __LINUX_USB_USB338X_H */ | ||
| @@ -18,10 +18,9 @@ enum functionfs_flags { · 17 unmodified lines | |||
| 18 | FUNCTIONFS_HAS_FS_DESC = 1, | 18 | FUNCTIONFS_HAS_FS_DESC = 1, |
| 19 | FUNCTIONFS_HAS_HS_DESC = 2, | 19 | FUNCTIONFS_HAS_HS_DESC = 2, |
| 20 | FUNCTIONFS_HAS_SS_DESC = 4, | 20 | FUNCTIONFS_HAS_SS_DESC = 4, |
| 21 | FUNCTIONFS_HAS_MS_OS_DESC = 8, | ||
| 21 | }; | 22 | }; |
| 22 | 23 | ||
| 23 | #ifndef __KERNEL__ | ||
| 24 | |||
| 25 | /* Descriptor of an non-audio endpoint */ | 24 | /* Descriptor of an non-audio endpoint */ |
| 26 | struct usb_endpoint_descriptor_no_audio { | 25 | struct usb_endpoint_descriptor_no_audio { |
| 27 | __u8 bLength; | 26 | __u8 bLength; |
| @@ -41,6 +40,37 @@ struct usb_functionfs_descs_head { · 13 unmodified lines | |||
| 41 | __le32 hs_count; | 40 | __le32 hs_count; |
| 42 | } __attribute__((packed, deprecated)); | 41 | } __attribute__((packed, deprecated)); |
| 43 | 42 | ||
| 43 | /* MS OS Descriptor header */ | ||
| 44 | struct usb_os_desc_header { | ||
| 45 | __u8 interface; | ||
| 46 | __le32 dwLength; | ||
| 47 | __le16 bcdVersion; | ||
| 48 | __le16 wIndex; | ||
| 49 | union { | ||
| 50 | struct { | ||
| 51 | __u8 bCount; | ||
| 52 | __u8 Reserved; | ||
| 53 | }; | ||
| 54 | __le16 wCount; | ||
| 55 | }; | ||
| 56 | } __attribute__((packed)); | ||
| 57 | |||
| 58 | struct usb_ext_compat_desc { | ||
| 59 | __u8 bFirstInterfaceNumber; | ||
| 60 | __u8 Reserved1; | ||
| 61 | __u8 CompatibleID[8]; | ||
| 62 | __u8 SubCompatibleID[8]; | ||
| 63 | __u8 Reserved2[6]; | ||
| 64 | }; | ||
| 65 | |||
| 66 | struct usb_ext_prop_desc { | ||
| 67 | __le32 dwSize; | ||
| 68 | __le32 dwPropertyDataType; | ||
| 69 | __le16 wPropertyNameLength; | ||
| 70 | } __attribute__((packed)); | ||
| 71 | |||
| 72 | #ifndef __KERNEL__ | ||
| 73 | |||
| 44 | /* | 74 | /* |
| 45 | * Descriptors format: | 75 | * Descriptors format: |
| 46 | * | 76 | * |
| @@ -52,9 +82,11 @@ struct usb_functionfs_descs_head { · 5 unmodified lines | |||
| 52 | * | | fs_count | LE32 | number of full-speed descriptors | | 82 | * | | fs_count | LE32 | number of full-speed descriptors | |
| 53 | * | | hs_count | LE32 | number of high-speed descriptors | | 83 | * | | hs_count | LE32 | number of high-speed descriptors | |
| 54 | * | | ss_count | LE32 | number of super-speed descriptors | | 84 | * | | ss_count | LE32 | number of super-speed descriptors | |
| 85 | * | | os_count | LE32 | number of MS OS descriptors | | ||
| 55 | * | | fs_descrs | Descriptor[] | list of full-speed descriptors | | 86 | * | | fs_descrs | Descriptor[] | list of full-speed descriptors | |
| 56 | * | | hs_descrs | Descriptor[] | list of high-speed descriptors | | 87 | * | | hs_descrs | Descriptor[] | list of high-speed descriptors | |
| 57 | * | | ss_descrs | Descriptor[] | list of super-speed descriptors | | 88 | * | | ss_descrs | Descriptor[] | list of super-speed descriptors | |
| 89 | * | | os_descrs | OSDesc[] | list of MS OS descriptors | | ||
| 58 | * | 90 | * |
| 59 | * Depending on which flags are set, various fields may be missing in the | 91 | * Depending on which flags are set, various fields may be missing in the |
| 60 | * structure. Any flags that are not recognised cause the whole block to be | 92 | * structure. Any flags that are not recognised cause the whole block to be |
| @@ -81,6 +113,52 @@ struct usb_functionfs_descs_head { · 20 unmodified lines | |||
| 81 | * | 0 | bLength | U8 | length of the descriptor | | 113 | * | 0 | bLength | U8 | length of the descriptor | |
| 82 | * | 1 | bDescriptorType | U8 | descriptor type | | 114 | * | 1 | bDescriptorType | U8 | descriptor type | |
| 83 | * | 2 | payload | | descriptor's payload | | 115 | * | 2 | payload | | descriptor's payload | |
| 116 | * | ||
| 117 | * OSDesc[] is an array of valid MS OS Feature Descriptors which have one of | ||
| 118 | * the following formats: | ||
| 119 | * | ||
| 120 | * | off | name | type | description | | ||
| 121 | * |-----+-----------------+------+--------------------------| | ||
| 122 | * | 0 | inteface | U8 | related interface number | | ||
| 123 | * | 1 | dwLength | U32 | length of the descriptor | | ||
| 124 | * | 5 | bcdVersion | U16 | currently supported: 1 | | ||
| 125 | * | 7 | wIndex | U16 | currently supported: 4 | | ||
| 126 | * | 9 | bCount | U8 | number of ext. compat. | | ||
| 127 | * | 10 | Reserved | U8 | 0 | | ||
| 128 | * | 11 | ExtCompat[] | | list of ext. compat. d. | | ||
| 129 | * | ||
| 130 | * | off | name | type | description | | ||
| 131 | * |-----+-----------------+------+--------------------------| | ||
| 132 | * | 0 | inteface | U8 | related interface number | | ||
| 133 | * | 1 | dwLength | U32 | length of the descriptor | | ||
| 134 | * | 5 | bcdVersion | U16 | currently supported: 1 | | ||
| 135 | * | 7 | wIndex | U16 | currently supported: 5 | | ||
| 136 | * | 9 | wCount | U16 | number of ext. compat. | | ||
| 137 | * | 11 | ExtProp[] | | list of ext. prop. d. | | ||
| 138 | * | ||
| 139 | * ExtCompat[] is an array of valid Extended Compatiblity descriptors | ||
| 140 | * which have the following format: | ||
| 141 | * | ||
| 142 | * | off | name | type | description | | ||
| 143 | * |-----+-----------------------+------+-------------------------------------| | ||
| 144 | * | 0 | bFirstInterfaceNumber | U8 | index of the interface or of the 1st| | ||
| 145 | * | | | | interface in an IAD group | | ||
| 146 | * | 1 | Reserved | U8 | 0 | | ||
| 147 | * | 2 | CompatibleID | U8[8]| compatible ID string | | ||
| 148 | * | 10 | SubCompatibleID | U8[8]| subcompatible ID string | | ||
| 149 | * | 18 | Reserved | U8[6]| 0 | | ||
| 150 | * | ||
| 151 | * ExtProp[] is an array of valid Extended Properties descriptors | ||
| 152 | * which have the following format: | ||
| 153 | * | ||
| 154 | * | off | name | type | description | | ||
| 155 | * |-----+-----------------------+------+-------------------------------------| | ||
| 156 | * | 0 | dwSize | U32 | length of the descriptor | | ||
| 157 | * | 4 | dwPropertyDataType | U32 | 1..7 | | ||
| 158 | * | 8 | wPropertyNameLength | U16 | bPropertyName length (NL) | | ||
| 159 | * | 10 | bPropertyName |U8[NL]| name of this property | | ||
| 160 | * |10+NL| dwPropertyDataLength | U32 | bPropertyData length (DL) | | ||
| 161 | * |14+NL| bProperty |U8[DL]| payload of this property | | ||
| 84 | */ | 162 | */ |
| 85 | 163 | ||
| 86 | struct usb_functionfs_strings_head { | 164 | struct usb_functionfs_strings_head { |
| @@ -1,3 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * This is free and unencumbered software released into the public domain. | ||
| 3 | * | ||
| 4 | * Anyone is free to copy, modify, publish, use, compile, sell, or | ||
| 5 | * distribute this software, either in source code form or as a compiled | ||
| 6 | * binary, for any purpose, commercial or non-commercial, and by any | ||
| 7 | * means. | ||
| 8 | * | ||
| 9 | * In jurisdictions that recognize copyright laws, the author or authors | ||
| 10 | * of this software dedicate any and all copyright interest in the | ||
| 11 | * software to the public domain. We make this dedication for the benefit | ||
| 12 | * of the public at large and to the detriment of our heirs and | ||
| 13 | * successors. We intend this dedication to be an overt act of | ||
| 14 | * relinquishment in perpetuity of all present and future rights to this | ||
| 15 | * software under copyright law. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 23 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | * | ||
| 25 | * For more information, please refer to <http://unlicense.org/> | ||
| 26 | */ | ||
| 27 | |||
| 1 | #define _BSD_SOURCE /* for endian.h */ | 28 | #define _BSD_SOURCE /* for endian.h */ |
| 2 | 29 | ||
| 3 | #include <endian.h> | 30 | #include <endian.h> |
| @@ -27,7 +54,9 @@ · 23 unmodified lines | |||
| 27 | /******************** Descriptors and Strings *******************************/ | 54 | /******************** Descriptors and Strings *******************************/ |
| 28 | 55 | ||
| 29 | static const struct { | 56 | static const struct { |
| 30 | struct usb_functionfs_descs_head header; | 57 | struct usb_functionfs_descs_head_v2 header; |
| 58 | __le32 fs_count; | ||
| 59 | __le32 hs_count; | ||
| 31 | struct { | 60 | struct { |
| 32 | struct usb_interface_descriptor intf; | 61 | struct usb_interface_descriptor intf; |
| 33 | struct usb_endpoint_descriptor_no_audio bulk_sink; | 62 | struct usb_endpoint_descriptor_no_audio bulk_sink; |
| @@ -35,11 +64,12 @@ static const struct { · 1 unmodified line | |||
| 35 | } __attribute__ ((__packed__)) fs_descs, hs_descs; | 64 | } __attribute__ ((__packed__)) fs_descs, hs_descs; |
| 36 | } __attribute__ ((__packed__)) descriptors = { | 65 | } __attribute__ ((__packed__)) descriptors = { |
| 37 | .header = { | 66 | .header = { |
| 38 | .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC), | 67 | .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), |
| 68 | .flags = htole32(FUNCTIONFS_HAS_FS_DESC | | ||
| 69 | FUNCTIONFS_HAS_HS_DESC), | ||
| 39 | .length = htole32(sizeof(descriptors)), | 70 | .length = htole32(sizeof(descriptors)), |
| 40 | .fs_count = 3, | ||
| 41 | .hs_count = 3, | ||
| 42 | }, | 71 | }, |
| 72 | .fs_count = htole32(3), | ||
| 43 | .fs_descs = { | 73 | .fs_descs = { |
| 44 | .intf = { | 74 | .intf = { |
| 45 | .bLength = sizeof(descriptors.fs_descs.intf), | 75 | .bLength = sizeof(descriptors.fs_descs.intf), |
| @@ -61,6 +91,7 @@ static const struct { · 15 unmodified lines | |||
| 61 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 91 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 62 | }, | 92 | }, |
| 63 | }, | 93 | }, |
| 94 | .hs_count = htole32(3), | ||
| 64 | .hs_descs = { | 95 | .hs_descs = { |
| 65 | .intf = { | 96 | .intf = { |
| 66 | .bLength = sizeof(descriptors.hs_descs.intf), | 97 | .bLength = sizeof(descriptors.hs_descs.intf), |
| @@ -1,3 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * This is free and unencumbered software released into the public domain. | ||
| 3 | * | ||
| 4 | * Anyone is free to copy, modify, publish, use, compile, sell, or | ||
| 5 | * distribute this software, either in source code form or as a compiled | ||
| 6 | * binary, for any purpose, commercial or non-commercial, and by any | ||
| 7 | * means. | ||
| 8 | * | ||
| 9 | * In jurisdictions that recognize copyright laws, the author or authors | ||
| 10 | * of this software dedicate any and all copyright interest in the | ||
| 11 | * software to the public domain. We make this dedication for the benefit | ||
| 12 | * of the public at large and to the detriment of our heirs and | ||
| 13 | * successors. We intend this dedication to be an overt act of | ||
| 14 | * relinquishment in perpetuity of all present and future rights to this | ||
| 15 | * software under copyright law. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 23 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | * | ||
| 25 | * For more information, please refer to <http://unlicense.org/> | ||
| 26 | */ | ||
| 27 | |||
| 1 | #include <libusb.h> | 28 | #include <libusb.h> |
| 2 | #include <stdio.h> | 29 | #include <stdio.h> |
| 3 | #include <string.h> | 30 | #include <string.h> |
| @@ -1,3 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * This is free and unencumbered software released into the public domain. | ||
| 3 | * | ||
| 4 | * Anyone is free to copy, modify, publish, use, compile, sell, or | ||
| 5 | * distribute this software, either in source code form or as a compiled | ||
| 6 | * binary, for any purpose, commercial or non-commercial, and by any | ||
| 7 | * means. | ||
| 8 | * | ||
| 9 | * In jurisdictions that recognize copyright laws, the author or authors | ||
| 10 | * of this software dedicate any and all copyright interest in the | ||
| 11 | * software to the public domain. We make this dedication for the benefit | ||
| 12 | * of the public at large and to the detriment of our heirs and | ||
| 13 | * successors. We intend this dedication to be an overt act of | ||
| 14 | * relinquishment in perpetuity of all present and future rights to this | ||
| 15 | * software under copyright law. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 23 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | * | ||
| 25 | * For more information, please refer to <http://unlicense.org/> | ||
| 26 | */ | ||
| 27 | |||
| 1 | #define _BSD_SOURCE /* for endian.h */ | 28 | #define _BSD_SOURCE /* for endian.h */ |
| 2 | 29 | ||
| 3 | #include <endian.h> | 30 | #include <endian.h> |
| @@ -25,7 +52,9 @@ · 21 unmodified lines | |||
| 25 | /******************** Descriptors and Strings *******************************/ | 52 | /******************** Descriptors and Strings *******************************/ |
| 26 | 53 | ||
| 27 | static const struct { | 54 | static const struct { |
| 28 | struct usb_functionfs_descs_head header; | 55 | struct usb_functionfs_descs_head_v2 header; |
| 56 | __le32 fs_count; | ||
| 57 | __le32 hs_count; | ||
| 29 | struct { | 58 | struct { |
| 30 | struct usb_interface_descriptor intf; | 59 | struct usb_interface_descriptor intf; |
| 31 | struct usb_endpoint_descriptor_no_audio bulk_sink; | 60 | struct usb_endpoint_descriptor_no_audio bulk_sink; |
| @@ -33,11 +62,12 @@ static const struct { · 1 unmodified line | |||
| 33 | } __attribute__ ((__packed__)) fs_descs, hs_descs; | 62 | } __attribute__ ((__packed__)) fs_descs, hs_descs; |
| 34 | } __attribute__ ((__packed__)) descriptors = { | 63 | } __attribute__ ((__packed__)) descriptors = { |
| 35 | .header = { | 64 | .header = { |
| 36 | .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC), | 65 | .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), |
| 66 | .flags = htole32(FUNCTIONFS_HAS_FS_DESC | | ||
| 67 | FUNCTIONFS_HAS_HS_DESC), | ||
| 37 | .length = htole32(sizeof(descriptors)), | 68 | .length = htole32(sizeof(descriptors)), |
| 38 | .fs_count = 3, | ||
| 39 | .hs_count = 3, | ||
| 40 | }, | 69 | }, |
| 70 | .fs_count = htole32(3), | ||
| 41 | .fs_descs = { | 71 | .fs_descs = { |
| 42 | .intf = { | 72 | .intf = { |
| 43 | .bLength = sizeof(descriptors.fs_descs.intf), | 73 | .bLength = sizeof(descriptors.fs_descs.intf), |
| @@ -59,6 +89,7 @@ static const struct { · 15 unmodified lines | |||
| 59 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 89 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 60 | }, | 90 | }, |
| 61 | }, | 91 | }, |
| 92 | .hs_count = htole32(3), | ||
| 62 | .hs_descs = { | 93 | .hs_descs = { |
| 63 | .intf = { | 94 | .intf = { |
| 64 | .bLength = sizeof(descriptors.hs_descs.intf), | 95 | .bLength = sizeof(descriptors.hs_descs.intf), |
| @@ -1,3 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * This is free and unencumbered software released into the public domain. | ||
| 3 | * | ||
| 4 | * Anyone is free to copy, modify, publish, use, compile, sell, or | ||
| 5 | * distribute this software, either in source code form or as a compiled | ||
| 6 | * binary, for any purpose, commercial or non-commercial, and by any | ||
| 7 | * means. | ||
| 8 | * | ||
| 9 | * In jurisdictions that recognize copyright laws, the author or authors | ||
| 10 | * of this software dedicate any and all copyright interest in the | ||
| 11 | * software to the public domain. We make this dedication for the benefit | ||
| 12 | * of the public at large and to the detriment of our heirs and | ||
| 13 | * successors. We intend this dedication to be an overt act of | ||
| 14 | * relinquishment in perpetuity of all present and future rights to this | ||
| 15 | * software under copyright law. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 23 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | * | ||
| 25 | * For more information, please refer to <http://unlicense.org/> | ||
| 26 | */ | ||
| 27 | |||
| 1 | #include <libusb.h> | 28 | #include <libusb.h> |
| 2 | #include <stdio.h> | 29 | #include <stdio.h> |
| 3 | #include <string.h> | 30 | #include <string.h> |