Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset f20bc82 in mainline


Ignore:
Timestamp:
2011-07-11T17:10:31Z (10 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master
Children:
14426a0
Parents:
b21dfba
Message:

OHCI: Root hub: Don't store interrupt mask in rh_t isntance.

It was never kept and always refreshed. OHCI limit of 15 ports enables us to use uint16_t directly if we take care of endian issue.

Location:
uspace/drv/bus/usb/ohci
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ohci/root_hub.c

    rb21dfba rf20bc82  
    134134static void create_serialized_hub_descriptor(rh_t *instance);
    135135static void rh_init_descriptors(rh_t *instance);
    136 static void create_interrupt_mask_in_instance(rh_t *instance);
     136static uint16_t create_interrupt_mask_in_instance(rh_t *instance);
    137137static int get_status_request(rh_t *instance, usb_transfer_batch_t *request);
    138138static int get_descriptor_request(
     
    145145static int request_without_data(rh_t *instance, usb_transfer_batch_t *request);
    146146static int ctrl_request(rh_t *instance, usb_transfer_batch_t *request);
    147 static void interrupt_mask_in_instance(
    148     rh_t *instance, usb_transfer_batch_t *request);
    149 static bool is_zeros(const void *buffer, size_t size);
    150 
    151147
    152148#define TRANSFER_OK(bytes) \
     
    175171        /* Don't forget the hub status bit and round up */
    176172        instance->interrupt_mask_size = (instance->port_count + 1 + 8) / 8;
    177         instance->interrupt_buffer[0] = 0;
    178         instance->interrupt_buffer[1] = 0;
    179173        instance->unfinished_interrupt_transfer = NULL;
    180174
     
    210204        case USB_TRANSFER_INTERRUPT:
    211205                usb_log_debug("Root hub got INTERRUPT packet\n");
    212                 create_interrupt_mask_in_instance(instance);
    213                 if (is_zeros(instance->interrupt_buffer,
    214                     instance->interrupt_mask_size)) {
     206                const uint16_t mask =
     207                    create_interrupt_mask_in_instance(instance);
     208                if (mask == 0) {
    215209                        usb_log_debug("No changes..\n");
    216210                        instance->unfinished_interrupt_transfer = request;
     
    218212                } else {
    219213                        usb_log_debug("Processing changes..\n");
    220                         interrupt_mask_in_instance(instance, request);
     214                        memcpy(request->data_buffer, &mask,
     215                            instance->interrupt_mask_size);
     216                        request->transfered_size = instance->interrupt_mask_size;
     217                        instance->unfinished_interrupt_transfer = NULL;
     218                        usb_transfer_batch_finish_error(request, EOK);
    221219                }
    222220                break;
     
    240238
    241239        usb_log_debug("Finalizing interrupt transfer\n");
    242         create_interrupt_mask_in_instance(instance);
    243         interrupt_mask_in_instance(instance,
    244             instance->unfinished_interrupt_transfer);
     240        const uint16_t mask = create_interrupt_mask_in_instance(instance);
     241        memcpy(instance->unfinished_interrupt_transfer->data_buffer,
     242            &mask, instance->interrupt_mask_size);
     243        instance->unfinished_interrupt_transfer->transfered_size =
     244           instance->interrupt_mask_size;
     245        usb_transfer_batch_finish(instance->unfinished_interrupt_transfer);
     246
     247        instance->unfinished_interrupt_transfer = NULL;
    245248}
    246249/*----------------------------------------------------------------------------*/
     
    383386 * @param instance root hub instance
    384387 */
    385 void create_interrupt_mask_in_instance(rh_t *instance)
    386 {
    387         assert(instance);
    388 
    389         uint8_t * bitmap = instance->interrupt_buffer;
    390         bzero(bitmap, instance->interrupt_mask_size);
     388uint16_t create_interrupt_mask_in_instance(rh_t *instance)
     389{
     390        assert(instance);
     391        uint16_t mask = 0;
     392
    391393        /* Only local power source change and over-current change can happen */
    392394        if (instance->registers->rh_status & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) {
    393                 bitmap[0] = 1;
     395                mask |= 1;
    394396        }
    395397        size_t port = 1;
     
    399401                    & instance->registers->rh_port_status[port - 1]) {
    400402
    401                         bitmap[(port) / 8] |= 1 << (port % 8);
     403                        mask |= (1 << port);
    402404                }
    403405        }
     406        return host2uint32_t_le(mask);
    404407}
    405408/*----------------------------------------------------------------------------*/
     
    700703        }
    701704}
    702 /*----------------------------------------------------------------------------*/
    703 /**
    704  * Process waiting interrupt request
    705  *
    706  * If an interrupt transfer has been received and there was no change,
    707  * the driver stores the transfer information and waits for change to occur.
    708  * This routine is called when that happens and it finalizes the interrupt
    709  * transfer.
    710  *
    711  * @param instance hub instance
    712  * @param request batch request to be processed
    713  *
    714  * @return
    715  */
    716 void interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t *request)
    717 {
    718         assert(instance);
    719         assert(request);
    720 
    721         memcpy(request->data_buffer, instance->interrupt_buffer,
    722             instance->interrupt_mask_size);
    723         request->transfered_size = instance->interrupt_mask_size;
    724         instance->unfinished_interrupt_transfer = NULL;
    725         usb_transfer_batch_finish_error(request, EOK);
    726 }
    727 /*----------------------------------------------------------------------------*/
    728 /**
    729  * return whether the buffer is full of zeros
    730  *
    731  * Convenience function.
    732  * @param buffer
    733  * @param size
    734  * @return
    735  */
    736 bool is_zeros(const void *buffer, size_t size)
    737 {
    738         if (!buffer) return true;
    739         const char * const end = buffer + size;
    740         const char *data = buffer;
    741         for (; data < end; ++data) {
    742                 if (*data)
    743                         return false;
    744         }
    745         return true;
    746 }
    747705
    748706/**
  • uspace/drv/bus/usb/ohci/root_hub.h

    rb21dfba rf20bc82  
    4242
    4343#define HUB_DESCRIPTOR_MAX_SIZE (7 + 2 + 2)
    44 #define INTERRUPT_BUFFER_MAX_SIZE 2
    4544
    4645/**
     
    5655        /** interrupt transfer waiting for an actual interrupt to occur */
    5756        usb_transfer_batch_t *unfinished_interrupt_transfer;
    58         /** Interrupt mask of changes
    59          *
    60          * OHCI support max 15 ports (specs page 124) + one global bit, it
    61          * gives max 2 bytes.
    62          */
    63         uint8_t interrupt_buffer[INTERRUPT_BUFFER_MAX_SIZE];
    6457        /** size of interrupt buffer */
    6558        size_t interrupt_mask_size;
Note: See TracChangeset for help on using the changeset viewer.