Skip to content

Commit

Permalink
Merge tag 'gadget-for-v3.4' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/balbi/usb into usb-next

USB: Gadget: changes for 3.4

This merge is rather big. Here's what it contains:

For am5536udc we have just simple coding style fixes. Nothing that has any
potential to cause any issues going forward.

With mv_udc, there's only one single change removing an unneeded NULL check.

at91_udc also only saw a single change this merge window, and that's only
removing a duplicated header.

The Renesas controller has a few more involved changes. Support for SUDMAC was
added, there's now a special handling of IRQ resources for when the IRQ line is
shared between Renesas controller and SUDMAC, we also had a bug fix where
Renesas controller would sleep in atomic context while doing DMA transfers from
a tasklet. There were also a set of minor cleanups.

The FSL UDC also had a scheduling in atomic context bug fix, but that's all.

Thanks to Sebastian, the dummy_hcd now works better than ever with support for
scatterlists and streams. Sebastian also added SuperSpeed descriptors to the
serial gadgets.

The highlight on this merge is the addition of a generic API for mapping and
unmapping usb_requests. This will avoid code duplication on all UDC controllers
and also kills all the defines for DMA_ADDR_INVALID which UDC controllers
sprinkled around. A few of the UDC controllers were already converted to use
this new API.

Conflicts:
	drivers/usb/dwc3/gadget.c
  • Loading branch information
Greg Kroah-Hartman committed Mar 1, 2012
2 parents 8062d94 + 6440093 commit f9b0f51
Show file tree
Hide file tree
Showing 52 changed files with 2,734 additions and 687 deletions.
2 changes: 0 additions & 2 deletions drivers/usb/dwc3/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,6 @@ struct dwc3_request {
* @ctrl_req_addr: dma address of ctrl_req
* @ep0_trb: dma address of ep0_trb
* @ep0_usb_req: dummy req used while handling STD USB requests
* @setup_buf_addr: dma address of setup_buf
* @ep0_bounce_addr: dma address of ep0_bounce
* @lock: for synchronizing
* @dev: pointer to our struct device
Expand Down Expand Up @@ -609,7 +608,6 @@ struct dwc3 {
u8 *setup_buf;
dma_addr_t ctrl_req_addr;
dma_addr_t ep0_trb_addr;
dma_addr_t setup_buf_addr;
dma_addr_t ep0_bounce_addr;
struct dwc3_request ep0_usb_req;
/* device lock */
Expand Down
16 changes: 13 additions & 3 deletions drivers/usb/dwc3/ep0.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
dep = dwc->eps[0];
dwc->ep0_usb_req.dep = dep;
dwc->ep0_usb_req.request.length = sizeof(*response_pkt);
dwc->ep0_usb_req.request.dma = dwc->setup_buf_addr;
dwc->ep0_usb_req.request.buf = dwc->setup_buf;
dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl;

return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
Expand Down Expand Up @@ -679,7 +679,12 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc,
DWC3_TRBCTL_CONTROL_DATA);
} else if ((req->request.length % dep->endpoint.maxpacket)
&& (event->endpoint_number == 0)) {
dwc3_map_buffer_to_dma(req);
ret = usb_gadget_map_request(&dwc->gadget, &req->request,
event->endpoint_number);
if (ret) {
dev_dbg(dwc->dev, "failed to map request\n");
return;
}

WARN_ON(req->request.length > dep->endpoint.maxpacket);

Expand All @@ -694,7 +699,12 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc,
dwc->ep0_bounce_addr, dep->endpoint.maxpacket,
DWC3_TRBCTL_CONTROL_DATA);
} else {
dwc3_map_buffer_to_dma(req);
ret = usb_gadget_map_request(&dwc->gadget, &req->request,
event->endpoint_number);
if (ret) {
dev_dbg(dwc->dev, "failed to map request\n");
return;
}

ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
req->request.dma, req->request.length,
Expand Down
94 changes: 18 additions & 76 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,70 +54,6 @@
#include "gadget.h"
#include "io.h"

#define DMA_ADDR_INVALID (~(dma_addr_t)0)

void dwc3_map_buffer_to_dma(struct dwc3_request *req)
{
struct dwc3 *dwc = req->dep->dwc;

if (req->request.length == 0) {
/* req->request.dma = dwc->setup_buf_addr; */
return;
}

if (req->request.num_sgs) {
int mapped;

mapped = dma_map_sg(dwc->dev, req->request.sg,
req->request.num_sgs,
req->direction ? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
if (mapped < 0) {
dev_err(dwc->dev, "failed to map SGs\n");
return;
}

req->request.num_mapped_sgs = mapped;
return;
}

if (req->request.dma == DMA_ADDR_INVALID) {
req->request.dma = dma_map_single(dwc->dev, req->request.buf,
req->request.length, req->direction
? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->mapped = true;
}
}

void dwc3_unmap_buffer_from_dma(struct dwc3_request *req)
{
struct dwc3 *dwc = req->dep->dwc;

if (req->request.length == 0) {
req->request.dma = DMA_ADDR_INVALID;
return;
}

if (req->request.num_mapped_sgs) {
req->request.dma = DMA_ADDR_INVALID;
dma_unmap_sg(dwc->dev, req->request.sg,
req->request.num_mapped_sgs,
req->direction ? DMA_TO_DEVICE
: DMA_FROM_DEVICE);

req->request.num_mapped_sgs = 0;
return;
}

if (req->mapped) {
dma_unmap_single(dwc->dev, req->request.dma,
req->request.length, req->direction
? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->mapped = 0;
req->request.dma = DMA_ADDR_INVALID;
}
}

void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
int status)
{
Expand All @@ -144,14 +80,15 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
if (req->request.status == -EINPROGRESS)
req->request.status = status;

dwc3_unmap_buffer_from_dma(req);
usb_gadget_unmap_request(&dwc->gadget, &req->request,
req->direction);

dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
req, dep->name, req->request.actual,
req->request.length, status);

spin_unlock(&dwc->lock);
req->request.complete(&req->dep->endpoint, &req->request);
req->request.complete(&dep->endpoint, &req->request);
spin_lock(&dwc->lock);
}

Expand Down Expand Up @@ -440,6 +377,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)

dep->stream_capable = false;
dep->desc = NULL;
dep->endpoint.desc = NULL;
dep->comp_desc = NULL;
dep->type = 0;
dep->flags = 0;
Expand Down Expand Up @@ -562,7 +500,6 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep,

req->epnum = dep->number;
req->dep = dep;
req->request.dma = DMA_ADDR_INVALID;

return &req->request;
}
Expand Down Expand Up @@ -821,7 +758,8 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
* here and stop, unmap, free and del each of the linked
* requests instead of we do now.
*/
dwc3_unmap_buffer_from_dma(req);
usb_gadget_unmap_request(&dwc->gadget, &req->request,
req->direction);
list_del(&req->list);
return ret;
}
Expand All @@ -837,6 +775,9 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,

static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
{
struct dwc3 *dwc = dep->dwc;
int ret;

req->request.actual = 0;
req->request.status = -EINPROGRESS;
req->direction = dep->direction;
Expand All @@ -854,7 +795,11 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
* This will also avoid Host cancelling URBs due to too
* many NACKs.
*/
dwc3_map_buffer_to_dma(req);
ret = usb_gadget_map_request(&dwc->gadget, &req->request,
dep->direction);
if (ret)
return ret;

list_add_tail(&req->list, &dep->request_list);

/*
Expand Down Expand Up @@ -2149,9 +2094,8 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
goto err1;
}

dwc->setup_buf = dma_alloc_coherent(dwc->dev,
sizeof(*dwc->setup_buf) * 2,
&dwc->setup_buf_addr, GFP_KERNEL);
dwc->setup_buf = kzalloc(sizeof(*dwc->setup_buf) * 2,
GFP_KERNEL);
if (!dwc->setup_buf) {
dev_err(dwc->dev, "failed to allocate setup buffer\n");
ret = -ENOMEM;
Expand Down Expand Up @@ -2242,8 +2186,7 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
dwc->ep0_bounce_addr);

err3:
dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
dwc->setup_buf, dwc->setup_buf_addr);
kfree(dwc->setup_buf);

err2:
dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
Expand Down Expand Up @@ -2272,8 +2215,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
dwc->ep0_bounce_addr);

dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
dwc->setup_buf, dwc->setup_buf_addr);
kfree(dwc->setup_buf);

dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
dwc->ep0_trb, dwc->ep0_trb_addr);
Expand Down
2 changes: 0 additions & 2 deletions drivers/usb/dwc3/gadget.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value);
int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);
void dwc3_map_buffer_to_dma(struct dwc3_request *req);
void dwc3_unmap_buffer_from_dma(struct dwc3_request *req);

/**
* dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
Expand Down
25 changes: 19 additions & 6 deletions drivers/usb/gadget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -599,16 +599,29 @@ config USB_AUDIO
depends on SND
select SND_PCM
help
Gadget Audio is compatible with USB Audio Class specification 1.0.
It will include at least one AudioControl interface, zero or more
AudioStream interface and zero or more MIDIStream interface.

Gadget Audio will use on-board ALSA (CONFIG_SND) audio card to
playback or capture audio stream.
This Gadget Audio driver is compatible with USB Audio Class
specification 2.0. It implements 1 AudioControl interface,
1 AudioStreaming Interface each for USB-OUT and USB-IN.
Number of channels, sample rate and sample size can be
specified as module parameters.
This driver doesn't expect any real Audio codec to be present
on the device - the audio streams are simply sinked to and
sourced from a virtual ALSA sound card created. The user-space
application may choose to do whatever it wants with the data
received from the USB Host and choose to provide whatever it
wants as audio data to the USB Host.

Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "g_audio".

config GADGET_UAC1
bool "UAC 1.0 (Legacy)"
depends on USB_AUDIO
help
If you instead want older UAC Spec-1.0 driver that also has audio
paths hardwired to the Audio codec chip on-board and doesn't work
without one.

config USB_ETH
tristate "Ethernet Gadget (with CDC Ethernet support)"
depends on NET
Expand Down
Loading

0 comments on commit f9b0f51

Please sign in to comment.