sas协议内核代码分析

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)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux技术芯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值