接着分析pm8001_pci_probe中调用的pm8001_pci_alloc和scsi_scan_host。先分析pm8001_pci_alloc,在下一篇文章中分析scsi_scan_host
注意1:pm8001_ioremap - remap the pci high physical address to kernal virtual address so that we can access them.
pm8001_ioremap的代码如下:
先把pm8001_pci_alloc的代码贴在下面:
/**
* pm8001_pci_alloc - initialize our ha card structure
* @pdev: pci device.
* @ent: ent
* @shost: scsi host struct which has been initialized before.
*/
static struct pm8001_hba_info *__devinit
pm8001_pci_alloc(struct pci_dev *pdev, u32 chip_id, struct Scsi_Host *shost)
{
struct pm8001_hba_info *pm8001_ha;//struct pm8001_hba_info represent HBA in lldd layer
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);//struct sas_ha_struct represent HBA in libsas layer
pm8001_ha = sha->lldd_ha;//mem alloced in pm8001_prep_sas_ha_init with kzalloc
if (!pm8001_ha)
return NULL;
//init part of struct pm8001_hba_info
pm8001_ha->pdev = pdev;
pm8001_ha->dev = &pdev->dev;
pm8001_ha->chip_id = chip_id;
pm8001_ha->chip = &pm8001_chips[pm8001_ha->chip_id];
pm8001_ha->irq = pdev->irq;
pm8001_ha->sas = sha;
pm8001_ha->shost = shost;
pm8001_ha->id = pm8001_id++;
pm8001_ha->logging_level = logging_level;
pm8001_ha->ses = 0x0;
sprintf(pm8001_ha->name, "%s%d", DRV_NAME, pm8001_ha->id);
//remap the pci high physical address to kernel virtual
pm8001_ioremap(pm8001_ha);//注意1
if (!pm8001_alloc(pm8001_ha))//注意2
return pm8001_ha;
pm8001_free(pm8001_ha);
return NULL;
}
注意1:pm8001_ioremap - remap the pci high physical address to kernal virtual address so that we can access them.
pm8001_ioremap的代码如下:
/**
* pm8001_ioremap - remap the pci high physical address to kernal virtual
* address so that we can access them.
* @pm8001_ha:our hba structure.
*/
static int pm8001_ioremap(struct pm8001_hba_info *pm8001_ha)
{
u32 bar;
u32 logicalBar = 0;
struct pci_dev *pdev;
pdev = pm8001_ha->pdev;
/* map pci mem (PMC pci base 0-3)*/
for (bar = 0; bar < 6; bar++) {
/*
** logical BARs for SPC:
** bar 0 and 1 - logical BAR0
** bar 2 and 3 - logical BAR1
** bar4 - logical BAR2
** bar5 - logical BAR3
** Skip the appropriate assignments:
*/
if ((bar == 1) || (bar == 3))
continue;
if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
pm8001_ha->io_mem[logicalBar].membase =
pci_resource_start(pdev, bar);
pm8001_ha->io_mem[logicalBar].membase &=
(u32)PCI_BASE_ADDRESS_MEM_MASK;
pm8001_ha->io_mem