Changeset e50cd7f in mainline for uspace/drv/uhci-hcd/iface.c


Ignore:
Timestamp:
2011-04-17T19:17:55Z (14 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
63517c2, cfbbe1d3
Parents:
ef354b6 (diff), 8595577b (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:

new report structure fixes

File:
1 edited

Legend:

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

    ref354b6 re50cd7f  
    4141#include "hc.h"
    4242
    43 /** Reserve default address interface function
    44  *
    45  * @param[in] fun DDF function that was called.
    46  * @param[in] speed Speed to associate with the new default address.
    47  * @return Error code.
    48  */
    49 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)
    50 {
     43static inline int setup_batch(
     44    ddf_fun_t *fun, usb_target_t target, usb_direction_t direction,
     45    void *data, size_t size, void * setup_data, size_t setup_size,
     46    usbhc_iface_transfer_in_callback_t in,
     47    usbhc_iface_transfer_out_callback_t out, void *arg, const char* name,
     48    hc_t **hc, usb_transfer_batch_t **batch)
     49{
     50        assert(hc);
     51        assert(batch);
    5152        assert(fun);
    52         hc_t *hc = fun_to_hc(fun);
    53         assert(hc);
    54         usb_log_debug("Default address request with speed %d.\n", speed);
    55         usb_device_keeper_reserve_default_address(&hc->manager, speed);
    56         return EOK;
    57 #if 0
    58         endpoint_t *ep = malloc(sizeof(endpoint_t));
    59         if (ep == NULL)
     53        *hc = fun_to_hc(fun);
     54        assert(*hc);
     55
     56        size_t res_bw;
     57        endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager,
     58            target.address, target.endpoint, direction, &res_bw);
     59        if (ep == NULL) {
     60                usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
     61                    target.address, target.endpoint, name);
     62                return ENOENT;
     63        }
     64
     65        usb_log_debug("%s %d:%d %zu(%zu).\n",
     66            name, target.address, target.endpoint, size, ep->max_packet_size);
     67
     68        const size_t bw = bandwidth_count_usb11(
     69            ep->speed, ep->transfer_type, size, ep->max_packet_size);
     70        if (res_bw < bw) {
     71                usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
     72                    "but only %zu is reserved.\n",
     73                    target.address, target.endpoint, name, bw, res_bw);
     74                return ENOSPC;
     75        }
     76
     77        *batch = batch_get(
     78                fun, ep, data, size, setup_data, setup_size, in, out, arg);
     79        if (!*batch)
    6080                return ENOMEM;
    61         const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64;
    62         endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size);
    63         int ret;
    64 try_retgister:
    65         ret = usb_endpoint_manager_register_ep(&hc->ep_manager,
    66             USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0);
    67         if (ret == EEXISTS) {
    68                 async_usleep(1000);
    69                 goto try_retgister;
    70         }
    71         if (ret != EOK) {
    72                 endpoint_destroy(ep);
    73         }
    74         return ret;
    75 #endif
    76 }
    77 /*----------------------------------------------------------------------------*/
    78 /** Release default address interface function
    79  *
    80  * @param[in] fun DDF function that was called.
    81  * @return Error code.
    82  */
    83 static int release_default_address(ddf_fun_t *fun)
    84 {
    85         assert(fun);
    86         hc_t *hc = fun_to_hc(fun);
    87         assert(hc);
    88         usb_log_debug("Default address release.\n");
    89 //      return usb_endpoint_manager_unregister_ep(&hc->ep_manager,
    90 //          USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);
    91         usb_device_keeper_release_default_address(&hc->manager);
    9281        return EOK;
    9382}
     
    151140/*----------------------------------------------------------------------------*/
    152141static int register_endpoint(
    153     ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
     142    ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed,
     143    usb_endpoint_t endpoint,
    154144    usb_transfer_type_t transfer_type, usb_direction_t direction,
    155145    size_t max_packet_size, unsigned int interval)
     
    157147        hc_t *hc = fun_to_hc(fun);
    158148        assert(hc);
    159         const usb_speed_t speed =
    160             usb_device_keeper_get_speed(&hc->manager, address);
    161         const size_t size =
    162             (transfer_type == USB_TRANSFER_INTERRUPT
    163             || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
    164             max_packet_size : 0;
    165         int ret;
    166 
    167         endpoint_t *ep = malloc(sizeof(endpoint_t));
    168         if (ep == NULL)
    169                 return ENOMEM;
    170         ret = endpoint_init(ep, address, endpoint, direction,
    171             transfer_type, speed, max_packet_size);
    172         if (ret != EOK) {
    173                 free(ep);
    174                 return ret;
    175         }
    176 
     149        const size_t size = max_packet_size;
     150        usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
     151        if (speed >= USB_SPEED_MAX) {
     152                speed = ep_speed;
     153        }
    177154        usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
    178155            address, endpoint, usb_str_transfer_type(transfer_type),
    179156            usb_str_speed(speed), direction, size, max_packet_size, interval);
    180157
    181         ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size);
    182         if (ret != EOK) {
    183                 endpoint_destroy(ep);
    184         } else {
    185                 usb_device_keeper_add_ep(&hc->manager, address, ep);
    186         }
    187         return ret;
     158        return usb_endpoint_manager_add_ep(&hc->ep_manager, address, endpoint,
     159            direction, transfer_type, speed, max_packet_size, size);
    188160}
    189161/*----------------------------------------------------------------------------*/
     
    204176 * @param[in] fun DDF function that was called.
    205177 * @param[in] target USB device to write to.
    206  * @param[in] max_packet_size maximum size of data packet the device accepts
    207178 * @param[in] data Source of data.
    208179 * @param[in] size Size of data source.
     
    212183 */
    213184static int interrupt_out(
    214     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     185    ddf_fun_t *fun, usb_target_t target, void *data,
    215186    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    216187{
    217         assert(fun);
    218         hc_t *hc = fun_to_hc(fun);
    219         assert(hc);
    220 
    221         usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
    222             target.address, target.endpoint, size, max_packet_size);
    223 
    224         size_t res_bw;
    225         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    226             target.address, target.endpoint, USB_DIRECTION_OUT, &res_bw);
    227         if (ep == NULL) {
    228                 usb_log_error("Endpoint(%d:%d) not registered for INT OUT.\n",
    229                         target.address, target.endpoint);
    230                 return ENOENT;
    231         }
    232         const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
    233             size, ep->max_packet_size);
    234         if (res_bw < bw)
    235         {
    236                 usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw "
    237                     "but only %zu is reserved.\n",
    238                     target.address, target.endpoint, bw, res_bw);
    239                 return ENOENT;
    240         }
    241         assert(ep->speed ==
    242             usb_device_keeper_get_speed(&hc->manager, target.address));
    243         assert(ep->max_packet_size == max_packet_size);
    244         assert(ep->transfer_type == USB_TRANSFER_INTERRUPT);
    245 
    246         usb_transfer_batch_t *batch =
    247             batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
    248                 ep->speed, data, size, NULL, 0, NULL, callback, arg, ep);
    249         if (!batch)
    250                 return ENOMEM;
     188        usb_transfer_batch_t *batch = NULL;
     189        hc_t *hc = NULL;
     190        int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
     191            NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch);
     192        if (ret != EOK)
     193                return ret;
    251194        batch_interrupt_out(batch);
    252         const int ret = hc_schedule(hc, batch);
    253         if (ret != EOK) {
    254                 batch_dispose(batch);
     195        ret = hc_schedule(hc, batch);
     196        if (ret != EOK) {
     197                usb_transfer_batch_dispose(batch);
    255198        }
    256199        return ret;
     
    261204 * @param[in] fun DDF function that was called.
    262205 * @param[in] target USB device to write to.
    263  * @param[in] max_packet_size maximum size of data packet the device accepts
    264206 * @param[out] data Data destination.
    265207 * @param[in] size Size of data source.
     
    269211 */
    270212static int interrupt_in(
    271     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     213    ddf_fun_t *fun, usb_target_t target, void *data,
    272214    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    273215{
    274         assert(fun);
    275         hc_t *hc = fun_to_hc(fun);
    276         assert(hc);
    277 
    278         usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
    279             target.address, target.endpoint, size, max_packet_size);
    280 
    281         size_t res_bw;
    282         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    283             target.address, target.endpoint, USB_DIRECTION_IN, &res_bw);
    284         if (ep == NULL) {
    285                 usb_log_error("Endpoint(%d:%d) not registered for INT IN.\n",
    286                     target.address, target.endpoint);
    287                 return ENOENT;
    288         }
    289         const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
    290             size, ep->max_packet_size);
    291         if (res_bw < bw)
    292         {
    293                 usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw "
    294                     "but only %zu bw is reserved.\n",
    295                     target.address, target.endpoint, bw, res_bw);
    296                 return ENOENT;
    297         }
    298 
    299         assert(ep->speed ==
    300             usb_device_keeper_get_speed(&hc->manager, target.address));
    301         assert(ep->max_packet_size == max_packet_size);
    302         assert(ep->transfer_type == USB_TRANSFER_INTERRUPT);
    303 
    304         usb_transfer_batch_t *batch =
    305             batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
    306                 ep->speed, data, size, NULL, 0, callback, NULL, arg, ep);
    307         if (!batch)
    308                 return ENOMEM;
     216        usb_transfer_batch_t *batch = NULL;
     217        hc_t *hc = NULL;
     218        int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
     219            NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch);
     220        if (ret != EOK)
     221                return ret;
    309222        batch_interrupt_in(batch);
    310         const int ret = hc_schedule(hc, batch);
    311         if (ret != EOK) {
    312                 batch_dispose(batch);
     223        ret = hc_schedule(hc, batch);
     224        if (ret != EOK) {
     225                usb_transfer_batch_dispose(batch);
    313226        }
    314227        return ret;
     
    319232 * @param[in] fun DDF function that was called.
    320233 * @param[in] target USB device to write to.
    321  * @param[in] max_packet_size maximum size of data packet the device accepts
    322234 * @param[in] data Source of data.
    323235 * @param[in] size Size of data source.
     
    327239 */
    328240static int bulk_out(
    329     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     241    ddf_fun_t *fun, usb_target_t target, void *data,
    330242    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    331243{
    332         assert(fun);
    333         hc_t *hc = fun_to_hc(fun);
    334         assert(hc);
    335 
    336         usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
    337             target.address, target.endpoint, size, max_packet_size);
    338 
    339         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    340             target.address, target.endpoint, USB_DIRECTION_OUT, NULL);
    341         if (ep == NULL) {
    342                 usb_log_error("Endpoint(%d:%d) not registered for BULK OUT.\n",
    343                         target.address, target.endpoint);
    344                 return ENOENT;
    345         }
    346         assert(ep->speed ==
    347             usb_device_keeper_get_speed(&hc->manager, target.address));
    348         assert(ep->max_packet_size == max_packet_size);
    349         assert(ep->transfer_type == USB_TRANSFER_BULK);
    350 
    351         usb_transfer_batch_t *batch =
    352             batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
    353                 ep->speed, data, size, NULL, 0, NULL, callback, arg, ep);
    354         if (!batch)
    355                 return ENOMEM;
     244        usb_transfer_batch_t *batch = NULL;
     245        hc_t *hc = NULL;
     246        int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
     247            NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch);
     248        if (ret != EOK)
     249                return ret;
    356250        batch_bulk_out(batch);
    357         const int ret = hc_schedule(hc, batch);
    358         if (ret != EOK) {
    359                 batch_dispose(batch);
     251        ret = hc_schedule(hc, batch);
     252        if (ret != EOK) {
     253                usb_transfer_batch_dispose(batch);
    360254        }
    361255        return ret;
     
    366260 * @param[in] fun DDF function that was called.
    367261 * @param[in] target USB device to write to.
    368  * @param[in] max_packet_size maximum size of data packet the device accepts
    369262 * @param[out] data Data destination.
    370263 * @param[in] size Size of data source.
     
    374267 */
    375268static int bulk_in(
    376     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     269    ddf_fun_t *fun, usb_target_t target, void *data,
    377270    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    378271{
    379         assert(fun);
    380         hc_t *hc = fun_to_hc(fun);
    381         assert(hc);
    382         usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
    383             target.address, target.endpoint, size, max_packet_size);
    384 
    385         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    386             target.address, target.endpoint, USB_DIRECTION_IN, NULL);
    387         if (ep == NULL) {
    388                 usb_log_error("Endpoint(%d:%d) not registered for BULK IN.\n",
    389                         target.address, target.endpoint);
    390                 return ENOENT;
    391         }
    392         assert(ep->speed ==
    393             usb_device_keeper_get_speed(&hc->manager, target.address));
    394         assert(ep->max_packet_size == max_packet_size);
    395         assert(ep->transfer_type == USB_TRANSFER_BULK);
    396 
    397         usb_transfer_batch_t *batch =
    398             batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
    399                 ep->speed, data, size, NULL, 0, callback, NULL, arg, ep);
    400         if (!batch)
    401                 return ENOMEM;
     272        usb_transfer_batch_t *batch = NULL;
     273        hc_t *hc = NULL;
     274        int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
     275            NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch);
     276        if (ret != EOK)
     277                return ret;
    402278        batch_bulk_in(batch);
    403         const int ret = hc_schedule(hc, batch);
    404         if (ret != EOK) {
    405                 batch_dispose(batch);
     279        ret = hc_schedule(hc, batch);
     280        if (ret != EOK) {
     281                usb_transfer_batch_dispose(batch);
    406282        }
    407283        return ret;
     
    412288 * @param[in] fun DDF function that was called.
    413289 * @param[in] target USB device to write to.
    414  * @param[in] max_packet_size maximum size of data packet the device accepts.
    415290 * @param[in] setup_data Data to send with SETUP transfer.
    416291 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
     
    422297 */
    423298static int control_write(
    424     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     299    ddf_fun_t *fun, usb_target_t target,
    425300    void *setup_data, size_t setup_size, void *data, size_t size,
    426301    usbhc_iface_transfer_out_callback_t callback, void *arg)
    427302{
    428         assert(fun);
    429         hc_t *hc = fun_to_hc(fun);
    430         assert(hc);
    431         usb_speed_t speed =
    432             usb_device_keeper_get_speed(&hc->manager, target.address);
    433         usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
    434             speed, target.address, target.endpoint, size, max_packet_size);
    435         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    436             target.address, target.endpoint, USB_DIRECTION_BOTH, NULL);
    437         if (ep == NULL) {
    438                 usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n",
    439                         target.address, target.endpoint);
    440         }
    441 
    442         if (setup_size != 8)
    443                 return EINVAL;
    444 
    445         usb_transfer_batch_t *batch =
    446             batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed,
    447                 data, size, setup_data, setup_size, NULL, callback, arg, ep);
    448         if (!batch)
    449                 return ENOMEM;
    450         usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
     303        usb_transfer_batch_t *batch = NULL;
     304        hc_t *hc = NULL;
     305        int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
     306            setup_data, setup_size, NULL, callback, arg, "Control WRITE",
     307            &hc, &batch);
     308        if (ret != EOK)
     309                return ret;
     310        usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data);
    451311        batch_control_write(batch);
    452         const int ret = hc_schedule(hc, batch);
    453         if (ret != EOK) {
    454                 batch_dispose(batch);
     312        ret = hc_schedule(hc, batch);
     313        if (ret != EOK) {
     314                usb_transfer_batch_dispose(batch);
    455315        }
    456316        return ret;
     
    461321 * @param[in] fun DDF function that was called.
    462322 * @param[in] target USB device to write to.
    463  * @param[in] max_packet_size maximum size of data packet the device accepts.
    464323 * @param[in] setup_data Data to send with SETUP packet.
    465324 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     
    471330 */
    472331static int control_read(
    473     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     332    ddf_fun_t *fun, usb_target_t target,
    474333    void *setup_data, size_t setup_size, void *data, size_t size,
    475334    usbhc_iface_transfer_in_callback_t callback, void *arg)
    476335{
    477         assert(fun);
    478         hc_t *hc = fun_to_hc(fun);
    479         assert(hc);
    480         usb_speed_t speed =
    481             usb_device_keeper_get_speed(&hc->manager, target.address);
    482 
    483         usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
    484             speed, target.address, target.endpoint, size, max_packet_size);
    485         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    486             target.address, target.endpoint, USB_DIRECTION_BOTH, NULL);
    487         if (ep == NULL) {
    488                 usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n",
    489                         target.address, target.endpoint);
    490         }
    491         usb_transfer_batch_t *batch =
    492             batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed,
    493                 data, size, setup_data, setup_size, callback, NULL, arg, ep);
    494         if (!batch)
    495                 return ENOMEM;
     336        usb_transfer_batch_t *batch = NULL;
     337        hc_t *hc = NULL;
     338        int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
     339            setup_data, setup_size, callback, NULL, arg, "Control READ",
     340            &hc, &batch);
     341        if (ret != EOK)
     342                return ret;
    496343        batch_control_read(batch);
    497         const int ret = hc_schedule(hc, batch);
    498         if (ret != EOK) {
    499                 batch_dispose(batch);
     344        ret = hc_schedule(hc, batch);
     345        if (ret != EOK) {
     346                usb_transfer_batch_dispose(batch);
    500347        }
    501348        return ret;
     
    503350/*----------------------------------------------------------------------------*/
    504351usbhc_iface_t hc_iface = {
    505         .reserve_default_address = reserve_default_address,
    506         .release_default_address = release_default_address,
    507352        .request_address = request_address,
    508353        .bind_address = bind_address,
Note: See TracChangeset for help on using the changeset viewer.