Changeset 7943c43 in mainline for uspace/srv


Ignore:
Timestamp:
2012-01-16T22:45:38Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
32817cc, 3fe58d3c
Parents:
9117ef9b (diff), 3ea725e (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 mainline changes.

Location:
uspace/srv
Files:
6 added
3 deleted
42 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/ata_bd/ata_bd.c

    r9117ef9b r7943c43  
    245245        void *vaddr;
    246246        int rc;
    247 
    248         rc = loc_server_register(NAME, ata_bd_connection);
     247       
     248        async_set_client_connection(ata_bd_connection);
     249        rc = loc_server_register(NAME);
    249250        if (rc < 0) {
    250251                printf(NAME ": Unable to register driver.\n");
     
    309310        }
    310311
    311         fs_va = as_get_mappable_page(comm_size);
    312         if (fs_va == NULL) {
     312        (void) async_share_out_finalize(callid, &fs_va);
     313        if (fs_va == (void *) -1) {
    313314                async_answer_0(callid, EHANGUP);
    314315                return;
    315316        }
    316 
    317         (void) async_share_out_finalize(callid, fs_va);
    318317
    319318        while (true) {
  • uspace/srv/bd/file_bd/file_bd.c

    r9117ef9b r7943c43  
    141141        int rc;
    142142        long img_size;
    143 
    144         rc = loc_server_register(NAME, file_bd_connection);
     143       
     144        async_set_client_connection(file_bd_connection);
     145        rc = loc_server_register(NAME);
    145146        if (rc < 0) {
    146147                printf(NAME ": Unable to register driver.\n");
     
    190191        }
    191192
    192         fs_va = as_get_mappable_page(comm_size);
    193         if (fs_va == NULL) {
     193        (void) async_share_out_finalize(callid, &fs_va);
     194        if (fs_va == (void *) -1) {
    194195                async_answer_0(callid, EHANGUP);
    195196                return;
    196197        }
    197 
    198         (void) async_share_out_finalize(callid, fs_va);
    199198
    200199        while (true) {
  • uspace/srv/bd/gxe_bd/gxe_bd.c

    r9117ef9b r7943c43  
    125125        int rc, i;
    126126        char name[16];
    127 
    128         rc = loc_server_register(NAME, gxe_bd_connection);
     127       
     128        async_set_client_connection(gxe_bd_connection);
     129        rc = loc_server_register(NAME);
    129130        if (rc < 0) {
    130131                printf(NAME ": Unable to register driver.\n");
     
    193194        }
    194195
    195         fs_va = as_get_mappable_page(comm_size);
    196         if (fs_va == NULL) {
     196        (void) async_share_out_finalize(callid, &fs_va);
     197        if (fs_va == (void *) -1) {
    197198                async_answer_0(callid, EHANGUP);
    198199                return;
    199200        }
    200 
    201         (void) async_share_out_finalize(callid, fs_va);
    202201
    203202        while (true) {
  • uspace/srv/bd/part/guid_part/guid_part.c

    r9117ef9b r7943c43  
    164164
    165165        /* Register server with location service. */
    166         rc = loc_server_register(NAME, gpt_connection);
     166        async_set_client_connection(gpt_connection);
     167        rc = loc_server_register(NAME);
    167168        if (rc != EOK) {
    168169                printf(NAME ": Unable to register server.\n");
     
    348349        }
    349350
    350         fs_va = as_get_mappable_page(comm_size);
    351         if (fs_va == NULL) {
     351        (void) async_share_out_finalize(callid, &fs_va);
     352        if (fs_va == (void *) -1) {
    352353                async_answer_0(callid, EHANGUP);
    353354                return;
    354355        }
    355 
    356         (void) async_share_out_finalize(callid, fs_va);
    357356
    358357        while (true) {
  • uspace/srv/bd/part/mbr_part/mbr_part.c

    r9117ef9b r7943c43  
    214214
    215215        /* Register server with location service. */
    216         rc = loc_server_register(NAME, mbr_connection);
     216        async_set_client_connection(mbr_connection);
     217        rc = loc_server_register(NAME);
    217218        if (rc != EOK) {
    218219                printf(NAME ": Unable to register server.\n");
     
    425426        }
    426427
    427         fs_va = as_get_mappable_page(comm_size);
    428         if (fs_va == NULL) {
     428        (void) async_share_out_finalize(callid, &fs_va);
     429        if (fs_va == (void *) -1) {
    429430                async_answer_0(callid, EHANGUP);
    430431                return;
    431432        }
    432 
    433         (void) async_share_out_finalize(callid, fs_va);
    434433
    435434        while (1) {
  • uspace/srv/bd/rd/rd.c

    r9117ef9b r7943c43  
    105105        unsigned int flags;
    106106        if (async_share_out_receive(&callid, &comm_size, &flags)) {
    107                 fs_va = as_get_mappable_page(comm_size);
    108                 if (fs_va) {
    109                         (void) async_share_out_finalize(callid, fs_va);
    110                 } else {
     107                (void) async_share_out_finalize(callid, &fs_va);
     108                if (fs_va == (void *) -1) {
    111109                        async_answer_0(callid, EHANGUP);
    112110                        return;
     
    224222       
    225223        rd_size = ALIGN_UP(size, block_size);
    226         rd_addr = as_get_mappable_page(rd_size);
    227        
    228224        unsigned int flags =
    229225            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
    230         ret = physmem_map((void *) addr_phys, rd_addr,
    231             ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
    232         if (ret < 0) {
     226       
     227        ret = physmem_map((void *) addr_phys,
     228            ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags, &rd_addr);
     229        if (ret != EOK) {
    233230                printf("%s: Error mapping RAM disk\n", NAME);
    234231                return false;
     
    238235            (void *) addr_phys, size);
    239236       
    240         ret = loc_server_register(NAME, rd_connection);
     237        async_set_client_connection(rd_connection);
     238        ret = loc_server_register(NAME);
    241239        if (ret < 0) {
    242240                printf("%s: Unable to register driver (%d)\n", NAME, ret);
  • uspace/srv/devman/main.c

    r9117ef9b r7943c43  
    13091309
    13101310        /*
    1311          * !!! devman_connection ... as the device manager is not a real loc
    1312          * driver (it uses a completely different ipc protocol than an ordinary
    1313          * loc driver) forwarding a connection from client to the devman by
    1314          * location service would not work.
     1311         * Caution: As the device manager is not a real loc
     1312         * driver (it uses a completely different IPC protocol
     1313         * than an ordinary loc driver), forwarding a connection
     1314         * from client to the devman by location service will
     1315         * not work.
    13151316         */
    1316         loc_server_register(NAME, devman_connection);
     1317        loc_server_register(NAME);
    13171318       
    13181319        return true;
     
    13251326        if (log_init(NAME, LVL_WARN) != EOK) {
    13261327                printf(NAME ": Error initializing logging subsystem.\n");
    1327                 return -1;
    1328         }
    1329 
    1330         if (!devman_init()) {
    1331                 log_msg(LVL_ERROR, "Error while initializing service.");
    13321328                return -1;
    13331329        }
     
    13381334        async_set_client_connection(devman_connection);
    13391335
     1336        if (!devman_init()) {
     1337                log_msg(LVL_ERROR, "Error while initializing service.");
     1338                return -1;
     1339        }
     1340
    13401341        /* Register device manager at naming service. */
    13411342        if (service_register(SERVICE_DEVMAN) != EOK) {
  • uspace/srv/hid/console/console.c

    r9117ef9b r7943c43  
    825825       
    826826        /* Register server */
    827         int rc = loc_server_register(NAME, client_connection);
     827        async_set_client_connection(client_connection);
     828        int rc = loc_server_register(NAME);
    828829        if (rc < 0) {
    829830                printf("%s: Unable to register server (%s)\n", NAME,
  • uspace/srv/hid/fb/fb.c

    r9117ef9b r7943c43  
    304304        }
    305305       
    306         frontbuf->data = as_get_mappable_page(frontbuf->size);
    307         int rc = async_answer_1(callid, EOK, (sysarg_t) frontbuf->data);
    308         if (rc != EOK) {
     306        int rc = async_share_out_finalize(callid, &frontbuf->data);
     307        if ((rc != EOK) || (frontbuf->data == (void *) -1)) {
    309308                free(frontbuf);
    310309                async_answer_0(iid, ENOMEM);
     
    348347        }
    349348       
    350         imagemap->data = as_get_mappable_page(imagemap->size);
    351         int rc = async_answer_1(callid, EOK, (sysarg_t) imagemap->data);
    352         if (rc != EOK) {
     349        int rc = async_share_out_finalize(callid, &imagemap->data);
     350        if ((rc != EOK) || (imagemap->data == (void *) -1)) {
    353351                free(imagemap);
    354352                async_answer_0(iid, ENOMEM);
     
    989987       
    990988        /* Register server */
    991         int rc = loc_server_register(NAME, client_connection);
     989        async_set_client_connection(client_connection);
     990        int rc = loc_server_register(NAME);
    992991        if (rc != EOK) {
    993992                printf("%s: Unable to register driver (%d)\n", NAME, rc);
  • uspace/srv/hid/fb/port/ega.c

    r9117ef9b r7943c43  
    280280       
    281281        ega.size = (width * height) << 1;
    282         ega.addr = as_get_mappable_page(ega.size);
    283         if (ega.addr == NULL)
    284                 return ENOMEM;
    285        
    286         rc = physmem_map((void *) paddr, ega.addr,
    287             ALIGN_UP(ega.size, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
     282       
     283        rc = physmem_map((void *) paddr,
     284            ALIGN_UP(ega.size, PAGE_SIZE) >> PAGE_WIDTH,
     285            AS_AREA_READ | AS_AREA_WRITE, (void *) &ega.addr);
    288286        if (rc != EOK)
    289287                return rc;
  • uspace/srv/hid/fb/port/kchar.c

    r9117ef9b r7943c43  
    8383                return rc;
    8484       
    85         kchar.addr = as_get_mappable_page(1);
    86         if (kchar.addr == NULL)
    87                 return ENOMEM;
    88        
    89         rc = physmem_map((void *) paddr, kchar.addr,
    90             ALIGN_UP(1, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
     85        rc = physmem_map((void *) paddr,
     86            ALIGN_UP(1, PAGE_SIZE) >> PAGE_WIDTH,
     87            AS_AREA_READ | AS_AREA_WRITE, (void *) &kchar.addr);
    9188        if (rc != EOK)
    9289                return rc;
  • uspace/srv/hid/fb/port/kfb.c

    r9117ef9b r7943c43  
    756756       
    757757        kfb.size = scanline * height;
    758         kfb.addr = as_get_mappable_page(kfb.size);
    759         if (kfb.addr == NULL) {
    760                 free(kfb.glyphs);
    761                 return ENOMEM;
    762         }
    763        
    764         rc = physmem_map((void *) paddr + offset, kfb.addr,
    765             ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
     758       
     759        rc = physmem_map((void *) paddr + offset,
     760            ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
     761            AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
    766762        if (rc != EOK) {
    767763                free(kfb.glyphs);
  • uspace/srv/hid/fb/port/niagara.c

    r9117ef9b r7943c43  
    103103                return rc;
    104104       
    105         niagara.fifo =
    106             (output_fifo_t *) as_get_mappable_page(sizeof(output_fifo_t));
    107         if (niagara.fifo == NULL)
    108                 return ENOMEM;
    109        
    110         rc = physmem_map((void *) paddr, (void *) niagara.fifo, 1,
    111             AS_AREA_READ | AS_AREA_WRITE);
     105        rc = physmem_map((void *) paddr, 1,
     106            AS_AREA_READ | AS_AREA_WRITE, (void *) &niagara.fifo);
    112107        if (rc != EOK)
    113108                return rc;
  • uspace/srv/hid/input/Makefile

    r9117ef9b r7943c43  
    4343        port/adb_mouse.c \
    4444        port/chardev.c \
    45         port/chardev_mouse.c \
    4645        port/gxemul.c \
    4746        port/msim.c \
     
    5251        proto/adb.c \
    5352        proto/mousedev.c \
    54         proto/ps2.c \
    5553        ctl/apple.c \
    5654        ctl/gxe_fb.c \
  • uspace/srv/hid/input/generic/input.c

    r9117ef9b r7943c43  
    172172
    173173/** Mouse pointer has moved. */
    174 void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy)
     174void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy, int dz)
    175175{
    176176        async_exch_t *exch = async_exchange_begin(client_sess);
    177         async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy);
     177        if (dx || dy)
     178                async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy);
     179        if (dz) {
     180                // TODO: Implement proper wheel support
     181                keycode_t code = dz > 0 ? KC_UP : KC_DOWN;
     182                for (int i = 0; i < 3; ++i) {
     183                        async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0);
     184                }
     185                async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0);
     186        }
    178187        async_exchange_end(exch);
    179188}
     
    397406         * them automatically.
    398407         */
    399 #if defined(UARCH_amd64)
    400         kbd_add_dev(&chardev_port, &pc_ctl);
    401 #endif
    402408#if defined(UARCH_arm32) && defined(MACHINE_gta02)
    403409        kbd_add_dev(&chardev_port, &stty_ctl);
     
    411417#if defined(UARCH_arm32) && defined(MACHINE_integratorcp)
    412418        kbd_add_dev(&pl050_port, &pc_ctl);
    413 #endif
    414 #if defined(UARCH_ia32)
    415         kbd_add_dev(&chardev_port, &pc_ctl);
    416 #endif
    417 #if defined(MACHINE_i460GX)
    418         kbd_add_dev(&chardev_port, &pc_ctl);
    419419#endif
    420420#if defined(MACHINE_ski)
     
    450450         * them automatically.
    451451         */
    452 #if defined(UARCH_amd64)
    453         mouse_add_dev(&chardev_mouse_port, &ps2_proto);
    454 #endif
    455 #if defined(UARCH_ia32)
    456         mouse_add_dev(&chardev_mouse_port, &ps2_proto);
    457 #endif
    458 #if defined(MACHINE_i460GX)
    459         mouse_add_dev(&chardev_mouse_port, &ps2_proto);
    460 #endif
    461452#if defined(UARCH_ppc32)
    462453        mouse_add_dev(&adb_mouse_port, &adb_proto);
     
    658649       
    659650        /* Register driver */
    660         int rc = loc_server_register(NAME, client_connection);
     651        async_set_client_connection(client_connection);
     652        int rc = loc_server_register(NAME);
    661653        if (rc < 0) {
    662654                printf("%s: Unable to register server (%d)\n", NAME, rc);
  • uspace/srv/hid/input/include/mouse.h

    r9117ef9b r7943c43  
    6262
    6363extern void mouse_push_data(mouse_dev_t *, sysarg_t);
    64 extern void mouse_push_event_move(mouse_dev_t *, int, int);
     64extern void mouse_push_event_move(mouse_dev_t *, int, int, int);
    6565extern void mouse_push_event_button(mouse_dev_t *, int, int);
    6666
  • uspace/srv/hid/input/include/mouse_proto.h

    r9117ef9b r7943c43  
    4848
    4949extern mouse_proto_ops_t adb_proto;
    50 extern mouse_proto_ops_t ps2_proto;
    5150extern mouse_proto_ops_t mousedev_proto;
    5251
  • uspace/srv/hid/input/port/chardev.c

    r9117ef9b r7943c43  
    6363/** List of devices to try connecting to. */
    6464static const char *in_devs[] = {
    65         "char/ps2a",
    6665        "char/s3c24ser"
    6766};
  • uspace/srv/hid/input/port/gxemul.c

    r9117ef9b r7943c43  
    9090        async_set_interrupt_received(gxemul_irq_handler);
    9191        gxemul_cmds[0].addr = (void *) addr;
    92         register_irq(inr, device_assign_devno(), 0, &gxemul_kbd);
     92        irq_register(inr, device_assign_devno(), 0, &gxemul_kbd);
    9393        return 0;
    9494}
  • uspace/srv/hid/input/port/msim.c

    r9117ef9b r7943c43  
    8989        msim_cmds[0].addr = (void *) vaddr;
    9090        async_set_interrupt_received(msim_irq_handler);
    91         register_irq(inr, device_assign_devno(), 0, &msim_kbd);
     91        irq_register(inr, device_assign_devno(), 0, &msim_kbd);
    9292       
    9393        return 0;
  • uspace/srv/hid/input/port/niagara.c

    r9117ef9b r7943c43  
    6363#define POLL_INTERVAL  10000
    6464
    65 /**
    66  * Virtual address mapped to the buffer shared with the kernel counterpart.
    67  */
    68 static uintptr_t input_buffer_addr;
    69 
    7065/*
    7166 * Kernel counterpart of the driver pushes characters (it has read) here.
     
    10297                return -1;
    10398       
    104         input_buffer_addr = (uintptr_t) as_get_mappable_page(PAGE_SIZE);
    105         int rc = physmem_map((void *) paddr, (void *) input_buffer_addr,
    106             1, AS_AREA_READ | AS_AREA_WRITE);
    107        
     99        int rc = physmem_map((void *) paddr, 1,
     100            AS_AREA_READ | AS_AREA_WRITE, (void *) &input_buffer);
    108101        if (rc != 0) {
    109102                printf("Niagara: uspace driver couldn't map physical memory: %d\n",
     
    111104                return rc;
    112105        }
    113        
    114         input_buffer = (input_buffer_t) input_buffer_addr;
    115106       
    116107        thread_id_t tid;
  • uspace/srv/hid/input/port/ns16550.c

    r9117ef9b r7943c43  
    135135       
    136136        async_set_interrupt_received(ns16550_irq_handler);
    137         register_irq(inr, device_assign_devno(), inr, &ns16550_kbd);
     137        irq_register(inr, device_assign_devno(), inr, &ns16550_kbd);
    138138       
    139139        return pio_enable((void *) ns16550_physical, 8, &vaddr);
  • uspace/srv/hid/input/port/pl050.c

    r9117ef9b r7943c43  
    117117       
    118118        async_set_interrupt_received(pl050_irq_handler);
    119         register_irq(inr, device_assign_devno(), 0, &pl050_kbd);
     119        irq_register(inr, device_assign_devno(), 0, &pl050_kbd);
    120120       
    121121        return 0;
  • uspace/srv/hid/input/proto/adb.c

    r9117ef9b r7943c43  
    8282       
    8383        if (dx != 0 || dy != 0)
    84                 mouse_push_event_move(mouse_dev, dx, dy);
     84                mouse_push_event_move(mouse_dev, dx, dy, 0);
    8585}
    8686
  • uspace/srv/hid/input/proto/mousedev.c

    r9117ef9b r7943c43  
    9191                switch (IPC_GET_IMETHOD(call)) {
    9292                case MOUSEEV_MOVE_EVENT:
    93                         mouse_push_event_move(mousedev->mouse_dev, IPC_GET_ARG1(call),
    94                             IPC_GET_ARG2(call));
     93                        mouse_push_event_move(mousedev->mouse_dev,
     94                            IPC_GET_ARG1(call), IPC_GET_ARG2(call),
     95                            IPC_GET_ARG3(call));
    9596                        retval = EOK;
    9697                        break;
    9798                case MOUSEEV_BUTTON_EVENT:
    98                         mouse_push_event_button(mousedev->mouse_dev, IPC_GET_ARG1(call),
    99                             IPC_GET_ARG2(call));
     99                        mouse_push_event_button(mousedev->mouse_dev,
     100                            IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    100101                        retval = EOK;
    101102                        break;
  • uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c

    r9117ef9b r7943c43  
    8585
    8686        printf(NAME ": S3C24xx touchscreen driver\n");
    87 
    88         rc = loc_server_register(NAME, s3c24xx_ts_connection);
     87       
     88        async_set_client_connection(s3c24xx_ts_connection);
     89        rc = loc_server_register(NAME);
    8990        if (rc < 0) {
    9091                printf(NAME ": Unable to register driver.\n");
     
    139140
    140141        async_set_interrupt_received(s3c24xx_ts_irq_handler);
    141         register_irq(inr, device_assign_devno(), 0, &ts_irq_code);
     142        irq_register(inr, device_assign_devno(), 0, &ts_irq_code);
    142143
    143144        s3c24xx_ts_wait_for_int_mode(ts, updn_down);
  • uspace/srv/hw/bus/cuda_adb/cuda_adb.c

    r9117ef9b r7943c43  
    154154        }
    155155
    156         rc = loc_server_register(NAME, cuda_connection);
     156        async_set_client_connection(cuda_connection);
     157        rc = loc_server_register(NAME);
    157158        if (rc < 0) {
    158159                printf(NAME ": Unable to register server.\n");
     
    275276        cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_kernel)->ifr;
    276277        async_set_interrupt_received(cuda_irq_handler);
    277         register_irq(10, device_assign_devno(), 0, &cuda_irq_code);
     278        irq_register(10, device_assign_devno(), 0, &cuda_irq_code);
    278279
    279280        /* Enable SR interrupt. */
  • uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c

    r9117ef9b r7943c43  
    7979        printf(NAME ": S3C24xx on-chip UART driver\n");
    8080
    81         rc = loc_server_register(NAME, s3c24xx_uart_connection);
     81        async_set_client_connection(s3c24xx_uart_connection);
     82        rc = loc_server_register(NAME);
    8283        if (rc < 0) {
    8384                printf(NAME ": Unable to register server.\n");
     
    194195        async_set_interrupt_received(s3c24xx_uart_irq_handler);
    195196
    196         register_irq(inr, device_assign_devno(), 0, &uart_irq_code);
     197        irq_register(inr, device_assign_devno(), 0, &uart_irq_code);
    197198
    198199        /* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
  • uspace/srv/hw/irc/obio/obio.c

    r9117ef9b r7943c43  
    124124       
    125125        base_phys = (void *) paddr;
    126         base_virt = as_get_mappable_page(OBIO_SIZE);
    127126       
    128127        int flags = AS_AREA_READ | AS_AREA_WRITE;
    129         int retval = physmem_map(base_phys, (void *) base_virt,
    130             ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags);
     128        int retval = physmem_map(base_phys,
     129            ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags,
     130            (void *) &base_virt);
    131131       
    132132        if (retval < 0) {
  • uspace/srv/net/nil/eth/eth.c

    r9117ef9b r7943c43  
    802802                        next = tmp;
    803803                } else {
     804                        nic_send_frame(device->sess, packet_get_data(next),
     805                            packet_get_data_length(next));
    804806                        next = pq_next(next);
    805807                }
    806808        } while (next);
    807809       
    808         /* Send packet queue */
    809         if (packet)
    810                 nic_send_message(device->sess, packet_get_id(packet));
     810        pq_release_remote(eth_globals.net_sess, packet_get_id(packet));
    811811       
    812812        fibril_rwlock_read_unlock(&eth_globals.devices_lock);
  • uspace/srv/net/nil/nildummy/nildummy.c

    r9117ef9b r7943c43  
    345345    services_t sender)
    346346{
     347        packet_t *p;
     348       
    347349        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    348350       
     
    354356        }
    355357       
    356         /* Send packet queue */
    357         if (packet)
    358                 nic_send_message(device->sess, packet_get_id(packet));
     358        p = packet;
     359        do {
     360                nic_send_frame(device->sess, packet_get_data(p),
     361                    packet_get_data_length(p));
     362                p = pq_next(p);
     363        } while (p != NULL);
     364       
     365        pq_release_remote(nildummy_globals.net_sess, packet_get_id(packet));
    359366       
    360367        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
  • uspace/srv/net/tl/tcp/conn.c

    r9117ef9b r7943c43  
    5656
    5757LIST_INITIALIZE(conn_list);
     58FIBRIL_MUTEX_INITIALIZE(conn_list_lock);
    5859
    5960static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg);
     
    6162static void tcp_conn_tw_timer_clear(tcp_conn_t *conn);
    6263
    63 /** Create new segment structure.
     64/** Create new connection structure.
    6465 *
    6566 * @param lsock         Local socket (will be deeply copied)
    6667 * @param fsock         Foreign socket (will be deeply copied)
    67  * @return              New segment or NULL
     68 * @return              New connection or NULL
    6869 */
    6970tcp_conn_t *tcp_conn_new(tcp_sock_t *lsock, tcp_sock_t *fsock)
     
    8182                goto error;
    8283
     84        fibril_mutex_initialize(&conn->lock);
     85
     86        /* One for the user, one for not being in closed state */
     87        atomic_set(&conn->refcnt, 2);
     88
    8389        /* Allocate receive buffer */
    84         fibril_mutex_initialize(&conn->rcv_buf_lock);
    8590        fibril_condvar_initialize(&conn->rcv_buf_cv);
    8691        conn->rcv_buf_size = RCV_BUF_SIZE;
     
    9398
    9499        /** Allocate send buffer */
     100        fibril_condvar_initialize(&conn->snd_buf_cv);
    95101        conn->snd_buf_size = SND_BUF_SIZE;
    96102        conn->snd_buf_used = 0;
     
    113119
    114120        /* Connection state change signalling */
    115         fibril_mutex_initialize(&conn->cstate_lock);
    116121        fibril_condvar_initialize(&conn->cstate_cv);
     122
     123        conn->cstate_cb = NULL;
    117124
    118125        conn->cstate = st_listen;
    119126        conn->reset = false;
     127        conn->deleted = false;
    120128        conn->ap = ap_passive;
    121129        conn->fin_is_acked = false;
     
    141149}
    142150
     151/** Destroy connection structure.
     152 *
     153 * Connection structure should be destroyed when the folowing condtitions
     154 * are met:
     155 * (1) user has deleted the connection
     156 * (2) the connection has entered closed state
     157 * (3) nobody is holding references to the connection
     158 *
     159 * This happens when @a conn->refcnt is zero as we count (1) and (2)
     160 * as special references.
     161 *
     162 * @param conn          Connection
     163 */
     164static void tcp_conn_free(tcp_conn_t *conn)
     165{
     166        log_msg(LVL_DEBUG, "%s: tcp_conn_free(%p)", conn->name, conn);
     167        tcp_tqueue_fini(&conn->retransmit);
     168
     169        if (conn->rcv_buf != NULL)
     170                free(conn->rcv_buf);
     171        if (conn->snd_buf != NULL)
     172                free(conn->snd_buf);
     173        if (conn->tw_timer != NULL)
     174                fibril_timer_destroy(conn->tw_timer);
     175        free(conn);
     176}
     177
     178/** Add reference to connection.
     179 *
     180 * Increase connection reference count by one.
     181 *
     182 * @param conn          Connection
     183 */
     184void tcp_conn_addref(tcp_conn_t *conn)
     185{
     186        log_msg(LVL_DEBUG, "%s: tcp_conn_addref(%p)", conn->name, conn);
     187        atomic_inc(&conn->refcnt);
     188}
     189
     190/** Remove reference from connection.
     191 *
     192 * Decrease connection reference count by one.
     193 *
     194 * @param conn          Connection
     195 */
     196void tcp_conn_delref(tcp_conn_t *conn)
     197{
     198        log_msg(LVL_DEBUG, "%s: tcp_conn_delref(%p)", conn->name, conn);
     199
     200        if (atomic_predec(&conn->refcnt) == 0)
     201                tcp_conn_free(conn);
     202}
     203
     204/** Delete connection.
     205 *
     206 * The caller promises not make no further references to @a conn.
     207 * TCP will free @a conn eventually.
     208 *
     209 * @param conn          Connection
     210 */
     211void tcp_conn_delete(tcp_conn_t *conn)
     212{
     213        log_msg(LVL_DEBUG, "%s: tcp_conn_delete(%p)", conn->name, conn);
     214
     215        assert(conn->deleted == false);
     216        tcp_conn_delref(conn);
     217}
     218
    143219/** Enlist connection.
    144220 *
     
    147223void tcp_conn_add(tcp_conn_t *conn)
    148224{
     225        tcp_conn_addref(conn);
     226        fibril_mutex_lock(&conn_list_lock);
    149227        list_append(&conn->link, &conn_list);
     228        fibril_mutex_unlock(&conn_list_lock);
    150229}
    151230
     
    156235void tcp_conn_remove(tcp_conn_t *conn)
    157236{
     237        fibril_mutex_lock(&conn_list_lock);
    158238        list_remove(&conn->link);
     239        fibril_mutex_unlock(&conn_list_lock);
     240        tcp_conn_delref(conn);
    159241}
    160242
    161243static void tcp_conn_state_set(tcp_conn_t *conn, tcp_cstate_t nstate)
    162244{
    163         fibril_mutex_lock(&conn->cstate_lock);
     245        tcp_cstate_t old_state;
     246
     247        log_msg(LVL_DEBUG, "tcp_conn_state_set(%p)", conn);
     248
     249        old_state = conn->cstate;
    164250        conn->cstate = nstate;
    165251        fibril_condvar_broadcast(&conn->cstate_cv);
    166         fibril_mutex_unlock(&conn->cstate_lock);
     252
     253        /* Run user callback function */
     254        if (conn->cstate_cb != NULL) {
     255                log_msg(LVL_DEBUG, "tcp_conn_state_set() - run user CB");
     256                conn->cstate_cb(conn, conn->cstate_cb_arg);
     257        } else {
     258                log_msg(LVL_DEBUG, "tcp_conn_state_set() - no user CB");
     259        }
     260
     261        assert(old_state != st_closed);
     262        if (nstate == st_closed) {
     263                /* Drop one reference for now being in closed state */
     264                tcp_conn_delref(conn);
     265        }
    167266}
    168267
     
    251350 * A connection is uniquely identified by a socket pair. Look up our
    252351 * connection map and return connection structure based on socket pair.
     352 * The connection reference count is bumped by one.
    253353 *
    254354 * @param sp    Socket pair
    255355 * @return      Connection structure or NULL if not found.
    256356 */
    257 tcp_conn_t *tcp_conn_find(tcp_sockpair_t *sp)
     357tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp)
    258358{
    259359        log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp);
     360
     361        fibril_mutex_lock(&conn_list_lock);
    260362
    261363        list_foreach(conn_list, link) {
     
    266368                    csp->local.addr.ipv4, csp->local.port);
    267369                if (tcp_sockpair_match(sp, csp)) {
     370                        tcp_conn_addref(conn);
     371                        fibril_mutex_unlock(&conn_list_lock);
    268372                        return conn;
    269373                }
    270374        }
    271375
     376        fibril_mutex_unlock(&conn_list_lock);
    272377        return NULL;
    273378}
     
    287392
    288393        fibril_condvar_broadcast(&conn->rcv_buf_cv);
     394        fibril_condvar_broadcast(&conn->snd_buf_cv);
    289395}
    290396
     
    397503                    conn->snd_una, seg->ack, conn->snd_nxt);
    398504                if (!seq_no_ack_acceptable(conn, seg->ack)) {
    399                         log_msg(LVL_WARN, "ACK not acceptable, send RST.");
    400                         tcp_reply_rst(&conn->ident, seg);
     505                        if ((seg->ctrl & CTL_RST) == 0) {
     506                                log_msg(LVL_WARN, "ACK not acceptable, send RST");
     507                                tcp_reply_rst(&conn->ident, seg);
     508                        } else {
     509                                log_msg(LVL_WARN, "RST,ACK not acceptable, drop");
     510                        }
    401511                        return;
    402512                }
     
    404514
    405515        if ((seg->ctrl & CTL_RST) != 0) {
    406                 log_msg(LVL_DEBUG, "%s: Connection reset. -> Closed",
    407                     conn->name);
    408                 /* Reset connection */
    409                 tcp_conn_reset(conn);
    410                 /* XXX delete connection */
    411                 return;
     516                /* If we get here, we have either an acceptable ACK or no ACK */
     517                if ((seg->ctrl & CTL_ACK) != 0) {
     518                        log_msg(LVL_DEBUG, "%s: Connection reset. -> Closed",
     519                            conn->name);
     520                        /* Reset connection */
     521                        tcp_conn_reset(conn);
     522                        return;
     523                } else {
     524                        log_msg(LVL_DEBUG, "%s: RST without ACK, drop",
     525                            conn->name);
     526                        return;
     527                }
    412528        }
    413529
     
    858974        tcp_conn_trim_seg_to_wnd(conn, seg);
    859975
    860         fibril_mutex_lock(&conn->rcv_buf_lock);
    861 
    862976        /* Determine how many bytes to copy */
    863977        text_size = tcp_segment_text_size(seg);
     
    871985        /* Signal to the receive function that new data has arrived */
    872986        fibril_condvar_broadcast(&conn->rcv_buf_cv);
    873         fibril_mutex_unlock(&conn->rcv_buf_lock);
    874987
    875988        log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
     
    9611074
    9621075                /* Add FIN to the receive buffer */
    963                 fibril_mutex_lock(&conn->rcv_buf_lock);
    9641076                conn->rcv_buf_fin = true;
    9651077                fibril_condvar_broadcast(&conn->rcv_buf_cv);
    966                 fibril_mutex_unlock(&conn->rcv_buf_lock);
    9671078
    9681079                tcp_segment_delete(seg);
     
    10731184        log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn);
    10741185
     1186        fibril_mutex_lock(&conn->lock);
     1187
    10751188        if (conn->cstate == st_closed) {
    10761189                log_msg(LVL_DEBUG, "Connection already closed.");
     1190                fibril_mutex_unlock(&conn->lock);
     1191                tcp_conn_delref(conn);
    10771192                return;
    10781193        }
     
    10811196        tcp_conn_remove(conn);
    10821197        tcp_conn_state_set(conn, st_closed);
     1198
     1199        fibril_mutex_unlock(&conn->lock);
     1200        tcp_conn_delref(conn);
    10831201}
    10841202
     
    10891207void tcp_conn_tw_timer_set(tcp_conn_t *conn)
    10901208{
     1209        tcp_conn_addref(conn);
    10911210        fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func,
    10921211            (void *)conn);
     
    10991218void tcp_conn_tw_timer_clear(tcp_conn_t *conn)
    11001219{
    1101         fibril_timer_clear(conn->tw_timer);
     1220        if (fibril_timer_clear(conn->tw_timer) == fts_active)
     1221                tcp_conn_delref(conn);
    11021222}
    11031223
  • uspace/srv/net/tl/tcp/conn.h

    r9117ef9b r7943c43  
    4040
    4141extern tcp_conn_t *tcp_conn_new(tcp_sock_t *, tcp_sock_t *);
     42extern void tcp_conn_delete(tcp_conn_t *);
    4243extern void tcp_conn_add(tcp_conn_t *);
    4344extern void tcp_conn_remove(tcp_conn_t *);
     
    4546extern void tcp_conn_fin_sent(tcp_conn_t *);
    4647extern void tcp_conn_ack_of_fin_rcvd(tcp_conn_t *);
    47 extern tcp_conn_t *tcp_conn_find(tcp_sockpair_t *);
     48extern tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *);
     49extern void tcp_conn_addref(tcp_conn_t *);
     50extern void tcp_conn_delref(tcp_conn_t *);
    4851extern bool tcp_conn_got_syn(tcp_conn_t *);
    4952extern void tcp_conn_segment_arrived(tcp_conn_t *, tcp_segment_t *);
  • uspace/srv/net/tl/tcp/segment.c

    r9117ef9b r7943c43  
    119119                return NULL;
    120120
    121         rseg->ctrl = CTL_RST;
    122         rseg->seq = seg->ack;
     121        if ((seg->ctrl & CTL_ACK) == 0) {
     122                rseg->ctrl = CTL_RST | CTL_ACK;
     123                rseg->seq = 0;
     124                rseg->ack = seg->seq + seg->len;
     125        } else {
     126                rseg->ctrl = CTL_RST;
     127                rseg->seq = seg->ack;
     128        }
    123129
    124130        return rseg;
  • uspace/srv/net/tl/tcp/sock.c

    r9117ef9b r7943c43  
    5252#define FRAGMENT_SIZE 1024
    5353
     54#define MAX_BACKLOG 128
     55
    5456/** Free ports pool start. */
    5557#define TCP_FREE_PORTS_START            1025
     
    6062static int last_used_port = TCP_FREE_PORTS_START - 1;
    6163static socket_ports_t gsock;
     64
     65static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg);
    6266
    6367void tcp_sock_init(void)
     
    9599{
    96100        tcp_sockdata_t *sock;
     101        socket_core_t *sock_core;
    97102        int sock_id;
    98103        int rc;
     
    106111        }
    107112
     113        fibril_mutex_initialize(&sock->lock);
    108114        sock->client = client;
    109115        sock->laddr.ipv4 = TCP_IPV4_ANY;
     116        sock->lconn = NULL;
     117        sock->backlog = 0;
     118        list_initialize(&sock->ready);
    110119
    111120        sock_id = SOCKET_GET_SOCKET_ID(call);
     
    115124                return;
    116125        }
     126
     127        sock_core = socket_cores_find(&client->sockets, sock_id);
     128        assert(sock_core != NULL);
     129        sock->sock_core = sock_core;
    117130
    118131        refresh_answer(&answer, NULL);
     
    167180        socket_core_t *sock_core;
    168181        tcp_sockdata_t *socket;
     182        tcp_error_t trc;
     183        tcp_sock_t lsocket;
     184        tcp_sock_t fsocket;
     185        tcp_conn_t *conn;
     186        tcp_sock_lconn_t *lconn;
     187        int i;
    169188
    170189        log_msg(LVL_DEBUG, "tcp_sock_listen()");
     
    177196                return;
    178197        }
     198
     199        if (backlog > MAX_BACKLOG)
     200                backlog = MAX_BACKLOG;
    179201
    180202        sock_core = socket_cores_find(&client->sockets, socket_id);
     
    187209
    188210        /*
    189          * XXX We do not do anything and defer action to accept().
    190          * This is a slight difference in semantics, but most servers
    191          * would just listen() and immediately accept() in a loop.
    192          *
    193          * The only difference is that there is a window between
    194          * listen() and accept() or two accept()s where we refuse
    195          * connections.
     211         * Prepare @c backlog listening connections.
    196212         */
    197         (void)backlog;
    198         (void)socket;
    199 
     213        fibril_mutex_lock(&socket->lock);
     214
     215        socket->backlog = backlog;
     216        socket->lconn = calloc(sizeof(tcp_conn_t *), backlog);
     217        if (socket->lconn == NULL) {
     218                fibril_mutex_unlock(&socket->lock);
     219                async_answer_0(callid, ENOMEM);
     220                return;
     221        }
     222
     223        log_msg(LVL_DEBUG, " - open connections");
     224
     225        lsocket.addr.ipv4 = TCP_IPV4_ANY;
     226        lsocket.port = sock_core->port;
     227        fsocket.addr.ipv4 = TCP_IPV4_ANY;
     228        fsocket.port = TCP_PORT_ANY;
     229
     230        for (i = 0; i < backlog; i++) {
     231
     232                lconn = calloc(sizeof(tcp_sock_lconn_t), 1);
     233                if (lconn == NULL) {
     234                        /* XXX Clean up */
     235                        fibril_mutex_unlock(&socket->lock);
     236                        async_answer_0(callid, ENOMEM);
     237                        return;
     238                }
     239
     240                trc = tcp_uc_open(&lsocket, &fsocket, ap_passive,
     241                    tcp_open_nonblock, &conn);
     242                if (conn == NULL) {
     243                        /* XXX Clean up */
     244                        fibril_mutex_unlock(&socket->lock);
     245                        async_answer_0(callid, ENOMEM);
     246                        return;
     247                }
     248
     249                tcp_uc_set_cstate_cb(conn, tcp_sock_cstate_cb, lconn);
     250
     251                assert(trc == TCP_EOK);
     252                conn->name = (char *)"S";
     253
     254                lconn->conn = conn;
     255                lconn->socket = socket;
     256                link_initialize(&lconn->ready_list);
     257                socket->lconn[i] = lconn;
     258        }
     259
     260        fibril_mutex_unlock(&socket->lock);
    200261        async_answer_0(callid, EOK);
    201         log_msg(LVL_DEBUG, "tcp_sock_listen(): notify data\n");
    202         /* Push one accept notification to client's queue */
    203         tcp_sock_notify_aconn(sock_core);
    204262}
    205263
     
    248306        }
    249307
     308        fibril_mutex_lock(&socket->lock);
     309
    250310        if (socket->laddr.ipv4 == TCP_IPV4_ANY) {
    251311                /* Find route to determine local IP address. */
     
    254314                    (void **)&phdr, &phdr_len);
    255315                if (rc != EOK) {
     316                        fibril_mutex_unlock(&socket->lock);
    256317                        async_answer_0(callid, rc);
    257318                        log_msg(LVL_DEBUG, "tcp_transmit_connect: Failed to find route.");
     
    269330        fsocket.port = uint16_t_be2host(addr->sin_port);
    270331
    271         trc = tcp_uc_open(&lsocket, &fsocket, ap_active, &socket->conn);
     332        trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, &socket->conn);
    272333
    273334        if (socket->conn != NULL)
    274335                socket->conn->name = (char *)"C";
     336
     337        fibril_mutex_unlock(&socket->lock);
    275338
    276339        switch (trc) {
     
    305368        tcp_sock_t fsocket;
    306369        tcp_conn_t *conn;
     370        tcp_conn_t *rconn;
     371        tcp_sock_lconn_t *lconn;
    307372        int rc;
    308373
     
    319384
    320385        socket = (tcp_sockdata_t *)sock_core->specific_data;
     386        fibril_mutex_lock(&socket->lock);
    321387
    322388        log_msg(LVL_DEBUG, " - verify socket->conn");
    323389        if (socket->conn != NULL) {
     390                fibril_mutex_unlock(&socket->lock);
    324391                async_answer_0(callid, EINVAL);
    325392                return;
    326393        }
    327394
    328         log_msg(LVL_DEBUG, " - open connection");
     395        if (list_empty(&socket->ready)) {
     396                fibril_mutex_unlock(&socket->lock);
     397                async_answer_0(callid, ENOENT);
     398                return;
     399        }
     400
     401        lconn = list_get_instance(list_first(&socket->ready),
     402            tcp_sock_lconn_t, ready_list);
     403        list_remove(&lconn->ready_list);
     404
     405        conn = lconn->conn;
     406        tcp_uc_set_cstate_cb(conn, NULL, NULL);
     407
     408        /* Replenish listening connection */
    329409
    330410        lsocket.addr.ipv4 = TCP_IPV4_ANY;
     
    333413        fsocket.port = TCP_PORT_ANY;
    334414
    335         trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, &conn);
    336         if (conn != NULL)
    337                 conn->name = (char *)"S";
    338 
    339         log_msg(LVL_DEBUG, " - decode TCP return code");
    340 
    341         switch (trc) {
    342         case TCP_EOK:
    343                 rc = EOK;
    344                 break;
    345         case TCP_ERESET:
    346                 rc = ECONNABORTED;
    347                 break;
    348         default:
    349                 assert(false);
    350         }
    351 
    352         log_msg(LVL_DEBUG, " - check TCP return code");
    353         if (rc != EOK) {
    354                 async_answer_0(callid, rc);
    355                 return;
    356         }
     415        trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, tcp_open_nonblock,
     416            &rconn);
     417        if (rconn == NULL) {
     418                /* XXX Clean up */
     419                fibril_mutex_unlock(&socket->lock);
     420                async_answer_0(callid, ENOMEM);
     421                return;
     422        }
     423
     424        tcp_uc_set_cstate_cb(rconn, tcp_sock_cstate_cb, lconn);
     425
     426        assert(trc == TCP_EOK);
     427        rconn->name = (char *)"S";
     428
     429        lconn->conn = rconn;
     430
     431        /* Allocate socket for accepted connection */
    357432
    358433        log_msg(LVL_DEBUG, "tcp_sock_accept(): allocate asocket\n");
    359434        asocket = calloc(sizeof(tcp_sockdata_t), 1);
    360435        if (asocket == NULL) {
     436                fibril_mutex_unlock(&socket->lock);
    361437                async_answer_0(callid, ENOMEM);
    362438                return;
    363439        }
    364440
     441        fibril_mutex_initialize(&asocket->lock);
    365442        asocket->client = client;
    366443        asocket->conn = conn;
     
    369446        rc = socket_create(&client->sockets, client->sess, asocket, &asock_id);
    370447        if (rc != EOK) {
     448                fibril_mutex_unlock(&socket->lock);
    371449                async_answer_0(callid, rc);
    372450                return;
     
    385463        answer_call(callid, asock_core->socket_id, &answer, 3);
    386464
    387         /* Push one accept notification to client's queue */
    388         tcp_sock_notify_aconn(sock_core);
    389 
    390465        /* Push one fragment notification to client's queue */
     466        log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n");
    391467        tcp_sock_notify_data(asock_core);
    392         log_msg(LVL_DEBUG, "tcp_sock_accept(): notify aconn\n");
     468        fibril_mutex_unlock(&socket->lock);
    393469}
    394470
     
    419495
    420496        socket = (tcp_sockdata_t *)sock_core->specific_data;
     497        fibril_mutex_lock(&socket->lock);
     498
    421499        if (socket->conn == NULL) {
     500                fibril_mutex_unlock(&socket->lock);
    422501                async_answer_0(callid, ENOTCONN);
    423502                return;
     
    426505        for (index = 0; index < fragments; index++) {
    427506                if (!async_data_write_receive(&wcallid, &length)) {
     507                        fibril_mutex_unlock(&socket->lock);
    428508                        async_answer_0(callid, EINVAL);
    429509                        return;
     
    435515                rc = async_data_write_finalize(wcallid, buffer, length);
    436516                if (rc != EOK) {
     517                        fibril_mutex_unlock(&socket->lock);
    437518                        async_answer_0(callid, rc);
    438519                        return;
     
    459540
    460541                if (rc != EOK) {
     542                        fibril_mutex_unlock(&socket->lock);
    461543                        async_answer_0(callid, rc);
    462544                        return;
     
    467549        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    468550        answer_call(callid, EOK, &answer, 2);
     551        fibril_mutex_unlock(&socket->lock);
    469552}
    470553
     
    504587
    505588        socket = (tcp_sockdata_t *)sock_core->specific_data;
     589        fibril_mutex_lock(&socket->lock);
     590
    506591        if (socket->conn == NULL) {
     592                fibril_mutex_unlock(&socket->lock);
    507593                async_answer_0(callid, ENOTCONN);
    508594                return;
     
    532618        log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc);
    533619        if (rc != EOK) {
     620                fibril_mutex_unlock(&socket->lock);
    534621                async_answer_0(callid, rc);
    535622                return;
     
    545632                log_msg(LVL_DEBUG, "addr read receive");
    546633                if (!async_data_read_receive(&rcallid, &addr_length)) {
     634                        fibril_mutex_unlock(&socket->lock);
    547635                        async_answer_0(callid, EINVAL);
    548636                        return;
     
    555643                rc = async_data_read_finalize(rcallid, &addr, addr_length);
    556644                if (rc != EOK) {
     645                        fibril_mutex_unlock(&socket->lock);
    557646                        async_answer_0(callid, EINVAL);
    558647                        return;
     
    562651        log_msg(LVL_DEBUG, "data read receive");
    563652        if (!async_data_read_receive(&rcallid, &length)) {
     653                fibril_mutex_unlock(&socket->lock);
    564654                async_answer_0(callid, EINVAL);
    565655                return;
     
    580670        /* Push one fragment notification to client's queue */
    581671        tcp_sock_notify_data(sock_core);
     672        fibril_mutex_unlock(&socket->lock);
    582673}
    583674
     
    603694
    604695        socket = (tcp_sockdata_t *)sock_core->specific_data;
    605         rc = tcp_uc_close(socket->conn);
    606         if (rc != EOK) {
    607                 async_answer_0(callid, rc);
    608                 return;
    609         }
    610 
    611         /* Drain incoming data. This should really be done in the background. */
    612         do {
    613                 trc = tcp_uc_receive(socket->conn, buffer, FRAGMENT_SIZE,
    614                     &data_len, &xflags);
    615         } while (trc == TCP_EOK);
     696        fibril_mutex_lock(&socket->lock);
     697
     698        if (socket->conn != NULL) {
     699                trc = tcp_uc_close(socket->conn);
     700                if (trc != TCP_EOK && trc != TCP_ENOTEXIST) {
     701                        fibril_mutex_unlock(&socket->lock);
     702                        async_answer_0(callid, EBADF);
     703                        return;
     704                }
     705
     706                /* Drain incoming data. This should really be done in the background. */
     707                do {
     708                        trc = tcp_uc_receive(socket->conn, buffer,
     709                            FRAGMENT_SIZE, &data_len, &xflags);
     710                } while (trc == TCP_EOK);
     711
     712                tcp_uc_delete(socket->conn);
     713        }
    616714
    617715        rc = socket_destroy(net_sess, socket_id, &client->sockets, &gsock,
    618716            tcp_free_sock_data);
    619717        if (rc != EOK) {
     718                fibril_mutex_unlock(&socket->lock);
    620719                async_answer_0(callid, rc);
    621720                return;
    622721        }
    623722
     723        fibril_mutex_unlock(&socket->lock);
    624724        async_answer_0(callid, EOK);
    625725}
     
    635735        log_msg(LVL_DEBUG, "tcp_sock_setsockopt()");
    636736        async_answer_0(callid, ENOTSUP);
     737}
     738
     739/** Called when connection state changes. */
     740static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg)
     741{
     742        tcp_conn_status_t cstatus;
     743        tcp_sock_lconn_t *lconn = (tcp_sock_lconn_t *)arg;
     744        tcp_sockdata_t *socket = lconn->socket;
     745
     746        log_msg(LVL_DEBUG, "tcp_sock_cstate_cb()");
     747        fibril_mutex_lock(&socket->lock);
     748        assert(conn == lconn->conn);
     749
     750        tcp_uc_status(conn, &cstatus);
     751        if (cstatus.cstate != st_established) {
     752                fibril_mutex_unlock(&socket->lock);
     753                return;
     754        }
     755
     756        assert_link_not_used(&lconn->ready_list);
     757        list_append(&lconn->ready_list, &socket->ready);
     758
     759        log_msg(LVL_DEBUG, "tcp_sock_cstate_cb(): notify accept");
     760
     761        /* Push one accept notification to client's queue */
     762        tcp_sock_notify_aconn(socket->sock_core);
     763        fibril_mutex_unlock(&socket->lock);
    637764}
    638765
  • uspace/srv/net/tl/tcp/tcp.c

    r9117ef9b r7943c43  
    3636
    3737#include <async.h>
     38#include <bitops.h>
    3839#include <byteorder.h>
    3940#include <errno.h>
     
    191192        tcp_pdu_t *pdu;
    192193        size_t hdr_size;
    193 
    194         /* XXX Header options */
    195         hdr_size = sizeof(tcp_header_t);
     194        tcp_header_t *hdr;
     195        uint32_t data_offset;
     196
     197        if (pdu_raw_size < sizeof(tcp_header_t)) {
     198                log_msg(LVL_WARN, "pdu_raw_size = %zu < sizeof(tcp_header_t) = %zu",
     199                    pdu_raw_size, sizeof(tcp_header_t));
     200                pq_release_remote(net_sess, packet_get_id(packet));
     201                return EINVAL;
     202        }
     203
     204        hdr = (tcp_header_t *)pdu_raw;
     205        data_offset = BIT_RANGE_EXTRACT(uint32_t, DF_DATA_OFFSET_h, DF_DATA_OFFSET_l,
     206            uint16_t_be2host(hdr->doff_flags));
     207
     208        hdr_size = sizeof(uint32_t) * data_offset;
    196209
    197210        if (pdu_raw_size < hdr_size) {
    198211                log_msg(LVL_WARN, "pdu_raw_size = %zu < hdr_size = %zu",
    199212                    pdu_raw_size, hdr_size);
     213                pq_release_remote(net_sess, packet_get_id(packet));
     214                return EINVAL;
     215        }
     216
     217        if (hdr_size < sizeof(tcp_header_t)) {
     218                log_msg(LVL_WARN, "hdr_size = %zu < sizeof(tcp_header_t) = %zu",
     219                    hdr_size, sizeof(tcp_header_t));
    200220                pq_release_remote(net_sess, packet_get_id(packet));
    201221                return EINVAL;
  • uspace/srv/net/tl/tcp/tcp_type.h

    r9117ef9b r7943c43  
    152152} acpass_t;
    153153
    154 typedef struct tcp_conn {
     154typedef enum {
     155        tcp_open_nonblock = 1
     156} tcp_open_flags_t;
     157
     158typedef struct tcp_conn tcp_conn_t;
     159
     160/** Connection state change callback function */
     161typedef void (*tcp_cstate_cb_t)(tcp_conn_t *, void *);
     162
     163/** Connection */
     164struct tcp_conn {
    155165        char *name;
    156166        link_t link;
     167
     168        /** Connection state change callback function */
     169        tcp_cstate_cb_t cstate_cb;
     170        /** Argument to @c cstate_cb */
     171        void *cstate_cb_arg;
    157172
    158173        /** Connection identification (local and foreign socket) */
     
    161176        /** Active or passive connection */
    162177        acpass_t ap;
     178
     179        /** Protects access to connection structure */
     180        fibril_mutex_t lock;
     181        /** Reference count */
     182        atomic_t refcnt;
    163183
    164184        /** Connection state */
     
    166186        /** True if connection was reset */
    167187        bool reset;
    168         /** Protects @c cstate */
    169         fibril_mutex_t cstate_lock;
     188        /** True if connection was deleted by user */
     189        bool deleted;
    170190        /** Signalled when @c cstate changes */
    171191        fibril_condvar_t cstate_cv;
     
    191211        /** Receive buffer contains FIN */
    192212        bool rcv_buf_fin;
    193         /** Receive buffer lock */
    194         fibril_mutex_t rcv_buf_lock;
    195213        /** Receive buffer CV. Broadcast when new data is inserted */
    196214        fibril_condvar_t rcv_buf_cv;
     
    204222        /** Send buffer contains FIN */
    205223        bool snd_buf_fin;
     224        /** Send buffer CV. Broadcast when space is made available in buffer */
     225        fibril_condvar_t snd_buf_cv;
    206226
    207227        /** Send unacknowledged */
     
    228248        /** Initial receive sequence number */
    229249        uint32_t irs;
    230 } tcp_conn_t;
    231 
    232 typedef struct {
    233         unsigned dummy;
     250};
     251
     252/** Data returned by Status user call */
     253typedef struct {
     254        /** Connection state */
     255        tcp_cstate_t cstate;
    234256} tcp_conn_status_t;
    235257
     
    309331} tcp_client_t;
    310332
    311 typedef struct {
     333typedef struct tcp_sockdata {
     334        /** Lock */
     335        fibril_mutex_t lock;
     336        /** Socket core */
     337        socket_core_t *sock_core;
    312338        /** Client */
    313339        tcp_client_t *client;
     
    316342        /** Local address */
    317343        netaddr_t laddr;
     344        /** Backlog size */
     345        int backlog;
     346        /** Array of listening connections, @c backlog elements */
     347        struct tcp_sock_lconn **lconn;
     348        /** List of connections (from lconn) that are ready to be accepted */
     349        list_t ready;
    318350} tcp_sockdata_t;
     351
     352typedef struct tcp_sock_lconn {
     353        tcp_conn_t *conn;
     354        tcp_sockdata_t *socket;
     355        int index;
     356        link_t ready_list;
     357} tcp_sock_lconn_t;
     358
    319359
    320360#endif
  • uspace/srv/net/tl/tcp/test.c

    r9117ef9b r7943c43  
    6262        fsock.addr.ipv4 = 0x7f000001;
    6363        printf("S: User open...\n");
    64         tcp_uc_open(&lsock, &fsock, ap_passive, &conn);
     64        tcp_uc_open(&lsock, &fsock, ap_passive, 0, &conn);
    6565        conn->name = (char *) "S";
    6666
     
    102102        async_usleep(1000*1000*3);
    103103        printf("C: User open...\n");
    104         tcp_uc_open(&lsock, &fsock, ap_active, &conn);
     104        tcp_uc_open(&lsock, &fsock, ap_active, 0, &conn);
    105105        conn->name = (char *) "C";
    106106
  • uspace/srv/net/tl/tcp/tqueue.c

    r9117ef9b r7943c43  
    188188                /* We are sending out FIN */
    189189                ctrl = CTL_FIN;
    190                 tcp_conn_fin_sent(conn);
    191190        } else {
    192191                ctrl = 0;
     
    206205        if (send_fin)
    207206                conn->snd_buf_fin = false;
     207
     208        fibril_condvar_broadcast(&conn->snd_buf_cv);
     209
     210        if (send_fin)
     211                tcp_conn_fin_sent(conn);
    208212
    209213        tcp_tqueue_seg(conn, seg);
     
    313317        log_msg(LVL_DEBUG, "### %s: retransmit_timeout_func(%p)", conn->name, conn);
    314318
     319        fibril_mutex_lock(&conn->lock);
     320
    315321        if (conn->cstate == st_closed) {
    316322                log_msg(LVL_DEBUG, "Connection already closed.");
     323                fibril_mutex_unlock(&conn->lock);
     324                tcp_conn_delref(conn);
    317325                return;
    318326        }
     
    321329        if (link == NULL) {
    322330                log_msg(LVL_DEBUG, "Nothing to retransmit");
     331                fibril_mutex_unlock(&conn->lock);
     332                tcp_conn_delref(conn);
    323333                return;
    324334        }
     
    329339        if (rt_seg == NULL) {
    330340                log_msg(LVL_ERROR, "Memory allocation failed.");
     341                fibril_mutex_unlock(&conn->lock);
     342                tcp_conn_delref(conn);
    331343                /* XXX Handle properly */
    332344                return;
     
    338350        /* Reset retransmission timer */
    339351        tcp_tqueue_timer_set(tqe->conn);
     352
     353        fibril_mutex_unlock(&conn->lock);
     354        tcp_conn_delref(conn);
    340355}
    341356
     
    345360        log_msg(LVL_DEBUG, "### %s: tcp_tqueue_timer_set()", conn->name);
    346361
    347         (void) retransmit_timeout_func;
     362        /* Clear first to make sure we update refcnt correctly */
     363        tcp_tqueue_timer_clear(conn);
     364
     365        tcp_conn_addref(conn);
    348366        fibril_timer_set(conn->retransmit.timer, RETRANSMIT_TIMEOUT,
    349367            retransmit_timeout_func, (void *) conn);
     
    355373        log_msg(LVL_DEBUG, "### %s: tcp_tqueue_timer_clear()", conn->name);
    356374
    357         fibril_timer_clear(conn->retransmit.timer);
     375        if (fibril_timer_clear(conn->retransmit.timer) == fts_active)
     376                tcp_conn_delref(conn);
    358377}
    359378
  • uspace/srv/net/tl/tcp/ucall.c

    r9117ef9b r7943c43  
    5353 * @param fsock         Foreign socket
    5454 * @param acpass        Active/passive
     55 * @param oflags        Open flags
    5556 * @param conn          Connection
    5657 *
     
    6566 */
    6667tcp_error_t tcp_uc_open(tcp_sock_t *lsock, tcp_sock_t *fsock, acpass_t acpass,
    67     tcp_conn_t **conn)
     68    tcp_open_flags_t oflags, tcp_conn_t **conn)
    6869{
    6970        tcp_conn_t *nconn;
    7071
    71         log_msg(LVL_DEBUG, "tcp_uc_open(%p, %p, %s, %p)",
     72        log_msg(LVL_DEBUG, "tcp_uc_open(%p, %p, %s, %s, %p)",
    7273            lsock, fsock, acpass == ap_active ? "active" : "passive",
    73             conn);
     74            oflags == tcp_open_nonblock ? "nonblock" : "none", conn);
    7475
    7576        nconn = tcp_conn_new(lsock, fsock);
     
    8182        }
    8283
     84        if (oflags == tcp_open_nonblock) {
     85                *conn = nconn;
     86                return TCP_EOK;
     87        }
     88
    8389        /* Wait for connection to be established or reset */
    8490        log_msg(LVL_DEBUG, "tcp_uc_open: Wait for connection.");
    85         fibril_mutex_lock(&nconn->cstate_lock);
     91        fibril_mutex_lock(&nconn->lock);
    8692        while (nconn->cstate == st_listen ||
    8793            nconn->cstate == st_syn_sent ||
    8894            nconn->cstate == st_syn_received) {
    89                 fibril_condvar_wait(&nconn->cstate_cv, &nconn->cstate_lock);
     95                fibril_condvar_wait(&nconn->cstate_cv, &nconn->lock);
    9096        }
    9197
     
    9399                log_msg(LVL_DEBUG, "tcp_uc_open: Connection was reset.");
    94100                assert(nconn->cstate == st_closed);
    95                 fibril_mutex_unlock(&nconn->cstate_lock);
     101                fibril_mutex_unlock(&nconn->lock);
    96102                return TCP_ERESET;
    97103        }
    98104
    99         fibril_mutex_unlock(&nconn->cstate_lock);
     105        fibril_mutex_unlock(&nconn->lock);
    100106        log_msg(LVL_DEBUG, "tcp_uc_open: Connection was established.");
    101107
    102108        *conn = nconn;
     109        log_msg(LVL_DEBUG, "tcp_uc_open -> %p", nconn);
    103110        return TCP_EOK;
    104111}
     
    113120        log_msg(LVL_DEBUG, "%s: tcp_uc_send()", conn->name);
    114121
    115         if (conn->cstate == st_closed)
     122        fibril_mutex_lock(&conn->lock);
     123
     124        if (conn->cstate == st_closed) {
     125                fibril_mutex_unlock(&conn->lock);
    116126                return TCP_ENOTEXIST;
     127        }
    117128
    118129        if (conn->cstate == st_listen) {
     
    121132        }
    122133
    123         if (conn->snd_buf_fin)
     134
     135        if (conn->snd_buf_fin) {
     136                fibril_mutex_unlock(&conn->lock);
    124137                return TCP_ECLOSING;
     138        }
    125139
    126140        while (size > 0) {
    127141                buf_free = conn->snd_buf_size - conn->snd_buf_used;
    128                 while (buf_free == 0 && !conn->reset)
    129                         tcp_tqueue_new_data(conn);
    130 
    131                 if (conn->reset)
     142                while (buf_free == 0 && !conn->reset) {
     143                        log_msg(LVL_DEBUG, "%s: buf_free == 0, waiting.",
     144                            conn->name);
     145                        fibril_condvar_wait(&conn->snd_buf_cv, &conn->lock);
     146                        buf_free = conn->snd_buf_size - conn->snd_buf_used;
     147                }
     148
     149                if (conn->reset) {
     150                        fibril_mutex_unlock(&conn->lock);
    132151                        return TCP_ERESET;
     152                }
    133153
    134154                xfer_size = min(size, buf_free);
     
    139159                conn->snd_buf_used += xfer_size;
    140160                size -= xfer_size;
     161
     162                tcp_tqueue_new_data(conn);
    141163        }
    142164
    143165        tcp_tqueue_new_data(conn);
     166        fibril_mutex_unlock(&conn->lock);
    144167
    145168        return TCP_EOK;
     
    154177        log_msg(LVL_DEBUG, "%s: tcp_uc_receive()", conn->name);
    155178
    156         if (conn->cstate == st_closed)
     179        fibril_mutex_lock(&conn->lock);
     180
     181        if (conn->cstate == st_closed) {
     182                fibril_mutex_unlock(&conn->lock);
    157183                return TCP_ENOTEXIST;
    158 
    159         fibril_mutex_lock(&conn->rcv_buf_lock);
     184        }
    160185
    161186        /* Wait for data to become available */
    162187        while (conn->rcv_buf_used == 0 && !conn->rcv_buf_fin && !conn->reset) {
    163188                log_msg(LVL_DEBUG, "tcp_uc_receive() - wait for data");
    164                 fibril_condvar_wait(&conn->rcv_buf_cv, &conn->rcv_buf_lock);
     189                fibril_condvar_wait(&conn->rcv_buf_cv, &conn->lock);
    165190        }
    166191
    167192        if (conn->rcv_buf_used == 0) {
    168                 fibril_mutex_unlock(&conn->rcv_buf_lock);
    169 
    170193                *rcvd = 0;
    171194                *xflags = 0;
     
    173196                if (conn->rcv_buf_fin) {
    174197                        /* End of data, peer closed connection */
     198                        fibril_mutex_unlock(&conn->lock);
    175199                        return TCP_ECLOSING;
    176200                } else {
    177201                        /* Connection was reset */
    178202                        assert(conn->reset);
     203                        fibril_mutex_unlock(&conn->lock);
    179204                        return TCP_ERESET;
    180205                }
     
    192217        conn->rcv_wnd += xfer_size;
    193218
    194         fibril_mutex_unlock(&conn->rcv_buf_lock);
    195 
    196219        /* TODO */
    197220        *xflags = 0;
     
    203226            conn->name, xfer_size);
    204227
     228        fibril_mutex_unlock(&conn->lock);
     229
    205230        return TCP_EOK;
    206231}
     
    211236        log_msg(LVL_DEBUG, "%s: tcp_uc_close()", conn->name);
    212237
    213         if (conn->cstate == st_closed)
     238        fibril_mutex_lock(&conn->lock);
     239
     240        if (conn->cstate == st_closed) {
     241                fibril_mutex_unlock(&conn->lock);
    214242                return TCP_ENOTEXIST;
    215 
    216         if (conn->snd_buf_fin)
     243        }
     244
     245        if (conn->snd_buf_fin) {
     246                fibril_mutex_unlock(&conn->lock);
    217247                return TCP_ECLOSING;
     248        }
    218249
    219250        conn->snd_buf_fin = true;
    220251        tcp_tqueue_new_data(conn);
    221252
     253        fibril_mutex_unlock(&conn->lock);
    222254        return TCP_EOK;
    223255}
     
    233265{
    234266        log_msg(LVL_DEBUG, "tcp_uc_status()");
    235 }
    236 
     267        cstatus->cstate = conn->cstate;
     268}
     269
     270/** Delete connection user call.
     271 *
     272 * (Not in spec.) Inform TCP that the user is done with this connection
     273 * and will not make any further calls/references to it. TCP can deallocate
     274 * the connection from now on.
     275 */
     276void tcp_uc_delete(tcp_conn_t *conn)
     277{
     278        log_msg(LVL_DEBUG, "tcp_uc_delete()");
     279        tcp_conn_delete(conn);
     280}
     281
     282void tcp_uc_set_cstate_cb(tcp_conn_t *conn, tcp_cstate_cb_t cb, void *arg)
     283{
     284        log_msg(LVL_DEBUG, "tcp_uc_set_ctate_cb(%p, %p, %p)",
     285            conn, cb, arg);
     286
     287        conn->cstate_cb = cb;
     288        conn->cstate_cb_arg = arg;
     289}
    237290
    238291/*
     
    249302            sp->local.addr.ipv4, sp->local.port);
    250303
    251         conn = tcp_conn_find(sp);
    252         if (conn != NULL && conn->cstate != st_closed) {
    253                 if (conn->ident.foreign.addr.ipv4 == TCP_IPV4_ANY)
    254                         conn->ident.foreign.addr.ipv4 = sp->foreign.addr.ipv4;
    255                 if (conn->ident.foreign.port == TCP_PORT_ANY)
    256                         conn->ident.foreign.port = sp->foreign.port;
    257                 if (conn->ident.local.addr.ipv4 == TCP_IPV4_ANY)
    258                         conn->ident.local.addr.ipv4 = sp->local.addr.ipv4;
    259 
    260                 tcp_conn_segment_arrived(conn, seg);
    261         } else {
    262                 if (conn == NULL)
    263                         log_msg(LVL_WARN, "No connection found.");
    264                 else
    265                         log_msg(LVL_WARN, "Connection is closed.");
     304        conn = tcp_conn_find_ref(sp);
     305        if (conn == NULL) {
     306                log_msg(LVL_WARN, "No connection found.");
    266307                tcp_unexpected_segment(sp, seg);
    267         }
     308                return;
     309        }
     310
     311        fibril_mutex_lock(&conn->lock);
     312
     313        if (conn->cstate == st_closed) {
     314                log_msg(LVL_WARN, "Connection is closed.");
     315                tcp_unexpected_segment(sp, seg);
     316                fibril_mutex_unlock(&conn->lock);
     317                tcp_conn_delref(conn);
     318                return;
     319        }
     320
     321        if (conn->ident.foreign.addr.ipv4 == TCP_IPV4_ANY)
     322                conn->ident.foreign.addr.ipv4 = sp->foreign.addr.ipv4;
     323        if (conn->ident.foreign.port == TCP_PORT_ANY)
     324                conn->ident.foreign.port = sp->foreign.port;
     325        if (conn->ident.local.addr.ipv4 == TCP_IPV4_ANY)
     326                conn->ident.local.addr.ipv4 = sp->local.addr.ipv4;
     327
     328        tcp_conn_segment_arrived(conn, seg);
     329
     330        fibril_mutex_unlock(&conn->lock);
     331        tcp_conn_delref(conn);
    268332}
    269333
  • uspace/srv/net/tl/tcp/ucall.h

    r9117ef9b r7943c43  
    4242 * User calls
    4343 */
    44 extern tcp_error_t tcp_uc_open(tcp_sock_t *, tcp_sock_t *, acpass_t, tcp_conn_t **);
     44extern tcp_error_t tcp_uc_open(tcp_sock_t *, tcp_sock_t *, acpass_t,
     45    tcp_open_flags_t, tcp_conn_t **);
    4546extern tcp_error_t tcp_uc_send(tcp_conn_t *, void *, size_t, xflags_t);
    4647extern tcp_error_t tcp_uc_receive(tcp_conn_t *, void *, size_t, size_t *, xflags_t *);
     
    4849extern void tcp_uc_abort(tcp_conn_t *);
    4950extern void tcp_uc_status(tcp_conn_t *, tcp_conn_status_t *);
     51extern void tcp_uc_delete(tcp_conn_t *);
     52extern void tcp_uc_set_cstate_cb(tcp_conn_t *, tcp_cstate_cb_t, void *);
    5053
    5154/*
  • uspace/srv/vfs/vfs.c

    r9117ef9b r7943c43  
    172172         * Allocate and initialize the Path Lookup Buffer.
    173173         */
    174         plb = as_get_mappable_page(PLB_SIZE);
    175         if (!plb) {
    176                 printf(NAME ": Cannot allocate a mappable piece of address space\n");
    177                 return ENOMEM;
    178         }
    179        
    180         if (as_area_create(plb, PLB_SIZE, AS_AREA_READ | AS_AREA_WRITE |
    181             AS_AREA_CACHEABLE) != plb) {
     174        plb = as_area_create((void *) -1, PLB_SIZE,
     175            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
     176        if (plb == (void *) -1) {
    182177                printf(NAME ": Cannot create address space area\n");
    183178                return ENOMEM;
Note: See TracChangeset for help on using the changeset viewer.