Changeset bc9a629 in mainline for uspace/srv/hw/bus/usb/hcd/virtual/hc.c
- Timestamp:
- 2010-10-10T09:00:53Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b371844
- Parents:
- 4bc309b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/bus/usb/hcd/virtual/hc.c
r4bc309b rbc9a629 40 40 #include <stdlib.h> 41 41 #include <stdio.h> 42 #include <errno.h> 43 #include <str_error.h> 44 45 #include <usb/virtdev.h> 42 46 43 47 #include "vhcd.h" 44 48 #include "hc.h" 49 #include "devices.h" 45 50 46 51 #define USLEEP_BASE (500 * 1000) … … 60 65 } while (0) 61 66 62 static link_t transaction_list; 67 static link_t transaction_to_device_list; 68 static link_t transaction_from_device_list; 63 69 64 70 … … 97 103 usb_str_transaction_outcome(outcome)); 98 104 105 dprintf(" callback %p (%p, %u, %d, %p)", transaction->callback, 106 transaction->buffer, transaction->len, outcome, 107 transaction->callback_arg); 108 99 109 transaction->callback(transaction->buffer, transaction->len, outcome, 100 110 transaction->callback_arg); 101 } 102 111 dprintf("callback processed"); 112 } 113 114 #if 0 103 115 static void process_transaction(transaction_t * transaction) 104 116 { … … 113 125 process_transaction_with_outcome(transaction, outcome); 114 126 } 127 #endif 115 128 116 129 void hc_manager(void) 117 130 { 118 list_initialize(&transaction_list); 131 list_initialize(&transaction_to_device_list); 132 list_initialize(&transaction_from_device_list); 119 133 120 134 static unsigned int seed = 4573; … … 125 139 async_usleep(USLEEP_BASE + (pseudo_random(&seed) % USLEEP_VAR)); 126 140 127 if (list_empty(&transaction_ list)) {141 if (list_empty(&transaction_to_device_list)) { 128 142 continue; 129 143 } 130 144 131 link_t * first_transaction_link = transaction_ list.next;132 transaction_t * first_transaction145 link_t * first_transaction_link = transaction_to_device_list.next; 146 transaction_t * transaction 133 147 = transaction_get_instance(first_transaction_link); 134 148 list_remove(first_transaction_link); 135 149 136 process_transaction(first_transaction); 137 138 free(first_transaction); 139 } 140 } 141 142 static void hc_add_transaction(usb_transfer_type_t type, usb_target_t target, 150 virtdev_connection_t *dev = virtdev_find_by_address( 151 transaction->target.address); 152 if (dev != NULL) { 153 dprintf("sending data to device at %d.%d (phone %d)\n", 154 dev->address, transaction->target.endpoint, 155 dev->phone); 156 ipc_call_t answer_data; 157 ipcarg_t answer_rc; 158 aid_t req; 159 int rc; 160 161 req = async_send_2(dev->phone, 162 IPC_M_USB_VIRTDEV_DATA_TO_DEVICE, 163 transaction->target.endpoint, 164 transaction->type, 165 &answer_data); 166 167 rc = async_data_write_start(dev->phone, 168 transaction->buffer, transaction->len); 169 if (rc != EOK) { 170 async_wait_for(req, NULL); 171 } else { 172 async_wait_for(req, &answer_rc); 173 rc = (int)answer_rc; 174 } 175 } else { 176 process_transaction_with_outcome(transaction, 177 USB_OUTCOME_OK); 178 } 179 180 free(transaction); 181 } 182 } 183 184 static transaction_t *transaction_create(usb_transfer_type_t type, usb_target_t target, 143 185 usb_direction_t direction, 144 186 void * buffer, size_t len, … … 156 198 transaction->callback_arg = arg; 157 199 158 dprintf("adding transaction " TRANSACTION_FORMAT, 159 TRANSACTION_PRINTF(*transaction)); 160 161 list_append(&transaction->link, &transaction_list); 162 } 163 164 void hc_add_out_transaction(usb_transfer_type_t type, usb_target_t target, 200 return transaction; 201 } 202 203 204 void hc_add_transaction_to_device(usb_transfer_type_t type, usb_target_t target, 165 205 void * buffer, size_t len, 166 206 hc_transaction_done_callback_t callback, void * arg) 167 207 { 168 hc_add_transaction(type, target, USB_DIRECTION_OUT, 169 buffer, len, callback, arg); 170 } 171 172 void hc_add_in_transaction(usb_transfer_type_t type, usb_target_t target, 208 transaction_t *transaction = transaction_create(type, target, 209 USB_DIRECTION_OUT, buffer, len, callback, arg); 210 list_append(&transaction->link, &transaction_to_device_list); 211 } 212 213 void hc_add_transaction_from_device(usb_transfer_type_t type, usb_target_t target, 173 214 void * buffer, size_t len, 174 215 hc_transaction_done_callback_t callback, void * arg) 175 216 { 176 static unsigned int seed = 216; 177 178 size_t i; 179 char * data = (char *)buffer; 180 for (i = 0; i < len; i++, data++) { 181 *data = 'A' + (pseudo_random(&seed) % ('Z' - 'A')); 182 } 183 184 unsigned int shortening = pseudo_random(&seed) % SHORTENING_VAR; 185 if (len > shortening) { 186 len -= shortening; 187 } 188 189 hc_add_transaction(type, target, USB_DIRECTION_IN, 190 buffer, len, callback, arg); 217 transaction_t *transaction = transaction_create(type, target, 218 USB_DIRECTION_IN, buffer, len, callback, arg); 219 list_append(&transaction->link, &transaction_from_device_list); 220 } 221 222 int hc_fillin_transaction_from_device(usb_transfer_type_t type, usb_target_t target, 223 void * buffer, size_t len) 224 { 225 dprintf("finding transaction to fill data in..."); 226 /* 227 * Find correct transaction envelope in the list. 228 */ 229 if (list_empty(&transaction_from_device_list)) { 230 return ENOENT; 231 } 232 233 transaction_t *transaction = NULL; 234 link_t *pos = transaction_from_device_list.next; 235 236 while (pos != &transaction_from_device_list) { 237 transaction_t *t = transaction_get_instance(pos); 238 if (usb_target_same(t->target, target)) { 239 transaction = t; 240 break; 241 } 242 pos = pos->next; 243 } 244 if (transaction == NULL) { 245 return ENOENT; 246 } 247 248 /* 249 * Remove the transaction from the list as it will be processed now. 250 */ 251 list_remove(&transaction->link); 252 253 if (transaction->len < len) { 254 process_transaction_with_outcome(transaction, USB_OUTCOME_BABBLE); 255 return ENOMEM; 256 } 257 258 /* 259 * Copy the data and finish processing the transaction. 260 */ 261 transaction->len = len; 262 memcpy(transaction->buffer, buffer, len); 263 264 process_transaction_with_outcome(transaction, USB_OUTCOME_OK); 265 266 dprintf(" ...transaction " TRANSACTION_FORMAT " sent back", 267 TRANSACTION_PRINTF(*transaction)); 268 269 270 free(transaction); 271 272 return EOK; 191 273 } 192 274
Note:
See TracChangeset
for help on using the changeset viewer.