00001 /* 00002 * Copyright (c) 2011 Vojtech Horky 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 "pipepriv.h" 00036 #include <devman.h> 00037 #include <errno.h> 00038 #include <assert.h> 00039 00044 void pipe_start_transaction(usb_pipe_t *pipe) 00045 { 00046 fibril_mutex_lock(&pipe->hc_phone_mutex); 00047 } 00048 00053 void pipe_end_transaction(usb_pipe_t *pipe) 00054 { 00055 fibril_mutex_unlock(&pipe->hc_phone_mutex); 00056 } 00057 00062 void pipe_acquire(usb_pipe_t *pipe) 00063 { 00064 fibril_mutex_lock(&pipe->guard); 00065 } 00066 00071 void pipe_release(usb_pipe_t *pipe) 00072 { 00073 fibril_mutex_unlock(&pipe->guard); 00074 } 00075 00084 int pipe_add_ref(usb_pipe_t *pipe, bool hide_failure) 00085 { 00086 pipe_acquire(pipe); 00087 00088 if (pipe->refcount == 0) { 00089 /* Need to open the phone by ourselves. */ 00090 int phone = devman_device_connect(pipe->wire->hc_handle, 0); 00091 if (phone < 0) { 00092 if (hide_failure) { 00093 pipe->refcount_soft++; 00094 phone = EOK; 00095 } 00096 pipe_release(pipe); 00097 return phone; 00098 } 00099 /* 00100 * No locking is needed, refcount is zero and whole pipe 00101 * mutex is locked. 00102 */ 00103 pipe->hc_phone = phone; 00104 } 00105 pipe->refcount++; 00106 00107 pipe_release(pipe); 00108 00109 return EOK; 00110 } 00111 00116 void pipe_drop_ref(usb_pipe_t *pipe) 00117 { 00118 pipe_acquire(pipe); 00119 if (pipe->refcount_soft > 0) { 00120 pipe->refcount_soft--; 00121 pipe_release(pipe); 00122 return; 00123 } 00124 assert(pipe->refcount > 0); 00125 pipe->refcount--; 00126 if (pipe->refcount == 0) { 00127 /* We were the last users, let's hang-up. */ 00128 async_hangup(pipe->hc_phone); 00129 pipe->hc_phone = -1; 00130 } 00131 pipe_release(pipe); 00132 } 00133 00134