1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2003-2004, 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 , bool lowspeed ) 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. Set up the pipe stuff 49 //Set the maximum transfer numbers for the incoming and the outgoing packets on endpoint 0 50 m_maxpacketin[0] = m_maxpacketout[0] = m_device_descriptor.max_packet_size_0; 51 m_device_descriptor = desc; 52 m_lowspeed = lowspeed; 53 m_defaultPipe = new ControlPipe( this , Pipe::Default , 0 ); 54 55 //4. Get the device descriptor 56 // We already have a part of it, but we want it all 57 retval = GetDescriptor( USB_DESCRIPTOR_DEVICE , 0 , 58 (void *)&m_device_descriptor , sizeof(m_device_descriptor ) ); 59 60 if ( retval != sizeof( m_device_descriptor ) ) 61 { 62 dprintf( "usb Device: error while getting the device descriptor\n" ); 63 return; 64 } 65 66 dprintf( "usb Device %d: Vendor id: %d , Product id: %d\n" , devicenum , 67 m_device_descriptor.vendor_id , m_device_descriptor.product_id ); 68 69 // 4. Get the configurations 70 m_configurations = (usb_configuration_descriptor *)malloc( m_device_descriptor.num_configurations * sizeof (usb_configuration_descriptor) ); 71 if ( m_configurations == 0 ) 72 { 73 dprintf( "usb Device: out of memory during config creations!\n" ); 74 return; 75 } 76 77 for ( int i = 0 ; i < m_device_descriptor.num_configurations ; i++ ) 78 { 79 if ( GetDescriptor( USB_DESCRIPTOR_CONFIGURATION , i , 80 (void *)( m_configurations + i ) , sizeof (usb_configuration_descriptor ) ) != sizeof( usb_configuration_descriptor ) ) 81 { 82 dprintf( "usb Device %d: error fetching configuration %d ...\n" , m_devicenum , i ); 83 return; 84 } 85 } 86 87 // 5. Set the default configuration 88 dprintf( "usb Device %d: setting configuration %d\n" , m_devicenum , 0 ); 89 SetConfiguration( 0 ); 90 91 //6. TODO: Find drivers for the device 92 93 m_initok = true; 94 } 95 96 //Returns the length that was copied (index gives the number of the config) 97 int16 Device::GetDescriptor( uint8 descriptor_type , uint16 index , 98 void *buffer , size_t size ) 99 { 100 size_t actual_length = 0; 101 m_defaultPipe->SendRequest(USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD , //Type 102 USB_REQUEST_GET_DESCRIPTOR , //Request 103 ( descriptor_type << 8 ) | index , //Value 104 0 , //Index 105 size , //Length 106 buffer , //Buffer 107 size , //Bufferlength 108 &actual_length ); //length 109 return actual_length; 110 } 111 112 status_t Device::SetConfiguration( uint8 value ) 113 { 114 if ( value >= m_device_descriptor.num_configurations ) 115 return EINVAL; 116 117 m_defaultPipe->SendRequest( USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD , //Type 118 USB_REQUEST_SET_CONFIGURATION , //Request 119 value , //Value 120 0 , //Index 121 0 , //Length 122 NULL , //Buffer 123 0 , //Bufferlength 124 0 ); //length 125 126 //Set current configuration 127 m_current_configuration = m_configurations + value; 128 return B_OK; 129 } 130