Ticket #350: OHCI_rh_port_replug.patch

File OHCI_rh_port_replug.patch, 3.3 KB (added by Jan Vesely, 13 years ago)

Move port switching quirk to hw startup routine

  • uspace/drv/bus/usb/ohci/hc.c

    === modified file 'uspace/drv/bus/usb/ohci/hc.c'
    old new  
    518518        instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT);
    519519        usb_log_debug("OHCI HC up and running (ctl_reg=0x%x).\n",
    520520            instance->registers->control);
     521        rh_replug(&instance->rh);
    521522}
    522523/*----------------------------------------------------------------------------*/
    523524/** Initialize schedule queues
  • uspace/drv/bus/usb/ohci/ohci_regs.h

    === modified file 'uspace/drv/bus/usb/ohci/ohci_regs.h'
    old new  
    137137
    138138        /** The first root hub control register */
    139139        volatile uint32_t rh_desc_a;
    140 #define RHDA_NDS_MASK (0xff) /* Number of downstream ports, max 15 */
    141 #define RHDA_NDS_SHIFT (0)
     140#define RHDA_NDP_MASK  (0xff)    /* Number of downstream ports, max 15 */
     141#define RHDA_NDP_SHIFT (0)
    142142#define RHDA_PSM_FLAG  (1 << 8)  /* Power switching mode: 0-global, 1-per port*/
    143143#define RHDA_NPS_FLAG  (1 << 9)  /* No power switch: 1-power on, 0-use PSM*/
    144144#define RHDA_DT_FLAG   (1 << 10) /* 1-Compound device, must be 0 */
  • uspace/drv/bus/usb/ohci/root_hub.c

    === modified file 'uspace/drv/bus/usb/ohci/root_hub.c'
    old new  
    218218        assert(instance);
    219219        instance->registers = regs;
    220220        instance->port_count =
    221             (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK;
     221            (instance->registers->rh_desc_a >> RHDA_NDP_SHIFT) & RHDA_NDP_MASK;
    222222        int opResult = rh_init_descriptors(instance);
    223223        if (opResult != EOK) {
    224224                return opResult;
    225225        }
    226         // set port power mode to no-power-switching
     226
     227        /* Set port power mode to no-power-switching (always on) */
    227228        instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
     229
    228230        instance->unfinished_interrupt_transfer = NULL;
    229231        instance->interrupt_mask_size = (instance->port_count + 8) / 8;
    230232        instance->interrupt_buffer = malloc(instance->interrupt_mask_size);
     
    236238
    237239        return EOK;
    238240}
     241
     242void rh_replug(rh_t *instance)
     243{
     244        assert(instance);
     245        /* Simulate unplug */
     246
     247        /* Enable power-switching */
     248        instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG;
     249        /* Set power switch to global */
     250        instance->registers->rh_desc_a &= ~RHDA_PSM_FLAG;
     251        /* Shut down ports */
     252        instance->registers->rh_status |= RHS_CLEAR_PORT_POWER;
     253        async_usleep(10000);
     254        instance->registers->rh_status |= RHS_SET_PORT_POWER;
     255
     256        /* Set port power mode to no-power-switching (always on) */
     257        instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
     258}
    239259/*----------------------------------------------------------------------------*/
    240260
    241261/**
  • uspace/drv/bus/usb/ohci/root_hub.h

    === modified file 'uspace/drv/bus/usb/ohci/root_hub.h'
    old new  
    7373
    7474int rh_init(rh_t *instance, ohci_regs_t *regs);
    7575
     76void rh_replug(rh_t *instance);
     77
    7678int rh_request(rh_t *instance, usb_transfer_batch_t *request);
    7779
    7880void rh_interrupt(rh_t *instance);