Changes in uspace/drv/bus/usb/vhc/transfer.c [58563585:9d58539] in mainline
- File:
-
- 1 edited
-
uspace/drv/bus/usb/vhc/transfer.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/vhc/transfer.c
r58563585 r9d58539 29 29 #include <errno.h> 30 30 #include <str_error.h> 31 #include <usb/debug.h>32 31 #include <usbvirt/device.h> 33 32 #include <usbvirt/ipc.h> 34 33 #include "vhcd.h" 35 #include "hub/virthub.h" 34 35 vhc_transfer_t *vhc_transfer_create(usb_address_t address, usb_endpoint_t ep, 36 usb_direction_t dir, usb_transfer_type_t tr_type, 37 ddf_fun_t *fun, void *callback_arg) 38 { 39 vhc_transfer_t *result = malloc(sizeof(vhc_transfer_t)); 40 if (result == NULL) { 41 return NULL; 42 } 43 link_initialize(&result->link); 44 result->address = address; 45 result->endpoint = ep; 46 result->direction = dir; 47 result->transfer_type = tr_type; 48 result->setup_buffer = NULL; 49 result->setup_buffer_size = 0; 50 result->data_buffer = NULL; 51 result->data_buffer_size = 0; 52 result->ddf_fun = fun; 53 result->callback_arg = callback_arg; 54 result->callback_in = NULL; 55 result->callback_out = NULL; 56 57 usb_log_debug2("Created transfer %p (%d.%d %s %s)\n", result, 58 address, ep, usb_str_transfer_type_short(tr_type), 59 dir == USB_DIRECTION_IN ? "in" : "out"); 60 61 return result; 62 } 36 63 37 64 static bool is_set_address_transfer(vhc_transfer_t *transfer) 38 65 { 39 if (transfer->batch->ep->endpoint != 0) { 40 return false; 41 } 42 if (transfer->batch->ep->transfer_type != USB_TRANSFER_CONTROL) { 43 return false; 44 } 45 if (usb_transfer_batch_direction(transfer->batch) != USB_DIRECTION_OUT) { 46 return false; 47 } 48 const usb_device_request_setup_packet_t *setup = 49 (void*)transfer->batch->setup_buffer; 66 if (transfer->endpoint != 0) { 67 return false; 68 } 69 if (transfer->transfer_type != USB_TRANSFER_CONTROL) { 70 return false; 71 } 72 if (transfer->direction != USB_DIRECTION_OUT) { 73 return false; 74 } 75 if (transfer->setup_buffer_size != sizeof(usb_device_request_setup_packet_t)) { 76 return false; 77 } 78 usb_device_request_setup_packet_t *setup = transfer->setup_buffer; 50 79 if (setup->request_type != 0) { 51 80 return false; … … 58 87 } 59 88 60 static int process_transfer_local(usb_transfer_batch_t *batch, 89 int vhc_virtdev_add_transfer(vhc_data_t *vhc, vhc_transfer_t *transfer) 90 { 91 fibril_mutex_lock(&vhc->guard); 92 93 bool target_found = false; 94 list_foreach(vhc->devices, pos) { 95 vhc_virtdev_t *dev = list_get_instance(pos, vhc_virtdev_t, link); 96 fibril_mutex_lock(&dev->guard); 97 if (dev->address == transfer->address) { 98 if (target_found) { 99 usb_log_warning("Transfer would be accepted by more devices!\n"); 100 goto next; 101 } 102 target_found = true; 103 list_append(&transfer->link, &dev->transfer_queue); 104 } 105 next: 106 fibril_mutex_unlock(&dev->guard); 107 } 108 109 fibril_mutex_unlock(&vhc->guard); 110 111 if (target_found) { 112 return EOK; 113 } else { 114 return ENOENT; 115 } 116 } 117 118 static int process_transfer_local(vhc_transfer_t *transfer, 61 119 usbvirt_device_t *dev, size_t *actual_data_size) 62 120 { 63 121 int rc; 64 65 const usb_direction_t dir = usb_transfer_batch_direction(batch); 66 67 if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) { 68 if (dir == USB_DIRECTION_IN) { 122 123 if (transfer->transfer_type == USB_TRANSFER_CONTROL) { 124 if (transfer->direction == USB_DIRECTION_IN) { 69 125 rc = usbvirt_control_read(dev, 70 batch->setup_buffer, batch->setup_size,71 batch->buffer, batch->buffer_size,72 actual_data_size); 73 } else { 74 assert( dir== USB_DIRECTION_OUT);126 transfer->setup_buffer, transfer->setup_buffer_size, 127 transfer->data_buffer, transfer->data_buffer_size, 128 actual_data_size); 129 } else { 130 assert(transfer->direction == USB_DIRECTION_OUT); 75 131 rc = usbvirt_control_write(dev, 76 batch->setup_buffer, batch->setup_size,77 batch->buffer, batch->buffer_size);78 } 79 } else { 80 if ( dir== USB_DIRECTION_IN) {81 rc = usbvirt_data_in(dev, batch->ep->transfer_type,82 batch->ep->endpoint,83 batch->buffer, batch->buffer_size,84 actual_data_size); 85 } else { 86 assert( dir== USB_DIRECTION_OUT);87 rc = usbvirt_data_out(dev, batch->ep->transfer_type,88 batch->ep->endpoint,89 batch->buffer, batch->buffer_size);132 transfer->setup_buffer, transfer->setup_buffer_size, 133 transfer->data_buffer, transfer->data_buffer_size); 134 } 135 } else { 136 if (transfer->direction == USB_DIRECTION_IN) { 137 rc = usbvirt_data_in(dev, transfer->transfer_type, 138 transfer->endpoint, 139 transfer->data_buffer, transfer->data_buffer_size, 140 actual_data_size); 141 } else { 142 assert(transfer->direction == USB_DIRECTION_OUT); 143 rc = usbvirt_data_out(dev, transfer->transfer_type, 144 transfer->endpoint, 145 transfer->data_buffer, transfer->data_buffer_size); 90 146 } 91 147 } … … 94 150 } 95 151 96 static int process_transfer_remote( usb_transfer_batch_t *batch,152 static int process_transfer_remote(vhc_transfer_t *transfer, 97 153 async_sess_t *sess, size_t *actual_data_size) 98 154 { 99 155 int rc; 100 156 101 const usb_direction_t dir = usb_transfer_batch_direction(batch); 102 103 if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) { 104 if (dir == USB_DIRECTION_IN) { 157 if (transfer->transfer_type == USB_TRANSFER_CONTROL) { 158 if (transfer->direction == USB_DIRECTION_IN) { 105 159 rc = usbvirt_ipc_send_control_read(sess, 106 batch->setup_buffer, batch->setup_size,107 batch->buffer, batch->buffer_size,108 actual_data_size); 109 } else { 110 assert( dir== USB_DIRECTION_OUT);160 transfer->setup_buffer, transfer->setup_buffer_size, 161 transfer->data_buffer, transfer->data_buffer_size, 162 actual_data_size); 163 } else { 164 assert(transfer->direction == USB_DIRECTION_OUT); 111 165 rc = usbvirt_ipc_send_control_write(sess, 112 batch->setup_buffer, batch->setup_size,113 batch->buffer, batch->buffer_size);114 } 115 } else { 116 if ( dir== USB_DIRECTION_IN) {117 rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,118 batch->ep->transfer_type,119 batch->buffer, batch->buffer_size,120 actual_data_size); 121 } else { 122 assert( dir== USB_DIRECTION_OUT);123 rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,124 batch->ep->transfer_type,125 batch->buffer, batch->buffer_size);166 transfer->setup_buffer, transfer->setup_buffer_size, 167 transfer->data_buffer, transfer->data_buffer_size); 168 } 169 } else { 170 if (transfer->direction == USB_DIRECTION_IN) { 171 rc = usbvirt_ipc_send_data_in(sess, transfer->endpoint, 172 transfer->transfer_type, 173 transfer->data_buffer, transfer->data_buffer_size, 174 actual_data_size); 175 } else { 176 assert(transfer->direction == USB_DIRECTION_OUT); 177 rc = usbvirt_ipc_send_data_out(sess, transfer->endpoint, 178 transfer->transfer_type, 179 transfer->data_buffer, transfer->data_buffer_size); 126 180 } 127 181 } … … 142 196 } 143 197 198 144 199 static void execute_transfer_callback_and_free(vhc_transfer_t *transfer, 145 200 size_t data_transfer_size, int outcome) 146 201 { 147 202 assert(outcome != ENAK); 148 assert(transfer); 149 assert(transfer->batch); 150 usb_transfer_batch_finish_error(transfer->batch, NULL, 151 data_transfer_size, outcome); 152 usb_transfer_batch_destroy(transfer->batch); 203 204 usb_log_debug2("Transfer %p ended: %s.\n", 205 transfer, str_error(outcome)); 206 207 if (transfer->direction == USB_DIRECTION_IN) { 208 transfer->callback_in(transfer->ddf_fun, outcome, 209 data_transfer_size, transfer->callback_arg); 210 } else { 211 assert(transfer->direction == USB_DIRECTION_OUT); 212 transfer->callback_out(transfer->ddf_fun, outcome, 213 transfer->callback_arg); 214 } 215 153 216 free(transfer); 154 }155 156 int vhc_init(vhc_data_t *instance)157 {158 assert(instance);159 list_initialize(&instance->devices);160 fibril_mutex_initialize(&instance->guard);161 instance->magic = 0xDEADBEEF;162 return virthub_init(&instance->hub, "root hub");163 }164 165 int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)166 {167 assert(hcd);168 assert(batch);169 vhc_data_t *vhc = hcd_get_driver_data(hcd);170 assert(vhc);171 172 vhc_transfer_t *transfer = malloc(sizeof(vhc_transfer_t));173 if (!transfer)174 return ENOMEM;175 link_initialize(&transfer->link);176 transfer->batch = batch;177 178 fibril_mutex_lock(&vhc->guard);179 180 int targets = 0;181 182 list_foreach(vhc->devices, link, vhc_virtdev_t, dev) {183 fibril_mutex_lock(&dev->guard);184 if (dev->address == transfer->batch->ep->address) {185 if (!targets) {186 list_append(&transfer->link, &dev->transfer_queue);187 }188 ++targets;189 }190 fibril_mutex_unlock(&dev->guard);191 }192 193 fibril_mutex_unlock(&vhc->guard);194 195 if (targets > 1)196 usb_log_warning("Transfer would be accepted by more devices!\n");197 198 return targets ? EOK : ENOENT;199 217 } 200 218 … … 217 235 size_t data_transfer_size = 0; 218 236 if (dev->dev_sess) { 219 rc = process_transfer_remote(transfer ->batch,220 dev->dev_sess,&data_transfer_size);237 rc = process_transfer_remote(transfer, dev->dev_sess, 238 &data_transfer_size); 221 239 } else if (dev->dev_local != NULL) { 222 rc = process_transfer_local(transfer ->batch,223 dev->dev_local,&data_transfer_size);240 rc = process_transfer_local(transfer, dev->dev_local, 241 &data_transfer_size); 224 242 } else { 225 243 usb_log_warning("Device has no remote phone nor local node.\n"); … … 233 251 if (rc == EOK) { 234 252 if (is_set_address_transfer(transfer)) { 235 usb_device_request_setup_packet_t *setup =236 (void*) transfer->batch->setup_buffer;253 usb_device_request_setup_packet_t *setup 254 = transfer->setup_buffer; 237 255 dev->address = setup->value; 238 256 usb_log_debug2("Address changed to %d\n", … … 267 285 return EOK; 268 286 } 287
Note:
See TracChangeset
for help on using the changeset viewer.
