Changeset 84439d7 in mainline for uspace/lib/drv


Ignore:
Timestamp:
2010-12-05T09:34:46Z (15 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
75732da
Parents:
56b962d (diff), 35537a7 (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 with development/

Location:
uspace/lib/drv
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/drv/generic/driver.c

    r56b962d r84439d7  
    4848#include <ctype.h>
    4949#include <errno.h>
     50#include <inttypes.h>
    5051
    5152#include <ipc/driver.h>
     
    164165       
    165166        devman_handle_t dev_handle =  IPC_GET_ARG1(*icall);
     167        devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall);
     168   
    166169        device_t *dev = create_device();
    167170        dev->handle = dev_handle;
     
    171174       
    172175        add_to_devices_list(dev);
     176        dev->parent = driver_get_device(&devices, parent_dev_handle);
     177       
    173178        res = driver->driver_ops->add_device(dev);
    174179        if (0 == res) {
    175                 printf("%s: new device with handle = %x was added.\n",
     180                printf("%s: new device with handle=%" PRIun " was added.\n",
    176181                    driver->name, dev_handle);
    177182        } else {
    178                 printf("%s: failed to add a new device with handle = %d.\n",
     183                printf("%s: failed to add a new device with handle = %" PRIun ".\n",
    179184                    driver->name, dev_handle);
    180185                remove_from_devices_list(dev);
     
    203208                        break;
    204209                default:
    205                         if (!(callid & IPC_CALLID_NOTIFICATION))
    206                                 ipc_answer_0(callid, ENOENT);
     210                        ipc_answer_0(callid, ENOENT);
    207211                }
    208212        }
     
    226230        if (dev == NULL) {
    227231                printf("%s: driver_connection_gen error - no device with handle"
    228                     " %x was found.\n", driver->name, handle);
     232                    " %" PRIun " was found.\n", driver->name, handle);
    229233                ipc_answer_0(iid, ENOENT);
    230234                return;
     
    290294                                printf("%s: driver_connection_gen error - ",
    291295                                    driver->name);
    292                                 printf("device with handle %d has no interface "
     296                                printf("device with handle %" PRIun " has no interface "
    293297                                    "with id %d.\n", handle, iface_idx);
    294298                                ipc_answer_0(callid, ENOTSUP);
  • uspace/lib/drv/generic/remote_usbhc.c

    r56b962d r84439d7  
    4242#define USB_MAX_PAYLOAD_SIZE 1020
    4343
     44static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4445static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4546static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4647static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
    47 //static void remote_usb(device_t *, void *, ipc_callid_t, ipc_call_t *);
     48static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
     49static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
     50static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
     51static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
     52static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
     53static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
     54static void remote_usbhc_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     55static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     56static void remote_usbhc_request_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     57static void remote_usbhc_bind_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     58static void remote_usbhc_release_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     59//static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4860
    4961/** Remote USB interface operations. */
    5062static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = {
    51         &remote_usbhc_get_buffer,
    52         &remote_usbhc_interrupt_out,
    53         &remote_usbhc_interrupt_in
     63        remote_usbhc_get_address,
     64
     65        remote_usbhc_get_buffer,
     66
     67        remote_usbhc_reserve_default_address,
     68        remote_usbhc_release_default_address,
     69
     70        remote_usbhc_request_address,
     71        remote_usbhc_bind_address,
     72        remote_usbhc_release_address,
     73
     74        remote_usbhc_interrupt_out,
     75        remote_usbhc_interrupt_in,
     76
     77        remote_usbhc_control_write_setup,
     78        remote_usbhc_control_write_data,
     79        remote_usbhc_control_write_status,
     80
     81        remote_usbhc_control_read_setup,
     82        remote_usbhc_control_read_data,
     83        remote_usbhc_control_read_status
    5484};
    5585
     
    6898} async_transaction_t;
    6999
     100void remote_usbhc_get_address(device_t *device, void *iface,
     101    ipc_callid_t callid, ipc_call_t *call)
     102{
     103        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     104
     105        if (!usb_iface->tell_address) {
     106                ipc_answer_0(callid, ENOTSUP);
     107                return;
     108        }
     109
     110        devman_handle_t handle = IPC_GET_ARG1(*call);
     111
     112        usb_address_t address;
     113        int rc = usb_iface->tell_address(device, handle, &address);
     114        if (rc != EOK) {
     115                ipc_answer_0(callid, rc);
     116        } else {
     117                ipc_answer_1(callid, EOK, address);
     118        }
     119}
    70120
    71121void remote_usbhc_get_buffer(device_t *device, void *iface,
     
    102152}
    103153
     154void remote_usbhc_reserve_default_address(device_t *device, void *iface,
     155    ipc_callid_t callid, ipc_call_t *call)
     156{
     157        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     158
     159        if (!usb_iface->reserve_default_address) {
     160                ipc_answer_0(callid, ENOTSUP);
     161                return;
     162        }
     163
     164        int rc = usb_iface->reserve_default_address(device);
     165
     166        ipc_answer_0(callid, rc);
     167}
     168
     169void remote_usbhc_release_default_address(device_t *device, void *iface,
     170    ipc_callid_t callid, ipc_call_t *call)
     171{
     172        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     173
     174        if (!usb_iface->release_default_address) {
     175                ipc_answer_0(callid, ENOTSUP);
     176                return;
     177        }
     178
     179        int rc = usb_iface->release_default_address(device);
     180
     181        ipc_answer_0(callid, rc);
     182}
     183
     184void remote_usbhc_request_address(device_t *device, void *iface,
     185    ipc_callid_t callid, ipc_call_t *call)
     186{
     187        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     188
     189        if (!usb_iface->request_address) {
     190                ipc_answer_0(callid, ENOTSUP);
     191                return;
     192        }
     193
     194        usb_address_t address;
     195        int rc = usb_iface->request_address(device, &address);
     196        if (rc != EOK) {
     197                ipc_answer_0(callid, rc);
     198        } else {
     199                ipc_answer_1(callid, EOK, (ipcarg_t) address);
     200        }
     201}
     202
     203void remote_usbhc_bind_address(device_t *device, void *iface,
     204    ipc_callid_t callid, ipc_call_t *call)
     205{
     206        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     207
     208        if (!usb_iface->bind_address) {
     209                ipc_answer_0(callid, ENOTSUP);
     210                return;
     211        }
     212
     213        usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call);
     214        devman_handle_t handle = (devman_handle_t) IPC_GET_ARG2(*call);
     215
     216        int rc = usb_iface->bind_address(device, address, handle);
     217
     218        ipc_answer_0(callid, rc);
     219}
     220
     221void remote_usbhc_release_address(device_t *device, void *iface,
     222    ipc_callid_t callid, ipc_call_t *call)
     223{
     224        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     225
     226        if (!usb_iface->release_address) {
     227                ipc_answer_0(callid, ENOTSUP);
     228                return;
     229        }
     230
     231        usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call);
     232
     233        int rc = usb_iface->release_address(device, address);
     234
     235        ipc_answer_0(callid, rc);
     236}
     237
    104238
    105239static void callback_out(device_t *device,
     
    125259}
    126260
    127 void remote_usbhc_interrupt_out(device_t *device, void *iface,
    128             ipc_callid_t callid, ipc_call_t *call)
    129 {
    130         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     261/** Process an outgoing transfer (both OUT and SETUP).
     262 *
     263 * @param device Target device.
     264 * @param callid Initiating caller.
     265 * @param call Initiating call.
     266 * @param transfer_func Transfer function (might be NULL).
     267 */
     268static void remote_usbhc_out_transfer(device_t *device,
     269    ipc_callid_t callid, ipc_call_t *call,
     270    usbhc_iface_transfer_out_t transfer_func)
     271{
     272        if (!transfer_func) {
     273                ipc_answer_0(callid, ENOTSUP);
     274                return;
     275        }
    131276
    132277        size_t expected_len = IPC_GET_ARG3(*call);
     
    149294        }
    150295
    151         if (!usb_iface->interrupt_out) {
    152                 ipc_answer_0(callid, ENOTSUP);
    153                 return;
    154         }
    155 
    156296        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    157297        trans->caller = callid;
    158         trans->buffer = NULL;
    159         trans->size = 0;
    160 
    161         int rc = usb_iface->interrupt_out(device, target, buffer, len,
     298        trans->buffer = buffer;
     299        trans->size = len;
     300
     301        int rc = transfer_func(device, target, buffer, len,
    162302            callback_out, trans);
    163303
    164304        if (rc != EOK) {
    165305                ipc_answer_0(callid, rc);
     306                if (buffer != NULL) {
     307                        free(buffer);
     308                }
    166309                free(trans);
    167310        }
    168311}
    169312
    170 void remote_usbhc_interrupt_in(device_t *device, void *iface,
    171             ipc_callid_t callid, ipc_call_t *call)
    172 {
    173         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     313/** Process an incoming transfer.
     314 *
     315 * @param device Target device.
     316 * @param callid Initiating caller.
     317 * @param call Initiating call.
     318 * @param transfer_func Transfer function (might be NULL).
     319 */
     320static void remote_usbhc_in_transfer(device_t *device,
     321    ipc_callid_t callid, ipc_call_t *call,
     322    usbhc_iface_transfer_in_t transfer_func)
     323{
     324        if (!transfer_func) {
     325                ipc_answer_0(callid, ENOTSUP);
     326                return;
     327        }
    174328
    175329        size_t len = IPC_GET_ARG3(*call);
     
    179333        };
    180334
    181         if (!usb_iface->interrupt_in) {
    182                 ipc_answer_0(callid, ENOTSUP);
    183                 return;
    184         }
    185 
    186335        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    187336        trans->caller = callid;
     
    189338        trans->size = len;
    190339
    191         int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,
     340        int rc = transfer_func(device, target, trans->buffer, len,
    192341            callback_in, trans);
    193342
     
    199348}
    200349
     350/** Process status part of control transfer.
     351 *
     352 * @param device Target device.
     353 * @param callid Initiating caller.
     354 * @param call Initiating call.
     355 * @param direction Transfer direction (read ~ in, write ~ out).
     356 * @param transfer_in_func Transfer function for control read (might be NULL).
     357 * @param transfer_out_func Transfer function for control write (might be NULL).
     358 */
     359static void remote_usbhc_status_transfer(device_t *device,
     360    ipc_callid_t callid, ipc_call_t *call,
     361    usb_direction_t direction,
     362    int (*transfer_in_func)(device_t *, usb_target_t,
     363        usbhc_iface_transfer_in_callback_t, void *),
     364    int (*transfer_out_func)(device_t *, usb_target_t,
     365        usbhc_iface_transfer_out_callback_t, void *))
     366{
     367        switch (direction) {
     368                case USB_DIRECTION_IN:
     369                        if (!transfer_in_func) {
     370                                ipc_answer_0(callid, ENOTSUP);
     371                                return;
     372                        }
     373                        break;
     374                case USB_DIRECTION_OUT:
     375                        if (!transfer_out_func) {
     376                                ipc_answer_0(callid, ENOTSUP);
     377                                return;
     378                        }
     379                        break;
     380                default:
     381                        assert(false && "unreachable code");
     382                        break;
     383        }
     384
     385        usb_target_t target = {
     386                .address = IPC_GET_ARG1(*call),
     387                .endpoint = IPC_GET_ARG2(*call)
     388        };
     389
     390        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     391        trans->caller = callid;
     392        trans->buffer = NULL;
     393        trans->size = 0;
     394
     395        int rc;
     396        switch (direction) {
     397                case USB_DIRECTION_IN:
     398                        rc = transfer_in_func(device, target,
     399                            callback_in, trans);
     400                        break;
     401                case USB_DIRECTION_OUT:
     402                        rc = transfer_out_func(device, target,
     403                            callback_out, trans);
     404                        break;
     405                default:
     406                        assert(false && "unreachable code");
     407                        break;
     408        }
     409
     410        if (rc != EOK) {
     411                ipc_answer_0(callid, rc);
     412                free(trans);
     413        }
     414        return;
     415}
     416
     417
     418void remote_usbhc_interrupt_out(device_t *device, void *iface,
     419    ipc_callid_t callid, ipc_call_t *call)
     420{
     421        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     422        assert(usb_iface != NULL);
     423
     424        return remote_usbhc_out_transfer(device, callid, call,
     425            usb_iface->interrupt_out);
     426}
     427
     428void remote_usbhc_interrupt_in(device_t *device, void *iface,
     429    ipc_callid_t callid, ipc_call_t *call)
     430{
     431        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     432        assert(usb_iface != NULL);
     433
     434        return remote_usbhc_in_transfer(device, callid, call,
     435            usb_iface->interrupt_in);
     436}
     437
     438void remote_usbhc_control_write_setup(device_t *device, void *iface,
     439    ipc_callid_t callid, ipc_call_t *call)
     440{
     441        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     442        assert(usb_iface != NULL);
     443
     444        return remote_usbhc_out_transfer(device, callid, call,
     445            usb_iface->control_write_setup);
     446}
     447
     448void remote_usbhc_control_write_data(device_t *device, void *iface,
     449    ipc_callid_t callid, ipc_call_t *call)
     450{
     451        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     452        assert(usb_iface != NULL);
     453
     454        return remote_usbhc_out_transfer(device, callid, call,
     455            usb_iface->control_write_data);
     456}
     457
     458void remote_usbhc_control_write_status(device_t *device, void *iface,
     459    ipc_callid_t callid, ipc_call_t *call)
     460{
     461        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     462        assert(usb_iface != NULL);
     463
     464        return remote_usbhc_status_transfer(device, callid, call,
     465            USB_DIRECTION_IN, usb_iface->control_write_status, NULL);
     466}
     467
     468void remote_usbhc_control_read_setup(device_t *device, void *iface,
     469    ipc_callid_t callid, ipc_call_t *call)
     470{
     471        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     472        assert(usb_iface != NULL);
     473
     474        return remote_usbhc_out_transfer(device, callid, call,
     475            usb_iface->control_read_setup);
     476}
     477
     478void remote_usbhc_control_read_data(device_t *device, void *iface,
     479            ipc_callid_t callid, ipc_call_t *call)
     480{
     481        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     482        assert(usb_iface != NULL);
     483
     484        return remote_usbhc_in_transfer(device, callid, call,
     485            usb_iface->control_read_data);
     486}
     487
     488void remote_usbhc_control_read_status(device_t *device, void *iface,
     489            ipc_callid_t callid, ipc_call_t *call)
     490{
     491        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     492        assert(usb_iface != NULL);
     493
     494        return remote_usbhc_status_transfer(device, callid, call,
     495            USB_DIRECTION_OUT, NULL, usb_iface->control_read_status);
     496}
     497
     498
    201499
    202500/**
  • uspace/lib/drv/include/usbhc_iface.h

    r56b962d r84439d7  
    9292 */
    9393typedef enum {
     94        /** Tell USB address assigned to device.
     95         * Parameters:
     96         * - devman handle id
     97         * Answer:
     98         * - EINVAL - unknown handle or handle not managed by this driver
     99         * - ENOTSUP - operation not supported by HC (shall not happen)
     100         * - arbitrary error code if returned by remote implementation
     101         * - EOK - handle found, first parameter contains the USB address
     102         */
     103        IPC_M_USBHC_GET_ADDRESS,
     104
    94105        /** Asks for data buffer.
    95106         * See explanation at usb_iface_funcs_t.
     
    100111
    101112
     113        /** Reserve usage of default address.
     114         * This call informs the host controller that the caller will be
     115         * using default USB address. It is duty of the HC driver to ensure
     116         * that only single entity will have it reserved.
     117         * The address is returned via IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS.
     118         * The caller can start using the address after receiving EOK
     119         * answer.
     120         */
     121        IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS,
     122
     123        /** Release usage of default address.
     124         * @see IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS
     125         */
     126        IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS,
     127
     128        /** Asks for address assignment by host controller.
     129         * Answer:
     130         * - ELIMIT - host controller run out of address
     131         * - EOK - address assigned
     132         * Answer arguments:
     133         * - assigned address
     134         *
     135         * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS.
     136         */
     137        IPC_M_USBHC_REQUEST_ADDRESS,
     138
     139        /** Bind USB address with devman handle.
     140         * Parameters:
     141         * - USB address
     142         * - devman handle
     143         * Answer:
     144         * - EOK - address binded
     145         * - ENOENT - address is not in use
     146         */
     147        IPC_M_USBHC_BIND_ADDRESS,
     148
     149        /** Release address in use.
     150         * Arguments:
     151         * - address to be released
     152         * Answer:
     153         * - ENOENT - address not in use
     154         * - EPERM - trying to release default USB address
     155         */
     156        IPC_M_USBHC_RELEASE_ADDRESS,
     157
     158
    102159        /** Send interrupt data to device.
    103160         * See explanation at usb_iface_funcs_t (OUT transaction).
     
    155212    usb_transaction_outcome_t, size_t, void *);
    156213
     214
     215/** Out transfer processing function prototype. */
     216typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t,
     217    void *, size_t,
     218    usbhc_iface_transfer_out_callback_t, void *);
     219
     220/** Setup transfer processing function prototype. */
     221typedef usbhc_iface_transfer_out_t usbhc_iface_transfer_setup_t;
     222
     223/** In transfer processing function prototype. */
     224typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t,
     225    void *, size_t,
     226    usbhc_iface_transfer_in_callback_t, void *);
     227
    157228/** USB devices communication interface. */
    158229typedef struct {
    159         int (*interrupt_out)(device_t *, usb_target_t,
    160             void *, size_t,
     230        int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
     231
     232        int (*reserve_default_address)(device_t *);
     233        int (*release_default_address)(device_t *);
     234        int (*request_address)(device_t *, usb_address_t *);
     235        int (*bind_address)(device_t *, usb_address_t, devman_handle_t);
     236        int (*release_address)(device_t *, usb_address_t);
     237
     238        usbhc_iface_transfer_out_t interrupt_out;
     239        usbhc_iface_transfer_in_t interrupt_in;
     240
     241        usbhc_iface_transfer_setup_t control_write_setup;
     242        usbhc_iface_transfer_out_t control_write_data;
     243        int (*control_write_status)(device_t *, usb_target_t,
     244            usbhc_iface_transfer_in_callback_t, void *);
     245
     246        usbhc_iface_transfer_setup_t control_read_setup;
     247        usbhc_iface_transfer_in_t control_read_data;
     248        int (*control_read_status)(device_t *, usb_target_t,
    161249            usbhc_iface_transfer_out_callback_t, void *);
    162         int (*interrupt_in)(device_t *, usb_target_t,
    163             void *, size_t,
    164             usbhc_iface_transfer_in_callback_t, void *);
    165250} usbhc_iface_t;
    166251
Note: See TracChangeset for help on using the changeset viewer.