device_keeper.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011 Jan Vesely
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00035 #include <assert.h>
00036 #include <errno.h>
00037 #include <usb/debug.h>
00038 #include <usb/host/device_keeper.h>
00039 
00040 /*----------------------------------------------------------------------------*/
00047 void usb_device_keeper_init(usb_device_keeper_t *instance)
00048 {
00049         assert(instance);
00050         unsigned i = 0;
00051         for (; i < USB_ADDRESS_COUNT; ++i) {
00052                 instance->devices[i].occupied = false;
00053                 instance->devices[i].handle = 0;
00054                 instance->devices[i].speed = USB_SPEED_MAX;
00055         }
00056         // TODO: is this hack enough?
00057         // (it is needed to allow smooth registration at default address)
00058         instance->devices[0].occupied = true;
00059         instance->last_address = 0;
00060         fibril_mutex_initialize(&instance->guard);
00061 }
00062 /*----------------------------------------------------------------------------*/
00069 usb_address_t device_keeper_get_free_address(
00070     usb_device_keeper_t *instance, usb_speed_t speed)
00071 {
00072         assert(instance);
00073         fibril_mutex_lock(&instance->guard);
00074 
00075         usb_address_t new_address = instance->last_address;
00076         do {
00077                 ++new_address;
00078                 if (new_address > USB11_ADDRESS_MAX)
00079                         new_address = 1;
00080                 if (new_address == instance->last_address) {
00081                         fibril_mutex_unlock(&instance->guard);
00082                         return ENOSPC;
00083                 }
00084         } while (instance->devices[new_address].occupied);
00085 
00086         assert(new_address != USB_ADDRESS_DEFAULT);
00087         assert(instance->devices[new_address].occupied == false);
00088 
00089         instance->devices[new_address].occupied = true;
00090         instance->devices[new_address].speed = speed;
00091         instance->last_address = new_address;
00092 
00093         fibril_mutex_unlock(&instance->guard);
00094         return new_address;
00095 }
00096 /*----------------------------------------------------------------------------*/
00103 void usb_device_keeper_bind(usb_device_keeper_t *instance,
00104     usb_address_t address, devman_handle_t handle)
00105 {
00106         assert(instance);
00107         fibril_mutex_lock(&instance->guard);
00108 
00109         assert(address > 0);
00110         assert(address <= USB11_ADDRESS_MAX);
00111         assert(instance->devices[address].occupied);
00112 
00113         instance->devices[address].handle = handle;
00114         fibril_mutex_unlock(&instance->guard);
00115 }
00116 /*----------------------------------------------------------------------------*/
00122 void usb_device_keeper_release(
00123     usb_device_keeper_t *instance, usb_address_t address)
00124 {
00125         assert(instance);
00126         assert(address > 0);
00127         assert(address <= USB11_ADDRESS_MAX);
00128 
00129         fibril_mutex_lock(&instance->guard);
00130         assert(instance->devices[address].occupied);
00131 
00132         instance->devices[address].occupied = false;
00133         fibril_mutex_unlock(&instance->guard);
00134 }
00135 /*----------------------------------------------------------------------------*/
00142 usb_address_t usb_device_keeper_find(
00143     usb_device_keeper_t *instance, devman_handle_t handle)
00144 {
00145         assert(instance);
00146         fibril_mutex_lock(&instance->guard);
00147         usb_address_t address = 1;
00148         while (address <= USB11_ADDRESS_MAX) {
00149                 if (instance->devices[address].handle == handle) {
00150                         assert(instance->devices[address].occupied);
00151                         fibril_mutex_unlock(&instance->guard);
00152                         return address;
00153                 }
00154                 ++address;
00155         }
00156         fibril_mutex_unlock(&instance->guard);
00157         return ENOENT;
00158 }
00159 
00168 bool usb_device_keeper_find_by_address(usb_device_keeper_t *instance,
00169     usb_address_t address, devman_handle_t *handle)
00170 {
00171         assert(instance);
00172         fibril_mutex_lock(&instance->guard);
00173         if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
00174                 fibril_mutex_unlock(&instance->guard);
00175                 return false;
00176         }
00177         if (!instance->devices[address].occupied) {
00178                 fibril_mutex_unlock(&instance->guard);
00179                 return false;
00180         }
00181 
00182         if (handle != NULL) {
00183                 *handle = instance->devices[address].handle;
00184         }
00185 
00186         fibril_mutex_unlock(&instance->guard);
00187         return true;
00188 }
00189 
00190 /*----------------------------------------------------------------------------*/
00197 usb_speed_t usb_device_keeper_get_speed(
00198     usb_device_keeper_t *instance, usb_address_t address)
00199 {
00200         assert(instance);
00201         assert(address >= 0);
00202         assert(address <= USB11_ADDRESS_MAX);
00203 
00204         return instance->devices[address].speed;
00205 }

Generated on Thu Jun 2 07:45:49 2011 for HelenOS/USB by  doxygen 1.4.7