1034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 2034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * Renesas USB driver 3034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 4034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * Copyright (C) 2011 Renesas Solutions Corp. 5034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 7034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * This program is distributed in the hope that it will be useful, 8034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * but WITHOUT ANY WARRANTY; without even the implied warranty of 9034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * GNU General Public License for more details. 11034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 12034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * You should have received a copy of the GNU General Public License 13034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * along with this program; if not, write to the Free Software 14034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 15034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 16034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 17034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#include <linux/io.h> 18034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#include <linux/list.h> 19034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#include <linux/module.h> 20034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#include <linux/platform_device.h> 21034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#include <linux/slab.h> 22034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#include <linux/usb.h> 23034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#include <linux/usb/hcd.h> 24034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#include "common.h" 25034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 26034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 27034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto *** HARDWARE LIMITATION *** 28034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 29034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 1) renesas_usbhs has a limited number of controllable devices. 30034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * it can control only 9 devices in generally. 31034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * see DEVADDn / DCPMAXP / PIPEMAXP. 32034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 33034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 2) renesas_usbhs pipe number is limited. 34034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * the pipe will be re-used for each devices. 35034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * so, software should control DATA0/1 sequence of each devices. 36034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 37034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 38034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 39034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 40034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * image of mod_host 41034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 42034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * +--------+ 43034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * | udev 0 | --> it is used when set address 44034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * +--------+ 45034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 46034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * +--------+ pipes are reused for each uep. 47034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * | udev 1 |-+- [uep 0 (dcp) ] --+ pipe will be switched when 48e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * +--------+ | | other device requested 49034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * +- [uep 1 (bulk)] --|---+ +--------------+ 50034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * | +--------------> | pipe0 (dcp) | 51e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * +- [uep 2 (bulk)] -@ | +--------------+ 52e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * | | pipe1 (isoc) | 53e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * +--------+ | +--------------+ 54e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * | udev 2 |-+- [uep 0 (dcp) ] -@ +----------> | pipe2 (bulk) | 55e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * +--------+ | +--------------+ 56e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * +- [uep 1 (int) ] ----+ +------> | pipe3 (bulk) | 57e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * | | +--------------+ 58e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * +--------+ +-----|------> | pipe4 (int) | 59e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * | udev 3 |-+- [uep 0 (dcp) ] -@ | +--------------+ 60e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * +--------+ | | | .... | 61e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * +- [uep 1 (bulk)] -@ | | .... | 62034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * | | 63034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * +- [uep 2 (bulk)]-----------+ 64e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * 65e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * @ : uep requested free pipe, but all have been used. 66e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * now it is waiting for free pipe 67034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 68034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 69034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 70034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 71034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * struct 72034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 73034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostruct usbhsh_request { 74034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct urb *urb; 75034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_pkt pkt; 76034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto}; 77034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 78034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostruct usbhsh_device { 79034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_device *usbv; 80034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct list_head ep_list_head; /* list of usbhsh_ep */ 81034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto}; 82034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 83034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostruct usbhsh_ep { 84e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usbhs_pipe *pipe; /* attached pipe */ 85034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_device *udev; /* attached udev */ 86e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct usb_host_endpoint *ep; 87034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct list_head ep_list; /* list to usbhsh_device */ 88034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto}; 89034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 90034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ 91034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define USBHSH_PORT_MAX 7 /* see DEVADDn :: HUBPORT */ 92034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostruct usbhsh_hpriv { 93034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_mod mod; 94034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_pipe *dcp; 95034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 96034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_device udev[USBHSH_DEVICE_MAX]; 97034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 98034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto u32 port_stat; /* USB_PORT_STAT_xxx */ 99034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1007fccd480b7fe84a98ee252fa79dd92f7fff5ec2aKuninori Morimoto struct completion setup_ack_done; 101034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto}; 102034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 103034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 104034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic const char usbhsh_hcd_name[] = "renesas_usbhs host"; 105034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 106034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 107034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * macro 108034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 109034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_priv_to_hpriv(priv) \ 110034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto container_of(usbhs_mod_get(priv, USBHS_HOST), struct usbhsh_hpriv, mod) 111034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 112034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define __usbhsh_for_each_udev(start, pos, h, i) \ 113034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto for (i = start, pos = (h)->udev + i; \ 114034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto i < USBHSH_DEVICE_MAX; \ 115034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto i++, pos = (h)->udev + i) 116034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 117034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_for_each_udev(pos, hpriv, i) \ 118034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto __usbhsh_for_each_udev(1, pos, hpriv, i) 119034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 120034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_for_each_udev_with_dev0(pos, hpriv, i) \ 121034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto __usbhsh_for_each_udev(0, pos, hpriv, i) 122034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 123034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_hcd_to_hpriv(h) (struct usbhsh_hpriv *)((h)->hcd_priv) 124034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_hcd_to_dev(h) ((h)->self.controller) 125034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 126034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_hpriv_to_priv(h) ((h)->mod.priv) 127034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_hpriv_to_dcp(h) ((h)->dcp) 128034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_hpriv_to_hcd(h) \ 129034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto container_of((void *)h, struct usb_hcd, hcd_priv) 130034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 131034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_ep_to_uep(u) ((u)->hcpriv) 132034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_uep_to_pipe(u) ((u)->pipe) 133034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_uep_to_udev(u) ((u)->udev) 134e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto#define usbhsh_uep_to_ep(u) ((u)->ep) 135e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 136034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_urb_to_ureq(u) ((u)->hcpriv) 137034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_urb_to_usbv(u) ((u)->dev) 138034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 139034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_usbv_to_udev(d) dev_get_drvdata(&(d)->dev) 140034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 141034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_udev_to_usbv(h) ((h)->usbv) 142ab14230854aba9d0c99b3cd0e4bb1ef430973d84Kuninori Morimoto#define usbhsh_udev_is_used(h) usbhsh_udev_to_usbv(h) 143034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 144e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto#define usbhsh_pipe_to_uep(p) ((p)->mod_private) 145034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1469c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto#define usbhsh_device_parent(d) (usbhsh_usbv_to_udev((d)->usbv->parent)) 1479c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto#define usbhsh_device_hubport(d) ((d)->usbv->portnum) 148034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_device_number(h, d) ((int)((d) - (h)->udev)) 149034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_device_nth(h, d) ((h)->udev + d) 150034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_device0(h) usbhsh_device_nth(h, 0) 151034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 152034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_port_stat_init(h) ((h)->port_stat = 0) 153034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_port_stat_set(h, s) ((h)->port_stat |= (s)) 154034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_port_stat_clear(h, s) ((h)->port_stat &= ~(s)) 155034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto#define usbhsh_port_stat_get(h) ((h)->port_stat) 156034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 15725234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimoto#define usbhsh_pkt_to_ureq(p) \ 158034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto container_of((void *)p, struct usbhsh_request, pkt) 159034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 160034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 161034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * req alloc/free 162034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 16325234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimotostatic struct usbhsh_request *usbhsh_ureq_alloc(struct usbhsh_hpriv *hpriv, 164034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct urb *urb, 165034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto gfp_t mem_flags) 166034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 167034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_request *ureq; 168034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 169034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 170034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 171c5b963f809f378d4fedd6f2f09b36f50c5a37bd5Kuninori Morimoto ureq = kzalloc(sizeof(struct usbhsh_request), mem_flags); 172034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (!ureq) { 173034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_err(dev, "ureq alloc fail\n"); 174034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return NULL; 175034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 176034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 177034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_pkt_init(&ureq->pkt); 178034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto ureq->urb = urb; 179fc9d5c79f681a7bff588d32de9429be360996df7Kuninori Morimoto usbhsh_urb_to_ureq(urb) = ureq; 180034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 181034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return ureq; 182034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 183034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 18425234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimotostatic void usbhsh_ureq_free(struct usbhsh_hpriv *hpriv, 185034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_request *ureq) 186034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 187fc9d5c79f681a7bff588d32de9429be360996df7Kuninori Morimoto usbhsh_urb_to_ureq(ureq->urb) = NULL; 188034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto ureq->urb = NULL; 189034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 190c5b963f809f378d4fedd6f2f09b36f50c5a37bd5Kuninori Morimoto kfree(ureq); 191034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 192034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 193034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 194b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * status 195b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto */ 196b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimotostatic int usbhsh_is_running(struct usbhsh_hpriv *hpriv) 197b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto{ 198034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 199b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * we can decide some device is attached or not 200b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * by checking mod.irq_attch 201b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * see 202b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * usbhsh_irq_attch() 203b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * usbhsh_irq_dtch() 204034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 205b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto return (hpriv->mod.irq_attch == NULL); 206034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 207034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 208034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 209e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * pipe control 210034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 2113edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimotostatic void usbhsh_endpoint_sequence_save(struct usbhsh_hpriv *hpriv, 2123edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto struct urb *urb, 2133edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto struct usbhs_pkt *pkt) 214034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 2153edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto int len = urb->actual_length; 2163edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto int maxp = usb_endpoint_maxp(&urb->ep->desc); 2173edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto int t = 0; 218034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 2193edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto /* DCP is out of sequence control */ 2203edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto if (usb_pipecontrol(urb->pipe)) 2213edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto return; 222034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 223034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 2243edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * renesas_usbhs pipe has a limitation in a number. 2253edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * So, driver should re-use the limited pipe for each device/endpoint. 2263edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * DATA0/1 sequence should be saved for it. 2273edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * see [image of mod_host] 2283edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * [HARDWARE LIMITATION] 229034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 230034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 231034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 2323edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * next sequence depends on actual_length 2333edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * 2343edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * ex) actual_length = 1147, maxp = 512 2353edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * data0 : 512 2363edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * data1 : 512 2373edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * data0 : 123 2383edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto * data1 is the next sequence 239034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 2403edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto t = len / maxp; 2413edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto if (len % maxp) 2423edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto t++; 2433edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto if (pkt->zero) 2443edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto t++; 2453edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto t %= 2; 2463edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto 2473edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto if (t) 2483edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto usb_dotoggle(urb->dev, 2493edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto usb_pipeendpoint(urb->pipe), 2503edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto usb_pipeout(urb->pipe)); 2513edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto} 2523edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto 253e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimotostatic struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, 254e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct urb *urb); 255e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto 256e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimotostatic int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, 257e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct urb *urb) 258e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto{ 259e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 260e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); 261e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); 262e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usbhs_pipe *pipe; 263e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usb_endpoint_descriptor *desc = &urb->ep->desc; 264e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 265e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto unsigned long flags; 266e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto int dir_in_req = !!usb_pipein(urb->pipe); 267e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto int is_dcp = usb_endpoint_xfer_control(desc); 268e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto int i, dir_in; 269e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto int ret = -EBUSY; 270e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 271e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto /******************** spin lock ********************/ 272e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhs_lock(priv, flags); 273e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 274e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto if (unlikely(usbhsh_uep_to_pipe(uep))) { 275e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto dev_err(dev, "uep already has pipe\n"); 276e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto goto usbhsh_pipe_attach_done; 277034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 278034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 279e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhs_for_each_pipe_with_dcp(pipe, priv, i) { 280034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 281e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto /* check pipe type */ 282e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc))) 283e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto continue; 284034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 285e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto /* check pipe direction if normal pipe */ 286e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto if (!is_dcp) { 287e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto dir_in = !!usbhs_pipe_is_dir_in(pipe); 288e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto if (0 != (dir_in - dir_in_req)) 289e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto continue; 290e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto } 291034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 292e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto /* check pipe is free */ 293e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto if (usbhsh_pipe_to_uep(pipe)) 294e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto continue; 295034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 296e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto /* 297e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * attach pipe to uep 298e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * 299e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * usbhs_pipe_config_update() should be called after 300e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * usbhs_set_device_config() 301e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * see 302e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * DCPMAXP/PIPEMAXP 303e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto */ 304e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhsh_uep_to_pipe(uep) = pipe; 305e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhsh_pipe_to_uep(pipe) = uep; 306034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 307e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhs_pipe_config_update(pipe, 308e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhsh_device_number(hpriv, udev), 309e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usb_endpoint_num(desc), 310e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usb_endpoint_maxp(desc)); 311034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 312e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto dev_dbg(dev, "%s [%d-%d(%s:%s)]\n", __func__, 313e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhsh_device_number(hpriv, udev), 314e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usb_endpoint_num(desc), 315e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhs_pipe_name(pipe), 316e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto dir_in_req ? "in" : "out"); 317034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 318e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto ret = 0; 319e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto break; 320e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto } 321e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 322e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimotousbhsh_pipe_attach_done: 323e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhs_unlock(priv, flags); 324e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto /******************** spin unlock ******************/ 325e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 326e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto return ret; 327034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 328034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 329e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimotostatic void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, 330e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usbhsh_ep *uep) 331034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 332e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 333e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usbhs_pipe *pipe; 334e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 335e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto unsigned long flags; 336034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 337e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto /******************** spin lock ********************/ 338e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhs_lock(priv, flags); 339034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 340e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto pipe = usbhsh_uep_to_pipe(uep); 341034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 342e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto if (unlikely(!pipe)) { 343e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto dev_err(dev, "uep doens't have pipe\n"); 344e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto } else { 345e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); 346e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); 347e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto 348e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto /* detach pipe from uep */ 349e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhsh_uep_to_pipe(uep) = NULL; 350e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhsh_pipe_to_uep(pipe) = NULL; 351e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto 352e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto dev_dbg(dev, "%s [%d-%d(%s)]\n", __func__, 353e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhsh_device_number(hpriv, udev), 354e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usb_endpoint_num(&ep->desc), 355e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhs_pipe_name(pipe)); 356e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto } 357e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 358e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhs_unlock(priv, flags); 359e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto /******************** spin unlock ******************/ 360034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 361034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 362034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 363e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * endpoint control 364034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 365e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimotostatic int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, 366e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct urb *urb, 367e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto gfp_t mem_flags) 368034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 369034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 370e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); 371e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct usb_host_endpoint *ep = urb->ep; 372034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_ep *uep; 373e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 374034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_endpoint_descriptor *desc = &ep->desc; 375e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto unsigned long flags; 37673ef635a07c0e6a0a159d8beabffb83399429188Kuninori Morimoto 377034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); 378034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (!uep) { 379034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_err(dev, "usbhsh_ep alloc fail\n"); 380e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto return -ENOMEM; 381034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 38273ef635a07c0e6a0a159d8beabffb83399429188Kuninori Morimoto 383e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto /******************** spin lock ********************/ 384e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhs_lock(priv, flags); 385e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto 386e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto /* 387e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * init endpoint 388e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto */ 389e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto INIT_LIST_HEAD(&uep->ep_list); 390e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto list_add_tail(&uep->ep_list, &udev->ep_list_head); 391e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto 392e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_uep_to_udev(uep) = udev; 393e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_uep_to_ep(uep) = ep; 394e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_ep_to_uep(ep) = uep; 395e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 396e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhs_unlock(priv, flags); 397e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto /******************** spin unlock ******************/ 398e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 399e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto dev_dbg(dev, "%s [%d-%d]\n", __func__, 400e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_device_number(hpriv, udev), 401e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usb_endpoint_num(desc)); 402e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 403e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto return 0; 404e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto} 405e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 406e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimotostatic void usbhsh_endpoint_detach(struct usbhsh_hpriv *hpriv, 407e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct usb_host_endpoint *ep) 408e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto{ 409e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 410e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 411e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); 412e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto unsigned long flags; 413e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 414e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto if (!uep) 415e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto return; 416e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 417e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto dev_dbg(dev, "%s [%d-%d]\n", __func__, 418e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), 419e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usb_endpoint_num(&ep->desc)); 420e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto 421e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto if (usbhsh_uep_to_pipe(uep)) 422e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhsh_pipe_detach(hpriv, uep); 423e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 424e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto /******************** spin lock ********************/ 425e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhs_lock(priv, flags); 426e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 427e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto /* remove this endpoint from udev */ 428e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto list_del_init(&uep->ep_list); 429e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 430e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_uep_to_udev(uep) = NULL; 431e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_uep_to_ep(uep) = NULL; 432e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_ep_to_uep(ep) = NULL; 433e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 434e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhs_unlock(priv, flags); 435e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto /******************** spin unlock ******************/ 436e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 437e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto kfree(uep); 438e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto} 439e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 440e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimotostatic void usbhsh_endpoint_detach_all(struct usbhsh_hpriv *hpriv, 441e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct usbhsh_device *udev) 442e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto{ 443e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto struct usbhsh_ep *uep, *next; 444e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 445e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto list_for_each_entry_safe(uep, next, &udev->ep_list_head, ep_list) 446e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_endpoint_detach(hpriv, usbhsh_uep_to_ep(uep)); 447e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto} 448e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto 449e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto/* 450034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * device control 451034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 4529c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimotostatic int usbhsh_connected_to_rhdev(struct usb_hcd *hcd, 4539c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto struct usbhsh_device *udev) 4549c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto{ 4559c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto struct usb_device *usbv = usbhsh_udev_to_usbv(udev); 4569c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto 4579c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto return hcd->self.root_hub == usbv->parent; 4589c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto} 459034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 460034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_device_has_endpoint(struct usbhsh_device *udev) 461034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 462034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return !list_empty(&udev->ep_list_head); 463034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 464034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 465c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimotostatic struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, 466c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto struct urb *urb) 467c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto{ 468c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto struct usb_device *usbv = usbhsh_urb_to_usbv(urb); 469c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv); 470c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto 471c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto /* usbhsh_device_attach() is still not called */ 472c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto if (!udev) 473c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto return NULL; 474c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto 475c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto /* if it is device0, return it */ 476c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto if (0 == usb_pipedevice(urb->pipe)) 477c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto return usbhsh_device0(hpriv); 478c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto 479c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto /* return attached device */ 480c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto return udev; 481c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto} 482c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto 4837aac8d1537b1fd1a9e39bd16edcd6728c19f8dd5Kuninori Morimotostatic struct usbhsh_device *usbhsh_device_attach(struct usbhsh_hpriv *hpriv, 484034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct urb *urb) 485034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 486034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_device *udev = NULL; 487c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto struct usbhsh_device *udev0 = usbhsh_device0(hpriv); 488c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto struct usbhsh_device *pos; 489034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 490034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 491034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_device *usbv = usbhsh_urb_to_usbv(urb); 492034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 493d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto unsigned long flags; 4949c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto u16 upphub, hubport; 495034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int i; 496034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 497c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto /* 498c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * This function should be called only while urb is pointing to device0. 499c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * It will attach unused usbhsh_device to urb (usbv), 500c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * and initialize device0. 501c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * You can use usbhsh_device_get() to get "current" udev, 502c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * and usbhsh_usbv_to_udev() is for "attached" udev. 503c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto */ 504c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto if (0 != usb_pipedevice(urb->pipe)) { 505c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto dev_err(dev, "%s fail: urb isn't pointing device0\n", __func__); 506c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto return NULL; 50773ef635a07c0e6a0a159d8beabffb83399429188Kuninori Morimoto } 508034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 509d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto /******************** spin lock ********************/ 510d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto usbhs_lock(priv, flags); 511d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto 512034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 513c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * find unused device 514034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 515c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto usbhsh_for_each_udev(pos, hpriv, i) { 516c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto if (usbhsh_udev_is_used(pos)) 517034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto continue; 518c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto udev = pos; 519c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto break; 520034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 521034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 522d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto if (udev) { 523d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto /* 524d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto * usbhsh_usbv_to_udev() 525d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto * usbhsh_udev_to_usbv() 526d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto * will be enable 527d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto */ 528d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto dev_set_drvdata(&usbv->dev, udev); 529d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto udev->usbv = usbv; 530d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto } 53173ef635a07c0e6a0a159d8beabffb83399429188Kuninori Morimoto 532d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto usbhs_unlock(priv, flags); 533d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto /******************** spin unlock ******************/ 534034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 535ab14230854aba9d0c99b3cd0e4bb1ef430973d84Kuninori Morimoto if (!udev) { 536ab14230854aba9d0c99b3cd0e4bb1ef430973d84Kuninori Morimoto dev_err(dev, "no free usbhsh_device\n"); 537ab14230854aba9d0c99b3cd0e4bb1ef430973d84Kuninori Morimoto return NULL; 538034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 539034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 540e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto if (usbhsh_device_has_endpoint(udev)) { 541034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_warn(dev, "udev have old endpoint\n"); 542e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_endpoint_detach_all(hpriv, udev); 543e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto } 544034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 545e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto if (usbhsh_device_has_endpoint(udev0)) { 546c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto dev_warn(dev, "udev0 have old endpoint\n"); 547e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_endpoint_detach_all(hpriv, udev0); 548034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 549c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto 550034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* uep will be attached */ 551c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto INIT_LIST_HEAD(&udev0->ep_list_head); 552034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto INIT_LIST_HEAD(&udev->ep_list_head); 553034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 554034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 555c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * set device0 config 556034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 557c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto usbhs_set_device_config(priv, 558c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto 0, 0, 0, usbv->speed); 559034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 560034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 561c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * set new device config 562034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 5639c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto upphub = 0; 5649c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto hubport = 0; 5659c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto if (!usbhsh_connected_to_rhdev(hcd, udev)) { 5669c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto /* if udev is not connected to rhdev, it means parent is Hub */ 5679c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto struct usbhsh_device *parent = usbhsh_device_parent(udev); 568034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 5699c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto upphub = usbhsh_device_number(hpriv, parent); 5709c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto hubport = usbhsh_device_hubport(udev); 571034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 5729c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto dev_dbg(dev, "%s connecte to Hub [%d:%d](%p)\n", __func__, 5739c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto upphub, hubport, parent); 5749c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto } 575034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 5763dd492686c063f9fa9417c3888e7a8eeb504b5b9Kuninori Morimoto usbhs_set_device_config(priv, 577034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_device_number(hpriv, udev), 5789c6736523a23371ae58c5427587ee1652ba059c1Kuninori Morimoto upphub, hubport, usbv->speed); 579034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 580034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s [%d](%p)\n", __func__, 581034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_device_number(hpriv, udev), udev); 582034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 583034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return udev; 584034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 585034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 5867aac8d1537b1fd1a9e39bd16edcd6728c19f8dd5Kuninori Morimotostatic void usbhsh_device_detach(struct usbhsh_hpriv *hpriv, 587034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_device *udev) 588034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 589034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 590034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 591034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 592034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_device *usbv = usbhsh_udev_to_usbv(udev); 593d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto unsigned long flags; 594034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 595034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s [%d](%p)\n", __func__, 596034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_device_number(hpriv, udev), udev); 597034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 598e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto if (usbhsh_device_has_endpoint(udev)) { 599034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_warn(dev, "udev still have endpoint\n"); 600e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto usbhsh_endpoint_detach_all(hpriv, udev); 601e4c57ded48d9bad95a4d7254e75a81f7abcffef9Kuninori Morimoto } 602034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 603c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto /* 604c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * There is nothing to do if it is device0. 605c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * see 606c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * usbhsh_device_attach() 607c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * usbhsh_device_get() 608c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto */ 609c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto if (0 == usbhsh_device_number(hpriv, udev)) 610c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto return; 611034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 612d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto /******************** spin lock ********************/ 613d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto usbhs_lock(priv, flags); 614034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 615034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 616034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * usbhsh_usbv_to_udev() 617034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * usbhsh_udev_to_usbv() 618034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * will be disable 619034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 620034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_set_drvdata(&usbv->dev, NULL); 621034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto udev->usbv = NULL; 622034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 623d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto usbhs_unlock(priv, flags); 624d399f90d192f4cbda2527d42d054d090e327a9a0Kuninori Morimoto /******************** spin unlock ******************/ 625034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 626034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 627034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 628034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * queue push/pop 629034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 630034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) 631034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 63225234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimoto struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); 633034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 634034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 635034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct urb *urb = ureq->urb; 636034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 6376d0376f84446507d07ae83935cbe7538d07c352fKuninori Morimoto int status = 0; 638034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 639034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s\n", __func__); 640034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 641034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (!urb) { 642034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_warn(dev, "pkt doesn't have urb\n"); 643034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return; 644034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 645034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 6466d0376f84446507d07ae83935cbe7538d07c352fKuninori Morimoto if (!usbhsh_is_running(hpriv)) 6476d0376f84446507d07ae83935cbe7538d07c352fKuninori Morimoto status = -ESHUTDOWN; 6486d0376f84446507d07ae83935cbe7538d07c352fKuninori Morimoto 649034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto urb->actual_length = pkt->actual; 65025234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimoto usbhsh_ureq_free(hpriv, ureq); 651034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 6523edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto usbhsh_endpoint_sequence_save(hpriv, urb, pkt); 653d9b78f33d9c1b699b66f10ad2329487f813c4642Kuninori Morimoto usbhsh_pipe_detach(hpriv, usbhsh_ep_to_uep(urb->ep)); 654034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 655034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usb_hcd_unlink_urb_from_ep(hcd, urb); 6566d0376f84446507d07ae83935cbe7538d07c352fKuninori Morimoto usb_hcd_giveback_urb(hcd, urb, status); 657034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 658034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 659034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_queue_push(struct usb_hcd *hcd, 660ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto struct urb *urb, 661ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto gfp_t mem_flags) 662034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 663ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 6643eddc9e4c828dbbeabb5924266bfded42a1ac042Kuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); 6653eddc9e4c828dbbeabb5924266bfded42a1ac042Kuninori Morimoto struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep); 666034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 667ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto struct usbhsh_request *ureq; 668034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto void *buf; 6693edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto int len, sequence; 670034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 671034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (usb_pipeisoc(urb->pipe)) { 672034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_err(dev, "pipe iso is not supported now\n"); 673034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return -EIO; 674034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 675034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 676ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto /* this ureq will be freed on usbhsh_queue_done() */ 677ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); 678ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto if (unlikely(!ureq)) { 679ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto dev_err(dev, "ureq alloc fail\n"); 680ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto return -ENOMEM; 681ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto } 682ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto 683034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (usb_pipein(urb->pipe)) 684034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto pipe->handler = &usbhs_fifo_pio_pop_handler; 685034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto else 686034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto pipe->handler = &usbhs_fifo_pio_push_handler; 687034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 688034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto buf = (void *)(urb->transfer_buffer + urb->actual_length); 689034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto len = urb->transfer_buffer_length - urb->actual_length; 690034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 6913edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto sequence = usb_gettoggle(urb->dev, 6923edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto usb_pipeendpoint(urb->pipe), 6933edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto usb_pipeout(urb->pipe)); 6943edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto 695034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s\n", __func__); 696ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto usbhs_pkt_push(pipe, &ureq->pkt, usbhsh_queue_done, 6973edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto buf, len, (urb->transfer_flags & URB_ZERO_PACKET), 6983edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto sequence); 6993edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto 700034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_pkt_start(pipe); 701034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 702034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 703034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 704034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 7052d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimotostatic void usbhsh_queue_force_pop(struct usbhs_priv *priv, 7062d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto struct usbhs_pipe *pipe) 7072d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto{ 7082d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto struct usbhs_pkt *pkt; 7092d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto 7102d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto while (1) { 7112d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto pkt = usbhs_pkt_pop(pipe, NULL); 7122d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto if (!pkt) 7132d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto break; 7142d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto 7152d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto /* 7162d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto * if all packet are gone, usbhsh_endpoint_disable() 7172d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto * will be called. 7182d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto * then, attached device/endpoint/pipe will be detached 7192d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto */ 7202d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto usbhsh_queue_done(priv, pkt); 7212d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto } 7222d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto} 7232d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto 7242d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimotostatic void usbhsh_queue_force_pop_all(struct usbhs_priv *priv) 7252d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto{ 7262d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto struct usbhs_pipe *pos; 7272d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto int i; 7282d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto 7292d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto usbhs_for_each_pipe_with_dcp(pos, priv, i) 7302d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto usbhsh_queue_force_pop(priv, pos); 7312d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto} 7322d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto 733034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 734034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * DCP setup stage 735034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 736034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_is_request_address(struct urb *urb) 737034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 73825234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimoto struct usb_ctrlrequest *req; 739034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 74025234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimoto req = (struct usb_ctrlrequest *)urb->setup_packet; 741034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 74225234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimoto if ((DeviceOutRequest == req->bRequestType << 8) && 74325234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimoto (USB_REQ_SET_ADDRESS == req->bRequest)) 744034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 1; 745034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto else 746034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 747034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 748034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 749034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, 750034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct urb *urb, 751034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_pipe *pipe) 752034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 753034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 754034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_ctrlrequest req; 755034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 756034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 757034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 758034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * wait setup packet ACK 759034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * see 760034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * usbhsh_irq_setup_ack() 761034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * usbhsh_irq_setup_err() 762034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 7637fccd480b7fe84a98ee252fa79dd92f7fff5ec2aKuninori Morimoto init_completion(&hpriv->setup_ack_done); 764034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 765034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* copy original request */ 766034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto memcpy(&req, urb->setup_packet, sizeof(struct usb_ctrlrequest)); 767034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 768034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 769034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * renesas_usbhs can not use original usb address. 770034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * see HARDWARE LIMITATION. 771c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * modify usb address here to use attached device. 772c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto * see usbhsh_device_attach() 773034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 774034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (usbhsh_is_request_address(urb)) { 775c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto struct usb_device *usbv = usbhsh_urb_to_usbv(urb); 776c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv); 777c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto 778c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto /* udev is a attached device */ 779c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto req.wValue = usbhsh_device_number(hpriv, udev); 780034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "create new address - %d\n", req.wValue); 781034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 782034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 783034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* set request */ 784034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_usbreq_set_val(priv, &req); 785034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 786034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 787034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * wait setup packet ACK 788034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 7897fccd480b7fe84a98ee252fa79dd92f7fff5ec2aKuninori Morimoto wait_for_completion(&hpriv->setup_ack_done); 790034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 791034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s done\n", __func__); 792034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 793034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 794034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 795034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * DCP data stage 796034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 797034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic void usbhsh_data_stage_packet_done(struct usbhs_priv *priv, 798034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_pkt *pkt) 799034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 80025234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimoto struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); 801034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 802034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 803034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* this ureq was connected to urb when usbhsh_urb_enqueue() */ 804034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 80525234b46be2a1688d38fb55ed9d7e3f2cc41c9afKuninori Morimoto usbhsh_ureq_free(hpriv, ureq); 806034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 807034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 808ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimotostatic int usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv, 809ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto struct urb *urb, 810ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto struct usbhs_pipe *pipe, 811ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto gfp_t mem_flags) 812ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto 813034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 814034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_request *ureq; 815034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 816ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto /* this ureq will be freed on usbhsh_data_stage_packet_done() */ 817ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); 818ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto if (unlikely(!ureq)) 819ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto return -ENOMEM; 820034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 821034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (usb_pipein(urb->pipe)) 822034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto pipe->handler = &usbhs_dcp_data_stage_in_handler; 823034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto else 824034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto pipe->handler = &usbhs_dcp_data_stage_out_handler; 825034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 826ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto usbhs_pkt_push(pipe, &ureq->pkt, 827034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_data_stage_packet_done, 828034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto urb->transfer_buffer, 829034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto urb->transfer_buffer_length, 8303edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto (urb->transfer_flags & URB_ZERO_PACKET), 8313edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto -1); 832ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto 833ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto return 0; 834034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 835034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 836034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 837034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * DCP status stage 838034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 839ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimotostatic int usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv, 840034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct urb *urb, 841ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto struct usbhs_pipe *pipe, 842ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto gfp_t mem_flags) 843034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 844034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_request *ureq; 845034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 846ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto /* This ureq will be freed on usbhsh_queue_done() */ 847ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); 848ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto if (unlikely(!ureq)) 849ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto return -ENOMEM; 850034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 851034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (usb_pipein(urb->pipe)) 852034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto pipe->handler = &usbhs_dcp_status_stage_in_handler; 853034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto else 854034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto pipe->handler = &usbhs_dcp_status_stage_out_handler; 855034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 856ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto usbhs_pkt_push(pipe, &ureq->pkt, 857034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_queue_done, 858034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto NULL, 859034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto urb->transfer_buffer_length, 8603edeee3893b107364fe4ed8535245773b1e1e72bKuninori Morimoto 0, -1); 861ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto 862ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto return 0; 863034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 864034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 865034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_dcp_queue_push(struct usb_hcd *hcd, 866ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto struct urb *urb, 867ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto gfp_t mflags) 868034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 869ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 8703eddc9e4c828dbbeabb5924266bfded42a1ac042Kuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); 8713eddc9e4c828dbbeabb5924266bfded42a1ac042Kuninori Morimoto struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep); 872034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhsh_hcd_to_dev(hcd); 873ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto int ret; 874034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 875034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s\n", __func__); 876034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 877034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 878034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * setup stage 879034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 880034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * usbhsh_send_setup_stage_packet() wait SACK/SIGN 881034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 882034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_setup_stage_packet_push(hpriv, urb, pipe); 883034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 884034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 885034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * data stage 886034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 887034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * It is pushed only when urb has buffer. 888034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 889ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto if (urb->transfer_buffer_length) { 890ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto ret = usbhsh_data_stage_packet_push(hpriv, urb, pipe, mflags); 891ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto if (ret < 0) { 892ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto dev_err(dev, "data stage failed\n"); 893ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto return ret; 894ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto } 895ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto } 896034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 897034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 898034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * status stage 899034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 900ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto ret = usbhsh_status_stage_packet_push(hpriv, urb, pipe, mflags); 901ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto if (ret < 0) { 902ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto dev_err(dev, "status stage failed\n"); 903ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto return ret; 904ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto } 905034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 906034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 907034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * start pushed packets 908034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 909034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_pkt_start(pipe); 910034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 911034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 912034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 913034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 914034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 915034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * dma map functions 916034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 917034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map) 918034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 919034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 920034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 921034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 922034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 923034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * for hc_driver 924034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 925034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_host_start(struct usb_hcd *hcd) 926034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 927034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 928034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 929034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 930034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic void usbhsh_host_stop(struct usb_hcd *hcd) 931034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 932034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 933034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 934034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_urb_enqueue(struct usb_hcd *hcd, 935034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct urb *urb, 936034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto gfp_t mem_flags) 937034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 938034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 939034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 940034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 941034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_host_endpoint *ep = urb->ep; 9427aac8d1537b1fd1a9e39bd16edcd6728c19f8dd5Kuninori Morimoto struct usbhsh_device *new_udev = NULL; 94373ef635a07c0e6a0a159d8beabffb83399429188Kuninori Morimoto int is_dir_in = usb_pipein(urb->pipe); 944e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto int i; 945034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int ret; 946034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 94773ef635a07c0e6a0a159d8beabffb83399429188Kuninori Morimoto dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); 948034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 949b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto if (!usbhsh_is_running(hpriv)) { 950b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto ret = -EIO; 95115a3838b101b292c2e40824d843a4d8871ac4010Kuninori Morimoto dev_err(dev, "host is not running\n"); 952b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto goto usbhsh_urb_enqueue_error_not_linked; 953b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto } 954b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto 955034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto ret = usb_hcd_link_urb_to_ep(hcd, urb); 95615a3838b101b292c2e40824d843a4d8871ac4010Kuninori Morimoto if (ret) { 95715a3838b101b292c2e40824d843a4d8871ac4010Kuninori Morimoto dev_err(dev, "urb link failed\n"); 958034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto goto usbhsh_urb_enqueue_error_not_linked; 95915a3838b101b292c2e40824d843a4d8871ac4010Kuninori Morimoto } 960034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 961034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 9627aac8d1537b1fd1a9e39bd16edcd6728c19f8dd5Kuninori Morimoto * attach udev if needed 963e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * see [image of mod_host] 964034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 965c1e4877a4106a31319c4ad65b625c11393df98d6Kuninori Morimoto if (!usbhsh_device_get(hpriv, urb)) { 9667aac8d1537b1fd1a9e39bd16edcd6728c19f8dd5Kuninori Morimoto new_udev = usbhsh_device_attach(hpriv, urb); 96737332ee0dfb017aea566047be945d6fd3531c713Kuninori Morimoto if (!new_udev) { 96837332ee0dfb017aea566047be945d6fd3531c713Kuninori Morimoto ret = -EIO; 96915a3838b101b292c2e40824d843a4d8871ac4010Kuninori Morimoto dev_err(dev, "device attach failed\n"); 970034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto goto usbhsh_urb_enqueue_error_not_linked; 97137332ee0dfb017aea566047be945d6fd3531c713Kuninori Morimoto } 972034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 973034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 974034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 9754825093e9d0692a2a1f1615ab69246ac07b17f2fKuninori Morimoto * attach endpoint if needed 976e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * see [image of mod_host] 977034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 9784825093e9d0692a2a1f1615ab69246ac07b17f2fKuninori Morimoto if (!usbhsh_ep_to_uep(ep)) { 9794825093e9d0692a2a1f1615ab69246ac07b17f2fKuninori Morimoto ret = usbhsh_endpoint_attach(hpriv, urb, mem_flags); 98015a3838b101b292c2e40824d843a4d8871ac4010Kuninori Morimoto if (ret < 0) { 98115a3838b101b292c2e40824d843a4d8871ac4010Kuninori Morimoto dev_err(dev, "endpoint attach failed\n"); 982034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto goto usbhsh_urb_enqueue_error_free_device; 98315a3838b101b292c2e40824d843a4d8871ac4010Kuninori Morimoto } 984034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 985034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 986034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 987e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * attach pipe to endpoint 988e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto * see [image of mod_host] 989034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 990e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto for (i = 0; i < 1024; i++) { 991e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto ret = usbhsh_pipe_attach(hpriv, urb); 992e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto if (ret < 0) 993e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto msleep(100); 994e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto else 995e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto break; 996e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto } 99715a3838b101b292c2e40824d843a4d8871ac4010Kuninori Morimoto if (ret < 0) { 99815a3838b101b292c2e40824d843a4d8871ac4010Kuninori Morimoto dev_err(dev, "pipe attach failed\n"); 999034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto goto usbhsh_urb_enqueue_error_free_endpoint; 1000034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1001034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1002034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1003034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * push packet 1004034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1005034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (usb_pipecontrol(urb->pipe)) 10063eddc9e4c828dbbeabb5924266bfded42a1ac042Kuninori Morimoto ret = usbhsh_dcp_queue_push(hcd, urb, mem_flags); 1007034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto else 10083eddc9e4c828dbbeabb5924266bfded42a1ac042Kuninori Morimoto ret = usbhsh_queue_push(hcd, urb, mem_flags); 1009034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1010ee8a0bf5a775098b1140195b6bfacb4813166e5fKuninori Morimoto return ret; 1011034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1012034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotousbhsh_urb_enqueue_error_free_endpoint: 1013e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto usbhsh_endpoint_detach(hpriv, ep); 1014034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotousbhsh_urb_enqueue_error_free_device: 1015034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (new_udev) 10167aac8d1537b1fd1a9e39bd16edcd6728c19f8dd5Kuninori Morimoto usbhsh_device_detach(hpriv, new_udev); 1017034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotousbhsh_urb_enqueue_error_not_linked: 1018034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1019034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s error\n", __func__); 1020034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1021034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return ret; 1022034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1023034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1024034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) 1025034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1026034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 1027034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); 1028034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1029034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (ureq) { 1030547965436d8dc8747b1931af954a178d30e86f6cKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1031547965436d8dc8747b1931af954a178d30e86f6cKuninori Morimoto struct usbhs_pkt *pkt = &ureq->pkt; 1032547965436d8dc8747b1931af954a178d30e86f6cKuninori Morimoto 1033547965436d8dc8747b1931af954a178d30e86f6cKuninori Morimoto usbhs_pkt_pop(pkt->pipe, pkt); 1034547965436d8dc8747b1931af954a178d30e86f6cKuninori Morimoto usbhsh_queue_done(priv, pkt); 1035034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1036034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1037034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1038034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1039034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1040034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic void usbhsh_endpoint_disable(struct usb_hcd *hcd, 1041034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_host_endpoint *ep) 1042034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1043034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); 1044034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_device *udev; 1045034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv; 1046034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1047034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1048034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * this function might be called manytimes by same hcd/ep 1049fca8ab7ee1c6d1857a4fcc9420cbf0e3b51aa199Kuninori Morimoto * in-endpoint == out-endpoint if ep == dcp. 1050034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1051034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (!uep) 1052034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return; 1053034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1054034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto udev = usbhsh_uep_to_udev(uep); 1055034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto hpriv = usbhsh_hcd_to_hpriv(hcd); 1056034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 10574825093e9d0692a2a1f1615ab69246ac07b17f2fKuninori Morimoto usbhsh_endpoint_detach(hpriv, ep); 1058034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1059034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1060034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * if there is no endpoint, 1061034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * free device 1062034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1063034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (!usbhsh_device_has_endpoint(udev)) 10647aac8d1537b1fd1a9e39bd16edcd6728c19f8dd5Kuninori Morimoto usbhsh_device_detach(hpriv, udev); 1065034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1066034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1067034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) 1068034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1069034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 1070034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1071034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1072034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int roothub_id = 1; /* only 1 root hub */ 1073034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1074034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1075034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * does port stat was changed ? 1076034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * check USB_PORT_STAT_C_xxx << 16 1077034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1078034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (usbhsh_port_stat_get(hpriv) & 0xFFFF0000) 1079034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto *buf = (1 << roothub_id); 1080034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto else 1081034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto *buf = 0; 1082034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1083034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s (%02x)\n", __func__, *buf); 1084034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1085034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return !!(*buf); 1086034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1087034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1088034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int __usbhsh_hub_hub_feature(struct usbhsh_hpriv *hpriv, 1089034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto u16 typeReq, u16 wValue, 1090034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1091034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1092034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1093034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1094034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1095034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto switch (wValue) { 1096034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case C_HUB_OVER_CURRENT: 1097034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case C_HUB_LOCAL_POWER: 1098034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s :: C_HUB_xx\n", __func__); 1099034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1100034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1101034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1102034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return -EPIPE; 1103034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1104034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1105034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int __usbhsh_hub_port_feature(struct usbhsh_hpriv *hpriv, 1106034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto u16 typeReq, u16 wValue, 1107034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1108034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1109034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1110034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1111034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int enable = (typeReq == SetPortFeature); 1112034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int speed, i, timeout = 128; 1113034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int roothub_id = 1; /* only 1 root hub */ 1114034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1115034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* common error */ 1116034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (wIndex > roothub_id || wLength != 0) 1117034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return -EPIPE; 1118034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1119034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* check wValue */ 1120034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto switch (wValue) { 1121034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_PORT_FEAT_POWER: 1122034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_vbus_ctrl(priv, enable); 1123034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s :: USB_PORT_FEAT_POWER\n", __func__); 1124034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto break; 1125034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1126034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_PORT_FEAT_ENABLE: 1127034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_PORT_FEAT_SUSPEND: 1128034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_PORT_FEAT_C_ENABLE: 1129034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_PORT_FEAT_C_SUSPEND: 1130034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_PORT_FEAT_C_CONNECTION: 1131034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_PORT_FEAT_C_OVER_CURRENT: 1132034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_PORT_FEAT_C_RESET: 1133034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s :: USB_PORT_FEAT_xxx\n", __func__); 1134034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto break; 1135034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1136034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_PORT_FEAT_RESET: 1137034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (!enable) 1138034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto break; 1139034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1140034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_port_stat_clear(hpriv, 1141034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto USB_PORT_STAT_HIGH_SPEED | 1142034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto USB_PORT_STAT_LOW_SPEED); 1143034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 11442d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto usbhsh_queue_force_pop_all(priv); 11452d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto 1146034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_bus_send_reset(priv); 1147034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto msleep(20); 1148034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_bus_send_sof_enable(priv); 1149034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1150034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto for (i = 0; i < timeout ; i++) { 1151034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto switch (usbhs_bus_get_speed(priv)) { 1152034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_SPEED_LOW: 1153034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto speed = USB_PORT_STAT_LOW_SPEED; 1154034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto goto got_usb_bus_speed; 1155034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_SPEED_HIGH: 1156034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto speed = USB_PORT_STAT_HIGH_SPEED; 1157034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto goto got_usb_bus_speed; 1158034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case USB_SPEED_FULL: 1159034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto speed = 0; 1160034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto goto got_usb_bus_speed; 1161034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1162034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1163034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto msleep(20); 1164034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1165034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return -EPIPE; 1166034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1167034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotogot_usb_bus_speed: 1168034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_port_stat_set(hpriv, speed); 1169034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_ENABLE); 1170034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1171034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s :: USB_PORT_FEAT_RESET (speed = %d)\n", 1172034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto __func__, speed); 1173034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1174034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* status change is not needed */ 1175034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1176034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1177034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto default: 1178034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return -EPIPE; 1179034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1180034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1181034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* set/clear status */ 1182034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (enable) 1183034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_port_stat_set(hpriv, (1 << wValue)); 1184034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto else 1185034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_port_stat_clear(hpriv, (1 << wValue)); 1186034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1187034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1188034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1189034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1190034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int __usbhsh_hub_get_status(struct usbhsh_hpriv *hpriv, 1191034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto u16 typeReq, u16 wValue, 1192034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1193034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1194034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1195034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_hub_descriptor *desc = (struct usb_hub_descriptor *)buf; 1196034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1197034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int roothub_id = 1; /* only 1 root hub */ 1198034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1199034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto switch (typeReq) { 1200034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case GetHubStatus: 1201034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s :: GetHubStatus\n", __func__); 1202034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1203034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto *buf = 0x00; 1204034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto break; 1205034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1206034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case GetPortStatus: 1207034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (wIndex != roothub_id) 1208034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return -EPIPE; 1209034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1210034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s :: GetPortStatus\n", __func__); 1211034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto *(__le32 *)buf = cpu_to_le32(usbhsh_port_stat_get(hpriv)); 1212034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto break; 1213034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1214034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case GetHubDescriptor: 1215034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto desc->bDescriptorType = 0x29; 1216034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto desc->bHubContrCurrent = 0; 1217034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto desc->bNbrPorts = roothub_id; 1218034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto desc->bDescLength = 9; 1219034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto desc->bPwrOn2PwrGood = 0; 1220034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto desc->wHubCharacteristics = cpu_to_le16(0x0011); 1221034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto desc->u.hs.DeviceRemovable[0] = (roothub_id << 1); 1222034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto desc->u.hs.DeviceRemovable[1] = ~0; 1223034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "%s :: GetHubDescriptor\n", __func__); 1224034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto break; 1225034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1226034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1227034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1228034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1229034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1230034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, 1231034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto u16 wIndex, char *buf, u16 wLength) 1232034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1233034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 1234034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); 1235034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1236034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int ret = -EPIPE; 1237034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1238034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto switch (typeReq) { 1239034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1240034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* Hub Feature */ 1241034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case ClearHubFeature: 1242034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case SetHubFeature: 1243034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto ret = __usbhsh_hub_hub_feature(hpriv, typeReq, 1244034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto wValue, wIndex, buf, wLength); 1245034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto break; 1246034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1247034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* Port Feature */ 1248034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case SetPortFeature: 1249034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case ClearPortFeature: 1250034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto ret = __usbhsh_hub_port_feature(hpriv, typeReq, 1251034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto wValue, wIndex, buf, wLength); 1252034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto break; 1253034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1254034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* Get status */ 1255034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case GetHubStatus: 1256034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case GetPortStatus: 1257034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto case GetHubDescriptor: 1258034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto ret = __usbhsh_hub_get_status(hpriv, typeReq, 1259034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto wValue, wIndex, buf, wLength); 1260034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto break; 1261034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1262034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1263034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "typeReq = %x, ret = %d, port_stat = %x\n", 1264034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto typeReq, ret, usbhsh_port_stat_get(hpriv)); 1265034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1266034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return ret; 1267034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1268034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1269034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic struct hc_driver usbhsh_driver = { 1270034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto .description = usbhsh_hcd_name, 1271034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto .hcd_priv_size = sizeof(struct usbhsh_hpriv), 1272034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1273034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1274034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * generic hardware linkage 1275034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1276034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto .flags = HCD_USB2, 1277034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1278034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto .start = usbhsh_host_start, 1279034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto .stop = usbhsh_host_stop, 1280034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1281034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1282034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * managing i/o requests and associated device resources 1283034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1284034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto .urb_enqueue = usbhsh_urb_enqueue, 1285034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto .urb_dequeue = usbhsh_urb_dequeue, 1286034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto .endpoint_disable = usbhsh_endpoint_disable, 1287034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1288034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1289034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * root hub 1290034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1291034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto .hub_status_data = usbhsh_hub_status_data, 1292034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto .hub_control = usbhsh_hub_control, 1293034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto}; 1294034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1295034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 1296034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * interrupt functions 1297034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1298034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_irq_attch(struct usbhs_priv *priv, 1299034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_irq_state *irq_state) 1300034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1301034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1302034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1303034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1304034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "device attached\n"); 1305034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1306034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_CONNECTION); 1307034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); 1308034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 130931e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto /* 131031e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto * attch interrupt might happen infinitely on some device 131131e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto * (on self power USB hub ?) 131231e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto * disable it here. 1313b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * 1314b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * usbhsh_is_running() becomes effective 1315b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * according to this process. 1316b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * see 1317b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * usbhsh_is_running() 1318b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * usbhsh_urb_enqueue() 131931e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto */ 132031e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto hpriv->mod.irq_attch = NULL; 132131e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto usbhs_irq_callback_update(priv, &hpriv->mod); 132231e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto 1323034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1324034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1325034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1326034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_irq_dtch(struct usbhs_priv *priv, 1327034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_irq_state *irq_state) 1328034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1329034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1330034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1331034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1332034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "device detached\n"); 1333034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1334034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_port_stat_clear(hpriv, USB_PORT_STAT_CONNECTION); 1335034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); 1336034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 133731e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto /* 133831e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto * enable attch interrupt again 1339b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * 1340b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * usbhsh_is_running() becomes invalid 1341b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * according to this process. 1342b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * see 1343b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * usbhsh_is_running() 1344b1930da08872f6e17b8cdca60ee9c7321a8b5b8cKuninori Morimoto * usbhsh_urb_enqueue() 134531e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto */ 134631e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto hpriv->mod.irq_attch = usbhsh_irq_attch; 134731e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto usbhs_irq_callback_update(priv, &hpriv->mod); 134831e00fd116cab296da2d12bc0b82a30a9fbdd681Kuninori Morimoto 13492d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto /* 13502d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto * usbhsh_queue_force_pop_all() should be called 13512d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto * after usbhsh_is_running() becomes invalid. 13522d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto */ 13532d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto usbhsh_queue_force_pop_all(priv); 13542d833faad260ad074fb1ed0a378f4ccd1b8025b8Kuninori Morimoto 1355034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1356034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1357034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1358034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_irq_setup_ack(struct usbhs_priv *priv, 1359034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_irq_state *irq_state) 1360034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1361034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1362034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1363034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1364034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "setup packet OK\n"); 1365034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 13667fccd480b7fe84a98ee252fa79dd92f7fff5ec2aKuninori Morimoto complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */ 1367034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1368034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1369034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1370034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1371034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_irq_setup_err(struct usbhs_priv *priv, 1372034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_irq_state *irq_state) 1373034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1374034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1375034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1376034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1377034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "setup packet Err\n"); 1378034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 13797fccd480b7fe84a98ee252fa79dd92f7fff5ec2aKuninori Morimoto complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */ 1380034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1381034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1382034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1383034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1384034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto/* 1385034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * module start/stop 1386034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1387034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) 1388034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1389034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1390034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_pipe *pipe; 1391034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); 1392034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int pipe_size = usbhs_get_dparam(priv, pipe_size); 1393034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int old_type, dir_in, i; 1394034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1395034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* init all pipe */ 1396034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto old_type = USB_ENDPOINT_XFER_CONTROL; 1397034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto for (i = 0; i < pipe_size; i++) { 1398034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1399034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1400034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * data "output" will be finished as soon as possible, 1401034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * but there is no guaranty at data "input" case. 1402034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 1403034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * "input" needs "standby" pipe. 1404034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * So, "input" direction pipe > "output" direction pipe 1405034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * is good idea. 1406034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 1407034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 1st USB_ENDPOINT_XFER_xxx will be output direction, 1408034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * and the other will be input direction here. 1409034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 1410034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * ex) 1411034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * ... 1412034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * USB_ENDPOINT_XFER_ISOC -> dir out 1413034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * USB_ENDPOINT_XFER_ISOC -> dir in 1414034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * USB_ENDPOINT_XFER_BULK -> dir out 1415034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * USB_ENDPOINT_XFER_BULK -> dir in 1416034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * USB_ENDPOINT_XFER_BULK -> dir in 1417034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * ... 1418034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1419034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dir_in = (pipe_type[i] == old_type); 1420034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto old_type = pipe_type[i]; 1421034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1422034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (USB_ENDPOINT_XFER_CONTROL == pipe_type[i]) { 1423034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto pipe = usbhs_dcp_malloc(priv); 1424034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_hpriv_to_dcp(hpriv) = pipe; 1425034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } else { 1426034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto pipe = usbhs_pipe_malloc(priv, 1427034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto pipe_type[i], 1428034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dir_in); 1429034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1430034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1431e5679d07a6ca5512070fb5e65dcc66eeb5087d0dKuninori Morimoto pipe->mod_private = NULL; 1432034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1433034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1434034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1435034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_start(struct usbhs_priv *priv) 1436034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1437034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1438034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 1439034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 1440034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1441034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int ret; 1442034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1443034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* add hcd */ 1444034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto ret = usb_add_hcd(hcd, 0, 0); 1445034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (ret < 0) 1446034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1447034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1448034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1449034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * pipe initialize and enable DCP 1450034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1451034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_pipe_init(priv, 1452034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_dma_map_ctrl); 1453034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_fifo_init(priv); 1454034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_pipe_init_for_host(priv); 1455034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1456034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1457034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * system config enble 1458034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * - HI speed 1459034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * - host 1460034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * - usb module 1461034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1462034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_sys_host_ctrl(priv, 1); 1463034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1464034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1465034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * enable irq callback 1466034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1467034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto mod->irq_attch = usbhsh_irq_attch; 1468034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto mod->irq_dtch = usbhsh_irq_dtch; 1469034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto mod->irq_sack = usbhsh_irq_setup_ack; 1470034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto mod->irq_sign = usbhsh_irq_setup_err; 1471034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_irq_callback_update(priv, mod); 1472034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1473034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "start host\n"); 1474034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1475034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return ret; 1476034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1477034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1478034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimotostatic int usbhsh_stop(struct usbhs_priv *priv) 1479034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1480034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1481034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 1482146ee50ae51c78fc93d025cb9528883df26ab705Kuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 1483034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1484034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1485146ee50ae51c78fc93d025cb9528883df26ab705Kuninori Morimoto /* 1486146ee50ae51c78fc93d025cb9528883df26ab705Kuninori Morimoto * disable irq callback 1487146ee50ae51c78fc93d025cb9528883df26ab705Kuninori Morimoto */ 1488146ee50ae51c78fc93d025cb9528883df26ab705Kuninori Morimoto mod->irq_attch = NULL; 1489146ee50ae51c78fc93d025cb9528883df26ab705Kuninori Morimoto mod->irq_dtch = NULL; 1490146ee50ae51c78fc93d025cb9528883df26ab705Kuninori Morimoto mod->irq_sack = NULL; 1491146ee50ae51c78fc93d025cb9528883df26ab705Kuninori Morimoto mod->irq_sign = NULL; 1492146ee50ae51c78fc93d025cb9528883df26ab705Kuninori Morimoto usbhs_irq_callback_update(priv, mod); 1493146ee50ae51c78fc93d025cb9528883df26ab705Kuninori Morimoto 1494034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usb_remove_hcd(hcd); 1495034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1496034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* disable sys */ 1497034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_sys_host_ctrl(priv, 0); 1498034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1499034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_dbg(dev, "quit host\n"); 1500034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1501034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1502034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1503034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1504b7a8d17db9a86db1040862600cf3a02848f83844Kuninori Morimotoint usbhs_mod_host_probe(struct usbhs_priv *priv) 1505034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1506034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv; 1507034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_hcd *hcd; 1508034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_device *udev; 1509034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1510034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto int i; 1511034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1512034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* initialize hcd */ 1513034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto hcd = usb_create_hcd(&usbhsh_driver, dev, usbhsh_hcd_name); 1514034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto if (!hcd) { 1515034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_err(dev, "Failed to create hcd\n"); 1516034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return -ENOMEM; 1517034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 15181115b9e279a23ca0bf7eda7d7697fe20a441304eKuninori Morimoto hcd->has_tt = 1; /* for low/full speed */ 1519034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1520034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1521034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * CAUTION 1522034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * 1523034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * There is no guarantee that it is possible to access usb module here. 1524034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * Don't accesses to it. 1525034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * The accesse will be enable after "usbhsh_start" 1526034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1527034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1528034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto hpriv = usbhsh_hcd_to_hpriv(hcd); 1529034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1530034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* 1531034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto * register itself 1532034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto */ 1533034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhs_mod_register(priv, &hpriv->mod, USBHS_HOST); 1534034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1535034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* init hpriv */ 1536034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto hpriv->mod.name = "host"; 1537034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto hpriv->mod.start = usbhsh_start; 1538034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto hpriv->mod.stop = usbhsh_stop; 1539034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_port_stat_init(hpriv); 1540034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1541034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto /* init all device */ 1542034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usbhsh_for_each_udev_with_dev0(udev, hpriv, i) { 1543034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto udev->usbv = NULL; 1544034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto INIT_LIST_HEAD(&udev->ep_list_head); 1545034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto } 1546034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1547034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto dev_info(dev, "host probed\n"); 1548034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1549034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1550034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1551034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1552b7a8d17db9a86db1040862600cf3a02848f83844Kuninori Morimotoint usbhs_mod_host_remove(struct usbhs_priv *priv) 1553034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto{ 1554034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); 1555034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); 1556034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1557034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto usb_put_hcd(hcd); 1558034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto 1559034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto return 0; 1560034d7c13a79c67d3b52dd782d68e6c324613878aKuninori Morimoto} 1561