1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2003, Niels S. Reedijk 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 22 #include "usb_p.h" 23 24 Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum ) 25 : Device ( bus , parent , desc , devicenum ) 26 { 27 dprintf( "USB Hub is being initialised\n" ); 28 m_initok = false; // We're not yet ready! 29 size_t actual_length; 30 31 32 if( m_device_descriptor.device_subclass != 0 || m_device_descriptor.device_protocol != 0 ) 33 { 34 dprintf( "USB Hub: wrong class/subclass/protocol! Bailing out\n" ); 35 return; 36 } 37 38 if ( m_current_configuration->number_interfaces > 1 ) 39 { 40 dprintf( "USB Hub: too much interfaces! Bailing out\n" ); 41 return; 42 } 43 44 dprintf( "USB Hub this: %p" , this ); 45 46 if ( GetDescriptor( USB_DESCRIPTOR_INTERFACE , 0 , 47 (void *)&m_interrupt_interface , 48 sizeof (usb_interface_descriptor) ) != sizeof( usb_interface_descriptor ) ) 49 { 50 dprintf( "USB Hub: error getting the interrupt interface! Bailing out.\n" ); 51 return; 52 } 53 54 if ( m_interrupt_interface.num_endpoints > 1 ) 55 { 56 dprintf( "USB Hub: too much endpoints! Bailing out.\n" ); 57 return; 58 } 59 60 if ( GetDescriptor( USB_DESCRIPTOR_ENDPOINT , 0 , 61 (void *)&m_interrupt_endpoint , 62 sizeof (usb_endpoint_descriptor) ) != sizeof (usb_endpoint_descriptor ) ) 63 { 64 dprintf( "USB Hub: Error getting the endpoint. Bailing out\n" ); 65 return; 66 } 67 68 if ( m_interrupt_endpoint.attributes != 0x03 ) //interrupt transfer 69 { 70 dprintf( "USB Hub: Not an interrupt endpoint. Bailing out\n" ); 71 return; 72 } 73 74 dprintf( "USB Hub: Getting hub descriptor...\n" ); 75 if ( GetDescriptor( USB_DESCRIPTOR_HUB , 0 , 76 (void *)&m_hub_descriptor , 77 sizeof (usb_hub_descriptor) ) != sizeof (usb_hub_descriptor ) ) 78 { 79 dprintf( "USB Hub: Error getting hub descriptor\n" ); 80 return; 81 } 82 83 // Enable port power on all ports 84 for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ ) 85 m_bus->SendRequest( this , USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT , 86 USB_REQUEST_SET_FEATURE , 87 PORT_POWER , 88 i + 1 , //index 89 0 , 90 NULL , 91 0 , 92 &actual_length ); 93 //Wait for power to stabilize 94 snooze( m_hub_descriptor.bPwrOn2PwrGood * 2 ); 95 96 //We're basically done now 97 m_initok = true; 98 } 99 100 void Hub::Explore() 101 { 102 size_t actual_length; 103 104 for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ ) 105 { 106 // Get the current port status 107 m_bus->SendRequest( this , USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN , 108 USB_REQUEST_GET_STATUS , 109 0 , //Value 110 i + 1 , //Index 111 4 , //length 112 (void *)&m_port_status[i], 113 4 , 114 &actual_length ); 115 if ( actual_length < 4 ) 116 { 117 dprintf( "USB Hub: ERROR getting port status" ); 118 return; 119 } 120 121 //We need to test the port change against a number of things 122 if ( m_port_status[i].change & PORT_STATUS_CONNECTION ) 123 { 124 if ( m_port_status[i].status & PORT_STATUS_CONNECTION ) 125 { 126 //New device attached! 127 //DO something 128 dprintf( "USB Hub Explore(): New device connected\n" ); 129 130 } 131 else 132 { 133 //Device removed... 134 //DO something 135 dprintf( "USB Hub Explore(): Device removed\n" ); 136 137 } 138 139 //Clear status 140 m_bus->SendRequest( this , USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT , 141 USB_REQUEST_CLEAR_FEATURE , 142 C_PORT_CONNECTION , 143 i + 1 , //index 144 0 , 145 NULL , 146 0 , 147 &actual_length ); 148 } // PORT_STATUS_CONNECTION 149 }//for (...) 150 } 151