Oliver Neukum wrote: > Am Dienstag, 26. Juni 2007 schrieb Jüri Reitel: > >> Hello. >> How to correctly turn off the port power of usb hub (assuming hub >> supports individual port power switching). Correctly means that all >> drivers using the device on that port are notified before the power is >> removed. Removed device could also be a usb hub. >> > > You'd have to use the code paths usbfs uses for disconnecting via+ioctl. > Thank you for fast replay
Looked into drivers/usb/core/devio.c functions usbdev_ioctl proc_ioctl_default proc_ioctl USBDEVFS_DISCONNECT branch calls usb_driver_release_interface As i can understand i should obtain list of all interfaces registered to the port that i want to turn of the power and then call usbdev ioctl drivers/usb/core/hub.c has function void usb_disconnect(struct usb_device **pdev) I exported usb_disconnect function and use it in my own driver where i get struct usb_device * hub, because i know bus topology static int set_usb_port_power_state(struct usb_device *hub, int port, int new_state) { int ret; if (new_state) { ret = set_usb_hub_port_feature(hub, port, USB_PORT_FEAT_POWER); } else { //notify also children device drivers if (port > 0 && port <= USB_MAXCHILDREN && hub->children[port - 1]) { usb_disconnect(&hub->children[port - 1]); } ret = clear_usb_hub_port_feature(hub, port, USB_PORT_FEAT_POWER); } return ret; } hub is obtained with usb_get_dev and later put with usb_put_dev First tests have been successful, with usb to usb hub and with root hub althoug i had to change some files in usb/host/ The most hardest part to me is to understand the needed locks before calling kernel functions Following patch is only tested with NEC uPD720101 usb 2.0 Host controller, this patch allows port power switching on nec root hub diff -ruN linux-2.6.18/drivers/usb/host/ehci-hub.c linux-2.6.18-modified/drivers/usb/host/ehci-hub.c --- linux-2.6.18/drivers/usb/host/ehci-hub.c 2006-09-20 06:42:06.000000000 +0300 +++ linux-2.6.18-modified/drivers/usb/host/ehci-hub.c 2006-11-30 13:12:01.000000000 +0200 @@ -344,7 +344,7 @@ goto error; wIndex--; temp = readl (&ehci->regs->port_status [wIndex]); - if (temp & PORT_OWNER) + if ((temp & PORT_OWNER) && wValue != USB_PORT_FEAT_POWER) break; switch (wValue) { @@ -510,7 +510,7 @@ goto error; wIndex--; temp = readl (&ehci->regs->port_status [wIndex]); - if (temp & PORT_OWNER) + if ((temp & PORT_OWNER) && wValue != USB_PORT_FEAT_POWER) break; temp &= ~PORT_RWC_BITS; diff -ruN linux-2.6.18/drivers/usb/host/ohci-hcd.c linux-2.6.18-modified/drivers/usb/host/ohci-hcd.c --- linux-2.6.18/drivers/usb/host/ohci-hcd.c 2006-09-20 06:42:06.000000000 +0300 +++ linux-2.6.18-modified/drivers/usb/host/ohci-hcd.c 2006-11-30 13:05:27.000000000 +0200 @@ -666,6 +666,11 @@ temp |= RH_A_NPS; ohci_writel (ohci, temp, &ohci->regs->roothub.a); } + + temp &= ~(RH_A_NPS | RH_A_NOCP); + temp |= RH_A_PSM | RH_A_OCPM; + ohci_writel (ohci, temp, &ohci->regs->roothub.a); + ohci_writel (ohci, RH_HS_LPSC, &ohci->regs->roothub.status); ohci_writel (ohci, (temp & RH_A_NPS) ? 0 : RH_B_PPCM, &ohci->regs->roothub.b); diff -ruN linux-2.6.18/drivers/usb/host/ohci-hub.c linux-2.6.18-modified/drivers/usb/host/ohci-hub.c --- linux-2.6.18/drivers/usb/host/ohci-hub.c 2006-09-20 06:42:06.000000000 +0300 +++ linux-2.6.18-modified/drivers/usb/host/ohci-hub.c 2006-11-30 13:16:25.000000000 +0200 @@ -559,6 +559,9 @@ break; case USB_PORT_FEAT_POWER: temp = RH_PS_LSDA; + ohci_writel (ohci, temp, &ohci->regs->roothub.portstatus[wIndex]); + ohci_readl (ohci, &ohci->regs->roothub.portstatus[wIndex]); + temp = RH_PS_CSC | RH_PS_PESC; break; case USB_PORT_FEAT_C_CONNECTION: temp = RH_PS_CSC; JR ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel