Changeset 960bee9 in mainline for uspace/drv/uhci-hcd
- Timestamp:
- 2011-03-07T16:51:59Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/fix-logger-deadlock, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 97ff14d
- Parents:
- a6add7a (diff), d4beec3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/drv/uhci-hcd
- Files:
-
- 8 edited
-
batch.c (modified) (14 diffs)
-
batch.h (modified) (4 diffs)
-
iface.c (modified) (6 diffs)
-
uhci.c (modified) (3 diffs)
-
uhci_struct/transfer_descriptor.c (modified) (3 diffs)
-
uhci_struct/transfer_descriptor.h (modified) (1 diff)
-
utils/device_keeper.c (modified) (3 diffs)
-
utils/device_keeper.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/batch.c
ra6add7a r960bee9 47 47 static int batch_schedule(batch_t *instance); 48 48 49 static void batch_control( 50 batch_t *instance, int data_stage, int status_stage); 49 static void batch_control(batch_t *instance, 50 usb_packet_id data_stage, usb_packet_id status_stage); 51 static void batch_data(batch_t *instance, usb_packet_id pid); 51 52 static void batch_call_in(batch_t *instance); 52 53 static void batch_call_out(batch_t *instance); 53 54 static void batch_call_in_and_dispose(batch_t *instance); 54 55 static void batch_call_out_and_dispose(batch_t *instance); 56 static void batch_dispose(batch_t *instance); 55 57 56 58 … … 60 62 char* setup_buffer, size_t setup_size, 61 63 usbhc_iface_transfer_in_callback_t func_in, 62 usbhc_iface_transfer_out_callback_t func_out, void *arg) 64 usbhc_iface_transfer_out_callback_t func_out, void *arg, 65 device_keeper_t *manager 66 ) 63 67 { 64 68 assert(func_in == NULL || func_out == NULL); … … 83 87 } 84 88 85 instance->tds = malloc32(sizeof(t ransfer_descriptor_t) * instance->packets);89 instance->tds = malloc32(sizeof(td_t) * instance->packets); 86 90 if (instance->tds == NULL) { 87 91 usb_log_error("Failed to allocate transfer descriptors.\n"); … … 90 94 return NULL; 91 95 } 92 bzero(instance->tds, sizeof(t ransfer_descriptor_t) * instance->packets);96 bzero(instance->tds, sizeof(td_t) * instance->packets); 93 97 94 98 const size_t transport_size = max_packet_size * instance->packets; … … 136 140 instance->arg = arg; 137 141 instance->speed = speed; 142 instance->manager = manager; 138 143 139 144 queue_head_element_td(instance->qh, addr_to_phys(instance->tds)); … … 151 156 size_t i = 0; 152 157 for (;i < instance->packets; ++i) { 153 if (t ransfer_descriptor_is_active(&instance->tds[i])) {158 if (td_is_active(&instance->tds[i])) { 154 159 return false; 155 160 } 156 instance->error = transfer_descriptor_status(&instance->tds[i]); 161 162 instance->error = td_status(&instance->tds[i]); 157 163 if (instance->error != EOK) { 164 usb_log_debug("Batch(%p) found error TD(%d):%x.\n", 165 instance, i, instance->tds[i].status); 166 167 device_keeper_set_toggle(instance->manager, instance->target, 168 td_toggle(&instance->tds[i])); 158 169 if (i > 0) 159 instance->transfered_size -= instance->setup_size; 160 usb_log_debug("Batch(%p) found error TD(%d):%x.\n", 161 instance, i, instance->tds[i].status); 170 goto substract_ret; 162 171 return true; 163 172 } 164 instance->transfered_size += 165 transfer_descriptor_actual_size(&instance->tds[i]); 166 } 173 174 instance->transfered_size += td_act_size(&instance->tds[i]); 175 if (td_is_short(&instance->tds[i])) 176 goto substract_ret; 177 } 178 substract_ret: 167 179 instance->transfered_size -= instance->setup_size; 168 180 return true; … … 192 204 { 193 205 assert(instance); 194 195 const bool low_speed = instance->speed == USB_SPEED_LOW; 196 int toggle = 1; 197 size_t i = 0; 198 for (;i < instance->packets; ++i) { 199 char *data = 200 instance->transport_buffer + (i * instance->max_packet_size); 201 transfer_descriptor_t *next = (i + 1) < instance->packets ? 202 &instance->tds[i + 1] : NULL; 203 toggle = 1 - toggle; 204 205 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 206 instance->max_packet_size, toggle, false, low_speed, 207 instance->target, USB_PID_IN, data, next); 208 } 209 210 instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 211 206 batch_data(instance, USB_PID_IN); 212 207 instance->next_step = batch_call_in_and_dispose; 213 208 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance); … … 219 214 assert(instance); 220 215 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 221 222 const bool low_speed = instance->speed == USB_SPEED_LOW; 223 int toggle = 1; 224 size_t i = 0; 225 for (;i < instance->packets; ++i) { 226 char *data = 227 instance->transport_buffer + (i * instance->max_packet_size); 228 transfer_descriptor_t *next = (i + 1) < instance->packets ? 229 &instance->tds[i + 1] : NULL; 230 toggle = 1 - toggle; 231 232 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 233 instance->max_packet_size, toggle++, false, low_speed, 234 instance->target, USB_PID_OUT, data, next); 235 } 236 237 instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 238 216 batch_data(instance, USB_PID_OUT); 239 217 instance->next_step = batch_call_out_and_dispose; 240 218 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance); … … 242 220 } 243 221 /*----------------------------------------------------------------------------*/ 244 static void batch_control( 245 batch_t *instance, int data_stage, int status_stage) 222 void batch_bulk_in(batch_t *instance) 223 { 224 assert(instance); 225 batch_data(instance, USB_PID_IN); 226 instance->next_step = batch_call_in_and_dispose; 227 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 228 batch_schedule(instance); 229 } 230 /*----------------------------------------------------------------------------*/ 231 void batch_bulk_out(batch_t *instance) 232 { 233 assert(instance); 234 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 235 batch_data(instance, USB_PID_OUT); 236 instance->next_step = batch_call_out_and_dispose; 237 usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance); 238 batch_schedule(instance); 239 } 240 /*----------------------------------------------------------------------------*/ 241 void batch_data(batch_t *instance, usb_packet_id pid) 242 { 243 assert(instance); 244 const bool low_speed = instance->speed == USB_SPEED_LOW; 245 int toggle = device_keeper_get_toggle(instance->manager, instance->target); 246 assert(toggle == 0 || toggle == 1); 247 248 size_t packet = 0; 249 size_t remain_size = instance->buffer_size; 250 while (remain_size > 0) { 251 char *data = 252 instance->transport_buffer + instance->buffer_size 253 - remain_size; 254 255 256 const size_t packet_size = 257 (instance->max_packet_size > remain_size) ? 258 remain_size : instance->max_packet_size; 259 260 td_init(&instance->tds[packet], 261 DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed, 262 instance->target, pid, data, 263 &instance->tds[packet + 1]); 264 265 toggle = 1 - toggle; 266 ++packet; 267 assert(packet <= instance->packets); 268 assert(packet_size <= remain_size); 269 remain_size -= packet_size; 270 } 271 device_keeper_set_toggle(instance->manager, instance->target, toggle); 272 273 instance->tds[packet - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 274 instance->tds[packet - 1].next = 0 | LINK_POINTER_TERMINATE_FLAG; 275 } 276 /*----------------------------------------------------------------------------*/ 277 void batch_control(batch_t *instance, 278 usb_packet_id data_stage, usb_packet_id status_stage) 246 279 { 247 280 assert(instance); … … 250 283 int toggle = 0; 251 284 /* setup stage */ 252 t ransfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,285 td_init(instance->tds, DEFAULT_ERROR_COUNT, 253 286 instance->setup_size, toggle, false, low_speed, instance->target, 254 287 USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]); … … 268 301 remain_size : instance->max_packet_size; 269 302 270 t ransfer_descriptor_init(&instance->tds[packet],303 td_init(&instance->tds[packet], 271 304 DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed, 272 305 instance->target, data_stage, data, … … 281 314 /* status stage */ 282 315 assert(packet == instance->packets - 1); 283 t ransfer_descriptor_init(&instance->tds[packet], DEFAULT_ERROR_COUNT,316 td_init(&instance->tds[packet], DEFAULT_ERROR_COUNT, 284 317 0, 1, false, low_speed, instance->target, status_stage, NULL, NULL); 285 318 … … 323 356 assert(instance); 324 357 batch_call_in(instance); 358 batch_dispose(instance); 359 } 360 /*----------------------------------------------------------------------------*/ 361 void batch_call_out_and_dispose(batch_t *instance) 362 { 363 assert(instance); 364 batch_call_out(instance); 365 batch_dispose(instance); 366 } 367 /*----------------------------------------------------------------------------*/ 368 void batch_dispose(batch_t *instance) 369 { 370 assert(instance); 325 371 usb_log_debug("Batch(%p) disposing.\n", instance); 326 372 free32(instance->tds); … … 331 377 } 332 378 /*----------------------------------------------------------------------------*/ 333 void batch_call_out_and_dispose(batch_t *instance)334 {335 assert(instance);336 batch_call_out(instance);337 usb_log_debug("Batch(%p) disposing.\n", instance);338 free32(instance->tds);339 free32(instance->qh);340 free32(instance->setup_buffer);341 free32(instance->transport_buffer);342 free(instance);343 }344 /*----------------------------------------------------------------------------*/345 379 int batch_schedule(batch_t *instance) 346 380 { -
uspace/drv/uhci-hcd/batch.h
ra6add7a r960bee9 42 42 #include "uhci_struct/transfer_descriptor.h" 43 43 #include "uhci_struct/queue_head.h" 44 #include "utils/device_keeper.h" 44 45 45 46 typedef struct batch … … 65 66 ddf_fun_t *fun; 66 67 queue_head_t *qh; 67 t ransfer_descriptor_t *tds;68 td_t *tds; 68 69 void (*next_step)(struct batch*); 70 device_keeper_t *manager; 69 71 } batch_t; 70 72 … … 74 76 char *setup_buffer, size_t setup_size, 75 77 usbhc_iface_transfer_in_callback_t func_in, 76 usbhc_iface_transfer_out_callback_t func_out, void *arg); 78 usbhc_iface_transfer_out_callback_t func_out, void *arg, 79 device_keeper_t *manager 80 ); 77 81 78 82 bool batch_is_complete(batch_t *instance); … … 86 90 void batch_interrupt_out(batch_t *instance); 87 91 88 /* DEPRECATED FUNCTIONS NEEDED BY THE OLD API */ 89 void batch_control_setup_old(batch_t *instance); 92 void batch_bulk_in(batch_t *instance); 90 93 91 void batch_control_write_data_old(batch_t *instance); 92 93 void batch_control_read_data_old(batch_t *instance); 94 95 void batch_control_write_status_old(batch_t *instance); 96 97 void batch_control_read_status_old(batch_t *instance); 94 void batch_bulk_out(batch_t *instance); 98 95 #endif 99 96 /** -
uspace/drv/uhci-hcd/iface.c
ra6add7a r960bee9 114 114 115 115 batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT, 116 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg); 116 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg, 117 &hc->device_manager); 117 118 if (!batch) 118 119 return ENOMEM; … … 133 134 134 135 batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT, 135 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg); 136 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg, 137 &hc->device_manager); 136 138 if (!batch) 137 139 return ENOMEM; 138 140 batch_interrupt_in(batch); 141 return EOK; 142 } 143 /*----------------------------------------------------------------------------*/ 144 static int bulk_out(ddf_fun_t *fun, usb_target_t target, 145 size_t max_packet_size, void *data, size_t size, 146 usbhc_iface_transfer_out_callback_t callback, void *arg) 147 { 148 assert(fun); 149 uhci_t *hc = fun_to_uhci(fun); 150 assert(hc); 151 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 152 153 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 154 target.address, target.endpoint, size, max_packet_size); 155 156 batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK, 157 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg, 158 &hc->device_manager); 159 if (!batch) 160 return ENOMEM; 161 batch_bulk_out(batch); 162 return EOK; 163 } 164 /*----------------------------------------------------------------------------*/ 165 static int bulk_in(ddf_fun_t *fun, usb_target_t target, 166 size_t max_packet_size, void *data, size_t size, 167 usbhc_iface_transfer_in_callback_t callback, void *arg) 168 { 169 assert(fun); 170 uhci_t *hc = fun_to_uhci(fun); 171 assert(hc); 172 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 173 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 174 target.address, target.endpoint, size, max_packet_size); 175 176 batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK, 177 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg, 178 &hc->device_manager); 179 if (!batch) 180 return ENOMEM; 181 batch_bulk_in(batch); 139 182 return EOK; 140 183 } … … 152 195 target.address, target.endpoint, size, max_packet_size); 153 196 197 if (setup_size != 8) 198 return EINVAL; 199 154 200 batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 155 201 max_packet_size, speed, data, size, setup_data, setup_size, 156 NULL, callback, arg); 157 if (!batch) 158 return ENOMEM; 202 NULL, callback, arg, &hc->device_manager); 203 if (!batch) 204 return ENOMEM; 205 device_keeper_reset_if_need(&hc->device_manager, target, setup_data); 159 206 batch_control_write(batch); 160 207 return EOK; … … 175 222 batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 176 223 max_packet_size, speed, data, size, setup_data, setup_size, callback, 177 NULL, arg );224 NULL, arg, &hc->device_manager); 178 225 if (!batch) 179 226 return ENOMEM; … … 181 228 return EOK; 182 229 } 183 184 185 230 /*----------------------------------------------------------------------------*/ 186 231 usbhc_iface_t uhci_iface = { … … 194 239 .interrupt_in = interrupt_in, 195 240 241 .bulk_in = bulk_in, 242 .bulk_out = bulk_out, 243 196 244 .control_read = control_read, 197 245 .control_write = control_write, -
uspace/drv/uhci-hcd/uhci.c
ra6add7a r960bee9 167 167 /* reset hc, all states and counters */ 168 168 pio_write_16(&instance->registers->usbcmd, UHCI_CMD_HCRESET); 169 while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0)170 { async_usleep(10); }169 do { async_usleep(10); } 170 while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0); 171 171 172 172 /* set framelist pointer */ … … 175 175 176 176 /* enable all interrupts, but resume interrupt */ 177 pio_write_16(&instance->registers->usbintr, 178 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 179 177 // pio_write_16(&instance->registers->usbintr, 178 // UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 179 180 uint16_t status = pio_read_16(&instance->registers->usbcmd); 181 usb_log_warning("Previous command value: %x.\n", status); 180 182 /* Start the hc with large(64B) packet FSBR */ 181 183 pio_write_16(&instance->registers->usbcmd, … … 336 338 uhci_interrupt(instance, status); 337 339 pio_write_16(&instance->registers->usbsts, 0x1f); 338 async_usleep(UHCI_CLEANER_TIMEOUT * 5);340 async_usleep(UHCI_CLEANER_TIMEOUT); 339 341 } 340 342 return EOK; -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
ra6add7a r960bee9 38 38 #include "utils/malloc32.h" 39 39 40 void transfer_descriptor_init(transfer_descriptor_t *instance, 41 int error_count, size_t size, bool toggle, bool isochronous, bool low_speed, 42 usb_target_t target, int pid, void *buffer, transfer_descriptor_t *next) 40 void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso, 41 bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer, td_t *next) 43 42 { 44 43 assert(instance); 44 assert(size < 1024); 45 assert((pid == USB_PID_SETUP) || (pid == USB_PID_IN) || (pid == USB_PID_OUT)); 45 46 46 47 instance->next = 0 … … 49 50 50 51 instance->status = 0 51 | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS) 52 | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0) 53 | TD_STATUS_ERROR_ACTIVE; 52 | ((err_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS) 53 | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0) 54 | (iso ? TD_STATUS_ISOCHRONOUS_FLAG : 0) 55 | TD_STATUS_ERROR_ACTIVE; 54 56 55 assert(size < 1024); 57 if (pid == USB_PID_IN && !iso) { 58 instance->status |= TD_STATUS_SPD_FLAG; 59 } 60 56 61 instance->device = 0 57 | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)58 | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)59 | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)60 | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)61 | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);62 | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS) 63 | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0) 64 | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS) 65 | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS) 66 | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS); 62 67 63 68 instance->buffer_ptr = 0; … … 68 73 69 74 usb_log_debug2("Created TD: %X:%X:%X:%X(%p).\n", 70 instance->next, instance->status, instance->device, 71 instance->buffer_ptr, buffer); 75 instance->next, instance->status, instance->device, 76 instance->buffer_ptr, buffer); 77 if (pid == USB_PID_SETUP) { 78 usb_log_debug("SETUP BUFFER: %s\n", 79 usb_debug_str_buffer(buffer, 8, 8)); 80 } 72 81 } 73 82 /*----------------------------------------------------------------------------*/ 74 int t ransfer_descriptor_status(transfer_descriptor_t *instance)83 int td_status(td_t *instance) 75 84 { 76 85 assert(instance); -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
ra6add7a r960bee9 88 88 * we don't use it anyway 89 89 */ 90 } __attribute__((packed)) t ransfer_descriptor_t;90 } __attribute__((packed)) td_t; 91 91 92 92 93 void t ransfer_descriptor_init(transfer_descriptor_t *instance,94 int error_count, size_t size, bool toggle, bool isochronous, bool low_speed,95 usb_target_t target, int pid, void *buffer, transfer_descriptor_t *next);93 void td_init(td_t *instance, int error_count, size_t size, bool toggle, bool iso, 94 bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer, 95 td_t *next); 96 96 97 int t ransfer_descriptor_status(transfer_descriptor_t *instance);97 int td_status(td_t *instance); 98 98 99 static inline size_t transfer_descriptor_actual_size( 100 transfer_descriptor_t *instance) 99 static inline size_t td_act_size(td_t *instance) 101 100 { 102 101 assert(instance); 103 102 return 104 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK; 103 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) 104 & TD_STATUS_ACTLEN_MASK; 105 105 } 106 106 107 static inline bool transfer_descriptor_is_active( 108 transfer_descriptor_t *instance) 107 static inline bool td_is_short(td_t *instance) 108 { 109 const size_t act_size = td_act_size(instance); 110 const size_t max_size = 111 ((instance->device >> TD_DEVICE_MAXLEN_POS) + 1) 112 & TD_DEVICE_MAXLEN_MASK; 113 return 114 (instance->status | TD_STATUS_SPD_FLAG) && act_size < max_size; 115 } 116 117 static inline int td_toggle(td_t *instance) 118 { 119 assert(instance); 120 return ((instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) != 0) 121 ? 1 : 0; 122 } 123 124 static inline bool td_is_active(td_t *instance) 109 125 { 110 126 assert(instance); -
uspace/drv/uhci-hcd/utils/device_keeper.c
ra6add7a r960bee9 49 49 instance->devices[i].occupied = false; 50 50 instance->devices[i].handle = 0; 51 instance->devices[i].toggle_status = 0; 51 52 } 52 53 } … … 73 74 fibril_mutex_unlock(&instance->guard); 74 75 fibril_condvar_signal(&instance->default_address_occupied); 76 } 77 /*----------------------------------------------------------------------------*/ 78 void device_keeper_reset_if_need( 79 device_keeper_t *instance, usb_target_t target, const unsigned char *data) 80 { 81 assert(instance); 82 fibril_mutex_lock(&instance->guard); 83 if (target.endpoint > 15 || target.endpoint < 0 84 || target.address >= USB_ADDRESS_COUNT || target.address < 0 85 || !instance->devices[target.address].occupied) { 86 goto the_end; 87 } 88 89 switch (data[1]) 90 { 91 case 0x01: /*clear feature*/ 92 /* recipient is enpoint, value is zero (ENDPOINT_STALL) */ 93 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) { 94 /* enpoint number is < 16, thus first byte is enough */ 95 instance->devices[target.address].toggle_status &= ~(1 << data[4]); 96 } 97 break; 98 99 case 0x9: /* set configuration */ 100 case 0x11: /* set interface */ 101 instance->devices[target.address].toggle_status = 0; 102 break; 103 } 104 the_end: 105 fibril_mutex_unlock(&instance->guard); 106 } 107 /*----------------------------------------------------------------------------*/ 108 int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target) 109 { 110 assert(instance); 111 int ret; 112 fibril_mutex_lock(&instance->guard); 113 if (target.endpoint > 15 || target.endpoint < 0 114 || target.address >= USB_ADDRESS_COUNT || target.address < 0 115 || !instance->devices[target.address].occupied) { 116 ret = EINVAL; 117 } else { 118 ret = (instance->devices[target.address].toggle_status >> target.endpoint) & 1; 119 } 120 fibril_mutex_unlock(&instance->guard); 121 return ret; 122 } 123 /*----------------------------------------------------------------------------*/ 124 int device_keeper_set_toggle( 125 device_keeper_t *instance, usb_target_t target, bool toggle) 126 { 127 assert(instance); 128 int ret; 129 fibril_mutex_lock(&instance->guard); 130 if (target.endpoint > 15 || target.endpoint < 0 131 || target.address >= USB_ADDRESS_COUNT || target.address < 0 132 || !instance->devices[target.address].occupied) { 133 ret = EINVAL; 134 } else { 135 if (toggle) { 136 instance->devices[target.address].toggle_status |= (1 << target.endpoint); 137 } else { 138 instance->devices[target.address].toggle_status &= ~(1 << target.endpoint); 139 } 140 ret = EOK; 141 } 142 fibril_mutex_unlock(&instance->guard); 143 return ret; 75 144 } 76 145 /*----------------------------------------------------------------------------*/ … … 96 165 instance->devices[new_address].occupied = true; 97 166 instance->devices[new_address].speed = speed; 167 instance->devices[new_address].toggle_status = 0; 98 168 instance->last_address = new_address; 99 169 fibril_mutex_unlock(&instance->guard); -
uspace/drv/uhci-hcd/utils/device_keeper.h
ra6add7a r960bee9 44 44 usb_speed_t speed; 45 45 bool occupied; 46 uint16_t toggle_status; 46 47 devman_handle_t handle; 47 48 }; … … 55 56 56 57 void device_keeper_init(device_keeper_t *instance); 58 57 59 void device_keeper_reserve_default( 58 60 device_keeper_t *instance, usb_speed_t speed); 61 59 62 void device_keeper_release_default(device_keeper_t *instance); 63 64 void device_keeper_reset_if_need( 65 device_keeper_t *instance, usb_target_t target, const unsigned char *setup_data); 66 67 int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target); 68 69 int device_keeper_set_toggle( 70 device_keeper_t *instance, usb_target_t target, bool toggle); 60 71 61 72 usb_address_t device_keeper_request( 62 73 device_keeper_t *instance, usb_speed_t speed); 74 63 75 void device_keeper_bind( 64 76 device_keeper_t *instance, usb_address_t address, devman_handle_t handle); 77 65 78 void device_keeper_release(device_keeper_t *instance, usb_address_t address); 79 66 80 usb_address_t device_keeper_find( 67 81 device_keeper_t *instance, devman_handle_t handle);
Note:
See TracChangeset
for help on using the changeset viewer.
