Changeset a35b458 in mainline for uspace/drv/char/ns8250
- Timestamp:
- 2018-03-02T20:10:49Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- uspace/drv/char/ns8250
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/ns8250/cyclic_buffer.h
r3061bc1 ra35b458 65 65 { 66 66 assert(!buf_is_empty(buf)); 67 67 68 68 uint8_t res = buf->buf[buf->start]; 69 69 buf->start = (buf->start + 1) % BUF_LEN; -
uspace/drv/char/ns8250/ns8250.c
r3061bc1 ra35b458 238 238 while (!is_transmit_empty(regs)) 239 239 ; 240 240 241 241 pio_write_8(®s->data, c); 242 242 } … … 256 256 char *bp = (char *) buf; 257 257 size_t pos = 0; 258 258 259 259 if (count == 0) { 260 260 *nread = 0; 261 261 return EOK; 262 262 } 263 263 264 264 fibril_mutex_lock(&ns->mutex); 265 265 while (buf_is_empty(&ns->input_buffer)) … … 270 270 } 271 271 fibril_mutex_unlock(&ns->mutex); 272 272 273 273 *nread = pos; 274 274 return EOK; … … 301 301 size_t idx; 302 302 uint8_t *bp = (uint8_t *) buf; 303 303 304 304 for (idx = 0; idx < count; idx++) 305 305 ns8250_putchar(ns, bp[idx]); 306 306 307 307 *nwritten = count; 308 308 return EOK; … … 355 355 { 356 356 ddf_msg(LVL_DEBUG, "ns8250_pio_enable %s", ddf_dev_get_name(ns->dev)); 357 357 358 358 /* Gain control over port's registers. */ 359 359 if (pio_enable((void *) ns->io_addr, REG_COUNT, … … 365 365 366 366 ns->regs = (ns8250_regs_t *)ns->port; 367 367 368 368 return true; 369 369 } … … 377 377 { 378 378 ddf_msg(LVL_DEBUG, "ns8250_dev_probe %s", ddf_dev_get_name(ns->dev)); 379 379 380 380 bool res = true; 381 381 uint8_t olddata; 382 382 383 383 olddata = pio_read_8(&ns->regs->mcr); 384 384 385 385 pio_write_8(&ns->regs->mcr, NS8250_MCR_LOOPBACK); 386 386 if (pio_read_8(&ns->regs->msr) & NS8250_MSR_SIGNALS) 387 387 res = false; 388 388 389 389 pio_write_8(&ns->regs->mcr, NS8250_MCR_ALL); 390 390 if ((pio_read_8(&ns->regs->msr) & NS8250_MSR_SIGNALS) 391 391 != NS8250_MSR_SIGNALS) 392 392 res = false; 393 393 394 394 pio_write_8(&ns->regs->mcr, olddata); 395 395 396 396 if (!res) { 397 397 ddf_msg(LVL_DEBUG, "Device %s is not present.", 398 398 ddf_dev_get_name(ns->dev)); 399 399 } 400 400 401 401 return res; 402 402 } … … 410 410 { 411 411 errno_t ret = EOK; 412 412 413 413 ddf_msg(LVL_DEBUG, "ns8250_dev_initialize %s", ddf_dev_get_name(ns->dev)); 414 414 415 415 hw_resource_list_t hw_resources; 416 416 memset(&hw_resources, 0, sizeof(hw_resource_list_t)); 417 417 418 418 /* Get hw resources. */ 419 419 ret = hw_res_get_resource_list(ns->parent_sess, &hw_resources); … … 423 423 goto failed; 424 424 } 425 425 426 426 size_t i; 427 427 hw_resource_t *res; 428 428 bool irq = false; 429 429 bool ioport = false; 430 430 431 431 for (i = 0; i < hw_resources.count; i++) { 432 432 res = &hw_resources.resources[i]; … … 438 438 ddf_dev_get_name(ns->dev), ns->irq); 439 439 break; 440 440 441 441 case IO_RANGE: 442 442 ns->io_addr = res->res.io_range.address; … … 451 451 "0x%#" PRIxn ".", ddf_dev_get_name(ns->dev), ns->io_addr); 452 452 break; 453 453 454 454 default: 455 455 break; 456 456 } 457 457 } 458 458 459 459 if (!irq || !ioport) { 460 460 ddf_msg(LVL_ERROR, "Missing HW resource(s) for device %s.", … … 463 463 goto failed; 464 464 } 465 465 466 466 hw_res_clean_resource_list(&hw_resources); 467 467 return ret; 468 468 469 469 failed: 470 470 ns8250_dev_cleanup(ns); … … 507 507 if (rc != EOK) 508 508 return EIO; 509 509 510 510 /* Read LSR to clear possible previous LSR interrupt */ 511 511 pio_read_8(&ns->regs->lsr); 512 512 513 513 /* Enable interrupt on the serial port. */ 514 514 ns8250_port_interrupts_enable(ns->regs); 515 515 516 516 return EOK; 517 517 } … … 551 551 uint16_t divisor; 552 552 uint8_t div_low, div_high; 553 553 554 554 if (baud_rate < 50 || MAX_BAUD_RATE % baud_rate != 0) { 555 555 ddf_msg(LVL_ERROR, "Invalid baud rate %d requested.", … … 557 557 return EINVAL; 558 558 } 559 559 560 560 divisor = MAX_BAUD_RATE / baud_rate; 561 561 div_low = (uint8_t)divisor; 562 562 div_high = (uint8_t)(divisor >> 8); 563 563 564 564 /* Enable DLAB to be able to access baud rate divisor. */ 565 565 enable_dlab(regs); 566 566 567 567 /* Set divisor low byte. */ 568 568 pio_write_8(®s->data, div_low); 569 569 /* Set divisor high byte. */ 570 570 pio_write_8(®s->ier, div_high); 571 571 572 572 clear_dlab(regs); 573 573 574 574 return EOK; 575 575 } … … 584 584 uint16_t divisor; 585 585 uint8_t div_low, div_high; 586 586 587 587 /* Enable DLAB to be able to access baud rate divisor. */ 588 588 enable_dlab(regs); 589 589 590 590 /* Get divisor low byte. */ 591 591 div_low = pio_read_8(®s->data); 592 592 /* Get divisor high byte. */ 593 593 div_high = pio_read_8(®s->ier); 594 594 595 595 clear_dlab(regs); 596 596 597 597 divisor = (div_high << 8) | div_low; 598 598 return MAX_BAUD_RATE / divisor; … … 610 610 { 611 611 uint8_t val; 612 612 613 613 val = pio_read_8(®s->lcr); 614 614 *parity = ((val >> NS8250_LCR_PARITY) & 7); 615 615 616 616 /* Silence warnings */ 617 617 *word_length = 0; … … 631 631 break; 632 632 } 633 633 634 634 if ((val >> NS8250_LCR_STOPBITS) & 1) 635 635 *stop_bits = 2; … … 650 650 { 651 651 uint8_t val; 652 652 653 653 switch (word_length) { 654 654 case 5: … … 667 667 return EINVAL; 668 668 } 669 669 670 670 switch (stop_bits) { 671 671 case 1: … … 678 678 return EINVAL; 679 679 } 680 680 681 681 switch (parity) { 682 682 case SERIAL_NO_PARITY: … … 690 690 return EINVAL; 691 691 } 692 692 693 693 pio_write_8(®s->lcr, val); 694 694 695 695 return EOK; 696 696 } … … 748 748 ns8250_regs_t *regs = ns->regs; 749 749 bool cont = true; 750 750 751 751 fibril_mutex_lock(&ns->mutex); 752 752 while (cont) { … … 754 754 if (cont) { 755 755 uint8_t val = ns8250_read_8(regs); 756 756 757 757 if (ns->client_connections > 0) { 758 758 bool buf_was_empty = buf_is_empty(&ns->input_buffer); … … 794 794 } 795 795 } 796 796 797 797 ns8250_read_from_device(ns); 798 798 hw_res_clear_interrupt(ns->parent_sess, ns->irq); … … 832 832 bool need_unreg_intr_handler = false; 833 833 errno_t rc; 834 834 835 835 ddf_msg(LVL_DEBUG, "ns8250_dev_add %s (handle = %d)", 836 836 ddf_dev_get_name(dev), (int) ddf_dev_get_handle(dev)); 837 837 838 838 /* Allocate soft-state for the device */ 839 839 ns = ddf_dev_data_alloc(dev, sizeof(ns8250_t)); … … 842 842 goto fail; 843 843 } 844 844 845 845 fibril_mutex_initialize(&ns->mutex); 846 846 fibril_condvar_initialize(&ns->input_buffer_available); 847 847 ns->dev = dev; 848 848 849 849 ns->parent_sess = ddf_dev_parent_sess_get(ns->dev); 850 850 if (ns->parent_sess == NULL) { … … 854 854 goto fail; 855 855 } 856 856 857 857 rc = ns8250_dev_initialize(ns); 858 858 if (rc != EOK) 859 859 goto fail; 860 860 861 861 need_cleanup = true; 862 862 863 863 if (!ns8250_pio_enable(ns)) { 864 864 rc = EADDRNOTAVAIL; 865 865 goto fail; 866 866 } 867 867 868 868 /* Find out whether the device is present. */ 869 869 if (!ns8250_dev_probe(ns)) { … … 871 871 goto fail; 872 872 } 873 873 874 874 /* Serial port initialization (baud rate etc.). */ 875 875 ns8250_initialize_port(ns); 876 876 877 877 /* Register interrupt handler. */ 878 878 rc = ns8250_register_interrupt_handler(ns, &ns->irq_cap); … … 891 891 goto fail; 892 892 } 893 893 894 894 fun = ddf_fun_create(dev, fun_exposed, "a"); 895 895 if (fun == NULL) { … … 897 897 goto fail; 898 898 } 899 899 900 900 ddf_fun_set_conn_handler(fun, ns8250_char_conn); 901 901 902 902 chardev_srvs_init(&ns->cds); 903 903 ns->cds.ops = &ns8250_chardev_ops; 904 904 ns->cds.sarg = ns; 905 905 906 906 rc = ddf_fun_bind(fun); 907 907 if (rc != EOK) { … … 911 911 912 912 ns->fun = fun; 913 913 914 914 ddf_fun_add_to_category(fun, "serial"); 915 915 916 916 ddf_msg(LVL_NOTE, "Device %s successfully initialized.", 917 917 ddf_dev_get_name(dev)); 918 918 919 919 return EOK; 920 920 fail: … … 932 932 ns8250_t *ns = dev_ns8250(dev); 933 933 errno_t rc; 934 934 935 935 fibril_mutex_lock(&ns->mutex); 936 936 if (ns->client_connections > 0) { … … 940 940 ns->removed = true; 941 941 fibril_mutex_unlock(&ns->mutex); 942 942 943 943 rc = ddf_fun_unbind(ns->fun); 944 944 if (rc != EOK) { … … 946 946 return rc; 947 947 } 948 948 949 949 ddf_fun_destroy(ns->fun); 950 950 951 951 ns8250_port_cleanup(ns); 952 952 ns8250_unregister_interrupt_handler(ns); … … 967 967 ns8250_t *ns = srv_ns8250(srv); 968 968 errno_t res; 969 969 970 970 fibril_mutex_lock(&ns->mutex); 971 971 if (ns->removed) { … … 976 976 } 977 977 fibril_mutex_unlock(&ns->mutex); 978 978 979 979 return res; 980 980 } … … 990 990 { 991 991 ns8250_t *data = srv_ns8250(srv); 992 992 993 993 fibril_mutex_lock(&data->mutex); 994 994 995 995 assert(data->client_connections > 0); 996 996 997 997 if (!(--data->client_connections)) 998 998 buf_clear(&data->input_buffer); 999 999 1000 1000 fibril_mutex_unlock(&data->mutex); 1001 1001 1002 1002 return EOK; 1003 1003 } … … 1018 1018 ns8250_t *data = dev_ns8250(dev); 1019 1019 ns8250_regs_t *regs = data->regs; 1020 1020 1021 1021 fibril_mutex_lock(&data->mutex); 1022 1022 ns8250_port_interrupts_disable(regs); … … 1025 1025 ns8250_port_interrupts_enable(regs); 1026 1026 fibril_mutex_unlock(&data->mutex); 1027 1027 1028 1028 ddf_msg(LVL_DEBUG, "ns8250_get_props: baud rate %d, parity 0x%x, word " 1029 1029 "length %d, stop bits %d", *baud_rate, *parity, *word_length, … … 1046 1046 "length %d, stop bits %d", baud_rate, parity, word_length, 1047 1047 stop_bits); 1048 1048 1049 1049 ns8250_t *data = dev_ns8250(dev); 1050 1050 ns8250_regs_t *regs = data->regs; 1051 1051 errno_t ret; 1052 1052 1053 1053 fibril_mutex_lock(&data->mutex); 1054 1054 ns8250_port_interrupts_disable(regs); … … 1058 1058 ns8250_port_interrupts_enable(regs); 1059 1059 fibril_mutex_unlock(&data->mutex); 1060 1060 1061 1061 return ret; 1062 1062 } … … 1074 1074 errno_t ret; 1075 1075 unsigned int baud_rate, parity, word_length, stop_bits; 1076 1076 1077 1077 switch (method) { 1078 1078 case SERIAL_GET_COM_PROPS: … … 1082 1082 stop_bits); 1083 1083 break; 1084 1084 1085 1085 case SERIAL_SET_COM_PROPS: 1086 1086 baud_rate = IPC_GET_ARG1(*call); … … 1092 1092 async_answer_0(callid, ret); 1093 1093 break; 1094 1094 1095 1095 default: 1096 1096 async_answer_0(callid, ENOTSUP);
Note:
See TracChangeset
for help on using the changeset viewer.