diff options
| author | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2008-12-17 16:53:07 +0100 | 
|---|---|---|
| committer | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2008-12-17 16:53:07 +0100 | 
| commit | cb5473205206c7f14cbb1e747f28ec75b48826e2 (patch) | |
| tree | 8f4808d60917100b18a10b05230f7638a0a9bbcc /drivers/usb/usb_ohci.c | |
| parent | baf449fc5ff96f071bb0e3789fd3265f6d4fd9a0 (diff) | |
| parent | 92c78a3bbcb2ce508b4bf1c4a1e0940406a024bb (diff) | |
| download | olio-uboot-2014.01-cb5473205206c7f14cbb1e747f28ec75b48826e2.tar.xz olio-uboot-2014.01-cb5473205206c7f14cbb1e747f28ec75b48826e2.zip | |
Merge branch 'fixes' into cleanups
Conflicts:
	board/atmel/atngw100/atngw100.c
	board/atmel/atstk1000/atstk1000.c
	cpu/at32ap/at32ap700x/gpio.c
	include/asm-avr32/arch-at32ap700x/clk.h
	include/configs/atngw100.h
	include/configs/atstk1002.h
	include/configs/atstk1003.h
	include/configs/atstk1004.h
	include/configs/atstk1006.h
	include/configs/favr-32-ezkit.h
	include/configs/hammerhead.h
	include/configs/mimc200.h
Diffstat (limited to 'drivers/usb/usb_ohci.c')
| -rw-r--r-- | drivers/usb/usb_ohci.c | 1035 | 
1 files changed, 568 insertions, 467 deletions
| diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c index 0bfa4d782..d68fdcf06 100644 --- a/drivers/usb/usb_ohci.c +++ b/drivers/usb/usb_ohci.c @@ -46,9 +46,6 @@   */  #include <common.h> - -#ifdef CONFIG_USB_OHCI_NEW -  #include <asm/byteorder.h>  #if defined(CONFIG_PCI_OHCI) @@ -73,7 +70,7 @@      defined(CONFIG_440EP) || \      defined(CONFIG_PCI_OHCI) || \      defined(CONFIG_MPC5200) || \ -    defined(CFG_OHCI_USE_NPS) +    defined(CONFIG_SYS_OHCI_USE_NPS)  # define OHCI_USE_NPS		/* force NoPowerSwitching mode */  #endif @@ -89,15 +86,16 @@  /*   * e.g. PCI controllers need this   */ -#ifdef CFG_OHCI_SWAP_REG_ACCESS +#ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS  # define readl(a) __swap_32(*((volatile u32 *)(a)))  # define writel(a, b) (*((volatile u32 *)(b)) = __swap_32((volatile u32)a))  #else  # define readl(a) (*((volatile u32 *)(a)))  # define writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a)) -#endif /* CFG_OHCI_SWAP_REG_ACCESS */ +#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */ -#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) +#define min_t(type, x, y) \ +		    ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })  #ifdef CONFIG_PCI_OHCI  static struct pci_device_id ohci_pci_ids[] = { @@ -109,25 +107,33 @@ static struct pci_device_id ohci_pci_ids[] = {  };  #endif +#ifdef CONFIG_PCI_EHCI_DEVNO +static struct pci_device_id ehci_pci_ids[] = { +	{0x1131, 0x1562},	/* Philips 1562 PCI EHCI module ids */ +	/* Please add supported PCI EHCI controller ids here */ +	{0, 0} +}; +#endif +  #ifdef DEBUG  #define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)  #else -#define dbg(format, arg...) do {} while(0) +#define dbg(format, arg...) do {} while (0)  #endif /* DEBUG */  #define err(format, arg...) printf("ERROR: " format "\n", ## arg)  #ifdef SHOW_INFO  #define info(format, arg...) printf("INFO: " format "\n", ## arg)  #else -#define info(format, arg...) do {} while(0) +#define info(format, arg...) do {} while (0)  #endif -#ifdef CFG_OHCI_BE_CONTROLLER +#ifdef CONFIG_SYS_OHCI_BE_CONTROLLER  # define m16_swap(x) cpu_to_be16(x)  # define m32_swap(x) cpu_to_be32(x)  #else  # define m16_swap(x) cpu_to_le16(x)  # define m32_swap(x) cpu_to_le32(x) -#endif /* CFG_OHCI_BE_CONTROLLER */ +#endif /* CONFIG_SYS_OHCI_BE_CONTROLLER */  /* global ohci_t */  static ohci_t gohci; @@ -137,25 +143,24 @@ struct ohci_hcca ghcca[1];  struct ohci_hcca *phcca;  /* this allocates EDs for all possible endpoints */  struct ohci_device ohci_dev; -/* RHSC flag */ -int got_rhsc;  /* device which was disconnected */  struct usb_device *devgone; -static inline u32 roothub_a (struct ohci *hc) -	{ return readl (&hc->regs->roothub.a); } -static inline u32 roothub_b (struct ohci *hc) -	{ return readl (&hc->regs->roothub.b); } -static inline u32 roothub_status (struct ohci *hc) -	{ return readl (&hc->regs->roothub.status); } -static inline u32 roothub_portstatus (struct ohci *hc, int i) -	{ return readl (&hc->regs->roothub.portstatus[i]); } +static inline u32 roothub_a(struct ohci *hc) +	{ return readl(&hc->regs->roothub.a); } +static inline u32 roothub_b(struct ohci *hc) +	{ return readl(&hc->regs->roothub.b); } +static inline u32 roothub_status(struct ohci *hc) +	{ return readl(&hc->regs->roothub.status); } +static inline u32 roothub_portstatus(struct ohci *hc, int i) +	{ return readl(&hc->regs->roothub.portstatus[i]); }  /* forward declaration */ -static int hc_interrupt (void); -static void -td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer, -	int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval); +static int hc_interrupt(void); +static void td_submit_job(struct usb_device *dev, unsigned long pipe, +			  void *buffer, int transfer_len, +			  struct devrequest *setup, urb_priv_t *urb, +			  int interval);  /*-------------------------------------------------------------------------*   * URB support functions @@ -163,11 +168,11 @@ td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer,  /* free HCD-private data associated with this URB */ -static void urb_free_priv (urb_priv_t * urb) +static void urb_free_priv(urb_priv_t *urb)  {  	int		i;  	int		last; -	struct td	* td; +	struct td	*td;  	last = urb->length - 1;  	if (last >= 0) { @@ -185,72 +190,74 @@ static void urb_free_priv (urb_priv_t * urb)  /*-------------------------------------------------------------------------*/  #ifdef DEBUG -static int sohci_get_current_frame_number (struct usb_device * dev); +static int sohci_get_current_frame_number(struct usb_device *dev);  /* debug| print the main components of an URB   * small: 0) header + data packets 1) just header */ -static void pkt_print (urb_priv_t *purb, struct usb_device * dev, -	unsigned long pipe, void * buffer, -	int transfer_len, struct devrequest * setup, char * str, int small) +static void pkt_print(urb_priv_t *purb, struct usb_device *dev, +		      unsigned long pipe, void *buffer, int transfer_len, +		      struct devrequest *setup, char *str, int small)  { -	dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx", +	dbg("%s URB:[%4x] dev:%2lu,ep:%2lu-%c,type:%s,len:%d/%d stat:%#lx",  			str, -			sohci_get_current_frame_number (dev), -			usb_pipedevice (pipe), -			usb_pipeendpoint (pipe), -			usb_pipeout (pipe)? 'O': 'I', -			usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): -				(usb_pipecontrol (pipe)? "CTRL": "BULK"), +			sohci_get_current_frame_number(dev), +			usb_pipedevice(pipe), +			usb_pipeendpoint(pipe), +			usb_pipeout(pipe)? 'O': 'I', +			usb_pipetype(pipe) < 2 ? \ +				(usb_pipeint(pipe)? "INTR": "ISOC"): \ +				(usb_pipecontrol(pipe)? "CTRL": "BULK"),  			(purb ? purb->actual_length : 0),  			transfer_len, dev->status);  #ifdef	OHCI_VERBOSE_DEBUG  	if (!small) {  		int i, len; -		if (usb_pipecontrol (pipe)) { -			printf (__FILE__ ": cmd(8):"); +		if (usb_pipecontrol(pipe)) { +			printf(__FILE__ ": cmd(8):");  			for (i = 0; i < 8 ; i++) -				printf (" %02x", ((__u8 *) setup) [i]); -			printf ("\n"); +				printf(" %02x", ((__u8 *) setup) [i]); +			printf("\n");  		}  		if (transfer_len > 0 && buffer) { -			printf (__FILE__ ": data(%d/%d):", +			printf(__FILE__ ": data(%d/%d):",  				(purb ? purb->actual_length : 0),  				transfer_len); -			len = usb_pipeout (pipe)? -					transfer_len: +			len = usb_pipeout(pipe)? transfer_len:  					(purb ? purb->actual_length : 0);  			for (i = 0; i < 16 && i < len; i++) -				printf (" %02x", ((__u8 *) buffer) [i]); -			printf ("%s\n", i < len? "...": ""); +				printf(" %02x", ((__u8 *) buffer) [i]); +			printf("%s\n", i < len? "...": "");  		}  	}  #endif  } -/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/ -void ep_print_int_eds (ohci_t *ohci, char * str) { +/* just for debugging; prints non-empty branches of the int ed tree + * inclusive iso eds */ +void ep_print_int_eds(ohci_t *ohci, char *str) +{  	int i, j; -	 __u32 * ed_p; -	for (i= 0; i < 32; i++) { +	 __u32 *ed_p; +	for (i = 0; i < 32; i++) {  		j = 5;  		ed_p = &(ohci->hcca->int_table [i]);  		if (*ed_p == 0)  		    continue; -		printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i); +		printf(__FILE__ ": %s branch int %2d(%2x):", str, i, i);  		while (*ed_p != 0 && j--) {  			ed_t *ed = (ed_t *)m32_swap(ed_p); -			printf (" ed: %4x;", ed->hwINFO); +			printf(" ed: %4x;", ed->hwINFO);  			ed_p = &ed->hwNextED;  		} -		printf ("\n"); +		printf("\n");  	}  } -static void ohci_dump_intr_mask (char *label, __u32 mask) +static void ohci_dump_intr_mask(char *label, __u32 mask)  { -	dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s", +	dbg("%s: 0x%08x%s%s%s%s%s%s%s%s%s",  		label,  		mask,  		(mask & OHCI_INTR_MIE) ? " MIE" : "", @@ -265,46 +272,46 @@ static void ohci_dump_intr_mask (char *label, __u32 mask)  		);  } -static void maybe_print_eds (char *label, __u32 value) +static void maybe_print_eds(char *label, __u32 value)  {  	ed_t *edp = (ed_t *)value;  	if (value) { -		dbg ("%s %08x", label, value); -		dbg ("%08x", edp->hwINFO); -		dbg ("%08x", edp->hwTailP); -		dbg ("%08x", edp->hwHeadP); -		dbg ("%08x", edp->hwNextED); +		dbg("%s %08x", label, value); +		dbg("%08x", edp->hwINFO); +		dbg("%08x", edp->hwTailP); +		dbg("%08x", edp->hwHeadP); +		dbg("%08x", edp->hwNextED);  	}  } -static char * hcfs2string (int state) +static char *hcfs2string(int state)  {  	switch (state) { -		case OHCI_USB_RESET:	return "reset"; -		case OHCI_USB_RESUME:	return "resume"; -		case OHCI_USB_OPER:	return "operational"; -		case OHCI_USB_SUSPEND:	return "suspend"; +	case OHCI_USB_RESET:	return "reset"; +	case OHCI_USB_RESUME:	return "resume"; +	case OHCI_USB_OPER:	return "operational"; +	case OHCI_USB_SUSPEND:	return "suspend";  	}  	return "?";  }  /* dump control and status registers */ -static void ohci_dump_status (ohci_t *controller) +static void ohci_dump_status(ohci_t *controller)  {  	struct ohci_regs	*regs = controller->regs;  	__u32			temp; -	temp = readl (®s->revision) & 0xff; +	temp = readl(®s->revision) & 0xff;  	if (temp != 0x10) -		dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f)); +		dbg("spec %d.%d", (temp >> 4), (temp & 0x0f)); -	temp = readl (®s->control); -	dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, +	temp = readl(®s->control); +	dbg("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,  		(temp & OHCI_CTRL_RWE) ? " RWE" : "",  		(temp & OHCI_CTRL_RWC) ? " RWC" : "",  		(temp & OHCI_CTRL_IR) ? " IR" : "", -		hcfs2string (temp & OHCI_CTRL_HCFS), +		hcfs2string(temp & OHCI_CTRL_HCFS),  		(temp & OHCI_CTRL_BLE) ? " BLE" : "",  		(temp & OHCI_CTRL_CLE) ? " CLE" : "",  		(temp & OHCI_CTRL_IE) ? " IE" : "", @@ -312,8 +319,8 @@ static void ohci_dump_status (ohci_t *controller)  		temp & OHCI_CTRL_CBSR  		); -	temp = readl (®s->cmdstatus); -	dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, +	temp = readl(®s->cmdstatus); +	dbg("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,  		(temp & OHCI_SOC) >> 16,  		(temp & OHCI_OCR) ? " OCR" : "",  		(temp & OHCI_BLF) ? " BLF" : "", @@ -321,31 +328,31 @@ static void ohci_dump_status (ohci_t *controller)  		(temp & OHCI_HCR) ? " HCR" : ""  		); -	ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus)); -	ohci_dump_intr_mask ("intrenable", readl (®s->intrenable)); +	ohci_dump_intr_mask("intrstatus", readl(®s->intrstatus)); +	ohci_dump_intr_mask("intrenable", readl(®s->intrenable)); -	maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent)); +	maybe_print_eds("ed_periodcurrent", readl(®s->ed_periodcurrent)); -	maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead)); -	maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent)); +	maybe_print_eds("ed_controlhead", readl(®s->ed_controlhead)); +	maybe_print_eds("ed_controlcurrent", readl(®s->ed_controlcurrent)); -	maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead)); -	maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent)); +	maybe_print_eds("ed_bulkhead", readl(®s->ed_bulkhead)); +	maybe_print_eds("ed_bulkcurrent", readl(®s->ed_bulkcurrent)); -	maybe_print_eds ("donehead", readl (®s->donehead)); +	maybe_print_eds("donehead", readl(®s->donehead));  } -static void ohci_dump_roothub (ohci_t *controller, int verbose) +static void ohci_dump_roothub(ohci_t *controller, int verbose)  {  	__u32			temp, ndp, i; -	temp = roothub_a (controller); +	temp = roothub_a(controller);  	ndp = (temp & RH_A_NDP);  #ifdef CONFIG_AT91C_PQFP_UHPBUG  	ndp = (ndp == 2) ? 1:0;  #endif  	if (verbose) { -		dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, +		dbg("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,  			((temp & RH_A_POTPGT) >> 24) & 0xff,  			(temp & RH_A_NOCP) ? " NOCP" : "",  			(temp & RH_A_OCPM) ? " OCPM" : "", @@ -354,14 +361,14 @@ static void ohci_dump_roothub (ohci_t *controller, int verbose)  			(temp & RH_A_PSM) ? " PSM" : "",  			ndp  			); -		temp = roothub_b (controller); -		dbg ("roothub.b: %08x PPCM=%04x DR=%04x", +		temp = roothub_b(controller); +		dbg("roothub.b: %08x PPCM=%04x DR=%04x",  			temp,  			(temp & RH_B_PPCM) >> 16,  			(temp & RH_B_DR)  			); -		temp = roothub_status (controller); -		dbg ("roothub.status: %08x%s%s%s%s%s%s", +		temp = roothub_status(controller); +		dbg("roothub.status: %08x%s%s%s%s%s%s",  			temp,  			(temp & RH_HS_CRWE) ? " CRWE" : "",  			(temp & RH_HS_OCIC) ? " OCIC" : "", @@ -373,8 +380,8 @@ static void ohci_dump_roothub (ohci_t *controller, int verbose)  	}  	for (i = 0; i < ndp; i++) { -		temp = roothub_portstatus (controller, i); -		dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", +		temp = roothub_portstatus(controller, i); +		dbg("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",  			i,  			temp,  			(temp & RH_PS_PRSC) ? " PRSC" : "", @@ -395,16 +402,16 @@ static void ohci_dump_roothub (ohci_t *controller, int verbose)  	}  } -static void ohci_dump (ohci_t *controller, int verbose) +static void ohci_dump(ohci_t *controller, int verbose)  { -	dbg ("OHCI controller usb-%s state", controller->slot_name); +	dbg("OHCI controller usb-%s state", controller->slot_name);  	/* dumps some of the state we know about */ -	ohci_dump_status (controller); +	ohci_dump_status(controller);  	if (verbose) -		ep_print_int_eds (controller, "hcca"); -	dbg ("hcca frame #%04x", controller->hcca->frame_no); -	ohci_dump_roothub (controller, 1); +		ep_print_int_eds(controller, "hcca"); +	dbg("hcca frame #%04x", controller->hcca->frame_no); +	ohci_dump_roothub(controller, 1);  }  #endif /* DEBUG */ @@ -417,7 +424,7 @@ static void ohci_dump (ohci_t *controller, int verbose)  int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup)  {  	ohci_t *ohci; -	ed_t * ed; +	ed_t *ed;  	urb_priv_t *purb_priv = urb;  	int i, size = 0;  	struct usb_device *dev = urb->dev; @@ -435,27 +442,29 @@ int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup)  		return -1;  	} -	/* we're about to begin a new transaction here so mark the URB unfinished */ +	/* we're about to begin a new transaction here so mark the +	 * URB unfinished */  	urb->finished = 0;  	/* every endpoint has a ed, locate and fill it */ -	if (!(ed = ep_add_ed (dev, pipe, interval, 1))) { +	ed = ep_add_ed(dev, pipe, interval, 1); +	if (!ed) {  		err("sohci_submit_job: ENOMEM");  		return -1;  	}  	/* for the private part of the URB we need the number of TDs (size) */ -	switch (usb_pipetype (pipe)) { -		case PIPE_BULK: /* one TD for every 4096 Byte */ -			size = (transfer_len - 1) / 4096 + 1; -			break; -		case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ -			size = (transfer_len == 0)? 2: -						(transfer_len - 1) / 4096 + 3; -			break; -		case PIPE_INTERRUPT: /* 1 TD */ -			size = 1; -			break; +	switch (usb_pipetype(pipe)) { +	case PIPE_BULK: /* one TD for every 4096 Byte */ +		size = (transfer_len - 1) / 4096 + 1; +		break; +	case PIPE_CONTROL:/* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ +		size = (transfer_len == 0)? 2: +					(transfer_len - 1) / 4096 + 3; +		break; +	case PIPE_INTERRUPT: /* 1 TD */ +		size = 1; +		break;  	}  	ed->purb = urb; @@ -474,27 +483,28 @@ int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup)  	/* allocate the TDs */  	/* note that td[0] was allocated in ep_add_ed */  	for (i = 0; i < size; i++) { -		purb_priv->td[i] = td_alloc (dev); +		purb_priv->td[i] = td_alloc(dev);  		if (!purb_priv->td[i]) {  			purb_priv->length = i; -			urb_free_priv (purb_priv); +			urb_free_priv(purb_priv);  			err("sohci_submit_job: ENOMEM");  			return -1;  		}  	}  	if (ed->state == ED_NEW || (ed->state & ED_DEL)) { -		urb_free_priv (purb_priv); +		urb_free_priv(purb_priv);  		err("sohci_submit_job: EINVAL");  		return -1;  	}  	/* link the ed into a chain if is not already */  	if (ed->state != ED_OPER) -		ep_link (ohci, ed); +		ep_link(ohci, ed);  	/* fill the TDs and link it to the ed */ -	td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval); +	td_submit_job(dev, pipe, buffer, transfer_len, +		      setup, purb_priv, interval);  	return 0;  } @@ -503,19 +513,19 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)  {  	struct ohci_regs *regs = hc->regs; -	switch (usb_pipetype (urb->pipe)) { +	switch (usb_pipetype(urb->pipe)) {  	case PIPE_INTERRUPT:  		/* implicitly requeued */  		if (urb->dev->irq_handle &&  				(urb->dev->irq_act_len = urb->actual_length)) { -			writel (OHCI_INTR_WDH, ®s->intrenable); -			readl (®s->intrenable); /* PCI posting flush */ +			writel(OHCI_INTR_WDH, ®s->intrenable); +			readl(®s->intrenable); /* PCI posting flush */  			urb->dev->irq_handle(urb->dev); -			writel (OHCI_INTR_WDH, ®s->intrdisable); -			readl (®s->intrdisable); /* PCI posting flush */ +			writel(OHCI_INTR_WDH, ®s->intrdisable); +			readl(®s->intrdisable); /* PCI posting flush */  		}  		urb->actual_length = 0; -		td_submit_job ( +		td_submit_job(  				urb->dev,  				urb->pipe,  				urb->transfer_buffer, @@ -538,11 +548,11 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)  #ifdef DEBUG  /* tell us the current USB frame number */ -static int sohci_get_current_frame_number (struct usb_device *usb_dev) +static int sohci_get_current_frame_number(struct usb_device *usb_dev)  {  	ohci_t *ohci = &gohci; -	return m16_swap (ohci->hcca->frame_no); +	return m16_swap(ohci->hcca->frame_no);  }  #endif @@ -555,7 +565,7 @@ static int sohci_get_current_frame_number (struct usb_device *usb_dev)   * returns the branch and   * sets the interval to interval = 2^integer (ld (interval)) */ -static int ep_int_ballance (ohci_t * ohci, int interval, int load) +static int ep_int_ballance(ohci_t *ohci, int interval, int load)  {  	int i, branch = 0; @@ -577,20 +587,19 @@ static int ep_int_ballance (ohci_t * ohci, int interval, int load)  /*  2^int( ld (inter)) */ -static int ep_2_n_interval (int inter) +static int ep_2_n_interval(int inter)  {  	int i; -	for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++); +	for (i = 0; ((inter >> i) > 1) && (i < 5); i++);  	return 1 << i;  }  /*-------------------------------------------------------------------------*/  /* the int tree is a binary tree - * in order to process it sequentially the indexes of the branches have to be mapped - * the mapping reverses the bits of a word of num_bits length */ - -static int ep_rev (int num_bits, int word) + * in order to process it sequentially the indexes of the branches have to + * be mapped the mapping reverses the bits of a word of num_bits length */ +static int ep_rev(int num_bits, int word)  {  	int i, wout = 0; @@ -605,7 +614,7 @@ static int ep_rev (int num_bits, int word)  /* link an ed into one of the HC chains */ -static int ep_link (ohci_t *ohci, ed_t *edi) +static int ep_link(ohci_t *ohci, ed_t *edi)  {  	volatile ed_t *ed = edi;  	int int_branch; @@ -613,7 +622,7 @@ static int ep_link (ohci_t *ohci, ed_t *edi)  	int inter;  	int interval;  	int load; -	__u32 * ed_p; +	__u32 *ed_p;  	ed->state = ED_OPER;  	ed->int_interval = 0; @@ -621,49 +630,54 @@ static int ep_link (ohci_t *ohci, ed_t *edi)  	switch (ed->type) {  	case PIPE_CONTROL:  		ed->hwNextED = 0; -		if (ohci->ed_controltail == NULL) { -			writel (ed, &ohci->regs->ed_controlhead); -		} else { -			ohci->ed_controltail->hwNextED = m32_swap ((unsigned long)ed); -		} +		if (ohci->ed_controltail == NULL) +			writel(ed, &ohci->regs->ed_controlhead); +		else +			ohci->ed_controltail->hwNextED = +						   m32_swap((unsigned long)ed); +  		ed->ed_prev = ohci->ed_controltail;  		if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&  			!ohci->ed_rm_list[1] && !ohci->sleeping) {  			ohci->hc_control |= OHCI_CTRL_CLE; -			writel (ohci->hc_control, &ohci->regs->control); +			writel(ohci->hc_control, &ohci->regs->control);  		}  		ohci->ed_controltail = edi;  		break;  	case PIPE_BULK:  		ed->hwNextED = 0; -		if (ohci->ed_bulktail == NULL) { -			writel (ed, &ohci->regs->ed_bulkhead); -		} else { -			ohci->ed_bulktail->hwNextED = m32_swap ((unsigned long)ed); -		} +		if (ohci->ed_bulktail == NULL) +			writel(ed, &ohci->regs->ed_bulkhead); +		else +			ohci->ed_bulktail->hwNextED = +						   m32_swap((unsigned long)ed); +  		ed->ed_prev = ohci->ed_bulktail;  		if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&  			!ohci->ed_rm_list[1] && !ohci->sleeping) {  			ohci->hc_control |= OHCI_CTRL_BLE; -			writel (ohci->hc_control, &ohci->regs->control); +			writel(ohci->hc_control, &ohci->regs->control);  		}  		ohci->ed_bulktail = edi;  		break;  	case PIPE_INTERRUPT:  		load = ed->int_load; -		interval = ep_2_n_interval (ed->int_period); +		interval = ep_2_n_interval(ed->int_period);  		ed->int_interval = interval; -		int_branch = ep_int_ballance (ohci, interval, load); +		int_branch = ep_int_ballance(ohci, interval, load);  		ed->int_branch = int_branch; -		for (i = 0; i < ep_rev (6, interval); i += inter) { +		for (i = 0; i < ep_rev(6, interval); i += inter) {  			inter = 1; -			for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]); -				(*ed_p != 0) && (((ed_t *)ed_p)->int_interval >= interval); +			for (ed_p = &(ohci->hcca->int_table[\ +						ep_rev(5, i) + int_branch]); +				(*ed_p != 0) && +				(((ed_t *)ed_p)->int_interval >= interval);  				ed_p = &(((ed_t *)ed_p)->hwNextED)) -					inter = ep_rev (6, ((ed_t *)ed_p)->int_interval); +					inter = ep_rev(6, +						 ((ed_t *)ed_p)->int_interval);  			ed->hwNextED = *ed_p;  			*ed_p = m32_swap((unsigned long)ed);  		} @@ -675,19 +689,21 @@ static int ep_link (ohci_t *ohci, ed_t *edi)  /*-------------------------------------------------------------------------*/  /* scan the periodic table to find and unlink this ED */ -static void periodic_unlink ( struct ohci *ohci, volatile struct ed *ed, -		unsigned index, unsigned period) +static void periodic_unlink(struct ohci *ohci, volatile struct ed *ed, +			    unsigned index, unsigned period)  {  	for (; index < NUM_INTS; index += period) {  		__u32	*ed_p = &ohci->hcca->int_table [index];  		/* ED might have been unlinked through another path */  		while (*ed_p != 0) { -			if (((struct ed *)m32_swap ((unsigned long)ed_p)) == ed) { +			if (((struct ed *) +					m32_swap((unsigned long)ed_p)) == ed) {  				*ed_p = ed->hwNextED;  				break;  			} -			ed_p = & (((struct ed *)m32_swap ((unsigned long)ed_p))->hwNextED); +			ed_p = &(((struct ed *) +				     m32_swap((unsigned long)ed_p))->hwNextED);  		}  	}  } @@ -697,28 +713,30 @@ static void periodic_unlink ( struct ohci *ohci, volatile struct ed *ed,   * the link from the ed still points to another operational ed or 0   * so the HC can eventually finish the processing of the unlinked ed */ -static int ep_unlink (ohci_t *ohci, ed_t *edi) +static int ep_unlink(ohci_t *ohci, ed_t *edi)  {  	volatile ed_t *ed = edi;  	int i; -	ed->hwINFO |= m32_swap (OHCI_ED_SKIP); +	ed->hwINFO |= m32_swap(OHCI_ED_SKIP);  	switch (ed->type) {  	case PIPE_CONTROL:  		if (ed->ed_prev == NULL) {  			if (!ed->hwNextED) {  				ohci->hc_control &= ~OHCI_CTRL_CLE; -				writel (ohci->hc_control, &ohci->regs->control); +				writel(ohci->hc_control, &ohci->regs->control);  			} -			writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead); +			writel(m32_swap(*((__u32 *)&ed->hwNextED)), +				&ohci->regs->ed_controlhead);  		} else {  			ed->ed_prev->hwNextED = ed->hwNextED;  		}  		if (ohci->ed_controltail == ed) {  			ohci->ed_controltail = ed->ed_prev;  		} else { -			((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; +			((ed_t *)m32_swap( +			    *((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;  		}  		break; @@ -726,21 +744,23 @@ static int ep_unlink (ohci_t *ohci, ed_t *edi)  		if (ed->ed_prev == NULL) {  			if (!ed->hwNextED) {  				ohci->hc_control &= ~OHCI_CTRL_BLE; -				writel (ohci->hc_control, &ohci->regs->control); +				writel(ohci->hc_control, &ohci->regs->control);  			} -			writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead); +			writel(m32_swap(*((__u32 *)&ed->hwNextED)), +			       &ohci->regs->ed_bulkhead);  		} else {  			ed->ed_prev->hwNextED = ed->hwNextED;  		}  		if (ohci->ed_bulktail == ed) {  			ohci->ed_bulktail = ed->ed_prev;  		} else { -			((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; +			((ed_t *)m32_swap( +			     *((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;  		}  		break;  	case PIPE_INTERRUPT: -		periodic_unlink (ohci, ed, 0, 1); +		periodic_unlink(ohci, ed, 0, 1);  		for (i = ed->int_branch; i < 32; i += ed->int_interval)  		    ohci->ohci_int_load[i] -= ed->int_load;  		break; @@ -759,15 +779,15 @@ static int ep_unlink (ohci_t *ohci, ed_t *edi)   * info fields are setted anyway even though most of them should not   * change   */ -static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe, -		int interval, int load) +static ed_t *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe, +			int interval, int load)  {  	td_t *td;  	ed_t *ed_ret;  	volatile ed_t *ed; -	ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) | -			(usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]; +	ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint(pipe) << 1) | +			(usb_pipecontrol(pipe)? 0: usb_pipeout(pipe))];  	if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {  		err("ep_add_ed: pending delete"); @@ -776,22 +796,22 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe,  	}  	if (ed->state == ED_NEW) { -		ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */  		/* dummy td; end of td list for ed */ -		td = td_alloc (usb_dev); -		ed->hwTailP = m32_swap ((unsigned long)td); +		td = td_alloc(usb_dev); +		ed->hwTailP = m32_swap((unsigned long)td);  		ed->hwHeadP = ed->hwTailP;  		ed->state = ED_UNLINK; -		ed->type = usb_pipetype (pipe); +		ed->type = usb_pipetype(pipe);  		ohci_dev.ed_cnt++;  	} -	ed->hwINFO = m32_swap (usb_pipedevice (pipe) -			| usb_pipeendpoint (pipe) << 7 -			| (usb_pipeisoc (pipe)? 0x8000: 0) -			| (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) -			| usb_pipeslow (pipe) << 13 -			| usb_maxpacket (usb_dev, pipe) << 16); +	ed->hwINFO = m32_swap(usb_pipedevice(pipe) +			| usb_pipeendpoint(pipe) << 7 +			| (usb_pipeisoc(pipe)? 0x8000: 0) +			| (usb_pipecontrol(pipe)? 0: \ +					   (usb_pipeout(pipe)? 0x800: 0x1000)) +			| usb_pipeslow(pipe) << 13 +			| usb_maxpacket(usb_dev, pipe) << 16);  	if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {  		ed->int_period = interval; @@ -807,7 +827,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe,  /* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ -static void td_fill (ohci_t *ohci, unsigned int info, +static void td_fill(ohci_t *ohci, unsigned int info,  	void *data, int len,  	struct usb_device *dev, int index, urb_priv_t *urb_priv)  { @@ -825,29 +845,31 @@ static void td_fill (ohci_t *ohci, unsigned int info,  	td_pt->hwNextTD = 0;  	/* fill the old dummy TD */ -	td = urb_priv->td [index] = (td_t *)(m32_swap (urb_priv->ed->hwTailP) & ~0xf); +	td = urb_priv->td [index] = +			     (td_t *)(m32_swap(urb_priv->ed->hwTailP) & ~0xf);  	td->ed = urb_priv->ed;  	td->next_dl_td = NULL;  	td->index = index;  	td->data = (__u32)data;  #ifdef OHCI_FILL_TRACE -	if ((usb_pipetype(urb_priv->pipe) == PIPE_BULK) && usb_pipeout(urb_priv->pipe)) { +	if (usb_pipebulk(urb_priv->pipe) && usb_pipeout(urb_priv->pipe)) {  		for (i = 0; i < len; i++) -		printf("td->data[%d] %#2x ",i, ((unsigned char *)td->data)[i]); +		printf("td->data[%d] %#2x ", i, ((unsigned char *)td->data)[i]);  		printf("\n");  	}  #endif  	if (!len)  		data = 0; -	td->hwINFO = m32_swap (info); -	td->hwCBP = m32_swap ((unsigned long)data); +	td->hwINFO = m32_swap(info); +	td->hwCBP = m32_swap((unsigned long)data);  	if (data) -		td->hwBE = m32_swap ((unsigned long)(data + len - 1)); +		td->hwBE = m32_swap((unsigned long)(data + len - 1));  	else  		td->hwBE = 0; -	td->hwNextTD = m32_swap ((unsigned long)td_pt); + +	td->hwNextTD = m32_swap((unsigned long)td_pt);  	/* append to queue */  	td->ed->hwTailP = td->hwNextTD; @@ -857,8 +879,10 @@ static void td_fill (ohci_t *ohci, unsigned int info,  /* prepare all TDs of a transfer */ -static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer, -	int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval) +static void td_submit_job(struct usb_device *dev, unsigned long pipe, +			  void *buffer, int transfer_len, +			  struct devrequest *setup, urb_priv_t *urb, +			  int interval)  {  	ohci_t *ohci = &gohci;  	int data_len = transfer_len; @@ -867,12 +891,14 @@ static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buf  	__u32 info = 0;  	unsigned int toggle = 0; -	/* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */ -	if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) { +	/* OHCI handles the DATA-toggles itself, we just use the USB-toggle +	 * bits for reseting */ +	if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {  		toggle = TD_T_TOGGLE;  	} else {  		toggle = TD_T_DATA0; -		usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1); +		usb_settoggle(dev, usb_pipeendpoint(pipe), +				usb_pipeout(pipe), 1);  	}  	urb->td_cnt = 0;  	if (data_len) @@ -880,44 +906,58 @@ static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buf  	else  		data = 0; -	switch (usb_pipetype (pipe)) { +	switch (usb_pipetype(pipe)) {  	case PIPE_BULK: -		info = usb_pipeout (pipe)? +		info = usb_pipeout(pipe)?  			TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ; -		while(data_len > 4096) { -			td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb); +		while (data_len > 4096) { +			td_fill(ohci, info | (cnt? TD_T_TOGGLE:toggle), +				data, 4096, dev, cnt, urb);  			data += 4096; data_len -= 4096; cnt++;  		} -		info = usb_pipeout (pipe)? +		info = usb_pipeout(pipe)?  			TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ; -		td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb); +		td_fill(ohci, info | (cnt? TD_T_TOGGLE:toggle), data, +			data_len, dev, cnt, urb);  		cnt++; -		if (!ohci->sleeping) -			writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ +		if (!ohci->sleeping) { +			/* start bulk list */ +			writel(OHCI_BLF, &ohci->regs->cmdstatus); +		}  		break;  	case PIPE_CONTROL: +		/* Setup phase */  		info = TD_CC | TD_DP_SETUP | TD_T_DATA0; -		td_fill (ohci, info, setup, 8, dev, cnt++, urb); +		td_fill(ohci, info, setup, 8, dev, cnt++, urb); + +		/* Optional Data phase */  		if (data_len > 0) { -			info = usb_pipeout (pipe)? -				TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; +			info = usb_pipeout(pipe)? +				TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : +				TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;  			/* NOTE:  mishandles transfers >8K, some >4K */ -			td_fill (ohci, info, data, data_len, dev, cnt++, urb); +			td_fill(ohci, info, data, data_len, dev, cnt++, urb); +		} + +		/* Status phase */ +		info = usb_pipeout(pipe)? +			TD_CC | TD_DP_IN | TD_T_DATA1: +			TD_CC | TD_DP_OUT | TD_T_DATA1; +		td_fill(ohci, info, data, 0, dev, cnt++, urb); + +		if (!ohci->sleeping) { +			/* start Control list */ +			writel(OHCI_CLF, &ohci->regs->cmdstatus);  		} -		info = usb_pipeout (pipe)? -			TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; -		td_fill (ohci, info, data, 0, dev, cnt++, urb); -		if (!ohci->sleeping) -			writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */  		break;  	case PIPE_INTERRUPT: -		info = usb_pipeout (urb->pipe)? +		info = usb_pipeout(urb->pipe)?  			TD_CC | TD_DP_OUT | toggle:  			TD_CC | TD_R | TD_DP_IN | toggle; -		td_fill (ohci, info, data, data_len, dev, cnt++, urb); +		td_fill(ohci, info, data, data_len, dev, cnt++, urb);  		break;  	}  	if (urb->length != cnt) @@ -930,16 +970,16 @@ static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buf  /* calculate the transfer length and update the urb */ -static void dl_transfer_length(td_t * td) +static void dl_transfer_length(td_t *td)  {  	__u32 tdINFO, tdBE, tdCBP;  	urb_priv_t *lurb_priv = td->ed->purb; -	tdINFO = m32_swap (td->hwINFO); -	tdBE   = m32_swap (td->hwBE); -	tdCBP  = m32_swap (td->hwCBP); +	tdINFO = m32_swap(td->hwINFO); +	tdBE   = m32_swap(td->hwBE); +	tdCBP  = m32_swap(td->hwCBP); -	if (!(usb_pipetype (lurb_priv->pipe) == PIPE_CONTROL && +	if (!(usb_pipecontrol(lurb_priv->pipe) &&  	    ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {  		if (tdBE != 0) {  			if (td->hwCBP == 0) @@ -951,105 +991,127 @@ static void dl_transfer_length(td_t * td)  }  /*-------------------------------------------------------------------------*/ +static void check_status(td_t *td_list) +{ +	urb_priv_t *lurb_priv = td_list->ed->purb; +	int	   urb_len    = lurb_priv->length; +	__u32      *phwHeadP  = &td_list->ed->hwHeadP; +	int	   cc; + +	cc = TD_CC_GET(m32_swap(td_list->hwINFO)); +	if (cc) { +		err(" USB-error: %s (%x)", cc_to_string[cc], cc); + +		if (*phwHeadP & m32_swap(0x1)) { +			if (lurb_priv && +			    ((td_list->index + 1) < urb_len)) { +				*phwHeadP = +					(lurb_priv->td[urb_len - 1]->hwNextTD &\ +							m32_swap(0xfffffff0)) | +						   (*phwHeadP & m32_swap(0x2)); + +				lurb_priv->td_cnt += urb_len - +						     td_list->index - 1; +			} else +				*phwHeadP &= m32_swap(0xfffffff2); +		} +#ifdef CONFIG_MPC5200 +		td_list->hwNextTD = 0; +#endif +	} +}  /* replies to the request have to be on a FIFO basis so   * we reverse the reversed done-list */ - -static td_t * dl_reverse_done_list (ohci_t *ohci) +static td_t *dl_reverse_done_list(ohci_t *ohci)  {  	__u32 td_list_hc;  	td_t *td_rev = NULL;  	td_t *td_list = NULL; -	urb_priv_t *lurb_priv = NULL; -	td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0; +	td_list_hc = m32_swap(ohci->hcca->done_head) & 0xfffffff0;  	ohci->hcca->done_head = 0;  	while (td_list_hc) {  		td_list = (td_t *)td_list_hc; - -		if (TD_CC_GET (m32_swap (td_list->hwINFO))) { -			lurb_priv = td_list->ed->purb; -			dbg(" USB-error/status: %x : %p", -					TD_CC_GET (m32_swap (td_list->hwINFO)), td_list); -			if (td_list->ed->hwHeadP & m32_swap (0x1)) { -				if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) { -					td_list->ed->hwHeadP = -						(lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) | -									(td_list->ed->hwHeadP & m32_swap (0x2)); -					lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1; -				} else -					td_list->ed->hwHeadP &= m32_swap (0xfffffff2); -			} -#ifdef CONFIG_MPC5200 -			td_list->hwNextTD = 0; -#endif -		} - +		check_status(td_list);  		td_list->next_dl_td = td_rev;  		td_rev = td_list; -		td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0; +		td_list_hc = m32_swap(td_list->hwNextTD) & 0xfffffff0;  	}  	return td_list;  }  /*-------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------*/ -/* td done list */ -static int dl_done_list (ohci_t *ohci, td_t *td_list) +static void finish_urb(ohci_t *ohci, urb_priv_t *urb, int status) +{ +	if ((status & (ED_OPER | ED_UNLINK)) && (urb->state != URB_DEL)) +		urb->finished = sohci_return_job(ohci, urb); +	else +		dbg("finish_urb: strange.., ED state %x, \n", status); +} + +/* + * Used to take back a TD from the host controller. This would normally be + * called from within dl_done_list, however it may be called directly if the + * HC no longer sees the TD and it has not appeared on the donelist (after + * two frames).  This bug has been observed on ZF Micro systems. + */ +static int takeback_td(ohci_t *ohci, td_t *td_list)  { -	td_t *td_list_next = NULL;  	ed_t *ed; -	int cc = 0; +	int cc;  	int stat = 0;  	/* urb_t *urb; */  	urb_priv_t *lurb_priv;  	__u32 tdINFO, edHeadP, edTailP; -	while (td_list) { -		td_list_next = td_list->next_dl_td; +	tdINFO = m32_swap(td_list->hwINFO); -		tdINFO = m32_swap (td_list->hwINFO); +	ed = td_list->ed; +	lurb_priv = ed->purb; -		ed = td_list->ed; -		lurb_priv = ed->purb; +	dl_transfer_length(td_list); -		dl_transfer_length(td_list); +	lurb_priv->td_cnt++; -		/* error code of transfer */ -		cc = TD_CC_GET (tdINFO); -		if (cc != 0) { -			dbg("ConditionCode %#x", cc); -			stat = cc_to_error[cc]; -		} +	/* error code of transfer */ +	cc = TD_CC_GET(tdINFO); +	if (cc) { +		err("USB-error: %s (%x)", cc_to_string[cc], cc); +		stat = cc_to_error[cc]; +	} -		/* see if this done list makes for all TD's of current URB, -		 * and mark the URB finished if so */ -		if (++(lurb_priv->td_cnt) == lurb_priv->length) { -#if 1 -			if ((ed->state & (ED_OPER | ED_UNLINK)) && -			    (lurb_priv->state != URB_DEL)) -#else -			if ((ed->state & (ED_OPER | ED_UNLINK))) -#endif -				lurb_priv->finished = sohci_return_job(ohci, -						lurb_priv); -			else -				dbg("dl_done_list: strange.., ED state %x, ed->state\n"); -		} else -			dbg("dl_done_list: processing TD %x, len %x\n", lurb_priv->td_cnt, -				lurb_priv->length); -		if (ed->state != ED_NEW && -			  (usb_pipetype (lurb_priv->pipe) != PIPE_INTERRUPT)) { -			edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0; -			edTailP = m32_swap (ed->hwTailP); +	/* see if this done list makes for all TD's of current URB, +	* and mark the URB finished if so */ +	if (lurb_priv->td_cnt == lurb_priv->length) +		finish_urb(ohci, lurb_priv, ed->state); -			/* unlink eds if they are not busy */ -			if ((edHeadP == edTailP) && (ed->state == ED_OPER)) -				ep_unlink (ohci, ed); -		} +	dbg("dl_done_list: processing TD %x, len %x\n", +		lurb_priv->td_cnt, lurb_priv->length); + +	if (ed->state != ED_NEW && (!usb_pipeint(lurb_priv->pipe))) { +		edHeadP = m32_swap(ed->hwHeadP) & 0xfffffff0; +		edTailP = m32_swap(ed->hwTailP); + +		/* unlink eds if they are not busy */ +		if ((edHeadP == edTailP) && (ed->state == ED_OPER)) +			ep_unlink(ohci, ed); +	} +	return stat; +} + +static int dl_done_list(ohci_t *ohci) +{ +	int stat = 0; +	td_t	*td_list = dl_reverse_done_list(ohci); -		td_list = td_list_next; +	while (td_list) { +		td_t	*td_next = td_list->next_dl_td; +		stat = takeback_td(ohci, td_list); +		td_list = td_next;  	}  	return stat;  } @@ -1092,7 +1154,7 @@ static __u8 root_hub_config_des[] =  	0x01,	    /*	__u8  bConfigurationValue; */  	0x00,	    /*	__u8  iConfiguration; */  	0x40,	    /*	__u8  bmAttributes; -		 Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ +	 Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */  	0x00,	    /*	__u8  MaxPower; */  	/* interface */ @@ -1162,14 +1224,17 @@ static unsigned char root_hub_str_index1[] =  #define OK(x)			len = (x); break  #ifdef DEBUG -#define WR_RH_STAT(x)		{info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);} -#define WR_RH_PORTSTAT(x)	{info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);} +#define WR_RH_STAT(x)		{info("WR:status %#8x", (x)); writel((x), \ +						&gohci.regs->roothub.status); } +#define WR_RH_PORTSTAT(x)	{info("WR:portstatus[%d] %#8x", wIndex-1, \ +		(x)); writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); }  #else  #define WR_RH_STAT(x)		writel((x), &gohci.regs->roothub.status) -#define WR_RH_PORTSTAT(x)	writel((x), &gohci.regs->roothub.portstatus[wIndex-1]) +#define WR_RH_PORTSTAT(x)	writel((x), \ +				    &gohci.regs->roothub.portstatus[wIndex-1])  #endif  #define RD_RH_STAT		roothub_status(&gohci) -#define RD_RH_PORTSTAT		roothub_portstatus(&gohci,wIndex-1) +#define RD_RH_PORTSTAT		roothub_portstatus(&gohci, wIndex-1)  /* request to virtual root hub */ @@ -1179,13 +1244,13 @@ int rh_check_port_status(ohci_t *controller)  	int res;  	res = -1; -	temp = roothub_a (controller); +	temp = roothub_a(controller);  	ndp = (temp & RH_A_NDP);  #ifdef CONFIG_AT91C_PQFP_UHPBUG  	ndp = (ndp == 2) ? 1:0;  #endif  	for (i = 0; i < ndp; i++) { -		temp = roothub_portstatus (controller, i); +		temp = roothub_portstatus(controller, i);  		/* check for a device disconnect */  		if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==  			(RH_PS_PESC | RH_PS_CSC)) && @@ -1200,7 +1265,7 @@ int rh_check_port_status(ohci_t *controller)  static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,  		void *buffer, int transfer_len, struct devrequest *cmd)  { -	void * data = buffer; +	void *data = buffer;  	int leni = transfer_len;  	int len = 0;  	int stat = 0; @@ -1212,19 +1277,20 @@ static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,  	__u16 wLength;  #ifdef DEBUG -pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe)); +pkt_print(NULL, dev, pipe, buffer, transfer_len, +	  cmd, "SUB(rh)", usb_pipein(pipe));  #else  	wait_ms(1);  #endif -	if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) { +	if (usb_pipeint(pipe)) {  		info("Root-Hub submit IRQ: NOT implemented");  		return 0;  	}  	bmRType_bReq  = cmd->requesttype | (cmd->request << 8); -	wValue	      = le16_to_cpu (cmd->value); -	wIndex	      = le16_to_cpu (cmd->index); -	wLength	      = le16_to_cpu (cmd->length); +	wValue	      = le16_to_cpu(cmd->value); +	wIndex	      = le16_to_cpu(cmd->index); +	wLength	      = le16_to_cpu(cmd->length);  	info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",  		dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength); @@ -1239,118 +1305,118 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe  	*/  	case RH_GET_STATUS: -			*(__u16 *) data_buf = cpu_to_le16 (1); OK (2); +		*(__u16 *) data_buf = cpu_to_le16(1); +		OK(2);  	case RH_GET_STATUS | RH_INTERFACE: -			*(__u16 *) data_buf = cpu_to_le16 (0); OK (2); +		*(__u16 *) data_buf = cpu_to_le16(0); +		OK(2);  	case RH_GET_STATUS | RH_ENDPOINT: -			*(__u16 *) data_buf = cpu_to_le16 (0); OK (2); +		*(__u16 *) data_buf = cpu_to_le16(0); +		OK(2);  	case RH_GET_STATUS | RH_CLASS: -			*(__u32 *) data_buf = cpu_to_le32 ( +		*(__u32 *) data_buf = cpu_to_le32(  				RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); -			OK (4); +		OK(4);  	case RH_GET_STATUS | RH_OTHER | RH_CLASS: -			*(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4); +		*(__u32 *) data_buf = cpu_to_le32(RD_RH_PORTSTAT); +		OK(4);  	case RH_CLEAR_FEATURE | RH_ENDPOINT:  		switch (wValue) { -			case (RH_ENDPOINT_STALL): OK (0); +		case (RH_ENDPOINT_STALL): +			OK(0);  		}  		break;  	case RH_CLEAR_FEATURE | RH_CLASS:  		switch (wValue) { -			case RH_C_HUB_LOCAL_POWER: -				OK(0); -			case (RH_C_HUB_OVER_CURRENT): -					WR_RH_STAT(RH_HS_OCIC); OK (0); +		case RH_C_HUB_LOCAL_POWER: +			OK(0); +		case (RH_C_HUB_OVER_CURRENT): +			WR_RH_STAT(RH_HS_OCIC); +			OK(0);  		}  		break;  	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:  		switch (wValue) { -			case (RH_PORT_ENABLE): -					WR_RH_PORTSTAT (RH_PS_CCS ); OK (0); -			case (RH_PORT_SUSPEND): -					WR_RH_PORTSTAT (RH_PS_POCI); OK (0); -			case (RH_PORT_POWER): -					WR_RH_PORTSTAT (RH_PS_LSDA); OK (0); -			case (RH_C_PORT_CONNECTION): -					WR_RH_PORTSTAT (RH_PS_CSC ); OK (0); -			case (RH_C_PORT_ENABLE): -					WR_RH_PORTSTAT (RH_PS_PESC); OK (0); -			case (RH_C_PORT_SUSPEND): -					WR_RH_PORTSTAT (RH_PS_PSSC); OK (0); -			case (RH_C_PORT_OVER_CURRENT): -					WR_RH_PORTSTAT (RH_PS_OCIC); OK (0); -			case (RH_C_PORT_RESET): -					WR_RH_PORTSTAT (RH_PS_PRSC); OK (0); +		case (RH_PORT_ENABLE):        WR_RH_PORTSTAT(RH_PS_CCS);  OK(0); +		case (RH_PORT_SUSPEND):       WR_RH_PORTSTAT(RH_PS_POCI); OK(0); +		case (RH_PORT_POWER):         WR_RH_PORTSTAT(RH_PS_LSDA); OK(0); +		case (RH_C_PORT_CONNECTION):  WR_RH_PORTSTAT(RH_PS_CSC);  OK(0); +		case (RH_C_PORT_ENABLE):      WR_RH_PORTSTAT(RH_PS_PESC); OK(0); +		case (RH_C_PORT_SUSPEND):     WR_RH_PORTSTAT(RH_PS_PSSC); OK(0); +		case (RH_C_PORT_OVER_CURRENT):WR_RH_PORTSTAT(RH_PS_OCIC); OK(0); +		case (RH_C_PORT_RESET):       WR_RH_PORTSTAT(RH_PS_PRSC); OK(0);  		}  		break;  	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:  		switch (wValue) { -			case (RH_PORT_SUSPEND): -					WR_RH_PORTSTAT (RH_PS_PSS ); OK (0); -			case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ -					if (RD_RH_PORTSTAT & RH_PS_CCS) -					    WR_RH_PORTSTAT (RH_PS_PRS); -					OK (0); -			case (RH_PORT_POWER): -					WR_RH_PORTSTAT (RH_PS_PPS ); -					wait_ms(100); -					OK (0); -			case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ -					if (RD_RH_PORTSTAT & RH_PS_CCS) -					    WR_RH_PORTSTAT (RH_PS_PES ); -					OK (0); +		case (RH_PORT_SUSPEND): +			WR_RH_PORTSTAT(RH_PS_PSS);  OK(0); +		case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ +			if (RD_RH_PORTSTAT & RH_PS_CCS) +				WR_RH_PORTSTAT(RH_PS_PRS); +			OK(0); +		case (RH_PORT_POWER): +			WR_RH_PORTSTAT(RH_PS_PPS); +			wait_ms(100); +			OK(0); +		case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ +			if (RD_RH_PORTSTAT & RH_PS_CCS) +				WR_RH_PORTSTAT(RH_PS_PES); +			OK(0);  		}  		break; -	case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0); +	case RH_SET_ADDRESS: +		gohci.rh.devnum = wValue; +		OK(0);  	case RH_GET_DESCRIPTOR:  		switch ((wValue & 0xff00) >> 8) { -			case (0x01): /* device descriptor */ -				len = min_t(unsigned int, -					  leni, -					  min_t(unsigned int, -					      sizeof (root_hub_dev_des), -					      wLength)); -				data_buf = root_hub_dev_des; OK(len); -			case (0x02): /* configuration descriptor */ +		case (0x01): /* device descriptor */ +			len = min_t(unsigned int, +					leni, +					min_t(unsigned int, +					sizeof(root_hub_dev_des), +					wLength)); +			data_buf = root_hub_dev_des; OK(len); +		case (0x02): /* configuration descriptor */ +			len = min_t(unsigned int, +					leni, +					min_t(unsigned int, +					sizeof(root_hub_config_des), +					wLength)); +			data_buf = root_hub_config_des; OK(len); +		case (0x03): /* string descriptors */ +			if (wValue == 0x0300) {  				len = min_t(unsigned int, -					  leni, -					  min_t(unsigned int, -					      sizeof (root_hub_config_des), -					      wLength)); -				data_buf = root_hub_config_des; OK(len); -			case (0x03): /* string descriptors */ -				if(wValue==0x0300) { -					len = min_t(unsigned int, -						  leni, -						  min_t(unsigned int, -						      sizeof (root_hub_str_index0), -						      wLength)); -					data_buf = root_hub_str_index0; -					OK(len); -				} -				if(wValue==0x0301) { -					len = min_t(unsigned int, -						  leni, -						  min_t(unsigned int, -						      sizeof (root_hub_str_index1), -						      wLength)); -					data_buf = root_hub_str_index1; -					OK(len); +						leni, +						min_t(unsigned int, +						sizeof(root_hub_str_index0), +						wLength)); +				data_buf = root_hub_str_index0; +				OK(len);  			} -			default: -				stat = USB_ST_STALLED; +			if (wValue == 0x0301) { +				len = min_t(unsigned int, +						leni, +						min_t(unsigned int, +						sizeof(root_hub_str_index1), +						wLength)); +				data_buf = root_hub_str_index1; +				OK(len); +		} +		default: +			stat = USB_ST_STALLED;  		}  		break;  	case RH_GET_DESCRIPTOR | RH_CLASS:  	{ -		__u32 temp = roothub_a (&gohci); +		__u32 temp = roothub_a(&gohci);  		data_buf [0] = 9;		/* min length; */  		data_buf [1] = 0x29; @@ -1363,13 +1429,13 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe  			data_buf [3] |= 0x1;  		if (temp & RH_A_NOCP)	/* no overcurrent reporting? */  			data_buf [3] |= 0x10; -		else if (temp & RH_A_OCPM)	/* per-port overcurrent reporting? */ +		else if (temp & RH_A_OCPM)/* per-port overcurrent reporting? */  			data_buf [3] |= 0x8;  		/* corresponds to data_buf[4-7] */  		datab [1] = 0;  		data_buf [5] = (temp & RH_A_POTPGT) >> 24; -		temp = roothub_b (&gohci); +		temp = roothub_b(&gohci);  		data_buf [7] = temp & RH_B_DR;  		if (data_buf [2] < 7) {  			data_buf [8] = 0xff; @@ -1381,32 +1447,33 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe  		len = min_t(unsigned int, leni,  			    min_t(unsigned int, data_buf [0], wLength)); -		OK (len); +		OK(len);  	} -	case RH_GET_CONFIGURATION:	*(__u8 *) data_buf = 0x01; OK (1); +	case RH_GET_CONFIGURATION:	*(__u8 *) data_buf = 0x01; OK(1); -	case RH_SET_CONFIGURATION:	WR_RH_STAT (0x10000); OK (0); +	case RH_SET_CONFIGURATION:	WR_RH_STAT(0x10000); OK(0);  	default: -		dbg ("unsupported root hub command"); +		dbg("unsupported root hub command");  		stat = USB_ST_STALLED;  	}  #ifdef	DEBUG -	ohci_dump_roothub (&gohci, 1); +	ohci_dump_roothub(&gohci, 1);  #else  	wait_ms(1);  #endif  	len = min_t(int, len, leni);  	if (data != data_buf) -	    memcpy (data, data_buf, len); +	    memcpy(data, data_buf, len);  	dev->act_len = len;  	dev->status = stat;  #ifdef DEBUG -	pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/); +	pkt_print(NULL, dev, pipe, buffer, +		  transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);  #else  	wait_ms(1);  #endif @@ -1443,7 +1510,8 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,  #ifdef DEBUG  	urb->actual_length = 0; -	pkt_print(urb, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); +	pkt_print(urb, dev, pipe, buffer, transfer_len, +		  setup, "SUB", usb_pipein(pipe));  #else  	wait_ms(1);  #endif @@ -1465,7 +1533,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,  	/* allow more time for a BULK device to react - some are slow */  #define BULK_TO	 5000	/* timeout in milliseconds */ -	if (usb_pipetype (pipe) == PIPE_BULK) +	if (usb_pipebulk(pipe))  		timeout = BULK_TO;  	else  		timeout = 100; @@ -1496,7 +1564,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,  		if (--timeout) {  			wait_ms(1);  			if (!urb->finished) -				dbg("\%"); +				dbg("*");  		} else {  			err("CTL:TIMEOUT "); @@ -1511,14 +1579,15 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,  	dev->act_len = transfer_len;  #ifdef DEBUG -	pkt_print(urb, dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe)); +	pkt_print(urb, dev, pipe, buffer, transfer_len, +		  setup, "RET(ctlr)", usb_pipein(pipe));  #else  	wait_ms(1);  #endif  	/* free TDs in urb_priv */ -	if (usb_pipetype (pipe) != PIPE_INTERRUPT) -		urb_free_priv (urb); +	if (!usb_pipeint(pipe)) +		urb_free_priv(urb);  	return 0;  } @@ -1537,7 +1606,8 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,  	info("submit_control_msg");  #ifdef DEBUG -	pkt_print(NULL, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); +	pkt_print(NULL, dev, pipe, buffer, transfer_len, +		  setup, "SUB", usb_pipein(pipe));  #else  	wait_ms(1);  #endif @@ -1570,18 +1640,46 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,  /* reset the HC and BUS */ -static int hc_reset (ohci_t *ohci) +static int hc_reset(ohci_t *ohci)  { +#ifdef CONFIG_PCI_EHCI_DEVNO +	pci_dev_t pdev; +#endif  	int timeout = 30;  	int smm_timeout = 50; /* 0,5 sec */  	dbg("%s\n", __FUNCTION__); -	if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ -		writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */ +#ifdef CONFIG_PCI_EHCI_DEVNO +	/* +	 *  Some multi-function controllers (e.g. ISP1562) allow root hub +	 * resetting via EHCI registers only. +	 */ +	pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVNO); +	if (pdev != -1) { +		u32 base; +		int timeout = 1000; + +		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base); +		writel(readl(base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET, +			base + EHCI_USBCMD_OFF); + +		while (readl(base + EHCI_USBCMD_OFF) & EHCI_USBCMD_HCRESET) { +			if (timeout-- <= 0) { +				printf("USB RootHub reset timed out!"); +				break; +			} +			udelay(1); +		} +	} else +		printf("No EHCI func at %d index!\n", CONFIG_PCI_EHCI_DEVNO); +#endif +	if (readl(&ohci->regs->control) & OHCI_CTRL_IR) { +		/* SMM owns the HC */ +		writel(OHCI_OCR, &ohci->regs->cmdstatus);/* request ownership */  		info("USB HC TakeOver from SMM"); -		while (readl (&ohci->regs->control) & OHCI_CTRL_IR) { -			wait_ms (10); +		while (readl(&ohci->regs->control) & OHCI_CTRL_IR) { +			wait_ms(10);  			if (--smm_timeout == 0) {  				err("USB HC TakeOver failed!");  				return -1; @@ -1590,7 +1688,7 @@ static int hc_reset (ohci_t *ohci)  	}  	/* Disable HC interrupts */ -	writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); +	writel(OHCI_INTR_MIE, &ohci->regs->intrdisable);  	dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;\n",  		ohci->slot_name, @@ -1598,16 +1696,16 @@ static int hc_reset (ohci_t *ohci)  	/* Reset USB (needed by some controllers) */  	ohci->hc_control = 0; -	writel (ohci->hc_control, &ohci->regs->control); +	writel(ohci->hc_control, &ohci->regs->control);  	/* HC Reset requires max 10 us delay */ -	writel (OHCI_HCR,  &ohci->regs->cmdstatus); -	while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { +	writel(OHCI_HCR,  &ohci->regs->cmdstatus); +	while ((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {  		if (--timeout == 0) {  			err("USB HC reset timed out!");  			return -1;  		} -		udelay (1); +		udelay(1);  	}  	return 0;  } @@ -1618,7 +1716,7 @@ static int hc_reset (ohci_t *ohci)   * enable interrupts   * connect the virtual root hub */ -static int hc_start (ohci_t * ohci) +static int hc_start(ohci_t *ohci)  {  	__u32 mask;  	unsigned int fminterval; @@ -1628,44 +1726,44 @@ static int hc_start (ohci_t * ohci)  	/* Tell the controller where the control and bulk lists are  	 * The lists are empty now. */ -	writel (0, &ohci->regs->ed_controlhead); -	writel (0, &ohci->regs->ed_bulkhead); +	writel(0, &ohci->regs->ed_controlhead); +	writel(0, &ohci->regs->ed_bulkhead); -	writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */ +	writel((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */  	fminterval = 0x2edf; -	writel ((fminterval * 9) / 10, &ohci->regs->periodicstart); +	writel((fminterval * 9) / 10, &ohci->regs->periodicstart);  	fminterval |= ((((fminterval - 210) * 6) / 7) << 16); -	writel (fminterval, &ohci->regs->fminterval); -	writel (0x628, &ohci->regs->lsthresh); +	writel(fminterval, &ohci->regs->fminterval); +	writel(0x628, &ohci->regs->lsthresh);  	/* start controller operations */  	ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;  	ohci->disabled = 0; -	writel (ohci->hc_control, &ohci->regs->control); +	writel(ohci->hc_control, &ohci->regs->control);  	/* disable all interrupts */  	mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |  			OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |  			OHCI_INTR_OC | OHCI_INTR_MIE); -	writel (mask, &ohci->regs->intrdisable); +	writel(mask, &ohci->regs->intrdisable);  	/* clear all interrupts */  	mask &= ~OHCI_INTR_MIE; -	writel (mask, &ohci->regs->intrstatus); +	writel(mask, &ohci->regs->intrstatus);  	/* Choose the interrupts we care about now  - but w/o MIE */  	mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; -	writel (mask, &ohci->regs->intrenable); +	writel(mask, &ohci->regs->intrenable);  #ifdef	OHCI_USE_NPS  	/* required for AMD-756 and some Mac platforms */ -	writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM, +	writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM,  		&ohci->regs->roothub.a); -	writel (RH_HS_LPSC, &ohci->regs->roothub.status); +	writel(RH_HS_LPSC, &ohci->regs->roothub.status);  #endif	/* OHCI_USE_NPS */ -#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);}) +#define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); })  	/* POTPGT delay is bits 24-31, in 2 ms units. */ -	mdelay ((roothub_a (ohci) >> 23) & 0x1fe); +	mdelay((roothub_a(ohci) >> 23) & 0x1fe);  	/* connect the virtual root hub */  	ohci->rh.devnum = 0; @@ -1683,7 +1781,7 @@ void usb_event_poll(void)  /* an interrupt happens */ -static int hc_interrupt (void) +static int hc_interrupt(void)  {  	ohci_t *ohci = &gohci;  	struct ohci_regs *regs = ohci->regs; @@ -1691,69 +1789,74 @@ static int hc_interrupt (void)  	int stat = -1;  	if ((ohci->hcca->done_head != 0) && -	    !(m32_swap (ohci->hcca->done_head) & 0x01)) { +				!(m32_swap(ohci->hcca->done_head) & 0x01)) {  		ints =  OHCI_INTR_WDH; -	} else if ((ints = readl (®s->intrstatus)) == ~(u32)0) { -		ohci->disabled++; -		err ("%s device removed!", ohci->slot_name); -		return -1; -	} else if ((ints &= readl (®s->intrenable)) == 0) { -		dbg("hc_interrupt: returning..\n"); -		return 0xff; +	} else { +		ints = readl(®s->intrstatus); +		if (ints == ~(u32)0) { +			ohci->disabled++; +			err("%s device removed!", ohci->slot_name); +			return -1; +		} else { +			ints &= readl(®s->intrenable); +			if (ints == 0) { +				dbg("hc_interrupt: returning..\n"); +				return 0xff; +			} +		}  	} -	/* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */ +	/* dbg("Interrupt: %x frame: %x", ints, +					le16_to_cpu(ohci->hcca->frame_no)); */ -	if (ints & OHCI_INTR_RHSC) { -		got_rhsc = 1; +	if (ints & OHCI_INTR_RHSC)  		stat = 0xff; -	}  	if (ints & OHCI_INTR_UE) {  		ohci->disabled++; -		err ("OHCI Unrecoverable Error, controller usb-%s disabled", +		err("OHCI Unrecoverable Error, controller usb-%s disabled",  			ohci->slot_name);  		/* e.g. due to PCI Master/Target Abort */  #ifdef	DEBUG -		ohci_dump (ohci, 1); +		ohci_dump(ohci, 1);  #else -	wait_ms(1); +		wait_ms(1);  #endif  		/* FIXME: be optimistic, hope that bug won't repeat often. */  		/* Make some non-interrupt context restart the controller. */  		/* Count and limit the retries though; either hardware or */  		/* software errors can go forever... */ -		hc_reset (ohci); +		hc_reset(ohci);  		return -1;  	}  	if (ints & OHCI_INTR_WDH) {  		wait_ms(1); -		writel (OHCI_INTR_WDH, ®s->intrdisable); -		(void)readl (®s->intrdisable); /* flush */ -		stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci)); -		writel (OHCI_INTR_WDH, ®s->intrenable); -		(void)readl (®s->intrdisable); /* flush */ +		writel(OHCI_INTR_WDH, ®s->intrdisable); +		(void)readl(®s->intrdisable); /* flush */ +		stat = dl_done_list(&gohci); +		writel(OHCI_INTR_WDH, ®s->intrenable); +		(void)readl(®s->intrdisable); /* flush */  	}  	if (ints & OHCI_INTR_SO) {  		dbg("USB Schedule overrun\n"); -		writel (OHCI_INTR_SO, ®s->intrenable); +		writel(OHCI_INTR_SO, ®s->intrenable);  		stat = -1;  	}  	/* FIXME:  this assumes SOF (1/ms) interrupts don't get lost... */  	if (ints & OHCI_INTR_SF) { -		unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1; +		unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1;  		wait_ms(1); -		writel (OHCI_INTR_SF, ®s->intrdisable); +		writel(OHCI_INTR_SF, ®s->intrdisable);  		if (ohci->ed_rm_list[frame] != NULL) -			writel (OHCI_INTR_SF, ®s->intrenable); +			writel(OHCI_INTR_SF, ®s->intrenable);  		stat = 0xff;  	} -	writel (ints, ®s->intrstatus); +	writel(ints, ®s->intrstatus);  	return stat;  } @@ -1763,12 +1866,12 @@ static int hc_interrupt (void)  /* De-allocate all resources.. */ -static void hc_release_ohci (ohci_t *ohci) +static void hc_release_ohci(ohci_t *ohci)  { -	dbg ("USB HC release ohci usb-%s", ohci->slot_name); +	dbg("USB HC release ohci usb-%s", ohci->slot_name);  	if (!ohci->disabled) -		hc_reset (ohci); +		hc_reset(ohci);  }  /*-------------------------------------------------------------------------*/ @@ -1784,18 +1887,18 @@ int usb_lowlevel_init(void)  	pci_dev_t pdev;  #endif -#ifdef CFG_USB_OHCI_CPU_INIT +#ifdef CONFIG_SYS_USB_OHCI_CPU_INIT  	/* cpu dependant init */ -	if(usb_cpu_init()) +	if (usb_cpu_init())  		return -1;  #endif -#ifdef CFG_USB_OHCI_BOARD_INIT +#ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT  	/*  board dependant init */ -	if(usb_board_init()) +	if (usb_board_init())  		return -1;  #endif -	memset (&gohci, 0, sizeof (ohci_t)); +	memset(&gohci, 0, sizeof(ohci_t));  	/* align the storage */  	if ((__u32)&ghcca[0] & 0xff) { @@ -1816,7 +1919,7 @@ int usb_lowlevel_init(void)  	}  	ptd = gtd;  	gohci.hcca = phcca; -	memset (phcca, 0, sizeof (struct ohci_hcca)); +	memset(phcca, 0, sizeof(struct ohci_hcca));  	gohci.disabled = 1;  	gohci.sleeping = 0; @@ -1838,40 +1941,37 @@ int usb_lowlevel_init(void)  	} else  		return -1;  #else -	gohci.regs = (struct ohci_regs *)CFG_USB_OHCI_REGS_BASE; +	gohci.regs = (struct ohci_regs *)CONFIG_SYS_USB_OHCI_REGS_BASE;  #endif  	gohci.flags = 0; -	gohci.slot_name = CFG_USB_OHCI_SLOT_NAME; +	gohci.slot_name = CONFIG_SYS_USB_OHCI_SLOT_NAME;  	if (hc_reset (&gohci) < 0) {  		hc_release_ohci (&gohci);  		err ("can't reset usb-%s", gohci.slot_name); -#ifdef CFG_USB_OHCI_BOARD_INIT +#ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT  		/* board dependant cleanup */  		usb_board_init_fail();  #endif -#ifdef CFG_USB_OHCI_CPU_INIT +#ifdef CONFIG_SYS_USB_OHCI_CPU_INIT  		/* cpu dependant cleanup */  		usb_cpu_init_fail();  #endif  		return -1;  	} -	/* FIXME this is a second HC reset; why?? */ -	/* writel(gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control); -	   wait_ms(10); */ -	if (hc_start (&gohci) < 0) { -		err ("can't start usb-%s", gohci.slot_name); -		hc_release_ohci (&gohci); +	if (hc_start(&gohci) < 0) { +		err("can't start usb-%s", gohci.slot_name); +		hc_release_ohci(&gohci);  		/* Initialization failed */ -#ifdef CFG_USB_OHCI_BOARD_INIT +#ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT  		/* board dependant cleanup */  		usb_board_stop();  #endif -#ifdef CFG_USB_OHCI_CPU_INIT +#ifdef CONFIG_SYS_USB_OHCI_CPU_INIT  		/* cpu dependant cleanup */  		usb_cpu_stop();  #endif @@ -1879,7 +1979,7 @@ int usb_lowlevel_init(void)  	}  #ifdef	DEBUG -	ohci_dump (&gohci, 1); +	ohci_dump(&gohci, 1);  #else  	wait_ms(1);  #endif @@ -1895,20 +1995,21 @@ int usb_lowlevel_stop(void)  		return 0;  	/* TODO release any interrupts, etc. */  	/* call hc_release_ohci() here ? */ -	hc_reset (&gohci); +	hc_reset(&gohci); -#ifdef CFG_USB_OHCI_BOARD_INIT +#ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT  	/* board dependant cleanup */ -	if(usb_board_stop()) +	if (usb_board_stop())  		return -1;  #endif -#ifdef CFG_USB_OHCI_CPU_INIT +#ifdef CONFIG_SYS_USB_OHCI_CPU_INIT  	/* cpu dependant cleanup */ -	if(usb_cpu_stop()) +	if (usb_cpu_stop())  		return -1;  #endif - +	/* This driver is no longer initialised. It needs a new low-level +	 * init (board/cpu) before it can be used again. */ +	ohci_inited = 0;  	return 0;  } -#endif /* CONFIG_USB_OHCI_NEW */ |