Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 280897
b: refs/heads/master
c: 3edeee3
h: refs/heads/master
i:
  280895: aeabf0f
v: v3
  • Loading branch information
Kuninori Morimoto authored and Felipe Balbi committed Dec 13, 2011
1 parent 1dfa3a2 commit 1f7ab94
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e5679d07a6ca5512070fb5e65dcc66eeb5087d0d
refs/heads/master: 3edeee3893b107364fe4ed8535245773b1e1e72b
9 changes: 8 additions & 1 deletion trunk/drivers/usb/renesas_usbhs/fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ static struct usbhs_pkt_handle usbhsf_null_handler = {
void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
void (*done)(struct usbhs_priv *priv,
struct usbhs_pkt *pkt),
void *buf, int len, int zero)
void *buf, int len, int zero, int sequence)
{
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
struct device *dev = usbhs_priv_to_dev(priv);
Expand Down Expand Up @@ -90,6 +90,7 @@ void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
pkt->zero = zero;
pkt->actual = 0;
pkt->done = done;
pkt->sequence = sequence;

usbhs_unlock(priv, flags);
/******************** spin unlock ******************/
Expand Down Expand Up @@ -481,6 +482,9 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done)
int i, ret, len;
int is_short;

usbhs_pipe_data_sequence(pipe, pkt->sequence);
pkt->sequence = -1; /* -1 sequence will be ignored */

ret = usbhsf_fifo_select(pipe, fifo, 1);
if (ret < 0)
return 0;
Expand Down Expand Up @@ -584,6 +588,8 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
/*
* pipe enable to prepare packet receive
*/
usbhs_pipe_data_sequence(pipe, pkt->sequence);
pkt->sequence = -1; /* -1 sequence will be ignored */

usbhs_pipe_enable(pipe);
usbhsf_rx_irq_ctrl(pipe, 1);
Expand Down Expand Up @@ -641,6 +647,7 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done)
* "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
*/
if (0 == rcv_len) {
pkt->zero = 1;
usbhsf_fifo_clear(pipe, fifo);
goto usbhs_fifo_read_end;
}
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/usb/renesas_usbhs/fifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct usbhs_pkt {
int trans;
int actual;
int zero;
int sequence;
};

struct usbhs_pkt_handle {
Expand Down Expand Up @@ -95,7 +96,7 @@ void usbhs_pkt_init(struct usbhs_pkt *pkt);
void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
void (*done)(struct usbhs_priv *priv,
struct usbhs_pkt *pkt),
void *buf, int len, int zero);
void *buf, int len, int zero, int sequence);
struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt);
void usbhs_pkt_start(struct usbhs_pipe *pipe);

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/usb/renesas_usbhs/mod_gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep,
req->actual = 0;
req->status = -EINPROGRESS;
usbhs_pkt_push(pipe, pkt, usbhsg_queue_done,
req->buf, req->length, req->zero);
req->buf, req->length, req->zero, -1);
usbhs_pkt_start(pipe);

dev_dbg(dev, "pipe %d : queue push (%d)\n",
Expand Down
71 changes: 56 additions & 15 deletions trunk/drivers/usb/renesas_usbhs/mod_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,48 @@ static void usbhsh_ureq_free(struct usbhsh_hpriv *hpriv,
/*
* pipe control
*/
static void usbhsh_endpoint_sequence_save(struct usbhsh_hpriv *hpriv,
struct urb *urb,
struct usbhs_pkt *pkt)
{
int len = urb->actual_length;
int maxp = usb_endpoint_maxp(&urb->ep->desc);
int t = 0;

/* DCP is out of sequence control */
if (usb_pipecontrol(urb->pipe))
return;

/*
* renesas_usbhs pipe has a limitation in a number.
* So, driver should re-use the limited pipe for each device/endpoint.
* DATA0/1 sequence should be saved for it.
* see [image of mod_host]
* [HARDWARE LIMITATION]
*/

/*
* next sequence depends on actual_length
*
* ex) actual_length = 1147, maxp = 512
* data0 : 512
* data1 : 512
* data0 : 123
* data1 is the next sequence
*/
t = len / maxp;
if (len % maxp)
t++;
if (pkt->zero)
t++;
t %= 2;

if (t)
usb_dotoggle(urb->dev,
usb_pipeendpoint(urb->pipe),
usb_pipeout(urb->pipe));
}

static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv,
struct urb *urb);

Expand Down Expand Up @@ -247,15 +289,6 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv,
usbhsh_uep_to_pipe(uep) = pipe;
usbhsh_pipe_to_uep(pipe) = uep;

if (!usb_gettoggle(urb->dev,
usb_pipeendpoint(urb->pipe),
usb_pipeout(urb->pipe))) {
usbhs_pipe_sequence_data0(pipe);
usb_settoggle(urb->dev,
usb_pipeendpoint(urb->pipe),
usb_pipeout(urb->pipe), 1);
}

usbhs_pipe_config_update(pipe,
usbhsh_device_number(hpriv, udev),
usb_endpoint_num(desc),
Expand Down Expand Up @@ -598,10 +631,11 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt)
urb->actual_length = pkt->actual;
usbhsh_ureq_free(hpriv, ureq);

usbhsh_endpoint_sequence_save(hpriv, urb, pkt);
usbhsh_pipe_detach(hpriv, uep);

usb_hcd_unlink_urb_from_ep(hcd, urb);
usb_hcd_giveback_urb(hcd, urb, 0);

usbhsh_pipe_detach(hpriv, uep);
}

static int usbhsh_queue_push(struct usb_hcd *hcd,
Expand All @@ -614,7 +648,7 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
struct device *dev = usbhsh_hcd_to_dev(hcd);
struct usbhsh_request *ureq;
void *buf;
int len;
int len, sequence;

if (usb_pipeisoc(urb->pipe)) {
dev_err(dev, "pipe iso is not supported now\n");
Expand All @@ -636,9 +670,15 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
buf = (void *)(urb->transfer_buffer + urb->actual_length);
len = urb->transfer_buffer_length - urb->actual_length;

sequence = usb_gettoggle(urb->dev,
usb_pipeendpoint(urb->pipe),
usb_pipeout(urb->pipe));

dev_dbg(dev, "%s\n", __func__);
usbhs_pkt_push(pipe, &ureq->pkt, usbhsh_queue_done,
buf, len, (urb->transfer_flags & URB_ZERO_PACKET));
buf, len, (urb->transfer_flags & URB_ZERO_PACKET),
sequence);

usbhs_pkt_start(pipe);

return 0;
Expand Down Expand Up @@ -741,7 +781,8 @@ static int usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv,
usbhsh_data_stage_packet_done,
urb->transfer_buffer,
urb->transfer_buffer_length,
(urb->transfer_flags & URB_ZERO_PACKET));
(urb->transfer_flags & URB_ZERO_PACKET),
-1);

return 0;
}
Expand Down Expand Up @@ -770,7 +811,7 @@ static int usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv,
usbhsh_queue_done,
NULL,
urb->transfer_buffer_length,
0);
0, -1);

return 0;
}
Expand Down
21 changes: 19 additions & 2 deletions trunk/drivers/usb/renesas_usbhs/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,27 @@ int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe)
return usbhsp_flags_has(pipe, IS_DIR_HOST);
}

void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int data)
void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence)
{
u16 mask = (SQCLR | SQSET);
u16 val = (data) ? SQSET : SQCLR;
u16 val;

/*
* sequence
* 0 : data0
* 1 : data1
* -1 : no change
*/
switch (sequence) {
case 0:
val = SQCLR;
break;
case 1:
val = SQSET;
break;
default:
return;
}

usbhsp_pipectrl_set(pipe, mask, val);
}
Expand Down

0 comments on commit 1f7ab94

Please sign in to comment.