aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2009-08-20 16:39:54 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:38 -0400
commit8d053c79f22462f55c02c8083580730b922cf7b4 (patch)
tree2b29c3219fec7cb622af6ffba69c8eb21650c662 /drivers/usb
parent917778267fbe67703ab7d5c6f0b7a05d4c3df485 (diff)
USB: ehci-dbgp,ehci: Allow early or late use of the dbgp device
If the EHCI debug port is initialized and in use, the EHCI host controller driver must follow two rules. 1) If the EHCI host driver issues a controller reset, the debug controller driver re-initialization must get called after the reset is completed. 2) The EHCI host driver should ignore any requests to the physical EHCI debug port when the EHCI debug port is in use. The code to check for the debug port was moved from ehci_pci_reinit() to ehci_pci_setup because it must get called prior to ehci_reset() which will clear the debug port registers. Signed-off-by: Jason Wessel <jason.wessel@windriver.com> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: dbrownell@users.sourceforge.net Cc: Ingo Molnar <mingo@elte.hu> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Yinghai Lu <yinghai@kernel.org> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/early/ehci-dbgp.c23
-rw-r--r--drivers/usb/host/ehci-hcd.c8
-rw-r--r--drivers/usb/host/ehci-hub.c10
-rw-r--r--drivers/usb/host/ehci-pci.c39
4 files changed, 60 insertions, 20 deletions
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c
index 06e05ea17871..b88cb65b64e0 100644
--- a/drivers/usb/early/ehci-dbgp.c
+++ b/drivers/usb/early/ehci-dbgp.c
@@ -933,3 +933,26 @@ struct console early_dbgp_console = {
933 .flags = CON_PRINTBUFFER, 933 .flags = CON_PRINTBUFFER,
934 .index = -1, 934 .index = -1,
935}; 935};
936
937int dbgp_reset_prep(void)
938{
939 u32 ctrl;
940
941 dbgp_not_safe = 1;
942 if (!ehci_debug)
943 return 0;
944
945 if (early_dbgp_console.index != -1 &&
946 !(early_dbgp_console.flags & CON_BOOT))
947 return 1;
948 /* This means the console is not initialized, or should get
949 * shutdown so as to allow for reuse of the usb device, which
950 * means it is time to shutdown the usb debug port. */
951 ctrl = readl(&ehci_debug->control);
952 if (ctrl & DBGP_ENABLED) {
953 ctrl &= ~(DBGP_CLAIM);
954 writel(ctrl, &ehci_debug->control);
955 }
956 return 0;
957}
958EXPORT_SYMBOL_GPL(dbgp_reset_prep);
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 4f89d7ffd53a..9835e0713943 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -240,6 +240,11 @@ static int ehci_reset (struct ehci_hcd *ehci)
240 int retval; 240 int retval;
241 u32 command = ehci_readl(ehci, &ehci->regs->command); 241 u32 command = ehci_readl(ehci, &ehci->regs->command);
242 242
243 /* If the EHCI debug controller is active, special care must be
244 * taken before and after a host controller reset */
245 if (ehci->debug && !dbgp_reset_prep())
246 ehci->debug = NULL;
247
243 command |= CMD_RESET; 248 command |= CMD_RESET;
244 dbg_cmd (ehci, "reset", command); 249 dbg_cmd (ehci, "reset", command);
245 ehci_writel(ehci, command, &ehci->regs->command); 250 ehci_writel(ehci, command, &ehci->regs->command);
@@ -260,6 +265,9 @@ static int ehci_reset (struct ehci_hcd *ehci)
260 if (ehci_is_TDI(ehci)) 265 if (ehci_is_TDI(ehci))
261 tdi_reset (ehci); 266 tdi_reset (ehci);
262 267
268 if (ehci->debug)
269 dbgp_external_startup();
270
263 return retval; 271 return retval;
264} 272}
265 273
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 818647c33da8..6b5e4d18d4bf 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -855,6 +855,15 @@ static int ehci_hub_control (
855 case SetPortFeature: 855 case SetPortFeature:
856 selector = wIndex >> 8; 856 selector = wIndex >> 8;
857 wIndex &= 0xff; 857 wIndex &= 0xff;
858 if (unlikely(ehci->debug)) {
859 /* If the debug port is active any port
860 * feature requests should get denied */
861 if (wIndex == HCS_DEBUG_PORT(ehci->hcs_params) &&
862 (readl(&ehci->debug->control) & DBGP_ENABLED)) {
863 retval = -ENODEV;
864 goto error_exit;
865 }
866 }
858 if (!wIndex || wIndex > ports) 867 if (!wIndex || wIndex > ports)
859 goto error; 868 goto error;
860 wIndex--; 869 wIndex--;
@@ -951,6 +960,7 @@ error:
951 /* "stall" on error */ 960 /* "stall" on error */
952 retval = -EPIPE; 961 retval = -EPIPE;
953 } 962 }
963error_exit:
954 spin_unlock_irqrestore (&ehci->lock, flags); 964 spin_unlock_irqrestore (&ehci->lock, flags);
955 return retval; 965 return retval;
956} 966}
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index a88ad517ec5c..378861b9d79a 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -27,28 +27,8 @@
27/* called after powerup, by probe or system-pm "wakeup" */ 27/* called after powerup, by probe or system-pm "wakeup" */
28static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) 28static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
29{ 29{
30 u32 temp;
31 int retval; 30 int retval;
32 31
33 /* optional debug port, normally in the first BAR */
34 temp = pci_find_capability(pdev, 0x0a);
35 if (temp) {
36 pci_read_config_dword(pdev, temp, &temp);
37 temp >>= 16;
38 if ((temp & (3 << 13)) == (1 << 13)) {
39 temp &= 0x1fff;
40 ehci->debug = ehci_to_hcd(ehci)->regs + temp;
41 temp = ehci_readl(ehci, &ehci->debug->control);
42 ehci_info(ehci, "debug port %d%s\n",
43 HCS_DEBUG_PORT(ehci->hcs_params),
44 (temp & DBGP_ENABLED)
45 ? " IN USE"
46 : "");
47 if (!(temp & DBGP_ENABLED))
48 ehci->debug = NULL;
49 }
50 }
51
52 /* we expect static quirk code to handle the "extended capabilities" 32 /* we expect static quirk code to handle the "extended capabilities"
53 * (currently just BIOS handoff) allowed starting with EHCI 0.96 33 * (currently just BIOS handoff) allowed starting with EHCI 0.96
54 */ 34 */
@@ -195,6 +175,25 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
195 break; 175 break;
196 } 176 }
197 177
178 /* optional debug port, normally in the first BAR */
179 temp = pci_find_capability(pdev, 0x0a);
180 if (temp) {
181 pci_read_config_dword(pdev, temp, &temp);
182 temp >>= 16;
183 if ((temp & (3 << 13)) == (1 << 13)) {
184 temp &= 0x1fff;
185 ehci->debug = ehci_to_hcd(ehci)->regs + temp;
186 temp = ehci_readl(ehci, &ehci->debug->control);
187 ehci_info(ehci, "debug port %d%s\n",
188 HCS_DEBUG_PORT(ehci->hcs_params),
189 (temp & DBGP_ENABLED)
190 ? " IN USE"
191 : "");
192 if (!(temp & DBGP_ENABLED))
193 ehci->debug = NULL;
194 }
195 }
196
198 ehci_reset(ehci); 197 ehci_reset(ehci);
199 198
200 /* at least the Genesys GL880S needs fixup here */ 199 /* at least the Genesys GL880S needs fixup here */