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

Changeset e913cc9 in mainline


Ignore:
Timestamp:
2011-05-13T20:40:48Z (11 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master
Children:
04c418d, 72cd53d
Parents:
00b6c73
Message:

Virtual HC destroy pending transfers after unplug

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/vhc/transfer.c

    r00b6c73 re913cc9  
    161161}
    162162
     163static vhc_transfer_t *dequeue_first_transfer(vhc_virtdev_t *dev)
     164{
     165        assert(fibril_mutex_is_locked(&dev->guard));
     166        assert(!list_empty(&dev->transfer_queue));
     167
     168        vhc_transfer_t *transfer = list_get_instance(dev->transfer_queue.next,
     169            vhc_transfer_t, link);
     170        list_remove(&transfer->link);
     171
     172        return transfer;
     173}
     174
     175
     176static void execute_transfer_callback_and_free(vhc_transfer_t *transfer,
     177    size_t data_transfer_size, int outcome)
     178{
     179        assert(outcome != ENAK);
     180
     181        usb_log_debug2("Transfer %p ended: %s.\n",
     182            transfer, str_error(outcome));
     183
     184        if (transfer->direction == USB_DIRECTION_IN) {
     185                transfer->callback_in(transfer->ddf_fun, outcome,
     186                    data_transfer_size, transfer->callback_arg);
     187        } else {
     188                assert(transfer->direction == USB_DIRECTION_OUT);
     189                transfer->callback_out(transfer->ddf_fun, outcome,
     190                    transfer->callback_arg);
     191        }
     192
     193        free(transfer);
     194}
    163195
    164196int vhc_transfer_queue_processor(void *arg)
     
    174206                }
    175207
    176                 vhc_transfer_t *transfer = list_get_instance(dev->transfer_queue.next,
    177                     vhc_transfer_t, link);
    178                 list_remove(&transfer->link);
     208                vhc_transfer_t *transfer = dequeue_first_transfer(dev);
    179209                fibril_mutex_unlock(&dev->guard);
    180210
     
    214244
    215245                if (rc != ENAK) {
    216                         usb_log_debug2("Transfer %p ended: %s.\n",
    217                             transfer, str_error(rc));
    218                         if (transfer->direction == USB_DIRECTION_IN) {
    219                                 transfer->callback_in(transfer->ddf_fun, rc,
    220                                     data_transfer_size, transfer->callback_arg);
    221                         } else {
    222                                 assert(transfer->direction == USB_DIRECTION_OUT);
    223                                 transfer->callback_out(transfer->ddf_fun, rc,
    224                                     transfer->callback_arg);
    225                         }
    226                         free(transfer);
     246                        execute_transfer_callback_and_free(transfer,
     247                            data_transfer_size, rc);
    227248                }
    228249
     
    231252        }
    232253
     254        /* Immediately fail all remaining transfers. */
     255        while (!list_empty(&dev->transfer_queue)) {
     256                vhc_transfer_t *transfer = dequeue_first_transfer(dev);
     257                execute_transfer_callback_and_free(transfer, 0, EBADCHECKSUM);
     258        }
     259
    233260        fibril_mutex_unlock(&dev->guard);
    234261
    235         // TODO - destroy pending transfers
    236 
    237262        return EOK;
    238263}
Note: See TracChangeset for help on using the changeset viewer.