Konstantin, some comments:
1. You added some USB specific code to kdba_io_32.c, namely kdb_usb_fill_int_urb(), kdb_uhci_submit_urb(). Would it be better to put this USB code into the kernel uhci files (uhci-q.c, uhci-hcd.c or whatever) so kdb can remain unaware of USB specifics? Also, I think if you did it this way, then it would remove the need for the new interface routine kdb_usb_uhci_keyboard_attach(). You should be able to just call kdb_usb_keyboard_attach() after you create and submit the new URB from hid_probe(). Just add a new parameter to kdb_usb_keyboard_attach() for the complete_func and pass NULL for it for OHCI and EHCI. The USB infastructure is constantly being rewritten and structures/parameters changing around, so it would be best to keep those details over in the kernel and not in kdb IMO. 2. What is the limiting factor preventing multiple keyboards? Is it the use of the globals kdb_uhci_hid_qh and kdb_hid_event? Can this be fixed somehow? Can they be put into the per device kdb_usb_kbd_info struct maybe? 3. Why can't you use the HID URB? Locking? Using the HID URB seems to work fine for OHCI and EHCI. This is the reason that seems to cause so much complication in your code. Back in the 2.4 timeframe, Intel did a UHCI KDB implementation that used the HID URB. Perhaps it would be useful to dig up that old code and compare it? I can possibly pass that code on to you if you want... Also, does enqueing two URBs for the same device cause any problems (is it "legal")? 4. I think you'll need to add your new interfaces to kdba_io_64.c and arch/ia64/kdb/kdba_io.c. Otherwise, the USB modules will encounter link/build errors when they can't find kdb_usb_uhci_keyboard_attach() (and the other globals and such) on those builds/systems. It would be nice to have UHCI support on those archs too. 5. I already submitted another patch for EHCI support which will conflict with this one (kdba_io_32.c). Can you add your patch on top of that one? -Aaron > > On Wed, 7 Nov 2007 17:11:37 +0300 > Konstantin Baydarov <[EMAIL PROTECTED]> wrote: > > > On Mon, 5 Nov 2007 10:54:42 -0800 (PST) > > Aaron Young <[EMAIL PROTECTED]> wrote: > > > > > I've only dealt with OHCI driver code before, so I'm not qualified > > > to review the UHCI specific code for you. As you say, it looks like > > > a lot of your infastructure code introduces new globals > > > (kdb_hcd_type) and uses kdb_usb_infos a lot - which is going away > > > with my new implementation. > > > > > > Would it be possible for you to wait for my new kdb/usb > > > infastructure code and re-implement your UHCI code against it at > > > that time? I could attempt to take an in depth look at it at that > > > time perhaps... > > > > > > Thanks, > > > > > > -Aaron > > > > Yes I'll intergrate UCHI code to the new KDB. > > --------------------------- > > Use http://oss.sgi.com/ecartis to modify your settings or to > > unsubscribe. > > UCHI support integrated to kdb-v4.4-2.6.24-rc2. Tested on i386 UP PC. > > Changes in USB interface: > - kdb_usb_uhci_keyboard_attach() to manage UHCI Keyboards > - kdb_uhci_submit_urb() is called by kdb_usb_uhci_keyboard_attach(). UHCI > KDB doesn't use HID urb, special urb with same parameters is used. > - void (*kdb_completion)(struct urb *urb); was added to hc_driver structure > to allow KDB UHCI driver reactivate KDB queue head. > > Known Issues of KDB driver: > - Autoreply of pressed key doesn't work > - When kernel enters KDB first pressed key doesn't appear on KDB > console, because it's caught by UHCI kernel driver. > - Keyboard hotplug wasn't tested. > - Only 1 UHCI keyboard supported. > > Jay, it looks you are using spaces instead of tabs or your mail client > replaces tabs with spaces, now(after USB patches) we have mixed code style. I > think cleanup should be done. > > Signed-off-by: Konstantin Baydarov <[EMAIL PROTECTED]> > > Index: linux-2.6.24-rc2/drivers/usb/host/uhci-q.c > =================================================================== > --- linux-2.6.24-rc2.orig/drivers/usb/host/uhci-q.c > +++ linux-2.6.24-rc2/drivers/usb/host/uhci-q.c > @@ -25,6 +25,11 @@ > * games with the FSBR code to make sure we get the correct order in all > * the cases. I don't think it's worth the effort > */ > +#ifdef CONFIG_KDB_USB > +/* KDB HID QH, managed by KDB code */ > +static struct uhci_qh *kdb_uhci_hid_qh; > +#endif > + > static void uhci_set_next_interrupt(struct uhci_hcd *uhci) > { > if (uhci->is_stopped) > @@ -292,6 +297,58 @@ static struct uhci_qh *uhci_alloc_qh(str > return qh; > } > > +#ifdef CONFIG_KDB_USB > +/* > + * Same as uhci_alloc_qh execpt it doesn't change to hep->hcpriv > + */ > +static struct uhci_qh *kdb_uhci_alloc_qh(struct uhci_hcd *uhci, > + struct usb_device *udev, struct usb_host_endpoint *hep) > +{ > + dma_addr_t dma_handle; > + struct uhci_qh *qh; > + > + qh = dma_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle); > + if (!qh) > + return NULL; > + > + memset(qh, 0, sizeof(*qh)); > + qh->dma_handle = dma_handle; > + > + qh->element = UHCI_PTR_TERM; > + qh->link = UHCI_PTR_TERM; > + > + INIT_LIST_HEAD(&qh->queue); > + INIT_LIST_HEAD(&qh->node); > + > + if (udev) { /* Normal QH */ > + qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; > + if (qh->type != USB_ENDPOINT_XFER_ISOC) { > + qh->dummy_td = uhci_alloc_td(uhci); > + if (!qh->dummy_td) { > + dma_pool_free(uhci->qh_pool, qh, dma_handle); > + return NULL; > + } > + } > + qh->state = QH_STATE_IDLE; > + qh->hep = hep; > + qh->udev = udev; > + > + if (qh->type == USB_ENDPOINT_XFER_INT || > + qh->type == USB_ENDPOINT_XFER_ISOC) > + qh->load = usb_calc_bus_time(udev->speed, > + usb_endpoint_dir_in(&hep->desc), > + qh->type == USB_ENDPOINT_XFER_ISOC, > + le16_to_cpu(hep->desc.wMaxPacketSize)) > + / 1000 + 1; > + > + } else { /* Skeleton QH */ > + qh->state = QH_STATE_ACTIVE; > + qh->type = -1; > + } > + return qh; > +} > +#endif > + > static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) > { > WARN_ON(qh->state != QH_STATE_IDLE && qh->udev); > @@ -1399,6 +1456,20 @@ static int uhci_urb_enqueue(struct usb_h > if (!urbp) > goto done; > > +#ifdef CONFIG_KDB_USB > + /* Always allocate new QH for KDB URB. > + * KDB HQ will be managed by KDB poll code not by > + * UHCI HCD Driver. > + */ > + if (kdb_uhci_keyboard_urb(urb)){ > + /* KDB urb will be enqued only once */ > + kdb_uhci_hid_qh = NULL; > + qh = kdb_uhci_alloc_qh(uhci, urb->dev, urb->ep); > + if (!qh) > + goto err_no_qh; > + kdb_uhci_hid_qh = qh; > + } else > +#endif > if (urb->ep->hcpriv) > qh = urb->ep->hcpriv; > else { > @@ -1648,6 +1719,13 @@ static int uhci_advance_check(struct uhc > int ret = 1; > unsigned status; > > +#ifdef CONFIG_KDB_USB > + /* Don't manage KDB QH */ > + if (qh == kdb_uhci_hid_qh){ > + ret = 0; > + goto done; > + } > +#endif > if (qh->type == USB_ENDPOINT_XFER_ISOC) > goto done; > > @@ -1740,6 +1818,11 @@ rescan: > uhci->next_qh = list_entry(qh->node.next, > struct uhci_qh, node); > > +#ifdef CONFIG_KDB_USB > + /* Don't manage KDB QH */ > + if (qh == kdb_uhci_hid_qh) > + continue; > +#endif > if (uhci_advance_check(uhci, qh)) { > uhci_scan_qh(uhci, qh); > if (qh->state == QH_STATE_ACTIVE) { > @@ -1766,3 +1849,80 @@ rescan: > else > uhci_set_next_interrupt(uhci); > } > + > +#ifdef CONFIG_KDB_USB > +static int kdb_hid_event = 0; /* eq 1 when key was pressed/released */ > + > +/* > + * Activate KDB UHCI QH, called by KDB poll code. > + */ > +static void kdb_activate_uhci_qh(void) > +{ > + struct urb_priv *urbp; > + struct uhci_td *td; > + struct uhci_qh *qh = kdb_uhci_hid_qh; > + __le32 status, token; > + > + urbp = list_entry(qh->queue.next, struct urb_priv, node); > + > + list_for_each_entry(td, &urbp->td_list, list){ > + status = td->status; > + token = td->token; > + barrier(); > + /* Clear Status and ActLen */ > + status &= cpu_to_le32(0xff000000); > + /* Make TD Active */ > + status |= cpu_to_le32(TD_CTRL_ACTIVE); > + /* Clear TD Interrupt */ > + status &= cpu_to_le32(~TD_CTRL_IOC); > + /* Toggle Data Sycronization Bit */ > + if (token & cpu_to_le32(TD_TOKEN_TOGGLE)) > + token &= cpu_to_le32(~TD_TOKEN_TOGGLE); > + else > + token |= cpu_to_le32(TD_TOKEN_TOGGLE); > + > + td->token = token; > + td->status = status; > + barrier(); > + } > + /* Activate KDB UHCI Keyboard HID QH */ > + td = list_entry(urbp->td_list.next, struct uhci_td, list); > + qh->element = LINK_TO_TD(td); > + barrier(); > +} > + > +/* > + * Called when KDB finishes process key press/release event. > + */ > +static void > +kdb_uhci_urb_complete (struct urb *urb) > +{ > + if (!kdb_hid_event) > + return; > + > + /* Activate KDB TD */ > + kdb_activate_uhci_qh(); > + kdb_hid_event = 0; > +} > + > +/* > + * Check if state of KDB URB changed (key was pressed/released). > + */ > +static int uhci_check_kdb_uhci_qh(void) > +{ > + struct uhci_qh *qh = kdb_uhci_hid_qh; > + struct urb_priv *urbp = NULL; > + struct uhci_td *td; > + unsigned status; > + > + urbp = list_entry(qh->queue.next, struct urb_priv, node); > + td = list_entry(urbp->td_list.next, struct uhci_td, list); > + status = td_status(td); > + if (!(status & TD_CTRL_ACTIVE)){ > + /* We're okay, the queue has advanced */ > + kdb_hid_event = 1; > + return 0; > + } > + return -1; > +} > +#endif > Index: linux-2.6.24-rc2/drivers/hid/usbhid/hid-core.c > =================================================================== > --- linux-2.6.24-rc2.orig/drivers/hid/usbhid/hid-core.c > +++ linux-2.6.24-rc2/drivers/hid/usbhid/hid-core.c > @@ -1045,8 +1045,17 @@ static int hid_probe(struct usb_interfac > int ret; > struct usbhid_device *usbhid = hid->driver_data; > extern void * usb_hcd_get_kdb_poll_func(struct usb_device > *udev); > - ret = kdb_usb_keyboard_attach(usbhid->urbin, usbhid->inbuf, > - usb_hcd_get_kdb_poll_func(interface_to_usbdev(intf))); > + extern void * usb_hcd_get_kdb_completion_func(struct usb_device > *udev); > + extern int usb_hcd_check_uhci(struct usb_device *udev); > + > + if (usb_hcd_check_uhci(interface_to_usbdev(intf))) > + ret = kdb_usb_uhci_keyboard_attach(usbhid->urbin, > usbhid->bufsize, > + > usb_hcd_get_kdb_poll_func(interface_to_usbdev(intf)), > + > usb_hcd_get_kdb_completion_func(interface_to_usbdev(intf))); > + else > + ret = kdb_usb_keyboard_attach(usbhid->urbin, > usbhid->inbuf, > + > usb_hcd_get_kdb_poll_func(interface_to_usbdev(intf))); > + > > if (ret == -1) > printk(": FAILED to register keyboard (%s) " > Index: linux-2.6.24-rc2/include/linux/kdb.h > =================================================================== > --- linux-2.6.24-rc2.orig/include/linux/kdb.h > +++ linux-2.6.24-rc2/include/linux/kdb.h > @@ -143,9 +143,15 @@ extern void smp_kdb_stop(void); > > #include <linux/usb.h> > > +extern int kdb_uhci_keyboard_urb(struct urb *urb); > + > extern int kdb_usb_keyboard_attach(struct urb *urb, unsigned char *buffer, > void *poll_func); > extern int kdb_usb_keyboard_detach(struct urb *urb); > > +extern int > +kdb_usb_uhci_keyboard_attach(struct urb *urb, unsigned int usbhid_bufsize, > + void *poll_func, void *compl_func); > + > #endif /* CONFIG_KDB_USB */ > > static inline > Index: linux-2.6.24-rc2/drivers/usb/host/uhci-hcd.c > =================================================================== > --- linux-2.6.24-rc2.orig/drivers/usb/host/uhci-hcd.c > +++ linux-2.6.24-rc2/drivers/usb/host/uhci-hcd.c > @@ -50,6 +50,10 @@ > #include "uhci-hcd.h" > #include "pci-quirks.h" > > +#ifdef CONFIG_KDB_USB > +#include <linux/kdb.h> > +#endif > + > /* > * Version Information > */ > @@ -430,6 +434,17 @@ static irqreturn_t uhci_irq(struct usb_h > return IRQ_HANDLED; > } > > +#ifdef CONFIG_KDB_USB > +static int > +uhci_kdb_poll_char(struct urb *urb) > +{ > + if (!urb) /* can happen if no keyboard attached */ > + return -1; > + > + return uhci_check_kdb_uhci_qh(); > +} > +#endif > + > /* > * Store the current frame number in uhci->frame_number if the controller > * is runnning. Expand from 11 bits (of which we use only 10) to a > @@ -888,6 +903,10 @@ static const struct hc_driver uhci_drive > > .hub_status_data = uhci_hub_status_data, > .hub_control = uhci_hub_control, > +#ifdef CONFIG_KDB_USB > + .kdb_poll_char = uhci_kdb_poll_char, > + .kdb_completion = kdb_uhci_urb_complete, > +#endif > }; > > static const struct pci_device_id uhci_pci_ids[] = { { > Index: linux-2.6.24-rc2/arch/x86/kdb/kdba_io_32.c > =================================================================== > --- linux-2.6.24-rc2.orig/arch/x86/kdb/kdba_io_32.c > +++ linux-2.6.24-rc2/arch/x86/kdb/kdba_io_32.c > @@ -54,6 +54,93 @@ static unsigned char kdb_usb_keycode[256 > 150,158,159,128,136,177,178,176,142,152,173,140 > }; > > +/* Check if URB is managed by KDB code */ > +int kdb_uhci_keyboard_urb(struct urb *urb) > +{ > + int i; > + > + for (i = 0; i < KDB_USB_NUM_KEYBOARDS; i++) { > + if (kdb_usb_kbds[i].urb && kdb_usb_kbds[i].urb == urb) > + return 1; > + } > + return 0; > +} > +EXPORT_SYMBOL_GPL (kdb_uhci_keyboard_urb); > + > +/* Only 1 UHCI Keyboard supported */ > +static int kdb_uhci_hid_initialized = 0; > + > +static inline void kdb_usb_fill_int_urb (struct urb *urb, > + struct usb_device *dev, > + unsigned int pipe, > + void *transfer_buffer, > + int buffer_length, > + usb_complete_t complete_fn, > + void *context, > + int interval) > +{ > + urb->dev = dev; > + urb->pipe = pipe; > + urb->transfer_buffer = transfer_buffer; > + urb->transfer_buffer_length = buffer_length; > + urb->complete = complete_fn; > + urb->context = context; > + urb->interval = interval; > + urb->start_frame = -1; > +} > + > +static int kdb_uhci_submit_urb(int kbd_num, unsigned int usbhid_bufsize, > struct urb *hid_inurb) > +{ > + dma_addr_t uhci_inbuf_dma; > + > + /* Only 1 UHCI Keyboard supported */ > + if (kdb_uhci_hid_initialized) > + return 1; > + > + if (!(kdb_usb_kbds[kbd_num].buffer = > + usb_buffer_alloc(hid_inurb->dev, > + usbhid_bufsize, GFP_ATOMIC, > + &uhci_inbuf_dma))) > + goto out; > + > + if (!(kdb_usb_kbds[kbd_num].urb = > + usb_alloc_urb(0, GFP_KERNEL))) > + goto out; > + > + kdb_usb_fill_int_urb(kdb_usb_kbds[kbd_num].urb, > + hid_inurb->dev, > + hid_inurb->pipe, > + kdb_usb_kbds[kbd_num].buffer, > + hid_inurb->transfer_buffer_length, > + hid_inurb->complete, > + hid_inurb->context, > + hid_inurb->interval > + ); > + > + (kdb_usb_kbds[kbd_num].urb)->transfer_dma = uhci_inbuf_dma; > + (kdb_usb_kbds[kbd_num].urb)->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; > + > + if (usb_submit_urb(kdb_usb_kbds[kbd_num].urb, GFP_ATOMIC)) > + goto out; > + > + kdb_uhci_hid_initialized = 1; > +out: > + if (kdb_uhci_hid_initialized) > + return 0; > + > + /* Some Error Cleanup */ > + printk("KDB: Error, UHCI Keyboard HID won't work!\n"); > + if (kdb_usb_kbds[kbd_num].buffer) > + usb_buffer_free(hid_inurb->dev, > + usbhid_bufsize, kdb_usb_kbds[kbd_num].buffer, > + uhci_inbuf_dma); > + > + if (kdb_usb_kbds[kbd_num].urb) > + usb_free_urb(kdb_usb_kbds[kbd_num].urb); > + > + return -1; > +} > + > /* > * kdb_usb_keyboard_attach() > * Attach a USB keyboard to kdb. > @@ -78,6 +165,7 @@ kdb_usb_keyboard_attach(struct urb *urb, > kdb_usb_kbds[i].urb = urb; > kdb_usb_kbds[i].buffer = buffer; > kdb_usb_kbds[i].poll_func = poll_func; > + kdb_usb_kbds[i].urb_complete = NULL; > > rc = 0; /* success */ > > @@ -88,6 +176,44 @@ kdb_usb_keyboard_attach(struct urb *urb, > } > EXPORT_SYMBOL_GPL (kdb_usb_keyboard_attach); > > +int > +kdb_usb_uhci_keyboard_attach(struct urb *urb, unsigned int usbhid_bufsize, > + void *poll_func, void *compl_func) > +{ > + int i; > + int rc = -1; > + > + /* > + * Search through the array of KDB USB keyboards (kdb_usb_kbds) > + * looking for a free index. If found, assign the keyboard to > + * the array index. > + */ > + > + for (i = 0; i < KDB_USB_NUM_KEYBOARDS; i++) { > + if (kdb_usb_kbds[i].urb) /* index is already assigned */ > + continue; > + > + /* found a free array index */ > + if (!(kdb_uhci_submit_urb(i, usbhid_bufsize, urb))){ > + kdb_usb_kbds[i].poll_func = poll_func; > + kdb_usb_kbds[i].urb_complete = compl_func; > + } else { > + /* Cleanup */ > + kdb_usb_kbds[i].urb = NULL; > + kdb_usb_kbds[i].buffer = NULL; > + kdb_usb_kbds[i].poll_func = NULL; > + kdb_usb_kbds[i].urb_complete = NULL; > + } > + > + rc = 0; /* success */ > + > + break; > + } > + > + return rc; > +} > +EXPORT_SYMBOL_GPL (kdb_usb_uhci_keyboard_attach); > + > /* > * kdb_usb_keyboard_detach() > * Detach a USB keyboard from kdb. > @@ -135,6 +261,9 @@ get_usb_char(void) > int ret; > unsigned char keycode, spec; > extern u_short plain_map[], shift_map[], ctrl_map[]; > + int poll_ret, i2, j, max; > + > + ret = -1; > > /* > * Loop through all the USB keyboard(s) and return > @@ -148,20 +277,27 @@ get_usb_char(void) > continue; > > /* Transfer char */ > - ret = (*kdb_usb_kbds[i].poll_func)(kdb_usb_kbds[i].urb); > - if (ret == -1) /* error or no characters, try the next kbd */ > + poll_ret = (*kdb_usb_kbds[i].poll_func)(kdb_usb_kbds[i].urb); > + if (poll_ret == -1) /* error or no characters, try the next > kbd */ > continue; > > + /* If 2 keys was pressed simultaneously, > + * both keycodes will be in buffer. > + * Last pressed key will be last non > + * zero byte. > + */ > + for (j=0; j<4; j++){ > + if (!kdb_usb_kbds[i].buffer[2+j]) > + break; > + } > + /* Last pressed key */ > + max = j + 1; > + > spec = kdb_usb_kbds[i].buffer[0]; > - keycode = kdb_usb_kbds[i].buffer[2]; > + keycode = kdb_usb_kbds[i].buffer[max]; > kdb_usb_kbds[i].buffer[0] = (char)0; > kdb_usb_kbds[i].buffer[2] = (char)0; > > - if(kdb_usb_kbds[i].buffer[3]) { > - kdb_usb_kbds[i].buffer[3] = (char)0; > - continue; > - } > - > /* A normal key is pressed, decode it */ > if(keycode) > keycode = kdb_usb_keycode[keycode]; > @@ -172,10 +308,12 @@ get_usb_char(void) > { > case 0x2: > case 0x20: /* Shift */ > - return shift_map[keycode]; > + ret = shift_map[keycode]; > + break; > case 0x1: > case 0x10: /* Ctrl */ > - return ctrl_map[keycode]; > + ret = ctrl_map[keycode]; > + break; > case 0x4: > case 0x40: /* Alt */ > break; > @@ -184,31 +322,45 @@ get_usb_char(void) > switch(keycode) > { > case 0x1C: /* Enter */ > - return 13; > - > + ret = 13; > + break; > case 0x3A: /* Capslock */ > kdb_usb_kbds[i].caps_lock = > !(kdb_usb_kbds[i].caps_lock); > break; > case 0x0E: /* Backspace */ > - return 8; > + ret = 8; > + break; > case 0x0F: /* TAB */ > - return 9; > + ret = 9; > + break; > case 0x77: /* Pause */ > break ; > default: > if(!kdb_usb_kbds[i].caps_lock) { > - return plain_map[keycode]; > + ret = plain_map[keycode]; > + break; > } > else { > - return shift_map[keycode]; > + ret = shift_map[keycode]; > + break; > } > } > } > + /* Key was pressed, return keycode */ > + break; > } > > - /* no chars were returned from any of the USB keyboards */ > + for(i2=0; i2<8; i2++){ > + if (kdb_usb_kbds[i2].buffer) > + for(j=0; j<8; j++){ > + kdb_usb_kbds[i2].buffer[j] = (char)0; > + } > + } > + > + if (kdb_usb_kbds[i].urb_complete) > + (*kdb_usb_kbds[i].urb_complete)((struct urb > *)kdb_usb_kbds[i].urb); > > - return -1; > + return ret; > } > #endif /* CONFIG_KDB_USB */ > > Index: linux-2.6.24-rc2/include/linux/kdbprivate.h > =================================================================== > --- linux-2.6.24-rc2.orig/include/linux/kdbprivate.h > +++ linux-2.6.24-rc2/include/linux/kdbprivate.h > @@ -489,6 +489,7 @@ struct kdb_usb_kbd_info { > struct urb *urb; /* pointer to the URB */ > unsigned char *buffer; /* pointer to the kbd char buffer */ > int (*poll_func)(struct urb *urb); /* poll function to retrieve chars */ > + int (*urb_complete)(struct urb *urb); /* called when URB int is > processed */ > int caps_lock; /* state of the caps lock for this keyboard */ > }; > #endif /* CONFIG_KDB_USB */ > Index: linux-2.6.24-rc2/drivers/usb/core/hcd.c > =================================================================== > --- linux-2.6.24-rc2.orig/drivers/usb/core/hcd.c > +++ linux-2.6.24-rc2/drivers/usb/core/hcd.c > @@ -1851,6 +1851,32 @@ usb_hcd_get_kdb_poll_func(struct usb_dev > return NULL; > } > EXPORT_SYMBOL_GPL (usb_hcd_get_kdb_poll_func); > + > +void * > +usb_hcd_get_kdb_completion_func(struct usb_device *udev) > +{ > + struct usb_hcd *hcd = bus_to_hcd(udev->bus); > + > + if (hcd && hcd->driver) > + return (void *)(hcd->driver->kdb_completion); > + > + return NULL; > +} > +EXPORT_SYMBOL_GPL (usb_hcd_get_kdb_completion_func); > + > +int > +usb_hcd_check_uhci(struct usb_device *udev) > +{ > + struct usb_hcd *hcd = bus_to_hcd(udev->bus); > + > + if (hcd && hcd->driver){ > + if (!(strcmp(hcd->driver->description, "uhci_hcd"))) > + return 1; > + } > + > + return 0; > +} > +EXPORT_SYMBOL_GPL (usb_hcd_check_uhci); > #endif /* CONFIG_KDB_USB */ > > /*-------------------------------------------------------------------------*/ > Index: linux-2.6.24-rc2/drivers/usb/core/hcd.h > =================================================================== > --- linux-2.6.24-rc2.orig/drivers/usb/core/hcd.h > +++ linux-2.6.24-rc2/drivers/usb/core/hcd.h > @@ -213,6 +213,7 @@ struct hc_driver { > #ifdef CONFIG_KDB_USB > /* KDB poll function for this HC */ > int (*kdb_poll_char)(struct urb *urb); > + void (*kdb_completion)(struct urb *urb); > #endif /* CONFIG_KDB_USB */ > }; > > --------------------------- > Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe. > --------------------------- Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.
