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 Device::Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum ) 25 { 26 status_t retval; 27 28 m_bus = bus; 29 m_parent = parent; 30 m_initok = false; 31 m_configurations = 0; 32 m_current_configuration = 0; 33 34 dprintf( "USB Device: new device\n" ); 35 36 //1. Create the semaphore 37 m_lock = create_sem( 1 , "device_sem" ); 38 if ( m_lock < B_OK ) 39 { 40 dprintf( "usb Device: could not create semaphore\n" ); 41 return; 42 } 43 set_sem_owner( m_lock , B_SYSTEM_TEAM ); 44 45 //2. Set the free entry free entry in the device map (for the device number) 46 m_devicenum = devicenum; 47 48 //3. Get the device descriptor 49 // We already have a part of it, but we want it all 50 m_device_descriptor = desc; 51 52 //Set the maximum transfer numbers for the incoming and the outgoing packets on endpoint 0 53 m_maxpacketin[0] = m_maxpacketout[0] = m_device_descriptor.max_packet_size_0; 54 55 retval = GetDescriptor( USB_DESCRIPTOR_DEVICE , 0 , 56 (void *)&m_device_descriptor , sizeof(m_device_descriptor ) ); 57 58 if ( retval != sizeof( m_device_descriptor ) ) 59 { 60 dprintf( "usb Device: error while getting the device descriptor\n" ); 61 return; 62 } 63 64 dprintf( "usb Device %d: Vendor id: %d , Product id: %d\n" , devicenum , 65 m_device_descriptor.vendor_id , m_device_descriptor.product_id ); 66 67 68 // 4. Get the configurations 69 m_configurations = (usb_configuration_descriptor *)malloc( m_device_descriptor.num_configurations * sizeof (usb_configuration_descriptor) ); 70 if ( m_configurations == 0 ) 71 { 72 dprintf( "usb Device: out of memory during config creations!\n" ); 73 return; 74 } 75 76 for ( int i = 0 ; i < m_device_descriptor.num_configurations ; i++ ) 77 { 78 if ( GetDescriptor( USB_DESCRIPTOR_CONFIGURATION , i , 79 (void *)( m_configurations + i ) , sizeof (usb_configuration_descriptor ) ) != sizeof( usb_configuration_descriptor ) ) 80 { 81 dprintf( "usb Device %d: error fetching configuration %d ...\n" , m_devicenum , i ); 82 return; 83 } 84 } 85 86 // 5. Set the default configuration 87 dprintf( "usb Device %d: setting configuration %d\n" , m_devicenum , 0 ); 88 SetConfiguration( 0 ); 89 90 //6. TODO: Find drivers for the device 91 } 92 93 //Returns the length that was copied (index gives the number of the config) 94 int16 Device::GetDescriptor( uint8 descriptor_type , uint16 index , 95 void *buffer , size_t size ) 96 { 97 size_t actual_length; 98 m_bus->SendRequest( this , 99 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD , //Type 100 USB_REQUEST_GET_DESCRIPTOR , //Request 101 ( descriptor_type << 8 ) | index , //Value 102 0 , //Index 103 size , //Length 104 buffer , //Buffer 105 size , //Bufferlength 106 &actual_length ); //length 107 return actual_length; 108 } 109 110 status_t Device::SetConfiguration( uint8 value ) 111 { 112 if ( value >= m_device_descriptor.num_configurations ) 113 return EINVAL; 114 115 m_bus->SendRequest( this , 116 USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD , //Type 117 USB_REQUEST_SET_CONFIGURATION , //Request 118 value , //Value 119 0 , //Index 120 0 , //Length 121 NULL , //Buffer 122 0 , //Bufferlength 123 0 ); //length 124 125 //Set current configuration 126 m_current_configuration = m_configurations + value; 127 } 128