thunderbolt: Let the connection manager handle all notifications
Currently the control channel (ctl.c) handles the one supported notification (PLUG_EVENT) and sends back ACK accordingly. However, we are going to add support for the internal connection manager (ICM) that needs to handle a different notifications. So instead of dealing everything in the control channel, we change the callback to take an arbitrary thunderbolt packet and convert the native connection manager to handle the event itself. In addition we only push replies we know of to the response FIFO. Everything else is treated as notification (or request) and is expected to be dealt by the connection manager implementation. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com> Reviewed-by: Michael Jamet <michael.jamet@intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Andreas Noever <andreas.noever@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
05c242e9e4
commit
81a54b5e19
@@ -311,18 +311,34 @@ out:
|
||||
*
|
||||
* Delegates to tb_handle_hotplug.
|
||||
*/
|
||||
static void tb_schedule_hotplug_handler(void *data, u64 route, u8 port,
|
||||
bool unplug)
|
||||
static void tb_handle_event(struct tb *tb, enum tb_cfg_pkg_type type,
|
||||
const void *buf, size_t size)
|
||||
{
|
||||
struct tb *tb = data;
|
||||
struct tb_hotplug_event *ev = kmalloc(sizeof(*ev), GFP_KERNEL);
|
||||
const struct cfg_event_pkg *pkg = buf;
|
||||
struct tb_hotplug_event *ev;
|
||||
u64 route;
|
||||
|
||||
if (type != TB_CFG_PKG_EVENT) {
|
||||
tb_warn(tb, "unexpected event %#x, ignoring\n", type);
|
||||
return;
|
||||
}
|
||||
|
||||
route = tb_cfg_get_route(&pkg->header);
|
||||
|
||||
if (tb_cfg_error(tb->ctl, route, pkg->port,
|
||||
TB_CFG_ERROR_ACK_PLUG_EVENT)) {
|
||||
tb_warn(tb, "could not ack plug event on %llx:%x\n", route,
|
||||
pkg->port);
|
||||
}
|
||||
|
||||
ev = kmalloc(sizeof(*ev), GFP_KERNEL);
|
||||
if (!ev)
|
||||
return;
|
||||
INIT_WORK(&ev->work, tb_handle_hotplug);
|
||||
ev->tb = tb;
|
||||
ev->route = route;
|
||||
ev->port = port;
|
||||
ev->unplug = unplug;
|
||||
ev->port = pkg->port;
|
||||
ev->unplug = pkg->unplug;
|
||||
queue_work(tb->wq, &ev->work);
|
||||
}
|
||||
|
||||
@@ -419,7 +435,7 @@ static const struct tb_cm_ops tb_cm_ops = {
|
||||
.stop = tb_stop,
|
||||
.suspend_noirq = tb_suspend_noirq,
|
||||
.resume_noirq = tb_resume_noirq,
|
||||
.hotplug = tb_schedule_hotplug_handler,
|
||||
.handle_event = tb_handle_event,
|
||||
};
|
||||
|
||||
struct tb *tb_probe(struct tb_nhi *nhi)
|
||||
|
||||
Reference in New Issue
Block a user