~jsvoboda/helenos/dnsr

« back to all changes in this revision

Viewing changes to uspace/drv/bus/usb/ohci/root_hub.c

  • Committer: Jiri Svoboda
  • Date: 2012-11-11 21:31:03 UTC
  • mfrom: (1527.1.178 mainline)
  • Revision ID: jiri@wiwaxia-20121111213103-314bmkettwvlwj97
MergeĀ mainlineĀ changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
 * @brief OHCI driver
33
33
 */
34
34
#include <assert.h>
 
35
#include <byteorder.h>
35
36
#include <errno.h>
36
37
#include <str_error.h>
37
38
#include <fibril_synch.h>
38
39
 
 
40
#include <usb/usb.h>
39
41
#include <usb/debug.h>
40
42
#include <usb/dev/request.h>
41
43
#include <usb/classes/hub.h>
42
44
 
43
 
#include "root_hub.h"
44
45
#include <usb/classes/classes.h>
45
46
#include <usb/classes/hub.h>
46
47
#include <usb/dev/driver.h>
47
48
#include "ohci_regs.h"
 
49
#include "root_hub.h"
48
50
 
49
51
/**
50
52
 * standart device descriptor for ohci root hub
121
123
    usb_transfer_batch_t *request, uint16_t mask, size_t size)
122
124
{
123
125
        assert(request);
 
126
        usb_log_debug("Sending interrupt vector(%zu) %hhx:%hhx.\n",
 
127
            size, ((uint8_t*)&mask)[0], ((uint8_t*)&mask)[1]);
124
128
        usb_transfer_batch_finish_error(request, &mask, size, EOK);
125
129
        usb_transfer_batch_destroy(request);
126
130
}
149
153
        assert(regs);
150
154
 
151
155
        instance->registers = regs;
152
 
        instance->port_count =
153
 
            (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK;
 
156
        instance->port_count = OHCI_RD(regs->rh_desc_a) & RHDA_NDS_MASK;
 
157
        usb_log_debug2("rh_desc_a: %x.\n", OHCI_RD(regs->rh_desc_a));
154
158
        if (instance->port_count > 15) {
155
159
                usb_log_warning("OHCI specification does not allow more than 15"
156
160
                    " ports. Max 15 ports will be used");
162
166
        instance->unfinished_interrupt_transfer = NULL;
163
167
 
164
168
#if defined OHCI_POWER_SWITCH_no
 
169
        usb_log_debug("OHCI rh: Set power mode to no power switching.\n");
165
170
        /* Set port power mode to no power-switching. (always on) */
166
 
        instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
 
171
        OHCI_SET(regs->rh_desc_a, RHDA_NPS_FLAG);
167
172
 
168
173
        /* Set to no over-current reporting */
169
 
        instance->registers->rh_desc_a |= RHDA_NOCP_FLAG;
 
174
        OHCI_SET(regs->rh_desc_a, RHDA_NOCP_FLAG);
170
175
 
171
176
#elif defined OHCI_POWER_SWITCH_ganged
172
 
        /* Set port power mode to no ganged power-switching. */
173
 
        instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG;
174
 
        instance->registers->rh_desc_a &= ~RHDA_PSM_FLAG;
175
 
        instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
 
177
        usb_log_debug("OHCI rh: Set power mode to ganged power switching.\n");
 
178
        /* Set port power mode to ganged power-switching. */
 
179
        OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG);
 
180
        OHCI_CLR(regs->rh_desc_a, RHDA_PSM_FLAG);
 
181
 
 
182
        /* Turn off power (hub driver will turn this back on)*/
 
183
        OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER);
176
184
 
177
185
        /* Set to global over-current */
178
 
        instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;
179
 
        instance->registers->rh_desc_a &= ~RHDA_OCPM_FLAG;
 
186
        OHCI_CLR(regs->rh_desc_a, RHDA_NOCP_FLAG);
 
187
        OHCI_CLR(regs->rh_desc_a, RHDA_OCPM_FLAG);
180
188
#else
181
 
        /* Set port power mode to no per port power-switching. */
182
 
        instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG;
183
 
        instance->registers->rh_desc_a |= RHDA_PSM_FLAG;
 
189
        usb_log_debug("OHCI rh: Set power mode to per-port power switching.\n");
 
190
        /* Set port power mode to per port power-switching. */
 
191
        OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG);
 
192
        OHCI_SET(regs->rh_desc_a, RHDA_PSM_FLAG);
184
193
 
185
194
        /* Control all ports by global switch and turn them off */
186
 
        instance->registers->rh_desc_b &= (RHDB_PCC_MASK << RHDB_PCC_SHIFT);
187
 
        instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
 
195
        OHCI_CLR(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT);
 
196
        OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER);
188
197
 
189
198
        /* Return control to per port state */
190
 
        instance->registers->rh_desc_b |=
191
 
                ((1 << (instance->port_count + 1)) - 1) << RHDB_PCC_SHIFT;
 
199
        OHCI_SET(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT);
192
200
 
193
201
        /* Set per port over-current */
194
 
        instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;
195
 
        instance->registers->rh_desc_a |= RHDA_OCPM_FLAG;
 
202
        OHCI_CLR(regs->rh_desc_a, RHDA_NOCP_FLAG);
 
203
        OHCI_SET(regs->rh_desc_a, RHDA_OCPM_FLAG);
196
204
#endif
197
205
 
198
206
        fibril_mutex_initialize(&instance->guard);
201
209
        usb_log_info("Root hub (%zu ports) initialized.\n",
202
210
            instance->port_count);
203
211
}
204
 
/*----------------------------------------------------------------------------*/
 
212
 
205
213
/**
206
214
 * Process root hub request.
207
215
 *
225
233
                usb_log_debug("Root hub got INTERRUPT packet\n");
226
234
                fibril_mutex_lock(&instance->guard);
227
235
                assert(instance->unfinished_interrupt_transfer == NULL);
228
 
                uint16_t mask = create_interrupt_mask(instance);
 
236
                const uint16_t mask = create_interrupt_mask(instance);
229
237
                if (mask == 0) {
230
 
                        usb_log_debug("No changes...\n");
 
238
                        usb_log_debug("No changes(%hx)...\n", mask);
231
239
                        instance->unfinished_interrupt_transfer = request;
232
240
                } else {
233
241
                        usb_log_debug("Processing changes...\n");
242
250
                TRANSFER_END(request, ENOTSUP);
243
251
        }
244
252
}
245
 
/*----------------------------------------------------------------------------*/
 
253
 
246
254
/**
247
255
 * Process interrupt on a hub device.
248
256
 *
256
264
        fibril_mutex_lock(&instance->guard);
257
265
        if (instance->unfinished_interrupt_transfer) {
258
266
                usb_log_debug("Finalizing interrupt transfer\n");
259
 
                uint16_t mask = create_interrupt_mask(instance);
 
267
                const uint16_t mask = create_interrupt_mask(instance);
260
268
                interrupt_request(instance->unfinished_interrupt_transfer,
261
269
                    mask, instance->interrupt_mask_size);
262
270
                instance->unfinished_interrupt_transfer = NULL;
263
271
        }
264
272
        fibril_mutex_unlock(&instance->guard);
265
273
}
266
 
/*----------------------------------------------------------------------------*/
 
274
 
267
275
/**
268
276
 * Create hub descriptor.
269
277
 *
281
289
        assert(size <= HUB_DESCRIPTOR_MAX_SIZE);
282
290
        instance->hub_descriptor_size = size;
283
291
 
284
 
        uint32_t hub_desc = instance->registers->rh_desc_a;
285
 
        uint32_t port_desc = instance->registers->rh_desc_b;
 
292
        const uint32_t hub_desc = OHCI_RD(instance->registers->rh_desc_a);
 
293
        const uint32_t port_desc = OHCI_RD(instance->registers->rh_desc_b);
286
294
 
287
295
        /* bDescLength */
288
296
        instance->descriptors.hub[0] = size;
304
312
        /* Reserved */
305
313
        instance->descriptors.hub[4] = 0;
306
314
        /* bPwrOn2PwrGood */
307
 
        instance->descriptors.hub[5] =
308
 
            (hub_desc >> RHDA_POTPGT_SHIFT) & RHDA_POTPGT_MASK;
 
315
        instance->descriptors.hub[5] = hub_desc >> RHDA_POTPGT_SHIFT;
309
316
        /* bHubContrCurrent, root hubs don't need no power. */
310
317
        instance->descriptors.hub[6] = 0;
311
318
 
312
319
        /* Device Removable and some legacy 1.0 stuff*/
313
 
        instance->descriptors.hub[7] =
314
 
            (port_desc >> RHDB_DR_SHIFT) & RHDB_DR_MASK & 0xff;
 
320
        instance->descriptors.hub[7] = (port_desc >> RHDB_DR_SHIFT) & 0xff;
315
321
        instance->descriptors.hub[8] = 0xff;
316
322
        if (instance->interrupt_mask_size == 2) {
317
323
                instance->descriptors.hub[8] =
318
 
                    (port_desc >> RHDB_DR_SHIFT) & RHDB_DR_MASK >> 8;
 
324
                    (port_desc >> RHDB_DR_SHIFT) >> 8;
319
325
                instance->descriptors.hub[9]  = 0xff;
320
326
                instance->descriptors.hub[10] = 0xff;
321
327
        }
322
328
}
323
 
/*----------------------------------------------------------------------------*/
 
329
 
324
330
/** Initialize hub descriptors.
325
331
 *
326
332
 * A full configuration descriptor is assembled. The configuration and endpoint
340
346
        instance->descriptors.endpoint.max_packet_size =
341
347
            instance->interrupt_mask_size;
342
348
 
343
 
        instance->descriptors.configuration.total_length =
 
349
        instance->descriptors.configuration.total_length = uint16_host2usb(
344
350
            sizeof(usb_standard_configuration_descriptor_t) +
345
351
            sizeof(usb_standard_endpoint_descriptor_t) +
346
352
            sizeof(usb_standard_interface_descriptor_t) +
347
 
            instance->hub_descriptor_size;
 
353
            instance->hub_descriptor_size);
348
354
}
349
 
/*----------------------------------------------------------------------------*/
 
355
 
350
356
/**
351
357
 * Create bitmap of changes to answer status interrupt.
352
358
 *
363
369
        uint16_t mask = 0;
364
370
 
365
371
        /* Only local power source change and over-current change can happen */
366
 
        if (instance->registers->rh_status & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) {
 
372
        if (OHCI_RD(instance->registers->rh_status)
 
373
            & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) {
367
374
                mask |= 1;
368
375
        }
369
376
        for (size_t port = 1; port <= instance->port_count; ++port) {
370
377
                /* Write-clean bits are those that indicate change */
371
 
                if (RHPS_CHANGE_WC_MASK
372
 
                    & instance->registers->rh_port_status[port - 1]) {
373
 
 
 
378
                if (OHCI_RD(instance->registers->rh_port_status[port - 1])
 
379
                    & RHPS_CHANGE_WC_MASK) {
374
380
                        mask |= (1 << port);
375
381
                }
376
382
        }
377
 
        /* USB is little endian */
378
 
        return host2uint32_t_le(mask);
 
383
        usb_log_debug2("OHCI root hub interrupt mask: %hx.\n", mask);
 
384
        return uint16_host2usb(mask);
379
385
}
380
 
/*----------------------------------------------------------------------------*/
 
386
 
381
387
/**
382
388
 * Create answer to status request.
383
389
 *
396
402
        usb_device_request_setup_packet_t *request_packet =
397
403
            (usb_device_request_setup_packet_t*)request->setup_buffer;
398
404
 
 
405
        const uint16_t index = uint16_usb2host(request_packet->index);
 
406
 
399
407
        switch (request_packet->request_type)
400
408
        {
401
409
        case USB_HUB_REQ_TYPE_GET_HUB_STATUS:
405
413
                            "status request.\n", request->buffer_size);
406
414
                        TRANSFER_END(request, EOVERFLOW);
407
415
                } else {
408
 
                        uint32_t data = instance->registers->rh_status &
409
 
                            (RHS_LPS_FLAG | RHS_LPSC_FLAG
410
 
                                | RHS_OCI_FLAG | RHS_OCIC_FLAG);
 
416
                        const uint32_t data =
 
417
                            OHCI_RD(instance->registers->rh_status) &
 
418
                                (RHS_LPS_FLAG | RHS_LPSC_FLAG
 
419
                                    | RHS_OCI_FLAG | RHS_OCIC_FLAG);
411
420
                        TRANSFER_END_DATA(request, &data, sizeof(data));
412
421
                }
413
422
 
419
428
                            "status request.\n", request->buffer_size);
420
429
                        TRANSFER_END(request, EOVERFLOW);
421
430
                } else {
422
 
                        unsigned port = request_packet->index;
 
431
                        const unsigned port = index;
423
432
                        if (port < 1 || port > instance->port_count)
424
433
                                TRANSFER_END(request, EINVAL);
425
 
 
426
 
                        uint32_t data =
427
 
                            instance->registers->rh_port_status[port - 1];
 
434
                        /* Register format matches the format of port status
 
435
                         * field */
 
436
                        const uint32_t data = uint32_host2usb(OHCI_RD(
 
437
                            instance->registers->rh_port_status[port - 1]));
428
438
                        TRANSFER_END_DATA(request, &data, sizeof(data));
429
439
                }
430
440
        case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE):
433
443
                            "get status request.\n", request->buffer_size);
434
444
                        TRANSFER_END(request, EOVERFLOW);
435
445
                } else {
436
 
                        uint16_t data =
 
446
                        const uint16_t data =
437
447
                            uint16_host2usb(USB_DEVICE_STATUS_SELF_POWERED);
438
448
                        TRANSFER_END_DATA(request, &data, sizeof(data));
439
449
                }
440
450
 
441
451
        case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE):
442
452
                /* Hubs are allowed to have only one interface */
443
 
                if (request_packet->index != 0)
 
453
                if (index != 0)
444
454
                        TRANSFER_END(request, EINVAL);
445
455
                /* Fall through, as the answer will be the same: 0x0000 */
446
456
        case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT):
447
457
                /* Endpoint 0 (default control) and 1 (interrupt) */
448
 
                if (request_packet->index >= 2)
 
458
                if (index >= 2)
449
459
                        TRANSFER_END(request, EINVAL);
450
460
 
451
461
                if (request->buffer_size < 2) {
454
464
                        TRANSFER_END(request, EOVERFLOW);
455
465
                } else {
456
466
                        /* Endpoints are OK. (We don't halt) */
457
 
                        uint16_t data = 0;
 
467
                        const uint16_t data = 0;
458
468
                        TRANSFER_END_DATA(request, &data, sizeof(data));
459
469
                }
460
470
 
464
474
        }
465
475
 
466
476
}
467
 
/*----------------------------------------------------------------------------*/
 
477
 
468
478
/**
469
479
 * Create answer to a descriptor request.
470
480
 *
481
491
 
482
492
        usb_device_request_setup_packet_t *setup_request =
483
493
            (usb_device_request_setup_packet_t *) request->setup_buffer;
484
 
        uint16_t setup_request_value = setup_request->value_high;
485
 
        switch (setup_request_value)
 
494
        /* "The wValue field specifies the descriptor type in the high byte
 
495
         * and the descriptor index in the low byte (refer to Table 9-5)." */
 
496
        const int desc_type = uint16_usb2host(setup_request->value) >> 8;
 
497
        switch (desc_type)
486
498
        {
487
499
        case USB_DESCTYPE_HUB:
488
500
                usb_log_debug2("USB_DESCTYPE_HUB\n");
529
541
                    "%d\n\tindex %d\n\tlen %d\n ",
530
542
                    setup_request->value,
531
543
                    setup_request->request_type, setup_request->request,
532
 
                    setup_request_value, setup_request->index,
 
544
                    desc_type, setup_request->index,
533
545
                    setup_request->length);
534
546
                TRANSFER_END(request, EINVAL);
535
547
        }
536
548
 
537
549
        TRANSFER_END(request, ENOTSUP);
538
550
}
539
 
/*----------------------------------------------------------------------------*/
 
551
 
540
552
/**
541
553
 * process feature-enabling request on hub
542
554
 *
553
565
        if (port < 1 || port > instance->port_count)
554
566
                return EINVAL;
555
567
 
556
 
        switch (feature)
557
 
        {
558
 
        case USB_HUB_FEATURE_PORT_POWER:   //8
559
 
                /* No power switching */
560
 
                if (instance->registers->rh_desc_a & RHDA_NPS_FLAG)
561
 
                        return EOK;
562
 
                /* Ganged power switching */
563
 
                if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) {
564
 
                        instance->registers->rh_status = RHS_SET_GLOBAL_POWER;
565
 
                        return EOK;
 
568
        switch (feature) {
 
569
        case USB_HUB_FEATURE_PORT_POWER:   /*8*/
 
570
                {
 
571
                        const uint32_t rhda =
 
572
                            OHCI_RD(instance->registers->rh_desc_a);
 
573
                        /* No power switching */
 
574
                        if (rhda & RHDA_NPS_FLAG)
 
575
                                return EOK;
 
576
                        /* Ganged power switching, one port powers all */
 
577
                        if (!(rhda & RHDA_PSM_FLAG)) {
 
578
                                OHCI_WR(instance->registers->rh_status,
 
579
                                    RHS_SET_GLOBAL_POWER);
 
580
                                return EOK;
 
581
                        }
566
582
                }
567
 
        case USB_HUB_FEATURE_PORT_ENABLE:  //1
568
 
        case USB_HUB_FEATURE_PORT_SUSPEND: //2
569
 
        case USB_HUB_FEATURE_PORT_RESET:   //4
570
 
                /* Nice thing is that these shifts correspond to the position
571
 
                 * of control bits in register */
572
 
                instance->registers->rh_port_status[port - 1] = (1 << feature);
 
583
                        /* Fall through */
 
584
        case USB_HUB_FEATURE_PORT_ENABLE:  /*1*/
 
585
        case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/
 
586
        case USB_HUB_FEATURE_PORT_RESET:   /*4*/
 
587
                usb_log_debug2("Setting port POWER, ENABLE, SUSPEND or RESET "
 
588
                    "on port %"PRIu16".\n", port);
 
589
                OHCI_WR(instance->registers->rh_port_status[port - 1],
 
590
                    1 << feature);
573
591
                return EOK;
574
592
        default:
575
593
                return ENOTSUP;
576
594
        }
577
595
}
578
 
/*----------------------------------------------------------------------------*/
 
596
 
579
597
/**
580
598
 * Process feature clear request.
581
599
 *
595
613
        /* Enabled features to clear: see page 269 of USB specs */
596
614
        switch (feature)
597
615
        {
598
 
        case USB_HUB_FEATURE_PORT_POWER:          //8
599
 
                /* No power switching */
600
 
                if (instance->registers->rh_desc_a & RHDA_NPS_FLAG)
601
 
                        return ENOTSUP;
602
 
                /* Ganged power switching */
603
 
                if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) {
604
 
                        instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
 
616
        case USB_HUB_FEATURE_PORT_POWER:          /*8*/
 
617
                {
 
618
                        const uint32_t rhda =
 
619
                            OHCI_RD(instance->registers->rh_desc_a);
 
620
                        /* No power switching */
 
621
                        if (rhda & RHDA_NPS_FLAG)
 
622
                                return ENOTSUP;
 
623
                        /* Ganged power switching, one port powers all */
 
624
                        if (!(rhda & RHDA_PSM_FLAG)) {
 
625
                                OHCI_WR(instance->registers->rh_status,
 
626
                                    RHS_CLEAR_GLOBAL_POWER);
 
627
                                return EOK;
 
628
                        }
 
629
                        OHCI_WR(instance->registers->rh_port_status[port - 1],
 
630
                            RHPS_CLEAR_PORT_POWER);
605
631
                        return EOK;
606
632
                }
607
 
                instance->registers->rh_port_status[port - 1] =
608
 
                        RHPS_CLEAR_PORT_POWER;
609
 
                return EOK;
610
 
 
611
 
        case USB_HUB_FEATURE_PORT_ENABLE:         //1
612
 
                instance->registers->rh_port_status[port - 1] =
613
 
                        RHPS_CLEAR_PORT_ENABLE;
614
 
                return EOK;
615
 
 
616
 
        case USB_HUB_FEATURE_PORT_SUSPEND:        //2
617
 
                instance->registers->rh_port_status[port - 1] =
618
 
                        RHPS_CLEAR_PORT_SUSPEND;
619
 
                return EOK;
620
 
 
621
 
        case USB_HUB_FEATURE_C_PORT_CONNECTION:   //16
622
 
        case USB_HUB_FEATURE_C_PORT_ENABLE:       //17
623
 
        case USB_HUB_FEATURE_C_PORT_SUSPEND:      //18
624
 
        case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: //19
625
 
        case USB_HUB_FEATURE_C_PORT_RESET:        //20
626
 
                /* Nice thing is that these shifts correspond to the position
627
 
                 * of control bits in register */
628
 
                instance->registers->rh_port_status[port - 1] = (1 << feature);
 
633
 
 
634
        case USB_HUB_FEATURE_PORT_ENABLE:         /*1*/
 
635
                OHCI_WR(instance->registers->rh_port_status[port - 1],
 
636
                    RHPS_CLEAR_PORT_ENABLE);
 
637
                return EOK;
 
638
 
 
639
        case USB_HUB_FEATURE_PORT_SUSPEND:        /*2*/
 
640
                OHCI_WR(instance->registers->rh_port_status[port - 1],
 
641
                    RHPS_CLEAR_PORT_SUSPEND);
 
642
                return EOK;
 
643
 
 
644
        case USB_HUB_FEATURE_C_PORT_CONNECTION:   /*16*/
 
645
        case USB_HUB_FEATURE_C_PORT_ENABLE:       /*17*/
 
646
        case USB_HUB_FEATURE_C_PORT_SUSPEND:      /*18*/
 
647
        case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: /*19*/
 
648
        case USB_HUB_FEATURE_C_PORT_RESET:        /*20*/
 
649
                usb_log_debug2("Clearing port C_CONNECTION, C_ENABLE, "
 
650
                    "C_SUSPEND, C_OC or C_RESET on port %"PRIu16".\n", port);
 
651
                /* Bit offsets correspond to the feature number */
 
652
                OHCI_WR(instance->registers->rh_port_status[port - 1],
 
653
                    1 << feature);
629
654
                return EOK;
630
655
 
631
656
        default:
632
657
                return ENOTSUP;
633
658
        }
634
659
}
635
 
/*----------------------------------------------------------------------------*/
 
660
 
636
661
/**
637
662
 * process one of requests that do not request nor carry additional data
638
663
 *
653
678
        {
654
679
        case USB_HUB_REQ_TYPE_SET_PORT_FEATURE:
655
680
                usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
656
 
                int ret = set_feature_port(instance,
 
681
                const int ret = set_feature_port(instance,
657
682
                    setup_request->value, setup_request->index);
658
683
                TRANSFER_END(request, ret);
659
684
 
670
695
                TRANSFER_END(request, ENOTSUP);
671
696
        }
672
697
}
673
 
/*----------------------------------------------------------------------------*/
 
698
 
674
699
/**
675
700
 * process one of requests that do not request nor carry additional data
676
701
 *
692
717
        {
693
718
        case USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE:
694
719
                usb_log_debug("USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE\n");
695
 
                int ret = clear_feature_port(instance,
 
720
                const int ret = clear_feature_port(instance,
696
721
                    setup_request->value, setup_request->index);
697
722
                TRANSFER_END(request, ret);
698
723
 
705
730
                 * C_HUB_LOCAL_POWER is not supported
706
731
                 * as root hubs do not support local power status feature.
707
732
                 * (OHCI pg. 127) */
708
 
                if (setup_request->value == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) {
709
 
                        instance->registers->rh_status = RHS_OCIC_FLAG;
 
733
                if (uint16_usb2host(setup_request->value)
 
734
                    == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) {
 
735
                        OHCI_WR(instance->registers->rh_status, RHS_OCIC_FLAG);
710
736
                        TRANSFER_END(request, EOK);
711
737
                }
712
738
        //TODO: Consider standard USB requests: REMOTE WAKEUP, ENDPOINT STALL
716
742
                TRANSFER_END(request, ENOTSUP);
717
743
        }
718
744
}
719
 
/*----------------------------------------------------------------------------*/
 
745
 
720
746
/**
721
747
 * Process hub control request.
722
748
 *
770
796
                usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
771
797
                if (request->buffer_size == 0)
772
798
                        TRANSFER_END(request, EOVERFLOW);
773
 
                uint8_t config = 1;
 
799
                const uint8_t config = 1;
774
800
                TRANSFER_END_DATA(request, &config, sizeof(config));
775
801
 
776
802
        case USB_DEVREQ_CLEAR_FEATURE:
789
815
                if (uint16_usb2host(setup_request->value) > 127)
790
816
                        TRANSFER_END(request, EINVAL);
791
817
 
792
 
                instance->address = setup_request->value;
 
818
                instance->address = uint16_usb2host(setup_request->value);
793
819
                TRANSFER_END(request, EOK);
794
820
 
795
821
        case USB_DEVREQ_SET_CONFIGURATION:
796
822
                usb_log_debug("USB_DEVREQ_SET_CONFIGURATION: %u\n",
797
 
                    setup_request->value);
 
823
                    uint16_usb2host(setup_request->value));
798
824
                /* We have only one configuration, it's number is 1 */
799
825
                if (uint16_usb2host(setup_request->value) != 1)
800
826
                        TRANSFER_END(request, EINVAL);