brintos

brintos / linux-shallow public Read only

0
0
Text · 4.7 KiB · bf930a1 Raw
145 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Thunderbolt driver - control channel and configuration commands4 *5 * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>6 * Copyright (C) 2018, Intel Corporation7 */8 9#ifndef _TB_CFG10#define _TB_CFG11 12#include <linux/kref.h>13#include <linux/thunderbolt.h>14 15#include "nhi.h"16#include "tb_msgs.h"17 18/* control channel */19struct tb_ctl;20 21typedef bool (*event_cb)(void *data, enum tb_cfg_pkg_type type,22			 const void *buf, size_t size);23 24struct tb_ctl *tb_ctl_alloc(struct tb_nhi *nhi, int index, int timeout_msec,25			    event_cb cb, void *cb_data);26void tb_ctl_start(struct tb_ctl *ctl);27void tb_ctl_stop(struct tb_ctl *ctl);28void tb_ctl_free(struct tb_ctl *ctl);29 30/* configuration commands */31 32struct tb_cfg_result {33	u64 response_route;34	u32 response_port; /*35			    * If err = 1 then this is the port that send the36			    * error.37			    * If err = 0 and if this was a cfg_read/write then38			    * this is the upstream port of the responding39			    * switch.40			    * Otherwise the field is set to zero.41			    */42	int err; /* negative errors, 0 for success, 1 for tb errors */43	enum tb_cfg_error tb_error; /* valid if err == 1 */44};45 46struct ctl_pkg {47	struct tb_ctl *ctl;48	void *buffer;49	struct ring_frame frame;50};51 52/**53 * struct tb_cfg_request - Control channel request54 * @kref: Reference count55 * @ctl: Pointer to the control channel structure. Only set when the56 *	 request is queued.57 * @request_size: Size of the request packet (in bytes)58 * @request_type: Type of the request packet59 * @response: Response is stored here60 * @response_size: Maximum size of one response packet61 * @response_type: Expected type of the response packet62 * @npackets: Number of packets expected to be returned with this request63 * @match: Function used to match the incoming packet64 * @copy: Function used to copy the incoming packet to @response65 * @callback: Callback called when the request is finished successfully66 * @callback_data: Data to be passed to @callback67 * @flags: Flags for the request68 * @work: Work item used to complete the request69 * @result: Result after the request has been completed70 * @list: Requests are queued using this field71 *72 * An arbitrary request over Thunderbolt control channel. For standard73 * control channel message, one should use tb_cfg_read/write() and74 * friends if possible.75 */76struct tb_cfg_request {77	struct kref kref;78	struct tb_ctl *ctl;79	const void *request;80	size_t request_size;81	enum tb_cfg_pkg_type request_type;82	void *response;83	size_t response_size;84	enum tb_cfg_pkg_type response_type;85	size_t npackets;86	bool (*match)(const struct tb_cfg_request *req,87		      const struct ctl_pkg *pkg);88	bool (*copy)(struct tb_cfg_request *req, const struct ctl_pkg *pkg);89	void (*callback)(void *callback_data);90	void *callback_data;91	unsigned long flags;92	struct work_struct work;93	struct tb_cfg_result result;94	struct list_head list;95};96 97#define TB_CFG_REQUEST_ACTIVE		098#define TB_CFG_REQUEST_CANCELED		199 100struct tb_cfg_request *tb_cfg_request_alloc(void);101void tb_cfg_request_get(struct tb_cfg_request *req);102void tb_cfg_request_put(struct tb_cfg_request *req);103int tb_cfg_request(struct tb_ctl *ctl, struct tb_cfg_request *req,104		   void (*callback)(void *), void *callback_data);105void tb_cfg_request_cancel(struct tb_cfg_request *req, int err);106struct tb_cfg_result tb_cfg_request_sync(struct tb_ctl *ctl,107			struct tb_cfg_request *req, int timeout_msec);108 109static inline u64 tb_cfg_get_route(const struct tb_cfg_header *header)110{111	return (u64) header->route_hi << 32 | header->route_lo;112}113 114static inline struct tb_cfg_header tb_cfg_make_header(u64 route)115{116	struct tb_cfg_header header = {117		.route_hi = route >> 32,118		.route_lo = route,119	};120	/* check for overflow, route_hi is not 32 bits! */121	WARN_ON(tb_cfg_get_route(&header) != route);122	return header;123}124 125int tb_cfg_ack_notification(struct tb_ctl *ctl, u64 route,126			    const struct cfg_error_pkg *error);127int tb_cfg_ack_plug(struct tb_ctl *ctl, u64 route, u32 port, bool unplug);128struct tb_cfg_result tb_cfg_reset(struct tb_ctl *ctl, u64 route);129struct tb_cfg_result tb_cfg_read_raw(struct tb_ctl *ctl, void *buffer,130				     u64 route, u32 port,131				     enum tb_cfg_space space, u32 offset,132				     u32 length, int timeout_msec);133struct tb_cfg_result tb_cfg_write_raw(struct tb_ctl *ctl, const void *buffer,134				      u64 route, u32 port,135				      enum tb_cfg_space space, u32 offset,136				      u32 length, int timeout_msec);137int tb_cfg_read(struct tb_ctl *ctl, void *buffer, u64 route, u32 port,138		enum tb_cfg_space space, u32 offset, u32 length);139int tb_cfg_write(struct tb_ctl *ctl, const void *buffer, u64 route, u32 port,140		 enum tb_cfg_space space, u32 offset, u32 length);141int tb_cfg_get_upstream_port(struct tb_ctl *ctl, u64 route);142 143 144#endif145