Changeset 79ae36dd in mainline for uspace/lib/usbvirt/src/ipc_hc.c


Ignore:
Timestamp:
2011-06-08T19:01:55Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0eff68e
Parents:
764d71e
Message:

new async framework with integrated exchange tracking

  • strict isolation between low-level IPC and high-level async framework with integrated exchange tracking
    • each IPC connection is represented by an async_sess_t structure
    • each IPC exchange is represented by an async_exch_t structure
    • exchange management is either based on atomic messages (EXCHANGE_ATOMIC), locking (EXCHANGE_SERIALIZE) or connection cloning (EXCHANGE_CLONE)
  • async_obsolete: temporary compatibility layer to keep old async clients working (several pieces of code are currently broken, but only non-essential functionality)
  • IPC_M_PHONE_HANGUP is now method no. 0 (for elegant boolean evaluation)
  • IPC_M_DEBUG_ALL has been renamed to IPC_M_DEBUG
  • IPC_M_PING has been removed (VFS protocol now has VFS_IN_PING)
  • console routines in libc have been rewritten for better abstraction
  • additional use for libc-private header files (FILE structure opaque to the client)
  • various cstyle changes (typos, indentation, missing externs in header files, improved comments, etc.)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbvirt/src/ipc_hc.c

    r764d71e r79ae36dd  
    4545/** Send control read transfer to virtual USB device.
    4646 *
    47  * @param phone IPC phone to the virtual device.
     47 * @param sess Session to the virtual device.
    4848 * @param ep Target endpoint number.
    4949 * @param setup_buffer Setup buffer.
     
    5252 * @param data_buffer_size Size of data buffer in bytes.
    5353 * @param data_transfered_size Number of actually transferred bytes.
     54 *
    5455 * @return Error code.
    55  */
    56 int usbvirt_ipc_send_control_read(int phone,
    57     void *setup_buffer, size_t setup_buffer_size,
    58     void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
     56 *
     57 */
     58int usbvirt_ipc_send_control_read(async_sess_t *sess, void *setup_buffer,
     59    size_t setup_buffer_size, void *data_buffer, size_t data_buffer_size,
     60    size_t *data_transfered_size)
    5961{
    60         if (phone < 0) {
    61                 return EINVAL;
    62         }
    63         if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
    64                 return EINVAL;
    65         }
    66         if ((data_buffer == NULL) || (data_buffer_size == 0)) {
    67                 return EINVAL;
    68         }
    69 
    70         aid_t opening_request = async_send_0(phone,
    71             IPC_M_USBVIRT_CONTROL_READ, NULL);
     62        if (!sess)
     63                return EINVAL;
     64       
     65        if ((setup_buffer == NULL) || (setup_buffer_size == 0))
     66                return EINVAL;
     67       
     68        if ((data_buffer == NULL) || (data_buffer_size == 0))
     69                return EINVAL;
     70       
     71        async_exch_t *exch = async_exchange_begin(sess);
     72       
     73        aid_t opening_request = async_send_0(exch, IPC_M_USBVIRT_CONTROL_READ,
     74            NULL);
    7275        if (opening_request == 0) {
    73                 return ENOMEM;
    74         }
    75 
    76         int rc = async_data_write_start(phone,
    77             setup_buffer, setup_buffer_size);
     76                async_exchange_end(exch);
     77                return ENOMEM;
     78        }
     79       
     80        int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size);
    7881        if (rc != EOK) {
     82                async_exchange_end(exch);
    7983                async_wait_for(opening_request, NULL);
    8084                return rc;
    8185        }
    82 
     86       
    8387        ipc_call_t data_request_call;
    84         aid_t data_request = async_data_read(phone,
    85             data_buffer, data_buffer_size,
     88        aid_t data_request = async_data_read(exch, data_buffer, data_buffer_size,
    8689            &data_request_call);
    87 
     90       
     91        async_exchange_end(exch);
     92       
    8893        if (data_request == 0) {
    8994                async_wait_for(opening_request, NULL);
    9095                return ENOMEM;
    9196        }
    92 
     97       
    9398        sysarg_t data_request_rc;
    9499        sysarg_t opening_request_rc;
    95100        async_wait_for(data_request, &data_request_rc);
    96101        async_wait_for(opening_request, &opening_request_rc);
    97 
     102       
    98103        if (data_request_rc != EOK) {
    99104                /* Prefer the return code of the opening request. */
    100                 if (opening_request_rc != EOK) {
     105                if (opening_request_rc != EOK)
    101106                        return (int) opening_request_rc;
    102                 } else {
     107                else
    103108                        return (int) data_request_rc;
    104                 }
    105         }
    106         if (opening_request_rc != EOK) {
     109        }
     110       
     111        if (opening_request_rc != EOK)
    107112                return (int) opening_request_rc;
    108         }
    109 
    110         if (data_transfered_size != NULL) {
     113       
     114        if (data_transfered_size != NULL)
    111115                *data_transfered_size = IPC_GET_ARG2(data_request_call);
    112         }
    113 
     116       
    114117        return EOK;
    115118}
     
    117120/** Send control write transfer to virtual USB device.
    118121 *
    119  * @param phone IPC phone to the virtual device.
     122 * @param sess Session to the virtual device.
    120123 * @param ep Target endpoint number.
    121124 * @param setup_buffer Setup buffer.
     
    123126 * @param data_buffer Data buffer (DATA stage of control transfer).
    124127 * @param data_buffer_size Size of data buffer in bytes.
     128 *
    125129 * @return Error code.
    126  */
    127 int usbvirt_ipc_send_control_write(int phone,
    128     void *setup_buffer, size_t setup_buffer_size,
    129     void *data_buffer, size_t data_buffer_size)
     130 *
     131 */
     132int usbvirt_ipc_send_control_write(async_sess_t *sess, void *setup_buffer,
     133    size_t setup_buffer_size, void *data_buffer, size_t data_buffer_size)
    130134{
    131         if (phone < 0) {
    132                 return EINVAL;
    133         }
    134         if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
    135                 return EINVAL;
    136         }
    137         if ((data_buffer_size > 0) && (data_buffer == NULL)) {
    138                 return EINVAL;
    139         }
    140 
    141         aid_t opening_request = async_send_1(phone,
    142             IPC_M_USBVIRT_CONTROL_WRITE, data_buffer_size,  NULL);
     135        if (!sess)
     136                return EINVAL;
     137       
     138        if ((setup_buffer == NULL) || (setup_buffer_size == 0))
     139                return EINVAL;
     140       
     141        if ((data_buffer_size > 0) && (data_buffer == NULL))
     142                return EINVAL;
     143       
     144        async_exch_t *exch = async_exchange_begin(sess);
     145       
     146        aid_t opening_request = async_send_1(exch, IPC_M_USBVIRT_CONTROL_WRITE,
     147            data_buffer_size, NULL);
    143148        if (opening_request == 0) {
    144                 return ENOMEM;
    145         }
    146 
    147         int rc = async_data_write_start(phone,
    148             setup_buffer, setup_buffer_size);
     149                async_exchange_end(exch);
     150                return ENOMEM;
     151        }
     152       
     153        int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size);
    149154        if (rc != EOK) {
     155                async_exchange_end(exch);
    150156                async_wait_for(opening_request, NULL);
    151157                return rc;
    152158        }
    153 
     159       
    154160        if (data_buffer_size > 0) {
    155                 rc = async_data_write_start(phone,
    156                     data_buffer, data_buffer_size);
    157 
     161                rc = async_data_write_start(exch, data_buffer, data_buffer_size);
    158162                if (rc != EOK) {
     163                        async_exchange_end(exch);
    159164                        async_wait_for(opening_request, NULL);
    160165                        return rc;
    161166                }
    162167        }
    163 
     168       
     169        async_exchange_end(exch);
     170       
    164171        sysarg_t opening_request_rc;
    165172        async_wait_for(opening_request, &opening_request_rc);
    166 
     173       
    167174        return (int) opening_request_rc;
    168175}
     
    170177/** Request data transfer from virtual USB device.
    171178 *
    172  * @param phone IPC phone to the virtual device.
     179 * @param sess Session to the virtual device.
    173180 * @param ep Target endpoint number.
    174181 * @param tr_type Transfer type (interrupt or bulk).
     
    176183 * @param data_size Size of the data buffer in bytes.
    177184 * @param act_size Number of actually returned bytes.
     185 *
    178186 * @return Error code.
    179  */
    180 int usbvirt_ipc_send_data_in(int phone, usb_endpoint_t ep,
     187 *
     188 */
     189int usbvirt_ipc_send_data_in(async_sess_t *sess, usb_endpoint_t ep,
    181190    usb_transfer_type_t tr_type, void *data, size_t data_size, size_t *act_size)
    182191{
    183         if (phone < 0) {
    184                 return EINVAL;
    185         }
     192        if (!sess)
     193                return EINVAL;
     194       
    186195        usbvirt_hc_to_device_method_t method;
     196       
    187197        switch (tr_type) {
    188198        case USB_TRANSFER_INTERRUPT:
     
    195205                return EINVAL;
    196206        }
    197         if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX)) {
    198                 return EINVAL;
    199         }
    200         if ((data == NULL) || (data_size == 0)) {
    201                 return EINVAL;
    202         }
    203 
    204 
    205         aid_t opening_request = async_send_2(phone, method, ep, tr_type, NULL);
     207       
     208        if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX))
     209                return EINVAL;
     210       
     211        if ((data == NULL) || (data_size == 0))
     212                return EINVAL;
     213       
     214        async_exch_t *exch = async_exchange_begin(sess);
     215       
     216        aid_t opening_request = async_send_2(exch, method, ep, tr_type, NULL);
    206217        if (opening_request == 0) {
    207                 return ENOMEM;
    208         }
    209 
    210 
     218                async_exchange_end(exch);
     219                return ENOMEM;
     220        }
     221       
    211222        ipc_call_t data_request_call;
    212         aid_t data_request = async_data_read(phone,
    213             data, data_size,  &data_request_call);
    214 
     223        aid_t data_request = async_data_read(exch, data, data_size,
     224            &data_request_call);
     225       
     226        async_exchange_end(exch);
     227       
    215228        if (data_request == 0) {
    216229                async_wait_for(opening_request, NULL);
    217230                return ENOMEM;
    218231        }
    219 
     232       
    220233        sysarg_t data_request_rc;
    221234        sysarg_t opening_request_rc;
    222235        async_wait_for(data_request, &data_request_rc);
    223236        async_wait_for(opening_request, &opening_request_rc);
    224 
     237       
    225238        if (data_request_rc != EOK) {
    226239                /* Prefer the return code of the opening request. */
    227                 if (opening_request_rc != EOK) {
     240                if (opening_request_rc != EOK)
    228241                        return (int) opening_request_rc;
    229                 } else {
     242                else
    230243                        return (int) data_request_rc;
    231                 }
    232         }
    233         if (opening_request_rc != EOK) {
     244        }
     245       
     246        if (opening_request_rc != EOK)
    234247                return (int) opening_request_rc;
    235         }
    236 
    237         if (act_size != NULL) {
     248       
     249        if (act_size != NULL)
    238250                *act_size = IPC_GET_ARG2(data_request_call);
    239         }
    240 
     251       
    241252        return EOK;
    242253}
     
    244255/** Send data to virtual USB device.
    245256 *
    246  * @param phone IPC phone to the virtual device.
     257 * @param sess Session to the virtual device.
    247258 * @param ep Target endpoint number.
    248259 * @param tr_type Transfer type (interrupt or bulk).
    249260 * @param data Data buffer.
    250261 * @param data_size Size of the data buffer in bytes.
     262 *
    251263 * @return Error code.
    252  */
    253 int usbvirt_ipc_send_data_out(int phone, usb_endpoint_t ep,
     264 *
     265 */
     266int usbvirt_ipc_send_data_out(async_sess_t *sess, usb_endpoint_t ep,
    254267    usb_transfer_type_t tr_type, void *data, size_t data_size)
    255268{
    256         if (phone < 0) {
    257                 return EINVAL;
    258         }
     269        if (!sess)
     270                return EINVAL;
     271       
    259272        usbvirt_hc_to_device_method_t method;
     273       
    260274        switch (tr_type) {
    261275        case USB_TRANSFER_INTERRUPT:
     
    268282                return EINVAL;
    269283        }
    270         if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX)) {
    271                 return EINVAL;
    272         }
    273         if ((data == NULL) || (data_size == 0)) {
    274                 return EINVAL;
    275         }
    276 
    277         aid_t opening_request = async_send_1(phone, method, ep, NULL);
     284       
     285        if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX))
     286                return EINVAL;
     287       
     288        if ((data == NULL) || (data_size == 0))
     289                return EINVAL;
     290       
     291        async_exch_t *exch = async_exchange_begin(sess);
     292       
     293        aid_t opening_request = async_send_1(exch, method, ep, NULL);
    278294        if (opening_request == 0) {
    279                 return ENOMEM;
    280         }
    281 
    282         int rc = async_data_write_start(phone,
    283             data, data_size);
     295                async_exchange_end(exch);
     296                return ENOMEM;
     297        }
     298       
     299        int rc = async_data_write_start(exch, data, data_size);
     300       
     301        async_exchange_end(exch);
     302       
    284303        if (rc != EOK) {
    285304                async_wait_for(opening_request, NULL);
    286305                return rc;
    287306        }
    288 
     307       
    289308        sysarg_t opening_request_rc;
    290309        async_wait_for(opening_request, &opening_request_rc);
    291 
     310       
    292311        return (int) opening_request_rc;
    293312}
    294313
    295 
    296314/**
    297315 * @}
Note: See TracChangeset for help on using the changeset viewer.