162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * SAS host prototypes and structures header file
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
662306a36Sopenharmony_ci * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifndef _LIBSAS_H_
1062306a36Sopenharmony_ci#define _LIBSAS_H_
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/timer.h>
1462306a36Sopenharmony_ci#include <linux/pci.h>
1562306a36Sopenharmony_ci#include <scsi/sas.h>
1662306a36Sopenharmony_ci#include <linux/libata.h>
1762306a36Sopenharmony_ci#include <linux/list.h>
1862306a36Sopenharmony_ci#include <scsi/scsi_device.h>
1962306a36Sopenharmony_ci#include <scsi/scsi_cmnd.h>
2062306a36Sopenharmony_ci#include <scsi/scsi_transport_sas.h>
2162306a36Sopenharmony_ci#include <linux/scatterlist.h>
2262306a36Sopenharmony_ci#include <linux/slab.h>
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistruct block_device;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cienum sas_phy_role {
2762306a36Sopenharmony_ci	PHY_ROLE_NONE = 0,
2862306a36Sopenharmony_ci	PHY_ROLE_TARGET = 0x40,
2962306a36Sopenharmony_ci	PHY_ROLE_INITIATOR = 0x80,
3062306a36Sopenharmony_ci};
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/* The events are mnemonically described in sas_dump.c
3362306a36Sopenharmony_ci * so when updating/adding events here, please also
3462306a36Sopenharmony_ci * update the other file too.
3562306a36Sopenharmony_ci */
3662306a36Sopenharmony_cienum port_event {
3762306a36Sopenharmony_ci	PORTE_BYTES_DMAED     = 0U,
3862306a36Sopenharmony_ci	PORTE_BROADCAST_RCVD,
3962306a36Sopenharmony_ci	PORTE_LINK_RESET_ERR,
4062306a36Sopenharmony_ci	PORTE_TIMER_EVENT,
4162306a36Sopenharmony_ci	PORTE_HARD_RESET,
4262306a36Sopenharmony_ci	PORT_NUM_EVENTS,
4362306a36Sopenharmony_ci};
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cienum phy_event {
4662306a36Sopenharmony_ci	PHYE_LOSS_OF_SIGNAL   = 0U,
4762306a36Sopenharmony_ci	PHYE_OOB_DONE,
4862306a36Sopenharmony_ci	PHYE_OOB_ERROR,
4962306a36Sopenharmony_ci	PHYE_SPINUP_HOLD,             /* hot plug SATA, no COMWAKE sent */
5062306a36Sopenharmony_ci	PHYE_RESUME_TIMEOUT,
5162306a36Sopenharmony_ci	PHYE_SHUTDOWN,
5262306a36Sopenharmony_ci	PHY_NUM_EVENTS,
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cienum discover_event {
5662306a36Sopenharmony_ci	DISCE_DISCOVER_DOMAIN   = 0U,
5762306a36Sopenharmony_ci	DISCE_REVALIDATE_DOMAIN,
5862306a36Sopenharmony_ci	DISCE_SUSPEND,
5962306a36Sopenharmony_ci	DISCE_RESUME,
6062306a36Sopenharmony_ci	DISC_NUM_EVENTS,
6162306a36Sopenharmony_ci};
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci/* ---------- Expander Devices ---------- */
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci#define to_dom_device(_obj) container_of(_obj, struct domain_device, dev_obj)
6662306a36Sopenharmony_ci#define to_dev_attr(_attr)  container_of(_attr, struct domain_dev_attribute,\
6762306a36Sopenharmony_ci					 attr)
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cienum routing_attribute {
7062306a36Sopenharmony_ci	DIRECT_ROUTING,
7162306a36Sopenharmony_ci	SUBTRACTIVE_ROUTING,
7262306a36Sopenharmony_ci	TABLE_ROUTING,
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cienum ex_phy_state {
7662306a36Sopenharmony_ci	PHY_EMPTY,
7762306a36Sopenharmony_ci	PHY_VACANT,
7862306a36Sopenharmony_ci	PHY_NOT_PRESENT,
7962306a36Sopenharmony_ci	PHY_DEVICE_DISCOVERED
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistruct ex_phy {
8362306a36Sopenharmony_ci	int    phy_id;
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	enum ex_phy_state phy_state;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	enum sas_device_type attached_dev_type;
8862306a36Sopenharmony_ci	enum sas_linkrate linkrate;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	u8   attached_sata_host:1;
9162306a36Sopenharmony_ci	u8   attached_sata_dev:1;
9262306a36Sopenharmony_ci	u8   attached_sata_ps:1;
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	enum sas_protocol attached_tproto;
9562306a36Sopenharmony_ci	enum sas_protocol attached_iproto;
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	u8   attached_sas_addr[SAS_ADDR_SIZE];
9862306a36Sopenharmony_ci	u8   attached_phy_id;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	int phy_change_count;
10162306a36Sopenharmony_ci	enum routing_attribute routing_attr;
10262306a36Sopenharmony_ci	u8   virtual:1;
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	int  last_da_index;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	struct sas_phy *phy;
10762306a36Sopenharmony_ci	struct sas_port *port;
10862306a36Sopenharmony_ci};
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_cistruct expander_device {
11162306a36Sopenharmony_ci	struct list_head children;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	int    ex_change_count;
11462306a36Sopenharmony_ci	u16    max_route_indexes;
11562306a36Sopenharmony_ci	u8     num_phys;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	u8     t2t_supp:1;
11862306a36Sopenharmony_ci	u8     configuring:1;
11962306a36Sopenharmony_ci	u8     conf_route_table:1;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	u8     enclosure_logical_id[8];
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	struct ex_phy *ex_phy;
12462306a36Sopenharmony_ci	struct sas_port *parent_port;
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	struct mutex cmd_mutex;
12762306a36Sopenharmony_ci};
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci/* ---------- SATA device ---------- */
13062306a36Sopenharmony_ci#define ATA_RESP_FIS_SIZE 24
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cistruct sata_device {
13362306a36Sopenharmony_ci	unsigned int class;
13462306a36Sopenharmony_ci	u8     port_no;        /* port number, if this is a PM (Port) */
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	struct ata_port *ap;
13762306a36Sopenharmony_ci	struct ata_host *ata_host;
13862306a36Sopenharmony_ci	struct smp_rps_resp rps_resp ____cacheline_aligned; /* report_phy_sata_resp */
13962306a36Sopenharmony_ci	u8     fis[ATA_RESP_FIS_SIZE];
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistruct ssp_device {
14362306a36Sopenharmony_ci	struct list_head eh_list_node; /* pending a user requested eh action */
14462306a36Sopenharmony_ci	struct scsi_lun reset_lun;
14562306a36Sopenharmony_ci};
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cienum {
14862306a36Sopenharmony_ci	SAS_DEV_GONE,
14962306a36Sopenharmony_ci	SAS_DEV_FOUND, /* device notified to lldd */
15062306a36Sopenharmony_ci	SAS_DEV_DESTROY,
15162306a36Sopenharmony_ci	SAS_DEV_EH_PENDING,
15262306a36Sopenharmony_ci	SAS_DEV_LU_RESET,
15362306a36Sopenharmony_ci	SAS_DEV_RESET,
15462306a36Sopenharmony_ci};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cistruct domain_device {
15762306a36Sopenharmony_ci	spinlock_t done_lock;
15862306a36Sopenharmony_ci	enum sas_device_type dev_type;
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	enum sas_linkrate linkrate;
16162306a36Sopenharmony_ci	enum sas_linkrate min_linkrate;
16262306a36Sopenharmony_ci	enum sas_linkrate max_linkrate;
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	int  pathways;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	struct domain_device *parent;
16762306a36Sopenharmony_ci	struct list_head siblings; /* devices on the same level */
16862306a36Sopenharmony_ci	struct asd_sas_port *port;        /* shortcut to root of the tree */
16962306a36Sopenharmony_ci	struct sas_phy *phy;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	struct list_head dev_list_node;
17262306a36Sopenharmony_ci	struct list_head disco_list_node; /* awaiting probe or destruct */
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	enum sas_protocol    iproto;
17562306a36Sopenharmony_ci	enum sas_protocol    tproto;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	struct sas_rphy *rphy;
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	u8  sas_addr[SAS_ADDR_SIZE];
18062306a36Sopenharmony_ci	u8  hashed_sas_addr[HASHED_SAS_ADDR_SIZE];
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	u8  frame_rcvd[32];
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci	union {
18562306a36Sopenharmony_ci		struct expander_device ex_dev;
18662306a36Sopenharmony_ci		struct sata_device     sata_dev; /* STP & directly attached */
18762306a36Sopenharmony_ci		struct ssp_device      ssp_dev;
18862306a36Sopenharmony_ci	};
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	void *lldd_dev;
19162306a36Sopenharmony_ci	unsigned long state;
19262306a36Sopenharmony_ci	struct kref kref;
19362306a36Sopenharmony_ci};
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_cistruct sas_work {
19662306a36Sopenharmony_ci	struct list_head drain_node;
19762306a36Sopenharmony_ci	struct work_struct work;
19862306a36Sopenharmony_ci};
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistatic inline bool dev_is_expander(enum sas_device_type type)
20162306a36Sopenharmony_ci{
20262306a36Sopenharmony_ci	return type == SAS_EDGE_EXPANDER_DEVICE ||
20362306a36Sopenharmony_ci	       type == SAS_FANOUT_EXPANDER_DEVICE;
20462306a36Sopenharmony_ci}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_cistatic inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *))
20762306a36Sopenharmony_ci{
20862306a36Sopenharmony_ci	INIT_WORK(&sw->work, fn);
20962306a36Sopenharmony_ci	INIT_LIST_HEAD(&sw->drain_node);
21062306a36Sopenharmony_ci}
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_cistruct sas_discovery_event {
21362306a36Sopenharmony_ci	struct sas_work work;
21462306a36Sopenharmony_ci	struct asd_sas_port *port;
21562306a36Sopenharmony_ci};
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_cistatic inline struct sas_discovery_event *to_sas_discovery_event(struct work_struct *work)
21862306a36Sopenharmony_ci{
21962306a36Sopenharmony_ci	struct sas_discovery_event *ev = container_of(work, typeof(*ev), work.work);
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	return ev;
22262306a36Sopenharmony_ci}
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_cistruct sas_discovery {
22562306a36Sopenharmony_ci	struct sas_discovery_event disc_work[DISC_NUM_EVENTS];
22662306a36Sopenharmony_ci	unsigned long    pending;
22762306a36Sopenharmony_ci	u8     fanout_sas_addr[SAS_ADDR_SIZE];
22862306a36Sopenharmony_ci	u8     eeds_a[SAS_ADDR_SIZE];
22962306a36Sopenharmony_ci	u8     eeds_b[SAS_ADDR_SIZE];
23062306a36Sopenharmony_ci	int    max_level;
23162306a36Sopenharmony_ci};
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci/* The port struct is Class:RW, driver:RO */
23462306a36Sopenharmony_cistruct asd_sas_port {
23562306a36Sopenharmony_ci/* private: */
23662306a36Sopenharmony_ci	struct sas_discovery disc;
23762306a36Sopenharmony_ci	struct domain_device *port_dev;
23862306a36Sopenharmony_ci	spinlock_t dev_list_lock;
23962306a36Sopenharmony_ci	struct list_head dev_list;
24062306a36Sopenharmony_ci	struct list_head disco_list;
24162306a36Sopenharmony_ci	struct list_head destroy_list;
24262306a36Sopenharmony_ci	struct list_head sas_port_del_list;
24362306a36Sopenharmony_ci	enum   sas_linkrate linkrate;
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	struct sas_work work;
24662306a36Sopenharmony_ci	int suspended;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci/* public: */
24962306a36Sopenharmony_ci	int id;
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	u8               sas_addr[SAS_ADDR_SIZE];
25262306a36Sopenharmony_ci	u8               attached_sas_addr[SAS_ADDR_SIZE];
25362306a36Sopenharmony_ci	enum sas_protocol   iproto;
25462306a36Sopenharmony_ci	enum sas_protocol   tproto;
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	enum sas_oob_mode oob_mode;
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	spinlock_t       phy_list_lock;
25962306a36Sopenharmony_ci	struct list_head phy_list;
26062306a36Sopenharmony_ci	int              num_phys;
26162306a36Sopenharmony_ci	u32              phy_mask;
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	struct sas_ha_struct *ha;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	struct sas_port	*port;
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	void *lldd_port;	  /* not touched by the sas class code */
26862306a36Sopenharmony_ci};
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_cistruct asd_sas_event {
27162306a36Sopenharmony_ci	struct sas_work work;
27262306a36Sopenharmony_ci	struct asd_sas_phy *phy;
27362306a36Sopenharmony_ci	int event;
27462306a36Sopenharmony_ci};
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_cistatic inline struct asd_sas_event *to_asd_sas_event(struct work_struct *work)
27762306a36Sopenharmony_ci{
27862306a36Sopenharmony_ci	struct asd_sas_event *ev = container_of(work, typeof(*ev), work.work);
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	return ev;
28162306a36Sopenharmony_ci}
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_cistatic inline void INIT_SAS_EVENT(struct asd_sas_event *ev,
28462306a36Sopenharmony_ci		void (*fn)(struct work_struct *),
28562306a36Sopenharmony_ci		struct asd_sas_phy *phy, int event)
28662306a36Sopenharmony_ci{
28762306a36Sopenharmony_ci	INIT_SAS_WORK(&ev->work, fn);
28862306a36Sopenharmony_ci	ev->phy = phy;
28962306a36Sopenharmony_ci	ev->event = event;
29062306a36Sopenharmony_ci}
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci#define SAS_PHY_SHUTDOWN_THRES   1024
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci/* The phy pretty much is controlled by the LLDD.
29562306a36Sopenharmony_ci * The class only reads those fields.
29662306a36Sopenharmony_ci */
29762306a36Sopenharmony_cistruct asd_sas_phy {
29862306a36Sopenharmony_ci/* private: */
29962306a36Sopenharmony_ci	atomic_t event_nr;
30062306a36Sopenharmony_ci	int in_shutdown;
30162306a36Sopenharmony_ci	int error;
30262306a36Sopenharmony_ci	int suspended;
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	struct sas_phy *phy;
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci/* public: */
30762306a36Sopenharmony_ci	/* The following are class:RO, driver:R/W */
30862306a36Sopenharmony_ci	int            enabled;	  /* must be set */
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci	int            id;	  /* must be set */
31162306a36Sopenharmony_ci	enum sas_protocol iproto;
31262306a36Sopenharmony_ci	enum sas_protocol tproto;
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci	enum sas_phy_role  role;
31562306a36Sopenharmony_ci	enum sas_oob_mode  oob_mode;
31662306a36Sopenharmony_ci	enum sas_linkrate linkrate;
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	u8   *sas_addr;		  /* must be set */
31962306a36Sopenharmony_ci	u8   attached_sas_addr[SAS_ADDR_SIZE]; /* class:RO, driver: R/W */
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	spinlock_t     frame_rcvd_lock;
32262306a36Sopenharmony_ci	u8             *frame_rcvd; /* must be set */
32362306a36Sopenharmony_ci	int            frame_rcvd_size;
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	spinlock_t     sas_prim_lock;
32662306a36Sopenharmony_ci	u32            sas_prim;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	struct list_head port_phy_el; /* driver:RO */
32962306a36Sopenharmony_ci	struct asd_sas_port      *port; /* Class:RW, driver: RO */
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	struct sas_ha_struct *ha; /* may be set; the class sets it anyway */
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	void *lldd_phy;		  /* not touched by the sas_class_code */
33462306a36Sopenharmony_ci};
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_cienum sas_ha_state {
33762306a36Sopenharmony_ci	SAS_HA_REGISTERED,
33862306a36Sopenharmony_ci	SAS_HA_DRAINING,
33962306a36Sopenharmony_ci	SAS_HA_ATA_EH_ACTIVE,
34062306a36Sopenharmony_ci	SAS_HA_FROZEN,
34162306a36Sopenharmony_ci	SAS_HA_RESUMING,
34262306a36Sopenharmony_ci};
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_cistruct sas_ha_struct {
34562306a36Sopenharmony_ci/* private: */
34662306a36Sopenharmony_ci	struct list_head  defer_q; /* work queued while draining */
34762306a36Sopenharmony_ci	struct mutex	  drain_mutex;
34862306a36Sopenharmony_ci	unsigned long	  state;
34962306a36Sopenharmony_ci	spinlock_t	  lock;
35062306a36Sopenharmony_ci	int		  eh_active;
35162306a36Sopenharmony_ci	wait_queue_head_t eh_wait_q;
35262306a36Sopenharmony_ci	struct list_head  eh_dev_q;
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	struct mutex disco_mutex;
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	struct Scsi_Host *shost;
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci/* public: */
35962306a36Sopenharmony_ci	char *sas_ha_name;
36062306a36Sopenharmony_ci	struct device *dev;	  /* should be set */
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci	struct workqueue_struct *event_q;
36362306a36Sopenharmony_ci	struct workqueue_struct *disco_q;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	u8 *sas_addr;		  /* must be set */
36662306a36Sopenharmony_ci	u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE];
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	spinlock_t      phy_port_lock;
36962306a36Sopenharmony_ci	struct asd_sas_phy  **sas_phy; /* array of valid pointers, must be set */
37062306a36Sopenharmony_ci	struct asd_sas_port **sas_port; /* array of valid pointers, must be set */
37162306a36Sopenharmony_ci	int             num_phys; /* must be set, gt 0, static */
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	int strict_wide_ports; /* both sas_addr and attached_sas_addr must match
37462306a36Sopenharmony_ci				* their siblings when forming wide ports */
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci	void *lldd_ha;		  /* not touched by sas class code */
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci	struct list_head eh_done_q;  /* complete via scsi_eh_flush_done_q */
37962306a36Sopenharmony_ci	struct list_head eh_ata_q; /* scmds to promote from sas to ata eh */
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	int event_thres;
38262306a36Sopenharmony_ci};
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci#define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata)
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_cistatic inline struct domain_device *
38762306a36Sopenharmony_cistarget_to_domain_dev(struct scsi_target *starget) {
38862306a36Sopenharmony_ci	return starget->hostdata;
38962306a36Sopenharmony_ci}
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_cistatic inline struct domain_device *
39262306a36Sopenharmony_cisdev_to_domain_dev(struct scsi_device *sdev) {
39362306a36Sopenharmony_ci	return starget_to_domain_dev(sdev->sdev_target);
39462306a36Sopenharmony_ci}
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_cistatic inline struct ata_device *sas_to_ata_dev(struct domain_device *dev)
39762306a36Sopenharmony_ci{
39862306a36Sopenharmony_ci	return &dev->sata_dev.ap->link.device[0];
39962306a36Sopenharmony_ci}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_cistatic inline struct domain_device *
40262306a36Sopenharmony_cicmd_to_domain_dev(struct scsi_cmnd *cmd)
40362306a36Sopenharmony_ci{
40462306a36Sopenharmony_ci	return sdev_to_domain_dev(cmd->device);
40562306a36Sopenharmony_ci}
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_civoid sas_hash_addr(u8 *hashed, const u8 *sas_addr);
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci/* Before calling a notify event, LLDD should use this function
41062306a36Sopenharmony_ci * when the link is severed (possibly from its tasklet).
41162306a36Sopenharmony_ci * The idea is that the Class only reads those, while the LLDD,
41262306a36Sopenharmony_ci * can R/W these (thus avoiding a race).
41362306a36Sopenharmony_ci */
41462306a36Sopenharmony_cistatic inline void sas_phy_disconnected(struct asd_sas_phy *phy)
41562306a36Sopenharmony_ci{
41662306a36Sopenharmony_ci	phy->oob_mode = OOB_NOT_CONNECTED;
41762306a36Sopenharmony_ci	phy->linkrate = SAS_LINK_RATE_UNKNOWN;
41862306a36Sopenharmony_ci}
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_cistatic inline unsigned int to_sas_gpio_od(int device, int bit)
42162306a36Sopenharmony_ci{
42262306a36Sopenharmony_ci	return 3 * device + bit;
42362306a36Sopenharmony_ci}
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_cistatic inline void sas_put_local_phy(struct sas_phy *phy)
42662306a36Sopenharmony_ci{
42762306a36Sopenharmony_ci	put_device(&phy->dev);
42862306a36Sopenharmony_ci}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci#ifdef CONFIG_SCSI_SAS_HOST_SMP
43162306a36Sopenharmony_ciint try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count);
43262306a36Sopenharmony_ci#else
43362306a36Sopenharmony_cistatic inline int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count)
43462306a36Sopenharmony_ci{
43562306a36Sopenharmony_ci	return -1;
43662306a36Sopenharmony_ci}
43762306a36Sopenharmony_ci#endif
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci/* ---------- Tasks ---------- */
44062306a36Sopenharmony_ci/*
44162306a36Sopenharmony_ci      service_response |  SAS_TASK_COMPLETE  |  SAS_TASK_UNDELIVERED |
44262306a36Sopenharmony_ci  exec_status          |                     |                       |
44362306a36Sopenharmony_ci  ---------------------+---------------------+-----------------------+
44462306a36Sopenharmony_ci       SAM_...         |         X           |                       |
44562306a36Sopenharmony_ci       DEV_NO_RESPONSE |         X           |           X           |
44662306a36Sopenharmony_ci       INTERRUPTED     |         X           |                       |
44762306a36Sopenharmony_ci       QUEUE_FULL      |                     |           X           |
44862306a36Sopenharmony_ci       DEVICE_UNKNOWN  |                     |           X           |
44962306a36Sopenharmony_ci       SG_ERR          |                     |           X           |
45062306a36Sopenharmony_ci  ---------------------+---------------------+-----------------------+
45162306a36Sopenharmony_ci */
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_cienum service_response {
45462306a36Sopenharmony_ci	SAS_TASK_COMPLETE,
45562306a36Sopenharmony_ci	SAS_TASK_UNDELIVERED = -1,
45662306a36Sopenharmony_ci};
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_cienum exec_status {
45962306a36Sopenharmony_ci	/*
46062306a36Sopenharmony_ci	 * Values 0..0x7f are used to return the SAM_STAT_* codes.  To avoid
46162306a36Sopenharmony_ci	 * 'case value not in enumerated type' compiler warnings every value
46262306a36Sopenharmony_ci	 * returned through the exec_status enum needs an alias with the SAS_
46362306a36Sopenharmony_ci	 * prefix here.
46462306a36Sopenharmony_ci	 */
46562306a36Sopenharmony_ci	SAS_SAM_STAT_GOOD = SAM_STAT_GOOD,
46662306a36Sopenharmony_ci	SAS_SAM_STAT_BUSY = SAM_STAT_BUSY,
46762306a36Sopenharmony_ci	SAS_SAM_STAT_TASK_ABORTED = SAM_STAT_TASK_ABORTED,
46862306a36Sopenharmony_ci	SAS_SAM_STAT_CHECK_CONDITION = SAM_STAT_CHECK_CONDITION,
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci	SAS_DEV_NO_RESPONSE = 0x80,
47162306a36Sopenharmony_ci	SAS_DATA_UNDERRUN,
47262306a36Sopenharmony_ci	SAS_DATA_OVERRUN,
47362306a36Sopenharmony_ci	SAS_INTERRUPTED,
47462306a36Sopenharmony_ci	SAS_QUEUE_FULL,
47562306a36Sopenharmony_ci	SAS_DEVICE_UNKNOWN,
47662306a36Sopenharmony_ci	SAS_OPEN_REJECT,
47762306a36Sopenharmony_ci	SAS_OPEN_TO,
47862306a36Sopenharmony_ci	SAS_PROTO_RESPONSE,
47962306a36Sopenharmony_ci	SAS_PHY_DOWN,
48062306a36Sopenharmony_ci	SAS_NAK_R_ERR,
48162306a36Sopenharmony_ci	SAS_PENDING,
48262306a36Sopenharmony_ci	SAS_ABORTED_TASK,
48362306a36Sopenharmony_ci};
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci/* When a task finishes with a response, the LLDD examines the
48662306a36Sopenharmony_ci * response:
48762306a36Sopenharmony_ci *	- For an ATA task task_status_struct::stat is set to
48862306a36Sopenharmony_ci * SAS_PROTO_RESPONSE, and the task_status_struct::buf is set to the
48962306a36Sopenharmony_ci * contents of struct ata_task_resp.
49062306a36Sopenharmony_ci *	- For SSP tasks, if no data is present or status/TMF response
49162306a36Sopenharmony_ci * is valid, task_status_struct::stat is set.  If data is present
49262306a36Sopenharmony_ci * (SENSE data), the LLDD copies up to SAS_STATUS_BUF_SIZE, sets
49362306a36Sopenharmony_ci * task_status_struct::buf_valid_size, and task_status_struct::stat is
49462306a36Sopenharmony_ci * set to SAM_CHECK_COND.
49562306a36Sopenharmony_ci *
49662306a36Sopenharmony_ci * "buf" has format SCSI Sense for SSP task, or struct ata_task_resp
49762306a36Sopenharmony_ci * for ATA task.
49862306a36Sopenharmony_ci *
49962306a36Sopenharmony_ci * "frame_len" is the total frame length, which could be more or less
50062306a36Sopenharmony_ci * than actually copied.
50162306a36Sopenharmony_ci *
50262306a36Sopenharmony_ci * Tasks ending with response, always set the residual field.
50362306a36Sopenharmony_ci */
50462306a36Sopenharmony_cistruct ata_task_resp {
50562306a36Sopenharmony_ci	u16  frame_len;
50662306a36Sopenharmony_ci	u8   ending_fis[ATA_RESP_FIS_SIZE];	  /* dev to host or data-in */
50762306a36Sopenharmony_ci};
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci#define SAS_STATUS_BUF_SIZE 96
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_cistruct task_status_struct {
51262306a36Sopenharmony_ci	enum service_response resp;
51362306a36Sopenharmony_ci	enum exec_status      stat;
51462306a36Sopenharmony_ci	int  buf_valid_size;
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	u8   buf[SAS_STATUS_BUF_SIZE];
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	u32  residual;
51962306a36Sopenharmony_ci	enum sas_open_rej_reason open_rej_reason;
52062306a36Sopenharmony_ci};
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci/* ATA and ATAPI task queuable to a SAS LLDD.
52362306a36Sopenharmony_ci */
52462306a36Sopenharmony_cistruct sas_ata_task {
52562306a36Sopenharmony_ci	struct host_to_dev_fis fis;
52662306a36Sopenharmony_ci	u8     atapi_packet[16];  /* 0 if not ATAPI task */
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	u8     dma_xfer:1;	  /* PIO:0 or DMA:1 */
52962306a36Sopenharmony_ci	u8     use_ncq:1;
53062306a36Sopenharmony_ci	u8     return_fis_on_success:1;
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	u8     device_control_reg_update:1;
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci	bool   force_phy;
53562306a36Sopenharmony_ci	int    force_phy_id;
53662306a36Sopenharmony_ci};
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci/* LLDDs rely on these values */
53962306a36Sopenharmony_cienum sas_internal_abort {
54062306a36Sopenharmony_ci	SAS_INTERNAL_ABORT_SINGLE	= 0,
54162306a36Sopenharmony_ci	SAS_INTERNAL_ABORT_DEV		= 1,
54262306a36Sopenharmony_ci};
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_cistruct sas_internal_abort_task {
54562306a36Sopenharmony_ci	enum sas_internal_abort type;
54662306a36Sopenharmony_ci	unsigned int qid;
54762306a36Sopenharmony_ci	u16 tag;
54862306a36Sopenharmony_ci};
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_cistruct sas_smp_task {
55162306a36Sopenharmony_ci	struct scatterlist smp_req;
55262306a36Sopenharmony_ci	struct scatterlist smp_resp;
55362306a36Sopenharmony_ci};
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_cienum task_attribute {
55662306a36Sopenharmony_ci	TASK_ATTR_SIMPLE = 0,
55762306a36Sopenharmony_ci	TASK_ATTR_HOQ    = 1,
55862306a36Sopenharmony_ci	TASK_ATTR_ORDERED= 2,
55962306a36Sopenharmony_ci	TASK_ATTR_ACA    = 4,
56062306a36Sopenharmony_ci};
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_cistruct sas_ssp_task {
56362306a36Sopenharmony_ci	u8     LUN[8];
56462306a36Sopenharmony_ci	enum   task_attribute task_attr;
56562306a36Sopenharmony_ci	struct scsi_cmnd *cmd;
56662306a36Sopenharmony_ci};
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_cistruct sas_tmf_task {
56962306a36Sopenharmony_ci	u8 tmf;
57062306a36Sopenharmony_ci	u16 tag_of_task_to_be_managed;
57162306a36Sopenharmony_ci};
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_cistruct sas_task {
57462306a36Sopenharmony_ci	struct domain_device *dev;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	spinlock_t   task_state_lock;
57762306a36Sopenharmony_ci	unsigned     task_state_flags;
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	enum   sas_protocol      task_proto;
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci	union {
58262306a36Sopenharmony_ci		struct sas_ata_task ata_task;
58362306a36Sopenharmony_ci		struct sas_smp_task smp_task;
58462306a36Sopenharmony_ci		struct sas_ssp_task ssp_task;
58562306a36Sopenharmony_ci		struct sas_internal_abort_task abort_task;
58662306a36Sopenharmony_ci	};
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	struct scatterlist *scatter;
58962306a36Sopenharmony_ci	int    num_scatter;
59062306a36Sopenharmony_ci	u32    total_xfer_len;
59162306a36Sopenharmony_ci	u8     data_dir:2;	  /* Use PCI_DMA_... */
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci	struct task_status_struct task_status;
59462306a36Sopenharmony_ci	void   (*task_done)(struct sas_task *);
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	void   *lldd_task;	  /* for use by LLDDs */
59762306a36Sopenharmony_ci	void   *uldd_task;
59862306a36Sopenharmony_ci	struct sas_task_slow *slow_task;
59962306a36Sopenharmony_ci	struct sas_tmf_task *tmf;
60062306a36Sopenharmony_ci};
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_cistruct sas_task_slow {
60362306a36Sopenharmony_ci	/* standard/extra infrastructure for slow path commands (SMP and
60462306a36Sopenharmony_ci	 * internal lldd commands
60562306a36Sopenharmony_ci	 */
60662306a36Sopenharmony_ci	struct timer_list     timer;
60762306a36Sopenharmony_ci	struct completion     completion;
60862306a36Sopenharmony_ci	struct sas_task       *task;
60962306a36Sopenharmony_ci};
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci#define SAS_TASK_STATE_PENDING      1
61262306a36Sopenharmony_ci#define SAS_TASK_STATE_DONE         2
61362306a36Sopenharmony_ci#define SAS_TASK_STATE_ABORTED      4
61462306a36Sopenharmony_ci#define SAS_TASK_NEED_DEV_RESET     8
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_cistatic inline bool sas_is_internal_abort(struct sas_task *task)
61762306a36Sopenharmony_ci{
61862306a36Sopenharmony_ci	return task->task_proto == SAS_PROTOCOL_INTERNAL_ABORT;
61962306a36Sopenharmony_ci}
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_cistatic inline struct request *sas_task_find_rq(struct sas_task *task)
62262306a36Sopenharmony_ci{
62362306a36Sopenharmony_ci	struct scsi_cmnd *scmd;
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci	if (task->task_proto & SAS_PROTOCOL_STP_ALL) {
62662306a36Sopenharmony_ci		struct ata_queued_cmd *qc = task->uldd_task;
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci		scmd = qc ? qc->scsicmd : NULL;
62962306a36Sopenharmony_ci	} else {
63062306a36Sopenharmony_ci		scmd = task->uldd_task;
63162306a36Sopenharmony_ci	}
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci	if (!scmd)
63462306a36Sopenharmony_ci		return NULL;
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci	return scsi_cmd_to_rq(scmd);
63762306a36Sopenharmony_ci}
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_cistruct sas_domain_function_template {
64062306a36Sopenharmony_ci	/* The class calls these to notify the LLDD of an event. */
64162306a36Sopenharmony_ci	void (*lldd_port_formed)(struct asd_sas_phy *);
64262306a36Sopenharmony_ci	void (*lldd_port_deformed)(struct asd_sas_phy *);
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci	/* The class calls these when a device is found or gone. */
64562306a36Sopenharmony_ci	int  (*lldd_dev_found)(struct domain_device *);
64662306a36Sopenharmony_ci	void (*lldd_dev_gone)(struct domain_device *);
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	int (*lldd_execute_task)(struct sas_task *, gfp_t gfp_flags);
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci	/* Task Management Functions. Must be called from process context. */
65162306a36Sopenharmony_ci	int (*lldd_abort_task)(struct sas_task *);
65262306a36Sopenharmony_ci	int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
65362306a36Sopenharmony_ci	int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
65462306a36Sopenharmony_ci	int (*lldd_I_T_nexus_reset)(struct domain_device *);
65562306a36Sopenharmony_ci	int (*lldd_ata_check_ready)(struct domain_device *);
65662306a36Sopenharmony_ci	void (*lldd_ata_set_dmamode)(struct domain_device *);
65762306a36Sopenharmony_ci	int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
65862306a36Sopenharmony_ci	int (*lldd_query_task)(struct sas_task *);
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_ci	/* Special TMF callbacks */
66162306a36Sopenharmony_ci	void (*lldd_tmf_exec_complete)(struct domain_device *dev);
66262306a36Sopenharmony_ci	void (*lldd_tmf_aborted)(struct sas_task *task);
66362306a36Sopenharmony_ci	bool (*lldd_abort_timeout)(struct sas_task *task, void *data);
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	/* Port and Adapter management */
66662306a36Sopenharmony_ci	int (*lldd_clear_nexus_port)(struct asd_sas_port *);
66762306a36Sopenharmony_ci	int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci	/* Phy management */
67062306a36Sopenharmony_ci	int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func, void *);
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	/* GPIO support */
67362306a36Sopenharmony_ci	int (*lldd_write_gpio)(struct sas_ha_struct *, u8 reg_type,
67462306a36Sopenharmony_ci			       u8 reg_index, u8 reg_count, u8 *write_data);
67562306a36Sopenharmony_ci};
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ciextern int sas_register_ha(struct sas_ha_struct *);
67862306a36Sopenharmony_ciextern int sas_unregister_ha(struct sas_ha_struct *);
67962306a36Sopenharmony_ciextern void sas_prep_resume_ha(struct sas_ha_struct *sas_ha);
68062306a36Sopenharmony_ciextern void sas_resume_ha(struct sas_ha_struct *sas_ha);
68162306a36Sopenharmony_ciextern void sas_resume_ha_no_sync(struct sas_ha_struct *sas_ha);
68262306a36Sopenharmony_ciextern void sas_suspend_ha(struct sas_ha_struct *sas_ha);
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ciint sas_set_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates);
68562306a36Sopenharmony_ciint sas_phy_reset(struct sas_phy *phy, int hard_reset);
68662306a36Sopenharmony_ciint sas_phy_enable(struct sas_phy *phy, int enable);
68762306a36Sopenharmony_ciextern int sas_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
68862306a36Sopenharmony_ciextern int sas_target_alloc(struct scsi_target *);
68962306a36Sopenharmony_ciextern int sas_slave_configure(struct scsi_device *);
69062306a36Sopenharmony_ciextern int sas_change_queue_depth(struct scsi_device *, int new_depth);
69162306a36Sopenharmony_ciextern int sas_bios_param(struct scsi_device *, struct block_device *,
69262306a36Sopenharmony_ci			  sector_t capacity, int *hsc);
69362306a36Sopenharmony_ciint sas_execute_internal_abort_single(struct domain_device *device,
69462306a36Sopenharmony_ci				      u16 tag, unsigned int qid,
69562306a36Sopenharmony_ci				      void *data);
69662306a36Sopenharmony_ciint sas_execute_internal_abort_dev(struct domain_device *device,
69762306a36Sopenharmony_ci				   unsigned int qid, void *data);
69862306a36Sopenharmony_ciextern struct scsi_transport_template *
69962306a36Sopenharmony_cisas_domain_attach_transport(struct sas_domain_function_template *);
70062306a36Sopenharmony_ciextern struct device_attribute dev_attr_phy_event_threshold;
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ciint  sas_discover_root_expander(struct domain_device *);
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ciint  sas_ex_revalidate_domain(struct domain_device *);
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_civoid sas_unregister_domain_devices(struct asd_sas_port *port, int gone);
70762306a36Sopenharmony_civoid sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *);
70862306a36Sopenharmony_civoid sas_discover_event(struct asd_sas_port *, enum discover_event ev);
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ciint  sas_discover_end_dev(struct domain_device *);
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_civoid sas_unregister_dev(struct asd_sas_port *port, struct domain_device *);
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_civoid sas_init_dev(struct domain_device *);
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_civoid sas_task_abort(struct sas_task *);
71762306a36Sopenharmony_ciint sas_eh_abort_handler(struct scsi_cmnd *cmd);
71862306a36Sopenharmony_ciint sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
71962306a36Sopenharmony_ciint sas_eh_target_reset_handler(struct scsi_cmnd *cmd);
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ciextern void sas_target_destroy(struct scsi_target *);
72262306a36Sopenharmony_ciextern int sas_slave_alloc(struct scsi_device *);
72362306a36Sopenharmony_ciextern int sas_ioctl(struct scsi_device *sdev, unsigned int cmd,
72462306a36Sopenharmony_ci		     void __user *arg);
72562306a36Sopenharmony_ciextern int sas_drain_work(struct sas_ha_struct *ha);
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ciextern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
72862306a36Sopenharmony_ci				  struct ssp_response_iu *iu);
72962306a36Sopenharmony_cistruct sas_phy *sas_get_local_phy(struct domain_device *dev);
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ciint sas_request_addr(struct Scsi_Host *shost, u8 *addr);
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ciint sas_abort_task_set(struct domain_device *dev, u8 *lun);
73462306a36Sopenharmony_ciint sas_clear_task_set(struct domain_device *dev, u8 *lun);
73562306a36Sopenharmony_ciint sas_lu_reset(struct domain_device *dev, u8 *lun);
73662306a36Sopenharmony_ciint sas_query_task(struct sas_task *task, u16 tag);
73762306a36Sopenharmony_ciint sas_abort_task(struct sas_task *task, u16 tag);
73862306a36Sopenharmony_ciint sas_find_attached_phy_id(struct expander_device *ex_dev,
73962306a36Sopenharmony_ci			     struct domain_device *dev);
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_civoid sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event,
74262306a36Sopenharmony_ci			   gfp_t gfp_flags);
74362306a36Sopenharmony_civoid sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event,
74462306a36Sopenharmony_ci			   gfp_t gfp_flags);
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci#endif /* _SASLIB_H_ */
747