mpt2sas-19.00.00.00_rhel6.5驱动笔记系列3-_scsih_probe

1. 注册一个scsi host adpter instance                                                                                                                                                                                                                                                                         shost = scsi_host_alloc(&scsih_driver_template,sizeof(struct MPT2SAS_ADAPTER));
     调用scsi_host_alloc注册一个scsi host adpter instance,传入的参数是&scsih_driver_template和sizeof(struct MPT2SAS_ADAPTER).scsih_driver_template为 struct scsi_host_template类型变量,取指针后传递给形参为sht( shost template ).sht指向struct scsi_host_template。在函数定义中将已经初始化完成的sht成员赋值给了对应的shost指向的结构体struct Scsi_Host成员。
     
2.初始化ioc指向struct MPT2SAS_ADAPTER 成员。
    2.1 将IOC指向的struct MPT2SAS_ADAPTER 成员初始化为0
   2.2 将回调函数索引赋值给IOC成员
    2.3 通过spin_lock_init初始化IOC中spinlock_t类型成员,即初始化各种成员自旋锁
   2.4 通过INIT_LIST_HEAD初始化IOC中list_head类型成员,即初始化各种成员链表


3.初始化shost参数
  3.1 调用scsi_add_host(),将scsi host作为一个dma设备加入
    scsi_add_host(shost, &pdev->dev) 
    
    static inline int __must_check scsi_add_host(struct Scsi_Host *host,
    struct device *dev)
{
return scsi_add_host_with_dma(host, dev, dev);
}
  
  
4. 创建firmware_event_thread线程
通过create_singlethread_workqueue 创建firmware_event_thread线程。


5.将 mpt2sas设置为可操作状态


 5.1 建立cpu_msix_table
   ......
   ioc->cpu_msix_table_sz = last_cpu_id + 1;
   ioc->cpu_msix_table = kzalloc(ioc->cpu_msix_table_sz, GFP_KERNEL);
   .....
   ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz,
       sizeof(resource_size_t *), GFP_KERNEL);
       
 5.2通过调用mpt2sas_base_map_resources为mpt2sas映射IO资源,设置中断
    调用pci_select_bars(pdev, IORESOURCE_MEM);选择base address register。PCIe有6个配置寄存器标示IO区域的大小和位置,分别为PCI_BASE_ADDRESS0 ~ PCI_BASE_ADDRESS5、
     调用pci_enable_device_mem(pdev)将mpt2sas作为PCIE设备激活
    调用pci_request_selected_regions(pdev, ioc->bars,MPT2SAS_DRIVER_NAME) 根据bar,选定相应的IO区域
    调用pci_enable_pcie_error_reporting(pdev);使能mpt2sas作为PCIE设备的error reporting机制
    调用pci_set_master(pdev);允许mpt2sas作为PCIe设备掌控总线控制权
    调用pci_resource_start获取IO资源首地址,调用pci_resource_len获取IO资源的大小,通过ioremap将IO资源映射到内存上。
    ioc->chip_phys = pci_resource_start(pdev, i);
   chip_phys = (u64)ioc->chip_phys;
   memap_sz = pci_resource_len(pdev, i);
   ioc->chip = ioremap(ioc->chip_phys,memap_sz);
   调用_base_mask_interrupts(ioc);禁止中断
   调用_base_get_ioc_facts(ioc, CAN_SLEEP);获取IOC状态。底层通过dollbell寄存器获取相应的状态
   调用_base_enable_msix(ioc);使能misxi
   调用pci_save_state保存mpt2sas作为PCIe设备的配置信息。


 5.3调用r = _base_get_ioc_facts(ioc, CAN_SLEEP); 获取IOC的fact状态
 
 5.4调用_base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);设置IOC为ready状态
 
 5.5调用_base_get_port_facts(ioc, i, CAN_SLEEP);获取port facts状态
 
 5.6调用_base_allocate_memory_pools(ioc, CAN_SLEEP);为各消息队列申请dma memory pool
 
 5.7为IOC中的base internal command, port_enable command,transport internal command, scsih internal command ,task management internal command , config page internal command, ctl 
 module internal command ,ctl module diag_buffer internal command 申请内存,并将这些命令的status设置为not used/MPT2_CMD_NOT_USED状态
 
 5.8调用_base_unmask_events使能一些event,并将这些event的标志位存在event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]
 

 5.9调用_base_make_ioc_operational(ioc, CAN_SLEEP);设置IOC为operational状态


6.调用 scsi_scan_host(shost); 扫描target device.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值