00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <devman.h>
00036 #include <async.h>
00037 #include <dev_iface.h>
00038 #include <usb_iface.h>
00039 #include <usbhc_iface.h>
00040 #include <usb/hc.h>
00041 #include <usb/debug.h>
00042 #include <errno.h>
00043 #include <assert.h>
00044
00051 int usb_hc_connection_initialize_from_device(usb_hc_connection_t *connection,
00052 ddf_dev_t *device)
00053 {
00054 assert(connection);
00055
00056 if (device == NULL) {
00057 return EBADMEM;
00058 }
00059
00060 devman_handle_t hc_handle;
00061 int rc = usb_hc_find(device->handle, &hc_handle);
00062 if (rc != EOK) {
00063 return rc;
00064 }
00065
00066 rc = usb_hc_connection_initialize(connection, hc_handle);
00067
00068 return rc;
00069 }
00070
00077 int usb_hc_connection_initialize(usb_hc_connection_t *connection,
00078 devman_handle_t hc_handle)
00079 {
00080 assert(connection);
00081
00082 connection->hc_handle = hc_handle;
00083 connection->hc_phone = -1;
00084
00085 return EOK;
00086 }
00087
00093 int usb_hc_connection_open(usb_hc_connection_t *connection)
00094 {
00095 assert(connection);
00096
00097 if (usb_hc_connection_is_opened(connection)) {
00098 return EBUSY;
00099 }
00100
00101 int phone = devman_device_connect(connection->hc_handle, 0);
00102 if (phone < 0) {
00103 return phone;
00104 }
00105
00106 connection->hc_phone = phone;
00107
00108 return EOK;
00109 }
00110
00116 bool usb_hc_connection_is_opened(const usb_hc_connection_t *connection)
00117 {
00118 assert(connection);
00119
00120 return (connection->hc_phone >= 0);
00121 }
00122
00128 int usb_hc_connection_close(usb_hc_connection_t *connection)
00129 {
00130 assert(connection);
00131
00132 if (!usb_hc_connection_is_opened(connection)) {
00133 return ENOENT;
00134 }
00135
00136 int rc = async_hangup(connection->hc_phone);
00137 if (rc != EOK) {
00138 return rc;
00139 }
00140
00141 connection->hc_phone = -1;
00142
00143 return EOK;
00144 }
00145
00153 int usb_hc_get_handle_by_address(usb_hc_connection_t *connection,
00154 usb_address_t address, devman_handle_t *handle)
00155 {
00156 if (!usb_hc_connection_is_opened(connection)) {
00157 return ENOENT;
00158 }
00159
00160 sysarg_t tmp;
00161 int rc = async_req_2_1(connection->hc_phone,
00162 DEV_IFACE_ID(USBHC_DEV_IFACE),
00163 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,
00164 address, &tmp);
00165 if ((rc == EOK) && (handle != NULL)) {
00166 *handle = tmp;
00167 }
00168
00169 return rc;
00170 }
00171
00177 usb_address_t usb_hc_get_address_by_handle(devman_handle_t dev_handle)
00178 {
00179 int parent_phone = devman_parent_device_connect(dev_handle,
00180 IPC_FLAG_BLOCKING);
00181 if (parent_phone < 0) {
00182 return parent_phone;
00183 }
00184
00185 sysarg_t address;
00186
00187 int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
00188 IPC_M_USB_GET_ADDRESS,
00189 dev_handle, &address);
00190
00191 if (rc != EOK) {
00192 return rc;
00193 }
00194
00195 async_hangup(parent_phone);
00196
00197 return (usb_address_t) address;
00198 }
00199
00200
00208 int usb_ddf_get_hc_handle_by_class(size_t class_index,
00209 devman_handle_t *hc_handle)
00210 {
00211 char *class_index_str;
00212 devman_handle_t hc_handle_tmp;
00213 int rc;
00214
00215 rc = asprintf(&class_index_str, "%zu", class_index);
00216 if (rc < 0) {
00217 return ENOMEM;
00218 }
00219 rc = devman_device_get_handle_by_class("usbhc", class_index_str,
00220 &hc_handle_tmp, 0);
00221 free(class_index_str);
00222 if (rc != EOK) {
00223 return rc;
00224 }
00225
00226 if (hc_handle != NULL) {
00227 *hc_handle = hc_handle_tmp;
00228 }
00229
00230 return EOK;
00231 }
00232
00240 int usb_hc_find(devman_handle_t device_handle, devman_handle_t *hc_handle)
00241 {
00242 int parent_phone = devman_parent_device_connect(device_handle,
00243 IPC_FLAG_BLOCKING);
00244 if (parent_phone < 0) {
00245 return parent_phone;
00246 }
00247
00248 devman_handle_t h;
00249 int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
00250 IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
00251
00252 async_hangup(parent_phone);
00253
00254 if (rc != EOK) {
00255 return rc;
00256 }
00257
00258 if (hc_handle != NULL) {
00259 *hc_handle = h;
00260 }
00261
00262 return EOK;
00263 }
00264