Changeset 92574f4 in mainline for uspace/lib/usb/src/pipes.c


Ignore:
Timestamp:
2011-02-24T12:03:27Z (14 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e7b7ebd5
Parents:
4837092 (diff), a80849c (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:

Merged development (changes in DDF, etc.).

Conflicts in uspace/drv/usbkbd/main.c

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/pipes.c

    r4837092 r92574f4  
    3131 */
    3232/** @file
    33  * Communication between device drivers and host controller driver.
    34  *
    35  * Note on synchronousness of the operations: there is ABSOLUTELY NO
    36  * guarantee that a call to particular function will not trigger a fibril
    37  * switch.
    38  * The initialization functions may actually involve contacting some other
    39  * task, starting/ending a session might involve asynchronous IPC and since
    40  * the transfer functions uses IPC, asynchronous nature of them is obvious.
    41  * The pseudo synchronous versions for the transfers internally call the
    42  * asynchronous ones and so fibril switch is possible in them as well.
     33 * USB endpoint pipes miscellaneous functions.
    4334 */
    4435#include <usb/usb.h>
    4536#include <usb/pipes.h>
     37#include <usb/debug.h>
     38#include <usbhc_iface.h>
     39#include <usb_iface.h>
     40#include <devman.h>
    4641#include <errno.h>
    4742#include <assert.h>
    48 #include <usb/usbdrv.h>
    49 
    50 #define _PREPARE_TARGET(varname, pipe) \
    51         usb_target_t varname = { \
    52                 .address = (pipe)->wire->address, \
    53                 .endpoint = (pipe)->endpoint_no \
    54         }
     43
     44/** Tell USB address assigned to given device.
     45 *
     46 * @param phone Phone to parent device.
     47 * @param dev Device in question.
     48 * @return USB address or error code.
     49 */
     50static usb_address_t get_my_address(int phone, ddf_dev_t *dev)
     51{
     52        sysarg_t address;
     53
     54
     55        /*
     56         * We are sending special value as a handle - zero - to get
     57         * handle of the parent function (that handle was used
     58         * when registering our device @p dev.
     59         */
     60        int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE),
     61            IPC_M_USB_GET_ADDRESS,
     62            0, &address);
     63
     64        if (rc != EOK) {
     65                return rc;
     66        }
     67
     68        return (usb_address_t) address;
     69}
     70
     71/** Tell USB interface assigned to given device.
     72 *
     73 * @param device Device in question.
     74 * @return Interface number (negative code means any).
     75 */
     76int usb_device_get_assigned_interface(ddf_dev_t *device)
     77{
     78        int parent_phone = devman_parent_device_connect(device->handle,
     79            IPC_FLAG_BLOCKING);
     80        if (parent_phone < 0) {
     81                return -1;
     82        }
     83
     84        sysarg_t iface_no;
     85        int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
     86            IPC_M_USB_GET_INTERFACE,
     87            device->handle, &iface_no);
     88
     89        async_hangup(parent_phone);
     90
     91        if (rc != EOK) {
     92                return -1;
     93        }
     94
     95        return (int) iface_no;
     96}
    5597
    5698/** Initialize connection to USB device.
     
    61103 */
    62104int usb_device_connection_initialize_from_device(
    63     usb_device_connection_t *connection, device_t *device)
     105    usb_device_connection_t *connection, ddf_dev_t *dev)
    64106{
    65107        assert(connection);
    66         assert(device);
     108        assert(dev);
    67109
    68110        int rc;
     
    70112        usb_address_t my_address;
    71113
    72         rc = usb_drv_find_hc(device, &hc_handle);
     114        rc = usb_hc_find(dev->handle, &hc_handle);
    73115        if (rc != EOK) {
    74116                return rc;
    75117        }
    76118
    77         int hc_phone = devman_device_connect(hc_handle, 0);
    78         if (hc_phone < 0) {
    79                 return hc_phone;
    80         }
    81 
    82         my_address = usb_drv_get_my_address(hc_phone, device);
     119        int parent_phone = devman_parent_device_connect(dev->handle,
     120            IPC_FLAG_BLOCKING);
     121        if (parent_phone < 0) {
     122                return parent_phone;
     123        }
     124
     125        my_address = get_my_address(parent_phone, dev);
    83126        if (my_address < 0) {
    84127                rc = my_address;
     
    90133
    91134leave:
    92         ipc_hangup(hc_phone);
     135        async_hangup(parent_phone);
    93136        return rc;
    94137}
     
    117160}
    118161
    119 /** Initialize USB endpoint pipe.
    120  *
    121  * @param pipe Endpoint pipe to be initialized.
    122  * @param connection Connection to the USB device backing this pipe (the wire).
    123  * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15).
    124  * @param transfer_type Transfer type (e.g. interrupt or bulk).
    125  * @param direction Endpoint direction (in/out).
    126  * @return Error code.
    127  */
    128 int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *pipe,
    129     usb_device_connection_t *connection, usb_endpoint_t endpoint_no,
    130     usb_transfer_type_t transfer_type, usb_direction_t direction)
    131 {
    132         assert(pipe);
    133         assert(connection);
    134 
    135         pipe->wire = connection;
    136         pipe->hc_phone = -1;
    137         pipe->endpoint_no = endpoint_no;
    138         pipe->transfer_type = transfer_type;
    139         pipe->direction = direction;
    140 
    141         return EOK;
    142 }
    143 
    144 
    145 /** Initialize USB endpoint pipe as the default zero control pipe.
    146  *
    147  * @param pipe Endpoint pipe to be initialized.
    148  * @param connection Connection to the USB device backing this pipe (the wire).
    149  * @return Error code.
    150  */
    151 int usb_endpoint_pipe_initialize_default_control(usb_endpoint_pipe_t *pipe,
    152     usb_device_connection_t *connection)
    153 {
    154         assert(pipe);
    155         assert(connection);
    156 
    157         int rc = usb_endpoint_pipe_initialize(pipe, connection,
    158             0, USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH);
    159 
    160         return rc;
     162/** Initialize connection to USB device on default address.
     163 *
     164 * @param dev_connection Device connection structure to be initialized.
     165 * @param hc_connection Initialized connection to host controller.
     166 * @return Error code.
     167 */
     168int usb_device_connection_initialize_on_default_address(
     169    usb_device_connection_t *dev_connection,
     170    usb_hc_connection_t *hc_connection)
     171{
     172        assert(dev_connection);
     173
     174        if (hc_connection == NULL) {
     175                return EBADMEM;
     176        }
     177
     178        return usb_device_connection_initialize(dev_connection,
     179            hc_connection->hc_handle, (usb_address_t) 0);
    161180}
    162181
     
    181200        assert(pipe);
    182201
    183         if (pipe->hc_phone >= 0) {
     202        if (usb_endpoint_pipe_is_session_started(pipe)) {
    184203                return EBUSY;
    185204        }
     
    207226        assert(pipe);
    208227
    209         if (pipe->hc_phone < 0) {
     228        if (!usb_endpoint_pipe_is_session_started(pipe)) {
    210229                return ENOENT;
    211230        }
    212231
    213         int rc = ipc_hangup(pipe->hc_phone);
     232        int rc = async_hangup(pipe->hc_phone);
    214233        if (rc != EOK) {
    215234                return rc;
     
    221240}
    222241
    223 
    224 /** Request a read (in) transfer on an endpoint pipe.
    225  *
    226  * @param[in] pipe Pipe used for the transfer.
    227  * @param[out] buffer Buffer where to store the data.
    228  * @param[in] size Size of the buffer (in bytes).
    229  * @param[out] size_transfered Number of bytes that were actually transfered.
    230  * @return Error code.
    231  */
    232 int usb_endpoint_pipe_read(usb_endpoint_pipe_t *pipe,
    233     void *buffer, size_t size, size_t *size_transfered)
    234 {
    235         assert(pipe);
    236 
    237         int rc;
    238         usb_handle_t handle;
    239 
    240         rc = usb_endpoint_pipe_async_read(pipe, buffer, size, size_transfered,
    241             &handle);
    242         if (rc != EOK) {
    243                 return rc;
    244         }
    245 
    246         rc = usb_endpoint_pipe_wait_for(pipe, handle);
    247         return rc;
    248 }
    249 
    250 /** Request a write (out) transfer on an endpoint pipe.
    251  *
    252  * @param[in] pipe Pipe used for the transfer.
    253  * @param[in] buffer Buffer with data to transfer.
    254  * @param[in] size Size of the buffer (in bytes).
    255  * @return Error code.
    256  */
    257 int usb_endpoint_pipe_write(usb_endpoint_pipe_t *pipe,
    258     void *buffer, size_t size)
    259 {
    260         assert(pipe);
    261 
    262         int rc;
    263         usb_handle_t handle;
    264 
    265         rc = usb_endpoint_pipe_async_write(pipe, buffer, size, &handle);
    266         if (rc != EOK) {
    267                 return rc;
    268         }
    269 
    270         rc = usb_endpoint_pipe_wait_for(pipe, handle);
    271         return rc;
    272 }
    273 
    274 
    275 /** Request a control read transfer on an endpoint pipe.
    276  *
    277  * This function encapsulates all three stages of a control transfer.
    278  *
    279  * @param[in] pipe Pipe used for the transfer.
    280  * @param[in] setup_buffer Buffer with the setup packet.
    281  * @param[in] setup_buffer_size Size of the setup packet (in bytes).
    282  * @param[out] data_buffer Buffer for incoming data.
    283  * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
    284  * @param[out] data_transfered_size Number of bytes that were actually
    285  *                                  transfered during the DATA stage.
    286  * @return Error code.
    287  */
    288 int usb_endpoint_pipe_control_read(usb_endpoint_pipe_t *pipe,
    289     void *setup_buffer, size_t setup_buffer_size,
    290     void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
    291 {
    292         assert(pipe);
    293 
    294         int rc;
    295         usb_handle_t handle;
    296 
    297         rc = usb_endpoint_pipe_async_control_read(pipe,
    298             setup_buffer, setup_buffer_size,
    299             data_buffer, data_buffer_size, data_transfered_size,
    300             &handle);
    301         if (rc != EOK) {
    302                 return rc;
    303         }
    304 
    305         rc = usb_endpoint_pipe_wait_for(pipe, handle);
    306         return rc;
    307 }
    308 
    309 
    310 /** Request a control write transfer on an endpoint pipe.
    311  *
    312  * This function encapsulates all three stages of a control transfer.
    313  *
    314  * @param[in] pipe Pipe used for the transfer.
    315  * @param[in] setup_buffer Buffer with the setup packet.
    316  * @param[in] setup_buffer_size Size of the setup packet (in bytes).
    317  * @param[in] data_buffer Buffer with data to be sent.
    318  * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
    319  * @return Error code.
    320  */
    321 int usb_endpoint_pipe_control_write(usb_endpoint_pipe_t *pipe,
    322     void *setup_buffer, size_t setup_buffer_size,
    323     void *data_buffer, size_t data_buffer_size)
    324 {
    325         assert(pipe);
    326 
    327         int rc;
    328         usb_handle_t handle;
    329 
    330         rc = usb_endpoint_pipe_async_control_write(pipe,
    331             setup_buffer, setup_buffer_size,
    332             data_buffer, data_buffer_size,
    333             &handle);
    334         if (rc != EOK) {
    335                 return rc;
    336         }
    337 
    338         rc = usb_endpoint_pipe_wait_for(pipe, handle);
    339         return rc;
    340 }
    341 
    342 
    343 /** Request a read (in) transfer on an endpoint pipe (asynchronous version).
    344  *
    345  * @param[in] pipe Pipe used for the transfer.
    346  * @param[out] buffer Buffer where to store the data.
    347  * @param[in] size Size of the buffer (in bytes).
    348  * @param[out] size_transfered Number of bytes that were actually transfered.
    349  * @param[out] handle Handle of the transfer.
    350  * @return Error code.
    351  */
    352 int usb_endpoint_pipe_async_read(usb_endpoint_pipe_t *pipe,
    353     void *buffer, size_t size, size_t *size_transfered,
    354     usb_handle_t *handle)
    355 {
    356         assert(pipe);
    357 
    358         if (pipe->hc_phone < 0) {
    359                 return EBADF;
    360         }
    361 
    362         if (pipe->direction != USB_DIRECTION_IN) {
    363                 return EBADF;
    364         }
    365 
    366         int rc;
    367         _PREPARE_TARGET(target, pipe);
    368 
    369         switch (pipe->transfer_type) {
    370                 case USB_TRANSFER_INTERRUPT:
    371                         rc = usb_drv_async_interrupt_in(pipe->hc_phone, target,
    372                             buffer, size, size_transfered, handle);
    373                         break;
    374                 case USB_TRANSFER_CONTROL:
    375                         rc = EBADF;
    376                         break;
    377                 default:
    378                         rc = ENOTSUP;
    379                         break;
    380         }
    381 
    382         return rc;
    383 }
    384 
    385 
    386 /** Request a write (out) transfer on an endpoint pipe (asynchronous version).
    387  *
    388  * @param[in] pipe Pipe used for the transfer.
    389  * @param[in] buffer Buffer with data to transfer.
    390  * @param[in] size Size of the buffer (in bytes).
    391  * @param[out] handle Handle of the transfer.
    392  * @return Error code.
    393  */
    394 int usb_endpoint_pipe_async_write(usb_endpoint_pipe_t *pipe,
    395     void *buffer, size_t size,
    396     usb_handle_t *handle)
    397 {
    398         assert(pipe);
    399 
    400         if (pipe->hc_phone < 0) {
    401                 return EBADF;
    402         }
    403 
    404         if (pipe->direction != USB_DIRECTION_OUT) {
    405                 return EBADF;
    406         }
    407 
    408         int rc;
    409         _PREPARE_TARGET(target, pipe);
    410 
    411         switch (pipe->transfer_type) {
    412                 case USB_TRANSFER_INTERRUPT:
    413                         rc = usb_drv_async_interrupt_out(pipe->hc_phone, target,
    414                             buffer, size, handle);
    415                         break;
    416                 case USB_TRANSFER_CONTROL:
    417                         rc = EBADF;
    418                         break;
    419                 default:
    420                         rc = ENOTSUP;
    421                         break;
    422         }
    423 
    424         return rc;
    425 }
    426 
    427 
    428 /** Request a control read transfer on an endpoint pipe (asynchronous version).
    429  *
    430  * This function encapsulates all three stages of a control transfer.
    431  *
    432  * @param[in] pipe Pipe used for the transfer.
    433  * @param[in] setup_buffer Buffer with the setup packet.
    434  * @param[in] setup_buffer_size Size of the setup packet (in bytes).
    435  * @param[out] data_buffer Buffer for incoming data.
    436  * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
    437  * @param[out] data_transfered_size Number of bytes that were actually
    438  *                                  transfered during the DATA stage.
    439  * @param[out] handle Handle of the transfer.
    440  * @return Error code.
    441  */
    442 int usb_endpoint_pipe_async_control_read(usb_endpoint_pipe_t *pipe,
    443     void *setup_buffer, size_t setup_buffer_size,
    444     void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size,
    445     usb_handle_t *handle)
    446 {
    447         assert(pipe);
    448 
    449         if (pipe->hc_phone < 0) {
    450                 return EBADF;
    451         }
    452 
    453         if ((pipe->direction != USB_DIRECTION_BOTH)
    454             || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
    455                 return EBADF;
    456         }
    457 
    458         int rc;
    459         _PREPARE_TARGET(target, pipe);
    460 
    461         rc = usb_drv_async_control_read(pipe->hc_phone, target,
    462             setup_buffer, setup_buffer_size,
    463             data_buffer, data_buffer_size, data_transfered_size,
    464             handle);
    465 
    466         return rc;
    467 }
    468 
    469 
    470 /** Request a control write transfer on an endpoint pipe (asynchronous version).
    471  *
    472  * This function encapsulates all three stages of a control transfer.
    473  *
    474  * @param[in] pipe Pipe used for the transfer.
    475  * @param[in] setup_buffer Buffer with the setup packet.
    476  * @param[in] setup_buffer_size Size of the setup packet (in bytes).
    477  * @param[in] data_buffer Buffer with data to be sent.
    478  * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
    479  * @param[out] handle Handle of the transfer.
    480  * @return Error code.
    481  */
    482 int usb_endpoint_pipe_async_control_write(usb_endpoint_pipe_t *pipe,
    483     void *setup_buffer, size_t setup_buffer_size,
    484     void *data_buffer, size_t data_buffer_size,
    485     usb_handle_t *handle)
    486 {
    487         assert(pipe);
    488 
    489         if (pipe->hc_phone < 0) {
    490                 return EBADF;
    491         }
    492 
    493         if ((pipe->direction != USB_DIRECTION_BOTH)
    494             || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
    495                 return EBADF;
    496         }
    497 
    498         int rc;
    499         _PREPARE_TARGET(target, pipe);
    500 
    501         rc = usb_drv_async_control_write(pipe->hc_phone, target,
    502             setup_buffer, setup_buffer_size,
    503             data_buffer, data_buffer_size,
    504             handle);
    505 
    506         return rc;
    507 }
    508 
    509 /** Wait for transfer completion.
    510  *
    511  * The function blocks the caller fibril until the transfer associated
    512  * with given @p handle is completed.
    513  *
    514  * @param[in] pipe Pipe the transfer executed on.
    515  * @param[in] handle Transfer handle.
    516  * @return Error code.
    517  */
    518 int usb_endpoint_pipe_wait_for(usb_endpoint_pipe_t *pipe, usb_handle_t handle)
    519 {
    520         return usb_drv_async_wait_for(handle);
    521 }
    522 
     242/** Tell whether a session is started (open) on the endpoint pipe.
     243 *
     244 * The expected usage of this function is in assertions for some
     245 * nested functions.
     246 *
     247 * @param pipe Endpoint pipe in question.
     248 * @return Whether @p pipe has opened a session.
     249 */
     250bool usb_endpoint_pipe_is_session_started(usb_endpoint_pipe_t *pipe)
     251{
     252        return (pipe->hc_phone >= 0);
     253}
    523254
    524255/**
Note: See TracChangeset for help on using the changeset viewer.