aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src/serial_usb.c
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-09-08 12:28:44 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-09-08 12:28:44 +0000
commite5833b6a09786844ae09f389d768accec9678026 (patch)
tree879fb45694cc431f39098e05c9ae6c0e9cde8c0e /os/hal/src/serial_usb.c
parentaa7557a5f206124dc232343be2010f7d9b82e267 (diff)
downloadChibiOS-e5833b6a09786844ae09f389d768accec9678026.tar.gz
ChibiOS-e5833b6a09786844ae09f389d768accec9678026.tar.bz2
ChibiOS-e5833b6a09786844ae09f389d768accec9678026.zip
Disconnect handling in SDU driver.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8287 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/src/serial_usb.c')
-rw-r--r--os/hal/src/serial_usb.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index dc0e803a8..c32a17376 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -56,43 +56,67 @@ static cdc_linecoding_t linecoding = {
static size_t write(void *ip, const uint8_t *bp, size_t n) {
+ if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE)
+ return 0;
+
return oqWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp,
n, TIME_INFINITE);
}
static size_t read(void *ip, uint8_t *bp, size_t n) {
+ if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE)
+ return 0;
+
return iqReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp,
n, TIME_INFINITE);
}
static msg_t put(void *ip, uint8_t b) {
+ if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE)
+ return MSG_RESET;
+
return oqPutTimeout(&((SerialUSBDriver *)ip)->oqueue, b, TIME_INFINITE);
}
static msg_t get(void *ip) {
+ if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE)
+ return MSG_RESET;
+
return iqGetTimeout(&((SerialUSBDriver *)ip)->iqueue, TIME_INFINITE);
}
static msg_t putt(void *ip, uint8_t b, systime_t timeout) {
+ if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE)
+ return MSG_RESET;
+
return oqPutTimeout(&((SerialUSBDriver *)ip)->oqueue, b, timeout);
}
static msg_t gett(void *ip, systime_t timeout) {
+ if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE)
+ return MSG_RESET;
+
return iqGetTimeout(&((SerialUSBDriver *)ip)->iqueue, timeout);
}
static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t timeout) {
+ if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE)
+ return 0;
+
return oqWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp, n, timeout);
}
static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t timeout) {
+ if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE)
+ return 0;
+
return iqReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp, n, timeout);
}
@@ -252,12 +276,27 @@ void sduStop(SerialUSBDriver *sdup) {
}
sdup->state = SDU_STOP;
+ /* Enforces a disconnection.*/
+ sduDisconnectI(sdup);
+ osalOsRescheduleS();
+ osalSysUnlock();
+}
+
+/**
+ * @brief USB device disconnection handler.
+ * @note If this function is not called from an ISR then an explicit call
+ * to @p osalOsRescheduleS() in necessary afterward.
+ *
+ * @param[in] sdup pointer to a @p SerialUSBDriver object
+ *
+ * @iclass
+ */
+void sduDisconnectI(SerialUSBDriver *sdup) {
+
/* Queues reset in order to signal the driver stop to the application.*/
chnAddFlagsI(sdup, CHN_DISCONNECTED);
iqResetI(&sdup->iqueue);
iqResetI(&sdup->oqueue);
- osalOsRescheduleS();
- osalSysUnlock();
}
/**