Changeset 7a7bfeb3 in mainline
- Timestamp:
- 2010-10-24T16:43:40Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 355f7c2
- Parents:
- b8a3cda
- Location:
- uspace
- Files:
-
- 1 added
- 1 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/virtusbkbd/stdreq.c
rb8a3cda r7a7bfeb3 65 65 * report descriptor. 66 66 */ 67 int rc = dev-> send_data(dev, 0,67 int rc = dev->control_transfer_reply(dev, 0, 68 68 report_descriptor, report_descriptor_size); 69 69 -
uspace/app/virtusbkbd/virtusbkbd.c
rb8a3cda r7a7bfeb3 67 67 (printf("%s: %s" fmt "\n", NAME, _QUOTEME(cmd), __VA_ARGS__), cmd(__VA_ARGS__)) 68 68 69 kb_status_t status; 70 69 71 static int on_incoming_data(struct usbvirt_device *dev, 70 72 usb_endpoint_t endpoint, void *buffer, size_t size) … … 83 85 } 84 86 87 static int on_request_for_data(struct usbvirt_device *dev, 88 usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size) 89 { 90 if (size < 2 + KB_MAX_KEYS_AT_ONCE) { 91 return EINVAL; 92 } 93 94 *actual_size = 2 + KB_MAX_KEYS_AT_ONCE; 95 96 uint8_t data[2 + KB_MAX_KEYS_AT_ONCE]; 97 data[0] = status.modifiers; 98 data[1] = 0; 99 100 size_t i; 101 for (i = 0; i < KB_MAX_KEYS_AT_ONCE; i++) { 102 data[2 + i] = status.pressed_keys[i]; 103 } 104 105 memcpy(buffer, &data, *actual_size); 106 107 return EOK; 108 } 109 110 85 111 /** Keyboard callbacks. 86 112 * We abuse the fact that static variables are zero-filled. … … 89 115 .standard_request_ops = &standard_request_ops, 90 116 .on_class_device_request = on_class_request, 91 .on_data = on_incoming_data 117 .on_data = on_incoming_data, 118 .on_data_request = on_request_for_data 92 119 }; 93 120 … … 151 178 } 152 179 printf("\n"); 153 154 uint8_t data[3 + KB_MAX_KEYS_AT_ONCE];155 data[0] = status->modifiers;156 data[1] = 0;157 data[2] = 0;158 for (i = 0; i < KB_MAX_KEYS_AT_ONCE; i++) {159 data[3 + i] = status->pressed_keys[i];160 }161 162 int rc = keyboard_dev.send_data(&keyboard_dev, 0, data, sizeof(data));163 printf("%s: Sent to VHCD (%s).\n", NAME, str_error(rc));164 180 165 181 fibril_sleep(1); … … 198 214 } 199 215 216 kb_init(&status); 217 200 218 201 219 int rc = usbvirt_connect(&keyboard_dev, DEV_HCD_NAME); … … 206 224 } 207 225 208 kb_status_t status;209 kb_init(&status);210 211 226 printf("%s: Simulating keyboard events...\n", NAME); 212 227 kb_process_events(&status, keyboard_events, keyboard_events_count, -
uspace/lib/usb/usb.h
rb8a3cda r7a7bfeb3 64 64 typedef int usb_endpoint_t; 65 65 66 /** Maximum endpoint number in USB 1.1. 67 */ 68 #define USB11_ENDPOINT_MAX 16 69 70 66 71 /** USB complete address type. 67 72 * Pair address + endpoint is identification of transaction recipient. -
uspace/lib/usbvirt/Makefile
rb8a3cda r7a7bfeb3 35 35 SOURCES = \ 36 36 ctrlpipe.c \ 37 incoming.c \38 37 main.c \ 39 stdreq.c 38 stdreq.c \ 39 transaction.c 40 40 41 41 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usbvirt/ctrlpipe.c
rb8a3cda r7a7bfeb3 53 53 54 54 55 56 int control_pipe(void *buffer, size_t size) 55 int control_pipe(usbvirt_control_transfer_t *transfer) 57 56 { 58 if ( size < sizeof(usb_device_request_setup_packet_t)) {57 if (transfer->request_size < sizeof(usb_device_request_setup_packet_t)) { 59 58 return ENOMEM; 60 59 } 61 60 62 usb_device_request_setup_packet_t *request = (usb_device_request_setup_packet_t *) buffer;63 uint8_t *remaining_data = ((uint8_t *) request) + sizeof(usb_device_request_setup_packet_t);61 usb_device_request_setup_packet_t *request = (usb_device_request_setup_packet_t *) transfer->request; 62 uint8_t *remaining_data = transfer->data; 64 63 65 64 int type = request_get_type(request->request_type); … … 80 79 break; 81 80 } 82 83 device->send_data(device, 0, NULL, 0);84 81 85 82 if (dev_new_address != -1) { -
uspace/lib/usbvirt/device.h
rb8a3cda r7a7bfeb3 41 41 42 42 struct usbvirt_device; 43 struct usbvirt_control_transfer; 43 44 44 45 typedef int (*usbvirt_on_device_request_t)(struct usbvirt_device *dev, … … 70 71 /** Callback for class-specific USB request. */ 71 72 usbvirt_on_device_request_t on_class_device_request; 73 74 int (*on_control_transfer)(struct usbvirt_device *dev, 75 usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer); 76 72 77 /** Callback for all other incoming data. */ 73 78 int (*on_data)(struct usbvirt_device *dev, 79 usb_endpoint_t endpoint, void *buffer, size_t size); 80 81 /** Callback for host request for data. */ 82 int (*on_data_request)(struct usbvirt_device *dev, 83 usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size); 84 85 /** Decides direction of control transfer. */ 86 usb_direction_t (*decide_control_transfer_direction)( 74 87 usb_endpoint_t endpoint, void *buffer, size_t size); 75 88 } usbvirt_device_ops_t; … … 117 130 } usbvirt_device_state_t; 118 131 132 /** Information about on-going control transfer. 133 */ 134 typedef struct usbvirt_control_transfer { 135 usb_direction_t direction; 136 void *request; 137 size_t request_size; 138 void *data; 139 size_t data_size; 140 } usbvirt_control_transfer_t; 141 119 142 /** Virtual USB device. */ 120 143 typedef struct usbvirt_device { … … 122 145 usbvirt_device_ops_t *ops; 123 146 124 /** Send data to HC. 125 * @warning Do not change after initializing with 126 * usbvirt_device_init(). 127 * This function is here merely to make the interface more OOP. 147 148 /** Reply onto control transfer. 128 149 */ 129 int (* send_data)(struct usbvirt_device *dev,150 int (*control_transfer_reply)(struct usbvirt_device *dev, 130 151 usb_endpoint_t endpoint, void *buffer, size_t size); 131 152 … … 153 174 int device_id_; 154 175 155 /** Main routine called when data is received from HC. 156 * @warning Do not change after initializing with 157 * usbvirt_device_init(). 158 * This function is here merely to make the interface more OOP. 159 */ 160 int (*receive_data)(struct usbvirt_device *dev, 176 int (*transaction_out)(struct usbvirt_device *dev, 161 177 usb_endpoint_t endpoint, void *buffer, size_t size); 178 int (*transaction_setup)(struct usbvirt_device *dev, 179 usb_endpoint_t endpoint, void *buffer, size_t size); 180 int (*transaction_in)(struct usbvirt_device *dev, 181 usb_endpoint_t endpoint, void *buffer, size_t size, size_t *data_size); 162 182 183 usbvirt_control_transfer_t current_control_transfers[USB11_ENDPOINT_MAX]; 163 184 } usbvirt_device_t; 164 185 -
uspace/lib/usbvirt/hub.h
rb8a3cda r7a7bfeb3 41 41 typedef enum { 42 42 IPC_M_USBVIRT_DATA_TO_DEVICE = IPC_FIRST_USER_METHOD, 43 IPC_M_USBVIRT_DATA_FROM_DEVICE 43 IPC_M_USBVIRT_DATA_FROM_DEVICE, 44 IPC_M_USBVIRT_TRANSACTION_SETUP, 45 IPC_M_USBVIRT_TRANSACTION_OUT, 46 IPC_M_USBVIRT_TRANSACTION_IN, 44 47 } usbvirt_device_method_t; 45 48 -
uspace/lib/usbvirt/main.c
rb8a3cda r7a7bfeb3 38 38 #include <errno.h> 39 39 #include <stdlib.h> 40 #include <mem.h> 40 41 41 42 #include "hub.h" … … 47 48 usbvirt_device_t *device = NULL; 48 49 49 50 static void handle_data_to_device(ipc_callid_t iid, ipc_call_t icall) 50 static void handle_setup_transaction(ipc_callid_t iid, ipc_call_t icall) 51 51 { 52 52 usb_address_t address = IPC_GET_ARG1(icall); 53 53 usb_endpoint_t endpoint = IPC_GET_ARG2(icall); 54 size_t expected_len = IPC_GET_ARG 5(icall);54 size_t expected_len = IPC_GET_ARG3(icall); 55 55 56 56 if (address != device->address) { … … 59 59 } 60 60 61 if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) { 62 ipc_answer_0(iid, EINVAL); 63 return; 64 } 65 66 if (expected_len == 0) { 67 ipc_answer_0(iid, EINVAL); 68 return; 69 } 70 61 71 size_t len = 0; 62 72 void * buffer = NULL; 73 int rc = async_data_write_accept(&buffer, false, 74 1, USB_MAX_PAYLOAD_SIZE, 0, &len); 75 76 if (rc != EOK) { 77 ipc_answer_0(iid, rc); 78 return; 79 } 80 81 rc = device->transaction_setup(device, endpoint, buffer, len); 82 83 ipc_answer_0(iid, rc); 84 } 85 86 87 static void handle_out_transaction(ipc_callid_t iid, ipc_call_t icall) 88 { 89 usb_address_t address = IPC_GET_ARG1(icall); 90 usb_endpoint_t endpoint = IPC_GET_ARG2(icall); 91 size_t expected_len = IPC_GET_ARG3(icall); 92 93 if (address != device->address) { 94 ipc_answer_0(iid, EADDRNOTAVAIL); 95 return; 96 } 97 98 if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) { 99 ipc_answer_0(iid, EINVAL); 100 return; 101 } 102 103 int rc = EOK; 104 105 size_t len = 0; 106 void *buffer = NULL; 107 63 108 if (expected_len > 0) { 64 int rc = async_data_write_accept(&buffer, false, 65 1, USB_MAX_PAYLOAD_SIZE, 66 0, &len); 67 109 rc = async_data_write_accept(&buffer, false, 110 1, USB_MAX_PAYLOAD_SIZE, 0, &len); 111 68 112 if (rc != EOK) { 69 113 ipc_answer_0(iid, rc); … … 72 116 } 73 117 74 device->receive_data(device, endpoint, buffer, len);118 rc = device->transaction_out(device, endpoint, buffer, len); 75 119 76 120 if (buffer != NULL) { … … 78 122 } 79 123 80 ipc_answer_0(iid, EOK); 81 } 124 ipc_answer_0(iid, rc); 125 } 126 127 128 129 static void handle_in_transaction(ipc_callid_t iid, ipc_call_t icall) 130 { 131 usb_address_t address = IPC_GET_ARG1(icall); 132 usb_endpoint_t endpoint = IPC_GET_ARG2(icall); 133 size_t expected_len = IPC_GET_ARG3(icall); 134 135 if (address != device->address) { 136 ipc_answer_0(iid, EADDRNOTAVAIL); 137 return; 138 } 139 140 if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) { 141 ipc_answer_0(iid, EINVAL); 142 return; 143 } 144 145 int rc = EOK; 146 147 void *buffer = expected_len > 0 ? malloc(expected_len) : NULL; 148 size_t len; 149 150 rc = device->transaction_in(device, endpoint, buffer, expected_len, &len); 151 /* 152 * If the request was processed, we will send data back. 153 */ 154 if (rc == EOK) { 155 size_t receive_len; 156 if (!async_data_read_receive(&iid, &receive_len)) { 157 ipc_answer_0(iid, EINVAL); 158 return; 159 } 160 async_data_read_finalize(iid, buffer, receive_len); 161 } 162 163 ipc_answer_0(iid, rc); 164 } 165 166 82 167 83 168 static void callback_connection(ipc_callid_t iid, ipc_call_t *icall) … … 95 180 return; 96 181 97 case IPC_M_USBVIRT_DATA_TO_DEVICE: 98 handle_data_to_device(callid, call); 182 case IPC_M_USBVIRT_TRANSACTION_SETUP: 183 handle_setup_transaction(callid, call); 184 break; 185 186 case IPC_M_USBVIRT_TRANSACTION_OUT: 187 handle_out_transaction(callid, call); 188 break; 189 190 case IPC_M_USBVIRT_TRANSACTION_IN: 191 handle_in_transaction(callid, call); 99 192 break; 100 193 … … 106 199 } 107 200 201 static int control_transfer_reply(struct usbvirt_device *device, 202 usb_endpoint_t endpoint, void *buffer, size_t size) 203 { 204 usbvirt_control_transfer_t *transfer = &device->current_control_transfers[endpoint]; 205 if (transfer->data != NULL) { 206 free(transfer->data); 207 } 208 transfer->data = malloc(size); 209 memcpy(transfer->data, buffer, size); 210 transfer->data_size = size; 211 212 return EOK; 213 } 214 108 215 static void device_init(usbvirt_device_t *dev) 109 216 { 110 dev->send_data = usbvirt_data_to_host; 111 dev->receive_data = handle_incoming_data; 217 dev->transaction_out = transaction_out; 218 dev->transaction_setup = transaction_setup; 219 dev->transaction_in = transaction_in; 220 221 dev->control_transfer_reply = control_transfer_reply; 222 112 223 dev->state = USBVIRT_STATE_DEFAULT; 113 224 dev->address = 0; 114 } 115 116 int usbvirt_data_to_host(struct usbvirt_device *dev, 117 usb_endpoint_t endpoint, void *buffer, size_t size) 118 { 119 int phone = dev->vhcd_phone_; 120 121 if (phone < 0) { 122 return EINVAL; 123 } 124 if ((buffer == NULL) && (size != 0)) { 125 return EINVAL; 126 } 127 128 ipc_call_t answer_data; 129 ipcarg_t answer_rc; 130 aid_t req; 131 int rc; 132 133 req = async_send_3(phone, 134 IPC_M_USBVIRT_DATA_FROM_DEVICE, 135 dev->address, 136 endpoint, 137 size, 138 &answer_data); 139 140 if (size > 0) { 141 rc = async_data_write_start(phone, buffer, size); 142 if (rc != EOK) { 143 async_wait_for(req, NULL); 144 return rc; 145 } 146 } 147 148 async_wait_for(req, &answer_rc); 149 rc = (int)answer_rc; 150 if (rc != EOK) { 151 return rc; 152 } 153 154 return EOK; 225 226 size_t i; 227 for (i = 0; i < USB11_ENDPOINT_MAX; i++) { 228 usbvirt_control_transfer_t *transfer = &dev->current_control_transfers[i]; 229 transfer->direction = 0; 230 transfer->request = NULL; 231 transfer->request_size = 0; 232 transfer->data = NULL; 233 transfer->data_size = 0; 234 } 155 235 } 156 236 -
uspace/lib/usbvirt/private.h
rb8a3cda r7a7bfeb3 54 54 usb_endpoint_t endpoint, void *buffer, size_t size); 55 55 56 int control_pipe( void *buffer, size_t size);56 int control_pipe(usbvirt_control_transfer_t *transfer); 57 57 58 58 int handle_std_request(usb_device_request_setup_packet_t *request, uint8_t *data); … … 60 60 extern usb_address_t dev_new_address; 61 61 62 int transaction_setup(usbvirt_device_t *device, usb_endpoint_t endpoint, 63 void *buffer, size_t size); 64 int transaction_out(usbvirt_device_t *device, usb_endpoint_t endpoint, 65 void *buffer, size_t size); 66 int transaction_in(usbvirt_device_t *device, usb_endpoint_t endpoint, 67 void *buffer, size_t size, size_t *data_size); 68 62 69 #endif 63 70 /** -
uspace/lib/usbvirt/stdreq.c
rb8a3cda r7a7bfeb3 57 57 if ((type == USB_DESCTYPE_DEVICE) && (index == 0)) { 58 58 if (device->descriptors && device->descriptors->device) { 59 return device-> send_data(device, 0,59 return device->control_transfer_reply(device, 0, 60 60 device->descriptors->device, 61 61 device->descriptors->device->length); … … 95 95 } 96 96 97 int rc = device-> send_data(device, 0, all_data,98 config->descriptor->total_length);97 int rc = device->control_transfer_reply(device, 0, 98 all_data, config->descriptor->total_length); 99 99 100 100 free(all_data); -
uspace/srv/hw/bus/usb/hcd/virtual/conndev.c
rb8a3cda r7a7bfeb3 42 42 #include "hub.h" 43 43 44 /** Handle data from device to host.45 */46 static void handle_data_from_device(ipc_callid_t iid, ipc_call_t icall,47 virtdev_connection_t *dev)48 {49 usb_target_t target = {50 .address = IPC_GET_ARG1(icall),51 .endpoint = IPC_GET_ARG2(icall)52 };53 size_t len = IPC_GET_ARG3(icall);54 55 if (!hub_can_device_signal(dev)) {56 ipc_answer_0(iid, EREFUSED);57 return;58 }59 60 dprintf("data from device %d [%d.%d]", dev->id,61 target.address, target.endpoint);62 63 int rc;64 65 void * buffer = NULL;66 if (len > 0) {67 rc = async_data_write_accept(&buffer, false,68 1, USB_MAX_PAYLOAD_SIZE,69 0, &len);70 71 if (rc != EOK) {72 ipc_answer_0(iid, rc);73 return;74 }75 }76 77 rc = hc_fillin_transaction_from_device(target, buffer, len);78 79 ipc_answer_0(iid, rc);80 }81 82 44 /** Connection handler for communcation with virtual device. 83 45 * … … 110 72 break; 111 73 112 case IPC_M_USBVIRT_DATA_FROM_DEVICE:113 handle_data_from_device(callid, call, dev);114 break;115 116 74 default: 117 75 ipc_answer_0(callid, EINVAL); -
uspace/srv/hw/bus/usb/hcd/virtual/devices.c
rb8a3cda r7a7bfeb3 126 126 aid_t req; 127 127 int rc = EOK; 128 129 req = async_send_4(dev->phone, 130 IPC_M_USBVIRT_DATA_TO_DEVICE, 128 int method = IPC_M_USBVIRT_TRANSACTION_SETUP; 129 130 switch (transaction->type) { 131 case USBVIRT_TRANSACTION_SETUP: 132 method = IPC_M_USBVIRT_TRANSACTION_SETUP; 133 break; 134 case USBVIRT_TRANSACTION_IN: 135 method = IPC_M_USBVIRT_TRANSACTION_IN; 136 break; 137 case USBVIRT_TRANSACTION_OUT: 138 method = IPC_M_USBVIRT_TRANSACTION_OUT; 139 break; 140 } 141 142 req = async_send_3(dev->phone, 143 method, 131 144 transaction->target.address, 132 145 transaction->target.endpoint, 133 transaction->type,134 146 transaction->len, 135 147 &answer_data); 136 148 137 149 if (transaction->len > 0) { 138 rc = async_data_write_start(dev->phone, 139 transaction->buffer, transaction->len); 140 } 150 if (transaction->type == USBVIRT_TRANSACTION_IN) { 151 rc = async_data_read_start(dev->phone, 152 transaction->buffer, transaction->len); 153 } else { 154 rc = async_data_write_start(dev->phone, 155 transaction->buffer, transaction->len); 156 } 157 } 158 141 159 if (rc != EOK) { 142 160 async_wait_for(req, NULL); … … 152 170 */ 153 171 if (virthub_dev.address == transaction->target.address) { 154 virthub_dev.receive_data(&virthub_dev, transaction->target.endpoint, 155 transaction->buffer, transaction->len); 172 size_t tmp; 173 switch (transaction->type) { 174 case USBVIRT_TRANSACTION_SETUP: 175 virthub_dev.transaction_setup(&virthub_dev, 176 transaction->target.endpoint, 177 transaction->buffer, transaction->len); 178 break; 179 180 case USBVIRT_TRANSACTION_IN: 181 virthub_dev.transaction_in(&virthub_dev, 182 transaction->target.endpoint, 183 transaction->buffer, transaction->len, 184 &tmp); 185 if (tmp < transaction->len) { 186 transaction->len = tmp; 187 } 188 break; 189 190 case USBVIRT_TRANSACTION_OUT: 191 virthub_dev.transaction_out(&virthub_dev, 192 transaction->target.endpoint, 193 transaction->buffer, transaction->len); 194 break; 195 } 156 196 } 157 197 -
uspace/srv/hw/bus/usb/hcd/virtual/hc.c
rb8a3cda r7a7bfeb3 48 48 #include "hc.h" 49 49 #include "devices.h" 50 #include "hub.h" 50 51 51 52 #define USLEEP_BASE (500 * 1000) … … 65 66 } while (0) 66 67 67 static link_t transaction_to_device_list; 68 static link_t transaction_from_device_list; 68 static link_t transaction_list; 69 69 70 #define TRANSACTION_FORMAT "T[%d:%d (%d) ]"70 #define TRANSACTION_FORMAT "T[%d:%d (%d) %d]" 71 71 #define TRANSACTION_PRINTF(t) \ 72 72 (t).target.address, (t).target.endpoint, \ 73 (int)(t).len 73 (int)(t).len, (int)(t).type 74 74 75 75 #define transaction_get_instance(lnk) \ … … 100 100 void hc_manager(void) 101 101 { 102 list_initialize(&transaction_to_device_list); 103 list_initialize(&transaction_from_device_list); 102 list_initialize(&transaction_list); 104 103 105 104 static unsigned int seed = 4573; … … 110 109 async_usleep(USLEEP_BASE + (pseudo_random(&seed) % USLEEP_VAR)); 111 110 112 if (list_empty(&transaction_ to_device_list)) {111 if (list_empty(&transaction_list)) { 113 112 continue; 114 113 } 115 114 116 link_t *first_transaction_link = transaction_to_device_list.next; 115 dprintf("virtual hub has address %d:*.", virthub_dev.address); 116 117 link_t *first_transaction_link = transaction_list.next; 117 118 transaction_t *transaction 118 119 = transaction_get_instance(first_transaction_link); 119 120 list_remove(first_transaction_link); 121 122 dprintf("processing transaction " TRANSACTION_FORMAT "", 123 TRANSACTION_PRINTF(*transaction)); 120 124 121 125 usb_transaction_outcome_t outcome; … … 157 161 setup ? USBVIRT_TRANSACTION_SETUP : USBVIRT_TRANSACTION_OUT, target, 158 162 buffer, len, callback, arg); 159 list_append(&transaction->link, &transaction_ to_device_list);163 list_append(&transaction->link, &transaction_list); 160 164 } 161 165 … … 168 172 transaction_t *transaction = transaction_create(USBVIRT_TRANSACTION_IN, 169 173 target, buffer, len, callback, arg); 170 list_append(&transaction->link, &transaction_from_device_list); 171 } 172 173 /** Fill data to existing transaction from device. 174 */ 175 int hc_fillin_transaction_from_device(usb_target_t target, 176 void * buffer, size_t len) 177 { 178 dprintf("finding transaction to fill data in (%d:%d)...", 179 target.address, target.endpoint); 180 int rc; 181 182 /* 183 * Find correct transaction envelope in the list. 184 */ 185 if (list_empty(&transaction_from_device_list)) { 186 rc = ENOENT; 187 goto leave; 188 } 189 190 transaction_t *transaction = NULL; 191 link_t *pos = transaction_from_device_list.next; 192 193 while (pos != &transaction_from_device_list) { 194 transaction_t *t = transaction_get_instance(pos); 195 if (usb_target_same(t->target, target)) { 196 transaction = t; 197 break; 198 } 199 pos = pos->next; 200 } 201 if (transaction == NULL) { 202 rc = ENOENT; 203 goto leave; 204 } 205 206 /* 207 * Remove the transaction from the list as it will be processed now. 208 */ 209 list_remove(&transaction->link); 210 211 if (transaction->len < len) { 212 process_transaction_with_outcome(transaction, USB_OUTCOME_BABBLE); 213 rc = ENOMEM; 214 goto leave; 215 } 216 217 /* 218 * Copy the data and finish processing the transaction. 219 */ 220 transaction->len = len; 221 memcpy(transaction->buffer, buffer, len); 222 223 process_transaction_with_outcome(transaction, USB_OUTCOME_OK); 224 225 dprintf(" ...transaction " TRANSACTION_FORMAT " sent back", 226 TRANSACTION_PRINTF(*transaction)); 227 228 229 free(transaction); 230 rc = EOK; 231 232 leave: 233 dprintf(" ...fill-in transaction: %s", str_error(rc)); 234 235 return rc; 174 list_append(&transaction->link, &transaction_list); 236 175 } 237 176 -
uspace/srv/hw/bus/usb/hcd/virtual/hub.c
rb8a3cda r7a7bfeb3 144 144 hub_device_t hub_dev; 145 145 146 static int send_data(struct usbvirt_device *dev,147 usb_endpoint_t endpoint, void *buffer, size_t size)148 {149 usb_target_t target = { dev->address, endpoint };150 void *my_buffer = NULL;151 if (size > 0) {152 my_buffer = malloc(size);153 memcpy(my_buffer, buffer, size);154 }155 hc_fillin_transaction_from_device(target, my_buffer, size);156 157 return EOK;158 }159 160 146 void hub_init(void) 161 147 { … … 170 156 171 157 usbvirt_connect_local(&virthub_dev); 172 virthub_dev.send_data = send_data;158 //virthub_dev.send_data = send_data; 173 159 174 160 printf("%s: virtual hub (%d ports) created.\n", NAME, HUB_PORT_COUNT); … … 235 221 } 236 222 237 void hub_check_port_changes(void)238 {239 /* FIXME - what if HUB_PORT_COUNT is greater than 8. */240 uint8_t change_map = 0;241 242 size_t i;243 for (i = 0; i < HUB_PORT_COUNT; i++) {244 hub_port_t *port = &hub_dev.ports[i];245 246 if (port->status_change != 0) {247 change_map |= (1 << (i + 1));248 }249 }250 251 /* FIXME - do not send when it has not changed since previous run. */252 if (change_map != 0) {253 virthub_dev.send_data(&virthub_dev, HUB_STATUS_CHANGE_PIPE,254 &change_map, 1);255 }256 }257 223 258 224 /** -
uspace/srv/hw/bus/usb/hcd/virtual/hub.h
rb8a3cda r7a7bfeb3 51 51 void hub_remove_device(virtdev_connection_t *); 52 52 bool hub_can_device_signal(virtdev_connection_t *); 53 void hub_check_port_changes(void);54 53 55 54 #endif -
uspace/srv/hw/bus/usb/hcd/virtual/hubops.c
rb8a3cda r7a7bfeb3 59 59 static int on_class_request(struct usbvirt_device *dev, 60 60 usb_device_request_setup_packet_t *request, uint8_t *data); 61 static int on_data_request(struct usbvirt_device *dev, 62 usb_endpoint_t endpoint, 63 void *buffer, size_t size, size_t *actual_size); 64 61 65 62 66 static usbvirt_standard_device_request_ops_t standard_request_ops = { … … 78 82 .standard_request_ops = &standard_request_ops, 79 83 .on_class_device_request = on_class_request, 80 .on_data = NULL 84 .on_data = NULL, 85 .on_data_request = on_data_request 81 86 }; 82 87 … … 85 90 { 86 91 if (request->value_high == USB_DESCTYPE_HUB) { 87 int rc = dev-> send_data(dev, 0,92 int rc = dev->control_transfer_reply(dev, 0, 88 93 &hub_descriptor, hub_descriptor.length); 89 94 … … 196 201 uint32_t hub_status = 0; 197 202 198 return virthub_dev.send_data(&virthub_dev, 0, &hub_status, 4); 203 return virthub_dev.control_transfer_reply(&virthub_dev, 0, 204 &hub_status, 4); 199 205 } 200 206 … … 230 236 status |= (port->status_change << 16); 231 237 232 return virthub_dev. send_data(&virthub_dev, 0, &status, 4);238 return virthub_dev.control_transfer_reply(&virthub_dev, 0, &status, 4); 233 239 } 234 240 … … 334 340 { 335 341 port->status_change &= (~change); 336 hub_check_port_changes();337 342 } 338 343 … … 341 346 port->status_change |= change; 342 347 } 348 349 static int on_data_request(struct usbvirt_device *dev, 350 usb_endpoint_t endpoint, 351 void *buffer, size_t size, size_t *actual_size) 352 { 353 uint8_t change_map = 0; 354 355 size_t i; 356 for (i = 0; i < HUB_PORT_COUNT; i++) { 357 hub_port_t *port = &hub_dev.ports[i]; 358 359 if (port->status_change != 0) { 360 change_map |= (1 << (i + 1)); 361 } 362 } 363 364 uint8_t *b = (uint8_t *) buffer; 365 if (size > 0) { 366 *b = change_map; 367 *actual_size = 1; 368 } 369 370 return EOK; 371 } 372 343 373 344 374 /**
Note:
See TracChangeset
for help on using the changeset viewer.