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 */ 88034d7c13SKuninori Morimoto }; 89034d7c13SKuninori Morimoto 90034d7c13SKuninori Morimoto #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ 91034d7c13SKuninori Morimoto #define USBHSH_PORT_MAX 7 /* see DEVADDn :: HUBPORT */ 92034d7c13SKuninori Morimoto struct usbhsh_hpriv { 93034d7c13SKuninori Morimoto struct usbhs_mod mod; 94034d7c13SKuninori Morimoto struct usbhs_pipe *dcp; 95034d7c13SKuninori Morimoto 96034d7c13SKuninori Morimoto struct usbhsh_device udev[USBHSH_DEVICE_MAX]; 97034d7c13SKuninori Morimoto 98034d7c13SKuninori Morimoto u32 port_stat; /* USB_PORT_STAT_xxx */ 99034d7c13SKuninori Morimoto 1007fccd480SKuninori Morimoto struct completion setup_ack_done; 101034d7c13SKuninori Morimoto }; 102034d7c13SKuninori Morimoto 103034d7c13SKuninori Morimoto 104034d7c13SKuninori Morimoto static const char usbhsh_hcd_name[] = "renesas_usbhs host"; 105034d7c13SKuninori Morimoto 106034d7c13SKuninori Morimoto /* 107034d7c13SKuninori Morimoto * macro 108034d7c13SKuninori Morimoto */ 109034d7c13SKuninori Morimoto #define usbhsh_priv_to_hpriv(priv) \ 110034d7c13SKuninori Morimoto container_of(usbhs_mod_get(priv, USBHS_HOST), struct usbhsh_hpriv, mod) 111034d7c13SKuninori Morimoto 112034d7c13SKuninori Morimoto #define __usbhsh_for_each_udev(start, pos, h, i) \ 113034d7c13SKuninori Morimoto for (i = start, pos = (h)->udev + i; \ 114034d7c13SKuninori Morimoto i < USBHSH_DEVICE_MAX; \ 115034d7c13SKuninori Morimoto i++, pos = (h)->udev + i) 116034d7c13SKuninori Morimoto 117034d7c13SKuninori Morimoto #define usbhsh_for_each_udev(pos, hpriv, i) \ 118034d7c13SKuninori Morimoto __usbhsh_for_each_udev(1, pos, hpriv, i) 119034d7c13SKuninori Morimoto 120034d7c13SKuninori Morimoto #define usbhsh_for_each_udev_with_dev0(pos, hpriv, i) \ 121034d7c13SKuninori Morimoto __usbhsh_for_each_udev(0, pos, hpriv, i) 122034d7c13SKuninori Morimoto 123034d7c13SKuninori Morimoto #define usbhsh_hcd_to_hpriv(h) (struct usbhsh_hpriv *)((h)->hcd_priv) 124034d7c13SKuninori Morimoto #define usbhsh_hcd_to_dev(h) ((h)->self.controller) 125034d7c13SKuninori Morimoto 126034d7c13SKuninori Morimoto #define usbhsh_hpriv_to_priv(h) ((h)->mod.priv) 127034d7c13SKuninori Morimoto #define usbhsh_hpriv_to_dcp(h) ((h)->dcp) 128034d7c13SKuninori Morimoto #define usbhsh_hpriv_to_hcd(h) \ 129034d7c13SKuninori Morimoto container_of((void *)h, struct usb_hcd, hcd_priv) 130034d7c13SKuninori Morimoto 131034d7c13SKuninori Morimoto #define usbhsh_ep_to_uep(u) ((u)->hcpriv) 132034d7c13SKuninori Morimoto #define usbhsh_uep_to_pipe(u) ((u)->pipe) 133034d7c13SKuninori Morimoto #define usbhsh_uep_to_udev(u) ((u)->udev) 134e4c57dedSKuninori Morimoto #define usbhsh_uep_to_ep(u) ((u)->ep) 135e4c57dedSKuninori Morimoto 136034d7c13SKuninori Morimoto #define usbhsh_urb_to_ureq(u) ((u)->hcpriv) 137034d7c13SKuninori Morimoto #define usbhsh_urb_to_usbv(u) ((u)->dev) 138034d7c13SKuninori Morimoto 139034d7c13SKuninori Morimoto #define usbhsh_usbv_to_udev(d) dev_get_drvdata(&(d)->dev) 140034d7c13SKuninori Morimoto 141034d7c13SKuninori Morimoto #define usbhsh_udev_to_usbv(h) ((h)->usbv) 142ab142308SKuninori Morimoto #define usbhsh_udev_is_used(h) usbhsh_udev_to_usbv(h) 143034d7c13SKuninori Morimoto 144e5679d07SKuninori Morimoto #define usbhsh_pipe_to_uep(p) ((p)->mod_private) 145034d7c13SKuninori Morimoto 1469c673652SKuninori Morimoto #define usbhsh_device_parent(d) (usbhsh_usbv_to_udev((d)->usbv->parent)) 1479c673652SKuninori Morimoto #define usbhsh_device_hubport(d) ((d)->usbv->portnum) 148034d7c13SKuninori Morimoto #define usbhsh_device_number(h, d) ((int)((d) - (h)->udev)) 149034d7c13SKuninori Morimoto #define usbhsh_device_nth(h, d) ((h)->udev + d) 150034d7c13SKuninori Morimoto #define usbhsh_device0(h) usbhsh_device_nth(h, 0) 151034d7c13SKuninori Morimoto 152034d7c13SKuninori Morimoto #define usbhsh_port_stat_init(h) ((h)->port_stat = 0) 153034d7c13SKuninori Morimoto #define usbhsh_port_stat_set(h, s) ((h)->port_stat |= (s)) 154034d7c13SKuninori Morimoto #define usbhsh_port_stat_clear(h, s) ((h)->port_stat &= ~(s)) 155034d7c13SKuninori Morimoto #define usbhsh_port_stat_get(h) ((h)->port_stat) 156034d7c13SKuninori Morimoto 15725234b46SKuninori Morimoto #define usbhsh_pkt_to_ureq(p) \ 158034d7c13SKuninori Morimoto container_of((void *)p, struct usbhsh_request, pkt) 159034d7c13SKuninori Morimoto 160034d7c13SKuninori Morimoto /* 161034d7c13SKuninori Morimoto * req alloc/free 162034d7c13SKuninori Morimoto */ 16325234b46SKuninori Morimoto static struct usbhsh_request *usbhsh_ureq_alloc(struct usbhsh_hpriv *hpriv, 164034d7c13SKuninori Morimoto struct urb *urb, 165034d7c13SKuninori Morimoto gfp_t mem_flags) 166034d7c13SKuninori Morimoto { 167034d7c13SKuninori Morimoto struct usbhsh_request *ureq; 168034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 169034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 170034d7c13SKuninori Morimoto 171034d7c13SKuninori Morimoto ureq = kzalloc(sizeof(struct usbhsh_request), mem_flags); 172034d7c13SKuninori Morimoto if (!ureq) { 173034d7c13SKuninori Morimoto dev_err(dev, "ureq alloc fail\n"); 174034d7c13SKuninori Morimoto return NULL; 175034d7c13SKuninori Morimoto } 176034d7c13SKuninori Morimoto 177034d7c13SKuninori Morimoto usbhs_pkt_init(&ureq->pkt); 178034d7c13SKuninori Morimoto ureq->urb = urb; 179fc9d5c79SKuninori Morimoto usbhsh_urb_to_ureq(urb) = ureq; 180034d7c13SKuninori Morimoto 181034d7c13SKuninori Morimoto return ureq; 182034d7c13SKuninori Morimoto } 183034d7c13SKuninori Morimoto 18425234b46SKuninori Morimoto static void usbhsh_ureq_free(struct usbhsh_hpriv *hpriv, 185034d7c13SKuninori Morimoto struct usbhsh_request *ureq) 186034d7c13SKuninori Morimoto { 187fc9d5c79SKuninori Morimoto usbhsh_urb_to_ureq(ureq->urb) = NULL; 188034d7c13SKuninori Morimoto ureq->urb = NULL; 189c5b963f8SKuninori Morimoto 190c5b963f8SKuninori Morimoto kfree(ureq); 191034d7c13SKuninori Morimoto } 192034d7c13SKuninori Morimoto 193034d7c13SKuninori Morimoto /* 194b1930da0SKuninori Morimoto * status 195b1930da0SKuninori Morimoto */ 196b1930da0SKuninori Morimoto static int usbhsh_is_running(struct usbhsh_hpriv *hpriv) 197b1930da0SKuninori Morimoto { 198b1930da0SKuninori Morimoto /* 199b1930da0SKuninori Morimoto * we can decide some device is attached or not 200b1930da0SKuninori Morimoto * by checking mod.irq_attch 201b1930da0SKuninori Morimoto * see 202b1930da0SKuninori Morimoto * usbhsh_irq_attch() 203b1930da0SKuninori Morimoto * usbhsh_irq_dtch() 204b1930da0SKuninori Morimoto */ 205b1930da0SKuninori Morimoto return (hpriv->mod.irq_attch == NULL); 206b1930da0SKuninori Morimoto } 207b1930da0SKuninori Morimoto 208b1930da0SKuninori Morimoto /* 209e5679d07SKuninori Morimoto * pipe control 210e4c57dedSKuninori Morimoto */ 2113edeee38SKuninori Morimoto static void usbhsh_endpoint_sequence_save(struct usbhsh_hpriv *hpriv, 2123edeee38SKuninori Morimoto struct urb *urb, 2133edeee38SKuninori Morimoto struct usbhs_pkt *pkt) 2143edeee38SKuninori Morimoto { 2153edeee38SKuninori Morimoto int len = urb->actual_length; 2163edeee38SKuninori Morimoto int maxp = usb_endpoint_maxp(&urb->ep->desc); 2173edeee38SKuninori Morimoto int t = 0; 2183edeee38SKuninori Morimoto 2193edeee38SKuninori Morimoto /* DCP is out of sequence control */ 2203edeee38SKuninori Morimoto if (usb_pipecontrol(urb->pipe)) 2213edeee38SKuninori Morimoto return; 2223edeee38SKuninori Morimoto 2233edeee38SKuninori Morimoto /* 2243edeee38SKuninori Morimoto * renesas_usbhs pipe has a limitation in a number. 2253edeee38SKuninori Morimoto * So, driver should re-use the limited pipe for each device/endpoint. 2263edeee38SKuninori Morimoto * DATA0/1 sequence should be saved for it. 2273edeee38SKuninori Morimoto * see [image of mod_host] 2283edeee38SKuninori Morimoto * [HARDWARE LIMITATION] 2293edeee38SKuninori Morimoto */ 2303edeee38SKuninori Morimoto 2313edeee38SKuninori Morimoto /* 2323edeee38SKuninori Morimoto * next sequence depends on actual_length 2333edeee38SKuninori Morimoto * 2343edeee38SKuninori Morimoto * ex) actual_length = 1147, maxp = 512 2353edeee38SKuninori Morimoto * data0 : 512 2363edeee38SKuninori Morimoto * data1 : 512 2373edeee38SKuninori Morimoto * data0 : 123 2383edeee38SKuninori Morimoto * data1 is the next sequence 2393edeee38SKuninori Morimoto */ 2403edeee38SKuninori Morimoto t = len / maxp; 2413edeee38SKuninori Morimoto if (len % maxp) 2423edeee38SKuninori Morimoto t++; 2433edeee38SKuninori Morimoto if (pkt->zero) 2443edeee38SKuninori Morimoto t++; 2453edeee38SKuninori Morimoto t %= 2; 2463edeee38SKuninori Morimoto 2473edeee38SKuninori Morimoto if (t) 2483edeee38SKuninori Morimoto usb_dotoggle(urb->dev, 2493edeee38SKuninori Morimoto usb_pipeendpoint(urb->pipe), 2503edeee38SKuninori Morimoto usb_pipeout(urb->pipe)); 2513edeee38SKuninori Morimoto } 2523edeee38SKuninori Morimoto 253e4c57dedSKuninori Morimoto static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, 254e4c57dedSKuninori Morimoto struct urb *urb); 255e5679d07SKuninori Morimoto 256e5679d07SKuninori Morimoto static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, 257e5679d07SKuninori Morimoto struct urb *urb) 258e5679d07SKuninori Morimoto { 259e5679d07SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 260e5679d07SKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); 261e5679d07SKuninori Morimoto struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); 262e5679d07SKuninori Morimoto struct usbhs_pipe *pipe; 263e5679d07SKuninori Morimoto struct usb_endpoint_descriptor *desc = &urb->ep->desc; 264e5679d07SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 265e5679d07SKuninori Morimoto unsigned long flags; 266e5679d07SKuninori Morimoto int dir_in_req = !!usb_pipein(urb->pipe); 267e5679d07SKuninori Morimoto int is_dcp = usb_endpoint_xfer_control(desc); 268e5679d07SKuninori Morimoto int i, dir_in; 269e5679d07SKuninori Morimoto int ret = -EBUSY; 270e5679d07SKuninori Morimoto 271e5679d07SKuninori Morimoto /******************** spin lock ********************/ 272e5679d07SKuninori Morimoto usbhs_lock(priv, flags); 273e5679d07SKuninori Morimoto 274e5679d07SKuninori Morimoto if (unlikely(usbhsh_uep_to_pipe(uep))) { 275e5679d07SKuninori Morimoto dev_err(dev, "uep already has pipe\n"); 276e5679d07SKuninori Morimoto goto usbhsh_pipe_attach_done; 277e5679d07SKuninori Morimoto } 278e5679d07SKuninori Morimoto 279e5679d07SKuninori Morimoto usbhs_for_each_pipe_with_dcp(pipe, priv, i) { 280e5679d07SKuninori Morimoto 281e5679d07SKuninori Morimoto /* check pipe type */ 282e5679d07SKuninori Morimoto if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc))) 283e5679d07SKuninori Morimoto continue; 284e5679d07SKuninori Morimoto 285e5679d07SKuninori Morimoto /* check pipe direction if normal pipe */ 286e5679d07SKuninori Morimoto if (!is_dcp) { 287e5679d07SKuninori Morimoto dir_in = !!usbhs_pipe_is_dir_in(pipe); 288e5679d07SKuninori Morimoto if (0 != (dir_in - dir_in_req)) 289e5679d07SKuninori Morimoto continue; 290e5679d07SKuninori Morimoto } 291e5679d07SKuninori Morimoto 292e5679d07SKuninori Morimoto /* check pipe is free */ 293e5679d07SKuninori Morimoto if (usbhsh_pipe_to_uep(pipe)) 294e5679d07SKuninori Morimoto continue; 295e5679d07SKuninori Morimoto 296e5679d07SKuninori Morimoto /* 297e5679d07SKuninori Morimoto * attach pipe to uep 298e5679d07SKuninori Morimoto * 299e5679d07SKuninori Morimoto * usbhs_pipe_config_update() should be called after 300e5679d07SKuninori Morimoto * usbhs_set_device_config() 301e5679d07SKuninori Morimoto * see 302e5679d07SKuninori Morimoto * DCPMAXP/PIPEMAXP 303e5679d07SKuninori Morimoto */ 304e5679d07SKuninori Morimoto usbhsh_uep_to_pipe(uep) = pipe; 305e5679d07SKuninori Morimoto usbhsh_pipe_to_uep(pipe) = uep; 306e5679d07SKuninori Morimoto 307e5679d07SKuninori Morimoto usbhs_pipe_config_update(pipe, 308e5679d07SKuninori Morimoto usbhsh_device_number(hpriv, udev), 309e5679d07SKuninori Morimoto usb_endpoint_num(desc), 310e5679d07SKuninori Morimoto usb_endpoint_maxp(desc)); 311e5679d07SKuninori Morimoto 312e5679d07SKuninori Morimoto dev_dbg(dev, "%s [%d-%d(%s:%s)]\n", __func__, 313e5679d07SKuninori Morimoto usbhsh_device_number(hpriv, udev), 314e5679d07SKuninori Morimoto usb_endpoint_num(desc), 315e5679d07SKuninori Morimoto usbhs_pipe_name(pipe), 316e5679d07SKuninori Morimoto dir_in_req ? "in" : "out"); 317e5679d07SKuninori Morimoto 318e5679d07SKuninori Morimoto ret = 0; 319e5679d07SKuninori Morimoto break; 320e5679d07SKuninori Morimoto } 321e5679d07SKuninori Morimoto 322e5679d07SKuninori Morimoto usbhsh_pipe_attach_done: 323e5679d07SKuninori Morimoto usbhs_unlock(priv, flags); 324e5679d07SKuninori Morimoto /******************** spin unlock ******************/ 325e5679d07SKuninori Morimoto 326e5679d07SKuninori Morimoto return ret; 327e5679d07SKuninori Morimoto } 328e5679d07SKuninori Morimoto 329e5679d07SKuninori Morimoto static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, 330e5679d07SKuninori Morimoto struct usbhsh_ep *uep) 331e5679d07SKuninori Morimoto { 332e5679d07SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 333e5679d07SKuninori Morimoto struct usbhs_pipe *pipe; 334e5679d07SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 335e5679d07SKuninori Morimoto unsigned long flags; 336e5679d07SKuninori Morimoto 337e5679d07SKuninori Morimoto /******************** spin lock ********************/ 338e5679d07SKuninori Morimoto usbhs_lock(priv, flags); 339e5679d07SKuninori Morimoto 340e5679d07SKuninori Morimoto pipe = usbhsh_uep_to_pipe(uep); 341e5679d07SKuninori Morimoto 342e5679d07SKuninori Morimoto if (unlikely(!pipe)) { 343e5679d07SKuninori Morimoto dev_err(dev, "uep doens't have pipe\n"); 344e5679d07SKuninori Morimoto } else { 345e5679d07SKuninori Morimoto struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); 346e5679d07SKuninori Morimoto struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); 347e5679d07SKuninori Morimoto 348e5679d07SKuninori Morimoto /* detach pipe from uep */ 349e5679d07SKuninori Morimoto usbhsh_uep_to_pipe(uep) = NULL; 350e5679d07SKuninori Morimoto usbhsh_pipe_to_uep(pipe) = NULL; 351e5679d07SKuninori Morimoto 352e5679d07SKuninori Morimoto dev_dbg(dev, "%s [%d-%d(%s)]\n", __func__, 353e5679d07SKuninori Morimoto usbhsh_device_number(hpriv, udev), 354e5679d07SKuninori Morimoto usb_endpoint_num(&ep->desc), 355e5679d07SKuninori Morimoto usbhs_pipe_name(pipe)); 356e5679d07SKuninori Morimoto } 357e5679d07SKuninori Morimoto 358e5679d07SKuninori Morimoto usbhs_unlock(priv, flags); 359e5679d07SKuninori Morimoto /******************** spin unlock ******************/ 360e5679d07SKuninori Morimoto } 361e5679d07SKuninori Morimoto 362e5679d07SKuninori Morimoto /* 363e5679d07SKuninori Morimoto * endpoint control 364e5679d07SKuninori Morimoto */ 365e4c57dedSKuninori Morimoto static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, 366e4c57dedSKuninori Morimoto struct urb *urb, 367e4c57dedSKuninori Morimoto gfp_t mem_flags) 368e4c57dedSKuninori Morimoto { 369e4c57dedSKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 370e4c57dedSKuninori Morimoto struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); 371e4c57dedSKuninori Morimoto struct usb_host_endpoint *ep = urb->ep; 372e4c57dedSKuninori Morimoto struct usbhsh_ep *uep; 373e4c57dedSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 374e4c57dedSKuninori Morimoto struct usb_endpoint_descriptor *desc = &ep->desc; 375e4c57dedSKuninori Morimoto unsigned long flags; 376e4c57dedSKuninori Morimoto 377e4c57dedSKuninori Morimoto uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); 378e4c57dedSKuninori Morimoto if (!uep) { 379e4c57dedSKuninori Morimoto dev_err(dev, "usbhsh_ep alloc fail\n"); 380e4c57dedSKuninori Morimoto return -ENOMEM; 381e4c57dedSKuninori Morimoto } 382e4c57dedSKuninori Morimoto 383e4c57dedSKuninori Morimoto /******************** spin lock ********************/ 384e4c57dedSKuninori Morimoto usbhs_lock(priv, flags); 385e4c57dedSKuninori Morimoto 386e4c57dedSKuninori Morimoto /* 387e5679d07SKuninori Morimoto * init endpoint 388e4c57dedSKuninori Morimoto */ 389e4c57dedSKuninori Morimoto INIT_LIST_HEAD(&uep->ep_list); 390e4c57dedSKuninori Morimoto list_add_tail(&uep->ep_list, &udev->ep_list_head); 391e4c57dedSKuninori Morimoto 392e4c57dedSKuninori Morimoto usbhsh_uep_to_udev(uep) = udev; 393e4c57dedSKuninori Morimoto usbhsh_uep_to_ep(uep) = ep; 394e4c57dedSKuninori Morimoto usbhsh_ep_to_uep(ep) = uep; 395e4c57dedSKuninori Morimoto 396e5679d07SKuninori Morimoto usbhs_unlock(priv, flags); 397e5679d07SKuninori Morimoto /******************** spin unlock ******************/ 398e4c57dedSKuninori Morimoto 399e5679d07SKuninori Morimoto dev_dbg(dev, "%s [%d-%d]\n", __func__, 400e4c57dedSKuninori Morimoto usbhsh_device_number(hpriv, udev), 401e5679d07SKuninori Morimoto usb_endpoint_num(desc)); 402e4c57dedSKuninori Morimoto 403e4c57dedSKuninori Morimoto return 0; 404e4c57dedSKuninori Morimoto } 405e4c57dedSKuninori Morimoto 406e4c57dedSKuninori Morimoto static void usbhsh_endpoint_detach(struct usbhsh_hpriv *hpriv, 407e4c57dedSKuninori Morimoto struct usb_host_endpoint *ep) 408e4c57dedSKuninori Morimoto { 409e4c57dedSKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 410e4c57dedSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 411e4c57dedSKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); 412e4c57dedSKuninori Morimoto unsigned long flags; 413e4c57dedSKuninori Morimoto 414e4c57dedSKuninori Morimoto if (!uep) 415e4c57dedSKuninori Morimoto return; 416e4c57dedSKuninori Morimoto 417e5679d07SKuninori Morimoto dev_dbg(dev, "%s [%d-%d]\n", __func__, 418e4c57dedSKuninori Morimoto usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), 419e5679d07SKuninori Morimoto usb_endpoint_num(&ep->desc)); 420e5679d07SKuninori Morimoto 421e5679d07SKuninori Morimoto if (usbhsh_uep_to_pipe(uep)) 422e5679d07SKuninori Morimoto usbhsh_pipe_detach(hpriv, uep); 423e4c57dedSKuninori Morimoto 424e4c57dedSKuninori Morimoto /******************** spin lock ********************/ 425e4c57dedSKuninori Morimoto usbhs_lock(priv, flags); 426e4c57dedSKuninori Morimoto 427e4c57dedSKuninori Morimoto /* remove this endpoint from udev */ 428e4c57dedSKuninori Morimoto list_del_init(&uep->ep_list); 429e4c57dedSKuninori Morimoto 430e4c57dedSKuninori Morimoto usbhsh_uep_to_udev(uep) = NULL; 431e4c57dedSKuninori Morimoto usbhsh_uep_to_ep(uep) = NULL; 432e4c57dedSKuninori Morimoto usbhsh_ep_to_uep(ep) = NULL; 433e4c57dedSKuninori Morimoto 434e4c57dedSKuninori Morimoto usbhs_unlock(priv, flags); 435e4c57dedSKuninori Morimoto /******************** spin unlock ******************/ 436e4c57dedSKuninori Morimoto 437e4c57dedSKuninori Morimoto kfree(uep); 438e4c57dedSKuninori Morimoto } 439e4c57dedSKuninori Morimoto 440e4c57dedSKuninori Morimoto static void usbhsh_endpoint_detach_all(struct usbhsh_hpriv *hpriv, 441e4c57dedSKuninori Morimoto struct usbhsh_device *udev) 442e4c57dedSKuninori Morimoto { 443e4c57dedSKuninori Morimoto struct usbhsh_ep *uep, *next; 444e4c57dedSKuninori Morimoto 445e4c57dedSKuninori Morimoto list_for_each_entry_safe(uep, next, &udev->ep_list_head, ep_list) 446e4c57dedSKuninori Morimoto usbhsh_endpoint_detach(hpriv, usbhsh_uep_to_ep(uep)); 447e4c57dedSKuninori Morimoto } 448e4c57dedSKuninori Morimoto 449e4c57dedSKuninori Morimoto /* 450034d7c13SKuninori Morimoto * device control 451034d7c13SKuninori Morimoto */ 4529c673652SKuninori Morimoto static int usbhsh_connected_to_rhdev(struct usb_hcd *hcd, 4539c673652SKuninori Morimoto struct usbhsh_device *udev) 4549c673652SKuninori Morimoto { 4559c673652SKuninori Morimoto struct usb_device *usbv = usbhsh_udev_to_usbv(udev); 4569c673652SKuninori Morimoto 4579c673652SKuninori Morimoto return hcd->self.root_hub == usbv->parent; 4589c673652SKuninori Morimoto } 459034d7c13SKuninori Morimoto 460034d7c13SKuninori Morimoto static int usbhsh_device_has_endpoint(struct usbhsh_device *udev) 461034d7c13SKuninori Morimoto { 462034d7c13SKuninori Morimoto return !list_empty(&udev->ep_list_head); 463034d7c13SKuninori Morimoto } 464034d7c13SKuninori Morimoto 465c1e4877aSKuninori Morimoto static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, 466c1e4877aSKuninori Morimoto struct urb *urb) 467c1e4877aSKuninori Morimoto { 468c1e4877aSKuninori Morimoto struct usb_device *usbv = usbhsh_urb_to_usbv(urb); 469c1e4877aSKuninori Morimoto struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv); 470c1e4877aSKuninori Morimoto 471c1e4877aSKuninori Morimoto /* usbhsh_device_attach() is still not called */ 472c1e4877aSKuninori Morimoto if (!udev) 473c1e4877aSKuninori Morimoto return NULL; 474c1e4877aSKuninori Morimoto 475c1e4877aSKuninori Morimoto /* if it is device0, return it */ 476c1e4877aSKuninori Morimoto if (0 == usb_pipedevice(urb->pipe)) 477c1e4877aSKuninori Morimoto return usbhsh_device0(hpriv); 478c1e4877aSKuninori Morimoto 479c1e4877aSKuninori Morimoto /* return attached device */ 480c1e4877aSKuninori Morimoto return udev; 481c1e4877aSKuninori Morimoto } 482c1e4877aSKuninori Morimoto 4837aac8d15SKuninori Morimoto static struct usbhsh_device *usbhsh_device_attach(struct usbhsh_hpriv *hpriv, 484034d7c13SKuninori Morimoto struct urb *urb) 485034d7c13SKuninori Morimoto { 486034d7c13SKuninori Morimoto struct usbhsh_device *udev = NULL; 487c1e4877aSKuninori Morimoto struct usbhsh_device *udev0 = usbhsh_device0(hpriv); 488c1e4877aSKuninori Morimoto struct usbhsh_device *pos; 489034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 490034d7c13SKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 491034d7c13SKuninori Morimoto struct usb_device *usbv = usbhsh_urb_to_usbv(urb); 492034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 493d399f90dSKuninori Morimoto unsigned long flags; 4949c673652SKuninori Morimoto u16 upphub, hubport; 495034d7c13SKuninori Morimoto int i; 496034d7c13SKuninori Morimoto 497c1e4877aSKuninori Morimoto /* 498c1e4877aSKuninori Morimoto * This function should be called only while urb is pointing to device0. 499c1e4877aSKuninori Morimoto * It will attach unused usbhsh_device to urb (usbv), 500c1e4877aSKuninori Morimoto * and initialize device0. 501c1e4877aSKuninori Morimoto * You can use usbhsh_device_get() to get "current" udev, 502c1e4877aSKuninori Morimoto * and usbhsh_usbv_to_udev() is for "attached" udev. 503c1e4877aSKuninori Morimoto */ 504c1e4877aSKuninori Morimoto if (0 != usb_pipedevice(urb->pipe)) { 505c1e4877aSKuninori Morimoto dev_err(dev, "%s fail: urb isn't pointing device0\n", __func__); 506c1e4877aSKuninori Morimoto return NULL; 507c1e4877aSKuninori Morimoto } 508c1e4877aSKuninori Morimoto 509d399f90dSKuninori Morimoto /******************** spin lock ********************/ 510d399f90dSKuninori Morimoto usbhs_lock(priv, flags); 511d399f90dSKuninori Morimoto 512034d7c13SKuninori Morimoto /* 513034d7c13SKuninori Morimoto * find unused device 514034d7c13SKuninori Morimoto */ 515ab142308SKuninori Morimoto usbhsh_for_each_udev(pos, hpriv, i) { 516ab142308SKuninori Morimoto if (usbhsh_udev_is_used(pos)) 517034d7c13SKuninori Morimoto continue; 518ab142308SKuninori Morimoto udev = pos; 519ab142308SKuninori Morimoto break; 520ab142308SKuninori Morimoto } 521034d7c13SKuninori Morimoto 522d399f90dSKuninori Morimoto if (udev) { 523d399f90dSKuninori Morimoto /* 524d399f90dSKuninori Morimoto * usbhsh_usbv_to_udev() 525d399f90dSKuninori Morimoto * usbhsh_udev_to_usbv() 526d399f90dSKuninori Morimoto * will be enable 527d399f90dSKuninori Morimoto */ 528d399f90dSKuninori Morimoto dev_set_drvdata(&usbv->dev, udev); 529d399f90dSKuninori Morimoto udev->usbv = usbv; 530d399f90dSKuninori Morimoto } 531d399f90dSKuninori Morimoto 532d399f90dSKuninori Morimoto usbhs_unlock(priv, flags); 533d399f90dSKuninori Morimoto /******************** spin unlock ******************/ 534d399f90dSKuninori Morimoto 535ab142308SKuninori Morimoto if (!udev) { 536034d7c13SKuninori Morimoto dev_err(dev, "no free usbhsh_device\n"); 537034d7c13SKuninori Morimoto return NULL; 538ab142308SKuninori Morimoto } 539034d7c13SKuninori Morimoto 540e4c57dedSKuninori Morimoto if (usbhsh_device_has_endpoint(udev)) { 541034d7c13SKuninori Morimoto dev_warn(dev, "udev have old endpoint\n"); 542e4c57dedSKuninori Morimoto usbhsh_endpoint_detach_all(hpriv, udev); 543e4c57dedSKuninori Morimoto } 544034d7c13SKuninori Morimoto 545e4c57dedSKuninori Morimoto if (usbhsh_device_has_endpoint(udev0)) { 546c1e4877aSKuninori Morimoto dev_warn(dev, "udev0 have old endpoint\n"); 547e4c57dedSKuninori Morimoto usbhsh_endpoint_detach_all(hpriv, udev0); 548e4c57dedSKuninori Morimoto } 549c1e4877aSKuninori Morimoto 550034d7c13SKuninori Morimoto /* uep will be attached */ 551c1e4877aSKuninori Morimoto INIT_LIST_HEAD(&udev0->ep_list_head); 552034d7c13SKuninori Morimoto INIT_LIST_HEAD(&udev->ep_list_head); 553034d7c13SKuninori Morimoto 554c1e4877aSKuninori Morimoto /* 555c1e4877aSKuninori Morimoto * set device0 config 556c1e4877aSKuninori Morimoto */ 557c1e4877aSKuninori Morimoto usbhs_set_device_config(priv, 558c1e4877aSKuninori Morimoto 0, 0, 0, usbv->speed); 559c1e4877aSKuninori Morimoto 560c1e4877aSKuninori Morimoto /* 561c1e4877aSKuninori Morimoto * set new device config 562c1e4877aSKuninori Morimoto */ 5639c673652SKuninori Morimoto upphub = 0; 5649c673652SKuninori Morimoto hubport = 0; 5659c673652SKuninori Morimoto if (!usbhsh_connected_to_rhdev(hcd, udev)) { 5669c673652SKuninori Morimoto /* if udev is not connected to rhdev, it means parent is Hub */ 5679c673652SKuninori Morimoto struct usbhsh_device *parent = usbhsh_device_parent(udev); 5689c673652SKuninori Morimoto 5699c673652SKuninori Morimoto upphub = usbhsh_device_number(hpriv, parent); 5709c673652SKuninori Morimoto hubport = usbhsh_device_hubport(udev); 5719c673652SKuninori Morimoto 5729c673652SKuninori Morimoto dev_dbg(dev, "%s connecte to Hub [%d:%d](%p)\n", __func__, 5739c673652SKuninori Morimoto upphub, hubport, parent); 5749c673652SKuninori Morimoto } 5759c673652SKuninori Morimoto 5763dd49268SKuninori Morimoto usbhs_set_device_config(priv, 577034d7c13SKuninori Morimoto usbhsh_device_number(hpriv, udev), 5789c673652SKuninori Morimoto upphub, hubport, usbv->speed); 579034d7c13SKuninori Morimoto 580034d7c13SKuninori Morimoto dev_dbg(dev, "%s [%d](%p)\n", __func__, 581034d7c13SKuninori Morimoto usbhsh_device_number(hpriv, udev), udev); 582034d7c13SKuninori Morimoto 583034d7c13SKuninori Morimoto return udev; 584034d7c13SKuninori Morimoto } 585034d7c13SKuninori Morimoto 5867aac8d15SKuninori Morimoto static void usbhsh_device_detach(struct usbhsh_hpriv *hpriv, 587034d7c13SKuninori Morimoto struct usbhsh_device *udev) 588034d7c13SKuninori Morimoto { 589034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 590d399f90dSKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 591034d7c13SKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 592034d7c13SKuninori Morimoto struct usb_device *usbv = usbhsh_udev_to_usbv(udev); 593d399f90dSKuninori Morimoto unsigned long flags; 594034d7c13SKuninori Morimoto 595034d7c13SKuninori Morimoto dev_dbg(dev, "%s [%d](%p)\n", __func__, 596034d7c13SKuninori Morimoto usbhsh_device_number(hpriv, udev), udev); 597034d7c13SKuninori Morimoto 598e4c57dedSKuninori Morimoto if (usbhsh_device_has_endpoint(udev)) { 599034d7c13SKuninori Morimoto dev_warn(dev, "udev still have endpoint\n"); 600e4c57dedSKuninori Morimoto usbhsh_endpoint_detach_all(hpriv, udev); 601e4c57dedSKuninori Morimoto } 602034d7c13SKuninori Morimoto 603c1e4877aSKuninori Morimoto /* 604c1e4877aSKuninori Morimoto * There is nothing to do if it is device0. 605c1e4877aSKuninori Morimoto * see 606c1e4877aSKuninori Morimoto * usbhsh_device_attach() 607c1e4877aSKuninori Morimoto * usbhsh_device_get() 608c1e4877aSKuninori Morimoto */ 609c1e4877aSKuninori Morimoto if (0 == usbhsh_device_number(hpriv, udev)) 610c1e4877aSKuninori Morimoto return; 611c1e4877aSKuninori Morimoto 612d399f90dSKuninori Morimoto /******************** spin lock ********************/ 613d399f90dSKuninori Morimoto usbhs_lock(priv, flags); 614d399f90dSKuninori Morimoto 615034d7c13SKuninori Morimoto /* 616034d7c13SKuninori Morimoto * usbhsh_usbv_to_udev() 617034d7c13SKuninori Morimoto * usbhsh_udev_to_usbv() 618034d7c13SKuninori Morimoto * will be disable 619034d7c13SKuninori Morimoto */ 620034d7c13SKuninori Morimoto dev_set_drvdata(&usbv->dev, NULL); 621034d7c13SKuninori Morimoto udev->usbv = NULL; 622d399f90dSKuninori Morimoto 623d399f90dSKuninori Morimoto usbhs_unlock(priv, flags); 624d399f90dSKuninori Morimoto /******************** spin unlock ******************/ 625034d7c13SKuninori Morimoto } 626034d7c13SKuninori Morimoto 627034d7c13SKuninori Morimoto /* 628034d7c13SKuninori Morimoto * queue push/pop 629034d7c13SKuninori Morimoto */ 630034d7c13SKuninori Morimoto static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) 631034d7c13SKuninori Morimoto { 63225234b46SKuninori Morimoto struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); 633034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 634034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 635034d7c13SKuninori Morimoto struct urb *urb = ureq->urb; 636e5679d07SKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); 637034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 6386d0376f8SKuninori Morimoto int status = 0; 639034d7c13SKuninori Morimoto 640034d7c13SKuninori Morimoto dev_dbg(dev, "%s\n", __func__); 641034d7c13SKuninori Morimoto 642034d7c13SKuninori Morimoto if (!urb) { 643034d7c13SKuninori Morimoto dev_warn(dev, "pkt doesn't have urb\n"); 644034d7c13SKuninori Morimoto return; 645034d7c13SKuninori Morimoto } 646034d7c13SKuninori Morimoto 6476d0376f8SKuninori Morimoto if (!usbhsh_is_running(hpriv)) 6486d0376f8SKuninori Morimoto status = -ESHUTDOWN; 6496d0376f8SKuninori Morimoto 650034d7c13SKuninori Morimoto urb->actual_length = pkt->actual; 65125234b46SKuninori Morimoto usbhsh_ureq_free(hpriv, ureq); 652034d7c13SKuninori Morimoto 6533edeee38SKuninori Morimoto usbhsh_endpoint_sequence_save(hpriv, urb, pkt); 6543edeee38SKuninori Morimoto usbhsh_pipe_detach(hpriv, uep); 6553edeee38SKuninori Morimoto 656034d7c13SKuninori Morimoto usb_hcd_unlink_urb_from_ep(hcd, urb); 6576d0376f8SKuninori Morimoto usb_hcd_giveback_urb(hcd, urb, status); 658034d7c13SKuninori Morimoto } 659034d7c13SKuninori Morimoto 660034d7c13SKuninori Morimoto static int usbhsh_queue_push(struct usb_hcd *hcd, 661ee8a0bf5SKuninori Morimoto struct urb *urb, 662ee8a0bf5SKuninori Morimoto gfp_t mem_flags) 663034d7c13SKuninori Morimoto { 664ee8a0bf5SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 6653eddc9e4SKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); 6663eddc9e4SKuninori Morimoto struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep); 667034d7c13SKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 668ee8a0bf5SKuninori Morimoto struct usbhsh_request *ureq; 669034d7c13SKuninori Morimoto void *buf; 6703edeee38SKuninori Morimoto int len, sequence; 671034d7c13SKuninori Morimoto 672034d7c13SKuninori Morimoto if (usb_pipeisoc(urb->pipe)) { 673034d7c13SKuninori Morimoto dev_err(dev, "pipe iso is not supported now\n"); 674034d7c13SKuninori Morimoto return -EIO; 675034d7c13SKuninori Morimoto } 676034d7c13SKuninori Morimoto 677ee8a0bf5SKuninori Morimoto /* this ureq will be freed on usbhsh_queue_done() */ 678ee8a0bf5SKuninori Morimoto ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); 679ee8a0bf5SKuninori Morimoto if (unlikely(!ureq)) { 680ee8a0bf5SKuninori Morimoto dev_err(dev, "ureq alloc fail\n"); 681ee8a0bf5SKuninori Morimoto return -ENOMEM; 682ee8a0bf5SKuninori Morimoto } 683ee8a0bf5SKuninori Morimoto 684034d7c13SKuninori Morimoto if (usb_pipein(urb->pipe)) 685034d7c13SKuninori Morimoto pipe->handler = &usbhs_fifo_pio_pop_handler; 686034d7c13SKuninori Morimoto else 687034d7c13SKuninori Morimoto pipe->handler = &usbhs_fifo_pio_push_handler; 688034d7c13SKuninori Morimoto 689034d7c13SKuninori Morimoto buf = (void *)(urb->transfer_buffer + urb->actual_length); 690034d7c13SKuninori Morimoto len = urb->transfer_buffer_length - urb->actual_length; 691034d7c13SKuninori Morimoto 6923edeee38SKuninori Morimoto sequence = usb_gettoggle(urb->dev, 6933edeee38SKuninori Morimoto usb_pipeendpoint(urb->pipe), 6943edeee38SKuninori Morimoto usb_pipeout(urb->pipe)); 6953edeee38SKuninori Morimoto 696034d7c13SKuninori Morimoto dev_dbg(dev, "%s\n", __func__); 697ee8a0bf5SKuninori Morimoto usbhs_pkt_push(pipe, &ureq->pkt, usbhsh_queue_done, 6983edeee38SKuninori Morimoto buf, len, (urb->transfer_flags & URB_ZERO_PACKET), 6993edeee38SKuninori Morimoto sequence); 7003edeee38SKuninori Morimoto 701034d7c13SKuninori Morimoto usbhs_pkt_start(pipe); 702034d7c13SKuninori Morimoto 703034d7c13SKuninori Morimoto return 0; 704034d7c13SKuninori Morimoto } 705034d7c13SKuninori Morimoto 706034d7c13SKuninori Morimoto /* 707034d7c13SKuninori Morimoto * DCP setup stage 708034d7c13SKuninori Morimoto */ 709034d7c13SKuninori Morimoto static int usbhsh_is_request_address(struct urb *urb) 710034d7c13SKuninori Morimoto { 71125234b46SKuninori Morimoto struct usb_ctrlrequest *req; 712034d7c13SKuninori Morimoto 71325234b46SKuninori Morimoto req = (struct usb_ctrlrequest *)urb->setup_packet; 714034d7c13SKuninori Morimoto 71525234b46SKuninori Morimoto if ((DeviceOutRequest == req->bRequestType << 8) && 71625234b46SKuninori Morimoto (USB_REQ_SET_ADDRESS == req->bRequest)) 717034d7c13SKuninori Morimoto return 1; 718034d7c13SKuninori Morimoto else 719034d7c13SKuninori Morimoto return 0; 720034d7c13SKuninori Morimoto } 721034d7c13SKuninori Morimoto 722034d7c13SKuninori Morimoto static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, 723034d7c13SKuninori Morimoto struct urb *urb, 724034d7c13SKuninori Morimoto struct usbhs_pipe *pipe) 725034d7c13SKuninori Morimoto { 726034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 727034d7c13SKuninori Morimoto struct usb_ctrlrequest req; 728034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 729034d7c13SKuninori Morimoto 730034d7c13SKuninori Morimoto /* 731034d7c13SKuninori Morimoto * wait setup packet ACK 732034d7c13SKuninori Morimoto * see 733034d7c13SKuninori Morimoto * usbhsh_irq_setup_ack() 734034d7c13SKuninori Morimoto * usbhsh_irq_setup_err() 735034d7c13SKuninori Morimoto */ 7367fccd480SKuninori Morimoto init_completion(&hpriv->setup_ack_done); 737034d7c13SKuninori Morimoto 738034d7c13SKuninori Morimoto /* copy original request */ 739034d7c13SKuninori Morimoto memcpy(&req, urb->setup_packet, sizeof(struct usb_ctrlrequest)); 740034d7c13SKuninori Morimoto 741034d7c13SKuninori Morimoto /* 742034d7c13SKuninori Morimoto * renesas_usbhs can not use original usb address. 743034d7c13SKuninori Morimoto * see HARDWARE LIMITATION. 744c1e4877aSKuninori Morimoto * modify usb address here to use attached device. 745c1e4877aSKuninori Morimoto * see usbhsh_device_attach() 746034d7c13SKuninori Morimoto */ 747034d7c13SKuninori Morimoto if (usbhsh_is_request_address(urb)) { 748c1e4877aSKuninori Morimoto struct usb_device *usbv = usbhsh_urb_to_usbv(urb); 749c1e4877aSKuninori Morimoto struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv); 750c1e4877aSKuninori Morimoto 751c1e4877aSKuninori Morimoto /* udev is a attached device */ 752c1e4877aSKuninori Morimoto req.wValue = usbhsh_device_number(hpriv, udev); 753034d7c13SKuninori Morimoto dev_dbg(dev, "create new address - %d\n", req.wValue); 754034d7c13SKuninori Morimoto } 755034d7c13SKuninori Morimoto 756034d7c13SKuninori Morimoto /* set request */ 757034d7c13SKuninori Morimoto usbhs_usbreq_set_val(priv, &req); 758034d7c13SKuninori Morimoto 759034d7c13SKuninori Morimoto /* 760034d7c13SKuninori Morimoto * wait setup packet ACK 761034d7c13SKuninori Morimoto */ 7627fccd480SKuninori Morimoto wait_for_completion(&hpriv->setup_ack_done); 763034d7c13SKuninori Morimoto 764034d7c13SKuninori Morimoto dev_dbg(dev, "%s done\n", __func__); 765034d7c13SKuninori Morimoto } 766034d7c13SKuninori Morimoto 767034d7c13SKuninori Morimoto /* 768034d7c13SKuninori Morimoto * DCP data stage 769034d7c13SKuninori Morimoto */ 770034d7c13SKuninori Morimoto static void usbhsh_data_stage_packet_done(struct usbhs_priv *priv, 771034d7c13SKuninori Morimoto struct usbhs_pkt *pkt) 772034d7c13SKuninori Morimoto { 77325234b46SKuninori Morimoto struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); 774034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 775034d7c13SKuninori Morimoto 776034d7c13SKuninori Morimoto /* this ureq was connected to urb when usbhsh_urb_enqueue() */ 777034d7c13SKuninori Morimoto 77825234b46SKuninori Morimoto usbhsh_ureq_free(hpriv, ureq); 779034d7c13SKuninori Morimoto } 780034d7c13SKuninori Morimoto 781ee8a0bf5SKuninori Morimoto static int usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv, 782034d7c13SKuninori Morimoto struct urb *urb, 783ee8a0bf5SKuninori Morimoto struct usbhs_pipe *pipe, 784ee8a0bf5SKuninori Morimoto gfp_t mem_flags) 785ee8a0bf5SKuninori Morimoto 786034d7c13SKuninori Morimoto { 787034d7c13SKuninori Morimoto struct usbhsh_request *ureq; 788034d7c13SKuninori Morimoto 789ee8a0bf5SKuninori Morimoto /* this ureq will be freed on usbhsh_data_stage_packet_done() */ 790ee8a0bf5SKuninori Morimoto ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); 791ee8a0bf5SKuninori Morimoto if (unlikely(!ureq)) 792ee8a0bf5SKuninori Morimoto return -ENOMEM; 793034d7c13SKuninori Morimoto 794034d7c13SKuninori Morimoto if (usb_pipein(urb->pipe)) 795034d7c13SKuninori Morimoto pipe->handler = &usbhs_dcp_data_stage_in_handler; 796034d7c13SKuninori Morimoto else 797034d7c13SKuninori Morimoto pipe->handler = &usbhs_dcp_data_stage_out_handler; 798034d7c13SKuninori Morimoto 799ee8a0bf5SKuninori Morimoto usbhs_pkt_push(pipe, &ureq->pkt, 800034d7c13SKuninori Morimoto usbhsh_data_stage_packet_done, 801034d7c13SKuninori Morimoto urb->transfer_buffer, 802034d7c13SKuninori Morimoto urb->transfer_buffer_length, 8033edeee38SKuninori Morimoto (urb->transfer_flags & URB_ZERO_PACKET), 8043edeee38SKuninori Morimoto -1); 805ee8a0bf5SKuninori Morimoto 806ee8a0bf5SKuninori Morimoto return 0; 807034d7c13SKuninori Morimoto } 808034d7c13SKuninori Morimoto 809034d7c13SKuninori Morimoto /* 810034d7c13SKuninori Morimoto * DCP status stage 811034d7c13SKuninori Morimoto */ 812ee8a0bf5SKuninori Morimoto static int usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv, 813034d7c13SKuninori Morimoto struct urb *urb, 814ee8a0bf5SKuninori Morimoto struct usbhs_pipe *pipe, 815ee8a0bf5SKuninori Morimoto gfp_t mem_flags) 816034d7c13SKuninori Morimoto { 817034d7c13SKuninori Morimoto struct usbhsh_request *ureq; 818034d7c13SKuninori Morimoto 819ee8a0bf5SKuninori Morimoto /* This ureq will be freed on usbhsh_queue_done() */ 820ee8a0bf5SKuninori Morimoto ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); 821ee8a0bf5SKuninori Morimoto if (unlikely(!ureq)) 822ee8a0bf5SKuninori Morimoto return -ENOMEM; 823034d7c13SKuninori Morimoto 824034d7c13SKuninori Morimoto if (usb_pipein(urb->pipe)) 825034d7c13SKuninori Morimoto pipe->handler = &usbhs_dcp_status_stage_in_handler; 826034d7c13SKuninori Morimoto else 827034d7c13SKuninori Morimoto pipe->handler = &usbhs_dcp_status_stage_out_handler; 828034d7c13SKuninori Morimoto 829ee8a0bf5SKuninori Morimoto usbhs_pkt_push(pipe, &ureq->pkt, 830034d7c13SKuninori Morimoto usbhsh_queue_done, 831034d7c13SKuninori Morimoto NULL, 832034d7c13SKuninori Morimoto urb->transfer_buffer_length, 8333edeee38SKuninori Morimoto 0, -1); 834ee8a0bf5SKuninori Morimoto 835ee8a0bf5SKuninori Morimoto return 0; 836034d7c13SKuninori Morimoto } 837034d7c13SKuninori Morimoto 838034d7c13SKuninori Morimoto static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, 839ee8a0bf5SKuninori Morimoto struct urb *urb, 840ee8a0bf5SKuninori Morimoto gfp_t mflags) 841034d7c13SKuninori Morimoto { 842ee8a0bf5SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 8433eddc9e4SKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); 8443eddc9e4SKuninori Morimoto struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep); 845034d7c13SKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 846ee8a0bf5SKuninori Morimoto int ret; 847034d7c13SKuninori Morimoto 848034d7c13SKuninori Morimoto dev_dbg(dev, "%s\n", __func__); 849034d7c13SKuninori Morimoto 850034d7c13SKuninori Morimoto /* 851034d7c13SKuninori Morimoto * setup stage 852034d7c13SKuninori Morimoto * 853034d7c13SKuninori Morimoto * usbhsh_send_setup_stage_packet() wait SACK/SIGN 854034d7c13SKuninori Morimoto */ 855034d7c13SKuninori Morimoto usbhsh_setup_stage_packet_push(hpriv, urb, pipe); 856034d7c13SKuninori Morimoto 857034d7c13SKuninori Morimoto /* 858034d7c13SKuninori Morimoto * data stage 859034d7c13SKuninori Morimoto * 860034d7c13SKuninori Morimoto * It is pushed only when urb has buffer. 861034d7c13SKuninori Morimoto */ 862ee8a0bf5SKuninori Morimoto if (urb->transfer_buffer_length) { 863ee8a0bf5SKuninori Morimoto ret = usbhsh_data_stage_packet_push(hpriv, urb, pipe, mflags); 864ee8a0bf5SKuninori Morimoto if (ret < 0) { 865ee8a0bf5SKuninori Morimoto dev_err(dev, "data stage failed\n"); 866ee8a0bf5SKuninori Morimoto return ret; 867ee8a0bf5SKuninori Morimoto } 868ee8a0bf5SKuninori Morimoto } 869034d7c13SKuninori Morimoto 870034d7c13SKuninori Morimoto /* 871034d7c13SKuninori Morimoto * status stage 872034d7c13SKuninori Morimoto */ 873ee8a0bf5SKuninori Morimoto ret = usbhsh_status_stage_packet_push(hpriv, urb, pipe, mflags); 874ee8a0bf5SKuninori Morimoto if (ret < 0) { 875ee8a0bf5SKuninori Morimoto dev_err(dev, "status stage failed\n"); 876ee8a0bf5SKuninori Morimoto return ret; 877ee8a0bf5SKuninori Morimoto } 878034d7c13SKuninori Morimoto 879034d7c13SKuninori Morimoto /* 880034d7c13SKuninori Morimoto * start pushed packets 881034d7c13SKuninori Morimoto */ 882034d7c13SKuninori Morimoto usbhs_pkt_start(pipe); 883034d7c13SKuninori Morimoto 884034d7c13SKuninori Morimoto return 0; 885034d7c13SKuninori Morimoto } 886034d7c13SKuninori Morimoto 887034d7c13SKuninori Morimoto /* 888034d7c13SKuninori Morimoto * dma map functions 889034d7c13SKuninori Morimoto */ 890034d7c13SKuninori Morimoto static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map) 891034d7c13SKuninori Morimoto { 892034d7c13SKuninori Morimoto return 0; 893034d7c13SKuninori Morimoto } 894034d7c13SKuninori Morimoto 895034d7c13SKuninori Morimoto /* 896034d7c13SKuninori Morimoto * for hc_driver 897034d7c13SKuninori Morimoto */ 898034d7c13SKuninori Morimoto static int usbhsh_host_start(struct usb_hcd *hcd) 899034d7c13SKuninori Morimoto { 900034d7c13SKuninori Morimoto return 0; 901034d7c13SKuninori Morimoto } 902034d7c13SKuninori Morimoto 903034d7c13SKuninori Morimoto static void usbhsh_host_stop(struct usb_hcd *hcd) 904034d7c13SKuninori Morimoto { 905034d7c13SKuninori Morimoto } 906034d7c13SKuninori Morimoto 907034d7c13SKuninori Morimoto static int usbhsh_urb_enqueue(struct usb_hcd *hcd, 908034d7c13SKuninori Morimoto struct urb *urb, 909034d7c13SKuninori Morimoto gfp_t mem_flags) 910034d7c13SKuninori Morimoto { 911034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 912034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 913034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 914034d7c13SKuninori Morimoto struct usb_host_endpoint *ep = urb->ep; 9157aac8d15SKuninori Morimoto struct usbhsh_device *new_udev = NULL; 91673ef635aSKuninori Morimoto int is_dir_in = usb_pipein(urb->pipe); 917e5679d07SKuninori Morimoto int i; 918034d7c13SKuninori Morimoto int ret; 919034d7c13SKuninori Morimoto 92073ef635aSKuninori Morimoto dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); 921034d7c13SKuninori Morimoto 922b1930da0SKuninori Morimoto if (!usbhsh_is_running(hpriv)) { 923b1930da0SKuninori Morimoto ret = -EIO; 924b1930da0SKuninori Morimoto goto usbhsh_urb_enqueue_error_not_linked; 925b1930da0SKuninori Morimoto } 926b1930da0SKuninori Morimoto 927034d7c13SKuninori Morimoto ret = usb_hcd_link_urb_to_ep(hcd, urb); 928034d7c13SKuninori Morimoto if (ret) 929034d7c13SKuninori Morimoto goto usbhsh_urb_enqueue_error_not_linked; 930034d7c13SKuninori Morimoto 931034d7c13SKuninori Morimoto /* 9327aac8d15SKuninori Morimoto * attach udev if needed 933e5679d07SKuninori Morimoto * see [image of mod_host] 934034d7c13SKuninori Morimoto */ 935c1e4877aSKuninori Morimoto if (!usbhsh_device_get(hpriv, urb)) { 9367aac8d15SKuninori Morimoto new_udev = usbhsh_device_attach(hpriv, urb); 93737332ee0SKuninori Morimoto if (!new_udev) { 93837332ee0SKuninori Morimoto ret = -EIO; 939034d7c13SKuninori Morimoto goto usbhsh_urb_enqueue_error_not_linked; 940034d7c13SKuninori Morimoto } 94137332ee0SKuninori Morimoto } 942034d7c13SKuninori Morimoto 943034d7c13SKuninori Morimoto /* 9444825093eSKuninori Morimoto * attach endpoint if needed 945e5679d07SKuninori Morimoto * see [image of mod_host] 946034d7c13SKuninori Morimoto */ 9474825093eSKuninori Morimoto if (!usbhsh_ep_to_uep(ep)) { 9484825093eSKuninori Morimoto ret = usbhsh_endpoint_attach(hpriv, urb, mem_flags); 9494825093eSKuninori Morimoto if (ret < 0) 950034d7c13SKuninori Morimoto goto usbhsh_urb_enqueue_error_free_device; 951034d7c13SKuninori Morimoto } 952034d7c13SKuninori Morimoto 953034d7c13SKuninori Morimoto /* 954e5679d07SKuninori Morimoto * attach pipe to endpoint 955e5679d07SKuninori Morimoto * see [image of mod_host] 956e5679d07SKuninori Morimoto */ 957e5679d07SKuninori Morimoto for (i = 0; i < 1024; i++) { 958e5679d07SKuninori Morimoto ret = usbhsh_pipe_attach(hpriv, urb); 959e5679d07SKuninori Morimoto if (ret < 0) 960e5679d07SKuninori Morimoto msleep(100); 961e5679d07SKuninori Morimoto else 962e5679d07SKuninori Morimoto break; 963e5679d07SKuninori Morimoto } 964e5679d07SKuninori Morimoto if (ret < 0) 965e5679d07SKuninori Morimoto goto usbhsh_urb_enqueue_error_free_endpoint; 966e5679d07SKuninori Morimoto 967e5679d07SKuninori Morimoto /* 968034d7c13SKuninori Morimoto * push packet 969034d7c13SKuninori Morimoto */ 970034d7c13SKuninori Morimoto if (usb_pipecontrol(urb->pipe)) 9713eddc9e4SKuninori Morimoto ret = usbhsh_dcp_queue_push(hcd, urb, mem_flags); 972034d7c13SKuninori Morimoto else 9733eddc9e4SKuninori Morimoto ret = usbhsh_queue_push(hcd, urb, mem_flags); 974034d7c13SKuninori Morimoto 975ee8a0bf5SKuninori Morimoto return ret; 976034d7c13SKuninori Morimoto 977e5679d07SKuninori Morimoto usbhsh_urb_enqueue_error_free_endpoint: 978e5679d07SKuninori Morimoto usbhsh_endpoint_detach(hpriv, ep); 979034d7c13SKuninori Morimoto usbhsh_urb_enqueue_error_free_device: 980034d7c13SKuninori Morimoto if (new_udev) 9817aac8d15SKuninori Morimoto usbhsh_device_detach(hpriv, new_udev); 982034d7c13SKuninori Morimoto usbhsh_urb_enqueue_error_not_linked: 983034d7c13SKuninori Morimoto 984034d7c13SKuninori Morimoto dev_dbg(dev, "%s error\n", __func__); 985034d7c13SKuninori Morimoto 986034d7c13SKuninori Morimoto return ret; 987034d7c13SKuninori Morimoto } 988034d7c13SKuninori Morimoto 989034d7c13SKuninori Morimoto static int usbhsh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) 990034d7c13SKuninori Morimoto { 991034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 992034d7c13SKuninori Morimoto struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); 993034d7c13SKuninori Morimoto 99454796543SKuninori Morimoto if (ureq) { 99554796543SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 99654796543SKuninori Morimoto struct usbhs_pkt *pkt = &ureq->pkt; 99754796543SKuninori Morimoto 99854796543SKuninori Morimoto usbhs_pkt_pop(pkt->pipe, pkt); 99954796543SKuninori Morimoto usbhsh_queue_done(priv, pkt); 100054796543SKuninori Morimoto } 1001034d7c13SKuninori Morimoto 1002034d7c13SKuninori Morimoto return 0; 1003034d7c13SKuninori Morimoto } 1004034d7c13SKuninori Morimoto 1005034d7c13SKuninori Morimoto static void usbhsh_endpoint_disable(struct usb_hcd *hcd, 1006034d7c13SKuninori Morimoto struct usb_host_endpoint *ep) 1007034d7c13SKuninori Morimoto { 1008034d7c13SKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); 1009034d7c13SKuninori Morimoto struct usbhsh_device *udev; 1010034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv; 1011034d7c13SKuninori Morimoto 1012034d7c13SKuninori Morimoto /* 1013034d7c13SKuninori Morimoto * this function might be called manytimes by same hcd/ep 1014fca8ab7eSKuninori Morimoto * in-endpoint == out-endpoint if ep == dcp. 1015034d7c13SKuninori Morimoto */ 1016034d7c13SKuninori Morimoto if (!uep) 1017034d7c13SKuninori Morimoto return; 1018034d7c13SKuninori Morimoto 1019034d7c13SKuninori Morimoto udev = usbhsh_uep_to_udev(uep); 1020034d7c13SKuninori Morimoto hpriv = usbhsh_hcd_to_hpriv(hcd); 1021034d7c13SKuninori Morimoto 10224825093eSKuninori Morimoto usbhsh_endpoint_detach(hpriv, ep); 1023034d7c13SKuninori Morimoto 1024034d7c13SKuninori Morimoto /* 1025034d7c13SKuninori Morimoto * if there is no endpoint, 1026034d7c13SKuninori Morimoto * free device 1027034d7c13SKuninori Morimoto */ 1028034d7c13SKuninori Morimoto if (!usbhsh_device_has_endpoint(udev)) 10297aac8d15SKuninori Morimoto usbhsh_device_detach(hpriv, udev); 1030034d7c13SKuninori Morimoto } 1031034d7c13SKuninori Morimoto 1032034d7c13SKuninori Morimoto static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) 1033034d7c13SKuninori Morimoto { 1034034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 1035034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1036034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1037034d7c13SKuninori Morimoto int roothub_id = 1; /* only 1 root hub */ 1038034d7c13SKuninori Morimoto 1039034d7c13SKuninori Morimoto /* 1040034d7c13SKuninori Morimoto * does port stat was changed ? 1041034d7c13SKuninori Morimoto * check USB_PORT_STAT_C_xxx << 16 1042034d7c13SKuninori Morimoto */ 1043034d7c13SKuninori Morimoto if (usbhsh_port_stat_get(hpriv) & 0xFFFF0000) 1044034d7c13SKuninori Morimoto *buf = (1 << roothub_id); 1045034d7c13SKuninori Morimoto else 1046034d7c13SKuninori Morimoto *buf = 0; 1047034d7c13SKuninori Morimoto 1048034d7c13SKuninori Morimoto dev_dbg(dev, "%s (%02x)\n", __func__, *buf); 1049034d7c13SKuninori Morimoto 1050034d7c13SKuninori Morimoto return !!(*buf); 1051034d7c13SKuninori Morimoto } 1052034d7c13SKuninori Morimoto 1053034d7c13SKuninori Morimoto static int __usbhsh_hub_hub_feature(struct usbhsh_hpriv *hpriv, 1054034d7c13SKuninori Morimoto u16 typeReq, u16 wValue, 1055034d7c13SKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1056034d7c13SKuninori Morimoto { 1057034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1058034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1059034d7c13SKuninori Morimoto 1060034d7c13SKuninori Morimoto switch (wValue) { 1061034d7c13SKuninori Morimoto case C_HUB_OVER_CURRENT: 1062034d7c13SKuninori Morimoto case C_HUB_LOCAL_POWER: 1063034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: C_HUB_xx\n", __func__); 1064034d7c13SKuninori Morimoto return 0; 1065034d7c13SKuninori Morimoto } 1066034d7c13SKuninori Morimoto 1067034d7c13SKuninori Morimoto return -EPIPE; 1068034d7c13SKuninori Morimoto } 1069034d7c13SKuninori Morimoto 1070034d7c13SKuninori Morimoto static int __usbhsh_hub_port_feature(struct usbhsh_hpriv *hpriv, 1071034d7c13SKuninori Morimoto u16 typeReq, u16 wValue, 1072034d7c13SKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1073034d7c13SKuninori Morimoto { 1074034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1075034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1076034d7c13SKuninori Morimoto int enable = (typeReq == SetPortFeature); 1077034d7c13SKuninori Morimoto int speed, i, timeout = 128; 1078034d7c13SKuninori Morimoto int roothub_id = 1; /* only 1 root hub */ 1079034d7c13SKuninori Morimoto 1080034d7c13SKuninori Morimoto /* common error */ 1081034d7c13SKuninori Morimoto if (wIndex > roothub_id || wLength != 0) 1082034d7c13SKuninori Morimoto return -EPIPE; 1083034d7c13SKuninori Morimoto 1084034d7c13SKuninori Morimoto /* check wValue */ 1085034d7c13SKuninori Morimoto switch (wValue) { 1086034d7c13SKuninori Morimoto case USB_PORT_FEAT_POWER: 1087034d7c13SKuninori Morimoto usbhs_vbus_ctrl(priv, enable); 1088034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: USB_PORT_FEAT_POWER\n", __func__); 1089034d7c13SKuninori Morimoto break; 1090034d7c13SKuninori Morimoto 1091034d7c13SKuninori Morimoto case USB_PORT_FEAT_ENABLE: 1092034d7c13SKuninori Morimoto case USB_PORT_FEAT_SUSPEND: 1093034d7c13SKuninori Morimoto case USB_PORT_FEAT_C_ENABLE: 1094034d7c13SKuninori Morimoto case USB_PORT_FEAT_C_SUSPEND: 1095034d7c13SKuninori Morimoto case USB_PORT_FEAT_C_CONNECTION: 1096034d7c13SKuninori Morimoto case USB_PORT_FEAT_C_OVER_CURRENT: 1097034d7c13SKuninori Morimoto case USB_PORT_FEAT_C_RESET: 1098034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: USB_PORT_FEAT_xxx\n", __func__); 1099034d7c13SKuninori Morimoto break; 1100034d7c13SKuninori Morimoto 1101034d7c13SKuninori Morimoto case USB_PORT_FEAT_RESET: 1102034d7c13SKuninori Morimoto if (!enable) 1103034d7c13SKuninori Morimoto break; 1104034d7c13SKuninori Morimoto 1105034d7c13SKuninori Morimoto usbhsh_port_stat_clear(hpriv, 1106034d7c13SKuninori Morimoto USB_PORT_STAT_HIGH_SPEED | 1107034d7c13SKuninori Morimoto USB_PORT_STAT_LOW_SPEED); 1108034d7c13SKuninori Morimoto 1109034d7c13SKuninori Morimoto usbhs_bus_send_reset(priv); 1110034d7c13SKuninori Morimoto msleep(20); 1111034d7c13SKuninori Morimoto usbhs_bus_send_sof_enable(priv); 1112034d7c13SKuninori Morimoto 1113034d7c13SKuninori Morimoto for (i = 0; i < timeout ; i++) { 1114034d7c13SKuninori Morimoto switch (usbhs_bus_get_speed(priv)) { 1115034d7c13SKuninori Morimoto case USB_SPEED_LOW: 1116034d7c13SKuninori Morimoto speed = USB_PORT_STAT_LOW_SPEED; 1117034d7c13SKuninori Morimoto goto got_usb_bus_speed; 1118034d7c13SKuninori Morimoto case USB_SPEED_HIGH: 1119034d7c13SKuninori Morimoto speed = USB_PORT_STAT_HIGH_SPEED; 1120034d7c13SKuninori Morimoto goto got_usb_bus_speed; 1121034d7c13SKuninori Morimoto case USB_SPEED_FULL: 1122034d7c13SKuninori Morimoto speed = 0; 1123034d7c13SKuninori Morimoto goto got_usb_bus_speed; 1124034d7c13SKuninori Morimoto } 1125034d7c13SKuninori Morimoto 1126034d7c13SKuninori Morimoto msleep(20); 1127034d7c13SKuninori Morimoto } 1128034d7c13SKuninori Morimoto return -EPIPE; 1129034d7c13SKuninori Morimoto 1130034d7c13SKuninori Morimoto got_usb_bus_speed: 1131034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, speed); 1132034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_ENABLE); 1133034d7c13SKuninori Morimoto 1134034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: USB_PORT_FEAT_RESET (speed = %d)\n", 1135034d7c13SKuninori Morimoto __func__, speed); 1136034d7c13SKuninori Morimoto 1137034d7c13SKuninori Morimoto /* status change is not needed */ 1138034d7c13SKuninori Morimoto return 0; 1139034d7c13SKuninori Morimoto 1140034d7c13SKuninori Morimoto default: 1141034d7c13SKuninori Morimoto return -EPIPE; 1142034d7c13SKuninori Morimoto } 1143034d7c13SKuninori Morimoto 1144034d7c13SKuninori Morimoto /* set/clear status */ 1145034d7c13SKuninori Morimoto if (enable) 1146034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, (1 << wValue)); 1147034d7c13SKuninori Morimoto else 1148034d7c13SKuninori Morimoto usbhsh_port_stat_clear(hpriv, (1 << wValue)); 1149034d7c13SKuninori Morimoto 1150034d7c13SKuninori Morimoto return 0; 1151034d7c13SKuninori Morimoto } 1152034d7c13SKuninori Morimoto 1153034d7c13SKuninori Morimoto static int __usbhsh_hub_get_status(struct usbhsh_hpriv *hpriv, 1154034d7c13SKuninori Morimoto u16 typeReq, u16 wValue, 1155034d7c13SKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1156034d7c13SKuninori Morimoto { 1157034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1158034d7c13SKuninori Morimoto struct usb_hub_descriptor *desc = (struct usb_hub_descriptor *)buf; 1159034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1160034d7c13SKuninori Morimoto int roothub_id = 1; /* only 1 root hub */ 1161034d7c13SKuninori Morimoto 1162034d7c13SKuninori Morimoto switch (typeReq) { 1163034d7c13SKuninori Morimoto case GetHubStatus: 1164034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: GetHubStatus\n", __func__); 1165034d7c13SKuninori Morimoto 1166034d7c13SKuninori Morimoto *buf = 0x00; 1167034d7c13SKuninori Morimoto break; 1168034d7c13SKuninori Morimoto 1169034d7c13SKuninori Morimoto case GetPortStatus: 1170034d7c13SKuninori Morimoto if (wIndex != roothub_id) 1171034d7c13SKuninori Morimoto return -EPIPE; 1172034d7c13SKuninori Morimoto 1173034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: GetPortStatus\n", __func__); 1174034d7c13SKuninori Morimoto *(__le32 *)buf = cpu_to_le32(usbhsh_port_stat_get(hpriv)); 1175034d7c13SKuninori Morimoto break; 1176034d7c13SKuninori Morimoto 1177034d7c13SKuninori Morimoto case GetHubDescriptor: 1178034d7c13SKuninori Morimoto desc->bDescriptorType = 0x29; 1179034d7c13SKuninori Morimoto desc->bHubContrCurrent = 0; 1180034d7c13SKuninori Morimoto desc->bNbrPorts = roothub_id; 1181034d7c13SKuninori Morimoto desc->bDescLength = 9; 1182034d7c13SKuninori Morimoto desc->bPwrOn2PwrGood = 0; 1183034d7c13SKuninori Morimoto desc->wHubCharacteristics = cpu_to_le16(0x0011); 1184034d7c13SKuninori Morimoto desc->u.hs.DeviceRemovable[0] = (roothub_id << 1); 1185034d7c13SKuninori Morimoto desc->u.hs.DeviceRemovable[1] = ~0; 1186034d7c13SKuninori Morimoto dev_dbg(dev, "%s :: GetHubDescriptor\n", __func__); 1187034d7c13SKuninori Morimoto break; 1188034d7c13SKuninori Morimoto } 1189034d7c13SKuninori Morimoto 1190034d7c13SKuninori Morimoto return 0; 1191034d7c13SKuninori Morimoto } 1192034d7c13SKuninori Morimoto 1193034d7c13SKuninori Morimoto static int usbhsh_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, 1194034d7c13SKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1195034d7c13SKuninori Morimoto { 1196034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 1197034d7c13SKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1198034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1199034d7c13SKuninori Morimoto int ret = -EPIPE; 1200034d7c13SKuninori Morimoto 1201034d7c13SKuninori Morimoto switch (typeReq) { 1202034d7c13SKuninori Morimoto 1203034d7c13SKuninori Morimoto /* Hub Feature */ 1204034d7c13SKuninori Morimoto case ClearHubFeature: 1205034d7c13SKuninori Morimoto case SetHubFeature: 1206034d7c13SKuninori Morimoto ret = __usbhsh_hub_hub_feature(hpriv, typeReq, 1207034d7c13SKuninori Morimoto wValue, wIndex, buf, wLength); 1208034d7c13SKuninori Morimoto break; 1209034d7c13SKuninori Morimoto 1210034d7c13SKuninori Morimoto /* Port Feature */ 1211034d7c13SKuninori Morimoto case SetPortFeature: 1212034d7c13SKuninori Morimoto case ClearPortFeature: 1213034d7c13SKuninori Morimoto ret = __usbhsh_hub_port_feature(hpriv, typeReq, 1214034d7c13SKuninori Morimoto wValue, wIndex, buf, wLength); 1215034d7c13SKuninori Morimoto break; 1216034d7c13SKuninori Morimoto 1217034d7c13SKuninori Morimoto /* Get status */ 1218034d7c13SKuninori Morimoto case GetHubStatus: 1219034d7c13SKuninori Morimoto case GetPortStatus: 1220034d7c13SKuninori Morimoto case GetHubDescriptor: 1221034d7c13SKuninori Morimoto ret = __usbhsh_hub_get_status(hpriv, typeReq, 1222034d7c13SKuninori Morimoto wValue, wIndex, buf, wLength); 1223034d7c13SKuninori Morimoto break; 1224034d7c13SKuninori Morimoto } 1225034d7c13SKuninori Morimoto 1226034d7c13SKuninori Morimoto dev_dbg(dev, "typeReq = %x, ret = %d, port_stat = %x\n", 1227034d7c13SKuninori Morimoto typeReq, ret, usbhsh_port_stat_get(hpriv)); 1228034d7c13SKuninori Morimoto 1229034d7c13SKuninori Morimoto return ret; 1230034d7c13SKuninori Morimoto } 1231034d7c13SKuninori Morimoto 1232034d7c13SKuninori Morimoto static struct hc_driver usbhsh_driver = { 1233034d7c13SKuninori Morimoto .description = usbhsh_hcd_name, 1234034d7c13SKuninori Morimoto .hcd_priv_size = sizeof(struct usbhsh_hpriv), 1235034d7c13SKuninori Morimoto 1236034d7c13SKuninori Morimoto /* 1237034d7c13SKuninori Morimoto * generic hardware linkage 1238034d7c13SKuninori Morimoto */ 1239034d7c13SKuninori Morimoto .flags = HCD_USB2, 1240034d7c13SKuninori Morimoto 1241034d7c13SKuninori Morimoto .start = usbhsh_host_start, 1242034d7c13SKuninori Morimoto .stop = usbhsh_host_stop, 1243034d7c13SKuninori Morimoto 1244034d7c13SKuninori Morimoto /* 1245034d7c13SKuninori Morimoto * managing i/o requests and associated device resources 1246034d7c13SKuninori Morimoto */ 1247034d7c13SKuninori Morimoto .urb_enqueue = usbhsh_urb_enqueue, 1248034d7c13SKuninori Morimoto .urb_dequeue = usbhsh_urb_dequeue, 1249034d7c13SKuninori Morimoto .endpoint_disable = usbhsh_endpoint_disable, 1250034d7c13SKuninori Morimoto 1251034d7c13SKuninori Morimoto /* 1252034d7c13SKuninori Morimoto * root hub 1253034d7c13SKuninori Morimoto */ 1254034d7c13SKuninori Morimoto .hub_status_data = usbhsh_hub_status_data, 1255034d7c13SKuninori Morimoto .hub_control = usbhsh_hub_control, 1256034d7c13SKuninori Morimoto }; 1257034d7c13SKuninori Morimoto 1258034d7c13SKuninori Morimoto /* 1259034d7c13SKuninori Morimoto * interrupt functions 1260034d7c13SKuninori Morimoto */ 1261034d7c13SKuninori Morimoto static int usbhsh_irq_attch(struct usbhs_priv *priv, 1262034d7c13SKuninori Morimoto struct usbhs_irq_state *irq_state) 1263034d7c13SKuninori Morimoto { 1264034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1265034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1266034d7c13SKuninori Morimoto 1267034d7c13SKuninori Morimoto dev_dbg(dev, "device attached\n"); 1268034d7c13SKuninori Morimoto 1269034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_CONNECTION); 1270034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); 1271034d7c13SKuninori Morimoto 127231e00fd1SKuninori Morimoto /* 127331e00fd1SKuninori Morimoto * attch interrupt might happen infinitely on some device 127431e00fd1SKuninori Morimoto * (on self power USB hub ?) 127531e00fd1SKuninori Morimoto * disable it here. 1276b1930da0SKuninori Morimoto * 1277b1930da0SKuninori Morimoto * usbhsh_is_running() becomes effective 1278b1930da0SKuninori Morimoto * according to this process. 1279b1930da0SKuninori Morimoto * see 1280b1930da0SKuninori Morimoto * usbhsh_is_running() 1281b1930da0SKuninori Morimoto * usbhsh_urb_enqueue() 128231e00fd1SKuninori Morimoto */ 128331e00fd1SKuninori Morimoto hpriv->mod.irq_attch = NULL; 128431e00fd1SKuninori Morimoto usbhs_irq_callback_update(priv, &hpriv->mod); 128531e00fd1SKuninori Morimoto 1286034d7c13SKuninori Morimoto return 0; 1287034d7c13SKuninori Morimoto } 1288034d7c13SKuninori Morimoto 1289034d7c13SKuninori Morimoto static int usbhsh_irq_dtch(struct usbhs_priv *priv, 1290034d7c13SKuninori Morimoto struct usbhs_irq_state *irq_state) 1291034d7c13SKuninori Morimoto { 1292034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1293034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1294034d7c13SKuninori Morimoto 1295034d7c13SKuninori Morimoto dev_dbg(dev, "device detached\n"); 1296034d7c13SKuninori Morimoto 1297034d7c13SKuninori Morimoto usbhsh_port_stat_clear(hpriv, USB_PORT_STAT_CONNECTION); 1298034d7c13SKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); 1299034d7c13SKuninori Morimoto 130031e00fd1SKuninori Morimoto /* 130131e00fd1SKuninori Morimoto * enable attch interrupt again 1302b1930da0SKuninori Morimoto * 1303b1930da0SKuninori Morimoto * usbhsh_is_running() becomes invalid 1304b1930da0SKuninori Morimoto * according to this process. 1305b1930da0SKuninori Morimoto * see 1306b1930da0SKuninori Morimoto * usbhsh_is_running() 1307b1930da0SKuninori Morimoto * usbhsh_urb_enqueue() 130831e00fd1SKuninori Morimoto */ 130931e00fd1SKuninori Morimoto hpriv->mod.irq_attch = usbhsh_irq_attch; 131031e00fd1SKuninori Morimoto usbhs_irq_callback_update(priv, &hpriv->mod); 131131e00fd1SKuninori Morimoto 1312034d7c13SKuninori Morimoto return 0; 1313034d7c13SKuninori Morimoto } 1314034d7c13SKuninori Morimoto 1315034d7c13SKuninori Morimoto static int usbhsh_irq_setup_ack(struct usbhs_priv *priv, 1316034d7c13SKuninori Morimoto struct usbhs_irq_state *irq_state) 1317034d7c13SKuninori Morimoto { 1318034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1319034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1320034d7c13SKuninori Morimoto 1321034d7c13SKuninori Morimoto dev_dbg(dev, "setup packet OK\n"); 1322034d7c13SKuninori Morimoto 13237fccd480SKuninori Morimoto complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */ 1324034d7c13SKuninori Morimoto 1325034d7c13SKuninori Morimoto return 0; 1326034d7c13SKuninori Morimoto } 1327034d7c13SKuninori Morimoto 1328034d7c13SKuninori Morimoto static int usbhsh_irq_setup_err(struct usbhs_priv *priv, 1329034d7c13SKuninori Morimoto struct usbhs_irq_state *irq_state) 1330034d7c13SKuninori Morimoto { 1331034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1332034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1333034d7c13SKuninori Morimoto 1334034d7c13SKuninori Morimoto dev_dbg(dev, "setup packet Err\n"); 1335034d7c13SKuninori Morimoto 13367fccd480SKuninori Morimoto complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */ 1337034d7c13SKuninori Morimoto 1338034d7c13SKuninori Morimoto return 0; 1339034d7c13SKuninori Morimoto } 1340034d7c13SKuninori Morimoto 1341034d7c13SKuninori Morimoto /* 1342034d7c13SKuninori Morimoto * module start/stop 1343034d7c13SKuninori Morimoto */ 1344034d7c13SKuninori Morimoto static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) 1345034d7c13SKuninori Morimoto { 1346034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1347034d7c13SKuninori Morimoto struct usbhs_pipe *pipe; 1348034d7c13SKuninori Morimoto u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); 1349034d7c13SKuninori Morimoto int pipe_size = usbhs_get_dparam(priv, pipe_size); 1350034d7c13SKuninori Morimoto int old_type, dir_in, i; 1351034d7c13SKuninori Morimoto 1352034d7c13SKuninori Morimoto /* init all pipe */ 1353034d7c13SKuninori Morimoto old_type = USB_ENDPOINT_XFER_CONTROL; 1354034d7c13SKuninori Morimoto for (i = 0; i < pipe_size; i++) { 1355034d7c13SKuninori Morimoto 1356034d7c13SKuninori Morimoto /* 1357034d7c13SKuninori Morimoto * data "output" will be finished as soon as possible, 1358034d7c13SKuninori Morimoto * but there is no guaranty at data "input" case. 1359034d7c13SKuninori Morimoto * 1360034d7c13SKuninori Morimoto * "input" needs "standby" pipe. 1361034d7c13SKuninori Morimoto * So, "input" direction pipe > "output" direction pipe 1362034d7c13SKuninori Morimoto * is good idea. 1363034d7c13SKuninori Morimoto * 1364034d7c13SKuninori Morimoto * 1st USB_ENDPOINT_XFER_xxx will be output direction, 1365034d7c13SKuninori Morimoto * and the other will be input direction here. 1366034d7c13SKuninori Morimoto * 1367034d7c13SKuninori Morimoto * ex) 1368034d7c13SKuninori Morimoto * ... 1369034d7c13SKuninori Morimoto * USB_ENDPOINT_XFER_ISOC -> dir out 1370034d7c13SKuninori Morimoto * USB_ENDPOINT_XFER_ISOC -> dir in 1371034d7c13SKuninori Morimoto * USB_ENDPOINT_XFER_BULK -> dir out 1372034d7c13SKuninori Morimoto * USB_ENDPOINT_XFER_BULK -> dir in 1373034d7c13SKuninori Morimoto * USB_ENDPOINT_XFER_BULK -> dir in 1374034d7c13SKuninori Morimoto * ... 1375034d7c13SKuninori Morimoto */ 1376034d7c13SKuninori Morimoto dir_in = (pipe_type[i] == old_type); 1377034d7c13SKuninori Morimoto old_type = pipe_type[i]; 1378034d7c13SKuninori Morimoto 1379034d7c13SKuninori Morimoto if (USB_ENDPOINT_XFER_CONTROL == pipe_type[i]) { 1380034d7c13SKuninori Morimoto pipe = usbhs_dcp_malloc(priv); 1381034d7c13SKuninori Morimoto usbhsh_hpriv_to_dcp(hpriv) = pipe; 1382034d7c13SKuninori Morimoto } else { 1383034d7c13SKuninori Morimoto pipe = usbhs_pipe_malloc(priv, 1384034d7c13SKuninori Morimoto pipe_type[i], 1385034d7c13SKuninori Morimoto dir_in); 1386034d7c13SKuninori Morimoto } 1387034d7c13SKuninori Morimoto 1388e5679d07SKuninori Morimoto pipe->mod_private = NULL; 1389034d7c13SKuninori Morimoto } 1390034d7c13SKuninori Morimoto } 1391034d7c13SKuninori Morimoto 1392034d7c13SKuninori Morimoto static int usbhsh_start(struct usbhs_priv *priv) 1393034d7c13SKuninori Morimoto { 1394034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1395034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 1396034d7c13SKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 1397034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1398034d7c13SKuninori Morimoto int ret; 1399034d7c13SKuninori Morimoto 1400034d7c13SKuninori Morimoto /* add hcd */ 1401034d7c13SKuninori Morimoto ret = usb_add_hcd(hcd, 0, 0); 1402034d7c13SKuninori Morimoto if (ret < 0) 1403034d7c13SKuninori Morimoto return 0; 1404034d7c13SKuninori Morimoto 1405034d7c13SKuninori Morimoto /* 1406034d7c13SKuninori Morimoto * pipe initialize and enable DCP 1407034d7c13SKuninori Morimoto */ 1408034d7c13SKuninori Morimoto usbhs_pipe_init(priv, 1409034d7c13SKuninori Morimoto usbhsh_dma_map_ctrl); 1410034d7c13SKuninori Morimoto usbhs_fifo_init(priv); 1411034d7c13SKuninori Morimoto usbhsh_pipe_init_for_host(priv); 1412034d7c13SKuninori Morimoto 1413034d7c13SKuninori Morimoto /* 1414034d7c13SKuninori Morimoto * system config enble 1415034d7c13SKuninori Morimoto * - HI speed 1416034d7c13SKuninori Morimoto * - host 1417034d7c13SKuninori Morimoto * - usb module 1418034d7c13SKuninori Morimoto */ 1419034d7c13SKuninori Morimoto usbhs_sys_host_ctrl(priv, 1); 1420034d7c13SKuninori Morimoto 1421034d7c13SKuninori Morimoto /* 1422034d7c13SKuninori Morimoto * enable irq callback 1423034d7c13SKuninori Morimoto */ 1424034d7c13SKuninori Morimoto mod->irq_attch = usbhsh_irq_attch; 1425034d7c13SKuninori Morimoto mod->irq_dtch = usbhsh_irq_dtch; 1426034d7c13SKuninori Morimoto mod->irq_sack = usbhsh_irq_setup_ack; 1427034d7c13SKuninori Morimoto mod->irq_sign = usbhsh_irq_setup_err; 1428034d7c13SKuninori Morimoto usbhs_irq_callback_update(priv, mod); 1429034d7c13SKuninori Morimoto 1430034d7c13SKuninori Morimoto dev_dbg(dev, "start host\n"); 1431034d7c13SKuninori Morimoto 1432034d7c13SKuninori Morimoto return ret; 1433034d7c13SKuninori Morimoto } 1434034d7c13SKuninori Morimoto 1435034d7c13SKuninori Morimoto static int usbhsh_stop(struct usbhs_priv *priv) 1436034d7c13SKuninori Morimoto { 1437034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1438034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 1439146ee50aSKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 1440034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1441034d7c13SKuninori Morimoto 1442146ee50aSKuninori Morimoto /* 1443146ee50aSKuninori Morimoto * disable irq callback 1444146ee50aSKuninori Morimoto */ 1445146ee50aSKuninori Morimoto mod->irq_attch = NULL; 1446146ee50aSKuninori Morimoto mod->irq_dtch = NULL; 1447146ee50aSKuninori Morimoto mod->irq_sack = NULL; 1448146ee50aSKuninori Morimoto mod->irq_sign = NULL; 1449146ee50aSKuninori Morimoto usbhs_irq_callback_update(priv, mod); 1450146ee50aSKuninori Morimoto 1451034d7c13SKuninori Morimoto usb_remove_hcd(hcd); 1452034d7c13SKuninori Morimoto 1453034d7c13SKuninori Morimoto /* disable sys */ 1454034d7c13SKuninori Morimoto usbhs_sys_host_ctrl(priv, 0); 1455034d7c13SKuninori Morimoto 1456034d7c13SKuninori Morimoto dev_dbg(dev, "quit host\n"); 1457034d7c13SKuninori Morimoto 1458034d7c13SKuninori Morimoto return 0; 1459034d7c13SKuninori Morimoto } 1460034d7c13SKuninori Morimoto 1461b7a8d17dSKuninori Morimoto int usbhs_mod_host_probe(struct usbhs_priv *priv) 1462034d7c13SKuninori Morimoto { 1463034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv; 1464034d7c13SKuninori Morimoto struct usb_hcd *hcd; 1465034d7c13SKuninori Morimoto struct usbhsh_device *udev; 1466034d7c13SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1467034d7c13SKuninori Morimoto int i; 1468034d7c13SKuninori Morimoto 1469034d7c13SKuninori Morimoto /* initialize hcd */ 1470034d7c13SKuninori Morimoto hcd = usb_create_hcd(&usbhsh_driver, dev, usbhsh_hcd_name); 1471034d7c13SKuninori Morimoto if (!hcd) { 1472034d7c13SKuninori Morimoto dev_err(dev, "Failed to create hcd\n"); 1473034d7c13SKuninori Morimoto return -ENOMEM; 1474034d7c13SKuninori Morimoto } 1475034d7c13SKuninori Morimoto 1476034d7c13SKuninori Morimoto /* 1477034d7c13SKuninori Morimoto * CAUTION 1478034d7c13SKuninori Morimoto * 1479034d7c13SKuninori Morimoto * There is no guarantee that it is possible to access usb module here. 1480034d7c13SKuninori Morimoto * Don't accesses to it. 1481034d7c13SKuninori Morimoto * The accesse will be enable after "usbhsh_start" 1482034d7c13SKuninori Morimoto */ 1483034d7c13SKuninori Morimoto 1484034d7c13SKuninori Morimoto hpriv = usbhsh_hcd_to_hpriv(hcd); 1485034d7c13SKuninori Morimoto 1486034d7c13SKuninori Morimoto /* 1487034d7c13SKuninori Morimoto * register itself 1488034d7c13SKuninori Morimoto */ 1489034d7c13SKuninori Morimoto usbhs_mod_register(priv, &hpriv->mod, USBHS_HOST); 1490034d7c13SKuninori Morimoto 1491034d7c13SKuninori Morimoto /* init hpriv */ 1492034d7c13SKuninori Morimoto hpriv->mod.name = "host"; 1493034d7c13SKuninori Morimoto hpriv->mod.start = usbhsh_start; 1494034d7c13SKuninori Morimoto hpriv->mod.stop = usbhsh_stop; 1495034d7c13SKuninori Morimoto usbhsh_port_stat_init(hpriv); 1496034d7c13SKuninori Morimoto 1497034d7c13SKuninori Morimoto /* init all device */ 1498034d7c13SKuninori Morimoto usbhsh_for_each_udev_with_dev0(udev, hpriv, i) { 1499034d7c13SKuninori Morimoto udev->usbv = NULL; 1500034d7c13SKuninori Morimoto INIT_LIST_HEAD(&udev->ep_list_head); 1501034d7c13SKuninori Morimoto } 1502034d7c13SKuninori Morimoto 1503034d7c13SKuninori Morimoto dev_info(dev, "host probed\n"); 1504034d7c13SKuninori Morimoto 1505034d7c13SKuninori Morimoto return 0; 1506034d7c13SKuninori Morimoto } 1507034d7c13SKuninori Morimoto 1508b7a8d17dSKuninori Morimoto int usbhs_mod_host_remove(struct usbhs_priv *priv) 1509034d7c13SKuninori Morimoto { 1510034d7c13SKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1511034d7c13SKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 1512034d7c13SKuninori Morimoto 1513034d7c13SKuninori Morimoto usb_put_hcd(hcd); 1514034d7c13SKuninori Morimoto 1515034d7c13SKuninori Morimoto return 0; 1516034d7c13SKuninori Morimoto } 1517