Changeset 48fe0c9 in mainline


Ignore:
Timestamp:
2011-03-21T13:43:27Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
361e61b, 5971dd3, 8a951ca
Parents:
0e45e7f (diff), 925e099 (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:

OHCI hc driver software side implementation

Location:
uspace
Files:
1 added
9 edited
5 moved

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/Makefile

    r0e45e7f r48fe0c9  
    3333
    3434SOURCES = \
    35         hc_iface.c \
     35        iface.c \
    3636        batch.c \
    3737        main.c \
    38         ohci_hc.c \
    39         ohci_rh.c \
     38        hc.c \
     39        root_hub.c \
    4040        pci.c
    4141
  • uspace/drv/ohci/batch.c

    r0e45e7f r48fe0c9  
    3939
    4040#include "batch.h"
     41#include "utils/malloc32.h"
     42
     43static void batch_call_in_and_dispose(batch_t *instance);
     44static void batch_call_out_and_dispose(batch_t *instance);
    4145
    4246#define DEFAULT_ERROR_COUNT 3
     47batch_t * batch_get(
     48    ddf_fun_t *fun,
     49                usb_target_t target,
     50    usb_transfer_type_t transfer_type,
     51                size_t max_packet_size,
     52    usb_speed_t speed,
     53                char *buffer,
     54                size_t buffer_size,
     55                char *setup_buffer,
     56                size_t setup_size,
     57    usbhc_iface_transfer_in_callback_t func_in,
     58    usbhc_iface_transfer_out_callback_t func_out,
     59                void *arg,
     60                device_keeper_t *manager
     61                )
     62{
     63#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
     64        if (ptr == NULL) { \
     65                usb_log_error(message); \
     66                if (instance) { \
     67                        batch_dispose(instance); \
     68                } \
     69                return NULL; \
     70        } else (void)0
    4371
     72        batch_t *instance = malloc(sizeof(batch_t));
     73        CHECK_NULL_DISPOSE_RETURN(instance,
     74            "Failed to allocate batch instance.\n");
     75        batch_init(instance, target, transfer_type, speed, max_packet_size,
     76            buffer, NULL, buffer_size, NULL, setup_size, func_in,
     77            func_out, arg, fun, NULL);
     78
     79        if (buffer_size > 0) {
     80                instance->transport_buffer = malloc32(buffer_size);
     81                CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
     82                    "Failed to allocate device accessible buffer.\n");
     83        }
     84
     85        if (setup_size > 0) {
     86                instance->setup_buffer = malloc32(setup_size);
     87                CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer,
     88                    "Failed to allocate device accessible setup buffer.\n");
     89                memcpy(instance->setup_buffer, setup_buffer, setup_size);
     90        }
     91
     92
     93        return instance;
     94}
     95/*----------------------------------------------------------------------------*/
     96void batch_dispose(batch_t *instance)
     97{
     98        assert(instance);
     99        free32(instance->transport_buffer);
     100        free32(instance->setup_buffer);
     101        free(instance);
     102}
     103/*----------------------------------------------------------------------------*/
     104void batch_control_write(batch_t *instance)
     105{
     106        assert(instance);
     107        /* We are data out, we are supposed to provide data */
     108        memcpy(instance->transport_buffer, instance->buffer,
     109            instance->buffer_size);
     110        instance->next_step = batch_call_out_and_dispose;
     111        /* TODO: implement */
     112        usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
     113}
     114/*----------------------------------------------------------------------------*/
     115void batch_control_read(batch_t *instance)
     116{
     117        assert(instance);
     118        instance->next_step = batch_call_in_and_dispose;
     119        /* TODO: implement */
     120        usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
     121}
     122/*----------------------------------------------------------------------------*/
     123void batch_interrupt_in(batch_t *instance)
     124{
     125        assert(instance);
     126        instance->direction = USB_DIRECTION_IN;
     127        instance->next_step = batch_call_in_and_dispose;
     128        /* TODO: implement */
     129        usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
     130}
     131/*----------------------------------------------------------------------------*/
     132void batch_interrupt_out(batch_t *instance)
     133{
     134        assert(instance);
     135        instance->direction = USB_DIRECTION_OUT;
     136        /* We are data out, we are supposed to provide data */
     137        memcpy(instance->transport_buffer, instance->buffer,
     138            instance->buffer_size);
     139        instance->next_step = batch_call_out_and_dispose;
     140        /* TODO: implement */
     141        usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
     142}
     143/*----------------------------------------------------------------------------*/
     144void batch_bulk_in(batch_t *instance)
     145{
     146        assert(instance);
     147        instance->direction = USB_DIRECTION_IN;
     148        instance->next_step = batch_call_in_and_dispose;
     149        /* TODO: implement */
     150        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
     151}
     152/*----------------------------------------------------------------------------*/
     153void batch_bulk_out(batch_t *instance)
     154{
     155        assert(instance);
     156        instance->direction = USB_DIRECTION_IN;
     157        instance->next_step = batch_call_in_and_dispose;
     158        /* TODO: implement */
     159        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
     160}
     161/*----------------------------------------------------------------------------*/
     162/** Helper function calls callback and correctly disposes of batch structure.
     163 *
     164 * @param[in] instance Batch structure to use.
     165 */
     166void batch_call_in_and_dispose(batch_t *instance)
     167{
     168        assert(instance);
     169        batch_call_in(instance);
     170        batch_dispose(instance);
     171}
     172/*----------------------------------------------------------------------------*/
     173/** Helper function calls callback and correctly disposes of batch structure.
     174 *
     175 * @param[in] instance Batch structure to use.
     176 */
     177void batch_call_out_and_dispose(batch_t *instance)
     178{
     179        assert(instance);
     180        batch_call_out(instance);
     181        batch_dispose(instance);
     182}
    44183/**
    45184 * @}
  • uspace/drv/ohci/hc.c

    r0e45e7f r48fe0c9  
    3939#include <usb/debug.h>
    4040#include <usb/usb.h>
     41#include <usb/hub.h>
    4142#include <usb/ddfiface.h>
    42 #include <usb_iface.h>
     43#include <usb/usbdevice.h>
    4344
    44 #include "ohci_hc.h"
     45#include "hc.h"
    4546
    46 int ohci_hc_init(ohci_hc_t *instance, ddf_fun_t *fun,
     47static int dummy_reset(int foo, void *arg)
     48{
     49        hc_t *hc = (hc_t*)arg;
     50        assert(hc);
     51        hc->rh.address = 0;
     52        return EOK;
     53}
     54/*----------------------------------------------------------------------------*/
     55int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
    4756    uintptr_t regs, size_t reg_size, bool interrupts)
    4857{
    4958        assert(instance);
    50         int ret = pio_enable((void*)regs, reg_size, (void**)&instance->registers);
     59        int ret = EOK;
     60
     61        ret = pio_enable((void*)regs, reg_size, (void**)&instance->registers);
    5162        if (ret != EOK) {
    5263                usb_log_error("Failed to gain access to device registers.\n");
    5364                return ret;
    5465        }
    55         instance->registers->interrupt_disable = 0;
    56         /* enable interrupt on root hub status change */
    57         instance->registers->interupt_enable |= IE_RHSC | IE_MIE;
     66        instance->ddf_instance = fun;
     67        device_keeper_init(&instance->manager);
    5868
    5969
    60         ohci_rh_init(&instance->rh, instance->registers);
     70        rh_init(&instance->rh, dev, instance->registers);
    6171        /* TODO: implement */
    62         /* TODO: register root hub */
    6372        return EOK;
    6473}
    6574/*----------------------------------------------------------------------------*/
    66 int ohci_hc_schedule(ohci_hc_t *instance, batch_t *batch)
     75int hc_register_hub(hc_t *instance)
     76{
     77        async_usleep(1000000);
     78#define CHECK_RET_RETURN(ret, msg...) \
     79        if (ret != EOK) { \
     80                usb_log_error(msg); \
     81                return ret; \
     82        } else (void)0
     83        assert(instance);
     84        assert(instance->ddf_instance);
     85        assert(instance->ddf_instance->handle);
     86        ddf_dev_t *dev = instance->rh.device;
     87        int ret = EOK;
     88
     89        usb_hc_connection_t conn;
     90        ret =
     91            usb_hc_connection_initialize(&conn, instance->ddf_instance->handle);
     92        CHECK_RET_RETURN(ret, "Failed to initialize hc connection.\n");
     93
     94        ret = usb_hc_connection_open(&conn);
     95        CHECK_RET_RETURN(ret, "Failed to open hc connection.\n");
     96
     97        usb_address_t address;
     98        devman_handle_t handle;
     99        ret = usb_hc_new_device_wrapper(dev, &conn, USB_SPEED_FULL, dummy_reset,
     100            0, instance, &address, &handle, NULL, NULL, NULL);
     101        CHECK_RET_RETURN(ret, "Failed to add rh device.\n");
     102
     103        ret = usb_hc_connection_close(&conn);
     104        CHECK_RET_RETURN(ret, "Failed to close hc connection.\n");
     105        return EOK;
     106}
     107/*----------------------------------------------------------------------------*/
     108int hc_schedule(hc_t *instance, batch_t *batch)
    67109{
    68110        assert(instance);
    69111        assert(batch);
    70112        if (batch->target.address == instance->rh.address) {
    71                 ohci_rh_request(&instance->rh, batch);
    72                 return EOK;
     113                return rh_request(&instance->rh, batch);
    73114        }
    74115        /* TODO: implement */
    75         return EOK;
     116        return ENOTSUP;
    76117}
    77118/*----------------------------------------------------------------------------*/
    78 void ohci_hc_interrupt(ohci_hc_t *instance, uint16_t status)
     119void hc_interrupt(hc_t *instance, uint16_t status)
    79120{
    80121        assert(instance);
    81122        /* TODO: Check for interrupt cause */
    82         ohci_rh_interrupt(&instance->rh);
     123        rh_interrupt(&instance->rh);
    83124        /* TODO: implement */
    84125}
  • uspace/drv/ohci/hc.h

    r0e45e7f r48fe0c9  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 
    29 /** @addtogroup drvusbohcihc
     28/** @addtogroup drvusbohci
    3029 * @{
    3130 */
     
    3332 * @brief OHCI host controller driver structure
    3433 */
    35 #ifndef DRV_OHCI_OHCI_HC_H
    36 #define DRV_OHCI_OHCI_HC_H
     34#ifndef DRV_OHCI_HC_H
     35#define DRV_OHCI_HC_H
    3736
    3837#include <fibril.h>
     
    4241
    4342#include <usb/usb.h>
     43#include <usb/host/device_keeper.h>
    4444#include <usbhc_iface.h>
    4545
    4646#include "batch.h"
    4747#include "ohci_regs.h"
    48 #include "ohci_rh.h"
     48#include "root_hub.h"
    4949
    50 typedef struct ohci_hc {
     50typedef struct hc {
    5151        ohci_regs_t *registers;
    5252        usb_address_t rh_address;
    53         ohci_rh_t rh;
     53        rh_t rh;
    5454        ddf_fun_t *ddf_instance;
    55 } ohci_hc_t;
     55        device_keeper_t manager;
     56} hc_t;
    5657
    57 int ohci_hc_init(ohci_hc_t *instance, ddf_fun_t *fun,
     58int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
    5859     uintptr_t regs, size_t reg_size, bool interrupts);
    5960
    60 int ohci_hc_schedule(ohci_hc_t *instance, batch_t *batch);
     61int hc_register_hub(hc_t *instance);
    6162
    62 void ohci_hc_interrupt(ohci_hc_t *instance, uint16_t status);
     63int hc_schedule(hc_t *instance, batch_t *batch);
     64
     65void hc_interrupt(hc_t *instance, uint16_t status);
    6366
    6467/** Safely dispose host controller internal structures
     
    6669 * @param[in] instance Host controller structure to use.
    6770 */
    68 static inline void ohci_hc_fini(ohci_hc_t *instance) { /* TODO: implement*/ };
     71static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ };
    6972
    7073/** Get and cast pointer to the driver data
     
    7376 * @return cast pointer to driver_data
    7477 */
    75 static inline ohci_hc_t * fun_to_ohci_hc(ddf_fun_t *fun)
    76         { return (ohci_hc_t*)fun->driver_data; }
     78static inline hc_t * fun_to_hc(ddf_fun_t *fun)
     79        { return (hc_t*)fun->driver_data; }
    7780#endif
    7881/**
  • uspace/drv/ohci/iface.c

    r0e45e7f r48fe0c9  
    4343
    4444#include "iface.h"
     45#include "hc.h"
    4546
    4647#define UNSUPPORTED(methodname) \
     
    5960static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)
    6061{
    61         UNSUPPORTED("reserve_default_address");
    62 
    63         return ENOTSUP;
    64 }
    65 
     62  assert(fun);
     63  hc_t *hc = fun_to_hc(fun);
     64  assert(hc);
     65  usb_log_debug("Default address request with speed %d.\n", speed);
     66  device_keeper_reserve_default(&hc->manager, speed);
     67  return EOK;
     68}
     69/*----------------------------------------------------------------------------*/
    6670/** Release default address.
    6771 *
     
    7175static int release_default_address(ddf_fun_t *fun)
    7276{
    73         UNSUPPORTED("release_default_address");
    74 
    75         return ENOTSUP;
    76 }
    77 
     77  assert(fun);
     78  hc_t *hc = fun_to_hc(fun);
     79  assert(hc);
     80  usb_log_debug("Default address release.\n");
     81  device_keeper_release_default(&hc->manager);
     82  return EOK;
     83}
     84/*----------------------------------------------------------------------------*/
    7885/** Found free USB address.
    7986 *
     
    8693    usb_address_t *address)
    8794{
    88         UNSUPPORTED("request_address");
    89 
    90         return ENOTSUP;
    91 }
    92 
     95  assert(fun);
     96  hc_t *hc = fun_to_hc(fun);
     97  assert(hc);
     98  assert(address);
     99
     100  usb_log_debug("Address request with speed %d.\n", speed);
     101  *address = device_keeper_request(&hc->manager, speed);
     102  usb_log_debug("Address request with result: %d.\n", *address);
     103  if (*address <= 0)
     104    return *address;
     105  return EOK;
     106}
     107/*----------------------------------------------------------------------------*/
    93108/** Bind USB address with device devman handle.
    94109 *
     
    101116    usb_address_t address, devman_handle_t handle)
    102117{
    103         UNSUPPORTED("bind_address");
    104 
    105         return ENOTSUP;
    106 }
    107 
     118  assert(fun);
     119  hc_t *hc = fun_to_hc(fun);
     120  assert(hc);
     121  usb_log_debug("Address bind %d-%d.\n", address, handle);
     122  device_keeper_bind(&hc->manager, address, handle);
     123  return EOK;
     124}
     125/*----------------------------------------------------------------------------*/
    108126/** Release previously requested address.
    109127 *
     
    114132static int release_address(ddf_fun_t *fun, usb_address_t address)
    115133{
    116         UNSUPPORTED("release_address");
    117 
    118         return ENOTSUP;
     134  assert(fun);
     135  hc_t *hc = fun_to_hc(fun);
     136  assert(hc);
     137  usb_log_debug("Address release %d.\n", address);
     138  device_keeper_release(&hc->manager, address);
     139  return EOK;
    119140}
    120141
     
    155176        return ENOTSUP;
    156177}
    157 
     178/*----------------------------------------------------------------------------*/
    158179/** Schedule interrupt out transfer.
    159180 *
     
    177198    usbhc_iface_transfer_out_callback_t callback, void *arg)
    178199{
    179         UNSUPPORTED("interrupt_out");
    180 
    181         return ENOTSUP;
    182 }
    183 
     200  hc_t *hc = fun_to_hc(fun);
     201  assert(hc);
     202  usb_speed_t speed = device_keeper_speed(&hc->manager, target.address);
     203
     204  usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
     205      target.address, target.endpoint, size, max_packet_size);
     206
     207  batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
     208      max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
     209      &hc->manager);
     210  if (!batch)
     211    return ENOMEM;
     212  batch_interrupt_out(batch);
     213  const int ret = hc_schedule(hc, batch);
     214  if (ret != EOK) {
     215    batch_dispose(batch);
     216    return ret;
     217  }
     218  return EOK;
     219}
     220/*----------------------------------------------------------------------------*/
    184221/** Schedule interrupt in transfer.
    185222 *
     
    203240    usbhc_iface_transfer_in_callback_t callback, void *arg)
    204241{
    205         UNSUPPORTED("interrupt_in");
    206 
    207         return ENOTSUP;
    208 }
    209 
     242  assert(fun);
     243  hc_t *hc = fun_to_hc(fun);
     244  assert(hc);
     245  usb_speed_t speed = device_keeper_speed(&hc->manager, target.address);
     246  usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
     247      target.address, target.endpoint, size, max_packet_size);
     248
     249  batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
     250      max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
     251      &hc->manager);
     252  if (!batch)
     253    return ENOMEM;
     254  batch_interrupt_in(batch);
     255  const int ret = hc_schedule(hc, batch);
     256  if (ret != EOK) {
     257    batch_dispose(batch);
     258    return ret;
     259  }
     260  return EOK;
     261}
     262/*----------------------------------------------------------------------------*/
    210263/** Schedule bulk out transfer.
    211264 *
     
    229282    usbhc_iface_transfer_out_callback_t callback, void *arg)
    230283{
    231         UNSUPPORTED("bulk_out");
    232 
    233         return ENOTSUP;
    234 }
    235 
     284  assert(fun);
     285  hc_t *hc = fun_to_hc(fun);
     286  assert(hc);
     287  usb_speed_t speed = device_keeper_speed(&hc->manager, target.address);
     288
     289  usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
     290      target.address, target.endpoint, size, max_packet_size);
     291
     292  batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
     293      max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
     294      &hc->manager);
     295  if (!batch)
     296    return ENOMEM;
     297  batch_bulk_out(batch);
     298  const int ret = hc_schedule(hc, batch);
     299  if (ret != EOK) {
     300    batch_dispose(batch);
     301    return ret;
     302  }
     303  return EOK;
     304
     305}
     306/*----------------------------------------------------------------------------*/
    236307/** Schedule bulk in transfer.
    237308 *
     
    255326    usbhc_iface_transfer_in_callback_t callback, void *arg)
    256327{
    257         UNSUPPORTED("bulk_in");
    258 
    259         return ENOTSUP;
    260 }
    261 
     328  assert(fun);
     329  hc_t *hc = fun_to_hc(fun);
     330  assert(hc);
     331  usb_speed_t speed = device_keeper_speed(&hc->manager, target.address);
     332  usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
     333      target.address, target.endpoint, size, max_packet_size);
     334
     335  batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
     336      max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
     337      &hc->manager);
     338  if (!batch)
     339    return ENOMEM;
     340  batch_bulk_in(batch);
     341  const int ret = hc_schedule(hc, batch);
     342  if (ret != EOK) {
     343    batch_dispose(batch);
     344    return ret;
     345  }
     346  return EOK;
     347}
     348/*----------------------------------------------------------------------------*/
    262349/** Schedule control write transfer.
    263350 *
     
    282369static int control_write(ddf_fun_t *fun, usb_target_t target,
    283370    size_t max_packet_size,
    284     void *setup_packet, size_t setup_packet_size,
    285     void *data_buffer, size_t data_buffer_size,
     371    void *setup_data, size_t setup_size,
     372    void *data, size_t size,
    286373    usbhc_iface_transfer_out_callback_t callback, void *arg)
    287374{
    288         UNSUPPORTED("control_write");
    289 
    290         return ENOTSUP;
    291 }
    292 
     375  assert(fun);
     376  hc_t *hc = fun_to_hc(fun);
     377  assert(hc);
     378  usb_speed_t speed = device_keeper_speed(&hc->manager, target.address);
     379  usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
     380      speed, target.address, target.endpoint, size, max_packet_size);
     381
     382  if (setup_size != 8)
     383    return EINVAL;
     384
     385  batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
     386      max_packet_size, speed, data, size, setup_data, setup_size,
     387      NULL, callback, arg, &hc->manager);
     388  if (!batch)
     389    return ENOMEM;
     390  device_keeper_reset_if_need(&hc->manager, target, setup_data);
     391  batch_control_write(batch);
     392  const int ret = hc_schedule(hc, batch);
     393  if (ret != EOK) {
     394    batch_dispose(batch);
     395    return ret;
     396  }
     397  return EOK;
     398}
     399/*----------------------------------------------------------------------------*/
    293400/** Schedule control read transfer.
    294401 *
     
    313420static int control_read(ddf_fun_t *fun, usb_target_t target,
    314421    size_t max_packet_size,
    315     void *setup_packet, size_t setup_packet_size,
    316     void *data_buffer, size_t data_buffer_size,
     422    void *setup_data, size_t setup_size,
     423    void *data, size_t size,
    317424    usbhc_iface_transfer_in_callback_t callback, void *arg)
    318425{
    319         UNSUPPORTED("control_read");
    320 
    321         return ENOTSUP;
    322 }
    323 
     426  assert(fun);
     427  hc_t *hc = fun_to_hc(fun);
     428  assert(hc);
     429  usb_speed_t speed = device_keeper_speed(&hc->manager, target.address);
     430
     431  usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
     432      speed, target.address, target.endpoint, size, max_packet_size);
     433  batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
     434      max_packet_size, speed, data, size, setup_data, setup_size, callback,
     435      NULL, arg, &hc->manager);
     436  if (!batch)
     437    return ENOMEM;
     438  batch_control_read(batch);
     439  const int ret = hc_schedule(hc, batch);
     440  if (ret != EOK) {
     441    batch_dispose(batch);
     442    return ret;
     443  }
     444  return EOK;
     445}
     446/*----------------------------------------------------------------------------*/
    324447/** Host controller interface implementation for OHCI. */
    325 usbhc_iface_t ohci_hc_iface = {
     448usbhc_iface_t hc_iface = {
    326449        .reserve_default_address = reserve_default_address,
    327450        .release_default_address = release_default_address,
  • uspace/drv/ohci/iface.h

    r0e45e7f r48fe0c9  
    4040#define NAME "ohci"
    4141
    42 extern usbhc_iface_t ohci_hc_iface;
     42extern usbhc_iface_t hc_iface;
    4343
    4444#endif
  • uspace/drv/ohci/main.c

    r0e45e7f r48fe0c9  
    4545#include "pci.h"
    4646#include "iface.h"
    47 #include "ohci_hc.h"
     47#include "hc.h"
    4848
    4949static int ohci_add_device(ddf_dev_t *device);
     50static int get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
     51{
     52        assert(handle);
     53  assert(fun != NULL);
     54
     55  *handle = fun->handle;
     56  return EOK;
     57}
     58/*----------------------------------------------------------------------------*/
     59static int get_address(
     60    ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
     61{
     62        assert(fun);
     63        device_keeper_t *manager = &fun_to_hc(fun)->manager;
     64  usb_address_t addr = device_keeper_find(manager, handle);
     65  if (addr < 0) {
     66    return addr;
     67  }
     68
     69  if (address != NULL) {
     70    *address = addr;
     71  }
     72
     73  return EOK;
     74}
    5075/*----------------------------------------------------------------------------*/
    5176/** IRQ handling callback, identifies device
     
    5883{
    5984        assert(dev);
    60         ohci_hc_t *hc = (ohci_hc_t*)dev->driver_data;
     85        hc_t *hc = (hc_t*)dev->driver_data;
    6186        assert(hc);
    62         ohci_hc_interrupt(hc, 0);
     87        hc_interrupt(hc, 0);
    6388}
    6489/*----------------------------------------------------------------------------*/
     
    7196        .driver_ops = &ohci_driver_ops
    7297};
     98/*----------------------------------------------------------------------------*/
     99static usb_iface_t hc_usb_iface = {
     100        .get_address = get_address,
     101        .get_hc_handle = get_hc_handle,
     102};
     103/*----------------------------------------------------------------------------*/
    73104static ddf_dev_ops_t hc_ops = {
    74         .interfaces[USBHC_DEV_IFACE] = &ohci_hc_iface,
    75 };
    76 
     105        .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
     106        .interfaces[USBHC_DEV_IFACE] = &hc_iface,
     107};
    77108/*----------------------------------------------------------------------------*/
    78109/** Initializes a new ddf driver instance of OHCI hcd.
     
    105136            "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));
    106137
    107         ohci_hc_t *hcd = malloc(sizeof(ohci_hc_t));
     138        hc_t *hcd = malloc(sizeof(hc_t));
    108139        if (hcd == NULL) {
    109140                usb_log_error("Failed to allocate OHCI driver.\n");
     
    129160        }
    130161
    131         ret = ohci_hc_init(hcd, hc_fun, mem_reg_base, mem_reg_size, interrupts);
     162        ret = hc_init(hcd, hc_fun, device, mem_reg_base, mem_reg_size, interrupts);
    132163        if (ret != EOK) {
    133164                usb_log_error("Failed to initialize OHCI driver.\n");
     
    148179        hc_fun->driver_data = hcd;
    149180
    150         /* TODO: register interrupt handler */
     181        fid_t later = fibril_create((int(*)(void*))hc_register_hub, hcd);
     182        fibril_add_ready(later);
    151183
    152184        usb_log_info("Controlling new OHCI device `%s' (handle %llu).\n",
  • uspace/drv/ohci/root_hub.c

    r0e45e7f r48fe0c9  
    3838#include <usb/debug.h>
    3939
    40 #include "ohci_rh.h"
     40#include "root_hub.h"
    4141
    4242/** Root hub initialization
    4343 * @return Error code.
    4444 */
    45 int ohci_rh_init(ohci_rh_t *instance, ohci_regs_t *regs)
     45int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs)
    4646{
    4747        assert(instance);
    48         instance->address = 0;
     48        instance->address = -1;
    4949        instance->registers = regs;
     50        instance->device = dev;
    5051
    5152        usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff);
     
    5556}
    5657/*----------------------------------------------------------------------------*/
    57 void ohci_rh_request(ohci_rh_t *instance, batch_t *request)
     58int rh_request(rh_t *instance, batch_t *request)
    5859{
     60        assert(instance);
     61        assert(request);
    5962        /* TODO: implement */
     63        if (request->setup_buffer) {
     64                usb_log_info("Root hub got SETUP packet: %s.\n",
     65                    usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
     66        }
     67        usb_log_error("Root hub request processing not implemented.\n");
     68        batch_finish(request, ENOTSUP);
     69        return EOK;
    6070}
    6171/*----------------------------------------------------------------------------*/
    62 void ohci_rh_interrupt(ohci_rh_t *instance)
     72void rh_interrupt(rh_t *instance)
    6373{
    64         usb_log_info("Interrupt!!.\n");
     74        usb_log_error("Root hub interrupt not implemented.\n");
    6575        /* TODO: implement */
    6676}
  • uspace/drv/ohci/root_hub.h

    r0e45e7f r48fe0c9  
    3333 * @brief OHCI driver
    3434 */
    35 #ifndef DRV_OHCI_OHCI_RH_H
    36 #define DRV_OHCI_OHCI_RH_H
     35#ifndef DRV_OHCI_ROOT_HUB_H
     36#define DRV_OHCI_ROOT_HUB_H
    3737
    3838#include <usb/usb.h>
     
    4141#include "batch.h"
    4242
    43 typedef struct ohci_rh {
     43typedef struct rh {
    4444        ohci_regs_t *registers;
    4545        usb_address_t address;
    46 } ohci_rh_t;
     46        ddf_dev_t *device;
     47} rh_t;
    4748
    48 int ohci_rh_init(ohci_rh_t *instance, ohci_regs_t *regs);
     49int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs);
    4950
    50 void ohci_rh_request(ohci_rh_t *instance, batch_t *request);
     51int rh_request(rh_t *instance, batch_t *request);
    5152
    52 void ohci_rh_interrupt(ohci_rh_t *instance);
     53void rh_interrupt(rh_t *instance);
    5354#endif
    5455/**
  • uspace/drv/uhci-hcd/batch.c

    r0e45e7f r48fe0c9  
    183183
    184184                        device_keeper_set_toggle(data->manager,
    185                             instance->target, td_toggle(&data->tds[i]));
     185                            instance->target, instance->direction,
     186                            td_toggle(&data->tds[i]));
    186187                        if (i > 0)
    187188                                goto substract_ret;
     
    238239{
    239240        assert(instance);
     241        instance->direction = USB_DIRECTION_IN;
    240242        batch_data(instance, USB_PID_IN);
    241243        instance->next_step = batch_call_in_and_dispose;
     
    252254{
    253255        assert(instance);
     256        instance->direction = USB_DIRECTION_OUT;
    254257        /* We are data out, we are supposed to provide data */
    255258        memcpy(instance->transport_buffer, instance->buffer,
     
    270273        assert(instance);
    271274        batch_data(instance, USB_PID_IN);
     275        instance->direction = USB_DIRECTION_IN;
    272276        instance->next_step = batch_call_in_and_dispose;
    273277        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
     
    283287{
    284288        assert(instance);
     289        instance->direction = USB_DIRECTION_OUT;
    285290        /* We are data out, we are supposed to provide data */
    286291        memcpy(instance->transport_buffer, instance->buffer,
     
    306311
    307312        const bool low_speed = instance->speed == USB_SPEED_LOW;
    308         int toggle = device_keeper_get_toggle(data->manager, instance->target);
     313        int toggle = device_keeper_get_toggle(
     314            data->manager, instance->target, instance->direction);
    309315        assert(toggle == 0 || toggle == 1);
    310316
     
    337343        }
    338344        td_set_ioc(&data->tds[packet - 1]);
    339         device_keeper_set_toggle(data->manager, instance->target, toggle);
     345        device_keeper_set_toggle(data->manager, instance->target,
     346            instance->direction, toggle);
    340347}
    341348/*----------------------------------------------------------------------------*/
  • uspace/lib/usb/include/usb/host/batch.h

    r0e45e7f r48fe0c9  
    4646        usb_transfer_type_t transfer_type;
    4747        usb_speed_t speed;
     48        usb_direction_t direction;
    4849        usbhc_iface_transfer_in_callback_t callback_in;
    4950        usbhc_iface_transfer_out_callback_t callback_out;
  • uspace/lib/usb/include/usb/host/device_keeper.h

    r0e45e7f r48fe0c9  
    4444        usb_speed_t speed;
    4545        bool occupied;
    46         uint16_t toggle_status;
     46        uint16_t toggle_status[2];
    4747        devman_handle_t handle;
    4848};
     
    6363
    6464void device_keeper_reset_if_need(
    65     device_keeper_t *instance, usb_target_t target, const unsigned char *setup_data);
     65    device_keeper_t *instance, usb_target_t target,
     66    const unsigned char *setup_data);
    6667
    67 int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target);
     68int device_keeper_get_toggle(
     69    device_keeper_t *instance, usb_target_t target, usb_direction_t direction);
    6870
    69 int device_keeper_set_toggle(
    70     device_keeper_t *instance, usb_target_t target, bool toggle);
     71int device_keeper_set_toggle(device_keeper_t *instance,
     72    usb_target_t target, usb_direction_t direction, bool toggle);
    7173
    7274usb_address_t device_keeper_request(
  • uspace/lib/usb/src/host/batch.c

    r0e45e7f r48fe0c9  
    6262        instance->transfer_type = transfer_type;
    6363        instance->speed = speed;
     64        instance->direction = USB_DIRECTION_BOTH;
    6465        instance->callback_in = func_in;
    6566        instance->callback_out = func_out;
  • uspace/lib/usb/src/host/device_keeper.c

    r0e45e7f r48fe0c9  
    5555                instance->devices[i].occupied = false;
    5656                instance->devices[i].handle = 0;
    57                 instance->devices[i].toggle_status = 0;
     57                instance->devices[i].toggle_status[0] = 0;
     58                instance->devices[i].toggle_status[1] = 0;
    5859        }
    5960}
     
    118119                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
    119120                        /* endpoint number is < 16, thus first byte is enough */
    120                         instance->devices[target.address].toggle_status &=
     121                        instance->devices[target.address].toggle_status[0] &=
     122                            ~(1 << data[4]);
     123                        instance->devices[target.address].toggle_status[1] &=
    121124                            ~(1 << data[4]);
    122125                }
     
    127130                /* target must be device */
    128131                if ((data[0] & 0xf) == 0) {
    129                         instance->devices[target.address].toggle_status = 0;
     132                        instance->devices[target.address].toggle_status[0] = 0;
     133                        instance->devices[target.address].toggle_status[1] = 0;
    130134                }
    131135        break;
     
    140144 * @return Error code
    141145 */
    142 int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target)
    143 {
    144         assert(instance);
     146int device_keeper_get_toggle(
     147    device_keeper_t *instance, usb_target_t target, usb_direction_t direction)
     148{
     149        assert(instance);
     150        /* only control pipes are bi-directional and those do not need toggle */
     151        if (direction == USB_DIRECTION_BOTH)
     152                return ENOENT;
    145153        int ret;
    146154        fibril_mutex_lock(&instance->guard);
     
    151159                ret = EINVAL;
    152160        } else {
    153                 ret = (instance->devices[target.address].toggle_status
     161                ret = (instance->devices[target.address].toggle_status[direction]
    154162                        >> target.endpoint) & 1;
    155163        }
     
    165173 * @return Error code.
    166174 */
    167 int device_keeper_set_toggle(
    168     device_keeper_t *instance, usb_target_t target, bool toggle)
    169 {
    170         assert(instance);
     175int device_keeper_set_toggle(device_keeper_t *instance,
     176    usb_target_t target, usb_direction_t direction, bool toggle)
     177{
     178        assert(instance);
     179        /* only control pipes are bi-directional and those do not need toggle */
     180        if (direction == USB_DIRECTION_BOTH)
     181                return ENOENT;
    171182        int ret;
    172183        fibril_mutex_lock(&instance->guard);
     
    178189        } else {
    179190                if (toggle) {
    180                         instance->devices[target.address].toggle_status |= (1 << target.endpoint);
     191                        instance->devices[target.address].toggle_status[direction]
     192                            |= (1 << target.endpoint);
    181193                } else {
    182                         instance->devices[target.address].toggle_status &= ~(1 << target.endpoint);
     194                        instance->devices[target.address].toggle_status[direction]
     195                            &= ~(1 << target.endpoint);
    183196                }
    184197                ret = EOK;
     
    215228        instance->devices[new_address].occupied = true;
    216229        instance->devices[new_address].speed = speed;
    217         instance->devices[new_address].toggle_status = 0;
     230        instance->devices[new_address].toggle_status[0] = 0;
     231        instance->devices[new_address].toggle_status[1] = 0;
    218232        instance->last_address = new_address;
    219233        fibril_mutex_unlock(&instance->guard);
Note: See TracChangeset for help on using the changeset viewer.