summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uvscom.c
diff options
context:
space:
mode:
authorShunsuke Akiyama <akiyama@FreeBSD.org>2005-01-31 13:58:10 +0000
committerShunsuke Akiyama <akiyama@FreeBSD.org>2005-01-31 13:58:10 +0000
commit4b6cd0347a7ab11b73a76008d64246a1f3579941 (patch)
tree3498baf34d6716670cf4e97495ae41c687bdcbef /sys/dev/usb/uvscom.c
parent1f0ce611b3167189f348fd4eb2dc006b0a05230c (diff)
Notes
Diffstat (limited to 'sys/dev/usb/uvscom.c')
-rw-r--r--sys/dev/usb/uvscom.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/sys/dev/usb/uvscom.c b/sys/dev/usb/uvscom.c
index 96f40d93766a..79f8b44dca4d 100644
--- a/sys/dev/usb/uvscom.c
+++ b/sys/dev/usb/uvscom.c
@@ -1,6 +1,6 @@
/* $NetBSD: usb/uvscom.c,v 1.1 2002/03/19 15:08:42 augustss Exp $ */
/*-
- * Copyright (c) 2001-2002, Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
+ * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/poll.h>
#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbcdc.h>
@@ -174,6 +175,8 @@ struct uvscom_softc {
uint16_t sc_lcr; /* Line control */
u_char sc_usr; /* unit status */
+
+ struct task sc_task;
};
/*
@@ -206,6 +209,7 @@ Static int uvscom_ioctl(void *, int, u_long, caddr_t, int, usb_proc_ptr);
Static int uvscom_param(void *, int, struct termios *);
Static int uvscom_open(void *, int);
Static void uvscom_close(void *, int);
+Static void uvscom_notify(void *, int);
struct ucom_callback uvscom_callback = {
uvscom_get_status,
@@ -437,6 +441,7 @@ USB_ATTACH(uvscom)
DPRINTF(("uvscom: in = 0x%x out = 0x%x intr = 0x%x\n",
ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));
+ TASK_INIT(&sc->sc_task, 0, uvscom_notify, sc);
ucom_attach(&sc->sc_ucom);
free(devinfo, M_USBDEV);
@@ -904,6 +909,18 @@ uvscom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
if (ISSET(pstatus, UVSCOM_DCD))
SET(sc->sc_msr, SER_DCD);
+ /* Deferred notifying to the ucom layer */
+ taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
+}
+
+Static void
+uvscom_notify(void *arg, int count)
+{
+ struct uvscom_softc *sc;
+
+ sc = (struct uvscom_softc *)arg;
+ if (sc->sc_ucom.sc_dying)
+ return;
ucom_status_change(&sc->sc_ucom);
}