Changeset 1d1f894 in mainline
- Timestamp:
- 2010-11-03T15:05:41Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d70a463
- Parents:
- af894a21
- Location:
- uspace
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/usb/example.c
raf894a21 r1d1f894 82 82 } 83 83 84 static void client_connection(ipc_callid_t iid, ipc_call_t *icall)85 {86 ipc_answer_0(iid, EOK);87 //printf("%s: client connection()\n", NAME);88 89 while (true) {90 ipc_callid_t callid;91 ipc_call_t call;92 int rc;93 void * buffer;94 size_t len;95 96 callid = async_get_call(&call);97 98 switch (IPC_GET_METHOD(call)) {99 case IPC_M_USB_HCD_DATA_SENT:100 printf("%s: >> Data sent over USB (handle %d, outcome %s).\n",101 NAME, IPC_GET_ARG1(call),102 usb_str_transaction_outcome(IPC_GET_ARG2(call)));103 ipc_answer_0(callid, EOK);104 break;105 106 case IPC_M_USB_HCD_DATA_RECEIVED:107 printf("%s: << Data received over USB (handle %d, outcome %s).\n",108 NAME, IPC_GET_ARG1(call),109 usb_str_transaction_outcome(IPC_GET_ARG2(call)));110 if (IPC_GET_ARG2(call) != USB_OUTCOME_OK) {111 ipc_answer_0(callid, EOK);112 break;113 }114 len = IPC_GET_ARG3(call);115 if (len > 0) {116 rc = async_data_write_accept(&buffer, false,117 1, MAX_SIZE_RECEIVE,118 0, &len);119 if (rc != EOK) {120 ipc_answer_0(callid, rc);121 break;122 }123 free(buffer);124 }125 printf("%s: << Received %uB long buffer (handle %d).\n",126 NAME, len, IPC_GET_ARG1(call));127 ipc_answer_0(callid, EOK);128 break;129 130 case IPC_M_PHONE_HUNGUP:131 //printf("%s: hang-up.\n", NAME);132 return;133 134 default:135 printf("%s: method %d called.\n", NAME, IPC_GET_METHOD(call));136 ipc_answer_0(callid, EOK);137 break;138 }139 }140 }141 142 84 static void data_dump(uint8_t *data, size_t len) 143 85 { … … 154 96 int main(int argc, char * argv[]) 155 97 { 156 int hcd_phone = usb_hcd_c reate_phones(DEV_HCD_NAME, client_connection);98 int hcd_phone = usb_hcd_connect(DEV_HCD_NAME); 157 99 if (hcd_phone < 0) { 158 100 printf("%s: Unable to start comunication with HCD at usb://%s (%d: %s).\n", … … 233 175 234 176 fibril_sleep(1); 235 236 #if 0237 int rc;238 239 printf("%s: usb_hcd_transfer_control_write_setup(...)\n", NAME);240 rc = usb_hcd_transfer_control_write_setup(hcd_phone, target,241 &setup_packet, sizeof(setup_packet), NULL);242 if (rc != EOK) {243 printf("%s: failed setting address (%d).\n", NAME, rc);244 return rc;245 }246 247 printf("%s: usb_hcd_transfer_control_write_status(...)\n", NAME);248 rc = usb_hcd_transfer_control_write_status(hcd_phone, target, NULL);249 if (rc != EOK) {250 printf("%s: failed completing control transfer (%d).\n", NAME, rc);251 return rc;252 }253 254 printf("%s: sleeping for a while...\n", NAME);255 fibril_sleep(5);256 #endif257 177 258 178 printf("%s: exiting.\n", NAME); -
uspace/app/virtusbkbd/virtusbkbd.c
raf894a21 r1d1f894 58 58 #define NAME "virt-usb-kbd" 59 59 60 #define DEV_HCD_NAME "hcd-virt "60 #define DEV_HCD_NAME "hcd-virt-dev" 61 61 62 62 #define __QUOTEME(x) #x -
uspace/lib/usb/hcd.c
raf894a21 r1d1f894 90 90 } 91 91 92 /** Create necessary phones for com unicating with HCD.92 /** Create necessary phones for communicating with HCD. 93 93 * This function wraps following calls: 94 94 * -# open <code>/dev/usb/<i>hcd_path</i></code> for reading 95 95 * -# access phone of file opened in previous step 96 * -# create callback through just opened phone97 * -# set handler for this callback98 96 * -# return the (outgoing) phone 99 97 * 100 98 * @warning This function is wrapper for several actions and therefore 101 99 * it is not possible - in case of error - to determine at which point 102 * error occur ed.100 * error occurred. 103 101 * 104 102 * @param hcd_path HCD identification under devfs 105 103 * (without <code>/dev/usb/</code>). 106 * @param callback_connection Handler for callbacks from HCD. 107 * @return Phone for comunicating with HCD or error code from errno.h. 108 */ 109 int usb_hcd_create_phones(const char * hcd_path, 110 async_client_conn_t callback_connection) 104 * @return Phone for communicating with HCD or error code from errno.h. 105 */ 106 int usb_hcd_connect(const char * hcd_path) 111 107 { 112 108 char dev_path[DEVMAP_NAME_MAXLEN + 1]; … … 124 120 return hcd_phone; 125 121 } 126 127 ipcarg_t phonehash; 128 int rc = ipc_connect_to_me(hcd_phone, 0, 0, 0, &phonehash); 129 if (rc != EOK) { 130 return rc; 131 } 132 async_new_connection(phonehash, 0, NULL, callback_connection); 133 122 134 123 return hcd_phone; 135 124 } 136 137 /** Send data from USB host to a function.138 *139 * @param hcd_phone Connected phone to HCD.140 * @param target USB function address.141 * @param transfer_type USB transfer type.142 * @param buffer Buffer with data to be sent.143 * @param len Buffer @p buffer size.144 * @param[out] transaction_handle Handle of created transaction (NULL to ignore).145 * @return Error status.146 * @retval EOK Everything OK, buffer transfered to HCD and queued there.147 * @retval EINVAL Invalid phone.148 * @retval EINVAL @p buffer is NULL.149 */150 int usb_hcd_send_data_to_function(int hcd_phone,151 usb_target_t target, usb_transfer_type_t transfer_type,152 void * buffer, size_t len,153 usb_transaction_handle_t * transaction_handle)154 {155 if (hcd_phone < 0) {156 return EINVAL;157 }158 if (buffer == NULL) {159 return EINVAL;160 }161 162 ipc_call_t answer_data;163 ipcarg_t answer_rc;164 aid_t req;165 int rc;166 167 req = async_send_4(hcd_phone,168 IPC_M_USB_HCD_SEND_DATA,169 target.address, target.endpoint,170 transfer_type, 0,171 &answer_data);172 173 rc = async_data_write_start(hcd_phone, buffer, len);174 if (rc != EOK) {175 async_wait_for(req, NULL);176 return rc;177 }178 179 async_wait_for(req, &answer_rc);180 rc = (int)answer_rc;181 if (rc != EOK) {182 return rc;183 }184 185 if (transaction_handle != NULL) {186 *transaction_handle = IPC_GET_ARG1(answer_data);187 }188 189 return EOK;190 }191 192 193 /** Inform HCD about data reception.194 * The actual reception is handled in callback.195 *196 * @param hcd_phone Connected phone to HCD.197 * @param target USB function address.198 * @param transfer_type USB transfer type.199 * @param len Maximum accepted packet size.200 * @param[out] transaction_handle Handle of created transaction (NULL to ignore).201 * @return Error status.202 */203 int usb_hcd_prepare_data_reception(int hcd_phone,204 usb_target_t target, usb_transfer_type_t transfer_type,205 size_t len,206 usb_transaction_handle_t * transaction_handle)207 {208 if (hcd_phone < 0) {209 return EINVAL;210 }211 212 usb_transaction_handle_t handle;213 214 int rc = ipc_call_sync_5_1(hcd_phone, IPC_M_USB_HCD_RECEIVE_DATA,215 target.address, target.endpoint,216 transfer_type, len, 0, &handle);217 218 if (rc != EOK) {219 return rc;220 }221 222 if (transaction_handle != NULL) {223 *transaction_handle = handle;224 }225 226 return EOK;227 }228 229 230 static int send_buffer(int phone, ipcarg_t method, usb_target_t target,231 void *buffer, size_t size, usb_transaction_handle_t * transaction_handle)232 {233 if (phone < 0) {234 return EINVAL;235 }236 237 if ((buffer == NULL) && (size > 0)) {238 return EINVAL;239 }240 241 ipc_call_t answer_data;242 ipcarg_t answer_rc;243 aid_t req;244 int rc;245 246 req = async_send_3(phone,247 method,248 target.address, target.endpoint,249 size,250 &answer_data);251 252 if (size > 0) {253 rc = async_data_write_start(phone, buffer, size);254 if (rc != EOK) {255 async_wait_for(req, NULL);256 return rc;257 }258 }259 260 async_wait_for(req, &answer_rc);261 rc = (int)answer_rc;262 if (rc != EOK) {263 return rc;264 }265 266 if (transaction_handle != NULL) {267 *transaction_handle = IPC_GET_ARG1(answer_data);268 }269 270 return EOK;271 }272 273 274 static int prep_receive_data(int phone, ipcarg_t method, usb_target_t target,275 size_t size, usb_transaction_handle_t * transaction_handle)276 {277 if (phone < 0) {278 return EINVAL;279 }280 281 usb_transaction_handle_t handle;282 283 int rc = ipc_call_sync_3_1(phone,284 method,285 target.address, target.endpoint,286 size,287 &handle);288 289 if (rc != EOK) {290 return rc;291 }292 293 if (transaction_handle != NULL) {294 *transaction_handle = handle;295 }296 297 return EOK;298 }299 300 301 int usb_hcd_transfer_interrupt_out(int hcd_phone, usb_target_t target,302 void *buffer, size_t size, usb_transaction_handle_t *handle)303 {304 return send_buffer(hcd_phone, IPC_M_USB_HCD_INTERRUPT_OUT,305 target, buffer, size, handle);306 }307 308 int usb_hcd_transfer_interrupt_in(int hcd_phone, usb_target_t target,309 size_t size, usb_transaction_handle_t *handle)310 {311 return prep_receive_data(hcd_phone, IPC_M_USB_HCD_INTERRUPT_IN,312 target, size, handle);313 }314 315 int usb_hcd_transfer_control_write_setup(int hcd_phone, usb_target_t target,316 void *buffer, size_t size, usb_transaction_handle_t *handle)317 {318 return send_buffer(hcd_phone, IPC_M_USB_HCD_CONTROL_WRITE_SETUP,319 target, buffer, size, handle);320 }321 322 int usb_hcd_transfer_control_write_data(int hcd_phone, usb_target_t target,323 void *buffer, size_t size, usb_transaction_handle_t *handle)324 {325 return send_buffer(hcd_phone, IPC_M_USB_HCD_CONTROL_WRITE_DATA,326 target, buffer, size, handle);327 328 }329 int usb_hcd_transfer_control_write_status(int hcd_phone, usb_target_t target,330 usb_transaction_handle_t *handle)331 {332 return prep_receive_data(hcd_phone, IPC_M_USB_HCD_CONTROL_WRITE_STATUS,333 target, 0, handle);334 }335 336 int usb_hcd_transfer_control_read_setup(int hcd_phone, usb_target_t target,337 void *buffer, size_t size, usb_transaction_handle_t *handle)338 {339 return send_buffer(hcd_phone, IPC_M_USB_HCD_CONTROL_READ_SETUP,340 target, buffer, size, handle);341 }342 int usb_hcd_transfer_control_read_data(int hcd_phone, usb_target_t target,343 size_t size, usb_transaction_handle_t *handle)344 {345 return prep_receive_data(hcd_phone, IPC_M_USB_HCD_CONTROL_READ_DATA,346 target, size, handle);347 }348 int usb_hcd_transfer_control_read_status(int hcd_phone, usb_target_t target,349 usb_transaction_handle_t *handle)350 {351 return send_buffer(hcd_phone, IPC_M_USB_HCD_CONTROL_READ_STATUS,352 target, NULL, 0, handle);353 }354 355 356 357 358 359 /*360 * =================361 * async versions of the above functions362 * =================363 */364 125 365 126 /** Send data to HCD. -
uspace/lib/usb/hcd.h
raf894a21 r1d1f894 133 133 * OUT transactions buffers can be freed immediatelly after call is dispatched 134 134 * (i.e. after return from wrapping function). 135 * 136 * Async methods for retrieving data from device: 137 */ 138 typedef enum { 139 /** Send data over USB to a function. 140 * This method initializes large data transfer that must follow 141 * immediatelly. 142 * The recipient of this method must issue immediately data reception 143 * and answer this call after data buffer was transfered. 144 * 145 * Arguments of the call: 146 * - USB address of the function 147 * - endpoint of the function 148 * - transfer type 149 * - flags (not used) 150 * 151 * Answer: 152 * - EOK - ready to accept the data buffer 153 * - ELIMIT - too many transactions for current connection 154 * - ENOENT - callback connection does not exist 155 * - EINVAL - other kind of error 156 * 157 * Arguments of the answer: 158 * - opaque transaction handle (used in callbacks) 159 */ 160 IPC_M_USB_HCD_SEND_DATA = IPC_FIRST_USER_METHOD, 161 162 /** Initiate data receive from a function. 163 * This method announces the HCD that some data will come. 164 * When this data arrives, the HCD will call back with 165 * IPC_M_USB_HCD_DATA_RECEIVED. 166 * 167 * Arguments of the call: 168 * - USB address of the function 169 * - endpoint of the function 170 * - transfer type 171 * - buffer size 172 * - flags (not used) 173 * 174 * Answer: 175 * - EOK - HCD accepted the request 176 * - ELIMIT - too many transactions for current connection 177 * - ENOENT - callback connection does not exist 178 * 179 * Arguments of the answer: 180 * - opaque transaction handle (used in callbacks) 181 */ 182 IPC_M_USB_HCD_RECEIVE_DATA, 183 135 * 136 */ 137 typedef enum { 184 138 /** Tell maximum size of the transaction buffer (payload). 185 139 * … … 193 147 * - buffer size (in bytes): 194 148 */ 195 IPC_M_USB_HCD_TRANSACTION_SIZE, 196 197 198 IPC_M_USB_HCD_INTERRUPT_OUT, 199 IPC_M_USB_HCD_INTERRUPT_IN, 200 201 IPC_M_USB_HCD_CONTROL_WRITE_SETUP, 202 IPC_M_USB_HCD_CONTROL_WRITE_DATA, 203 IPC_M_USB_HCD_CONTROL_WRITE_STATUS, 204 205 IPC_M_USB_HCD_CONTROL_READ_SETUP, 206 IPC_M_USB_HCD_CONTROL_READ_DATA, 207 IPC_M_USB_HCD_CONTROL_READ_STATUS, 208 209 /* async methods */ 149 IPC_M_USB_HCD_TRANSACTION_SIZE = IPC_FIRST_USER_METHOD, 210 150 211 151 /** Asks for data buffer. … … 293 233 294 234 295 int usb_hcd_create_phones(const char *, async_client_conn_t); 296 int usb_hcd_send_data_to_function(int, usb_target_t, usb_transfer_type_t, 297 void *, size_t, usb_transaction_handle_t *); 298 int usb_hcd_prepare_data_reception(int, usb_target_t, usb_transfer_type_t, 299 size_t, usb_transaction_handle_t *); 300 301 302 int usb_hcd_transfer_interrupt_out(int, usb_target_t, 303 void *, size_t, usb_transaction_handle_t *); 304 int usb_hcd_transfer_interrupt_in(int, usb_target_t, 305 size_t, usb_transaction_handle_t *); 306 307 int usb_hcd_transfer_control_write_setup(int, usb_target_t, 308 void *, size_t, usb_transaction_handle_t *); 309 int usb_hcd_transfer_control_write_data(int, usb_target_t, 310 void *, size_t, usb_transaction_handle_t *); 311 int usb_hcd_transfer_control_write_status(int, usb_target_t, 312 usb_transaction_handle_t *); 313 314 int usb_hcd_transfer_control_read_setup(int, usb_target_t, 315 void *, size_t, usb_transaction_handle_t *); 316 int usb_hcd_transfer_control_read_data(int, usb_target_t, 317 size_t, usb_transaction_handle_t *); 318 int usb_hcd_transfer_control_read_status(int, usb_target_t, 319 usb_transaction_handle_t *); 235 int usb_hcd_connect(const char *); 320 236 321 237 int usb_hcd_async_transfer_interrupt_out(int, usb_target_t, -
uspace/lib/usbvirt/main.c
raf894a21 r1d1f894 225 225 226 226 ipcarg_t phonehash; 227 int rc = ipc_connect_to_me(hcd_phone, 1, 0, 0, &phonehash);227 int rc = ipc_connect_to_me(hcd_phone, 0, 0, 0, &phonehash); 228 228 if (rc != EOK) { 229 229 return rc; -
uspace/srv/hw/bus/usb/hcd/virtual/conn.h
raf894a21 r1d1f894 40 40 #include "devices.h" 41 41 42 void connection_handler_host(ipcarg_t , int);42 void connection_handler_host(ipcarg_t); 43 43 void connection_handler_device(ipcarg_t, virtdev_connection_t *); 44 44 -
uspace/srv/hw/bus/usb/hcd/virtual/connhost.c
raf894a21 r1d1f894 41 41 #include "hc.h" 42 42 43 static usb_transaction_handle_t g_handle_seed = 1;44 static usb_transaction_handle_t create_transaction_handle(int phone)45 {46 return g_handle_seed++;47 }48 49 43 typedef struct { 50 int phone; 51 usb_transaction_handle_t handle; 52 } transaction_details_t; 53 54 55 /** Callback for outgoing transaction. 56 */ 57 static void out_callback(void * buffer, size_t len, usb_transaction_outcome_t outcome, void * arg) 58 { 59 dprintf(2, "out_callback(buffer, %u, %d, %p)", len, outcome, arg); 60 61 transaction_details_t * trans = (transaction_details_t *)arg; 62 63 async_msg_2(trans->phone, IPC_M_USB_HCD_DATA_SENT, trans->handle, outcome); 44 ipc_callid_t caller; 45 void *buffer; 46 size_t size; 47 } async_transaction_t; 48 49 static void async_out_callback(void * buffer, size_t len, 50 usb_transaction_outcome_t outcome, void * arg) 51 { 52 async_transaction_t * trans = (async_transaction_t *)arg; 53 54 dprintf(2, "async_out_callback(buffer, %u, %d, %p) -> %x", 55 len, outcome, arg, trans->caller); 56 57 // FIXME - answer according to outcome 58 ipc_answer_1(trans->caller, EOK, 0); 64 59 65 60 free(trans); … … 67 62 free(buffer); 68 63 } 69 } 70 71 /** Callback for incoming transaction. 72 */ 73 static void in_callback(void * buffer, size_t len, usb_transaction_outcome_t outcome, void * arg) 74 { 75 dprintf(2, "in_callback(buffer, %u, %d, %p)", len, outcome, arg); 76 transaction_details_t * trans = (transaction_details_t *)arg; 77 78 ipc_call_t answer_data; 79 ipcarg_t answer_rc; 80 aid_t req; 81 int rc; 82 83 req = async_send_3(trans->phone, 84 IPC_M_USB_HCD_DATA_RECEIVED, 85 trans->handle, outcome, 86 len, 87 &answer_data); 88 89 if (len > 0) { 90 rc = async_data_write_start(trans->phone, buffer, len); 91 if (rc != EOK) { 92 async_wait_for(req, NULL); 93 goto leave; 94 } 95 } 96 97 async_wait_for(req, &answer_rc); 98 rc = (int)answer_rc; 99 if (rc != EOK) { 100 goto leave; 101 } 102 103 leave: 104 free(trans); 105 if (buffer != NULL) { 106 free(buffer); 107 } 108 } 109 110 /** Handle data from host to function. 111 */ 112 static void handle_data_to_function(ipc_callid_t iid, ipc_call_t icall, 113 bool setup_transaction, int callback_phone) 64 dprintf(4, "async_out_callback answered"); 65 } 66 67 static void async_to_device(ipc_callid_t iid, ipc_call_t icall, bool setup_transaction) 114 68 { 115 69 size_t expected_len = IPC_GET_ARG3(icall); … … 119 73 }; 120 74 121 dprintf(1, "pretending transfer to function (dev=%d:%d)", 122 target.address, target.endpoint); 123 124 if (callback_phone == -1) { 125 ipc_answer_0(iid, ENOENT); 126 return; 127 } 128 129 usb_transaction_handle_t handle 130 = create_transaction_handle(callback_phone); 75 dprintf(1, "async_to_device: dev=%d:%d, size=%d, iid=%x", 76 target.address, target.endpoint, expected_len, iid); 131 77 132 78 size_t len = 0; … … 143 89 } 144 90 145 transaction_details_t * trans = malloc(sizeof(transaction_details_t)); 146 trans->phone = callback_phone; 147 trans->handle = handle; 91 async_transaction_t * trans = malloc(sizeof(async_transaction_t)); 92 trans->caller = iid; 93 trans->buffer = NULL; 94 trans->size = 0; 148 95 149 96 hc_add_transaction_to_device(setup_transaction, target, 150 97 buffer, len, 151 out_callback, trans); 152 153 ipc_answer_1(iid, EOK, handle); 154 dprintf(2, "transfer to function scheduled (handle %d)", handle); 155 } 156 157 /** Handle data from function to host. 158 */ 159 static void handle_data_from_function(ipc_callid_t iid, ipc_call_t icall, int callback_phone) 98 async_out_callback, trans); 99 100 dprintf(2, "async transaction to device scheduled (%p)", trans); 101 } 102 103 static void async_in_callback(void * buffer, size_t len, 104 usb_transaction_outcome_t outcome, void * arg) 105 { 106 async_transaction_t * trans = (async_transaction_t *)arg; 107 108 dprintf(2, "async_in_callback(buffer, %u, %d, %p) -> %x", 109 len, outcome, arg, trans->caller); 110 111 trans->buffer = buffer; 112 trans->size = len; 113 114 ipc_callid_t caller = trans->caller; 115 116 if (buffer == NULL) { 117 free(trans); 118 trans = NULL; 119 } 120 121 122 // FIXME - answer according to outcome 123 ipc_answer_1(caller, EOK, (ipcarg_t)trans); 124 dprintf(4, "async_in_callback answered (%#x)", (ipcarg_t)trans); 125 } 126 127 static void async_from_device(ipc_callid_t iid, ipc_call_t icall) 160 128 { 161 129 usb_target_t target = { … … 165 133 size_t len = IPC_GET_ARG3(icall); 166 134 167 dprintf(1, "pretending transfer from function (dev=%d:%d)",168 target.address, target.endpoint);169 170 if (callback_phone == -1) {171 ipc_answer_0(iid, ENOENT);172 return;173 }174 175 usb_transaction_handle_t handle176 = create_transaction_handle(callback_phone);177 178 void * buffer = NULL;179 if (len > 0) {180 buffer = malloc(len);181 }182 183 transaction_details_t * trans = malloc(sizeof(transaction_details_t));184 trans->phone = callback_phone;185 trans->handle = handle;186 187 hc_add_transaction_from_device(target,188 buffer, len,189 in_callback, trans);190 191 ipc_answer_1(iid, EOK, handle);192 dprintf(2, "transfer from function scheduled (handle %d)", handle);193 }194 195 196 typedef struct {197 ipc_callid_t caller;198 void *buffer;199 size_t size;200 } async_transaction_t;201 202 static void async_out_callback(void * buffer, size_t len,203 usb_transaction_outcome_t outcome, void * arg)204 {205 async_transaction_t * trans = (async_transaction_t *)arg;206 207 dprintf(2, "async_out_callback(buffer, %u, %d, %p) -> %x",208 len, outcome, arg, trans->caller);209 210 // FIXME - answer according to outcome211 ipc_answer_1(trans->caller, EOK, 0);212 213 free(trans);214 if (buffer) {215 free(buffer);216 }217 dprintf(4, "async_out_callback answered");218 }219 220 static void async_to_device(ipc_callid_t iid, ipc_call_t icall, bool setup_transaction)221 {222 size_t expected_len = IPC_GET_ARG3(icall);223 usb_target_t target = {224 .address = IPC_GET_ARG1(icall),225 .endpoint = IPC_GET_ARG2(icall)226 };227 228 dprintf(1, "async_to_device: dev=%d:%d, size=%d, iid=%x",229 target.address, target.endpoint, expected_len, iid);230 231 size_t len = 0;232 void * buffer = NULL;233 if (expected_len > 0) {234 int rc = async_data_write_accept(&buffer, false,235 1, USB_MAX_PAYLOAD_SIZE,236 0, &len);237 238 if (rc != EOK) {239 ipc_answer_0(iid, rc);240 return;241 }242 }243 244 async_transaction_t * trans = malloc(sizeof(async_transaction_t));245 trans->caller = iid;246 trans->buffer = NULL;247 trans->size = 0;248 249 hc_add_transaction_to_device(setup_transaction, target,250 buffer, len,251 async_out_callback, trans);252 253 dprintf(2, "async transaction to device scheduled (%p)", trans);254 }255 256 static void async_in_callback(void * buffer, size_t len,257 usb_transaction_outcome_t outcome, void * arg)258 {259 async_transaction_t * trans = (async_transaction_t *)arg;260 261 dprintf(2, "async_in_callback(buffer, %u, %d, %p) -> %x",262 len, outcome, arg, trans->caller);263 264 trans->buffer = buffer;265 trans->size = len;266 267 ipc_callid_t caller = trans->caller;268 269 if (buffer == NULL) {270 free(trans);271 trans = NULL;272 }273 274 275 // FIXME - answer according to outcome276 ipc_answer_1(caller, EOK, (ipcarg_t)trans);277 dprintf(4, "async_in_callback answered (%#x)", (ipcarg_t)trans);278 }279 280 static void async_from_device(ipc_callid_t iid, ipc_call_t icall)281 {282 usb_target_t target = {283 .address = IPC_GET_ARG1(icall),284 .endpoint = IPC_GET_ARG2(icall)285 };286 size_t len = IPC_GET_ARG3(icall);287 288 135 dprintf(1, "async_from_device: dev=%d:%d, size=%d, iid=%x", 289 136 target.address, target.endpoint, len, iid); … … 345 192 * 346 193 * @param phone_hash Incoming phone hash. 347 * @param host_phone Callback phone to host. 348 */ 349 void connection_handler_host(ipcarg_t phone_hash, int host_phone) 350 { 351 assert(host_phone > 0); 352 194 */ 195 void connection_handler_host(ipcarg_t phone_hash) 196 { 353 197 dprintf(0, "host connected through phone %#x", phone_hash); 354 198 … … 368 212 369 213 switch (IPC_GET_METHOD(call)) { 214 215 /* standard IPC methods */ 216 370 217 case IPC_M_PHONE_HUNGUP: 371 ipc_hangup(host_phone);372 218 ipc_answer_0(callid, EOK); 373 219 dprintf(0, "phone%#x: host hung-up", … … 379 225 break; 380 226 227 228 /* USB methods */ 229 381 230 case IPC_M_USB_HCD_TRANSACTION_SIZE: 382 231 ipc_answer_1(callid, EOK, USB_MAX_PAYLOAD_SIZE); 383 232 break; 384 385 /* callback-result methods */386 387 case IPC_M_USB_HCD_INTERRUPT_OUT:388 handle_data_to_function(callid, call,389 false, host_phone);390 break;391 392 case IPC_M_USB_HCD_INTERRUPT_IN:393 handle_data_from_function(callid, call, host_phone);394 break;395 396 case IPC_M_USB_HCD_CONTROL_WRITE_SETUP:397 handle_data_to_function(callid, call,398 true, host_phone);399 break;400 401 case IPC_M_USB_HCD_CONTROL_WRITE_DATA:402 handle_data_to_function(callid, call,403 false, host_phone);404 break;405 406 case IPC_M_USB_HCD_CONTROL_WRITE_STATUS:407 handle_data_from_function(callid, call, host_phone);408 break;409 410 case IPC_M_USB_HCD_CONTROL_READ_SETUP:411 handle_data_to_function(callid, call,412 true, host_phone);413 break;414 415 /* async methods */416 233 417 234 case IPC_M_USB_HCD_GET_BUFFER_ASYNC: … … 436 253 break; 437 254 255 438 256 /* end of known methods */ 439 257 -
uspace/srv/hw/bus/usb/hcd/virtual/hcd.c
raf894a21 r1d1f894 52 52 53 53 54 static dev_handle_t handle_virtual_device; 55 static dev_handle_t handle_host_driver; 56 54 57 static void client_connection(ipc_callid_t iid, ipc_call_t *icall) 55 58 { 56 59 ipcarg_t phone_hash = icall->in_phone_hash; 60 dev_handle_t handle = (dev_handle_t)IPC_GET_ARG1(*icall); 57 61 58 ipc_answer_0(iid, EOK); 59 60 while (true) { 61 ipc_callid_t callid; 62 ipc_call_t call; 63 64 callid = async_get_call(&call); 65 62 if (handle == handle_host_driver) { 66 63 /* 67 * We can do nothing until we have the callback phone. 68 * Thus, we will wait for the callback and start processing 69 * after that. 64 * We can connect host controller driver immediately. 70 65 */ 71 int method = (int) IPC_GET_METHOD(call); 72 73 if (method == IPC_M_PHONE_HUNGUP) { 74 ipc_answer_0(callid, EOK); 75 return; 76 } 77 78 if (method == IPC_M_CONNECT_TO_ME) { 79 int kind = IPC_GET_ARG1(call); 80 int callback = IPC_GET_ARG5(call); 81 66 ipc_answer_0(iid, EOK); 67 connection_handler_host(phone_hash); 68 } else if (handle == handle_virtual_device) { 69 ipc_answer_0(iid, EOK); 70 71 while (true) { 82 72 /* 83 * Determine whether host connected to us84 * or adevice.73 * We need to wait for callback request to allow 74 * connection of virtual device. 85 75 */ 86 if (kind == 0) { 76 ipc_callid_t callid; 77 ipc_call_t call; 78 79 callid = async_get_call(&call); 80 81 /* 82 * We can do nothing until we have the callback phone. 83 * Thus, we will wait for the callback and start processing 84 * after that. 85 */ 86 int method = (int) IPC_GET_METHOD(call); 87 88 if (method == IPC_M_PHONE_HUNGUP) { 87 89 ipc_answer_0(callid, EOK); 88 connection_handler_host(phone_hash, callback);89 90 return; 90 } else if (kind == 1) { 91 } 92 93 if (method == IPC_M_CONNECT_TO_ME) { 94 int callback = IPC_GET_ARG5(call); 91 95 virtdev_connection_t *dev 92 96 = virtdev_add_device(callback); … … 100 104 virtdev_destroy_device(dev); 101 105 return; 102 } else {103 ipc_answer_0(callid, EINVAL);104 ipc_hangup(callback);105 return;106 106 } 107 108 /* 109 * No other methods could be served now. 110 */ 111 dprintf_inval_call(1, call, phone_hash); 112 ipc_answer_0(callid, ENOTSUP); 107 113 } 108 114 } else { 109 115 /* 110 * No other methods could be served now. 116 * Hmmm, someone else just tried to connect to us. 117 * Kick him out ;-). 111 118 */ 112 dprintf_inval_call(1, call, phone_hash);113 ipc_answer_0(callid, ENOTSUP);119 ipc_answer_0(iid, ENOTSUP); 120 return; 114 121 } 115 122 } … … 135 142 } 136 143 137 rc = devmap_device_register(DEVMAP_PATH , NULL);144 rc = devmap_device_register(DEVMAP_PATH_HC, &handle_host_driver); 138 145 if (rc != EOK) { 139 146 printf("%s: unable to register device %s (%s).\n", 140 NAME, DEVMAP_PATH , str_error(rc));147 NAME, DEVMAP_PATH_HC, str_error(rc)); 141 148 return 1; 142 149 } 143 150 151 rc = devmap_device_register(DEVMAP_PATH_DEV, &handle_virtual_device); 152 if (rc != EOK) { 153 printf("%s: unable to register device %s (%s).\n", 154 NAME, DEVMAP_PATH_DEV, str_error(rc)); 155 return 1; 156 } 157 144 158 hub_init(); 145 159 146 printf("%s: accepting connections [devmap=%s, debug=%d].\n", NAME, 147 DEVMAP_PATH, debug_level); 160 printf("%s: accepting connections [debug=%d]\n", NAME, debug_level); 161 printf("%s: -> host controller at %s\n", NAME, DEVMAP_PATH_HC); 162 printf("%s: -> virtual hub at %s\n", NAME, DEVMAP_PATH_DEV); 163 148 164 hc_manager(); 149 165 -
uspace/srv/hw/bus/usb/hcd/virtual/vhcd.h
raf894a21 r1d1f894 37 37 38 38 #define NAME "hcd-virt" 39 #define NAME_DEV "hcd-virt-dev" 39 40 #define NAMESPACE "usb" 40 41 41 #define DEVMAP_PATH NAMESPACE "/" NAME 42 #define DEVMAP_PATH_HC NAMESPACE "/" NAME 43 #define DEVMAP_PATH_DEV NAMESPACE "/" NAME_DEV 42 44 43 45 extern int debug_level;
Note:
See TracChangeset
for help on using the changeset viewer.