patch-2.3.34 linux/drivers/usb/ohci-root-hub.c

Next file: linux/drivers/usb/ohci-root-hub.h
Previous file: linux/drivers/usb/ohci-hcd.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.33/linux/drivers/usb/ohci-root-hub.c linux/drivers/usb/ohci-root-hub.c
@@ -1,341 +0,0 @@
-/*
- * HCD (OHCI) Virtual Root Hub for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber (weissg@vienna.at)
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
- *	This program is distributed in the hope that it will be useful,
- *	but WITHOUT ANY WARRANTY; without even the implied warranty of
- *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *	GNU General Public License for more details.
- *
- *	You should have received a copy of the GNU General Public License
- *	along with this program; if not, write to the Free Software
- *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * 
- * The Root Hub is build into the HC (UHCI or OHCI) hardware. 
- * This piece of code lets it look like it resides on the usb
- * like the other hubs.
- * (for anyone who wants to do a control operation on the root hub)
- * 
- * v4.0 1999/08/18 
- * v2.1 1999/05/09 
- * v2.0 1999/05/04
- * v1.0 1999/04/27
- * ohci-root-hub.c
- *  
- */
- 
-
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
-
-#include "usb.h"
-#include "ohci-hcd.h" 
-
-#ifdef VROOTHUB 
-
-#include "ohci-root-hub.h"
-
-static __u8 root_hub_dev_des[] =
-{
-        0x12,       /*  __u8  bLength; */
-		0x01,       /*  __u8  bDescriptorType; Device */
-		0x00,	    /*  __u16 bcdUSB; v1.0 */
-        0x01,
-		0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
-		0x00,	    /*  __u8  bDeviceSubClass; */
-		0x00,       /*  __u8  bDeviceProtocol; */
-		0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
-		0x00,       /*  __u16 idVendor; */
-        0x00,
-		0x00,       /*  __u16 idProduct; */
-        0x00,
-		0x00,       /*  __u16 bcdDevice; */
-        0x00,
-		0x00,       /*  __u8  iManufacturer; */
-		0x00,       /*  __u8  iProduct; */
-		0x00,       /*  __u8  iSerialNumber; */
-        0x01        /*  __u8  bNumConfigurations; */
-};
-
-
-/* Configuration descriptor */
-static __u8 root_hub_config_des[] =
-{
-		0x09,       /*  __u8  bLength; */
-		0x02,       /*  __u8  bDescriptorType; Configuration */
-		0x19,       /*  __u16 wTotalLength; */
-        0x00,
-		0x01,       /*  __u8  bNumInterfaces; */
-		0x01,       /*  __u8  bConfigurationValue; */
-		0x00,       /*  __u8  iConfiguration; */
-		0x40,       /*  __u8  bmAttributes; 
-                 Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
-		0x00,       /*  __u8  MaxPower; */
-      
-     /* interface */	  
-        0x09,       /*  __u8  if_bLength; */
-        0x04,       /*  __u8  if_bDescriptorType; Interface */
-        0x00,       /*  __u8  if_bInterfaceNumber; */
-        0x00,       /*  __u8  if_bAlternateSetting; */
-        0x01,       /*  __u8  if_bNumEndpoints; */
-        0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
-        0x00,       /*  __u8  if_bInterfaceSubClass; */
-        0x00,       /*  __u8  if_bInterfaceProtocol; */
-        0x00,       /*  __u8  if_iInterface; */
-     
-     /* endpoint */
-        0x07,       /*  __u8  ep_bLength; */
-        0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
-        0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
-        0x03,       /*  __u8  ep_bmAttributes; Interrupt */
-        0x08,       /*  __u16 ep_wMaxPacketSize; 8 Bytes */
-        0x00,
-        0xff        /*  __u8  ep_bInterval; 255 ms */
-};
-
-/* 
-For OHCI we need just the  2nd Byte, so we 
-don't need this constant byte-array 
-
-static __u8 root_hub_hub_des[] =
-{ 
-        0x00,       *  __u8  bLength; *
-		0x29,       *  __u8  bDescriptorType; Hub-descriptor *
-        0x02,       *  __u8  bNbrPorts; *
-        0x00,       * __u16  wHubCharacteristics; *
-        0x00,
-        0x01,       *  __u8  bPwrOn2pwrGood; 2ms * 
-        0x00,       *  __u8  bHubContrCurrent; 0 mA *
-        0x00,       *  __u8  DeviceRemovable; *** 8 Ports max *** *
-        0xff        *  __u8  PortPwrCtrlMask; *** 8 ports max *** *
-};
-*/
-
-#define OK(x) 			len = (x); req_reply = 0; break
-#define WR_RH_STAT(x) 		writel((x), &ohci->regs->roothub.status)
-#define WR_RH_PORTSTAT(x) 	writel((x), &ohci->regs->roothub.portstatus[wIndex-1])
-#define RD_RH_STAT			readl(&ohci->regs->roothub.status)
-#define RD_RH_PORTSTAT		readl(&ohci->regs->roothub.portstatus[wIndex-1])
-
-int root_hub_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest * cmd, void *data, int leni)
-{ 
-	struct ohci * ohci = usb_dev->bus->hcpriv;
-	__u8 data_buf[16];
-	int req_reply=4;
- 
-	int len =leni;
-
-	__u16 bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
-	__u16 wValue        = cpu_to_le16(cmd->value);
-	__u16 wIndex        = cpu_to_le16(cmd->index);
-	__u16 wLength       = cpu_to_le16(cmd->length);
-
-	OHCI_DEBUG(printk("USB root hub: adr: %2x cmd(%1x): ", ohci->rh.devnum, 8);)
-	OHCI_DEBUG({ int i; for(i=0;i<8;i++) printk(" %02x", ((unsigned char *)cmd)[i]);})
-	OHCI_DEBUG(printk(" ; \n");)
- 
-	switch (bmRType_bReq) {
-	/* Request Destination:
-	   without flags: Device, 
-	   RH_INTERFACE: interface, 
-	   RH_ENDPOINT: endpoint,
-	   RH_CLASS means HUB here, 
-	   RH_OTHER | RH_CLASS  almost ever means HUB_PORT here 
-	*/
-  
-		case RH_GET_STATUS: 				 		*(__u16 *)data = cpu_to_le16(1); OK(2);
-		case RH_GET_STATUS | RH_INTERFACE: 	 		*(__u16 *)data = cpu_to_le16(0); OK(2);
-		case RH_GET_STATUS | RH_ENDPOINT:	 		*(__u16 *)data = cpu_to_le16(0); OK(2);   
-		case RH_GET_STATUS | RH_CLASS: 				*(__u32 *)data = cpu_to_le32(RD_RH_STAT & 0x7fff7fff); OK(4);
-		case RH_GET_STATUS | RH_OTHER | RH_CLASS: 	*(__u32 *)data = cpu_to_le32(RD_RH_PORTSTAT); OK(4);
-
-		case RH_CLEAR_FEATURE | RH_ENDPOINT:  
-			switch (wValue) {
-				case (RH_ENDPOINT_STALL): OK(0);
-			}
-			break;
-
-		case RH_CLEAR_FEATURE | RH_CLASS:
-			switch (wValue) {
-				case (RH_C_HUB_OVER_CURRENT): WR_RH_STAT(RH_PS_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); 
-			}
-			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): if((RD_RH_PORTSTAT &1) != 0)  WR_RH_PORTSTAT(RH_PS_PRS ); /* BUG IN HUP CODE *********/ OK(0);
-				case (RH_PORT_POWER):			WR_RH_PORTSTAT(RH_PS_PPS ); OK(0); 
-				case (RH_PORT_ENABLE):			WR_RH_PORTSTAT(RH_PS_PES ); OK(0);
-			}
-			break;
-
-		case RH_SET_ADDRESS: ohci->rh.devnum = wValue; OK(0);
-
-		case RH_GET_DESCRIPTOR:
-			switch ((wValue & 0xff00) >> 8) {
-				case (0x01): /* device descriptor */
-					len = min(leni, min(sizeof(root_hub_dev_des), wLength));
-					memcpy(data, root_hub_dev_des, len); OK(len);
-				case (0x02): /* configuration descriptor */
-					len = min(leni, min(sizeof(root_hub_config_des), wLength));
-					memcpy(data, root_hub_config_des, len); OK(len);
-				case (0x03): /* string descriptors */
-				default: OK(-4);
-			}
-			break;
-		
-		case RH_GET_DESCRIPTOR | RH_CLASS:
-			*(__u8 *)(data_buf+1) = 0x29;
-			*(__u32 *)(data_buf+2) = cpu_to_le32(readl(&ohci->regs->roothub.a));  
-	 		*(__u8 *)data_buf = (*(__u8 *)(data_buf+2) / 8) * 2 + 9; /* length of descriptor */
-				 
-			len = min(leni, min(*(__u8 *)data_buf, wLength));
-			*(__u8 *)(data_buf+6) = 0; /* Root Hub needs no current from bus */
-			if(*(__u8 *)(data_buf+2) < 8) { /* less than 8 Ports */
-				*(__u8 *) (data_buf+7) = readl(&ohci->regs->roothub.b) & 0xff; 
-				*(__u8 *) (data_buf+8) = (readl(&ohci->regs->roothub.b) & 0xff0000) >> 16; 
-			}
-			else {
-				*(__u32 *) (data_buf+7) = cpu_to_le32(readl(&ohci->regs->roothub.b)); 
-			}
-			memcpy(data, data_buf, len);
-			OK(len); 
- 
-		case RH_GET_CONFIGURATION: 	*(__u8 *)data = 0x01; OK(1);
-
-		case RH_SET_CONFIGURATION: 	WR_RH_STAT( 0x10000); OK(0);
-
-		default: OK(-4);
-	}
-	
-	OHCI_DEBUG(printk("USB HC roothubstat1: %x \n", readl( &(ohci->regs->roothub.portstatus[0]) ));)
-	OHCI_DEBUG(printk("USB HC roothubstat2: %x \n", readl( &(ohci->regs->roothub.portstatus[1]) ));)
-  		
-	
-	return len;
-}
-
-/* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */ 
-static int root_hub_send_irq(struct ohci * ohci, void * rh_data, int rh_len ) {
-
-  int num_ports;
-  int i;
-  int ret;
-  int len;
-
-  __u8 * data = rh_data;
-
-  num_ports = readl(&ohci->regs->roothub.a) & 0xff; 
-  *(__u8 *)data = (readl(&ohci->regs->roothub.status) & 0x00030000)>0?1:0;
-  ret = *(__u8 *)data;
-
-  for(i=0; i < num_ports; i++) {
-    *(__u8 *)(data+i/8) |= ((readl(&ohci->regs->roothub.portstatus[i]) & 0x001f0000)>0?1:0) << ((i+1) % 8);
-    ret += *(__u8 *)(data+i/8);
-  }
-  len = i/8 + 1;
-  
-  if (ret > 0) return len;
-
-  return  RH_NACK;
-}
-
- 
-static int ohci_init_rh_int_timer(struct usb_device * usb_dev, int interval);
-
-/* Virtual Root Hub INTs are polled by this timer every "intervall" ms */
-static void rh_int_timer_do(unsigned long ptr) {
-	int len; 
-	int interval;
-	int ret;
-	
-	struct usb_device * usb_dev = (struct usb_device *) ptr;
-    struct ohci * ohci = usb_dev->bus->hcpriv;
-	struct ohci_device * dev = usb_to_ohci(usb_dev);
-
-
-	if(ohci->rh.send) { 
-		len = root_hub_send_irq(ohci, dev->data, 1 );
-
-		if(len > 0) { 
-			
-			ret = ohci->rh.handler(0, dev->data, len, ohci->rh.dev_id);
-			if(ret <= 0)ohci->rh.send = 0; /* 0 .. do not requeue  */
-		}
-	}	
-	interval = ohci->rh.interval;
-	ohci_init_rh_int_timer(usb_dev, interval);
-}
-
-/* Root Hub INTs are polled by this timer */
-static int ohci_init_rh_int_timer(struct usb_device * usb_dev, int interval) {
-	struct ohci * ohci = usb_dev->bus->hcpriv;
-
-	ohci->rh.interval = interval;
-	init_timer(& ohci->rh.rh_int_timer);
-	ohci->rh.rh_int_timer.function = rh_int_timer_do;
-	ohci->rh.rh_int_timer.data = (unsigned long) usb_dev;
-	ohci->rh.rh_int_timer.expires = jiffies + (HZ * (interval<30?30: interval)) /1000;
-	add_timer(&ohci->rh.rh_int_timer);
-	
-	return 0;
-}
-
-static int ohci_del_rh_int_timer(struct ohci * ohci) {
-	del_timer(&ohci->rh.rh_int_timer);
-	return 0;
-}
- 
-int root_hub_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id, void **handle)
-{
-	struct ohci * ohci = usb_dev->bus->hcpriv;
-	
-	OHCI_DEBUG( printk("USB HC-RH IRQ>>>: RH every %d ms\n", period);) 
-	ohci->rh.handler = handler;
-	ohci->rh.dev_id =  dev_id;
-	ohci->rh.send = 1;
-	ohci->rh.interval = period;
-	ohci_init_rh_int_timer(usb_dev, period);
-	*handle = ohci->rh.int_addr = usb_to_ohci(usb_dev);
-	return 0;
-}
-
-int root_hub_release_irq(struct usb_device *usb_dev, void * ed) 
-{
-	// struct usb_device *usb_dev = ((struct ohci_device *) ((unsigned int)ed & 0xfffff000))->usb;
-	struct ohci * ohci = usb_dev->bus->hcpriv;
-
-	OHCI_DEBUG( printk("USB HC-RH RM_IRQ>>>:\n");) 
-	ohci->rh.send = 0;
-	ohci_del_rh_int_timer(ohci);
-	return 0;
-}
-
-
- 
-#endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)