Changeset 4fa05a32 in mainline


Ignore:
Timestamp:
2011-03-17T22:29:16Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7b13d8e
Parents:
bf58895 (diff), 0fd82c9 (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.
Message:

Merge development/ changes

Location:
uspace/drv
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/batch.c

    rbf58895 r4fa05a32  
    153153}
    154154/*----------------------------------------------------------------------------*/
     155/** Mark batch as failed and continue with next step.
     156 *
     157 * @param[in] instance Batch structure to use.
     158 *
     159 */
     160void batch_abort(batch_t *instance)
     161{
     162        assert(instance);
     163        instance->error = EIO;
     164        instance->next_step(instance);
     165}
     166/*----------------------------------------------------------------------------*/
    155167/** Check batch TDs for activity.
    156168 *
     
    251263        assert(instance);
    252264        /* We are data out, we are supposed to provide data */
    253         memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
     265        memcpy(instance->transport_buffer, instance->buffer,
     266            instance->buffer_size);
    254267        batch_data(instance, USB_PID_OUT);
    255268        instance->next_step = batch_call_out_and_dispose;
     
    281294        assert(instance);
    282295        /* We are data out, we are supposed to provide data */
    283         memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
     296        memcpy(instance->transport_buffer, instance->buffer,
     297            instance->buffer_size);
    284298        batch_data(instance, USB_PID_OUT);
    285299        instance->next_step = batch_call_out_and_dispose;
  • uspace/drv/uhci-hcd/batch.h

    rbf58895 r4fa05a32  
    6969} batch_t;
    7070
    71 batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    72     usb_transfer_type_t transfer_type, size_t max_packet_size,
    73     usb_speed_t speed, char *buffer, size_t size,
    74                 char *setup_buffer, size_t setup_size,
     71batch_t * batch_get(
     72    ddf_fun_t *fun,
     73                usb_target_t target,
     74    usb_transfer_type_t transfer_type,
     75                size_t max_packet_size,
     76    usb_speed_t speed,
     77                char *buffer,
     78                size_t size,
     79                char *setup_buffer,
     80                size_t setup_size,
    7581    usbhc_iface_transfer_in_callback_t func_in,
    76     usbhc_iface_transfer_out_callback_t func_out, void *arg,
     82    usbhc_iface_transfer_out_callback_t func_out,
     83                void *arg,
    7784                device_keeper_t *manager
    7885                );
    7986
    8087void batch_dispose(batch_t *instance);
     88
     89void batch_abort(batch_t *instance);
    8190
    8291bool batch_is_complete(batch_t *instance);
  • uspace/drv/uhci-hcd/transfer_list.c

    rbf58895 r4fa05a32  
    129129}
    130130/*----------------------------------------------------------------------------*/
     131/** Check list for finished batches.
     132 *
     133 * @param[in] instance List to use.
     134 * @return Error code
     135 *
     136 * Creates a local list of finished batches and calls next_step on each and
     137 * every one. This is safer because next_step may theoretically access
     138 * this transfer list leading to the deadlock if its done inline.
     139 */
     140void transfer_list_remove_finished(transfer_list_t *instance)
     141{
     142        assert(instance);
     143
     144        LIST_INITIALIZE(done);
     145
     146        fibril_mutex_lock(&instance->guard);
     147        link_t *current = instance->batch_list.next;
     148        while (current != &instance->batch_list) {
     149                link_t *next = current->next;
     150                batch_t *batch = list_get_instance(current, batch_t, link);
     151
     152                if (batch_is_complete(batch)) {
     153                        /* Save for post-processing */
     154                        transfer_list_remove_batch(instance, batch);
     155                        list_append(current, &done);
     156                }
     157                current = next;
     158        }
     159        fibril_mutex_unlock(&instance->guard);
     160
     161        while (!list_empty(&done)) {
     162                link_t *item = done.next;
     163                list_remove(item);
     164                batch_t *batch = list_get_instance(item, batch_t, link);
     165                batch->next_step(batch);
     166        }
     167}
     168/*----------------------------------------------------------------------------*/
     169/** Walk the list and abort all batches.
     170 *
     171 * @param[in] instance List to use.
     172 */
     173void transfer_list_abort_all(transfer_list_t *instance)
     174{
     175        fibril_mutex_lock(&instance->guard);
     176        while (list_empty(&instance->batch_list)) {
     177                link_t *current = instance->batch_list.next;
     178                batch_t *batch = list_get_instance(current, batch_t, link);
     179                transfer_list_remove_batch(instance, batch);
     180                batch_abort(batch);
     181        }
     182        fibril_mutex_unlock(&instance->guard);
     183}
     184/*----------------------------------------------------------------------------*/
    131185/** Remove a transfer batch from the list and queue.
    132186 *
     
    163217            batch, pos, instance->name, batch->qh->next);
    164218}
    165 /*----------------------------------------------------------------------------*/
    166 /** Check list for finished batches.
    167  *
    168  * @param[in] instance List to use.
    169  * @return Error code
    170  *
    171  * Creates a local list of finished batches and calls next_step on each and
    172  * every one. This is safer because next_step may theoretically access
    173  * this transfer list leading to the deadlock if its done inline.
    174  */
    175 void transfer_list_remove_finished(transfer_list_t *instance)
    176 {
    177         assert(instance);
    178 
    179         LIST_INITIALIZE(done);
    180 
    181         fibril_mutex_lock(&instance->guard);
    182         link_t *current = instance->batch_list.next;
    183         while (current != &instance->batch_list) {
    184                 link_t *next = current->next;
    185                 batch_t *batch = list_get_instance(current, batch_t, link);
    186 
    187                 if (batch_is_complete(batch)) {
    188                         /* Save for post-processing */
    189                         transfer_list_remove_batch(instance, batch);
    190                         list_append(current, &done);
    191                 }
    192                 current = next;
    193         }
    194         fibril_mutex_unlock(&instance->guard);
    195 
    196         while (!list_empty(&done)) {
    197                 link_t *item = done.next;
    198                 list_remove(item);
    199                 batch_t *batch = list_get_instance(item, batch_t, link);
    200                 batch->next_step(batch);
    201         }
    202 }
    203219/**
    204220 * @}
  • uspace/drv/uhci-hcd/transfer_list.h

    rbf58895 r4fa05a32  
    6666void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next);
    6767
     68void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch);
     69
    6870void transfer_list_remove_finished(transfer_list_t *instance);
    6971
    70 void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch);
     72void transfer_list_abort_all(transfer_list_t *instance);
    7173#endif
    7274/**
  • uspace/drv/uhci-hcd/uhci_hc.c

    rbf58895 r4fa05a32  
    9797
    9898        instance->hw_interrupts = interrupts;
     99        instance->hw_failures = 0;
     100
    99101        /* Setup UHCI function. */
    100102        instance->ddf_instance = fun;
     
    149151        while ((pio_read_16(&registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
    150152
    151         /* Set framelist pointer */
     153        /* Set frame to exactly 1ms */
     154        pio_write_8(&registers->sofmod, 64);
     155
     156        /* Set frame list pointer */
    152157        const uint32_t pa = addr_to_phys(instance->frame_list);
    153158        pio_write_32(&registers->flbaseadd, pa);
     
    347352{
    348353        assert(instance);
    349         /* TODO: Check interrupt cause here */
     354        /* TODO: Resume interrupts are not supported */
    350355        /* Lower 2 bits are transaction error and transaction complete */
    351356        if (status & 0x3) {
     
    354359                transfer_list_remove_finished(&instance->transfers_control_full);
    355360                transfer_list_remove_finished(&instance->transfers_bulk_full);
     361        }
     362        /* bits 4 and 5 indicate hc error */
     363        if (status & 0x18) {
     364                usb_log_error("UHCI hardware failure!.\n");
     365                ++instance->hw_failures;
     366                transfer_list_abort_all(&instance->transfers_interrupt);
     367                transfer_list_abort_all(&instance->transfers_control_slow);
     368                transfer_list_abort_all(&instance->transfers_control_full);
     369                transfer_list_abort_all(&instance->transfers_bulk_full);
     370
     371                if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) {
     372                        /* reinitialize hw, this triggers virtual disconnect*/
     373                        uhci_hc_init_hw(instance);
     374                } else {
     375                        usb_log_fatal("Too many UHCI hardware failures!.\n");
     376                        uhci_hc_fini(instance);
     377                }
    356378        }
    357379}
  • uspace/drv/uhci-hcd/uhci_hc.h

    rbf58895 r4fa05a32  
    8080#define UHCI_CLEANER_TIMEOUT 10000
    8181#define UHCI_DEBUGER_TIMEOUT 5000000
     82#define UHCI_ALLOWED_HW_FAIL 5
    8283
    8384typedef struct uhci_hc {
     
    100101        fid_t debug_checker;
    101102        bool hw_interrupts;
     103        unsigned hw_failures;
    102104
    103105        ddf_fun_t *ddf_instance;
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c

    rbf58895 r4fa05a32  
    159159            (s & TD_STATUS_ERROR_BIT_STUFF) ? " BIT_STUFF," : "",
    160160            (s & TD_STATUS_ERROR_RESERVED) ? " RESERVED," : "",
    161             (s >> TD_STATUS_ACTLEN_POS) & TD_STATUS_ACTLEN_MASK
     161            td_act_size(instance)
    162162        );
    163163}
  • uspace/drv/usbhub/usbhub.c

    rbf58895 r4fa05a32  
    7272int usb_hub_control_loop(void * hub_info_param){
    7373        usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;
    74         while(true){
    75                 usb_hub_check_hub_changes(hub_info);
     74        int errorCode = EOK;
     75
     76        while(errorCode == EOK){
     77                errorCode = usb_hub_check_hub_changes(hub_info);
    7678                async_usleep(1000 * 1000 );/// \TODO proper number once
    7779        }
     80        dprintf(USB_LOG_LEVEL_ERROR,
     81                                "something in ctrl loop went wrong, errno %d",errorCode);
    7882        return 0;
    7983}
     
    380384 * @param target
    381385 */
    382 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) {
     386static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
     387                bool isLowSpeed) {
    383388        usb_device_request_setup_packet_t request;
    384389        int opResult;
     
    386391        assert(hub->endpoints.control.hc_phone);
    387392        //get default address
    388         //opResult = usb_drv_reserve_default_address(hc);
    389         opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
     393        usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL;
     394        opResult = usb_hc_reserve_default_address(&hub->connection, speed);
    390395       
    391396        if (opResult != EOK) {
     
    446451        usb_address_t new_device_address = usb_hc_request_address(
    447452                        &hub->connection,
    448                         speed/// \TODO fullspeed??
     453                        speed
    449454                        );
    450455        if (new_device_address < 0) {
     
    510515static void usb_hub_removed_device(
    511516    usb_hub_info_t * hub,uint16_t port) {
    512         //usb_device_request_setup_packet_t request;
    513         int opResult;
    514        
     517               
    515518        /** \TODO remove device from device manager - not yet implemented in
    516519         * devide manager
     
    519522        //close address
    520523        if(hub->attached_devs[port].address!=0){
    521                 //opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
     524                /*uncomment this code to use it when DDF allows device removal
    522525                opResult = usb_hc_unregister_device(
    523526                                &hub->connection, hub->attached_devs[port].address);
     
    528531                hub->attached_devs[port].address = 0;
    529532                hub->attached_devs[port].handle = 0;
     533                 */
    530534        }else{
    531535                dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address");
     
    597601                if (usb_port_dev_connected(&status)) {
    598602                        dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
    599                         usb_hub_init_add_device(hub, port);
     603                        usb_hub_init_add_device(hub, port, usb_port_low_speed(&status));
    600604                } else {
    601605                        usb_hub_removed_device(hub, port);
     
    635639/**
    636640 * Check changes on particular hub
    637  * @param hub_info_param
    638  */
    639 void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
     641 * @param hub_info_param pointer to usb_hub_info_t structure
     642 * @return error code if there is problem when initializing communication with
     643 * hub, EOK otherwise
     644 */
     645int usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
    640646        int opResult;
    641647        opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
     
    643649                dprintf(USB_LOG_LEVEL_ERROR,
    644650                                "could not initialize communication for hub; %d", opResult);
    645                 return;
     651                return opResult;
    646652        }
    647653
     
    665671                dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub");
    666672                usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
    667                 return;
     673                return opResult;
    668674        }
    669675        unsigned int port;
     
    673679                                opResult);
    674680                usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
    675                 return;
     681                return opResult;
    676682        }
    677683        opResult = usb_hc_connection_open(&hub_info->connection);
     
    681687                usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
    682688                usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
    683                 return;
     689                return opResult;
    684690        }
    685691
     
    697703        usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
    698704        free(change_bitmap);
     705        return EOK;
    699706}
    700707
  • uspace/drv/usbhub/usbhub.h

    rbf58895 r4fa05a32  
    8787
    8888/**
    89  * check changes on specified hub
     89 * Check changes on specified hub
    9090 * @param hub_info_param pointer to usb_hub_info_t structure
     91 * @return error code if there is problem when initializing communication with
     92 * hub, EOK otherwise
    9193 */
    92 void usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
     94int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
    9395
    9496
Note: See TracChangeset for help on using the changeset viewer.