2005-09-09 18:22:50 +04:00
# ifndef SCSI_TRANSPORT_SAS_H
# define SCSI_TRANSPORT_SAS_H
# include <linux/transport_class.h>
# include <linux/types.h>
2006-06-28 20:22:50 +04:00
# include <linux/mutex.h>
2005-09-09 18:22:50 +04:00
struct scsi_transport_template ;
struct sas_rphy ;
enum sas_device_type {
SAS_PHY_UNUSED ,
SAS_END_DEVICE ,
SAS_EDGE_EXPANDER_DEVICE ,
SAS_FANOUT_EXPANDER_DEVICE ,
} ;
enum sas_protocol {
SAS_PROTOCOL_SATA = 0x01 ,
SAS_PROTOCOL_SMP = 0x02 ,
SAS_PROTOCOL_STP = 0x04 ,
SAS_PROTOCOL_SSP = 0x08 ,
} ;
enum sas_linkrate {
SAS_LINK_RATE_UNKNOWN ,
SAS_PHY_DISABLED ,
SAS_LINK_RATE_FAILED ,
SAS_SATA_SPINUP_HOLD ,
SAS_SATA_PORT_SELECTOR ,
SAS_LINK_RATE_1_5_GBPS ,
SAS_LINK_RATE_3_0_GBPS ,
2006-03-02 23:12:56 +03:00
SAS_LINK_RATE_6_0_GBPS ,
2005-09-09 18:22:50 +04:00
SAS_LINK_VIRTUAL ,
} ;
struct sas_identify {
enum sas_device_type device_type ;
enum sas_protocol initiator_port_protocols ;
enum sas_protocol target_port_protocols ;
u64 sas_address ;
u8 phy_identifier ;
} ;
struct sas_phy {
struct device dev ;
int number ;
2005-09-19 23:59:42 +04:00
/* phy identification */
2005-09-09 18:22:50 +04:00
struct sas_identify identify ;
2005-09-19 23:59:42 +04:00
/* phy attributes */
2005-09-09 18:22:50 +04:00
enum sas_linkrate negotiated_linkrate ;
enum sas_linkrate minimum_linkrate_hw ;
enum sas_linkrate minimum_linkrate ;
enum sas_linkrate maximum_linkrate_hw ;
enum sas_linkrate maximum_linkrate ;
2005-09-19 23:59:42 +04:00
/* link error statistics */
u32 invalid_dword_count ;
u32 running_disparity_error_count ;
u32 loss_of_dword_sync_count ;
u32 phy_reset_problem_count ;
2006-06-28 20:22:50 +04:00
/* for the list of phys belonging to a port */
struct list_head port_siblings ;
2005-09-09 18:22:50 +04:00
} ;
# define dev_to_phy(d) \
container_of ( ( d ) , struct sas_phy , dev )
# define transport_class_to_phy(cdev) \
dev_to_phy ( ( cdev ) - > dev )
# define phy_to_shost(phy) \
dev_to_shost ( ( phy ) - > dev . parent )
struct sas_rphy {
struct device dev ;
struct sas_identify identify ;
struct list_head list ;
u32 scsi_target_id ;
} ;
# define dev_to_rphy(d) \
container_of ( ( d ) , struct sas_rphy , dev )
# define transport_class_to_rphy(cdev) \
dev_to_rphy ( ( cdev ) - > dev )
# define rphy_to_shost(rphy) \
dev_to_shost ( ( rphy ) - > dev . parent )
2006-03-04 18:10:18 +03:00
# define target_to_rphy(targ) \
dev_to_rphy ( ( targ ) - > dev . parent )
struct sas_end_device {
struct sas_rphy rphy ;
/* flags */
unsigned ready_led_meaning : 1 ;
/* parameters */
u16 I_T_nexus_loss_timeout ;
u16 initiator_response_timeout ;
} ;
# define rphy_to_end_device(r) \
container_of ( ( r ) , struct sas_end_device , rphy )
2005-09-09 18:22:50 +04:00
2006-03-13 22:50:04 +03:00
struct sas_expander_device {
int level ;
2006-07-02 20:10:18 +04:00
int next_port_id ;
2006-03-13 22:50:04 +03:00
# define SAS_EXPANDER_VENDOR_ID_LEN 8
char vendor_id [ SAS_EXPANDER_VENDOR_ID_LEN + 1 ] ;
# define SAS_EXPANDER_PRODUCT_ID_LEN 16
char product_id [ SAS_EXPANDER_PRODUCT_ID_LEN + 1 ] ;
# define SAS_EXPANDER_PRODUCT_REV_LEN 4
char product_rev [ SAS_EXPANDER_PRODUCT_REV_LEN + 1 ] ;
# define SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN 8
char component_vendor_id [ SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN + 1 ] ;
u16 component_id ;
u8 component_revision_id ;
struct sas_rphy rphy ;
} ;
# define rphy_to_expander_device(r) \
container_of ( ( r ) , struct sas_expander_device , rphy )
2005-09-19 23:59:42 +04:00
2006-06-28 20:22:50 +04:00
struct sas_port {
struct device dev ;
2006-07-02 20:10:18 +04:00
int port_identifier ;
2006-06-28 20:22:50 +04:00
int num_phys ;
2006-07-09 21:38:19 +04:00
/* port flags */
unsigned int is_backlink : 1 ;
2006-06-28 20:22:50 +04:00
/* the other end of the link */
struct sas_rphy * rphy ;
struct mutex phy_list_mutex ;
struct list_head phy_list ;
} ;
# define dev_to_sas_port(d) \
container_of ( ( d ) , struct sas_port , dev )
# define transport_class_to_sas_port(cdev) \
dev_to_sas_port ( ( cdev ) - > dev )
2005-09-19 23:59:42 +04:00
/* The functions by which the transport class and the driver communicate */
struct sas_function_template {
int ( * get_linkerrors ) ( struct sas_phy * ) ;
2006-02-16 15:31:47 +03:00
int ( * get_enclosure_identifier ) ( struct sas_rphy * , u64 * ) ;
int ( * get_bay_identifier ) ( struct sas_rphy * ) ;
2005-10-19 22:01:31 +04:00
int ( * phy_reset ) ( struct sas_phy * , int ) ;
2005-09-19 23:59:42 +04:00
} ;
2006-06-28 20:22:50 +04:00
void sas_remove_children ( struct device * ) ;
2005-09-09 18:22:50 +04:00
extern void sas_remove_host ( struct Scsi_Host * ) ;
extern struct sas_phy * sas_phy_alloc ( struct device * , int ) ;
extern void sas_phy_free ( struct sas_phy * ) ;
extern int sas_phy_add ( struct sas_phy * ) ;
extern void sas_phy_delete ( struct sas_phy * ) ;
extern int scsi_is_sas_phy ( const struct device * ) ;
2006-06-28 20:22:50 +04:00
extern struct sas_rphy * sas_end_device_alloc ( struct sas_port * ) ;
extern struct sas_rphy * sas_expander_alloc ( struct sas_port * , enum sas_device_type ) ;
2005-09-09 18:22:50 +04:00
void sas_rphy_free ( struct sas_rphy * ) ;
extern int sas_rphy_add ( struct sas_rphy * ) ;
extern void sas_rphy_delete ( struct sas_rphy * ) ;
extern int scsi_is_sas_rphy ( const struct device * ) ;
2006-06-28 20:22:50 +04:00
struct sas_port * sas_port_alloc ( struct device * , int ) ;
2006-07-02 20:10:18 +04:00
struct sas_port * sas_port_alloc_num ( struct device * ) ;
2006-06-28 20:22:50 +04:00
int sas_port_add ( struct sas_port * ) ;
void sas_port_free ( struct sas_port * ) ;
void sas_port_delete ( struct sas_port * ) ;
void sas_port_add_phy ( struct sas_port * , struct sas_phy * ) ;
void sas_port_delete_phy ( struct sas_port * , struct sas_phy * ) ;
2006-07-09 21:38:19 +04:00
void sas_port_mark_backlink ( struct sas_port * ) ;
2006-06-28 20:22:50 +04:00
int scsi_is_sas_port ( const struct device * ) ;
2005-09-09 18:22:50 +04:00
extern struct scsi_transport_template *
sas_attach_transport ( struct sas_function_template * ) ;
extern void sas_release_transport ( struct scsi_transport_template * ) ;
2006-03-04 18:10:18 +03:00
int sas_read_port_mode_page ( struct scsi_device * ) ;
2005-09-09 18:22:50 +04:00
2006-03-13 22:50:04 +03:00
static inline int
scsi_is_sas_expander_device ( struct device * dev )
{
struct sas_rphy * rphy ;
if ( ! scsi_is_sas_rphy ( dev ) )
return 0 ;
rphy = dev_to_rphy ( dev ) ;
return rphy - > identify . device_type = = SAS_FANOUT_EXPANDER_DEVICE | |
rphy - > identify . device_type = = SAS_EDGE_EXPANDER_DEVICE ;
}
2006-08-25 22:48:18 +04:00
# define scsi_is_sas_phy_local(phy) scsi_is_host_device((phy)->dev.parent)
2005-09-09 18:22:50 +04:00
# endif /* SCSI_TRANSPORT_SAS_H */