1034d7c13SKuninori Morimoto /* 2034d7c13SKuninori Morimoto * Renesas USB driver 3034d7c13SKuninori Morimoto * 4034d7c13SKuninori Morimoto * Copyright (C) 2011 Renesas Solutions Corp. 5034d7c13SKuninori Morimoto * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6034d7c13SKuninori Morimoto * 7034d7c13SKuninori Morimoto * This program is distributed in the hope that it will be useful, 8034d7c13SKuninori Morimoto * but WITHOUT ANY WARRANTY; without even the implied warranty of 9034d7c13SKuninori Morimoto * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10034d7c13SKuninori Morimoto * GNU General Public License for more details. 11034d7c13SKuninori Morimoto * 12034d7c13SKuninori Morimoto * You should have received a copy of the GNU General Public License 13034d7c13SKuninori Morimoto * along with this program; if not, write to the Free Software 14034d7c13SKuninori Morimoto * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 15034d7c13SKuninori Morimoto * 16034d7c13SKuninori Morimoto */ 17034d7c13SKuninori Morimoto #include <linux/io.h> 18034d7c13SKuninori Morimoto #include <linux/list.h> 19034d7c13SKuninori Morimoto #include <linux/module.h> 20034d7c13SKuninori Morimoto #include <linux/platform_device.h> 21034d7c13SKuninori Morimoto #include <linux/slab.h> 22034d7c13SKuninori Morimoto #include <linux/usb.h> 23034d7c13SKuninori Morimoto #include <linux/usb/hcd.h> 24034d7c13SKuninori Morimoto #include "common.h" 25034d7c13SKuninori Morimoto 26034d7c13SKuninori Morimoto /* 27034d7c13SKuninori Morimoto *** HARDWARE LIMITATION *** 28034d7c13SKuninori Morimoto * 29034d7c13SKuninori Morimoto * 1) renesas_usbhs has a limited number of controllable devices. 30034d7c13SKuninori Morimoto * it can control only 9 devices in generally. 31034d7c13SKuninori Morimoto * see DEVADDn / DCPMAXP / PIPEMAXP. 32034d7c13SKuninori Morimoto * 33034d7c13SKuninori Morimoto * 2) renesas_usbhs pipe number is limited. 34034d7c13SKuninori Morimoto * the pipe will be re-used for each devices. 35034d7c13SKuninori Morimoto * so, software should control DATA0/1 sequence of each devices. 36034d7c13SKuninori Morimoto */ 37034d7c13SKuninori Morimoto 38034d7c13SKuninori Morimoto 39034d7c13SKuninori Morimoto /* 40034d7c13SKuninori Morimoto * image of mod_host 41034d7c13SKuninori Morimoto * 42034d7c13SKuninori Morimoto * +--------+ 43034d7c13SKuninori Morimoto * | udev 0 | --> it is used when set address 44034d7c13SKuninori Morimoto * +--------+ 45034d7c13SKuninori Morimoto * 46034d7c13SKuninori Morimoto * +--------+ pipes are reused for each uep. 47034d7c13SKuninori Morimoto * | udev 1 |-+- [uep 0 (dcp) ] --+ pipe will be switched when 48e5679d07SKuninori Morimoto * +--------+ | | other device requested 49034d7c13SKuninori Morimoto * +- [uep 1 (bulk)] --|---+ +--------------+ 50034d7c13SKuninori Morimoto * | +--------------> | pipe0 (dcp) | 51e5679d07SKuninori Morimoto * +- [uep 2 (bulk)] -@ | +--------------+ 52e5679d07SKuninori Morimoto * | | pipe1 (isoc) | 53e5679d07SKuninori Morimoto * +--------+ | +--------------+ 54e5679d07SKuninori Morimoto * | udev 2 |-+- [uep 0 (dcp) ] -@ +----------> | pipe2 (bulk) | 55e5679d07SKuninori Morimoto * +--------+ | +--------------+ 56e5679d07SKuninori Morimoto * +- [uep 1 (int) ] ----+ +------> | pipe3 (bulk) | 57e5679d07SKuninori Morimoto * | | +--------------+ 58e5679d07SKuninori Morimoto * +--------+ +-----|------> | pipe4 (int) | 59e5679d07SKuninori Morimoto * | udev 3 |-+- [uep 0 (dcp) ] -@ | +--------------+ 60e5679d07SKuninori Morimoto * +--------+ | | | .... | 61e5679d07SKuninori Morimoto * +- [uep 1 (bulk)] -@ | | .... | 62034d7c13SKuninori Morimoto * | | 63034d7c13SKuninori Morimoto * +- [uep 2 (bulk)]-----------+ 64e5679d07SKuninori Morimoto * 65e5679d07SKuninori Morimoto * @ : uep requested free pipe, but all have been used. 66e5679d07SKuninori Morimoto * now it is waiting for free pipe 67034d7c13SKuninori Morimoto */ 68034d7c13SKuninori Morimoto 69034d7c13SKuninori Morimoto 70034d7c13SKuninori Morimoto /* 71034d7c13SKuninori Morimoto * struct 72034d7c13SKuninori Morimoto */ 73034d7c13SKuninori Morimoto struct usbhsh_request { 74034d7c13SKuninori Morimoto struct urb *urb; 75034d7c13SKuninori Morimoto struct usbhs_pkt pkt; 76034d7c13SKuninori Morimoto }; 77034d7c13SKuninori Morimoto 78034d7c13SKuninori Morimoto struct usbhsh_device { 79034d7c13SKuninori Morimoto struct usb_device *usbv; 80034d7c13SKuninori Morimoto struct list_head ep_list_head; /* list of usbhsh_ep */ 81034d7c13SKuninori Morimoto }; 82034d7c13SKuninori Morimoto 83034d7c13SKuninori Morimoto struct usbhsh_ep { 84e5679d07SKuninori Morimoto struct usbhs_pipe *pipe; /* attached pipe */ 85034d7c13SKuninori Morimoto struct usbhsh_device *udev; /* attached udev */ 86e4c57dedSKuninori Morimoto struct usb_host_endpoint *ep; 87034d7c13SKuninori Morimoto struct list_head ep_list; /* list to usbhsh_device */ 887b332e5fSKuninori Morimoto unsigned int counter; /* pipe attach counter */ 89034d7c13SKuninori Morimoto }; 90034d7c13SKuninori Morimoto 91034d7c13SKuninori Morimoto #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ 92034d7c13SKuninori Morimoto #define USBHSH_PORT_MAX 7 /* see DEVADDn :: HUBPORT */ 93034d7c13SKuninori Morimoto struct usbhsh_hpriv { 94034d7c13SKuninori Morimoto struct usbhs_mod mod; 95034d7c13SKuninori Morimoto struct usbhs_pipe *dcp; 96034d7c13SKuninori Morimoto 97034d7c13SKuninori Morimoto struct usbhsh_device udev[USBHSH_DEVICE_MAX]; 98034d7c13SKuninori Morimoto 99034d7c13SKuninori Morimoto u32 port_stat; /* USB_PORT_STAT_xxx */ 100034d7c13SKuninori Morimoto 1017fccd480SKuninori Morimoto struct completion setup_ack_done; 102034d7c13SKuninori Morimoto }; 103034d7c13SKuninori Morimoto 104034d7c13SKuninori Morimoto 105034d7c13SKuninori Morimoto static const char usbhsh_hcd_name[] = "renesas_usbhs host"; 106034d7c13SKuninori Morimoto 107034d7c13SKuninori Morimoto /* 108034d7c13SKuninori Morimoto * macro 109034d7c13SKuninori Morimoto */ 110034d7c13SKuninori Morimoto #define usbhsh_priv_to_hpriv(priv) \ 111034d7c13SKuninori Morimoto container_of(usbhs_mod_get(priv, USBHS_HOST), struct usbhsh_hpriv, mod) 112034d7c13SKuninori Morimoto 113034d7c13SKuninori Morimoto #define __usbhsh_for_each_udev(start, pos, h, i) \ 114925403f4SKuninori Morimoto for ((i) = start; \ 115925403f4SKuninori Morimoto ((i) < USBHSH_DEVICE_MAX) && ((pos) = (h)->udev + (i)); \ 116925403f4SKuninori Morimoto (i)++) 117034d7c13SKuninori Morimoto 118034d7c13SKuninori Morimoto #define usbhsh_for_each_udev(pos, hpriv, i) \ 119034d7c13SKuninori Morimoto __usbhsh_for_each_udev(1, pos, hpriv, i) 120034d7c13SKuninori Morimoto 121034d7c13SKuninori Morimoto #define usbhsh_for_each_udev_with_dev0(pos, hpriv, i) \ 122034d7c13SKuninori Morimoto __usbhsh_for_each_udev(0, pos, hpriv, i) 123034d7c13SKuninori Morimoto 124034d7c13SKuninori Morimoto #define usbhsh_hcd_to_hpriv(h) (struct usbhsh_hpriv *)((h)->hcd_priv) 125034d7c13SKuninori Morimoto #define usbhsh_hcd_to_dev(h) ((h)->self.controller) 126034d7c13SKuninori Morimoto 127034d7c13SKuninori Morimoto #define usbhsh_hpriv_to_priv(h) ((h)->mod.priv) 128034d7c13SKuninori Morimoto #define usbhsh_hpriv_to_dcp(h) ((h)->dcp) 129034d7c13SKuninori Morimoto #define usbhsh_hpriv_to_hcd(h) \ 130034d7c13SKuninori Morimoto container_of((void *)h, struct usb_hcd, hcd_priv) 131034d7c13SKuninori Morimoto 132034d7c13SKuninori Morimoto #define usbhsh_ep_to_uep(u) ((u)->hcpriv) 133034d7c13SKuninori Morimoto #define usbhsh_uep_to_pipe(u) ((u)->pipe) 134034d7c13SKuninori Morimoto #define usbhsh_uep_to_udev(u) ((u)->udev) 135e4c57dedSKuninori Morimoto #define usbhsh_uep_to_ep(u) ((u)->ep) 136e4c57dedSKuninori Morimoto 137034d7c13SKuninori Morimoto #define usbhsh_urb_to_ureq(u) ((u)->hcpriv) 138034d7c13SKuninori Morimoto #define usbhsh_urb_to_usbv(u) ((u)->dev) 139034d7c13SKuninori Morimoto 140034d7c13SKuninori Morimoto #define usbhsh_usbv_to_udev(d) dev_get_drvdata(&(d)->dev) 141034d7c13SKuninori Morimoto 142034d7c13SKuninori Morimoto #define usbhsh_udev_to_usbv(h) ((h)->usbv) 143ab142308SKuninori Morimoto #define usbhsh_udev_is_used(h) usbhsh_udev_to_usbv(h) 144034d7c13SKuninori Morimoto 145e5679d07SKuninori Morimoto #define usbhsh_pipe_to_uep(p) ((p)->mod_private) 146034d7c13SKuninori Morimoto 1479c673652SKuninori Morimoto #define usbhsh_device_parent(d) (usbhsh_usbv_to_udev((d)->usbv->parent)) 1489c673652SKuninori Morimoto #define usbhsh_device_hubport(d) ((d)->usbv->portnum) 149034d7c13SKuninori Morimoto #define usbhsh_device_number(h, d) ((int)((d) - (h)->udev)) 150034d7c13SKuninori Morimoto #define usbhsh_device_nth(h, d) ((h)->udev + d) 151034d7c13SKuninori Morimoto #define usbhsh_device0(h) usbhsh_device_nth(h, 0) 152034d7c13SKuninori Morimoto 153034d7c13SKuninori Morimoto #define usbhsh_port_stat_init(h) ((h)->port_stat = 0) 154034d7c13SKuninori Morimoto #define usbhsh_port_stat_set(h, s) ((h)->port_stat |= (s)) 155034d7c13SKuninori Morimoto #define usbhsh_port_stat_clear(h, s) ((h)->port_stat &= ~(s)) 156034d7c13SKuninori Morimoto #define usbhsh_port_stat_get(h) ((h)->port_stat) 157034d7c13SKuninori Morimoto 15825234b46SKuninori Morimoto #define usbhsh_pkt_to_ureq(p) \ 159034d7c13SKuninori Morimoto container_of((void *)p, struct usbhsh_request, pkt) 160034d7c13SKuninori Morimoto 161034d7c13SKuninori Morimoto /* 162034d7c13SKuninori Morimoto * req alloc/free 163034d7c13SKuninori Morimoto */ 16425234b46SKuninori Morimoto static struct usbhsh_request *usbhsh_ureq_alloc(struct usbhsh_hpriv *hpriv, 165034d7c13SKuninori Morimoto struct urb *urb, 166034d7c13SKuninori Morimoto gfp_t mem_flags) 167034d7c13SKuninori Morimoto { 168034d7c13SKuninori Morimoto struct usbhsh_request *ureq; 169034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 170034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 171034d7c13SKuninori Morimoto 172034d7c13SKuninori Morimoto ureq = kzalloc(sizeof(struct usbhsh_request), mem_flags); 173034d7c13SKuninori Morimoto if (!ureq) { 174034d7c13SKuninori Morimoto dev_err(dev, "ureq alloc fail\n"); 175034d7c13SKuninori Morimoto return NULL; 176034d7c13SKuninori Morimoto } 177034d7c13SKuninori Morimoto 178034d7c13SKuninori Morimoto usbhs_pkt_init(&ureq->pkt); 179034d7c13SKuninori Morimoto ureq->urb = urb; 180fc9d5c79SKuninori Morimoto usbhsh_urb_to_ureq(urb) = ureq; 181034d7c13SKuninori Morimoto 182034d7c13SKuninori Morimoto return ureq; 183034d7c13SKuninori Morimoto } 184034d7c13SKuninori Morimoto 18525234b46SKuninori Morimoto static void usbhsh_ureq_free(struct usbhsh_hpriv *hpriv, 186034d7c13SKuninori Morimoto struct usbhsh_request *ureq) 187034d7c13SKuninori Morimoto { 188fc9d5c79SKuninori Morimoto usbhsh_urb_to_ureq(ureq->urb) = NULL; 189034d7c13SKuninori Morimoto ureq->urb = NULL; 190034d7c13SKuninori Morimoto 191c5b963f8SKuninori Morimoto kfree(ureq); 192034d7c13SKuninori Morimoto } 193034d7c13SKuninori Morimoto 194034d7c13SKuninori Morimoto /* 195b1930da0SKuninori Morimoto * status 196034d7c13SKuninori Morimoto */ 197b1930da0SKuninori Morimoto static int usbhsh_is_running(struct usbhsh_hpriv *hpriv) 198b1930da0SKuninori Morimoto { 199b1930da0SKuninori Morimoto /* 200b1930da0SKuninori Morimoto * we can decide some device is attached or not 201b1930da0SKuninori Morimoto * by checking mod.irq_attch 202b1930da0SKuninori Morimoto * see 203b1930da0SKuninori Morimoto * usbhsh_irq_attch() 204b1930da0SKuninori Morimoto * usbhsh_irq_dtch() 205b1930da0SKuninori Morimoto */ 206b1930da0SKuninori Morimoto return (hpriv->mod.irq_attch == NULL); 207b1930da0SKuninori Morimoto } 208b1930da0SKuninori Morimoto 209b1930da0SKuninori Morimoto /* 210e5679d07SKuninori Morimoto * pipe control 211e4c57dedSKuninori Morimoto */ 2123edeee38SKuninori Morimoto static void usbhsh_endpoint_sequence_save(struct usbhsh_hpriv *hpriv, 2133edeee38SKuninori Morimoto struct urb *urb, 2143edeee38SKuninori Morimoto struct usbhs_pkt *pkt) 2153edeee38SKuninori Morimoto { 2163edeee38SKuninori Morimoto int len = urb->actual_length; 2173edeee38SKuninori Morimoto int maxp = usb_endpoint_maxp(&urb->ep->desc); 2183edeee38SKuninori Morimoto int t = 0; 2193edeee38SKuninori Morimoto 2203edeee38SKuninori Morimoto /* DCP is out of sequence control */ 2213edeee38SKuninori Morimoto if (usb_pipecontrol(urb->pipe)) 2223edeee38SKuninori Morimoto return; 2233edeee38SKuninori Morimoto 2243edeee38SKuninori Morimoto /* 2253edeee38SKuninori Morimoto * renesas_usbhs pipe has a limitation in a number. 2263edeee38SKuninori Morimoto * So, driver should re-use the limited pipe for each device/endpoint. 2273edeee38SKuninori Morimoto * DATA0/1 sequence should be saved for it. 2283edeee38SKuninori Morimoto * see [image of mod_host] 2293edeee38SKuninori Morimoto * [HARDWARE LIMITATION] 2303edeee38SKuninori Morimoto */ 2313edeee38SKuninori Morimoto 2323edeee38SKuninori Morimoto /* 2333edeee38SKuninori Morimoto * next sequence depends on actual_length 2343edeee38SKuninori Morimoto * 2353edeee38SKuninori Morimoto * ex) actual_length = 1147, maxp = 512 2363edeee38SKuninori Morimoto * data0 : 512 2373edeee38SKuninori Morimoto * data1 : 512 2383edeee38SKuninori Morimoto * data0 : 123 2393edeee38SKuninori Morimoto * data1 is the next sequence 2403edeee38SKuninori Morimoto */ 2413edeee38SKuninori Morimoto t = len / maxp; 2423edeee38SKuninori Morimoto if (len % maxp) 2433edeee38SKuninori Morimoto t++; 2443edeee38SKuninori Morimoto if (pkt->zero) 2453edeee38SKuninori Morimoto t++; 2463edeee38SKuninori Morimoto t %= 2; 2473edeee38SKuninori Morimoto 2483edeee38SKuninori Morimoto if (t) 2493edeee38SKuninori Morimoto usb_dotoggle(urb->dev, 2503edeee38SKuninori Morimoto usb_pipeendpoint(urb->pipe), 2513edeee38SKuninori Morimoto usb_pipeout(urb->pipe)); 2523edeee38SKuninori Morimoto } 2533edeee38SKuninori Morimoto 254e4c57dedSKuninori Morimoto static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, 255e4c57dedSKuninori Morimoto struct urb *urb); 256e5679d07SKuninori Morimoto 257e5679d07SKuninori Morimoto static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, 258e5679d07SKuninori Morimoto struct urb *urb) 259e5679d07SKuninori Morimoto { 260e5679d07SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 261e5679d07SKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); 262e5679d07SKuninori Morimoto struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); 263e5679d07SKuninori Morimoto struct usbhs_pipe *pipe; 264e5679d07SKuninori Morimoto struct usb_endpoint_descriptor *desc = &urb->ep->desc; 265e5679d07SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 266e5679d07SKuninori Morimoto unsigned long flags; 267e5679d07SKuninori Morimoto int dir_in_req = !!usb_pipein(urb->pipe); 268e5679d07SKuninori Morimoto int is_dcp = usb_endpoint_xfer_control(desc); 269e5679d07SKuninori Morimoto int i, dir_in; 270e5679d07SKuninori Morimoto int ret = -EBUSY; 271e5679d07SKuninori Morimoto 272e5679d07SKuninori Morimoto /******************** spin lock ********************/ 273e5679d07SKuninori Morimoto usbhs_lock(priv, flags); 274e5679d07SKuninori Morimoto 2757b332e5fSKuninori Morimoto /* 2767b332e5fSKuninori Morimoto * if uep has been attached to pipe, 2777b332e5fSKuninori Morimoto * reuse it 2787b332e5fSKuninori Morimoto */ 2797b332e5fSKuninori Morimoto if (usbhsh_uep_to_pipe(uep)) { 2807b332e5fSKuninori Morimoto ret = 0; 281e5679d07SKuninori Morimoto goto usbhsh_pipe_attach_done; 282e5679d07SKuninori Morimoto } 283e5679d07SKuninori Morimoto 284e5679d07SKuninori Morimoto usbhs_for_each_pipe_with_dcp(pipe, priv, i) { 285e5679d07SKuninori Morimoto 286e5679d07SKuninori Morimoto /* check pipe type */ 287e5679d07SKuninori Morimoto if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc))) 288e5679d07SKuninori Morimoto continue; 289e5679d07SKuninori Morimoto 290e5679d07SKuninori Morimoto /* check pipe direction if normal pipe */ 291e5679d07SKuninori Morimoto if (!is_dcp) { 292e5679d07SKuninori Morimoto dir_in = !!usbhs_pipe_is_dir_in(pipe); 293e5679d07SKuninori Morimoto if (0 != (dir_in - dir_in_req)) 294e5679d07SKuninori Morimoto continue; 295e5679d07SKuninori Morimoto } 296e5679d07SKuninori Morimoto 297e5679d07SKuninori Morimoto /* check pipe is free */ 298e5679d07SKuninori Morimoto if (usbhsh_pipe_to_uep(pipe)) 299e5679d07SKuninori Morimoto continue; 300e5679d07SKuninori Morimoto 301e5679d07SKuninori Morimoto /* 302e5679d07SKuninori Morimoto * attach pipe to uep 303e5679d07SKuninori Morimoto * 304e5679d07SKuninori Morimoto * usbhs_pipe_config_update() should be called after 305e5679d07SKuninori Morimoto * usbhs_set_device_config() 306e5679d07SKuninori Morimoto * see 307e5679d07SKuninori Morimoto * DCPMAXP/PIPEMAXP 308e5679d07SKuninori Morimoto */ 309e5679d07SKuninori Morimoto usbhsh_uep_to_pipe(uep) = pipe; 310e5679d07SKuninori Morimoto usbhsh_pipe_to_uep(pipe) = uep; 311e5679d07SKuninori Morimoto 312e5679d07SKuninori Morimoto usbhs_pipe_config_update(pipe, 313e5679d07SKuninori Morimoto usbhsh_device_number(hpriv, udev), 314e5679d07SKuninori Morimoto usb_endpoint_num(desc), 315e5679d07SKuninori Morimoto usb_endpoint_maxp(desc)); 316e5679d07SKuninori Morimoto 317e5679d07SKuninori Morimoto dev_dbg(dev, "%s [%d-%d(%s:%s)]\n", __func__, 318e5679d07SKuninori Morimoto usbhsh_device_number(hpriv, udev), 319e5679d07SKuninori Morimoto usb_endpoint_num(desc), 320e5679d07SKuninori Morimoto usbhs_pipe_name(pipe), 321e5679d07SKuninori Morimoto dir_in_req ? "in" : "out"); 322e5679d07SKuninori Morimoto 323e5679d07SKuninori Morimoto ret = 0; 324e5679d07SKuninori Morimoto break; 325e5679d07SKuninori Morimoto } 326e5679d07SKuninori Morimoto 327e5679d07SKuninori Morimoto usbhsh_pipe_attach_done: 3287b332e5fSKuninori Morimoto if (0 == ret) 3297b332e5fSKuninori Morimoto uep->counter++; 3307b332e5fSKuninori Morimoto 331e5679d07SKuninori Morimoto usbhs_unlock(priv, flags); 332e5679d07SKuninori Morimoto /******************** spin unlock ******************/ 333e5679d07SKuninori Morimoto 334e5679d07SKuninori Morimoto return ret; 335e5679d07SKuninori Morimoto } 336e5679d07SKuninori Morimoto 337e5679d07SKuninori Morimoto static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, 338e5679d07SKuninori Morimoto struct usbhsh_ep *uep) 339e5679d07SKuninori Morimoto { 340e5679d07SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 341e5679d07SKuninori Morimoto struct usbhs_pipe *pipe; 342e5679d07SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 343e5679d07SKuninori Morimoto unsigned long flags; 344e5679d07SKuninori Morimoto 3454f053a24SKuninori Morimoto if (unlikely(!uep)) { 3464f053a24SKuninori Morimoto dev_err(dev, "no uep\n"); 3474f053a24SKuninori Morimoto return; 3484f053a24SKuninori Morimoto } 3494f053a24SKuninori Morimoto 350e5679d07SKuninori Morimoto /******************** spin lock ********************/ 351e5679d07SKuninori Morimoto usbhs_lock(priv, flags); 352e5679d07SKuninori Morimoto 353e5679d07SKuninori Morimoto pipe = usbhsh_uep_to_pipe(uep); 354e5679d07SKuninori Morimoto 355e5679d07SKuninori Morimoto if (unlikely(!pipe)) { 356e5679d07SKuninori Morimoto dev_err(dev, "uep doens't have pipe\n"); 3577b332e5fSKuninori Morimoto } else if (1 == uep->counter--) { /* last user */ 358e5679d07SKuninori Morimoto struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); 359e5679d07SKuninori Morimoto struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); 360e5679d07SKuninori Morimoto 361e5679d07SKuninori Morimoto /* detach pipe from uep */ 362e5679d07SKuninori Morimoto usbhsh_uep_to_pipe(uep) = NULL; 363e5679d07SKuninori Morimoto usbhsh_pipe_to_uep(pipe) = NULL; 364e5679d07SKuninori Morimoto 365e5679d07SKuninori Morimoto dev_dbg(dev, "%s [%d-%d(%s)]\n", __func__, 366e5679d07SKuninori Morimoto usbhsh_device_number(hpriv, udev), 367e5679d07SKuninori Morimoto usb_endpoint_num(&ep->desc), 368e5679d07SKuninori Morimoto usbhs_pipe_name(pipe)); 369e5679d07SKuninori Morimoto } 370e5679d07SKuninori Morimoto 371e5679d07SKuninori Morimoto usbhs_unlock(priv, flags); 372e5679d07SKuninori Morimoto /******************** spin unlock ******************/ 373e5679d07SKuninori Morimoto } 374e5679d07SKuninori Morimoto 375e5679d07SKuninori Morimoto /* 376e5679d07SKuninori Morimoto * endpoint control 377e5679d07SKuninori Morimoto */ 378e4c57dedSKuninori Morimoto static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, 379e4c57dedSKuninori Morimoto struct urb *urb, 380e4c57dedSKuninori Morimoto gfp_t mem_flags) 381e4c57dedSKuninori Morimoto { 382e4c57dedSKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 383e4c57dedSKuninori Morimoto struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); 384e4c57dedSKuninori Morimoto struct usb_host_endpoint *ep = urb->ep; 385e4c57dedSKuninori Morimoto struct usbhsh_ep *uep; 386e4c57dedSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 387e4c57dedSKuninori Morimoto struct usb_endpoint_descriptor *desc = &ep->desc; 388e4c57dedSKuninori Morimoto unsigned long flags; 389e4c57dedSKuninori Morimoto 390e4c57dedSKuninori Morimoto uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); 391e4c57dedSKuninori Morimoto if (!uep) { 392e4c57dedSKuninori Morimoto dev_err(dev, "usbhsh_ep alloc fail\n"); 393e4c57dedSKuninori Morimoto return -ENOMEM; 394e4c57dedSKuninori Morimoto } 395e4c57dedSKuninori Morimoto 396e4c57dedSKuninori Morimoto /******************** spin lock ********************/ 397e4c57dedSKuninori Morimoto usbhs_lock(priv, flags); 398e4c57dedSKuninori Morimoto 399e4c57dedSKuninori Morimoto /* 400e5679d07SKuninori Morimoto * init endpoint 401e4c57dedSKuninori Morimoto */ 4027b332e5fSKuninori Morimoto uep->counter = 0; 403e4c57dedSKuninori Morimoto INIT_LIST_HEAD(&uep->ep_list); 404e4c57dedSKuninori Morimoto list_add_tail(&uep->ep_list, &udev->ep_list_head); 405e4c57dedSKuninori Morimoto 406e4c57dedSKuninori Morimoto usbhsh_uep_to_udev(uep) = udev; 407e4c57dedSKuninori Morimoto usbhsh_uep_to_ep(uep) = ep; 408e4c57dedSKuninori Morimoto usbhsh_ep_to_uep(ep) = uep; 409e4c57dedSKuninori Morimoto 410e5679d07SKuninori Morimoto usbhs_unlock(priv, flags); 411e5679d07SKuninori Morimoto /******************** spin unlock ******************/ 412e4c57dedSKuninori Morimoto 413e5679d07SKuninori Morimoto dev_dbg(dev, "%s [%d-%d]\n", __func__, 414e4c57dedSKuninori Morimoto usbhsh_device_number(hpriv, udev), 415e5679d07SKuninori Morimoto usb_endpoint_num(desc)); 416e4c57dedSKuninori Morimoto 417e4c57dedSKuninori Morimoto return 0; 418e4c57dedSKuninori Morimoto } 419e4c57dedSKuninori Morimoto 420e4c57dedSKuninori Morimoto static void usbhsh_endpoint_detach(struct usbhsh_hpriv *hpriv, 421e4c57dedSKuninori Morimoto struct usb_host_endpoint *ep) 422e4c57dedSKuninori Morimoto { 423e4c57dedSKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 424e4c57dedSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 425e4c57dedSKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); 426e4c57dedSKuninori Morimoto unsigned long flags; 427e4c57dedSKuninori Morimoto 428e4c57dedSKuninori Morimoto if (!uep) 429e4c57dedSKuninori Morimoto return; 430e4c57dedSKuninori Morimoto 431e5679d07SKuninori Morimoto dev_dbg(dev, "%s [%d-%d]\n", __func__, 432e4c57dedSKuninori Morimoto usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), 433e5679d07SKuninori Morimoto usb_endpoint_num(&ep->desc)); 434e5679d07SKuninori Morimoto 435e5679d07SKuninori Morimoto if (usbhsh_uep_to_pipe(uep)) 436e5679d07SKuninori Morimoto usbhsh_pipe_detach(hpriv, uep); 437e4c57dedSKuninori Morimoto 438e4c57dedSKuninori Morimoto /******************** spin lock ********************/ 439e4c57dedSKuninori Morimoto usbhs_lock(priv, flags); 440e4c57dedSKuninori Morimoto 441e4c57dedSKuninori Morimoto /* remove this endpoint from udev */ 442e4c57dedSKuninori Morimoto list_del_init(&uep->ep_list); 443e4c57dedSKuninori Morimoto 444e4c57dedSKuninori Morimoto usbhsh_uep_to_udev(uep) = NULL; 445e4c57dedSKuninori Morimoto usbhsh_uep_to_ep(uep) = NULL; 446e4c57dedSKuninori Morimoto usbhsh_ep_to_uep(ep) = NULL; 447e4c57dedSKuninori Morimoto 448e4c57dedSKuninori Morimoto usbhs_unlock(priv, flags); 449e4c57dedSKuninori Morimoto /******************** spin unlock ******************/ 450e4c57dedSKuninori Morimoto 451e4c57dedSKuninori Morimoto kfree(uep); 452e4c57dedSKuninori Morimoto } 453e4c57dedSKuninori Morimoto 454e4c57dedSKuninori Morimoto static void usbhsh_endpoint_detach_all(struct usbhsh_hpriv *hpriv, 455e4c57dedSKuninori Morimoto struct usbhsh_device *udev) 456e4c57dedSKuninori Morimoto { 457e4c57dedSKuninori Morimoto struct usbhsh_ep *uep, *next; 458e4c57dedSKuninori Morimoto 459e4c57dedSKuninori Morimoto list_for_each_entry_safe(uep, next, &udev->ep_list_head, ep_list) 460e4c57dedSKuninori Morimoto usbhsh_endpoint_detach(hpriv, usbhsh_uep_to_ep(uep)); 461034d7c13SKuninori Morimoto } 462034d7c13SKuninori Morimoto 463034d7c13SKuninori Morimoto /* 464034d7c13SKuninori Morimoto * device control 465034d7c13SKuninori Morimoto */ 4669c673652SKuninori Morimoto static int usbhsh_connected_to_rhdev(struct usb_hcd *hcd, 4679c673652SKuninori Morimoto struct usbhsh_device *udev) 4689c673652SKuninori Morimoto { 4699c673652SKuninori Morimoto struct usb_device *usbv = usbhsh_udev_to_usbv(udev); 4709c673652SKuninori Morimoto 4719c673652SKuninori Morimoto return hcd->self.root_hub == usbv->parent; 4729c673652SKuninori Morimoto } 473034d7c13SKuninori Morimoto 474034d7c13SKuninori Morimoto static int usbhsh_device_has_endpoint(struct usbhsh_device *udev) 475034d7c13SKuninori Morimoto { 476034d7c13SKuninori Morimoto return !list_empty(&udev->ep_list_head); 477034d7c13SKuninori Morimoto } 478034d7c13SKuninori Morimoto 479c1e4877aSKuninori Morimoto static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, 480c1e4877aSKuninori Morimoto struct urb *urb) 481c1e4877aSKuninori Morimoto { 482c1e4877aSKuninori Morimoto struct usb_device *usbv = usbhsh_urb_to_usbv(urb); 483c1e4877aSKuninori Morimoto struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv); 484c1e4877aSKuninori Morimoto 485c1e4877aSKuninori Morimoto /* usbhsh_device_attach() is still not called */ 486c1e4877aSKuninori Morimoto if (!udev) 487c1e4877aSKuninori Morimoto return NULL; 488c1e4877aSKuninori Morimoto 489c1e4877aSKuninori Morimoto /* if it is device0, return it */ 490c1e4877aSKuninori Morimoto if (0 == usb_pipedevice(urb->pipe)) 491c1e4877aSKuninori Morimoto return usbhsh_device0(hpriv); 492c1e4877aSKuninori Morimoto 493c1e4877aSKuninori Morimoto /* return attached device */ 494c1e4877aSKuninori Morimoto return udev; 495c1e4877aSKuninori Morimoto } 496c1e4877aSKuninori Morimoto 4977aac8d15SKuninori Morimoto static struct usbhsh_device *usbhsh_device_attach(struct usbhsh_hpriv *hpriv, 498034d7c13SKuninori Morimoto struct urb *urb) 499034d7c13SKuninori Morimoto { 500034d7c13SKuninori Morimoto struct usbhsh_device *udev = NULL; 501c1e4877aSKuninori Morimoto struct usbhsh_device *udev0 = usbhsh_device0(hpriv); 502c1e4877aSKuninori Morimoto struct usbhsh_device *pos; 503034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 504034d7c13SKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 505034d7c13SKuninori Morimoto struct usb_device *usbv = usbhsh_urb_to_usbv(urb); 506034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 507d399f90dSKuninori Morimoto unsigned long flags; 5089c673652SKuninori Morimoto u16 upphub, hubport; 509034d7c13SKuninori Morimoto int i; 510034d7c13SKuninori Morimoto 511034d7c13SKuninori Morimoto /* 512c1e4877aSKuninori Morimoto * This function should be called only while urb is pointing to device0. 513c1e4877aSKuninori Morimoto * It will attach unused usbhsh_device to urb (usbv), 514c1e4877aSKuninori Morimoto * and initialize device0. 515c1e4877aSKuninori Morimoto * You can use usbhsh_device_get() to get "current" udev, 516c1e4877aSKuninori Morimoto * and usbhsh_usbv_to_udev() is for "attached" udev. 517034d7c13SKuninori Morimoto */ 518c1e4877aSKuninori Morimoto if (0 != usb_pipedevice(urb->pipe)) { 519c1e4877aSKuninori Morimoto dev_err(dev, "%s fail: urb isn't pointing device0\n", __func__); 520c1e4877aSKuninori Morimoto return NULL; 521034d7c13SKuninori Morimoto } 522034d7c13SKuninori Morimoto 523d399f90dSKuninori Morimoto /******************** spin lock ********************/ 524d399f90dSKuninori Morimoto usbhs_lock(priv, flags); 525d399f90dSKuninori Morimoto 526034d7c13SKuninori Morimoto /* 527034d7c13SKuninori Morimoto * find unused device 528034d7c13SKuninori Morimoto */ 529ab142308SKuninori Morimoto usbhsh_for_each_udev(pos, hpriv, i) { 530ab142308SKuninori Morimoto if (usbhsh_udev_is_used(pos)) 531034d7c13SKuninori Morimoto continue; 532ab142308SKuninori Morimoto udev = pos; 533ab142308SKuninori Morimoto break; 534034d7c13SKuninori Morimoto } 535034d7c13SKuninori Morimoto 536d399f90dSKuninori Morimoto if (udev) { 537034d7c13SKuninori Morimoto /* 538034d7c13SKuninori Morimoto * usbhsh_usbv_to_udev() 539034d7c13SKuninori Morimoto * usbhsh_udev_to_usbv() 540034d7c13SKuninori Morimoto * will be enable 541034d7c13SKuninori Morimoto */ 542034d7c13SKuninori Morimoto dev_set_drvdata(&usbv->dev, udev); 543034d7c13SKuninori Morimoto udev->usbv = usbv; 544d399f90dSKuninori Morimoto } 545034d7c13SKuninori Morimoto 546d399f90dSKuninori Morimoto usbhs_unlock(priv, flags); 547d399f90dSKuninori Morimoto /******************** spin unlock ******************/ 548d399f90dSKuninori Morimoto 549ab142308SKuninori Morimoto if (!udev) { 550034d7c13SKuninori Morimoto dev_err(dev, "no free usbhsh_device\n"); 551034d7c13SKuninori Morimoto return NULL; 552ab142308SKuninori Morimoto } 553034d7c13SKuninori Morimoto 554e4c57dedSKuninori Morimoto if (usbhsh_device_has_endpoint(udev)) { 555034d7c13SKuninori Morimoto dev_warn(dev, "udev have old endpoint\n"); 556e4c57dedSKuninori Morimoto usbhsh_endpoint_detach_all(hpriv, udev); 557e4c57dedSKuninori Morimoto } 558034d7c13SKuninori Morimoto 559e4c57dedSKuninori Morimoto if (usbhsh_device_has_endpoint(udev0)) { 560c1e4877aSKuninori Morimoto dev_warn(dev, "udev0 have old endpoint\n"); 561e4c57dedSKuninori Morimoto usbhsh_endpoint_detach_all(hpriv, udev0); 562e4c57dedSKuninori Morimoto } 563c1e4877aSKuninori Morimoto 564034d7c13SKuninori Morimoto /* uep will be attached */ 565c1e4877aSKuninori Morimoto INIT_LIST_HEAD(&udev0->ep_list_head); 566034d7c13SKuninori Morimoto INIT_LIST_HEAD(&udev->ep_list_head); 567034d7c13SKuninori Morimoto 568c1e4877aSKuninori Morimoto /* 569c1e4877aSKuninori Morimoto * set device0 config 570c1e4877aSKuninori Morimoto */ 571c1e4877aSKuninori Morimoto usbhs_set_device_config(priv, 572c1e4877aSKuninori Morimoto 0, 0, 0, usbv->speed); 573c1e4877aSKuninori Morimoto 574c1e4877aSKuninori Morimoto /* 575c1e4877aSKuninori Morimoto * set new device config 576c1e4877aSKuninori Morimoto */ 5779c673652SKuninori Morimoto upphub = 0; 5789c673652SKuninori Morimoto hubport = 0; 5799c673652SKuninori Morimoto if (!usbhsh_connected_to_rhdev(hcd, udev)) { 5809c673652SKuninori Morimoto /* if udev is not connected to rhdev, it means parent is Hub */ 5819c673652SKuninori Morimoto struct usbhsh_device *parent = usbhsh_device_parent(udev); 5829c673652SKuninori Morimoto 5839c673652SKuninori Morimoto upphub = usbhsh_device_number(hpriv, parent); 5849c673652SKuninori Morimoto hubport = usbhsh_device_hubport(udev); 5859c673652SKuninori Morimoto 5869c673652SKuninori Morimoto dev_dbg(dev, "%s connecte to Hub [%d:%d](%p)\n", __func__, 5879c673652SKuninori Morimoto upphub, hubport, parent); 5889c673652SKuninori Morimoto } 5899c673652SKuninori Morimoto 5903dd49268SKuninori Morimoto usbhs_set_device_config(priv, 591034d7c13SKuninori Morimoto usbhsh_device_number(hpriv, udev), 5929c673652SKuninori Morimoto upphub, hubport, usbv->speed); 593034d7c13SKuninori Morimoto 594034d7c13SKuninori Morimoto dev_dbg(dev, "%s [%d](%p)\n", __func__, 595034d7c13SKuninori Morimoto usbhsh_device_number(hpriv, udev), udev); 596034d7c13SKuninori Morimoto 597034d7c13SKuninori Morimoto return udev; 598034d7c13SKuninori Morimoto } 599034d7c13SKuninori Morimoto 6007aac8d15SKuninori Morimoto static void usbhsh_device_detach(struct usbhsh_hpriv *hpriv, 601034d7c13SKuninori Morimoto struct usbhsh_device *udev) 602034d7c13SKuninori Morimoto { 603034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 604d399f90dSKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 605034d7c13SKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 606034d7c13SKuninori Morimoto struct usb_device *usbv = usbhsh_udev_to_usbv(udev); 607d399f90dSKuninori Morimoto unsigned long flags; 608034d7c13SKuninori Morimoto 609034d7c13SKuninori Morimoto dev_dbg(dev, "%s [%d](%p)\n", __func__, 610034d7c13SKuninori Morimoto usbhsh_device_number(hpriv, udev), udev); 611034d7c13SKuninori Morimoto 612e4c57dedSKuninori Morimoto if (usbhsh_device_has_endpoint(udev)) { 613034d7c13SKuninori Morimoto dev_warn(dev, "udev still have endpoint\n"); 614e4c57dedSKuninori Morimoto usbhsh_endpoint_detach_all(hpriv, udev); 615e4c57dedSKuninori Morimoto } 616034d7c13SKuninori Morimoto 617c1e4877aSKuninori Morimoto /* 618c1e4877aSKuninori Morimoto * There is nothing to do if it is device0. 619c1e4877aSKuninori Morimoto * see 620c1e4877aSKuninori Morimoto * usbhsh_device_attach() 621c1e4877aSKuninori Morimoto * usbhsh_device_get() 622c1e4877aSKuninori Morimoto */ 623c1e4877aSKuninori Morimoto if (0 == usbhsh_device_number(hpriv, udev)) 624c1e4877aSKuninori Morimoto return; 625c1e4877aSKuninori Morimoto 626d399f90dSKuninori Morimoto /******************** spin lock ********************/ 627d399f90dSKuninori Morimoto usbhs_lock(priv, flags); 628034d7c13SKuninori Morimoto 629034d7c13SKuninori Morimoto /* 630034d7c13SKuninori Morimoto * usbhsh_usbv_to_udev() 631034d7c13SKuninori Morimoto * usbhsh_udev_to_usbv() 632034d7c13SKuninori Morimoto * will be disable 633034d7c13SKuninori Morimoto */ 634034d7c13SKuninori Morimoto dev_set_drvdata(&usbv->dev, NULL); 635034d7c13SKuninori Morimoto udev->usbv = NULL; 636034d7c13SKuninori Morimoto 637d399f90dSKuninori Morimoto usbhs_unlock(priv, flags); 638d399f90dSKuninori Morimoto /******************** spin unlock ******************/ 639034d7c13SKuninori Morimoto } 640034d7c13SKuninori Morimoto 641034d7c13SKuninori Morimoto /* 642034d7c13SKuninori Morimoto * queue push/pop 643034d7c13SKuninori Morimoto */ 644034d7c13SKuninori Morimoto static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) 645034d7c13SKuninori Morimoto { 64625234b46SKuninori Morimoto struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); 647034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 648034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 649034d7c13SKuninori Morimoto struct urb *urb = ureq->urb; 650034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 6516d0376f8SKuninori Morimoto int status = 0; 652034d7c13SKuninori Morimoto 653034d7c13SKuninori Morimoto dev_dbg(dev, "%s\n", __func__); 654034d7c13SKuninori Morimoto 655034d7c13SKuninori Morimoto if (!urb) { 656034d7c13SKuninori Morimoto dev_warn(dev, "pkt doesn't have urb\n"); 657034d7c13SKuninori Morimoto return; 658034d7c13SKuninori Morimoto } 659034d7c13SKuninori Morimoto 6606d0376f8SKuninori Morimoto if (!usbhsh_is_running(hpriv)) 6616d0376f8SKuninori Morimoto status = -ESHUTDOWN; 6626d0376f8SKuninori Morimoto 663034d7c13SKuninori Morimoto urb->actual_length = pkt->actual; 664034d7c13SKuninori Morimoto 6653edeee38SKuninori Morimoto usbhsh_endpoint_sequence_save(hpriv, urb, pkt); 666e0b64ce6SKuninori Morimoto usbhsh_ureq_free(hpriv, ureq); 667e0b64ce6SKuninori Morimoto 668d9b78f33SKuninori Morimoto usbhsh_pipe_detach(hpriv, usbhsh_ep_to_uep(urb->ep)); 669034d7c13SKuninori Morimoto 670034d7c13SKuninori Morimoto usb_hcd_unlink_urb_from_ep(hcd, urb); 6716d0376f8SKuninori Morimoto usb_hcd_giveback_urb(hcd, urb, status); 672034d7c13SKuninori Morimoto } 673034d7c13SKuninori Morimoto 674034d7c13SKuninori Morimoto static int usbhsh_queue_push(struct usb_hcd *hcd, 675ee8a0bf5SKuninori Morimoto struct urb *urb, 676ee8a0bf5SKuninori Morimoto gfp_t mem_flags) 677034d7c13SKuninori Morimoto { 678ee8a0bf5SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 6793eddc9e4SKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); 6803eddc9e4SKuninori Morimoto struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep); 681034d7c13SKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 682ee8a0bf5SKuninori Morimoto struct usbhsh_request *ureq; 683034d7c13SKuninori Morimoto void *buf; 6843edeee38SKuninori Morimoto int len, sequence; 685034d7c13SKuninori Morimoto 686034d7c13SKuninori Morimoto if (usb_pipeisoc(urb->pipe)) { 687034d7c13SKuninori Morimoto dev_err(dev, "pipe iso is not supported now\n"); 688034d7c13SKuninori Morimoto return -EIO; 689034d7c13SKuninori Morimoto } 690034d7c13SKuninori Morimoto 691ee8a0bf5SKuninori Morimoto /* this ureq will be freed on usbhsh_queue_done() */ 692ee8a0bf5SKuninori Morimoto ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); 693ee8a0bf5SKuninori Morimoto if (unlikely(!ureq)) { 694ee8a0bf5SKuninori Morimoto dev_err(dev, "ureq alloc fail\n"); 695ee8a0bf5SKuninori Morimoto return -ENOMEM; 696ee8a0bf5SKuninori Morimoto } 697ee8a0bf5SKuninori Morimoto 698034d7c13SKuninori Morimoto if (usb_pipein(urb->pipe)) 69987c2905fSKuninori Morimoto pipe->handler = &usbhs_fifo_dma_pop_handler; 700034d7c13SKuninori Morimoto else 70187c2905fSKuninori Morimoto pipe->handler = &usbhs_fifo_dma_push_handler; 702034d7c13SKuninori Morimoto 703034d7c13SKuninori Morimoto buf = (void *)(urb->transfer_buffer + urb->actual_length); 704034d7c13SKuninori Morimoto len = urb->transfer_buffer_length - urb->actual_length; 705034d7c13SKuninori Morimoto 7063edeee38SKuninori Morimoto sequence = usb_gettoggle(urb->dev, 7073edeee38SKuninori Morimoto usb_pipeendpoint(urb->pipe), 7083edeee38SKuninori Morimoto usb_pipeout(urb->pipe)); 7093edeee38SKuninori Morimoto 710034d7c13SKuninori Morimoto dev_dbg(dev, "%s\n", __func__); 711ee8a0bf5SKuninori Morimoto usbhs_pkt_push(pipe, &ureq->pkt, usbhsh_queue_done, 7123edeee38SKuninori Morimoto buf, len, (urb->transfer_flags & URB_ZERO_PACKET), 7133edeee38SKuninori Morimoto sequence); 7143edeee38SKuninori Morimoto 715034d7c13SKuninori Morimoto usbhs_pkt_start(pipe); 716034d7c13SKuninori Morimoto 717034d7c13SKuninori Morimoto return 0; 718034d7c13SKuninori Morimoto } 719034d7c13SKuninori Morimoto 7202d833faaSKuninori Morimoto static void usbhsh_queue_force_pop(struct usbhs_priv *priv, 7212d833faaSKuninori Morimoto struct usbhs_pipe *pipe) 7222d833faaSKuninori Morimoto { 7232d833faaSKuninori Morimoto struct usbhs_pkt *pkt; 7242d833faaSKuninori Morimoto 7252d833faaSKuninori Morimoto while (1) { 7262d833faaSKuninori Morimoto pkt = usbhs_pkt_pop(pipe, NULL); 7272d833faaSKuninori Morimoto if (!pkt) 7282d833faaSKuninori Morimoto break; 7292d833faaSKuninori Morimoto 7302d833faaSKuninori Morimoto /* 7312d833faaSKuninori Morimoto * if all packet are gone, usbhsh_endpoint_disable() 7322d833faaSKuninori Morimoto * will be called. 7332d833faaSKuninori Morimoto * then, attached device/endpoint/pipe will be detached 7342d833faaSKuninori Morimoto */ 7352d833faaSKuninori Morimoto usbhsh_queue_done(priv, pkt); 7362d833faaSKuninori Morimoto } 7372d833faaSKuninori Morimoto } 7382d833faaSKuninori Morimoto 7392d833faaSKuninori Morimoto static void usbhsh_queue_force_pop_all(struct usbhs_priv *priv) 7402d833faaSKuninori Morimoto { 7412d833faaSKuninori Morimoto struct usbhs_pipe *pos; 7422d833faaSKuninori Morimoto int i; 7432d833faaSKuninori Morimoto 7442d833faaSKuninori Morimoto usbhs_for_each_pipe_with_dcp(pos, priv, i) 7452d833faaSKuninori Morimoto usbhsh_queue_force_pop(priv, pos); 7462d833faaSKuninori Morimoto } 7472d833faaSKuninori Morimoto 748034d7c13SKuninori Morimoto /* 749034d7c13SKuninori Morimoto * DCP setup stage 750034d7c13SKuninori Morimoto */ 751034d7c13SKuninori Morimoto static int usbhsh_is_request_address(struct urb *urb) 752034d7c13SKuninori Morimoto { 75325234b46SKuninori Morimoto struct usb_ctrlrequest *req; 754034d7c13SKuninori Morimoto 75525234b46SKuninori Morimoto req = (struct usb_ctrlrequest *)urb->setup_packet; 756034d7c13SKuninori Morimoto 75725234b46SKuninori Morimoto if ((DeviceOutRequest == req->bRequestType << 8) && 75825234b46SKuninori Morimoto (USB_REQ_SET_ADDRESS == req->bRequest)) 759034d7c13SKuninori Morimoto return 1; 760034d7c13SKuninori Morimoto else 761034d7c13SKuninori Morimoto return 0; 762034d7c13SKuninori Morimoto } 763034d7c13SKuninori Morimoto 764034d7c13SKuninori Morimoto static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, 765034d7c13SKuninori Morimoto struct urb *urb, 766034d7c13SKuninori Morimoto struct usbhs_pipe *pipe) 767034d7c13SKuninori Morimoto { 768034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 769034d7c13SKuninori Morimoto struct usb_ctrlrequest req; 770034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 771034d7c13SKuninori Morimoto 772034d7c13SKuninori Morimoto /* 773034d7c13SKuninori Morimoto * wait setup packet ACK 774034d7c13SKuninori Morimoto * see 775034d7c13SKuninori Morimoto * usbhsh_irq_setup_ack() 776034d7c13SKuninori Morimoto * usbhsh_irq_setup_err() 777034d7c13SKuninori Morimoto */ 7787fccd480SKuninori Morimoto init_completion(&hpriv->setup_ack_done); 779034d7c13SKuninori Morimoto 780034d7c13SKuninori Morimoto /* copy original request */ 781034d7c13SKuninori Morimoto memcpy(&req, urb->setup_packet, sizeof(struct usb_ctrlrequest)); 782034d7c13SKuninori Morimoto 783034d7c13SKuninori Morimoto /* 784034d7c13SKuninori Morimoto * renesas_usbhs can not use original usb address. 785034d7c13SKuninori Morimoto * see HARDWARE LIMITATION. 786c1e4877aSKuninori Morimoto * modify usb address here to use attached device. 787c1e4877aSKuninori Morimoto * see usbhsh_device_attach() 788034d7c13SKuninori Morimoto */ 789034d7c13SKuninori Morimoto if (usbhsh_is_request_address(urb)) { 790c1e4877aSKuninori Morimoto struct usb_device *usbv = usbhsh_urb_to_usbv(urb); 791c1e4877aSKuninori Morimoto struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv); 792c1e4877aSKuninori Morimoto 793c1e4877aSKuninori Morimoto /* udev is a attached device */ 794c1e4877aSKuninori Morimoto req.wValue = usbhsh_device_number(hpriv, udev); 795034d7c13SKuninori Morimoto dev_dbg(dev, "create new address - %d\n", req.wValue); 796034d7c13SKuninori Morimoto } 797034d7c13SKuninori Morimoto 798034d7c13SKuninori Morimoto /* set request */ 799034d7c13SKuninori Morimoto usbhs_usbreq_set_val(priv, &req); 800034d7c13SKuninori Morimoto 801034d7c13SKuninori Morimoto /* 802034d7c13SKuninori Morimoto * wait setup packet ACK 803034d7c13SKuninori Morimoto */ 8047fccd480SKuninori Morimoto wait_for_completion(&hpriv->setup_ack_done); 805034d7c13SKuninori Morimoto 806034d7c13SKuninori Morimoto dev_dbg(dev, "%s done\n", __func__); 807034d7c13SKuninori Morimoto } 808034d7c13SKuninori Morimoto 809034d7c13SKuninori Morimoto /* 810034d7c13SKuninori Morimoto * DCP data stage 811034d7c13SKuninori Morimoto */ 812034d7c13SKuninori Morimoto static void usbhsh_data_stage_packet_done(struct usbhs_priv *priv, 813034d7c13SKuninori Morimoto struct usbhs_pkt *pkt) 814034d7c13SKuninori Morimoto { 81525234b46SKuninori Morimoto struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); 816034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 817034d7c13SKuninori Morimoto 818034d7c13SKuninori Morimoto /* this ureq was connected to urb when usbhsh_urb_enqueue() */ 819034d7c13SKuninori Morimoto 82025234b46SKuninori Morimoto usbhsh_ureq_free(hpriv, ureq); 821034d7c13SKuninori Morimoto } 822034d7c13SKuninori Morimoto 823ee8a0bf5SKuninori Morimoto static int usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv, 824034d7c13SKuninori Morimoto struct urb *urb, 825ee8a0bf5SKuninori Morimoto struct usbhs_pipe *pipe, 826ee8a0bf5SKuninori Morimoto gfp_t mem_flags) 827ee8a0bf5SKuninori Morimoto 828034d7c13SKuninori Morimoto { 829034d7c13SKuninori Morimoto struct usbhsh_request *ureq; 830034d7c13SKuninori Morimoto 831ee8a0bf5SKuninori Morimoto /* this ureq will be freed on usbhsh_data_stage_packet_done() */ 832ee8a0bf5SKuninori Morimoto ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); 833ee8a0bf5SKuninori Morimoto if (unlikely(!ureq)) 834ee8a0bf5SKuninori Morimoto return -ENOMEM; 835034d7c13SKuninori Morimoto 836034d7c13SKuninori Morimoto if (usb_pipein(urb->pipe)) 837034d7c13SKuninori Morimoto pipe->handler = &usbhs_dcp_data_stage_in_handler; 838034d7c13SKuninori Morimoto else 839034d7c13SKuninori Morimoto pipe->handler = &usbhs_dcp_data_stage_out_handler; 840034d7c13SKuninori Morimoto 841ee8a0bf5SKuninori Morimoto usbhs_pkt_push(pipe, &ureq->pkt, 842034d7c13SKuninori Morimoto usbhsh_data_stage_packet_done, 843034d7c13SKuninori Morimoto urb->transfer_buffer, 844034d7c13SKuninori Morimoto urb->transfer_buffer_length, 8453edeee38SKuninori Morimoto (urb->transfer_flags & URB_ZERO_PACKET), 8463edeee38SKuninori Morimoto -1); 847ee8a0bf5SKuninori Morimoto 848ee8a0bf5SKuninori Morimoto return 0; 849034d7c13SKuninori Morimoto } 850034d7c13SKuninori Morimoto 851034d7c13SKuninori Morimoto /* 852034d7c13SKuninori Morimoto * DCP status stage 853034d7c13SKuninori Morimoto */ 854ee8a0bf5SKuninori Morimoto static int usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv, 855034d7c13SKuninori Morimoto struct urb *urb, 856ee8a0bf5SKuninori Morimoto struct usbhs_pipe *pipe, 857ee8a0bf5SKuninori Morimoto gfp_t mem_flags) 858034d7c13SKuninori Morimoto { 859034d7c13SKuninori Morimoto struct usbhsh_request *ureq; 860034d7c13SKuninori Morimoto 861ee8a0bf5SKuninori Morimoto /* This ureq will be freed on usbhsh_queue_done() */ 862ee8a0bf5SKuninori Morimoto ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); 863ee8a0bf5SKuninori Morimoto if (unlikely(!ureq)) 864ee8a0bf5SKuninori Morimoto return -ENOMEM; 865034d7c13SKuninori Morimoto 866034d7c13SKuninori Morimoto if (usb_pipein(urb->pipe)) 867034d7c13SKuninori Morimoto pipe->handler = &usbhs_dcp_status_stage_in_handler; 868034d7c13SKuninori Morimoto else 869034d7c13SKuninori Morimoto pipe->handler = &usbhs_dcp_status_stage_out_handler; 870034d7c13SKuninori Morimoto 871ee8a0bf5SKuninori Morimoto usbhs_pkt_push(pipe, &ureq->pkt, 872034d7c13SKuninori Morimoto usbhsh_queue_done, 873034d7c13SKuninori Morimoto NULL, 874034d7c13SKuninori Morimoto urb->transfer_buffer_length, 8753edeee38SKuninori Morimoto 0, -1); 876ee8a0bf5SKuninori Morimoto 877ee8a0bf5SKuninori Morimoto return 0; 878034d7c13SKuninori Morimoto } 879034d7c13SKuninori Morimoto 880034d7c13SKuninori Morimoto static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, 881ee8a0bf5SKuninori Morimoto struct urb *urb, 882ee8a0bf5SKuninori Morimoto gfp_t mflags) 883034d7c13SKuninori Morimoto { 884ee8a0bf5SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 8853eddc9e4SKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); 8863eddc9e4SKuninori Morimoto struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep); 887034d7c13SKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 888ee8a0bf5SKuninori Morimoto int ret; 889034d7c13SKuninori Morimoto 890034d7c13SKuninori Morimoto dev_dbg(dev, "%s\n", __func__); 891034d7c13SKuninori Morimoto 892034d7c13SKuninori Morimoto /* 893034d7c13SKuninori Morimoto * setup stage 894034d7c13SKuninori Morimoto * 895034d7c13SKuninori Morimoto * usbhsh_send_setup_stage_packet() wait SACK/SIGN 896034d7c13SKuninori Morimoto */ 897034d7c13SKuninori Morimoto usbhsh_setup_stage_packet_push(hpriv, urb, pipe); 898034d7c13SKuninori Morimoto 899034d7c13SKuninori Morimoto /* 900034d7c13SKuninori Morimoto * data stage 901034d7c13SKuninori Morimoto * 902034d7c13SKuninori Morimoto * It is pushed only when urb has buffer. 903034d7c13SKuninori Morimoto */ 904ee8a0bf5SKuninori Morimoto if (urb->transfer_buffer_length) { 905ee8a0bf5SKuninori Morimoto ret = usbhsh_data_stage_packet_push(hpriv, urb, pipe, mflags); 906ee8a0bf5SKuninori Morimoto if (ret < 0) { 907ee8a0bf5SKuninori Morimoto dev_err(dev, "data stage failed\n"); 908ee8a0bf5SKuninori Morimoto return ret; 909ee8a0bf5SKuninori Morimoto } 910ee8a0bf5SKuninori Morimoto } 911034d7c13SKuninori Morimoto 912034d7c13SKuninori Morimoto /* 913034d7c13SKuninori Morimoto * status stage 914034d7c13SKuninori Morimoto */ 915ee8a0bf5SKuninori Morimoto ret = usbhsh_status_stage_packet_push(hpriv, urb, pipe, mflags); 916ee8a0bf5SKuninori Morimoto if (ret < 0) { 917ee8a0bf5SKuninori Morimoto dev_err(dev, "status stage failed\n"); 918ee8a0bf5SKuninori Morimoto return ret; 919ee8a0bf5SKuninori Morimoto } 920034d7c13SKuninori Morimoto 921034d7c13SKuninori Morimoto /* 922034d7c13SKuninori Morimoto * start pushed packets 923034d7c13SKuninori Morimoto */ 924034d7c13SKuninori Morimoto usbhs_pkt_start(pipe); 925034d7c13SKuninori Morimoto 926034d7c13SKuninori Morimoto return 0; 927034d7c13SKuninori Morimoto } 928034d7c13SKuninori Morimoto 929034d7c13SKuninori Morimoto /* 930034d7c13SKuninori Morimoto * dma map functions 931034d7c13SKuninori Morimoto */ 932034d7c13SKuninori Morimoto static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map) 933034d7c13SKuninori Morimoto { 93487c2905fSKuninori Morimoto if (map) { 93587c2905fSKuninori Morimoto struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); 93687c2905fSKuninori Morimoto struct urb *urb = ureq->urb; 93787c2905fSKuninori Morimoto 93887c2905fSKuninori Morimoto /* it can not use scatter/gather */ 93987c2905fSKuninori Morimoto if (urb->num_sgs) 94087c2905fSKuninori Morimoto return -EINVAL; 94187c2905fSKuninori Morimoto 94287c2905fSKuninori Morimoto pkt->dma = urb->transfer_dma; 94387c2905fSKuninori Morimoto if (!pkt->dma) 94487c2905fSKuninori Morimoto return -EINVAL; 94587c2905fSKuninori Morimoto } 94687c2905fSKuninori Morimoto 947034d7c13SKuninori Morimoto return 0; 948034d7c13SKuninori Morimoto } 949034d7c13SKuninori Morimoto 950034d7c13SKuninori Morimoto /* 951034d7c13SKuninori Morimoto * for hc_driver 952034d7c13SKuninori Morimoto */ 953034d7c13SKuninori Morimoto static int usbhsh_host_start(struct usb_hcd *hcd) 954034d7c13SKuninori Morimoto { 955034d7c13SKuninori Morimoto return 0; 956034d7c13SKuninori Morimoto } 957034d7c13SKuninori Morimoto 958034d7c13SKuninori Morimoto static void usbhsh_host_stop(struct usb_hcd *hcd) 959034d7c13SKuninori Morimoto { 960034d7c13SKuninori Morimoto } 961034d7c13SKuninori Morimoto 962034d7c13SKuninori Morimoto static int usbhsh_urb_enqueue(struct usb_hcd *hcd, 963034d7c13SKuninori Morimoto struct urb *urb, 964034d7c13SKuninori Morimoto gfp_t mem_flags) 965034d7c13SKuninori Morimoto { 966034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 967034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 968034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 969034d7c13SKuninori Morimoto struct usb_host_endpoint *ep = urb->ep; 9707aac8d15SKuninori Morimoto struct usbhsh_device *new_udev = NULL; 97173ef635aSKuninori Morimoto int is_dir_in = usb_pipein(urb->pipe); 972034d7c13SKuninori Morimoto int ret; 973034d7c13SKuninori Morimoto 97473ef635aSKuninori Morimoto dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); 975034d7c13SKuninori Morimoto 976b1930da0SKuninori Morimoto if (!usbhsh_is_running(hpriv)) { 977b1930da0SKuninori Morimoto ret = -EIO; 97815a3838bSKuninori Morimoto dev_err(dev, "host is not running\n"); 979b1930da0SKuninori Morimoto goto usbhsh_urb_enqueue_error_not_linked; 980b1930da0SKuninori Morimoto } 981b1930da0SKuninori Morimoto 982034d7c13SKuninori Morimoto ret = usb_hcd_link_urb_to_ep(hcd, urb); 98315a3838bSKuninori Morimoto if (ret) { 98415a3838bSKuninori Morimoto dev_err(dev, "urb link failed\n"); 985034d7c13SKuninori Morimoto goto usbhsh_urb_enqueue_error_not_linked; 986034d7c13SKuninori Morimoto } 987034d7c13SKuninori Morimoto 988034d7c13SKuninori Morimoto /* 9897aac8d15SKuninori Morimoto * attach udev if needed 990e5679d07SKuninori Morimoto * see [image of mod_host] 991034d7c13SKuninori Morimoto */ 992c1e4877aSKuninori Morimoto if (!usbhsh_device_get(hpriv, urb)) { 9937aac8d15SKuninori Morimoto new_udev = usbhsh_device_attach(hpriv, urb); 99437332ee0SKuninori Morimoto if (!new_udev) { 99537332ee0SKuninori Morimoto ret = -EIO; 99615a3838bSKuninori Morimoto dev_err(dev, "device attach failed\n"); 997034d7c13SKuninori Morimoto goto usbhsh_urb_enqueue_error_not_linked; 998034d7c13SKuninori Morimoto } 99937332ee0SKuninori Morimoto } 1000034d7c13SKuninori Morimoto 1001034d7c13SKuninori Morimoto /* 10024825093eSKuninori Morimoto * attach endpoint if needed 1003e5679d07SKuninori Morimoto * see [image of mod_host] 1004034d7c13SKuninori Morimoto */ 10054825093eSKuninori Morimoto if (!usbhsh_ep_to_uep(ep)) { 10064825093eSKuninori Morimoto ret = usbhsh_endpoint_attach(hpriv, urb, mem_flags); 100715a3838bSKuninori Morimoto if (ret < 0) { 100815a3838bSKuninori Morimoto dev_err(dev, "endpoint attach failed\n"); 1009034d7c13SKuninori Morimoto goto usbhsh_urb_enqueue_error_free_device; 1010034d7c13SKuninori Morimoto } 101115a3838bSKuninori Morimoto } 1012034d7c13SKuninori Morimoto 1013034d7c13SKuninori Morimoto /* 1014e5679d07SKuninori Morimoto * attach pipe to endpoint 1015e5679d07SKuninori Morimoto * see [image of mod_host] 1016034d7c13SKuninori Morimoto */ 1017e5679d07SKuninori Morimoto ret = usbhsh_pipe_attach(hpriv, urb); 101815a3838bSKuninori Morimoto if (ret < 0) { 101915a3838bSKuninori Morimoto dev_err(dev, "pipe attach failed\n"); 1020034d7c13SKuninori Morimoto goto usbhsh_urb_enqueue_error_free_endpoint; 1021034d7c13SKuninori Morimoto } 1022034d7c13SKuninori Morimoto 1023034d7c13SKuninori Morimoto /* 1024034d7c13SKuninori Morimoto * push packet 1025034d7c13SKuninori Morimoto */ 1026034d7c13SKuninori Morimoto if (usb_pipecontrol(urb->pipe)) 10273eddc9e4SKuninori Morimoto ret = usbhsh_dcp_queue_push(hcd, urb, mem_flags); 1028034d7c13SKuninori Morimoto else 10293eddc9e4SKuninori Morimoto ret = usbhsh_queue_push(hcd, urb, mem_flags); 1030034d7c13SKuninori Morimoto 1031ee8a0bf5SKuninori Morimoto return ret; 1032034d7c13SKuninori Morimoto 1033034d7c13SKuninori Morimoto usbhsh_urb_enqueue_error_free_endpoint: 1034e5679d07SKuninori Morimoto usbhsh_endpoint_detach(hpriv, ep); 1035034d7c13SKuninori Morimoto usbhsh_urb_enqueue_error_free_device: 1036034d7c13SKuninori Morimoto if (new_udev) 10377aac8d15SKuninori Morimoto usbhsh_device_detach(hpriv, new_udev); 1038034d7c13SKuninori Morimoto usbhsh_urb_enqueue_error_not_linked: 1039034d7c13SKuninori Morimoto 1040034d7c13SKuninori Morimoto dev_dbg(dev, "%s error\n", __func__); 1041034d7c13SKuninori Morimoto 1042034d7c13SKuninori Morimoto return ret; 1043034d7c13SKuninori Morimoto } 1044034d7c13SKuninori Morimoto 1045034d7c13SKuninori Morimoto static int usbhsh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) 1046034d7c13SKuninori Morimoto { 1047034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 1048034d7c13SKuninori Morimoto struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); 1049034d7c13SKuninori Morimoto 1050034d7c13SKuninori Morimoto if (ureq) { 105154796543SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 105254796543SKuninori Morimoto struct usbhs_pkt *pkt = &ureq->pkt; 105354796543SKuninori Morimoto 105454796543SKuninori Morimoto usbhs_pkt_pop(pkt->pipe, pkt); 105554796543SKuninori Morimoto usbhsh_queue_done(priv, pkt); 1056034d7c13SKuninori Morimoto } 1057034d7c13SKuninori Morimoto 1058034d7c13SKuninori Morimoto return 0; 1059034d7c13SKuninori Morimoto } 1060034d7c13SKuninori Morimoto 1061034d7c13SKuninori Morimoto static void usbhsh_endpoint_disable(struct usb_hcd *hcd, 1062034d7c13SKuninori Morimoto struct usb_host_endpoint *ep) 1063034d7c13SKuninori Morimoto { 1064034d7c13SKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); 1065034d7c13SKuninori Morimoto struct usbhsh_device *udev; 1066034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv; 1067034d7c13SKuninori Morimoto 1068034d7c13SKuninori Morimoto /* 1069034d7c13SKuninori Morimoto * this function might be called manytimes by same hcd/ep 1070fca8ab7eSKuninori Morimoto * in-endpoint == out-endpoint if ep == dcp. 1071034d7c13SKuninori Morimoto */ 1072034d7c13SKuninori Morimoto if (!uep) 1073034d7c13SKuninori Morimoto return; 1074034d7c13SKuninori Morimoto 1075034d7c13SKuninori Morimoto udev = usbhsh_uep_to_udev(uep); 1076034d7c13SKuninori Morimoto hpriv = usbhsh_hcd_to_hpriv(hcd); 1077034d7c13SKuninori Morimoto 10784825093eSKuninori Morimoto usbhsh_endpoint_detach(hpriv, ep); 1079034d7c13SKuninori Morimoto 1080034d7c13SKuninori Morimoto /* 1081034d7c13SKuninori Morimoto * if there is no endpoint, 1082034d7c13SKuninori Morimoto * free device 1083034d7c13SKuninori Morimoto */ 1084034d7c13SKuninori Morimoto if (!usbhsh_device_has_endpoint(udev)) 10857aac8d15SKuninori Morimoto usbhsh_device_detach(hpriv, udev); 1086034d7c13SKuninori Morimoto } 1087034d7c13SKuninori Morimoto 1088034d7c13SKuninori Morimoto static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) 1089034d7c13SKuninori Morimoto { 1090034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 1091034d7c13SKuninori Morimoto int roothub_id = 1; /* only 1 root hub */ 1092034d7c13SKuninori Morimoto 1093034d7c13SKuninori Morimoto /* 1094034d7c13SKuninori Morimoto * does port stat was changed ? 1095034d7c13SKuninori Morimoto * check USB_PORT_STAT_C_xxx << 16 1096034d7c13SKuninori Morimoto */ 1097034d7c13SKuninori Morimoto if (usbhsh_port_stat_get(hpriv) & 0xFFFF0000) 1098034d7c13SKuninori Morimoto *buf = (1 << roothub_id); 1099034d7c13SKuninori Morimoto else 1100034d7c13SKuninori Morimoto *buf = 0; 1101034d7c13SKuninori Morimoto 1102034d7c13SKuninori Morimoto return !!(*buf); 1103034d7c13SKuninori Morimoto } 1104034d7c13SKuninori Morimoto 1105034d7c13SKuninori Morimoto static int __usbhsh_hub_hub_feature(struct usbhsh_hpriv *hpriv, 1106034d7c13SKuninori Morimoto u16 typeReq, u16 wValue, 1107034d7c13SKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1108034d7c13SKuninori Morimoto { 1109034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1110034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1111034d7c13SKuninori Morimoto 1112034d7c13SKuninori Morimoto switch (wValue) { 1113034d7c13SKuninori Morimoto case C_HUB_OVER_CURRENT: 1114034d7c13SKuninori Morimoto case C_HUB_LOCAL_POWER: 1115034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: C_HUB_xx\n", __func__); 1116034d7c13SKuninori Morimoto return 0; 1117034d7c13SKuninori Morimoto } 1118034d7c13SKuninori Morimoto 1119034d7c13SKuninori Morimoto return -EPIPE; 1120034d7c13SKuninori Morimoto } 1121034d7c13SKuninori Morimoto 1122034d7c13SKuninori Morimoto static int __usbhsh_hub_port_feature(struct usbhsh_hpriv *hpriv, 1123034d7c13SKuninori Morimoto u16 typeReq, u16 wValue, 1124034d7c13SKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1125034d7c13SKuninori Morimoto { 1126034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1127034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1128034d7c13SKuninori Morimoto int enable = (typeReq == SetPortFeature); 1129034d7c13SKuninori Morimoto int speed, i, timeout = 128; 1130034d7c13SKuninori Morimoto int roothub_id = 1; /* only 1 root hub */ 1131034d7c13SKuninori Morimoto 1132034d7c13SKuninori Morimoto /* common error */ 1133034d7c13SKuninori Morimoto if (wIndex > roothub_id || wLength != 0) 1134034d7c13SKuninori Morimoto return -EPIPE; 1135034d7c13SKuninori Morimoto 1136034d7c13SKuninori Morimoto /* check wValue */ 1137034d7c13SKuninori Morimoto switch (wValue) { 1138034d7c13SKuninori Morimoto case USB_PORT_FEAT_POWER: 1139034d7c13SKuninori Morimoto usbhs_vbus_ctrl(priv, enable); 1140034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: USB_PORT_FEAT_POWER\n", __func__); 1141034d7c13SKuninori Morimoto break; 1142034d7c13SKuninori Morimoto 1143034d7c13SKuninori Morimoto case USB_PORT_FEAT_ENABLE: 1144034d7c13SKuninori Morimoto case USB_PORT_FEAT_SUSPEND: 1145034d7c13SKuninori Morimoto case USB_PORT_FEAT_C_ENABLE: 1146034d7c13SKuninori Morimoto case USB_PORT_FEAT_C_SUSPEND: 1147034d7c13SKuninori Morimoto case USB_PORT_FEAT_C_CONNECTION: 1148034d7c13SKuninori Morimoto case USB_PORT_FEAT_C_OVER_CURRENT: 1149034d7c13SKuninori Morimoto case USB_PORT_FEAT_C_RESET: 1150034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: USB_PORT_FEAT_xxx\n", __func__); 1151034d7c13SKuninori Morimoto break; 1152034d7c13SKuninori Morimoto 1153034d7c13SKuninori Morimoto case USB_PORT_FEAT_RESET: 1154034d7c13SKuninori Morimoto if (!enable) 1155034d7c13SKuninori Morimoto break; 1156034d7c13SKuninori Morimoto 1157034d7c13SKuninori Morimoto usbhsh_port_stat_clear(hpriv, 1158034d7c13SKuninori Morimoto USB_PORT_STAT_HIGH_SPEED | 1159034d7c13SKuninori Morimoto USB_PORT_STAT_LOW_SPEED); 1160034d7c13SKuninori Morimoto 11612d833faaSKuninori Morimoto usbhsh_queue_force_pop_all(priv); 11622d833faaSKuninori Morimoto 1163034d7c13SKuninori Morimoto usbhs_bus_send_reset(priv); 1164034d7c13SKuninori Morimoto msleep(20); 1165034d7c13SKuninori Morimoto usbhs_bus_send_sof_enable(priv); 1166034d7c13SKuninori Morimoto 1167034d7c13SKuninori Morimoto for (i = 0; i < timeout ; i++) { 1168034d7c13SKuninori Morimoto switch (usbhs_bus_get_speed(priv)) { 1169034d7c13SKuninori Morimoto case USB_SPEED_LOW: 1170034d7c13SKuninori Morimoto speed = USB_PORT_STAT_LOW_SPEED; 1171034d7c13SKuninori Morimoto goto got_usb_bus_speed; 1172034d7c13SKuninori Morimoto case USB_SPEED_HIGH: 1173034d7c13SKuninori Morimoto speed = USB_PORT_STAT_HIGH_SPEED; 1174034d7c13SKuninori Morimoto goto got_usb_bus_speed; 1175034d7c13SKuninori Morimoto case USB_SPEED_FULL: 1176034d7c13SKuninori Morimoto speed = 0; 1177034d7c13SKuninori Morimoto goto got_usb_bus_speed; 1178034d7c13SKuninori Morimoto } 1179034d7c13SKuninori Morimoto 1180034d7c13SKuninori Morimoto msleep(20); 1181034d7c13SKuninori Morimoto } 1182034d7c13SKuninori Morimoto return -EPIPE; 1183034d7c13SKuninori Morimoto 1184034d7c13SKuninori Morimoto got_usb_bus_speed: 1185034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, speed); 1186034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_ENABLE); 1187034d7c13SKuninori Morimoto 1188034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: USB_PORT_FEAT_RESET (speed = %d)\n", 1189034d7c13SKuninori Morimoto __func__, speed); 1190034d7c13SKuninori Morimoto 1191034d7c13SKuninori Morimoto /* status change is not needed */ 1192034d7c13SKuninori Morimoto return 0; 1193034d7c13SKuninori Morimoto 1194034d7c13SKuninori Morimoto default: 1195034d7c13SKuninori Morimoto return -EPIPE; 1196034d7c13SKuninori Morimoto } 1197034d7c13SKuninori Morimoto 1198034d7c13SKuninori Morimoto /* set/clear status */ 1199034d7c13SKuninori Morimoto if (enable) 1200034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, (1 << wValue)); 1201034d7c13SKuninori Morimoto else 1202034d7c13SKuninori Morimoto usbhsh_port_stat_clear(hpriv, (1 << wValue)); 1203034d7c13SKuninori Morimoto 1204034d7c13SKuninori Morimoto return 0; 1205034d7c13SKuninori Morimoto } 1206034d7c13SKuninori Morimoto 1207034d7c13SKuninori Morimoto static int __usbhsh_hub_get_status(struct usbhsh_hpriv *hpriv, 1208034d7c13SKuninori Morimoto u16 typeReq, u16 wValue, 1209034d7c13SKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1210034d7c13SKuninori Morimoto { 1211034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1212034d7c13SKuninori Morimoto struct usb_hub_descriptor *desc = (struct usb_hub_descriptor *)buf; 1213034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1214034d7c13SKuninori Morimoto int roothub_id = 1; /* only 1 root hub */ 1215034d7c13SKuninori Morimoto 1216034d7c13SKuninori Morimoto switch (typeReq) { 1217034d7c13SKuninori Morimoto case GetHubStatus: 1218034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: GetHubStatus\n", __func__); 1219034d7c13SKuninori Morimoto 1220034d7c13SKuninori Morimoto *buf = 0x00; 1221034d7c13SKuninori Morimoto break; 1222034d7c13SKuninori Morimoto 1223034d7c13SKuninori Morimoto case GetPortStatus: 1224034d7c13SKuninori Morimoto if (wIndex != roothub_id) 1225034d7c13SKuninori Morimoto return -EPIPE; 1226034d7c13SKuninori Morimoto 1227034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: GetPortStatus\n", __func__); 1228034d7c13SKuninori Morimoto *(__le32 *)buf = cpu_to_le32(usbhsh_port_stat_get(hpriv)); 1229034d7c13SKuninori Morimoto break; 1230034d7c13SKuninori Morimoto 1231034d7c13SKuninori Morimoto case GetHubDescriptor: 1232b11373deSSergei Shtylyov desc->bDescriptorType = USB_DT_HUB; 1233034d7c13SKuninori Morimoto desc->bHubContrCurrent = 0; 1234034d7c13SKuninori Morimoto desc->bNbrPorts = roothub_id; 1235034d7c13SKuninori Morimoto desc->bDescLength = 9; 1236034d7c13SKuninori Morimoto desc->bPwrOn2PwrGood = 0; 1237a1837d15SSergei Shtylyov desc->wHubCharacteristics = 1238a1837d15SSergei Shtylyov cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_NO_OCPM); 1239034d7c13SKuninori Morimoto desc->u.hs.DeviceRemovable[0] = (roothub_id << 1); 1240034d7c13SKuninori Morimoto desc->u.hs.DeviceRemovable[1] = ~0; 1241034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: GetHubDescriptor\n", __func__); 1242034d7c13SKuninori Morimoto break; 1243034d7c13SKuninori Morimoto } 1244034d7c13SKuninori Morimoto 1245034d7c13SKuninori Morimoto return 0; 1246034d7c13SKuninori Morimoto } 1247034d7c13SKuninori Morimoto 1248034d7c13SKuninori Morimoto static int usbhsh_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, 1249034d7c13SKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1250034d7c13SKuninori Morimoto { 1251034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 1252034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1253034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1254034d7c13SKuninori Morimoto int ret = -EPIPE; 1255034d7c13SKuninori Morimoto 1256034d7c13SKuninori Morimoto switch (typeReq) { 1257034d7c13SKuninori Morimoto 1258034d7c13SKuninori Morimoto /* Hub Feature */ 1259034d7c13SKuninori Morimoto case ClearHubFeature: 1260034d7c13SKuninori Morimoto case SetHubFeature: 1261034d7c13SKuninori Morimoto ret = __usbhsh_hub_hub_feature(hpriv, typeReq, 1262034d7c13SKuninori Morimoto wValue, wIndex, buf, wLength); 1263034d7c13SKuninori Morimoto break; 1264034d7c13SKuninori Morimoto 1265034d7c13SKuninori Morimoto /* Port Feature */ 1266034d7c13SKuninori Morimoto case SetPortFeature: 1267034d7c13SKuninori Morimoto case ClearPortFeature: 1268034d7c13SKuninori Morimoto ret = __usbhsh_hub_port_feature(hpriv, typeReq, 1269034d7c13SKuninori Morimoto wValue, wIndex, buf, wLength); 1270034d7c13SKuninori Morimoto break; 1271034d7c13SKuninori Morimoto 1272034d7c13SKuninori Morimoto /* Get status */ 1273034d7c13SKuninori Morimoto case GetHubStatus: 1274034d7c13SKuninori Morimoto case GetPortStatus: 1275034d7c13SKuninori Morimoto case GetHubDescriptor: 1276034d7c13SKuninori Morimoto ret = __usbhsh_hub_get_status(hpriv, typeReq, 1277034d7c13SKuninori Morimoto wValue, wIndex, buf, wLength); 1278034d7c13SKuninori Morimoto break; 1279034d7c13SKuninori Morimoto } 1280034d7c13SKuninori Morimoto 1281034d7c13SKuninori Morimoto dev_dbg(dev, "typeReq = %x, ret = %d, port_stat = %x\n", 1282034d7c13SKuninori Morimoto typeReq, ret, usbhsh_port_stat_get(hpriv)); 1283034d7c13SKuninori Morimoto 1284034d7c13SKuninori Morimoto return ret; 1285034d7c13SKuninori Morimoto } 1286034d7c13SKuninori Morimoto 1287e7ae64c7SKuninori Morimoto static int usbhsh_bus_nop(struct usb_hcd *hcd) 1288e7ae64c7SKuninori Morimoto { 1289e7ae64c7SKuninori Morimoto /* nothing to do */ 1290e7ae64c7SKuninori Morimoto return 0; 1291e7ae64c7SKuninori Morimoto } 1292e7ae64c7SKuninori Morimoto 1293034d7c13SKuninori Morimoto static struct hc_driver usbhsh_driver = { 1294034d7c13SKuninori Morimoto .description = usbhsh_hcd_name, 1295034d7c13SKuninori Morimoto .hcd_priv_size = sizeof(struct usbhsh_hpriv), 1296034d7c13SKuninori Morimoto 1297034d7c13SKuninori Morimoto /* 1298034d7c13SKuninori Morimoto * generic hardware linkage 1299034d7c13SKuninori Morimoto */ 1300034d7c13SKuninori Morimoto .flags = HCD_USB2, 1301034d7c13SKuninori Morimoto 1302034d7c13SKuninori Morimoto .start = usbhsh_host_start, 1303034d7c13SKuninori Morimoto .stop = usbhsh_host_stop, 1304034d7c13SKuninori Morimoto 1305034d7c13SKuninori Morimoto /* 1306034d7c13SKuninori Morimoto * managing i/o requests and associated device resources 1307034d7c13SKuninori Morimoto */ 1308034d7c13SKuninori Morimoto .urb_enqueue = usbhsh_urb_enqueue, 1309034d7c13SKuninori Morimoto .urb_dequeue = usbhsh_urb_dequeue, 1310034d7c13SKuninori Morimoto .endpoint_disable = usbhsh_endpoint_disable, 1311034d7c13SKuninori Morimoto 1312034d7c13SKuninori Morimoto /* 1313034d7c13SKuninori Morimoto * root hub 1314034d7c13SKuninori Morimoto */ 1315034d7c13SKuninori Morimoto .hub_status_data = usbhsh_hub_status_data, 1316034d7c13SKuninori Morimoto .hub_control = usbhsh_hub_control, 1317e7ae64c7SKuninori Morimoto .bus_suspend = usbhsh_bus_nop, 1318e7ae64c7SKuninori Morimoto .bus_resume = usbhsh_bus_nop, 1319034d7c13SKuninori Morimoto }; 1320034d7c13SKuninori Morimoto 1321034d7c13SKuninori Morimoto /* 1322034d7c13SKuninori Morimoto * interrupt functions 1323034d7c13SKuninori Morimoto */ 1324034d7c13SKuninori Morimoto static int usbhsh_irq_attch(struct usbhs_priv *priv, 1325034d7c13SKuninori Morimoto struct usbhs_irq_state *irq_state) 1326034d7c13SKuninori Morimoto { 1327034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1328034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1329034d7c13SKuninori Morimoto 1330034d7c13SKuninori Morimoto dev_dbg(dev, "device attached\n"); 1331034d7c13SKuninori Morimoto 1332034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_CONNECTION); 1333034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); 1334034d7c13SKuninori Morimoto 133531e00fd1SKuninori Morimoto /* 133631e00fd1SKuninori Morimoto * attch interrupt might happen infinitely on some device 133731e00fd1SKuninori Morimoto * (on self power USB hub ?) 133831e00fd1SKuninori Morimoto * disable it here. 1339b1930da0SKuninori Morimoto * 1340b1930da0SKuninori Morimoto * usbhsh_is_running() becomes effective 1341b1930da0SKuninori Morimoto * according to this process. 1342b1930da0SKuninori Morimoto * see 1343b1930da0SKuninori Morimoto * usbhsh_is_running() 1344b1930da0SKuninori Morimoto * usbhsh_urb_enqueue() 134531e00fd1SKuninori Morimoto */ 134631e00fd1SKuninori Morimoto hpriv->mod.irq_attch = NULL; 134731e00fd1SKuninori Morimoto usbhs_irq_callback_update(priv, &hpriv->mod); 134831e00fd1SKuninori Morimoto 1349034d7c13SKuninori Morimoto return 0; 1350034d7c13SKuninori Morimoto } 1351034d7c13SKuninori Morimoto 1352034d7c13SKuninori Morimoto static int usbhsh_irq_dtch(struct usbhs_priv *priv, 1353034d7c13SKuninori Morimoto struct usbhs_irq_state *irq_state) 1354034d7c13SKuninori Morimoto { 1355034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1356034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1357034d7c13SKuninori Morimoto 1358034d7c13SKuninori Morimoto dev_dbg(dev, "device detached\n"); 1359034d7c13SKuninori Morimoto 1360034d7c13SKuninori Morimoto usbhsh_port_stat_clear(hpriv, USB_PORT_STAT_CONNECTION); 1361034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); 1362034d7c13SKuninori Morimoto 136331e00fd1SKuninori Morimoto /* 136431e00fd1SKuninori Morimoto * enable attch interrupt again 1365b1930da0SKuninori Morimoto * 1366b1930da0SKuninori Morimoto * usbhsh_is_running() becomes invalid 1367b1930da0SKuninori Morimoto * according to this process. 1368b1930da0SKuninori Morimoto * see 1369b1930da0SKuninori Morimoto * usbhsh_is_running() 1370b1930da0SKuninori Morimoto * usbhsh_urb_enqueue() 137131e00fd1SKuninori Morimoto */ 137231e00fd1SKuninori Morimoto hpriv->mod.irq_attch = usbhsh_irq_attch; 137331e00fd1SKuninori Morimoto usbhs_irq_callback_update(priv, &hpriv->mod); 137431e00fd1SKuninori Morimoto 13752d833faaSKuninori Morimoto /* 13762d833faaSKuninori Morimoto * usbhsh_queue_force_pop_all() should be called 13772d833faaSKuninori Morimoto * after usbhsh_is_running() becomes invalid. 13782d833faaSKuninori Morimoto */ 13792d833faaSKuninori Morimoto usbhsh_queue_force_pop_all(priv); 13802d833faaSKuninori Morimoto 1381034d7c13SKuninori Morimoto return 0; 1382034d7c13SKuninori Morimoto } 1383034d7c13SKuninori Morimoto 1384034d7c13SKuninori Morimoto static int usbhsh_irq_setup_ack(struct usbhs_priv *priv, 1385034d7c13SKuninori Morimoto struct usbhs_irq_state *irq_state) 1386034d7c13SKuninori Morimoto { 1387034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1388034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1389034d7c13SKuninori Morimoto 1390034d7c13SKuninori Morimoto dev_dbg(dev, "setup packet OK\n"); 1391034d7c13SKuninori Morimoto 13927fccd480SKuninori Morimoto complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */ 1393034d7c13SKuninori Morimoto 1394034d7c13SKuninori Morimoto return 0; 1395034d7c13SKuninori Morimoto } 1396034d7c13SKuninori Morimoto 1397034d7c13SKuninori Morimoto static int usbhsh_irq_setup_err(struct usbhs_priv *priv, 1398034d7c13SKuninori Morimoto struct usbhs_irq_state *irq_state) 1399034d7c13SKuninori Morimoto { 1400034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1401034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1402034d7c13SKuninori Morimoto 1403034d7c13SKuninori Morimoto dev_dbg(dev, "setup packet Err\n"); 1404034d7c13SKuninori Morimoto 14057fccd480SKuninori Morimoto complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */ 1406034d7c13SKuninori Morimoto 1407034d7c13SKuninori Morimoto return 0; 1408034d7c13SKuninori Morimoto } 1409034d7c13SKuninori Morimoto 1410034d7c13SKuninori Morimoto /* 1411034d7c13SKuninori Morimoto * module start/stop 1412034d7c13SKuninori Morimoto */ 1413034d7c13SKuninori Morimoto static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) 1414034d7c13SKuninori Morimoto { 1415034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1416034d7c13SKuninori Morimoto struct usbhs_pipe *pipe; 141751f141a9SYoshihiro Shimoda struct renesas_usbhs_driver_pipe_config *pipe_configs = 141851f141a9SYoshihiro Shimoda usbhs_get_dparam(priv, pipe_configs); 1419034d7c13SKuninori Morimoto int pipe_size = usbhs_get_dparam(priv, pipe_size); 1420034d7c13SKuninori Morimoto int old_type, dir_in, i; 1421034d7c13SKuninori Morimoto 1422034d7c13SKuninori Morimoto /* init all pipe */ 1423034d7c13SKuninori Morimoto old_type = USB_ENDPOINT_XFER_CONTROL; 1424034d7c13SKuninori Morimoto for (i = 0; i < pipe_size; i++) { 1425034d7c13SKuninori Morimoto 1426034d7c13SKuninori Morimoto /* 1427034d7c13SKuninori Morimoto * data "output" will be finished as soon as possible, 1428034d7c13SKuninori Morimoto * but there is no guaranty at data "input" case. 1429034d7c13SKuninori Morimoto * 1430034d7c13SKuninori Morimoto * "input" needs "standby" pipe. 1431034d7c13SKuninori Morimoto * So, "input" direction pipe > "output" direction pipe 1432034d7c13SKuninori Morimoto * is good idea. 1433034d7c13SKuninori Morimoto * 1434034d7c13SKuninori Morimoto * 1st USB_ENDPOINT_XFER_xxx will be output direction, 1435034d7c13SKuninori Morimoto * and the other will be input direction here. 1436034d7c13SKuninori Morimoto * 1437034d7c13SKuninori Morimoto * ex) 1438034d7c13SKuninori Morimoto * ... 1439034d7c13SKuninori Morimoto * USB_ENDPOINT_XFER_ISOC -> dir out 1440034d7c13SKuninori Morimoto * USB_ENDPOINT_XFER_ISOC -> dir in 1441034d7c13SKuninori Morimoto * USB_ENDPOINT_XFER_BULK -> dir out 1442034d7c13SKuninori Morimoto * USB_ENDPOINT_XFER_BULK -> dir in 1443034d7c13SKuninori Morimoto * USB_ENDPOINT_XFER_BULK -> dir in 1444034d7c13SKuninori Morimoto * ... 1445034d7c13SKuninori Morimoto */ 144651f141a9SYoshihiro Shimoda dir_in = (pipe_configs[i].type == old_type); 144751f141a9SYoshihiro Shimoda old_type = pipe_configs[i].type; 1448034d7c13SKuninori Morimoto 144951f141a9SYoshihiro Shimoda if (USB_ENDPOINT_XFER_CONTROL == pipe_configs[i].type) { 1450034d7c13SKuninori Morimoto pipe = usbhs_dcp_malloc(priv); 1451034d7c13SKuninori Morimoto usbhsh_hpriv_to_dcp(hpriv) = pipe; 1452034d7c13SKuninori Morimoto } else { 1453034d7c13SKuninori Morimoto pipe = usbhs_pipe_malloc(priv, 145451f141a9SYoshihiro Shimoda pipe_configs[i].type, 1455034d7c13SKuninori Morimoto dir_in); 1456034d7c13SKuninori Morimoto } 1457034d7c13SKuninori Morimoto 1458e5679d07SKuninori Morimoto pipe->mod_private = NULL; 1459034d7c13SKuninori Morimoto } 1460034d7c13SKuninori Morimoto } 1461034d7c13SKuninori Morimoto 1462034d7c13SKuninori Morimoto static int usbhsh_start(struct usbhs_priv *priv) 1463034d7c13SKuninori Morimoto { 1464034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1465034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 1466034d7c13SKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 1467034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1468034d7c13SKuninori Morimoto int ret; 1469034d7c13SKuninori Morimoto 1470034d7c13SKuninori Morimoto /* add hcd */ 1471034d7c13SKuninori Morimoto ret = usb_add_hcd(hcd, 0, 0); 1472034d7c13SKuninori Morimoto if (ret < 0) 1473034d7c13SKuninori Morimoto return 0; 14743c9740a1SPeter Chen device_wakeup_enable(hcd->self.controller); 1475034d7c13SKuninori Morimoto 1476034d7c13SKuninori Morimoto /* 1477034d7c13SKuninori Morimoto * pipe initialize and enable DCP 1478034d7c13SKuninori Morimoto */ 1479cdeb7943SYoshihiro Shimoda usbhs_fifo_init(priv); 1480034d7c13SKuninori Morimoto usbhs_pipe_init(priv, 1481034d7c13SKuninori Morimoto usbhsh_dma_map_ctrl); 1482034d7c13SKuninori Morimoto usbhsh_pipe_init_for_host(priv); 1483034d7c13SKuninori Morimoto 1484034d7c13SKuninori Morimoto /* 1485034d7c13SKuninori Morimoto * system config enble 1486034d7c13SKuninori Morimoto * - HI speed 1487034d7c13SKuninori Morimoto * - host 1488034d7c13SKuninori Morimoto * - usb module 1489034d7c13SKuninori Morimoto */ 1490034d7c13SKuninori Morimoto usbhs_sys_host_ctrl(priv, 1); 1491034d7c13SKuninori Morimoto 1492034d7c13SKuninori Morimoto /* 1493034d7c13SKuninori Morimoto * enable irq callback 1494034d7c13SKuninori Morimoto */ 1495034d7c13SKuninori Morimoto mod->irq_attch = usbhsh_irq_attch; 1496034d7c13SKuninori Morimoto mod->irq_dtch = usbhsh_irq_dtch; 1497034d7c13SKuninori Morimoto mod->irq_sack = usbhsh_irq_setup_ack; 1498034d7c13SKuninori Morimoto mod->irq_sign = usbhsh_irq_setup_err; 1499034d7c13SKuninori Morimoto usbhs_irq_callback_update(priv, mod); 1500034d7c13SKuninori Morimoto 1501034d7c13SKuninori Morimoto dev_dbg(dev, "start host\n"); 1502034d7c13SKuninori Morimoto 1503034d7c13SKuninori Morimoto return ret; 1504034d7c13SKuninori Morimoto } 1505034d7c13SKuninori Morimoto 1506034d7c13SKuninori Morimoto static int usbhsh_stop(struct usbhs_priv *priv) 1507034d7c13SKuninori Morimoto { 1508034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1509034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 1510146ee50aSKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 1511034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1512034d7c13SKuninori Morimoto 1513146ee50aSKuninori Morimoto /* 1514146ee50aSKuninori Morimoto * disable irq callback 1515146ee50aSKuninori Morimoto */ 1516146ee50aSKuninori Morimoto mod->irq_attch = NULL; 1517146ee50aSKuninori Morimoto mod->irq_dtch = NULL; 1518146ee50aSKuninori Morimoto mod->irq_sack = NULL; 1519146ee50aSKuninori Morimoto mod->irq_sign = NULL; 1520146ee50aSKuninori Morimoto usbhs_irq_callback_update(priv, mod); 1521146ee50aSKuninori Morimoto 1522034d7c13SKuninori Morimoto usb_remove_hcd(hcd); 1523034d7c13SKuninori Morimoto 1524034d7c13SKuninori Morimoto /* disable sys */ 1525034d7c13SKuninori Morimoto usbhs_sys_host_ctrl(priv, 0); 1526034d7c13SKuninori Morimoto 1527034d7c13SKuninori Morimoto dev_dbg(dev, "quit host\n"); 1528034d7c13SKuninori Morimoto 1529034d7c13SKuninori Morimoto return 0; 1530034d7c13SKuninori Morimoto } 1531034d7c13SKuninori Morimoto 1532b7a8d17dSKuninori Morimoto int usbhs_mod_host_probe(struct usbhs_priv *priv) 1533034d7c13SKuninori Morimoto { 1534034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv; 1535034d7c13SKuninori Morimoto struct usb_hcd *hcd; 1536034d7c13SKuninori Morimoto struct usbhsh_device *udev; 1537034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1538034d7c13SKuninori Morimoto int i; 1539034d7c13SKuninori Morimoto 1540034d7c13SKuninori Morimoto /* initialize hcd */ 1541034d7c13SKuninori Morimoto hcd = usb_create_hcd(&usbhsh_driver, dev, usbhsh_hcd_name); 1542034d7c13SKuninori Morimoto if (!hcd) { 1543034d7c13SKuninori Morimoto dev_err(dev, "Failed to create hcd\n"); 1544034d7c13SKuninori Morimoto return -ENOMEM; 1545034d7c13SKuninori Morimoto } 15461115b9e2SKuninori Morimoto hcd->has_tt = 1; /* for low/full speed */ 1547034d7c13SKuninori Morimoto 1548034d7c13SKuninori Morimoto /* 1549034d7c13SKuninori Morimoto * CAUTION 1550034d7c13SKuninori Morimoto * 1551034d7c13SKuninori Morimoto * There is no guarantee that it is possible to access usb module here. 1552034d7c13SKuninori Morimoto * Don't accesses to it. 1553034d7c13SKuninori Morimoto * The accesse will be enable after "usbhsh_start" 1554034d7c13SKuninori Morimoto */ 1555034d7c13SKuninori Morimoto 1556034d7c13SKuninori Morimoto hpriv = usbhsh_hcd_to_hpriv(hcd); 1557034d7c13SKuninori Morimoto 1558034d7c13SKuninori Morimoto /* 1559034d7c13SKuninori Morimoto * register itself 1560034d7c13SKuninori Morimoto */ 1561034d7c13SKuninori Morimoto usbhs_mod_register(priv, &hpriv->mod, USBHS_HOST); 1562034d7c13SKuninori Morimoto 1563034d7c13SKuninori Morimoto /* init hpriv */ 1564034d7c13SKuninori Morimoto hpriv->mod.name = "host"; 1565034d7c13SKuninori Morimoto hpriv->mod.start = usbhsh_start; 1566034d7c13SKuninori Morimoto hpriv->mod.stop = usbhsh_stop; 1567034d7c13SKuninori Morimoto usbhsh_port_stat_init(hpriv); 1568034d7c13SKuninori Morimoto 1569034d7c13SKuninori Morimoto /* init all device */ 1570034d7c13SKuninori Morimoto usbhsh_for_each_udev_with_dev0(udev, hpriv, i) { 1571034d7c13SKuninori Morimoto udev->usbv = NULL; 1572034d7c13SKuninori Morimoto INIT_LIST_HEAD(&udev->ep_list_head); 1573034d7c13SKuninori Morimoto } 1574034d7c13SKuninori Morimoto 1575034d7c13SKuninori Morimoto dev_info(dev, "host probed\n"); 1576034d7c13SKuninori Morimoto 1577034d7c13SKuninori Morimoto return 0; 1578034d7c13SKuninori Morimoto } 1579034d7c13SKuninori Morimoto 1580b7a8d17dSKuninori Morimoto int usbhs_mod_host_remove(struct usbhs_priv *priv) 1581034d7c13SKuninori Morimoto { 1582034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1583034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 1584034d7c13SKuninori Morimoto 1585034d7c13SKuninori Morimoto usb_put_hcd(hcd); 1586034d7c13SKuninori Morimoto 1587034d7c13SKuninori Morimoto return 0; 1588034d7c13SKuninori Morimoto } 1589