18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _SBP_BASE_H 38c2ecf20Sopenharmony_ci#define _SBP_BASE_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/firewire.h> 68c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 78c2ecf20Sopenharmony_ci#include <linux/types.h> 88c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 98c2ecf20Sopenharmony_ci#include <target/target_core_base.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#define SBP_VERSION "v0.1" 128c2ecf20Sopenharmony_ci#define SBP_NAMELEN 32 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define SBP_ORB_FETCH_SIZE 8 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define MANAGEMENT_AGENT_STATE_IDLE 0 178c2ecf20Sopenharmony_ci#define MANAGEMENT_AGENT_STATE_BUSY 1 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define ORB_NOTIFY(v) (((v) >> 31) & 0x01) 208c2ecf20Sopenharmony_ci#define ORB_REQUEST_FORMAT(v) (((v) >> 29) & 0x03) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define MANAGEMENT_ORB_FUNCTION(v) (((v) >> 16) & 0x0f) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define MANAGEMENT_ORB_FUNCTION_LOGIN 0x0 258c2ecf20Sopenharmony_ci#define MANAGEMENT_ORB_FUNCTION_QUERY_LOGINS 0x1 268c2ecf20Sopenharmony_ci#define MANAGEMENT_ORB_FUNCTION_RECONNECT 0x3 278c2ecf20Sopenharmony_ci#define MANAGEMENT_ORB_FUNCTION_SET_PASSWORD 0x4 288c2ecf20Sopenharmony_ci#define MANAGEMENT_ORB_FUNCTION_LOGOUT 0x7 298c2ecf20Sopenharmony_ci#define MANAGEMENT_ORB_FUNCTION_ABORT_TASK 0xb 308c2ecf20Sopenharmony_ci#define MANAGEMENT_ORB_FUNCTION_ABORT_TASK_SET 0xc 318c2ecf20Sopenharmony_ci#define MANAGEMENT_ORB_FUNCTION_LOGICAL_UNIT_RESET 0xe 328c2ecf20Sopenharmony_ci#define MANAGEMENT_ORB_FUNCTION_TARGET_RESET 0xf 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define LOGIN_ORB_EXCLUSIVE(v) (((v) >> 28) & 0x01) 358c2ecf20Sopenharmony_ci#define LOGIN_ORB_RESERVED(v) (((v) >> 24) & 0x0f) 368c2ecf20Sopenharmony_ci#define LOGIN_ORB_RECONNECT(v) (((v) >> 20) & 0x0f) 378c2ecf20Sopenharmony_ci#define LOGIN_ORB_LUN(v) (((v) >> 0) & 0xffff) 388c2ecf20Sopenharmony_ci#define LOGIN_ORB_PASSWORD_LENGTH(v) (((v) >> 16) & 0xffff) 398c2ecf20Sopenharmony_ci#define LOGIN_ORB_RESPONSE_LENGTH(v) (((v) >> 0) & 0xffff) 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#define RECONNECT_ORB_LOGIN_ID(v) (((v) >> 0) & 0xffff) 428c2ecf20Sopenharmony_ci#define LOGOUT_ORB_LOGIN_ID(v) (((v) >> 0) & 0xffff) 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#define CMDBLK_ORB_DIRECTION(v) (((v) >> 27) & 0x01) 458c2ecf20Sopenharmony_ci#define CMDBLK_ORB_SPEED(v) (((v) >> 24) & 0x07) 468c2ecf20Sopenharmony_ci#define CMDBLK_ORB_MAX_PAYLOAD(v) (((v) >> 20) & 0x0f) 478c2ecf20Sopenharmony_ci#define CMDBLK_ORB_PG_TBL_PRESENT(v) (((v) >> 19) & 0x01) 488c2ecf20Sopenharmony_ci#define CMDBLK_ORB_PG_SIZE(v) (((v) >> 16) & 0x07) 498c2ecf20Sopenharmony_ci#define CMDBLK_ORB_DATA_SIZE(v) (((v) >> 0) & 0xffff) 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#define STATUS_BLOCK_SRC(v) (((v) & 0x03) << 30) 528c2ecf20Sopenharmony_ci#define STATUS_BLOCK_RESP(v) (((v) & 0x03) << 28) 538c2ecf20Sopenharmony_ci#define STATUS_BLOCK_DEAD(v) (((v) ? 1 : 0) << 27) 548c2ecf20Sopenharmony_ci#define STATUS_BLOCK_LEN(v) (((v) & 0x07) << 24) 558c2ecf20Sopenharmony_ci#define STATUS_BLOCK_SBP_STATUS(v) (((v) & 0xff) << 16) 568c2ecf20Sopenharmony_ci#define STATUS_BLOCK_ORB_OFFSET_HIGH(v) (((v) & 0xffff) << 0) 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#define STATUS_SRC_ORB_CONTINUING 0 598c2ecf20Sopenharmony_ci#define STATUS_SRC_ORB_FINISHED 1 608c2ecf20Sopenharmony_ci#define STATUS_SRC_UNSOLICITED 2 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci#define STATUS_RESP_REQUEST_COMPLETE 0 638c2ecf20Sopenharmony_ci#define STATUS_RESP_TRANSPORT_FAILURE 1 648c2ecf20Sopenharmony_ci#define STATUS_RESP_ILLEGAL_REQUEST 2 658c2ecf20Sopenharmony_ci#define STATUS_RESP_VENDOR_DEPENDENT 3 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#define SBP_STATUS_OK 0 688c2ecf20Sopenharmony_ci#define SBP_STATUS_REQ_TYPE_NOTSUPP 1 698c2ecf20Sopenharmony_ci#define SBP_STATUS_SPEED_NOTSUPP 2 708c2ecf20Sopenharmony_ci#define SBP_STATUS_PAGE_SIZE_NOTSUPP 3 718c2ecf20Sopenharmony_ci#define SBP_STATUS_ACCESS_DENIED 4 728c2ecf20Sopenharmony_ci#define SBP_STATUS_LUN_NOTSUPP 5 738c2ecf20Sopenharmony_ci#define SBP_STATUS_PAYLOAD_TOO_SMALL 6 748c2ecf20Sopenharmony_ci/* 7 is reserved */ 758c2ecf20Sopenharmony_ci#define SBP_STATUS_RESOURCES_UNAVAIL 8 768c2ecf20Sopenharmony_ci#define SBP_STATUS_FUNCTION_REJECTED 9 778c2ecf20Sopenharmony_ci#define SBP_STATUS_LOGIN_ID_UNKNOWN 10 788c2ecf20Sopenharmony_ci#define SBP_STATUS_DUMMY_ORB_COMPLETE 11 798c2ecf20Sopenharmony_ci#define SBP_STATUS_REQUEST_ABORTED 12 808c2ecf20Sopenharmony_ci#define SBP_STATUS_UNSPECIFIED_ERROR 0xff 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci#define AGENT_STATE_RESET 0 838c2ecf20Sopenharmony_ci#define AGENT_STATE_ACTIVE 1 848c2ecf20Sopenharmony_ci#define AGENT_STATE_SUSPENDED 2 858c2ecf20Sopenharmony_ci#define AGENT_STATE_DEAD 3 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_cistruct sbp2_pointer { 888c2ecf20Sopenharmony_ci __be32 high; 898c2ecf20Sopenharmony_ci __be32 low; 908c2ecf20Sopenharmony_ci}; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistruct sbp_command_block_orb { 938c2ecf20Sopenharmony_ci struct sbp2_pointer next_orb; 948c2ecf20Sopenharmony_ci struct sbp2_pointer data_descriptor; 958c2ecf20Sopenharmony_ci __be32 misc; 968c2ecf20Sopenharmony_ci u8 command_block[12]; 978c2ecf20Sopenharmony_ci}; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistruct sbp_page_table_entry { 1008c2ecf20Sopenharmony_ci __be16 segment_length; 1018c2ecf20Sopenharmony_ci __be16 segment_base_hi; 1028c2ecf20Sopenharmony_ci __be32 segment_base_lo; 1038c2ecf20Sopenharmony_ci}; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistruct sbp_management_orb { 1068c2ecf20Sopenharmony_ci struct sbp2_pointer ptr1; 1078c2ecf20Sopenharmony_ci struct sbp2_pointer ptr2; 1088c2ecf20Sopenharmony_ci __be32 misc; 1098c2ecf20Sopenharmony_ci __be32 length; 1108c2ecf20Sopenharmony_ci struct sbp2_pointer status_fifo; 1118c2ecf20Sopenharmony_ci}; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistruct sbp_status_block { 1148c2ecf20Sopenharmony_ci __be32 status; 1158c2ecf20Sopenharmony_ci __be32 orb_low; 1168c2ecf20Sopenharmony_ci u8 data[24]; 1178c2ecf20Sopenharmony_ci}; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistruct sbp_login_response_block { 1208c2ecf20Sopenharmony_ci __be32 misc; 1218c2ecf20Sopenharmony_ci struct sbp2_pointer command_block_agent; 1228c2ecf20Sopenharmony_ci __be32 reconnect_hold; 1238c2ecf20Sopenharmony_ci}; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cistruct sbp_login_descriptor { 1268c2ecf20Sopenharmony_ci struct sbp_session *sess; 1278c2ecf20Sopenharmony_ci struct list_head link; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci u32 login_lun; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci u64 status_fifo_addr; 1328c2ecf20Sopenharmony_ci int exclusive; 1338c2ecf20Sopenharmony_ci u16 login_id; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci struct sbp_target_agent *tgt_agt; 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistruct sbp_session { 1398c2ecf20Sopenharmony_ci spinlock_t lock; 1408c2ecf20Sopenharmony_ci struct se_session *se_sess; 1418c2ecf20Sopenharmony_ci struct list_head login_list; 1428c2ecf20Sopenharmony_ci struct delayed_work maint_work; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci u64 guid; /* login_owner_EUI_64 */ 1458c2ecf20Sopenharmony_ci int node_id; /* login_owner_ID */ 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci struct fw_card *card; 1488c2ecf20Sopenharmony_ci int generation; 1498c2ecf20Sopenharmony_ci int speed; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci int reconnect_hold; 1528c2ecf20Sopenharmony_ci u64 reconnect_expires; 1538c2ecf20Sopenharmony_ci}; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_cistruct sbp_tpg { 1568c2ecf20Sopenharmony_ci /* Target portal group tag for TCM */ 1578c2ecf20Sopenharmony_ci u16 tport_tpgt; 1588c2ecf20Sopenharmony_ci /* Pointer back to sbp_tport */ 1598c2ecf20Sopenharmony_ci struct sbp_tport *tport; 1608c2ecf20Sopenharmony_ci /* Returned by sbp_make_tpg() */ 1618c2ecf20Sopenharmony_ci struct se_portal_group se_tpg; 1628c2ecf20Sopenharmony_ci}; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistruct sbp_tport { 1658c2ecf20Sopenharmony_ci /* Target Unit Identifier (EUI-64) */ 1668c2ecf20Sopenharmony_ci u64 guid; 1678c2ecf20Sopenharmony_ci /* Target port name */ 1688c2ecf20Sopenharmony_ci char tport_name[SBP_NAMELEN]; 1698c2ecf20Sopenharmony_ci /* Returned by sbp_make_tport() */ 1708c2ecf20Sopenharmony_ci struct se_wwn tport_wwn; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci struct sbp_tpg *tpg; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci /* FireWire unit directory */ 1758c2ecf20Sopenharmony_ci struct fw_descriptor unit_directory; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci /* SBP Management Agent */ 1788c2ecf20Sopenharmony_ci struct sbp_management_agent *mgt_agt; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci /* Parameters */ 1818c2ecf20Sopenharmony_ci int enable; 1828c2ecf20Sopenharmony_ci s32 directory_id; 1838c2ecf20Sopenharmony_ci int mgt_orb_timeout; 1848c2ecf20Sopenharmony_ci int max_reconnect_timeout; 1858c2ecf20Sopenharmony_ci int max_logins_per_lun; 1868c2ecf20Sopenharmony_ci}; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_cistatic inline u64 sbp2_pointer_to_addr(const struct sbp2_pointer *ptr) 1898c2ecf20Sopenharmony_ci{ 1908c2ecf20Sopenharmony_ci return (u64)(be32_to_cpu(ptr->high) & 0x0000ffff) << 32 | 1918c2ecf20Sopenharmony_ci (be32_to_cpu(ptr->low) & 0xfffffffc); 1928c2ecf20Sopenharmony_ci} 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_cistatic inline void addr_to_sbp2_pointer(u64 addr, struct sbp2_pointer *ptr) 1958c2ecf20Sopenharmony_ci{ 1968c2ecf20Sopenharmony_ci ptr->high = cpu_to_be32(addr >> 32); 1978c2ecf20Sopenharmony_ci ptr->low = cpu_to_be32(addr); 1988c2ecf20Sopenharmony_ci} 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistruct sbp_target_agent { 2018c2ecf20Sopenharmony_ci spinlock_t lock; 2028c2ecf20Sopenharmony_ci struct fw_address_handler handler; 2038c2ecf20Sopenharmony_ci struct sbp_login_descriptor *login; 2048c2ecf20Sopenharmony_ci int state; 2058c2ecf20Sopenharmony_ci struct work_struct work; 2068c2ecf20Sopenharmony_ci u64 orb_pointer; 2078c2ecf20Sopenharmony_ci bool doorbell; 2088c2ecf20Sopenharmony_ci}; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistruct sbp_target_request { 2118c2ecf20Sopenharmony_ci struct sbp_login_descriptor *login; 2128c2ecf20Sopenharmony_ci u64 orb_pointer; 2138c2ecf20Sopenharmony_ci struct sbp_command_block_orb orb; 2148c2ecf20Sopenharmony_ci struct sbp_status_block status; 2158c2ecf20Sopenharmony_ci struct work_struct work; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci struct se_cmd se_cmd; 2188c2ecf20Sopenharmony_ci struct sbp_page_table_entry *pg_tbl; 2198c2ecf20Sopenharmony_ci void *cmd_buf; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci unsigned char sense_buf[TRANSPORT_SENSE_BUFFER]; 2228c2ecf20Sopenharmony_ci}; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_cistruct sbp_management_agent { 2258c2ecf20Sopenharmony_ci spinlock_t lock; 2268c2ecf20Sopenharmony_ci struct sbp_tport *tport; 2278c2ecf20Sopenharmony_ci struct fw_address_handler handler; 2288c2ecf20Sopenharmony_ci int state; 2298c2ecf20Sopenharmony_ci struct work_struct work; 2308c2ecf20Sopenharmony_ci u64 orb_offset; 2318c2ecf20Sopenharmony_ci struct sbp_management_request *request; 2328c2ecf20Sopenharmony_ci}; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistruct sbp_management_request { 2358c2ecf20Sopenharmony_ci struct sbp_management_orb orb; 2368c2ecf20Sopenharmony_ci struct sbp_status_block status; 2378c2ecf20Sopenharmony_ci struct fw_card *card; 2388c2ecf20Sopenharmony_ci int generation; 2398c2ecf20Sopenharmony_ci int node_addr; 2408c2ecf20Sopenharmony_ci int speed; 2418c2ecf20Sopenharmony_ci}; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci#endif 244