Changeset f5f0cfb in mainline for uspace/drv/bus/usb/vhc/transfer.c
- Timestamp:
- 2012-12-22T16:24:28Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1e2af6a9
- Parents:
- f6577d9
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/vhc/transfer.c
rf6577d9 rf5f0cfb 33 33 #include <usbvirt/ipc.h> 34 34 #include "vhcd.h" 35 #include "hub/virthub.h" 36 37 static bool is_set_address_transfer(vhc_transfer_t *transfer) 38 { 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; 50 if (setup->request_type != 0) { 51 return false; 52 } 53 if (setup->request != USB_DEVREQ_SET_ADDRESS) { 54 return false; 55 } 56 57 return true; 58 } 59 60 static int process_transfer_local(usb_transfer_batch_t *batch, 61 usbvirt_device_t *dev, size_t *actual_data_size) 62 { 63 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) { 69 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); 75 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); 90 } 91 } 92 93 return rc; 94 } 95 96 static int process_transfer_remote(usb_transfer_batch_t *batch, 97 async_sess_t *sess, size_t *actual_data_size) 98 { 99 int rc; 100 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) { 105 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); 111 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); 126 } 127 } 128 129 return rc; 130 } 131 132 static vhc_transfer_t *dequeue_first_transfer(vhc_virtdev_t *dev) 133 { 134 assert(fibril_mutex_is_locked(&dev->guard)); 135 assert(!list_empty(&dev->transfer_queue)); 136 137 vhc_transfer_t *transfer = list_get_instance( 138 list_first(&dev->transfer_queue), vhc_transfer_t, link); 139 list_remove(&transfer->link); 140 141 return transfer; 142 } 143 144 static void execute_transfer_callback_and_free(vhc_transfer_t *transfer, 145 size_t data_transfer_size, int outcome) 146 { 147 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); 153 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 } 35 164 36 165 int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) … … 69 198 70 199 return targets ? EOK : ENOENT; 71 }72 73 static bool is_set_address_transfer(vhc_transfer_t *transfer)74 {75 if (transfer->batch->ep->endpoint != 0) {76 return false;77 }78 if (transfer->batch->ep->transfer_type != USB_TRANSFER_CONTROL) {79 return false;80 }81 if (usb_transfer_batch_direction(transfer->batch) != USB_DIRECTION_OUT) {82 return false;83 }84 const usb_device_request_setup_packet_t *setup =85 (void*)transfer->batch->setup_buffer;86 if (setup->request_type != 0) {87 return false;88 }89 if (setup->request != USB_DEVREQ_SET_ADDRESS) {90 return false;91 }92 93 return true;94 }95 96 static int process_transfer_local(usb_transfer_batch_t *batch,97 usbvirt_device_t *dev, size_t *actual_data_size)98 {99 int rc;100 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) {105 rc = usbvirt_control_read(dev,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);111 rc = usbvirt_control_write(dev,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_data_in(dev, batch->ep->transfer_type,118 batch->ep->endpoint,119 batch->buffer, batch->buffer_size,120 actual_data_size);121 } else {122 assert(dir == USB_DIRECTION_OUT);123 rc = usbvirt_data_out(dev, batch->ep->transfer_type,124 batch->ep->endpoint,125 batch->buffer, batch->buffer_size);126 }127 }128 129 return rc;130 }131 132 static int process_transfer_remote(usb_transfer_batch_t *batch,133 async_sess_t *sess, size_t *actual_data_size)134 {135 int rc;136 137 const usb_direction_t dir = usb_transfer_batch_direction(batch);138 139 if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {140 if (dir == USB_DIRECTION_IN) {141 rc = usbvirt_ipc_send_control_read(sess,142 batch->setup_buffer, batch->setup_size,143 batch->buffer, batch->buffer_size,144 actual_data_size);145 } else {146 assert(dir == USB_DIRECTION_OUT);147 rc = usbvirt_ipc_send_control_write(sess,148 batch->setup_buffer, batch->setup_size,149 batch->buffer, batch->buffer_size);150 }151 } else {152 if (dir == USB_DIRECTION_IN) {153 rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,154 batch->ep->transfer_type,155 batch->buffer, batch->buffer_size,156 actual_data_size);157 } else {158 assert(dir == USB_DIRECTION_OUT);159 rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,160 batch->ep->transfer_type,161 batch->buffer, batch->buffer_size);162 }163 }164 165 return rc;166 }167 168 static vhc_transfer_t *dequeue_first_transfer(vhc_virtdev_t *dev)169 {170 assert(fibril_mutex_is_locked(&dev->guard));171 assert(!list_empty(&dev->transfer_queue));172 173 vhc_transfer_t *transfer = list_get_instance(174 list_first(&dev->transfer_queue), vhc_transfer_t, link);175 list_remove(&transfer->link);176 177 return transfer;178 }179 180 static void execute_transfer_callback_and_free(vhc_transfer_t *transfer,181 size_t data_transfer_size, int outcome)182 {183 assert(outcome != ENAK);184 assert(transfer);185 assert(transfer->batch);186 usb_transfer_batch_finish_error(transfer->batch, NULL,187 data_transfer_size, outcome);188 usb_transfer_batch_destroy(transfer->batch);189 free(transfer);190 200 } 191 201
Note:
See TracChangeset
for help on using the changeset viewer.