Changeset 18e35a7 in mainline for uspace/drv/uhci/root_hub/root_hub.c


Ignore:
Timestamp:
2010-12-18T15:40:36Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f088c00
Parents:
3515533
Message:

root hub detection of devices works

TODO: assign correct match ids before reporting
TODO: communicate new address to the device

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci/root_hub/root_hub.c

    r3515533 r18e35a7  
    44#include <stdint.h>
    55#include <stdio.h>
     6
    67#include <usb/debug.h>
    78
     
    1112#include "root_hub.h"
    1213
    13 static int uhci_root_hub_check_ports( void * device );
     14#define ROOT_HUB_WAIT_USEC 10000000 /* 10 second */
     15
     16static int uhci_root_hub_check_ports( void *hc );
     17static int uhci_root_hub_new_device( device_t *hc, unsigned port );
     18static usb_address_t uhci_root_hub_assign_address( device_t *hc );
     19static int uhci_root_hub_report_new_device(
     20  device_t *hc, usb_address_t address, int port, devman_handle_t *handle );
     21
    1422/*----------------------------------------------------------------------------*/
    15 int uhci_root_hub_init( uhci_root_hub_t *hub, device_t *device, void *addr )
     23int uhci_root_hub_init( uhci_root_hub_t *hub, device_t *hc, void *addr )
    1624{
    1725        assert( hub );
    18         hub->checker = fibril_create( uhci_root_hub_check_ports, device );
     26
     27        /* allow access to root hub registers */
     28        port_regs_t *regs;
     29        const int ret = pio_enable( addr, sizeof(port_regs_t), (void**)&regs);
     30        if (ret < 0) {
     31                printf( NAME": Failed to gain access to port registers at %p\n", regs );
     32                return ret;
     33        }
     34        hub->registers = regs;
     35
     36        /* add fibril for periodic checks */
     37        hub->checker = fibril_create( uhci_root_hub_check_ports, hc );
    1938        if (hub->checker == 0) {
    20                 printf( NAME": Failed to launch root hub fibril." );
     39                printf( NAME": failed to launch root hub fibril." );
    2140                return ENOMEM;
    2241        }
    2342        fibril_add_ready( hub->checker );
    24         port_regs_t *regs;
    25         const int ret = pio_enable( addr, sizeof(port_regs_t), (void**)&regs);
    26         if (ret < 0) {
    27                 printf(NAME": Failed to gain access to port registers at %p\n", regs);
    28                 return ret;
    29         }
    30         hub->registers = regs;
    3143
    3244        return EOK;
     
    3648{
    3749        assert( instance );
     50        // TODO:
    3851        //destroy fibril here
     52        //disable access to registers
    3953        return EOK;
    4054}
     
    4458        assert( device );
    4559        uhci_t *uhci_instance = ((device_t*)device)->driver_data;
     60
    4661        while (1) {
    4762                int i = 0;
     
    5166
    5267                        usb_dprintf( NAME, 1, "Port(%d) status address %p:\n", i, address );
    53                         uint16_t value = pio_read_16( address );
    54                         usb_dprintf( NAME, 1, "Port(%d) status 0x%x:\n", i, value );
    55                         print_port_status( (port_status_t*)&value );
     68
     69                        /* read register value */
     70                        port_status_t port_status;
     71                        port_status.raw_value = pio_read_16( address );
     72
     73                        /* debug print */
     74                        usb_dprintf( NAME, 1, "Port(%d) status 0x%x:\n", i, port_status.raw_value );
     75                        print_port_status( &port_status );
     76
     77                        if (port_status.status.connect_change) {
     78                                if (port_status.status.connected) {
     79                                        /* assign address and report new device */
     80                                        uhci_root_hub_new_device( (device_t*)device, i );
     81                                } else {
     82                                        /* TODO */
     83                                        /* remove device here */
     84                                }
     85                        }
    5686                }
    57                 async_usleep( 1000000 );
     87                async_usleep( ROOT_HUB_WAIT_USEC );
    5888        }
    5989        return ENOTSUP;
    6090}
     91/*----------------------------------------------------------------------------*/
     92int uhci_root_hub_new_device( device_t *hc, unsigned port )
     93{
     94        assert( hc );
     95        assert( hc->driver_data );
     96        assert( port < UHCI_ROOT_HUB_PORT_COUNT );
     97
     98        usb_dprintf( NAME, 2, "Adding new device on port %d.\n", port );
     99
     100        uhci_t *uhci_instance = (uhci_t*)hc->driver_data;
     101
     102        /* enable port */
     103        {
     104                volatile uint16_t * address =
     105                        &(uhci_instance->root_hub.registers->portsc[port]);
     106
     107                /* read register value */
     108                port_status_t port_status;
     109                port_status.raw_value = pio_read_16( address );
     110
     111                /* enable port: register write */
     112                port_status.status.enabled = 1;
     113                pio_write_16( address, port_status.raw_value );
     114
     115                usb_dprintf( NAME, 2, "Enabled port %d.\n", port );
     116        }
     117
     118        /* assign address to device */
     119        usb_address_t address =
     120         uhci_root_hub_assign_address( hc );
     121        if (address <= 0) {
     122                printf( NAME": Failed to assign address to the device" );
     123                return ENOMEM;
     124        }
     125
     126        /* report to devman */
     127        devman_handle_t child = 0;
     128        uhci_root_hub_report_new_device( hc, address, port, &child );
     129
     130        /* bind address */
     131        usb_address_keeping_devman_bind( &uhci_instance->address_manager,
     132          address, child );
     133
     134
     135        return EOK;
     136}
     137/*----------------------------------------------------------------------------*/
     138static usb_address_t uhci_root_hub_assign_address( device_t *hc )
     139{
     140        assert( hc );
     141        assert( hc->driver_data );
     142
     143        uhci_t *uhci_instance = (uhci_t*)hc->driver_data;
     144        /* get new address */
     145        const usb_address_t usb_address = usb_address_keeping_request(
     146          &uhci_instance->address_manager );
     147
     148        /* get default address */
     149        usb_address_keeping_reserve_default( &uhci_instance->address_manager );
     150
     151        /* assign new address */
     152        /* TODO send new address*/
     153        usb_dprintf( NAME, 3, "Assigned address 0x%x.\n", usb_address );
     154
     155        /* release default address */
     156        usb_address_keeping_release_default( &uhci_instance->address_manager );
     157
     158        return usb_address;
     159}
     160/*----------------------------------------------------------------------------*/
     161static int uhci_root_hub_report_new_device(
     162  device_t *hc, usb_address_t address, int hub_port, devman_handle_t *handle )
     163{
     164        assert( hc );
     165        assert( address > 0 );
     166        assert( address <= USB11_ADDRESS_MAX );
     167
     168        int ret;
     169        device_t *child = create_device();
     170        if (child == NULL)
     171                { return ENOMEM; }
     172        char *name;
     173
     174        ret = asprintf( &name, "usbdevice on hc%p/%d/0x%x", hc, hub_port, address );
     175        if (ret < 0) {
     176                usb_dprintf( NAME, 4, "Failed to create device name.\n" );
     177                delete_device( child );
     178                return ret;
     179        }
     180        child->name = name;
     181
     182        /* TODO create match ids */
     183
     184        ret = child_device_register( child, hc );
     185        if (ret < 0) {
     186                usb_dprintf( NAME, 4, "Failed to create device name.\n" );
     187                delete_device( child );
     188                return ret;
     189        }
     190
     191        if (handle != NULL)
     192                { *handle = child->handle; }
     193
     194        return EOK;
     195}
Note: See TracChangeset for help on using the changeset viewer.