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

Changeset 3a85a2b in mainline


Ignore:
Timestamp:
2011-04-15T07:46:50Z (11 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master
Children:
cd5b878
Parents:
e05d6c3
Message:

ohci root hub, interrupts

File:
1 edited

Legend:

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

    re05d6c3 r3a85a2b  
    198198static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request);
    199199
    200 
     200static int process_interrupt(rh_t *instance, usb_transfer_batch_t * request,
     201    void * change_buffer, size_t buffe_size);
     202
     203static bool is_zeros(void * buffer, size_t size);
    201204
    202205
     
    213216        // set port power mode to no-power-switching
    214217        instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
    215 
     218        instance->unfinished_interrupt_transfer = NULL;
    216219        usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);
    217220        return EOK;
     
    236239                usb_log_info("Root hub got INTERRUPT packet\n");
    237240                void * buffer;
     241                size_t buffer_size;
    238242                create_interrupt_mask(instance, &buffer,
    239                         &(request->transfered_size));
    240                 memcpy(request->data_buffer, buffer,
    241                         request->transfered_size);
     243                        &buffer_size);
     244                if(is_zeros(buffer,buffer_size)){
     245                        usb_log_debug("no changes..");
     246                        instance->unfinished_interrupt_transfer=
     247                            request;
     248                        //will be finished later
     249                }else{
     250                        usb_log_debug("processing changes..");
     251                        process_interrupt(instance, request,
     252                            buffer, buffer_size);
     253                }
     254                free(buffer);
    242255                opResult = EOK;
    243256        } else {
    244257                opResult = EINVAL;
    245         }
    246         usb_transfer_batch_finish_error(request, opResult);
     258                usb_transfer_batch_finish_error(request, opResult);
     259        }
    247260        return EOK;
    248261}
     
    252265
    253266void rh_interrupt(rh_t *instance) {
    254         usb_log_info("Whoa whoa wait, I`m not supposed to receive any "
    255                 "interrupts, am I?\n");
    256         /* TODO: implement? */
     267        //usb_log_info("Whoa whoa wait, I`m not supposed to receive any "
     268        //      "interrupts, am I?\n");
     269        if(!instance->unfinished_interrupt_transfer){
     270                return;
     271        }
     272        size_t size;
     273        void * buffer;
     274        create_interrupt_mask(instance, &buffer,
     275                        &size);
     276        process_interrupt(instance,instance->unfinished_interrupt_transfer,
     277            buffer,size);
     278        free(buffer);
    257279}
    258280/*----------------------------------------------------------------------------*/
     
    859881        return opResult;
    860882}
     883/*----------------------------------------------------------------------------*/
     884
     885/**
     886 * process hanging interrupt request
     887 *
     888 * If an interrupt transfer has been received and there was no change,
     889 * the driver stores the transfer information and waits for change to occcur.
     890 * This routine is called when that happens and it finalizes the interrupt
     891 * transfer.
     892 *
     893 * @param instance hub instance
     894 * @param request batch request to be processed
     895 * @param change_buffer chages on hub
     896 * @param buffer_size size of change buffer
     897 *
     898 * @return
     899 */
     900static int process_interrupt(rh_t *instance, usb_transfer_batch_t * request,
     901    void * change_buffer, size_t buffe_size){
     902        create_interrupt_mask(instance, &change_buffer,
     903            &(request->transfered_size));
     904        memcpy(request->data_buffer, change_buffer,request->transfered_size);
     905        instance->unfinished_interrupt_transfer = NULL;
     906        usb_transfer_batch_finish_error(request, EOK);
     907        return EOK;
     908}
     909
     910/*----------------------------------------------------------------------------*/
     911
     912/**
     913 * return whether the buffer is full of zeros
     914 *
     915 * Convenience function.
     916 * @param buffer
     917 * @param size
     918 * @return
     919 */
     920static bool is_zeros(void * buffer, size_t size){
     921        if(!buffer) return true;
     922        if(!size) return true;
     923        size_t i;
     924        for(i=0;i<size;++i){
     925                if(((char*)buffer)[i])
     926                        return false;
     927        }
     928        return true;
     929}
    861930
    862931/**
Note: See TracChangeset for help on using the changeset viewer.