X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/59ecf21e36b2332f6adf2a568ef555283d8c119a..64e5fa9a495e388c922157b9a616204c299f5e05:/lunaix-os/hal/char/serial.c diff --git a/lunaix-os/hal/char/serial.c b/lunaix-os/hal/char/serial.c index ddcd57f..1dbdb68 100644 --- a/lunaix-os/hal/char/serial.c +++ b/lunaix-os/hal/char/serial.c @@ -7,6 +7,15 @@ #include +#define lock_sdev(sdev) device_lock((sdev)->dev) +#define unlock_sdev(sdev) device_unlock((sdev)->dev) +#define unlock_and_wait(sdev, wq) \ + ({ \ + unlock_sdev(sdev); \ + pwait(&(sdev)->wq); \ + lock_sdev(sdev); \ + }) + static DEFINE_LLIST(serial_devs); static int serial_idx = 0; @@ -44,11 +53,11 @@ serial_end_xmit(struct serial_dev* sdev, size_t len) int serial_readone_nowait(struct serial_dev* sdev, u8_t* val) { - device_lock(sdev->dev); + lock_sdev(sdev); int rd_len = rbuffer_get(&sdev->rxbuf, (char*)val); - device_unlock(sdev->dev); + unlock_sdev(sdev); return rd_len; } @@ -56,30 +65,30 @@ serial_readone_nowait(struct serial_dev* sdev, u8_t* val) void serial_readone(struct serial_dev* sdev, u8_t* val) { - device_lock(sdev->dev); + lock_sdev(sdev); mark_device_doing_read(sdev->dev); while (!rbuffer_get(&sdev->rxbuf, (char*)val)) { - pwait(&sdev->wq_rxdone); + unlock_and_wait(sdev, wq_rxdone); } - device_unlock(sdev->dev); + unlock_sdev(sdev); } size_t serial_readbuf(struct serial_dev* sdev, u8_t* buf, size_t len) { - device_lock(sdev->dev); + lock_sdev(sdev); mark_device_doing_read(sdev->dev); size_t rdlen; while (!(rdlen = rbuffer_gets(&sdev->rxbuf, (char*)buf, len))) { - pwait(&sdev->wq_rxdone); + unlock_and_wait(sdev, wq_rxdone); } - device_unlock(sdev->dev); + unlock_sdev(sdev); return rdlen; } @@ -87,13 +96,13 @@ serial_readbuf(struct serial_dev* sdev, u8_t* buf, size_t len) int serial_readbuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len) { - device_lock(sdev->dev); + lock_sdev(sdev); mark_device_doing_read(sdev->dev); int rdlen = rbuffer_gets(&sdev->rxbuf, (char*)buf, len); - device_unlock(sdev->dev); + unlock_sdev(sdev); return rdlen; } @@ -101,7 +110,7 @@ serial_readbuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len) int serial_writebuf(struct serial_dev* sdev, u8_t* buf, size_t len) { - device_lock(sdev->dev); + lock_sdev(sdev); mark_device_doing_write(sdev->dev); @@ -109,11 +118,11 @@ serial_writebuf(struct serial_dev* sdev, u8_t* buf, size_t len) goto done; } - pwait(&sdev->wq_txdone); + unlock_and_wait(sdev, wq_txdone); done: int rdlen = sdev->wr_len; - device_unlock(sdev->dev); + unlock_sdev(sdev); return rdlen; } @@ -121,14 +130,14 @@ done: int serial_writebuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len) { - device_lock(sdev->dev); + lock_sdev(sdev); mark_device_doing_write(sdev->dev); sdev->write(sdev, buf, len); int rdlen = sdev->wr_len; - device_unlock(sdev->dev); + unlock_sdev(sdev); return rdlen; } @@ -139,6 +148,13 @@ __serial_read(struct device* dev, void* buf, size_t offset, size_t len) return serial_readbuf(serial_device(dev), &((u8_t*)buf)[offset], len); } +static int +__serial_read_async(struct device* dev, void* buf, size_t offset, size_t len) +{ + return serial_readbuf_nowait( + serial_device(dev), &((u8_t*)buf)[offset], len); +} + static int __serial_read_page(struct device* dev, void* buf, size_t offset) { @@ -151,6 +167,13 @@ __serial_write(struct device* dev, void* buf, size_t offset, size_t len) return serial_writebuf(serial_device(dev), &((u8_t*)buf)[offset], len); } +static int +__serial_write_async(struct device* dev, void* buf, size_t offset, size_t len) +{ + return serial_writebuf_nowait( + serial_device(dev), &((u8_t*)buf)[offset], len); +} + static int __serial_write_page(struct device* dev, void* buf, size_t offset) { @@ -186,6 +209,8 @@ serial_create(struct devclass* class, char* if_ident) struct device* dev = device_allocseq(NULL, sdev); dev->ops.read = __serial_read; dev->ops.read_page = __serial_read_page; + dev->ops.read_async = __serial_read_async; + dev->ops.write_async = __serial_write_async; dev->ops.write = __serial_write; dev->ops.write_page = __serial_write_page; dev->ops.exec_cmd = __serial_exec_command;