Changeset 7943c43 in mainline for uspace/srv
- Timestamp:
- 2012-01-16T22:45:38Z (14 years ago)
- 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. - Location:
- uspace/srv
- Files:
-
- 6 added
- 3 deleted
- 42 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/ata_bd/ata_bd.c
r9117ef9b r7943c43 245 245 void *vaddr; 246 246 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); 249 250 if (rc < 0) { 250 251 printf(NAME ": Unable to register driver.\n"); … … 309 310 } 310 311 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) { 313 314 async_answer_0(callid, EHANGUP); 314 315 return; 315 316 } 316 317 (void) async_share_out_finalize(callid, fs_va);318 317 319 318 while (true) { -
uspace/srv/bd/file_bd/file_bd.c
r9117ef9b r7943c43 141 141 int rc; 142 142 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); 145 146 if (rc < 0) { 146 147 printf(NAME ": Unable to register driver.\n"); … … 190 191 } 191 192 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) { 194 195 async_answer_0(callid, EHANGUP); 195 196 return; 196 197 } 197 198 (void) async_share_out_finalize(callid, fs_va);199 198 200 199 while (true) { -
uspace/srv/bd/gxe_bd/gxe_bd.c
r9117ef9b r7943c43 125 125 int rc, i; 126 126 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); 129 130 if (rc < 0) { 130 131 printf(NAME ": Unable to register driver.\n"); … … 193 194 } 194 195 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) { 197 198 async_answer_0(callid, EHANGUP); 198 199 return; 199 200 } 200 201 (void) async_share_out_finalize(callid, fs_va);202 201 203 202 while (true) { -
uspace/srv/bd/part/guid_part/guid_part.c
r9117ef9b r7943c43 164 164 165 165 /* 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); 167 168 if (rc != EOK) { 168 169 printf(NAME ": Unable to register server.\n"); … … 348 349 } 349 350 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) { 352 353 async_answer_0(callid, EHANGUP); 353 354 return; 354 355 } 355 356 (void) async_share_out_finalize(callid, fs_va);357 356 358 357 while (true) { -
uspace/srv/bd/part/mbr_part/mbr_part.c
r9117ef9b r7943c43 214 214 215 215 /* 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); 217 218 if (rc != EOK) { 218 219 printf(NAME ": Unable to register server.\n"); … … 425 426 } 426 427 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) { 429 430 async_answer_0(callid, EHANGUP); 430 431 return; 431 432 } 432 433 (void) async_share_out_finalize(callid, fs_va);434 433 435 434 while (1) { -
uspace/srv/bd/rd/rd.c
r9117ef9b r7943c43 105 105 unsigned int flags; 106 106 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) { 111 109 async_answer_0(callid, EHANGUP); 112 110 return; … … 224 222 225 223 rd_size = ALIGN_UP(size, block_size); 226 rd_addr = as_get_mappable_page(rd_size);227 228 224 unsigned int flags = 229 225 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) { 233 230 printf("%s: Error mapping RAM disk\n", NAME); 234 231 return false; … … 238 235 (void *) addr_phys, size); 239 236 240 ret = loc_server_register(NAME, rd_connection); 237 async_set_client_connection(rd_connection); 238 ret = loc_server_register(NAME); 241 239 if (ret < 0) { 242 240 printf("%s: Unable to register driver (%d)\n", NAME, ret); -
uspace/srv/devman/main.c
r9117ef9b r7943c43 1309 1309 1310 1310 /* 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. 1315 1316 */ 1316 loc_server_register(NAME , devman_connection);1317 loc_server_register(NAME); 1317 1318 1318 1319 return true; … … 1325 1326 if (log_init(NAME, LVL_WARN) != EOK) { 1326 1327 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.");1332 1328 return -1; 1333 1329 } … … 1338 1334 async_set_client_connection(devman_connection); 1339 1335 1336 if (!devman_init()) { 1337 log_msg(LVL_ERROR, "Error while initializing service."); 1338 return -1; 1339 } 1340 1340 1341 /* Register device manager at naming service. */ 1341 1342 if (service_register(SERVICE_DEVMAN) != EOK) { -
uspace/srv/hid/console/console.c
r9117ef9b r7943c43 825 825 826 826 /* 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); 828 829 if (rc < 0) { 829 830 printf("%s: Unable to register server (%s)\n", NAME, -
uspace/srv/hid/fb/fb.c
r9117ef9b r7943c43 304 304 } 305 305 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)) { 309 308 free(frontbuf); 310 309 async_answer_0(iid, ENOMEM); … … 348 347 } 349 348 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)) { 353 351 free(imagemap); 354 352 async_answer_0(iid, ENOMEM); … … 989 987 990 988 /* 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); 992 991 if (rc != EOK) { 993 992 printf("%s: Unable to register driver (%d)\n", NAME, rc); -
uspace/srv/hid/fb/port/ega.c
r9117ef9b r7943c43 280 280 281 281 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); 288 286 if (rc != EOK) 289 287 return rc; -
uspace/srv/hid/fb/port/kchar.c
r9117ef9b r7943c43 83 83 return rc; 84 84 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); 91 88 if (rc != EOK) 92 89 return rc; -
uspace/srv/hid/fb/port/kfb.c
r9117ef9b r7943c43 756 756 757 757 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); 766 762 if (rc != EOK) { 767 763 free(kfb.glyphs); -
uspace/srv/hid/fb/port/niagara.c
r9117ef9b r7943c43 103 103 return rc; 104 104 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); 112 107 if (rc != EOK) 113 108 return rc; -
uspace/srv/hid/input/Makefile
r9117ef9b r7943c43 43 43 port/adb_mouse.c \ 44 44 port/chardev.c \ 45 port/chardev_mouse.c \46 45 port/gxemul.c \ 47 46 port/msim.c \ … … 52 51 proto/adb.c \ 53 52 proto/mousedev.c \ 54 proto/ps2.c \55 53 ctl/apple.c \ 56 54 ctl/gxe_fb.c \ -
uspace/srv/hid/input/generic/input.c
r9117ef9b r7943c43 172 172 173 173 /** Mouse pointer has moved. */ 174 void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy )174 void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy, int dz) 175 175 { 176 176 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 } 178 187 async_exchange_end(exch); 179 188 } … … 397 406 * them automatically. 398 407 */ 399 #if defined(UARCH_amd64)400 kbd_add_dev(&chardev_port, &pc_ctl);401 #endif402 408 #if defined(UARCH_arm32) && defined(MACHINE_gta02) 403 409 kbd_add_dev(&chardev_port, &stty_ctl); … … 411 417 #if defined(UARCH_arm32) && defined(MACHINE_integratorcp) 412 418 kbd_add_dev(&pl050_port, &pc_ctl); 413 #endif414 #if defined(UARCH_ia32)415 kbd_add_dev(&chardev_port, &pc_ctl);416 #endif417 #if defined(MACHINE_i460GX)418 kbd_add_dev(&chardev_port, &pc_ctl);419 419 #endif 420 420 #if defined(MACHINE_ski) … … 450 450 * them automatically. 451 451 */ 452 #if defined(UARCH_amd64)453 mouse_add_dev(&chardev_mouse_port, &ps2_proto);454 #endif455 #if defined(UARCH_ia32)456 mouse_add_dev(&chardev_mouse_port, &ps2_proto);457 #endif458 #if defined(MACHINE_i460GX)459 mouse_add_dev(&chardev_mouse_port, &ps2_proto);460 #endif461 452 #if defined(UARCH_ppc32) 462 453 mouse_add_dev(&adb_mouse_port, &adb_proto); … … 658 649 659 650 /* 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); 661 653 if (rc < 0) { 662 654 printf("%s: Unable to register server (%d)\n", NAME, rc); -
uspace/srv/hid/input/include/mouse.h
r9117ef9b r7943c43 62 62 63 63 extern void mouse_push_data(mouse_dev_t *, sysarg_t); 64 extern void mouse_push_event_move(mouse_dev_t *, int, int );64 extern void mouse_push_event_move(mouse_dev_t *, int, int, int); 65 65 extern void mouse_push_event_button(mouse_dev_t *, int, int); 66 66 -
uspace/srv/hid/input/include/mouse_proto.h
r9117ef9b r7943c43 48 48 49 49 extern mouse_proto_ops_t adb_proto; 50 extern mouse_proto_ops_t ps2_proto;51 50 extern mouse_proto_ops_t mousedev_proto; 52 51 -
uspace/srv/hid/input/port/chardev.c
r9117ef9b r7943c43 63 63 /** List of devices to try connecting to. */ 64 64 static const char *in_devs[] = { 65 "char/ps2a",66 65 "char/s3c24ser" 67 66 }; -
uspace/srv/hid/input/port/gxemul.c
r9117ef9b r7943c43 90 90 async_set_interrupt_received(gxemul_irq_handler); 91 91 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); 93 93 return 0; 94 94 } -
uspace/srv/hid/input/port/msim.c
r9117ef9b r7943c43 89 89 msim_cmds[0].addr = (void *) vaddr; 90 90 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); 92 92 93 93 return 0; -
uspace/srv/hid/input/port/niagara.c
r9117ef9b r7943c43 63 63 #define POLL_INTERVAL 10000 64 64 65 /**66 * Virtual address mapped to the buffer shared with the kernel counterpart.67 */68 static uintptr_t input_buffer_addr;69 70 65 /* 71 66 * Kernel counterpart of the driver pushes characters (it has read) here. … … 102 97 return -1; 103 98 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); 108 101 if (rc != 0) { 109 102 printf("Niagara: uspace driver couldn't map physical memory: %d\n", … … 111 104 return rc; 112 105 } 113 114 input_buffer = (input_buffer_t) input_buffer_addr;115 106 116 107 thread_id_t tid; -
uspace/srv/hid/input/port/ns16550.c
r9117ef9b r7943c43 135 135 136 136 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); 138 138 139 139 return pio_enable((void *) ns16550_physical, 8, &vaddr); -
uspace/srv/hid/input/port/pl050.c
r9117ef9b r7943c43 117 117 118 118 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); 120 120 121 121 return 0; -
uspace/srv/hid/input/proto/adb.c
r9117ef9b r7943c43 82 82 83 83 if (dx != 0 || dy != 0) 84 mouse_push_event_move(mouse_dev, dx, dy );84 mouse_push_event_move(mouse_dev, dx, dy, 0); 85 85 } 86 86 -
uspace/srv/hid/input/proto/mousedev.c
r9117ef9b r7943c43 91 91 switch (IPC_GET_IMETHOD(call)) { 92 92 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)); 95 96 retval = EOK; 96 97 break; 97 98 case MOUSEEV_BUTTON_EVENT: 98 mouse_push_event_button(mousedev->mouse_dev, IPC_GET_ARG1(call),99 IPC_GET_ARG 2(call));99 mouse_push_event_button(mousedev->mouse_dev, 100 IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 100 101 retval = EOK; 101 102 break; -
uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
r9117ef9b r7943c43 85 85 86 86 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); 89 90 if (rc < 0) { 90 91 printf(NAME ": Unable to register driver.\n"); … … 139 140 140 141 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); 142 143 143 144 s3c24xx_ts_wait_for_int_mode(ts, updn_down); -
uspace/srv/hw/bus/cuda_adb/cuda_adb.c
r9117ef9b r7943c43 154 154 } 155 155 156 rc = loc_server_register(NAME, cuda_connection); 156 async_set_client_connection(cuda_connection); 157 rc = loc_server_register(NAME); 157 158 if (rc < 0) { 158 159 printf(NAME ": Unable to register server.\n"); … … 275 276 cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_kernel)->ifr; 276 277 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); 278 279 279 280 /* Enable SR interrupt. */ -
uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
r9117ef9b r7943c43 79 79 printf(NAME ": S3C24xx on-chip UART driver\n"); 80 80 81 rc = loc_server_register(NAME, s3c24xx_uart_connection); 81 async_set_client_connection(s3c24xx_uart_connection); 82 rc = loc_server_register(NAME); 82 83 if (rc < 0) { 83 84 printf(NAME ": Unable to register server.\n"); … … 194 195 async_set_interrupt_received(s3c24xx_uart_irq_handler); 195 196 196 register_irq(inr, device_assign_devno(), 0, &uart_irq_code);197 irq_register(inr, device_assign_devno(), 0, &uart_irq_code); 197 198 198 199 /* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */ -
uspace/srv/hw/irc/obio/obio.c
r9117ef9b r7943c43 124 124 125 125 base_phys = (void *) paddr; 126 base_virt = as_get_mappable_page(OBIO_SIZE);127 126 128 127 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); 131 131 132 132 if (retval < 0) { -
uspace/srv/net/nil/eth/eth.c
r9117ef9b r7943c43 802 802 next = tmp; 803 803 } else { 804 nic_send_frame(device->sess, packet_get_data(next), 805 packet_get_data_length(next)); 804 806 next = pq_next(next); 805 807 } 806 808 } while (next); 807 809 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)); 811 811 812 812 fibril_rwlock_read_unlock(ð_globals.devices_lock); -
uspace/srv/net/nil/nildummy/nildummy.c
r9117ef9b r7943c43 345 345 services_t sender) 346 346 { 347 packet_t *p; 348 347 349 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 348 350 … … 354 356 } 355 357 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)); 359 366 360 367 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); -
uspace/srv/net/tl/tcp/conn.c
r9117ef9b r7943c43 56 56 57 57 LIST_INITIALIZE(conn_list); 58 FIBRIL_MUTEX_INITIALIZE(conn_list_lock); 58 59 59 60 static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg); … … 61 62 static void tcp_conn_tw_timer_clear(tcp_conn_t *conn); 62 63 63 /** Create new segmentstructure.64 /** Create new connection structure. 64 65 * 65 66 * @param lsock Local socket (will be deeply copied) 66 67 * @param fsock Foreign socket (will be deeply copied) 67 * @return New segmentor NULL68 * @return New connection or NULL 68 69 */ 69 70 tcp_conn_t *tcp_conn_new(tcp_sock_t *lsock, tcp_sock_t *fsock) … … 81 82 goto error; 82 83 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 83 89 /* Allocate receive buffer */ 84 fibril_mutex_initialize(&conn->rcv_buf_lock);85 90 fibril_condvar_initialize(&conn->rcv_buf_cv); 86 91 conn->rcv_buf_size = RCV_BUF_SIZE; … … 93 98 94 99 /** Allocate send buffer */ 100 fibril_condvar_initialize(&conn->snd_buf_cv); 95 101 conn->snd_buf_size = SND_BUF_SIZE; 96 102 conn->snd_buf_used = 0; … … 113 119 114 120 /* Connection state change signalling */ 115 fibril_mutex_initialize(&conn->cstate_lock);116 121 fibril_condvar_initialize(&conn->cstate_cv); 122 123 conn->cstate_cb = NULL; 117 124 118 125 conn->cstate = st_listen; 119 126 conn->reset = false; 127 conn->deleted = false; 120 128 conn->ap = ap_passive; 121 129 conn->fin_is_acked = false; … … 141 149 } 142 150 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 */ 164 static 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 */ 184 void 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 */ 196 void 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 */ 211 void 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 143 219 /** Enlist connection. 144 220 * … … 147 223 void tcp_conn_add(tcp_conn_t *conn) 148 224 { 225 tcp_conn_addref(conn); 226 fibril_mutex_lock(&conn_list_lock); 149 227 list_append(&conn->link, &conn_list); 228 fibril_mutex_unlock(&conn_list_lock); 150 229 } 151 230 … … 156 235 void tcp_conn_remove(tcp_conn_t *conn) 157 236 { 237 fibril_mutex_lock(&conn_list_lock); 158 238 list_remove(&conn->link); 239 fibril_mutex_unlock(&conn_list_lock); 240 tcp_conn_delref(conn); 159 241 } 160 242 161 243 static void tcp_conn_state_set(tcp_conn_t *conn, tcp_cstate_t nstate) 162 244 { 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; 164 250 conn->cstate = nstate; 165 251 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 } 167 266 } 168 267 … … 251 350 * A connection is uniquely identified by a socket pair. Look up our 252 351 * connection map and return connection structure based on socket pair. 352 * The connection reference count is bumped by one. 253 353 * 254 354 * @param sp Socket pair 255 355 * @return Connection structure or NULL if not found. 256 356 */ 257 tcp_conn_t *tcp_conn_find (tcp_sockpair_t *sp)357 tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp) 258 358 { 259 359 log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp); 360 361 fibril_mutex_lock(&conn_list_lock); 260 362 261 363 list_foreach(conn_list, link) { … … 266 368 csp->local.addr.ipv4, csp->local.port); 267 369 if (tcp_sockpair_match(sp, csp)) { 370 tcp_conn_addref(conn); 371 fibril_mutex_unlock(&conn_list_lock); 268 372 return conn; 269 373 } 270 374 } 271 375 376 fibril_mutex_unlock(&conn_list_lock); 272 377 return NULL; 273 378 } … … 287 392 288 393 fibril_condvar_broadcast(&conn->rcv_buf_cv); 394 fibril_condvar_broadcast(&conn->snd_buf_cv); 289 395 } 290 396 … … 397 503 conn->snd_una, seg->ack, conn->snd_nxt); 398 504 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 } 401 511 return; 402 512 } … … 404 514 405 515 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 } 412 528 } 413 529 … … 858 974 tcp_conn_trim_seg_to_wnd(conn, seg); 859 975 860 fibril_mutex_lock(&conn->rcv_buf_lock);861 862 976 /* Determine how many bytes to copy */ 863 977 text_size = tcp_segment_text_size(seg); … … 871 985 /* Signal to the receive function that new data has arrived */ 872 986 fibril_condvar_broadcast(&conn->rcv_buf_cv); 873 fibril_mutex_unlock(&conn->rcv_buf_lock);874 987 875 988 log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size); … … 961 1074 962 1075 /* Add FIN to the receive buffer */ 963 fibril_mutex_lock(&conn->rcv_buf_lock);964 1076 conn->rcv_buf_fin = true; 965 1077 fibril_condvar_broadcast(&conn->rcv_buf_cv); 966 fibril_mutex_unlock(&conn->rcv_buf_lock);967 1078 968 1079 tcp_segment_delete(seg); … … 1073 1184 log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn); 1074 1185 1186 fibril_mutex_lock(&conn->lock); 1187 1075 1188 if (conn->cstate == st_closed) { 1076 1189 log_msg(LVL_DEBUG, "Connection already closed."); 1190 fibril_mutex_unlock(&conn->lock); 1191 tcp_conn_delref(conn); 1077 1192 return; 1078 1193 } … … 1081 1196 tcp_conn_remove(conn); 1082 1197 tcp_conn_state_set(conn, st_closed); 1198 1199 fibril_mutex_unlock(&conn->lock); 1200 tcp_conn_delref(conn); 1083 1201 } 1084 1202 … … 1089 1207 void tcp_conn_tw_timer_set(tcp_conn_t *conn) 1090 1208 { 1209 tcp_conn_addref(conn); 1091 1210 fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func, 1092 1211 (void *)conn); … … 1099 1218 void tcp_conn_tw_timer_clear(tcp_conn_t *conn) 1100 1219 { 1101 fibril_timer_clear(conn->tw_timer); 1220 if (fibril_timer_clear(conn->tw_timer) == fts_active) 1221 tcp_conn_delref(conn); 1102 1222 } 1103 1223 -
uspace/srv/net/tl/tcp/conn.h
r9117ef9b r7943c43 40 40 41 41 extern tcp_conn_t *tcp_conn_new(tcp_sock_t *, tcp_sock_t *); 42 extern void tcp_conn_delete(tcp_conn_t *); 42 43 extern void tcp_conn_add(tcp_conn_t *); 43 44 extern void tcp_conn_remove(tcp_conn_t *); … … 45 46 extern void tcp_conn_fin_sent(tcp_conn_t *); 46 47 extern void tcp_conn_ack_of_fin_rcvd(tcp_conn_t *); 47 extern tcp_conn_t *tcp_conn_find(tcp_sockpair_t *); 48 extern tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *); 49 extern void tcp_conn_addref(tcp_conn_t *); 50 extern void tcp_conn_delref(tcp_conn_t *); 48 51 extern bool tcp_conn_got_syn(tcp_conn_t *); 49 52 extern void tcp_conn_segment_arrived(tcp_conn_t *, tcp_segment_t *); -
uspace/srv/net/tl/tcp/segment.c
r9117ef9b r7943c43 119 119 return NULL; 120 120 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 } 123 129 124 130 return rseg; -
uspace/srv/net/tl/tcp/sock.c
r9117ef9b r7943c43 52 52 #define FRAGMENT_SIZE 1024 53 53 54 #define MAX_BACKLOG 128 55 54 56 /** Free ports pool start. */ 55 57 #define TCP_FREE_PORTS_START 1025 … … 60 62 static int last_used_port = TCP_FREE_PORTS_START - 1; 61 63 static socket_ports_t gsock; 64 65 static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg); 62 66 63 67 void tcp_sock_init(void) … … 95 99 { 96 100 tcp_sockdata_t *sock; 101 socket_core_t *sock_core; 97 102 int sock_id; 98 103 int rc; … … 106 111 } 107 112 113 fibril_mutex_initialize(&sock->lock); 108 114 sock->client = client; 109 115 sock->laddr.ipv4 = TCP_IPV4_ANY; 116 sock->lconn = NULL; 117 sock->backlog = 0; 118 list_initialize(&sock->ready); 110 119 111 120 sock_id = SOCKET_GET_SOCKET_ID(call); … … 115 124 return; 116 125 } 126 127 sock_core = socket_cores_find(&client->sockets, sock_id); 128 assert(sock_core != NULL); 129 sock->sock_core = sock_core; 117 130 118 131 refresh_answer(&answer, NULL); … … 167 180 socket_core_t *sock_core; 168 181 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; 169 188 170 189 log_msg(LVL_DEBUG, "tcp_sock_listen()"); … … 177 196 return; 178 197 } 198 199 if (backlog > MAX_BACKLOG) 200 backlog = MAX_BACKLOG; 179 201 180 202 sock_core = socket_cores_find(&client->sockets, socket_id); … … 187 209 188 210 /* 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. 196 212 */ 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); 200 261 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);204 262 } 205 263 … … 248 306 } 249 307 308 fibril_mutex_lock(&socket->lock); 309 250 310 if (socket->laddr.ipv4 == TCP_IPV4_ANY) { 251 311 /* Find route to determine local IP address. */ … … 254 314 (void **)&phdr, &phdr_len); 255 315 if (rc != EOK) { 316 fibril_mutex_unlock(&socket->lock); 256 317 async_answer_0(callid, rc); 257 318 log_msg(LVL_DEBUG, "tcp_transmit_connect: Failed to find route."); … … 269 330 fsocket.port = uint16_t_be2host(addr->sin_port); 270 331 271 trc = tcp_uc_open(&lsocket, &fsocket, ap_active, &socket->conn);332 trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, &socket->conn); 272 333 273 334 if (socket->conn != NULL) 274 335 socket->conn->name = (char *)"C"; 336 337 fibril_mutex_unlock(&socket->lock); 275 338 276 339 switch (trc) { … … 305 368 tcp_sock_t fsocket; 306 369 tcp_conn_t *conn; 370 tcp_conn_t *rconn; 371 tcp_sock_lconn_t *lconn; 307 372 int rc; 308 373 … … 319 384 320 385 socket = (tcp_sockdata_t *)sock_core->specific_data; 386 fibril_mutex_lock(&socket->lock); 321 387 322 388 log_msg(LVL_DEBUG, " - verify socket->conn"); 323 389 if (socket->conn != NULL) { 390 fibril_mutex_unlock(&socket->lock); 324 391 async_answer_0(callid, EINVAL); 325 392 return; 326 393 } 327 394 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 */ 329 409 330 410 lsocket.addr.ipv4 = TCP_IPV4_ANY; … … 333 413 fsocket.port = TCP_PORT_ANY; 334 414 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 */ 357 432 358 433 log_msg(LVL_DEBUG, "tcp_sock_accept(): allocate asocket\n"); 359 434 asocket = calloc(sizeof(tcp_sockdata_t), 1); 360 435 if (asocket == NULL) { 436 fibril_mutex_unlock(&socket->lock); 361 437 async_answer_0(callid, ENOMEM); 362 438 return; 363 439 } 364 440 441 fibril_mutex_initialize(&asocket->lock); 365 442 asocket->client = client; 366 443 asocket->conn = conn; … … 369 446 rc = socket_create(&client->sockets, client->sess, asocket, &asock_id); 370 447 if (rc != EOK) { 448 fibril_mutex_unlock(&socket->lock); 371 449 async_answer_0(callid, rc); 372 450 return; … … 385 463 answer_call(callid, asock_core->socket_id, &answer, 3); 386 464 387 /* Push one accept notification to client's queue */388 tcp_sock_notify_aconn(sock_core);389 390 465 /* Push one fragment notification to client's queue */ 466 log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n"); 391 467 tcp_sock_notify_data(asock_core); 392 log_msg(LVL_DEBUG, "tcp_sock_accept(): notify aconn\n");468 fibril_mutex_unlock(&socket->lock); 393 469 } 394 470 … … 419 495 420 496 socket = (tcp_sockdata_t *)sock_core->specific_data; 497 fibril_mutex_lock(&socket->lock); 498 421 499 if (socket->conn == NULL) { 500 fibril_mutex_unlock(&socket->lock); 422 501 async_answer_0(callid, ENOTCONN); 423 502 return; … … 426 505 for (index = 0; index < fragments; index++) { 427 506 if (!async_data_write_receive(&wcallid, &length)) { 507 fibril_mutex_unlock(&socket->lock); 428 508 async_answer_0(callid, EINVAL); 429 509 return; … … 435 515 rc = async_data_write_finalize(wcallid, buffer, length); 436 516 if (rc != EOK) { 517 fibril_mutex_unlock(&socket->lock); 437 518 async_answer_0(callid, rc); 438 519 return; … … 459 540 460 541 if (rc != EOK) { 542 fibril_mutex_unlock(&socket->lock); 461 543 async_answer_0(callid, rc); 462 544 return; … … 467 549 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 468 550 answer_call(callid, EOK, &answer, 2); 551 fibril_mutex_unlock(&socket->lock); 469 552 } 470 553 … … 504 587 505 588 socket = (tcp_sockdata_t *)sock_core->specific_data; 589 fibril_mutex_lock(&socket->lock); 590 506 591 if (socket->conn == NULL) { 592 fibril_mutex_unlock(&socket->lock); 507 593 async_answer_0(callid, ENOTCONN); 508 594 return; … … 532 618 log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc); 533 619 if (rc != EOK) { 620 fibril_mutex_unlock(&socket->lock); 534 621 async_answer_0(callid, rc); 535 622 return; … … 545 632 log_msg(LVL_DEBUG, "addr read receive"); 546 633 if (!async_data_read_receive(&rcallid, &addr_length)) { 634 fibril_mutex_unlock(&socket->lock); 547 635 async_answer_0(callid, EINVAL); 548 636 return; … … 555 643 rc = async_data_read_finalize(rcallid, &addr, addr_length); 556 644 if (rc != EOK) { 645 fibril_mutex_unlock(&socket->lock); 557 646 async_answer_0(callid, EINVAL); 558 647 return; … … 562 651 log_msg(LVL_DEBUG, "data read receive"); 563 652 if (!async_data_read_receive(&rcallid, &length)) { 653 fibril_mutex_unlock(&socket->lock); 564 654 async_answer_0(callid, EINVAL); 565 655 return; … … 580 670 /* Push one fragment notification to client's queue */ 581 671 tcp_sock_notify_data(sock_core); 672 fibril_mutex_unlock(&socket->lock); 582 673 } 583 674 … … 603 694 604 695 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 } 616 714 617 715 rc = socket_destroy(net_sess, socket_id, &client->sockets, &gsock, 618 716 tcp_free_sock_data); 619 717 if (rc != EOK) { 718 fibril_mutex_unlock(&socket->lock); 620 719 async_answer_0(callid, rc); 621 720 return; 622 721 } 623 722 723 fibril_mutex_unlock(&socket->lock); 624 724 async_answer_0(callid, EOK); 625 725 } … … 635 735 log_msg(LVL_DEBUG, "tcp_sock_setsockopt()"); 636 736 async_answer_0(callid, ENOTSUP); 737 } 738 739 /** Called when connection state changes. */ 740 static 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); 637 764 } 638 765 -
uspace/srv/net/tl/tcp/tcp.c
r9117ef9b r7943c43 36 36 37 37 #include <async.h> 38 #include <bitops.h> 38 39 #include <byteorder.h> 39 40 #include <errno.h> … … 191 192 tcp_pdu_t *pdu; 192 193 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; 196 209 197 210 if (pdu_raw_size < hdr_size) { 198 211 log_msg(LVL_WARN, "pdu_raw_size = %zu < hdr_size = %zu", 199 212 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)); 200 220 pq_release_remote(net_sess, packet_get_id(packet)); 201 221 return EINVAL; -
uspace/srv/net/tl/tcp/tcp_type.h
r9117ef9b r7943c43 152 152 } acpass_t; 153 153 154 typedef struct tcp_conn { 154 typedef enum { 155 tcp_open_nonblock = 1 156 } tcp_open_flags_t; 157 158 typedef struct tcp_conn tcp_conn_t; 159 160 /** Connection state change callback function */ 161 typedef void (*tcp_cstate_cb_t)(tcp_conn_t *, void *); 162 163 /** Connection */ 164 struct tcp_conn { 155 165 char *name; 156 166 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; 157 172 158 173 /** Connection identification (local and foreign socket) */ … … 161 176 /** Active or passive connection */ 162 177 acpass_t ap; 178 179 /** Protects access to connection structure */ 180 fibril_mutex_t lock; 181 /** Reference count */ 182 atomic_t refcnt; 163 183 164 184 /** Connection state */ … … 166 186 /** True if connection was reset */ 167 187 bool reset; 168 /** Protects @c cstate*/169 fibril_mutex_t cstate_lock;188 /** True if connection was deleted by user */ 189 bool deleted; 170 190 /** Signalled when @c cstate changes */ 171 191 fibril_condvar_t cstate_cv; … … 191 211 /** Receive buffer contains FIN */ 192 212 bool rcv_buf_fin; 193 /** Receive buffer lock */194 fibril_mutex_t rcv_buf_lock;195 213 /** Receive buffer CV. Broadcast when new data is inserted */ 196 214 fibril_condvar_t rcv_buf_cv; … … 204 222 /** Send buffer contains FIN */ 205 223 bool snd_buf_fin; 224 /** Send buffer CV. Broadcast when space is made available in buffer */ 225 fibril_condvar_t snd_buf_cv; 206 226 207 227 /** Send unacknowledged */ … … 228 248 /** Initial receive sequence number */ 229 249 uint32_t irs; 230 } tcp_conn_t; 231 232 typedef struct { 233 unsigned dummy; 250 }; 251 252 /** Data returned by Status user call */ 253 typedef struct { 254 /** Connection state */ 255 tcp_cstate_t cstate; 234 256 } tcp_conn_status_t; 235 257 … … 309 331 } tcp_client_t; 310 332 311 typedef struct { 333 typedef struct tcp_sockdata { 334 /** Lock */ 335 fibril_mutex_t lock; 336 /** Socket core */ 337 socket_core_t *sock_core; 312 338 /** Client */ 313 339 tcp_client_t *client; … … 316 342 /** Local address */ 317 343 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; 318 350 } tcp_sockdata_t; 351 352 typedef 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 319 359 320 360 #endif -
uspace/srv/net/tl/tcp/test.c
r9117ef9b r7943c43 62 62 fsock.addr.ipv4 = 0x7f000001; 63 63 printf("S: User open...\n"); 64 tcp_uc_open(&lsock, &fsock, ap_passive, &conn);64 tcp_uc_open(&lsock, &fsock, ap_passive, 0, &conn); 65 65 conn->name = (char *) "S"; 66 66 … … 102 102 async_usleep(1000*1000*3); 103 103 printf("C: User open...\n"); 104 tcp_uc_open(&lsock, &fsock, ap_active, &conn);104 tcp_uc_open(&lsock, &fsock, ap_active, 0, &conn); 105 105 conn->name = (char *) "C"; 106 106 -
uspace/srv/net/tl/tcp/tqueue.c
r9117ef9b r7943c43 188 188 /* We are sending out FIN */ 189 189 ctrl = CTL_FIN; 190 tcp_conn_fin_sent(conn);191 190 } else { 192 191 ctrl = 0; … … 206 205 if (send_fin) 207 206 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); 208 212 209 213 tcp_tqueue_seg(conn, seg); … … 313 317 log_msg(LVL_DEBUG, "### %s: retransmit_timeout_func(%p)", conn->name, conn); 314 318 319 fibril_mutex_lock(&conn->lock); 320 315 321 if (conn->cstate == st_closed) { 316 322 log_msg(LVL_DEBUG, "Connection already closed."); 323 fibril_mutex_unlock(&conn->lock); 324 tcp_conn_delref(conn); 317 325 return; 318 326 } … … 321 329 if (link == NULL) { 322 330 log_msg(LVL_DEBUG, "Nothing to retransmit"); 331 fibril_mutex_unlock(&conn->lock); 332 tcp_conn_delref(conn); 323 333 return; 324 334 } … … 329 339 if (rt_seg == NULL) { 330 340 log_msg(LVL_ERROR, "Memory allocation failed."); 341 fibril_mutex_unlock(&conn->lock); 342 tcp_conn_delref(conn); 331 343 /* XXX Handle properly */ 332 344 return; … … 338 350 /* Reset retransmission timer */ 339 351 tcp_tqueue_timer_set(tqe->conn); 352 353 fibril_mutex_unlock(&conn->lock); 354 tcp_conn_delref(conn); 340 355 } 341 356 … … 345 360 log_msg(LVL_DEBUG, "### %s: tcp_tqueue_timer_set()", conn->name); 346 361 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); 348 366 fibril_timer_set(conn->retransmit.timer, RETRANSMIT_TIMEOUT, 349 367 retransmit_timeout_func, (void *) conn); … … 355 373 log_msg(LVL_DEBUG, "### %s: tcp_tqueue_timer_clear()", conn->name); 356 374 357 fibril_timer_clear(conn->retransmit.timer); 375 if (fibril_timer_clear(conn->retransmit.timer) == fts_active) 376 tcp_conn_delref(conn); 358 377 } 359 378 -
uspace/srv/net/tl/tcp/ucall.c
r9117ef9b r7943c43 53 53 * @param fsock Foreign socket 54 54 * @param acpass Active/passive 55 * @param oflags Open flags 55 56 * @param conn Connection 56 57 * … … 65 66 */ 66 67 tcp_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) 68 69 { 69 70 tcp_conn_t *nconn; 70 71 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)", 72 73 lsock, fsock, acpass == ap_active ? "active" : "passive", 73 conn);74 oflags == tcp_open_nonblock ? "nonblock" : "none", conn); 74 75 75 76 nconn = tcp_conn_new(lsock, fsock); … … 81 82 } 82 83 84 if (oflags == tcp_open_nonblock) { 85 *conn = nconn; 86 return TCP_EOK; 87 } 88 83 89 /* Wait for connection to be established or reset */ 84 90 log_msg(LVL_DEBUG, "tcp_uc_open: Wait for connection."); 85 fibril_mutex_lock(&nconn-> cstate_lock);91 fibril_mutex_lock(&nconn->lock); 86 92 while (nconn->cstate == st_listen || 87 93 nconn->cstate == st_syn_sent || 88 94 nconn->cstate == st_syn_received) { 89 fibril_condvar_wait(&nconn->cstate_cv, &nconn-> cstate_lock);95 fibril_condvar_wait(&nconn->cstate_cv, &nconn->lock); 90 96 } 91 97 … … 93 99 log_msg(LVL_DEBUG, "tcp_uc_open: Connection was reset."); 94 100 assert(nconn->cstate == st_closed); 95 fibril_mutex_unlock(&nconn-> cstate_lock);101 fibril_mutex_unlock(&nconn->lock); 96 102 return TCP_ERESET; 97 103 } 98 104 99 fibril_mutex_unlock(&nconn-> cstate_lock);105 fibril_mutex_unlock(&nconn->lock); 100 106 log_msg(LVL_DEBUG, "tcp_uc_open: Connection was established."); 101 107 102 108 *conn = nconn; 109 log_msg(LVL_DEBUG, "tcp_uc_open -> %p", nconn); 103 110 return TCP_EOK; 104 111 } … … 113 120 log_msg(LVL_DEBUG, "%s: tcp_uc_send()", conn->name); 114 121 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); 116 126 return TCP_ENOTEXIST; 127 } 117 128 118 129 if (conn->cstate == st_listen) { … … 121 132 } 122 133 123 if (conn->snd_buf_fin) 134 135 if (conn->snd_buf_fin) { 136 fibril_mutex_unlock(&conn->lock); 124 137 return TCP_ECLOSING; 138 } 125 139 126 140 while (size > 0) { 127 141 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); 132 151 return TCP_ERESET; 152 } 133 153 134 154 xfer_size = min(size, buf_free); … … 139 159 conn->snd_buf_used += xfer_size; 140 160 size -= xfer_size; 161 162 tcp_tqueue_new_data(conn); 141 163 } 142 164 143 165 tcp_tqueue_new_data(conn); 166 fibril_mutex_unlock(&conn->lock); 144 167 145 168 return TCP_EOK; … … 154 177 log_msg(LVL_DEBUG, "%s: tcp_uc_receive()", conn->name); 155 178 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); 157 183 return TCP_ENOTEXIST; 158 159 fibril_mutex_lock(&conn->rcv_buf_lock); 184 } 160 185 161 186 /* Wait for data to become available */ 162 187 while (conn->rcv_buf_used == 0 && !conn->rcv_buf_fin && !conn->reset) { 163 188 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); 165 190 } 166 191 167 192 if (conn->rcv_buf_used == 0) { 168 fibril_mutex_unlock(&conn->rcv_buf_lock);169 170 193 *rcvd = 0; 171 194 *xflags = 0; … … 173 196 if (conn->rcv_buf_fin) { 174 197 /* End of data, peer closed connection */ 198 fibril_mutex_unlock(&conn->lock); 175 199 return TCP_ECLOSING; 176 200 } else { 177 201 /* Connection was reset */ 178 202 assert(conn->reset); 203 fibril_mutex_unlock(&conn->lock); 179 204 return TCP_ERESET; 180 205 } … … 192 217 conn->rcv_wnd += xfer_size; 193 218 194 fibril_mutex_unlock(&conn->rcv_buf_lock);195 196 219 /* TODO */ 197 220 *xflags = 0; … … 203 226 conn->name, xfer_size); 204 227 228 fibril_mutex_unlock(&conn->lock); 229 205 230 return TCP_EOK; 206 231 } … … 211 236 log_msg(LVL_DEBUG, "%s: tcp_uc_close()", conn->name); 212 237 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); 214 242 return TCP_ENOTEXIST; 215 216 if (conn->snd_buf_fin) 243 } 244 245 if (conn->snd_buf_fin) { 246 fibril_mutex_unlock(&conn->lock); 217 247 return TCP_ECLOSING; 248 } 218 249 219 250 conn->snd_buf_fin = true; 220 251 tcp_tqueue_new_data(conn); 221 252 253 fibril_mutex_unlock(&conn->lock); 222 254 return TCP_EOK; 223 255 } … … 233 265 { 234 266 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 */ 276 void tcp_uc_delete(tcp_conn_t *conn) 277 { 278 log_msg(LVL_DEBUG, "tcp_uc_delete()"); 279 tcp_conn_delete(conn); 280 } 281 282 void 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 } 237 290 238 291 /* … … 249 302 sp->local.addr.ipv4, sp->local.port); 250 303 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."); 266 307 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); 268 332 } 269 333 -
uspace/srv/net/tl/tcp/ucall.h
r9117ef9b r7943c43 42 42 * User calls 43 43 */ 44 extern tcp_error_t tcp_uc_open(tcp_sock_t *, tcp_sock_t *, acpass_t, tcp_conn_t **); 44 extern tcp_error_t tcp_uc_open(tcp_sock_t *, tcp_sock_t *, acpass_t, 45 tcp_open_flags_t, tcp_conn_t **); 45 46 extern tcp_error_t tcp_uc_send(tcp_conn_t *, void *, size_t, xflags_t); 46 47 extern tcp_error_t tcp_uc_receive(tcp_conn_t *, void *, size_t, size_t *, xflags_t *); … … 48 49 extern void tcp_uc_abort(tcp_conn_t *); 49 50 extern void tcp_uc_status(tcp_conn_t *, tcp_conn_status_t *); 51 extern void tcp_uc_delete(tcp_conn_t *); 52 extern void tcp_uc_set_cstate_cb(tcp_conn_t *, tcp_cstate_cb_t, void *); 50 53 51 54 /* -
uspace/srv/vfs/vfs.c
r9117ef9b r7943c43 172 172 * Allocate and initialize the Path Lookup Buffer. 173 173 */ 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) { 182 177 printf(NAME ": Cannot create address space area\n"); 183 178 return ENOMEM;
Note:
See TracChangeset
for help on using the changeset viewer.