1.sas相关对象
(1)所有关于sas头文件,所涉及的对象和枚举
kernel/include/scsi/libsas.h
kernel/include/scsi/scsi_transport_sas.h
kernel/include/scsi/sas.h
kernel/drivers/scsi/libsas/sas_internal.h
kernel/drivers/scsi/scsi_sas_internal.h
kernel/include/scsi/libsas.h
@||- enum
@||| sas_class
@||| sas_phy_role
@||| sas_phy_type
@||| ha_event
@||| port_event
@||| phy_event
@||| discover_event
@||| routing_attribute
@||| ex_phy_state
@||| ata_command_set
@||| sas_ha_state
@||| service_response
@||| exec_status
@||| task_attribute
@||- struct
@||| ex_phy
@||| expander_device
@||| sata_device
@||| ssp_device
@||| domain_device
@||| sas_work
@||| sas_discovery_event
@||| sas_discovery
@||| asd_sas_port
@||| asd_sas_event
@||| asd_sas_phy
@||| scsi_core
@||| sas_ha_event
@||| sas_ha_struct
@||| ata_task_resp
@||| task_status_struct
@||| sas_ata_task
@||| sas_smp_task
@||| sas_ssp_task
@||| sas_task
@||| sas_task_slow
@||| sas_domain_function_template
kernel/include/scsi/scsi_transport_sas.h
@||- enum
@||| sas_linkrate
@||- struct
@||| sas_identify
@||| sas_phy
@||| sas_rphy
@||| sas_end_device
@||| sas_expander_device
@||| sas_port
@||| sas_phy_linkrates
@||| sas_function_template
kernel/include/scsi/sas.h
@||- enum
@||| sas_oob_mode
@||| sas_device_type
@||| sas_protocol
@||| phy_func
@||| sas_prim
@||| sas_open_rej_reason
@||| sas_gpio_reg_type
@||- struct
@||| dev_to_host_fis
@||| host_to_dev_fis
@||| sas_identify_frame
@||| ssp_frame_hdr
@||| ssp_response_iu
@||| report_general_resp
@||| discover_resp
@||| report_phy_sata_resp
@||| smp_resp
@||| sas_identify_frame
@||| ssp_frame_hdr
@||| ssp_response_iu
@||| report_general_resp
@||| discover_resp
@||| report_phy_sata_resp
@||| smp_resp
kernel/drivers/scsi/libsas/sas_internal.h
@||- struct
@||| sas_phy_data
kernel/drivers/scsi/scsi_sas_internal.h
@||- struct
@||| sas_internal
(2)struct sas_internal
这个对象能拿到下面对象的函数指针:
struct scsi_transport_template t;
struct sas_function_template *f;
struct sas_domain_function_template *dft;
struct sas_internal {
struct scsi_transport_template t;
struct sas_function_template *f;
struct sas_domain_function_template *dft;
struct device_attribute private_host_attrs[SAS_HOST_ATTRS];
struct device_attribute private_phy_attrs[SAS_PHY_ATTRS];
struct device_attribute private_port_attrs[SAS_PORT_ATTRS];
struct device_attribute private_rphy_attrs[SAS_RPORT_ATTRS];
struct device_attribute private_end_dev_attrs[SAS_END_DEV_ATTRS];
struct device_attribute private_expander_attrs[SAS_EXPANDER_ATTRS];
struct transport_container phy_attr_cont;
struct transport_container port_attr_cont;
struct transport_container rphy_attr_cont;
struct transport_container end_dev_attr_cont;
struct transport_container expander_attr_cont;
/*
* The array of null terminated pointers to attributes
* needed by scsi_sysfs.c
*/
struct device_attribute *host_attrs[SAS_HOST_ATTRS + 1];
struct device_attribute *phy_attrs[SAS_PHY_ATTRS + 1];
struct device_attribute *port_attrs[SAS_PORT_ATTRS + 1];
struct device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1];
struct device_attribute *end_dev_attrs[SAS_END_DEV_ATTRS + 1];
struct device_attribute *expander_attrs[SAS_EXPANDER_ATTRS + 1];
};
1.struct scsi_transport_template
重点函数stt->eh_strategy_handler = sas_scsi_recover_host;
struct scsi_transport_template {
/* the attribute containers */
struct transport_container host_attrs;
struct transport_container target_attrs;
struct transport_container device_attrs;
/*
* If set, called from sysfs and legacy procfs rescanning code.
*/
int (*user_scan)(struct Scsi_Host *, uint, uint, uint);
/* The size of the specific transport attribute structure (a
* space of this size will be left at the end of the
* scsi_* structure */
int device_size;
int device_private_offset;
int target_size;
int target_private_offset;
int host_size;
/* no private offset for the host; there's an alternative mechanism */
/*
* True if the transport wants to use a host-based work-queue
*/
unsigned int create_work_queue : 1;
/*
* Allows a transport to override the default error handler.
*/
void (* eh_strategy_handler)(struct Scsi_Host *);
/*
* This is an optional routine that allows the transport to become
* involved when a scsi io timer fires. The return value tells the
* timer routine how to finish the io timeout handling:
* EH_HANDLED: I fixed the error, please complete the command
* EH_RESET_TIMER: I need more time, reset the timer and
* begin counting again
* EH_NOT_HANDLED Begin normal error recovery
*/
enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *);
/*
* Used as callback for the completion of i_t_nexus request
* for target drivers.
*/
int (* it_nexus_response)(struct Scsi_Host *, u64, int);
/*
* Used as callback for the completion of task management
* request for target drivers.
*/
int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int);
};
struct scsi_transport_template *
sas_domain_attach_transport(struct sas_domain_function_template *dft)
{
struct scsi_transport_template *stt = sas_attach_transport(&sft);
stt->create_work_queue = 1;
stt->eh_timed_out = sas_scsi_timed_out;
stt->eh_strategy_handler = sas_scsi_recover_host;
return stt;
}
2.struct sas_function_template
/* The functions by which the transport class and the driver communicate */
struct sas_function_template {
int (*get_linkerrors)(struct sas_phy *);
int (*get_enclosure_identifier)(struct sas_rphy *, u64 *);
int (*get_bay_identifier)(struct sas_rphy *);
int (*phy_reset)(struct sas_phy *, int);
int (*phy_enable)(struct sas_phy *, int);
int (*phy_setup)(struct sas_phy *);
void (*phy_release)(struct sas_phy *);
int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *);
int (*smp_handler)(struct Scsi_Host *, struct sas_rphy *, struct request *);
};
struct scsi_transport_template *
sas_domain_attach_transport(struct sas_domain_function_template *dft)
{
struct scsi_transport_template *stt = sas_attach_transport(&sft);
}
/**
* sas_attach_transport - instantiate SAS transport template
* @ft: SAS transport class function template
*/
struct scsi_transport_template *
sas_attach_transport(struct sas_function_template *ft)
{
struct sas_internal *i;
int count;
i = kzalloc(sizeof(struct sas_internal), GFP_KERNEL);
i->f = ft;
return &i->t;
}
3.struct sas_domain_function_template
该函数指针调用到8001驱动那边。
struct sas_domain_function_template {
/* The class calls these to notify the LLDD of an event. */
void (*lldd_port_formed)(struct asd_sas_phy *);
void (*lldd_port_deformed)(struct asd_sas_phy *);
/* The class calls these when a device is found or gone. */
int (*lldd_dev_found)(struct domain_device *);
void (*lldd_dev_gone)(struct domain_device *);
int (*lldd_execute_task)(struct sas_task *, int num,
gfp_t gfp_flags);
/* Task Management Functions. Must be called from process context. */
int (*lldd_abort_task)(struct sas_task *);
int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
int (*lldd_I_T_nexus_reset)(struct domain_device *);
int (*lldd_ata_check_ready)(struct domain_device *);
void (*lldd_ata_set_dmamode)(struct domain_device *);
int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
int (*lldd_query_task)(struct sas_task *);
/* Port and Adapter management */
int (*lldd_clear_nexus_port)(struct asd_sas_port *);
int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);
/* Phy management */
int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func, void *);
/* GPIO support */
int (*lldd_write_gpio)(struct sas_ha_struct *, u8 reg_type,
u8 reg_index, u8 reg_count, u8 *write_data);
};
/**
* Sas layer call this function to execute specific task.
*/
static struct sas_domain_function_template pm8001_transport_ops = {
.lldd_dev_found = pm8001_dev_found,
.lldd_dev_gone = pm8001_dev_gone,
.lldd_execute_task = pm8001_queue_command,
.lldd_control_phy = pm8001_phy_control,
.lldd_abort_task = pm8001_abort_task,
.lldd_abort_task_set = pm8001_abort_task_set,
.lldd_clear_aca = pm8001_clear_aca,
.lldd_clear_task_set = pm8001_clear_task_set,
.lldd_I_T_nexus_reset = pm8001_I_T_nexus_reset,
.lldd_lu_reset = pm8001_lu_reset,
.lldd_query_task = pm8001_query_task,
};
static struct scsi_transport_template *pm8001_stt;
/**
* pm8001_init - initialize scsi transport template
*/
static int __init pm8001_init(void)
{
pm8001_stt = sas_domain_attach_transport(&pm8001_transport_ops);
}
struct scsi_transport_template *
sas_domain_attach_transport(struct sas_domain_function_template *dft)
{
struct sas_internal *i;
i->dft = dft;
}
(2)