]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.xen/xen3-x86-usb-debug-port-early-console-v4.patch
Add a patch to fix Intel E100 wake-on-lan problems.
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.xen / xen3-x86-usb-debug-port-early-console-v4.patch
1 From 5c05917e7fe313a187ad6ebb94c1c6cf42862a0b Mon Sep 17 00:00:00 2001
2 From: Yinghai Lu <yhlu.kernel@gmail.com>
3 Date: Thu, 24 Jul 2008 17:29:40 -0700
4 Subject: x86: usb debug port early console, v4
5 Patch-mainline: 2.6.28
6
7 From: Yinghai Lu <yhlu.kernel@gmail.com>
8
9 commit 5c05917e7fe313a187ad6ebb94c1c6cf42862a0b upstream.
10
11 based on work from Eric, and add some timeout so don't dead loop when debug
12 device is not installed
13
14 v2: fix checkpatch warning
15 v3: move ehci struct def to linux/usrb/ehci_def.h from host/ehci.h
16 also add CONFIG_EARLY_PRINTK_DBGP to disable it by default
17 v4: address comments from Ingo, seperate ehci reg def moving to another patch
18 also add auto detect port that connect to debug device for Nvidia
19 southbridge
20
21 Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
22 Cc: Andrew Morton <akpm@linux-foundation.org>
23 Cc: Andi Kleen <andi@firstfloor.org>
24 Cc: "Arjan van de Ven" <arjan@infradead.org>
25 Cc: "Eric W. Biederman" <ebiederm@xmission.com>
26 Cc: "Greg KH" <greg@kroah.com>
27 Signed-off-by: Ingo Molnar <mingo@elte.hu>
28 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
29
30 Automatically created from "patches.suse/x86-usb-debug-port-early-console-v4.patch" by xen-port-patches.py
31
32 --- head-2009-02-02.orig/arch/x86/kernel/early_printk-xen.c 2008-12-15 11:28:15.000000000 +0100
33 +++ head-2009-02-02/arch/x86/kernel/early_printk-xen.c 2009-02-02 10:17:33.000000000 +0100
34 @@ -3,10 +3,18 @@
35 #include <linux/init.h>
36 #include <linux/string.h>
37 #include <linux/screen_info.h>
38 +#include <linux/usb/ch9.h>
39 +#include <linux/pci_regs.h>
40 +#include <linux/pci_ids.h>
41 +#include <linux/errno.h>
42 #include <asm/io.h>
43 #include <asm/processor.h>
44 #include <asm/fcntl.h>
45 #include <asm/setup.h>
46 +#include <asm/pci-direct.h>
47 +#include <asm/pgtable.h>
48 +#include <asm/fixmap.h>
49 +#include <linux/usb/ehci_def.h>
50
51 /* Simple VGA output */
52 #define VGABASE (__ISA_IO_base + 0xb8000)
53 @@ -78,6 +86,7 @@ static int early_serial_base = 0x3f8; /
54 static int early_serial_putc(unsigned char ch)
55 {
56 unsigned timeout = 0xffff;
57 +
58 while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
59 cpu_relax();
60 outb(ch, early_serial_base + TXR);
61 @@ -180,6 +189,721 @@ static struct console early_serial_conso
62 .index = -1,
63 };
64
65 +#ifdef CONFIG_EARLY_PRINTK_DBGP
66 +
67 +static struct ehci_caps __iomem *ehci_caps;
68 +static struct ehci_regs __iomem *ehci_regs;
69 +static struct ehci_dbg_port __iomem *ehci_debug;
70 +static unsigned int dbgp_endpoint_out;
71 +
72 +struct ehci_dev {
73 + u32 bus;
74 + u32 slot;
75 + u32 func;
76 +};
77 +
78 +static struct ehci_dev ehci_dev;
79 +
80 +#define USB_DEBUG_DEVNUM 127
81 +
82 +#define DBGP_DATA_TOGGLE 0x8800
83 +
84 +static inline u32 dbgp_pid_update(u32 x, u32 tok)
85 +{
86 + return ((x ^ DBGP_DATA_TOGGLE) & 0xffff00) | (tok & 0xff);
87 +}
88 +
89 +static inline u32 dbgp_len_update(u32 x, u32 len)
90 +{
91 + return (x & ~0x0f) | (len & 0x0f);
92 +}
93 +
94 +/*
95 + * USB Packet IDs (PIDs)
96 + */
97 +
98 +/* token */
99 +#define USB_PID_OUT 0xe1
100 +#define USB_PID_IN 0x69
101 +#define USB_PID_SOF 0xa5
102 +#define USB_PID_SETUP 0x2d
103 +/* handshake */
104 +#define USB_PID_ACK 0xd2
105 +#define USB_PID_NAK 0x5a
106 +#define USB_PID_STALL 0x1e
107 +#define USB_PID_NYET 0x96
108 +/* data */
109 +#define USB_PID_DATA0 0xc3
110 +#define USB_PID_DATA1 0x4b
111 +#define USB_PID_DATA2 0x87
112 +#define USB_PID_MDATA 0x0f
113 +/* Special */
114 +#define USB_PID_PREAMBLE 0x3c
115 +#define USB_PID_ERR 0x3c
116 +#define USB_PID_SPLIT 0x78
117 +#define USB_PID_PING 0xb4
118 +#define USB_PID_UNDEF_0 0xf0
119 +
120 +#define USB_PID_DATA_TOGGLE 0x88
121 +#define DBGP_CLAIM (DBGP_OWNER | DBGP_ENABLED | DBGP_INUSE)
122 +
123 +#define PCI_CAP_ID_EHCI_DEBUG 0xa
124 +
125 +#define HUB_ROOT_RESET_TIME 50 /* times are in msec */
126 +#define HUB_SHORT_RESET_TIME 10
127 +#define HUB_LONG_RESET_TIME 200
128 +#define HUB_RESET_TIMEOUT 500
129 +
130 +#define DBGP_MAX_PACKET 8
131 +
132 +static int dbgp_wait_until_complete(void)
133 +{
134 + u32 ctrl;
135 + int loop = 0x100000;
136 +
137 + do {
138 + ctrl = readl(&ehci_debug->control);
139 + /* Stop when the transaction is finished */
140 + if (ctrl & DBGP_DONE)
141 + break;
142 + } while (--loop > 0);
143 +
144 + if (!loop)
145 + return -1;
146 +
147 + /*
148 + * Now that we have observed the completed transaction,
149 + * clear the done bit.
150 + */
151 + writel(ctrl | DBGP_DONE, &ehci_debug->control);
152 + return (ctrl & DBGP_ERROR) ? -DBGP_ERRCODE(ctrl) : DBGP_LEN(ctrl);
153 +}
154 +
155 +static void dbgp_mdelay(int ms)
156 +{
157 + int i;
158 +
159 + while (ms--) {
160 + for (i = 0; i < 1000; i++)
161 + outb(0x1, 0x80);
162 + }
163 +}
164 +
165 +static void dbgp_breath(void)
166 +{
167 + /* Sleep to give the debug port a chance to breathe */
168 +}
169 +
170 +static int dbgp_wait_until_done(unsigned ctrl)
171 +{
172 + u32 pids, lpid;
173 + int ret;
174 + int loop = 3;
175 +
176 +retry:
177 + writel(ctrl | DBGP_GO, &ehci_debug->control);
178 + ret = dbgp_wait_until_complete();
179 + pids = readl(&ehci_debug->pids);
180 + lpid = DBGP_PID_GET(pids);
181 +
182 + if (ret < 0)
183 + return ret;
184 +
185 + /*
186 + * If the port is getting full or it has dropped data
187 + * start pacing ourselves, not necessary but it's friendly.
188 + */
189 + if ((lpid == USB_PID_NAK) || (lpid == USB_PID_NYET))
190 + dbgp_breath();
191 +
192 + /* If I get a NACK reissue the transmission */
193 + if (lpid == USB_PID_NAK) {
194 + if (--loop > 0)
195 + goto retry;
196 + }
197 +
198 + return ret;
199 +}
200 +
201 +static void dbgp_set_data(const void *buf, int size)
202 +{
203 + const unsigned char *bytes = buf;
204 + u32 lo, hi;
205 + int i;
206 +
207 + lo = hi = 0;
208 + for (i = 0; i < 4 && i < size; i++)
209 + lo |= bytes[i] << (8*i);
210 + for (; i < 8 && i < size; i++)
211 + hi |= bytes[i] << (8*(i - 4));
212 + writel(lo, &ehci_debug->data03);
213 + writel(hi, &ehci_debug->data47);
214 +}
215 +
216 +static void dbgp_get_data(void *buf, int size)
217 +{
218 + unsigned char *bytes = buf;
219 + u32 lo, hi;
220 + int i;
221 +
222 + lo = readl(&ehci_debug->data03);
223 + hi = readl(&ehci_debug->data47);
224 + for (i = 0; i < 4 && i < size; i++)
225 + bytes[i] = (lo >> (8*i)) & 0xff;
226 + for (; i < 8 && i < size; i++)
227 + bytes[i] = (hi >> (8*(i - 4))) & 0xff;
228 +}
229 +
230 +static int dbgp_bulk_write(unsigned devnum, unsigned endpoint,
231 + const char *bytes, int size)
232 +{
233 + u32 pids, addr, ctrl;
234 + int ret;
235 +
236 + if (size > DBGP_MAX_PACKET)
237 + return -1;
238 +
239 + addr = DBGP_EPADDR(devnum, endpoint);
240 +
241 + pids = readl(&ehci_debug->pids);
242 + pids = dbgp_pid_update(pids, USB_PID_OUT);
243 +
244 + ctrl = readl(&ehci_debug->control);
245 + ctrl = dbgp_len_update(ctrl, size);
246 + ctrl |= DBGP_OUT;
247 + ctrl |= DBGP_GO;
248 +
249 + dbgp_set_data(bytes, size);
250 + writel(addr, &ehci_debug->address);
251 + writel(pids, &ehci_debug->pids);
252 +
253 + ret = dbgp_wait_until_done(ctrl);
254 + if (ret < 0)
255 + return ret;
256 +
257 + return ret;
258 +}
259 +
260 +static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
261 + int size)
262 +{
263 + u32 pids, addr, ctrl;
264 + int ret;
265 +
266 + if (size > DBGP_MAX_PACKET)
267 + return -1;
268 +
269 + addr = DBGP_EPADDR(devnum, endpoint);
270 +
271 + pids = readl(&ehci_debug->pids);
272 + pids = dbgp_pid_update(pids, USB_PID_IN);
273 +
274 + ctrl = readl(&ehci_debug->control);
275 + ctrl = dbgp_len_update(ctrl, size);
276 + ctrl &= ~DBGP_OUT;
277 + ctrl |= DBGP_GO;
278 +
279 + writel(addr, &ehci_debug->address);
280 + writel(pids, &ehci_debug->pids);
281 + ret = dbgp_wait_until_done(ctrl);
282 + if (ret < 0)
283 + return ret;
284 +
285 + if (size > ret)
286 + size = ret;
287 + dbgp_get_data(data, size);
288 + return ret;
289 +}
290 +
291 +static int dbgp_control_msg(unsigned devnum, int requesttype, int request,
292 + int value, int index, void *data, int size)
293 +{
294 + u32 pids, addr, ctrl;
295 + struct usb_ctrlrequest req;
296 + int read;
297 + int ret;
298 +
299 + read = (requesttype & USB_DIR_IN) != 0;
300 + if (size > (read ? DBGP_MAX_PACKET:0))
301 + return -1;
302 +
303 + /* Compute the control message */
304 + req.bRequestType = requesttype;
305 + req.bRequest = request;
306 + req.wValue = value;
307 + req.wIndex = index;
308 + req.wLength = size;
309 +
310 + pids = DBGP_PID_SET(USB_PID_DATA0, USB_PID_SETUP);
311 + addr = DBGP_EPADDR(devnum, 0);
312 +
313 + ctrl = readl(&ehci_debug->control);
314 + ctrl = dbgp_len_update(ctrl, sizeof(req));
315 + ctrl |= DBGP_OUT;
316 + ctrl |= DBGP_GO;
317 +
318 + /* Send the setup message */
319 + dbgp_set_data(&req, sizeof(req));
320 + writel(addr, &ehci_debug->address);
321 + writel(pids, &ehci_debug->pids);
322 + ret = dbgp_wait_until_done(ctrl);
323 + if (ret < 0)
324 + return ret;
325 +
326 + /* Read the result */
327 + return dbgp_bulk_read(devnum, 0, data, size);
328 +}
329 +
330 +
331 +/* Find a PCI capability */
332 +static u32 __init find_cap(u32 num, u32 slot, u32 func, int cap)
333 +{
334 + u8 pos;
335 + int bytes;
336 +
337 + if (!(read_pci_config_16(num, slot, func, PCI_STATUS) &
338 + PCI_STATUS_CAP_LIST))
339 + return 0;
340 +
341 + pos = read_pci_config_byte(num, slot, func, PCI_CAPABILITY_LIST);
342 + for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
343 + u8 id;
344 +
345 + pos &= ~3;
346 + id = read_pci_config_byte(num, slot, func, pos+PCI_CAP_LIST_ID);
347 + if (id == 0xff)
348 + break;
349 + if (id == cap)
350 + return pos;
351 +
352 + pos = read_pci_config_byte(num, slot, func,
353 + pos+PCI_CAP_LIST_NEXT);
354 + }
355 + return 0;
356 +}
357 +
358 +static u32 __init __find_dbgp(u32 bus, u32 slot, u32 func)
359 +{
360 + u32 class;
361 +
362 + class = read_pci_config(bus, slot, func, PCI_CLASS_REVISION);
363 + if ((class >> 8) != PCI_CLASS_SERIAL_USB_EHCI)
364 + return 0;
365 +
366 + return find_cap(bus, slot, func, PCI_CAP_ID_EHCI_DEBUG);
367 +}
368 +
369 +static u32 __init find_dbgp(int ehci_num, u32 *rbus, u32 *rslot, u32 *rfunc)
370 +{
371 + u32 bus, slot, func;
372 +
373 + for (bus = 0; bus < 256; bus++) {
374 + for (slot = 0; slot < 32; slot++) {
375 + for (func = 0; func < 8; func++) {
376 + unsigned cap;
377 +
378 + cap = __find_dbgp(bus, slot, func);
379 +
380 + if (!cap)
381 + continue;
382 + if (ehci_num-- != 0)
383 + continue;
384 + *rbus = bus;
385 + *rslot = slot;
386 + *rfunc = func;
387 + return cap;
388 + }
389 + }
390 + }
391 + return 0;
392 +}
393 +
394 +static int ehci_reset_port(int port)
395 +{
396 + u32 portsc;
397 + u32 delay_time, delay;
398 + int loop;
399 +
400 + /* Reset the usb debug port */
401 + portsc = readl(&ehci_regs->port_status[port - 1]);
402 + portsc &= ~PORT_PE;
403 + portsc |= PORT_RESET;
404 + writel(portsc, &ehci_regs->port_status[port - 1]);
405 +
406 + delay = HUB_ROOT_RESET_TIME;
407 + for (delay_time = 0; delay_time < HUB_RESET_TIMEOUT;
408 + delay_time += delay) {
409 + dbgp_mdelay(delay);
410 +
411 + portsc = readl(&ehci_regs->port_status[port - 1]);
412 + if (portsc & PORT_RESET) {
413 + /* force reset to complete */
414 + loop = 2;
415 + writel(portsc & ~(PORT_RWC_BITS | PORT_RESET),
416 + &ehci_regs->port_status[port - 1]);
417 + do {
418 + portsc = readl(&ehci_regs->port_status[port-1]);
419 + } while ((portsc & PORT_RESET) && (--loop > 0));
420 + }
421 +
422 + /* Device went away? */
423 + if (!(portsc & PORT_CONNECT))
424 + return -ENOTCONN;
425 +
426 + /* bomb out completely if something weird happend */
427 + if ((portsc & PORT_CSC))
428 + return -EINVAL;
429 +
430 + /* If we've finished resetting, then break out of the loop */
431 + if (!(portsc & PORT_RESET) && (portsc & PORT_PE))
432 + return 0;
433 + }
434 + return -EBUSY;
435 +}
436 +
437 +static int ehci_wait_for_port(int port)
438 +{
439 + u32 status;
440 + int ret, reps;
441 +
442 + for (reps = 0; reps < 3; reps++) {
443 + dbgp_mdelay(100);
444 + status = readl(&ehci_regs->status);
445 + if (status & STS_PCD) {
446 + ret = ehci_reset_port(port);
447 + if (ret == 0)
448 + return 0;
449 + }
450 + }
451 + return -ENOTCONN;
452 +}
453 +
454 +#ifdef DBGP_DEBUG
455 +# define dbgp_printk early_printk
456 +#else
457 +static inline void dbgp_printk(const char *fmt, ...) { }
458 +#endif
459 +
460 +typedef void (*set_debug_port_t)(int port);
461 +
462 +static void default_set_debug_port(int port)
463 +{
464 +}
465 +
466 +static set_debug_port_t set_debug_port = default_set_debug_port;
467 +
468 +static void nvidia_set_debug_port(int port)
469 +{
470 + u32 dword;
471 + dword = read_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func,
472 + 0x74);
473 + dword &= ~(0x0f<<12);
474 + dword |= ((port & 0x0f)<<12);
475 + write_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func, 0x74,
476 + dword);
477 + dbgp_printk("set debug port to %d\n", port);
478 +}
479 +
480 +static void __init detect_set_debug_port(void)
481 +{
482 + u32 vendorid;
483 +
484 + vendorid = read_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func,
485 + 0x00);
486 +
487 + if ((vendorid & 0xffff) == 0x10de) {
488 + dbgp_printk("using nvidia set_debug_port\n");
489 + set_debug_port = nvidia_set_debug_port;
490 + }
491 +}
492 +
493 +static int __init ehci_setup(void)
494 +{
495 + struct usb_debug_descriptor dbgp_desc;
496 + u32 cmd, ctrl, status, portsc, hcs_params;
497 + u32 debug_port, new_debug_port = 0, n_ports;
498 + u32 devnum;
499 + int ret, i;
500 + int loop;
501 + int port_map_tried;
502 + int playtimes = 3;
503 +
504 +try_next_time:
505 + port_map_tried = 0;
506 +
507 +try_next_port:
508 +
509 + hcs_params = readl(&ehci_caps->hcs_params);
510 + debug_port = HCS_DEBUG_PORT(hcs_params);
511 + n_ports = HCS_N_PORTS(hcs_params);
512 +
513 + dbgp_printk("debug_port: %d\n", debug_port);
514 + dbgp_printk("n_ports: %d\n", n_ports);
515 +
516 + for (i = 1; i <= n_ports; i++) {
517 + portsc = readl(&ehci_regs->port_status[i-1]);
518 + dbgp_printk("portstatus%d: %08x\n", i, portsc);
519 + }
520 +
521 + if (port_map_tried && (new_debug_port != debug_port)) {
522 + if (--playtimes) {
523 + set_debug_port(new_debug_port);
524 + goto try_next_time;
525 + }
526 + return -1;
527 + }
528 +
529 + loop = 10;
530 + /* Reset the EHCI controller */
531 + cmd = readl(&ehci_regs->command);
532 + cmd |= CMD_RESET;
533 + writel(cmd, &ehci_regs->command);
534 + do {
535 + cmd = readl(&ehci_regs->command);
536 + } while ((cmd & CMD_RESET) && (--loop > 0));
537 +
538 + if (!loop) {
539 + dbgp_printk("can not reset ehci\n");
540 + return -1;
541 + }
542 + dbgp_printk("ehci reset done\n");
543 +
544 + /* Claim ownership, but do not enable yet */
545 + ctrl = readl(&ehci_debug->control);
546 + ctrl |= DBGP_OWNER;
547 + ctrl &= ~(DBGP_ENABLED | DBGP_INUSE);
548 + writel(ctrl, &ehci_debug->control);
549 +
550 + /* Start the ehci running */
551 + cmd = readl(&ehci_regs->command);
552 + cmd &= ~(CMD_LRESET | CMD_IAAD | CMD_PSE | CMD_ASE | CMD_RESET);
553 + cmd |= CMD_RUN;
554 + writel(cmd, &ehci_regs->command);
555 +
556 + /* Ensure everything is routed to the EHCI */
557 + writel(FLAG_CF, &ehci_regs->configured_flag);
558 +
559 + /* Wait until the controller is no longer halted */
560 + loop = 10;
561 + do {
562 + status = readl(&ehci_regs->status);
563 + } while ((status & STS_HALT) && (--loop > 0));
564 +
565 + if (!loop) {
566 + dbgp_printk("ehci can be started\n");
567 + return -1;
568 + }
569 + dbgp_printk("ehci started\n");
570 +
571 + /* Wait for a device to show up in the debug port */
572 + ret = ehci_wait_for_port(debug_port);
573 + if (ret < 0) {
574 + dbgp_printk("No device found in debug port\n");
575 + goto next_debug_port;
576 + }
577 + dbgp_printk("ehci wait for port done\n");
578 +
579 + /* Enable the debug port */
580 + ctrl = readl(&ehci_debug->control);
581 + ctrl |= DBGP_CLAIM;
582 + writel(ctrl, &ehci_debug->control);
583 + ctrl = readl(&ehci_debug->control);
584 + if ((ctrl & DBGP_CLAIM) != DBGP_CLAIM) {
585 + dbgp_printk("No device in debug port\n");
586 + writel(ctrl & ~DBGP_CLAIM, &ehci_debug->control);
587 + goto err;
588 + }
589 + dbgp_printk("debug ported enabled\n");
590 +
591 + /* Completely transfer the debug device to the debug controller */
592 + portsc = readl(&ehci_regs->port_status[debug_port - 1]);
593 + portsc &= ~PORT_PE;
594 + writel(portsc, &ehci_regs->port_status[debug_port - 1]);
595 +
596 + dbgp_mdelay(100);
597 +
598 + /* Find the debug device and make it device number 127 */
599 + for (devnum = 0; devnum <= 127; devnum++) {
600 + ret = dbgp_control_msg(devnum,
601 + USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
602 + USB_REQ_GET_DESCRIPTOR, (USB_DT_DEBUG << 8), 0,
603 + &dbgp_desc, sizeof(dbgp_desc));
604 + if (ret > 0)
605 + break;
606 + }
607 + if (devnum > 127) {
608 + dbgp_printk("Could not find attached debug device\n");
609 + goto err;
610 + }
611 + if (ret < 0) {
612 + dbgp_printk("Attached device is not a debug device\n");
613 + goto err;
614 + }
615 + dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint;
616 +
617 + /* Move the device to 127 if it isn't already there */
618 + if (devnum != USB_DEBUG_DEVNUM) {
619 + ret = dbgp_control_msg(devnum,
620 + USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
621 + USB_REQ_SET_ADDRESS, USB_DEBUG_DEVNUM, 0, NULL, 0);
622 + if (ret < 0) {
623 + dbgp_printk("Could not move attached device to %d\n",
624 + USB_DEBUG_DEVNUM);
625 + goto err;
626 + }
627 + devnum = USB_DEBUG_DEVNUM;
628 + dbgp_printk("debug device renamed to 127\n");
629 + }
630 +
631 + /* Enable the debug interface */
632 + ret = dbgp_control_msg(USB_DEBUG_DEVNUM,
633 + USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
634 + USB_REQ_SET_FEATURE, USB_DEVICE_DEBUG_MODE, 0, NULL, 0);
635 + if (ret < 0) {
636 + dbgp_printk(" Could not enable the debug device\n");
637 + goto err;
638 + }
639 + dbgp_printk("debug interface enabled\n");
640 +
641 + /* Perform a small write to get the even/odd data state in sync
642 + */
643 + ret = dbgp_bulk_write(USB_DEBUG_DEVNUM, dbgp_endpoint_out, " ", 1);
644 + if (ret < 0) {
645 + dbgp_printk("dbgp_bulk_write failed: %d\n", ret);
646 + goto err;
647 + }
648 + dbgp_printk("small write doned\n");
649 +
650 + return 0;
651 +err:
652 + /* Things didn't work so remove my claim */
653 + ctrl = readl(&ehci_debug->control);
654 + ctrl &= ~(DBGP_CLAIM | DBGP_OUT);
655 + writel(ctrl, &ehci_debug->control);
656 + return -1;
657 +
658 +next_debug_port:
659 + port_map_tried |= (1<<(debug_port - 1));
660 + new_debug_port = ((debug_port-1+1)%n_ports) + 1;
661 + if (port_map_tried != ((1<<n_ports) - 1)) {
662 + set_debug_port(new_debug_port);
663 + goto try_next_port;
664 + }
665 + if (--playtimes) {
666 + set_debug_port(new_debug_port);
667 + goto try_next_time;
668 + }
669 +
670 + return -1;
671 +}
672 +
673 +static int __init early_dbgp_init(char *s)
674 +{
675 + u32 debug_port, bar, offset;
676 + u32 bus, slot, func, cap;
677 + void __iomem *ehci_bar;
678 + u32 dbgp_num;
679 + u32 bar_val;
680 + char *e;
681 + int ret;
682 + u8 byte;
683 +
684 + if (!early_pci_allowed())
685 + return -1;
686 +
687 + dbgp_num = 0;
688 + if (*s)
689 + dbgp_num = simple_strtoul(s, &e, 10);
690 + dbgp_printk("dbgp_num: %d\n", dbgp_num);
691 +
692 + cap = find_dbgp(dbgp_num, &bus, &slot, &func);
693 + if (!cap)
694 + return -1;
695 +
696 + dbgp_printk("Found EHCI debug port on %02x:%02x.%1x\n", bus, slot,
697 + func);
698 +
699 + debug_port = read_pci_config(bus, slot, func, cap);
700 + bar = (debug_port >> 29) & 0x7;
701 + bar = (bar * 4) + 0xc;
702 + offset = (debug_port >> 16) & 0xfff;
703 + dbgp_printk("bar: %02x offset: %03x\n", bar, offset);
704 + if (bar != PCI_BASE_ADDRESS_0) {
705 + dbgp_printk("only debug ports on bar 1 handled.\n");
706 +
707 + return -1;
708 + }
709 +
710 + bar_val = read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
711 + dbgp_printk("bar_val: %02x offset: %03x\n", bar_val, offset);
712 + if (bar_val & ~PCI_BASE_ADDRESS_MEM_MASK) {
713 + dbgp_printk("only simple 32bit mmio bars supported\n");
714 +
715 + return -1;
716 + }
717 +
718 + /* double check if the mem space is enabled */
719 + byte = read_pci_config_byte(bus, slot, func, 0x04);
720 + if (!(byte & 0x2)) {
721 + byte |= 0x02;
722 + write_pci_config_byte(bus, slot, func, 0x04, byte);
723 + dbgp_printk("mmio for ehci enabled\n");
724 + }
725 +
726 + /*
727 + * FIXME I don't have the bar size so just guess PAGE_SIZE is more
728 + * than enough. 1K is the biggest I have seen.
729 + */
730 + set_fixmap_nocache(FIX_DBGP_BASE, bar_val & PAGE_MASK);
731 + ehci_bar = (void __iomem *)__fix_to_virt(FIX_DBGP_BASE);
732 + ehci_bar += bar_val & ~PAGE_MASK;
733 + dbgp_printk("ehci_bar: %p\n", ehci_bar);
734 +
735 + ehci_caps = ehci_bar;
736 + ehci_regs = ehci_bar + HC_LENGTH(readl(&ehci_caps->hc_capbase));
737 + ehci_debug = ehci_bar + offset;
738 + ehci_dev.bus = bus;
739 + ehci_dev.slot = slot;
740 + ehci_dev.func = func;
741 +
742 + detect_set_debug_port();
743 +
744 + ret = ehci_setup();
745 + if (ret < 0) {
746 + dbgp_printk("ehci_setup failed\n");
747 + ehci_debug = 0;
748 +
749 + return -1;
750 + }
751 +
752 + return 0;
753 +}
754 +
755 +static void early_dbgp_write(struct console *con, const char *str, u32 n)
756 +{
757 + int chunk, ret;
758 +
759 + if (!ehci_debug)
760 + return;
761 + while (n > 0) {
762 + chunk = n;
763 + if (chunk > DBGP_MAX_PACKET)
764 + chunk = DBGP_MAX_PACKET;
765 + ret = dbgp_bulk_write(USB_DEBUG_DEVNUM,
766 + dbgp_endpoint_out, str, chunk);
767 + str += chunk;
768 + n -= chunk;
769 + }
770 +}
771 +
772 +static struct console early_dbgp_console = {
773 + .name = "earlydbg",
774 + .write = early_dbgp_write,
775 + .flags = CON_PRINTBUFFER,
776 + .index = -1,
777 +};
778 +#endif
779 +
780 /* Console interface to a host file on AMD's SimNow! */
781
782 static int simnow_fd;
783 @@ -194,6 +918,7 @@ enum {
784 static noinline long simnow(long cmd, long a, long b, long c)
785 {
786 long ret;
787 +
788 asm volatile("cpuid" :
789 "=a" (ret) :
790 "b" (a), "c" (b), "d" (c), "0" (MAGIC1), "D" (cmd + MAGIC2));
791 @@ -203,6 +928,7 @@ static noinline long simnow(long cmd, lo
792 static void __init simnow_init(char *str)
793 {
794 char *fn = "klog";
795 +
796 if (*str == '=')
797 fn = ++str;
798 /* error ignored */
799 @@ -237,10 +963,11 @@ asmlinkage void early_printk(const char
800 va_end(ap);
801 }
802
803 -static int __initdata keep_early;
804
805 static int __init setup_early_printk(char *buf)
806 {
807 + int keep_early;
808 +
809 if (!buf)
810 return 0;
811
812 @@ -248,8 +975,7 @@ static int __init setup_early_printk(cha
813 return 0;
814 early_console_initialized = 1;
815
816 - if (strstr(buf, "keep"))
817 - keep_early = 1;
818 + keep_early = (strstr(buf, "keep") != NULL);
819
820 if (!strncmp(buf, "serial", 6)) {
821 early_serial_init(buf + 6);
822 @@ -269,6 +995,17 @@ static int __init setup_early_printk(cha
823 simnow_init(buf + 6);
824 early_console = &simnow_console;
825 keep_early = 1;
826 +#ifdef CONFIG_EARLY_PRINTK_DBGP
827 + } else if (!strncmp(buf, "dbgp", 4)) {
828 + if (early_dbgp_init(buf+4) < 0)
829 + return 0;
830 + early_console = &early_dbgp_console;
831 + /*
832 + * usb subsys will reset ehci controller, so don't keep
833 + * that early console
834 + */
835 + keep_early = 0;
836 +#endif
837 #ifdef CONFIG_XEN
838 } else if (!strncmp(buf, "xen", 3)) {
839 early_console = &xenboot_console;
840 @@ -282,4 +1019,23 @@ static int __init setup_early_printk(cha
841 register_console(early_console);
842 return 0;
843 }
844 +
845 +void __init enable_debug_console(char *buf)
846 +{
847 +#ifdef DBGP_DEBUG
848 + struct console *old_early_console = NULL;
849 +
850 + if (early_console_initialized && early_console) {
851 + old_early_console = early_console;
852 + unregister_console(early_console);
853 + early_console_initialized = 0;
854 + }
855 +
856 + setup_early_printk(buf);
857 +
858 + if (early_console == old_early_console && old_early_console)
859 + register_console(old_early_console);
860 +#endif
861 +}
862 +
863 early_param("earlyprintk", setup_early_printk);