Use a taskqueue to handle port status changes.
Calling ucom layer directly from interrupt context make a panic. MFC after: 1 week
This commit is contained in:
parent
1f0ce611b3
commit
4b6cd0347a
@ -94,6 +94,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/bus.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/taskqueue.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbcdc.h>
|
||||
@ -165,6 +166,8 @@ struct umodem_softc {
|
||||
usb_cdc_notification_t sc_notify_buf; /* Notification structure */
|
||||
u_char sc_lsr; /* Local status register */
|
||||
u_char sc_msr; /* Modem status register */
|
||||
|
||||
struct task sc_task;
|
||||
};
|
||||
|
||||
Static void *umodem_get_desc(usbd_device_handle dev, int type, int subtype);
|
||||
@ -186,6 +189,7 @@ Static int umodem_ioctl(void *, int, u_long, caddr_t, int, usb_proc_ptr );
|
||||
Static int umodem_open(void *, int portno);
|
||||
Static void umodem_close(void *, int portno);
|
||||
Static void umodem_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
|
||||
Static void umodem_notify(void *, int);
|
||||
|
||||
Static struct ucom_callback umodem_callback = {
|
||||
umodem_get_status,
|
||||
@ -415,6 +419,7 @@ USB_ATTACH(umodem)
|
||||
ucom->sc_opkthdrlen = 0;
|
||||
ucom->sc_callback = &umodem_callback;
|
||||
|
||||
TASK_INIT(&sc->sc_task, 0, umodem_notify, sc);
|
||||
ucom_attach(&sc->sc_ucom);
|
||||
|
||||
free(devinfo, M_USBDEV);
|
||||
@ -521,7 +526,8 @@ umodem_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
|
||||
sc->sc_msr |= SER_DSR;
|
||||
if (ISSET(mstatus, UCDC_N_SERIAL_DCD))
|
||||
sc->sc_msr |= SER_DCD;
|
||||
ucom_status_change(&sc->sc_ucom);
|
||||
/* Deferred notifying to the ucom layer */
|
||||
taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
|
||||
break;
|
||||
default:
|
||||
DPRINTF(("%s: unknown notify message: %02x\n",
|
||||
@ -531,6 +537,17 @@ umodem_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
|
||||
}
|
||||
}
|
||||
|
||||
Static void
|
||||
umodem_notify(void *arg, int count)
|
||||
{
|
||||
struct umodem_softc *sc;
|
||||
|
||||
sc = (struct umodem_softc *)arg;
|
||||
if (sc->sc_ucom.sc_dying)
|
||||
return;
|
||||
ucom_status_change(&sc->sc_ucom);
|
||||
}
|
||||
|
||||
void
|
||||
umodem_get_caps(usbd_device_handle dev, int *cm, int *acm)
|
||||
{
|
||||
|
@ -107,6 +107,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/poll.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/taskqueue.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
@ -176,6 +177,8 @@ struct uplcom_softc {
|
||||
u_char sc_msr; /* uplcom status register */
|
||||
|
||||
int sc_chiptype; /* Type of chip */
|
||||
|
||||
struct task sc_task;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -203,6 +206,7 @@ Static int uplcom_ioctl(void *, int, u_long, caddr_t, int, usb_proc_ptr);
|
||||
Static int uplcom_param(void *, int, struct termios *);
|
||||
Static int uplcom_open(void *, int);
|
||||
Static void uplcom_close(void *, int);
|
||||
Static void uplcom_notify(void *, int);
|
||||
|
||||
struct ucom_callback uplcom_callback = {
|
||||
uplcom_get_status,
|
||||
@ -530,6 +534,7 @@ USB_ATTACH(uplcom)
|
||||
DPRINTF(("uplcom: 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, uplcom_notify, sc);
|
||||
ucom_attach(&sc->sc_ucom);
|
||||
|
||||
free(devinfo, M_USBDEV);
|
||||
@ -950,6 +955,19 @@ uplcom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
|
||||
sc->sc_msr |= SER_DCD;
|
||||
else
|
||||
sc->sc_msr &= ~SER_DCD;
|
||||
|
||||
/* Deferred notifying to the ucom layer */
|
||||
taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
|
||||
}
|
||||
|
||||
Static void
|
||||
uplcom_notify(void *arg, int count)
|
||||
{
|
||||
struct uplcom_softc *sc;
|
||||
|
||||
sc = (struct uplcom_softc *)arg;
|
||||
if (sc->sc_ucom.sc_dying)
|
||||
return;
|
||||
ucom_status_change(&sc->sc_ucom);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user