Changes in uspace/drv/char/ns8250/ns8250.c [1dc4a5e:128c78b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/ns8250/ns8250.c
r1dc4a5e r128c78b 59 59 60 60 #include <devman.h> 61 #include <ns.h> 61 62 #include <ipc/devman.h> 63 #include <ipc/services.h> 64 #include <ipc/irc.h> 62 65 #include <device/hw_res.h> 63 66 #include <ipc/serial_ctl.h> … … 111 114 /** The fibril mutex for synchronizing the access to the device. */ 112 115 fibril_mutex_t mutex; 116 /** True if device is removed. */ 117 bool removed; 113 118 } ns8250_t; 114 115 /** Create per-device soft-state structure.116 *117 * @return Pointer to soft-state structure.118 */119 static ns8250_t *ns8250_new(void)120 {121 ns8250_t *ns;122 123 ns = (ns8250_t *) calloc(1, sizeof(ns8250_t));124 if (ns == NULL)125 return NULL;126 127 fibril_mutex_initialize(&ns->mutex);128 return ns;129 }130 131 /** Delete soft-state structure.132 *133 * @param ns The driver data structure.134 */135 static void ns8250_delete(ns8250_t *ns)136 {137 assert(ns != NULL);138 free(ns);139 }140 119 141 120 /** Find out if there is some incomming data available on the serial port. … … 245 224 246 225 static int ns8250_add_device(ddf_dev_t *dev); 226 static int ns8250_dev_remove(ddf_dev_t *dev); 247 227 248 228 /** The serial port device driver's standard operations. */ 249 229 static driver_ops_t ns8250_ops = { 250 .add_device = &ns8250_add_device 230 .add_device = &ns8250_add_device, 231 .dev_remove = &ns8250_dev_remove 251 232 }; 252 233 … … 431 412 static int ns8250_interrupt_enable(ns8250_t *ns) 432 413 { 414 /* 415 * Enable interrupt using IRC service. 416 * TODO: This is a temporary solution until the device framework 417 * takes care of this itself. 418 */ 419 async_sess_t *irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 420 SERVICE_IRC, 0, 0); 421 if (!irc_sess) { 422 return EIO; 423 } 424 425 async_exch_t *exch = async_exchange_begin(irc_sess); 426 if (!exch) { 427 return EIO; 428 } 429 async_msg_1(exch, IRC_ENABLE_INTERRUPT, ns->irq); 430 async_exchange_end(exch); 431 433 432 /* Enable interrupt on the serial port. */ 434 433 ns8250_port_interrupts_enable(ns->port); … … 636 635 */ 637 636 pio_write_8(port + 4, 0x0B); 637 } 638 639 /** Deinitialize the serial port device. 640 * 641 * @param ns Serial port device 642 */ 643 static void ns8250_port_cleanup(ns8250_t *ns) 644 { 645 /* Disable FIFO */ 646 pio_write_8(ns->port + 2, 0x00); 647 /* Disable DTR, RTS, OUT1, OUT2 (int. enable) */ 648 pio_write_8(ns->port + 4, 0x00); 649 /* Disable all interrupts from the port */ 650 ns8250_port_interrupts_disable(ns->port); 638 651 } 639 652 … … 721 734 722 735 /* Allocate soft-state for the device */ 723 ns = ns8250_new();736 ns = ddf_dev_data_alloc(dev, sizeof(ns8250_t)); 724 737 if (ns == NULL) { 725 738 rc = ENOMEM; … … 727 740 } 728 741 742 fibril_mutex_initialize(&ns->mutex); 729 743 ns->dev = dev; 730 dev->driver_data = ns;731 744 732 745 rc = ns8250_dev_initialize(ns); … … 792 805 if (need_cleanup) 793 806 ns8250_dev_cleanup(ns); 794 if (ns != NULL)795 ns8250_delete(ns);796 807 return rc; 808 } 809 810 static int ns8250_dev_remove(ddf_dev_t *dev) 811 { 812 ns8250_t *ns = NS8250_FROM_DEV(dev); 813 int rc; 814 815 fibril_mutex_lock(&ns->mutex); 816 if (ns->client_connected) { 817 fibril_mutex_unlock(&ns->mutex); 818 return EBUSY; 819 } 820 ns->removed = true; 821 fibril_mutex_unlock(&ns->mutex); 822 823 rc = ddf_fun_unbind(ns->fun); 824 if (rc != EOK) { 825 ddf_msg(LVL_ERROR, "Failed to unbind function."); 826 return rc; 827 } 828 829 ddf_fun_destroy(ns->fun); 830 831 ns8250_port_cleanup(ns); 832 ns8250_unregister_interrupt_handler(ns); 833 ns8250_dev_cleanup(ns); 834 return EOK; 797 835 } 798 836 … … 806 844 static int ns8250_open(ddf_fun_t *fun) 807 845 { 808 ns8250_t * data = (ns8250_t *) fun->dev->driver_data;846 ns8250_t *ns = NS8250(fun); 809 847 int res; 810 848 811 fibril_mutex_lock(& data->mutex);812 if ( data->client_connected) {849 fibril_mutex_lock(&ns->mutex); 850 if (ns->client_connected) { 813 851 res = ELIMIT; 852 } else if (ns->removed) { 853 res = ENXIO; 814 854 } else { 815 855 res = EOK; 816 data->client_connected = true;817 } 818 fibril_mutex_unlock(& data->mutex);856 ns->client_connected = true; 857 } 858 fibril_mutex_unlock(&ns->mutex); 819 859 820 860 return res;
Note:
See TracChangeset
for help on using the changeset viewer.