Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 280894
b: refs/heads/master
c: c1e4877
h: refs/heads/master
v: v3
  • Loading branch information
Kuninori Morimoto authored and Felipe Balbi committed Dec 13, 2011
1 parent 79bf2c4 commit b63c5a7
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 29 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: 547965436d8dc8747b1931af954a178d30e86f6c
refs/heads/master: c1e4877a4106a31319c4ad65b625c11393df98d6
97 changes: 69 additions & 28 deletions trunk/drivers/usb/renesas_usbhs/mod_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,30 @@ static int usbhsh_device_has_endpoint(struct usbhsh_device *udev)
return !list_empty(&udev->ep_list_head);
}

static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv,
struct urb *urb)
{
struct usb_device *usbv = usbhsh_urb_to_usbv(urb);
struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv);

/* usbhsh_device_attach() is still not called */
if (!udev)
return NULL;

/* if it is device0, return it */
if (0 == usb_pipedevice(urb->pipe))
return usbhsh_device0(hpriv);

/* return attached device */
return udev;
}

static struct usbhsh_device *usbhsh_device_attach(struct usbhsh_hpriv *hpriv,
struct urb *urb)
{
struct usbhsh_device *udev = NULL;
struct usbhsh_device *udev0 = usbhsh_device0(hpriv);
struct usbhsh_device *pos;
struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv);
struct device *dev = usbhsh_hcd_to_dev(hcd);
struct usb_device *usbv = usbhsh_urb_to_usbv(urb);
Expand All @@ -232,31 +252,29 @@ static struct usbhsh_device *usbhsh_device_attach(struct usbhsh_hpriv *hpriv,
u16 upphub, hubport;
int i;

/*
* This function should be called only while urb is pointing to device0.
* It will attach unused usbhsh_device to urb (usbv),
* and initialize device0.
* You can use usbhsh_device_get() to get "current" udev,
* and usbhsh_usbv_to_udev() is for "attached" udev.
*/
if (0 != usb_pipedevice(urb->pipe)) {
dev_err(dev, "%s fail: urb isn't pointing device0\n", __func__);
return NULL;
}

/******************** spin lock ********************/
usbhs_lock(priv, flags);

/*
* find device
* find unused device
*/
if (0 == usb_pipedevice(urb->pipe)) {
/*
* device0 is special case
*/
udev = usbhsh_device0(hpriv);
if (usbhsh_udev_is_used(udev))
udev = NULL;
} else {
struct usbhsh_device *pos;

/*
* find unused device
*/
usbhsh_for_each_udev(pos, hpriv, i) {
if (usbhsh_udev_is_used(pos))
continue;
udev = pos;
break;
}
usbhsh_for_each_udev(pos, hpriv, i) {
if (usbhsh_udev_is_used(pos))
continue;
udev = pos;
break;
}

if (udev) {
Expand All @@ -280,9 +298,22 @@ static struct usbhsh_device *usbhsh_device_attach(struct usbhsh_hpriv *hpriv,
if (usbhsh_device_has_endpoint(udev))
dev_warn(dev, "udev have old endpoint\n");

if (usbhsh_device_has_endpoint(udev0))
dev_warn(dev, "udev0 have old endpoint\n");

/* uep will be attached */
INIT_LIST_HEAD(&udev0->ep_list_head);
INIT_LIST_HEAD(&udev->ep_list_head);

/*
* set device0 config
*/
usbhs_set_device_config(priv,
0, 0, 0, usbv->speed);

/*
* set new device config
*/
upphub = 0;
hubport = 0;
if (!usbhsh_connected_to_rhdev(hcd, udev)) {
Expand All @@ -296,7 +327,6 @@ static struct usbhsh_device *usbhsh_device_attach(struct usbhsh_hpriv *hpriv,
upphub, hubport, parent);
}

/* set device config */
usbhs_set_device_config(priv,
usbhsh_device_number(hpriv, udev),
upphub, hubport, usbv->speed);
Expand All @@ -322,6 +352,15 @@ static void usbhsh_device_detach(struct usbhsh_hpriv *hpriv,
if (usbhsh_device_has_endpoint(udev))
dev_warn(dev, "udev still have endpoint\n");

/*
* There is nothing to do if it is device0.
* see
* usbhsh_device_attach()
* usbhsh_device_get()
*/
if (0 == usbhsh_device_number(hpriv, udev))
return;

/******************** spin lock ********************/
usbhs_lock(priv, flags);

Expand All @@ -345,8 +384,7 @@ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv,
gfp_t mem_flags)
{
struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
struct usb_device *usbv = usbhsh_urb_to_usbv(urb);
struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv);
struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb);
struct usb_host_endpoint *ep = urb->ep;
struct usbhsh_ep *uep;
struct usbhsh_pipe_info *info;
Expand Down Expand Up @@ -577,11 +615,15 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv,
/*
* renesas_usbhs can not use original usb address.
* see HARDWARE LIMITATION.
* modify usb address here.
* modify usb address here to use attached device.
* see usbhsh_device_attach()
*/
if (usbhsh_is_request_address(urb)) {
/* FIXME */
req.wValue = 1;
struct usb_device *usbv = usbhsh_urb_to_usbv(urb);
struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv);

/* udev is a attached device */
req.wValue = usbhsh_device_number(hpriv, udev);
dev_dbg(dev, "create new address - %d\n", req.wValue);
}

Expand Down Expand Up @@ -742,7 +784,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd);
struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
struct device *dev = usbhs_priv_to_dev(priv);
struct usb_device *usbv = usbhsh_urb_to_usbv(urb);
struct usb_host_endpoint *ep = urb->ep;
struct usbhsh_device *new_udev = NULL;
int is_dir_in = usb_pipein(urb->pipe);
Expand All @@ -758,7 +799,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
/*
* attach udev if needed
*/
if (!usbhsh_usbv_to_udev(usbv)) {
if (!usbhsh_device_get(hpriv, urb)) {
new_udev = usbhsh_device_attach(hpriv, urb);
if (!new_udev) {
ret = -EIO;
Expand Down

0 comments on commit b63c5a7

Please sign in to comment.