- fusion - inactive raid support, and raid event bug fix's
Subsystems (2)
PATCH 5/9 - fusion - inactive raid support, and raid event bug fix's
inactive raid support, e.g. exposing hidden raid components belonging to a volume that are inactive. Also misc bug fix's for various raid asyn events.
Signed-off-by Eric Moore <[email protected]>
drivers/message/fusion/mptbase.c +222 -56
@@ -184,6 +184,7 @@ static void mpt_fc_log_info(MPT_ADAPTERstatic void mpt_spi_log_info (MPT_ADAPTER *ioc,u32 log_info);static void mpt_sas_log_info (MPT_ADAPTER *ioc,u32 log_info);static int mpt_read_ioc_pg_3 (MPT_ADAPTER *ioc); +static void mpt_inactive_raid_list_free (MPT_ADAPTER *ioc);/* module entry point */ static int __init fusion_init (void );
@@ -1815,6 +1816,13 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u3* and we try GetLanConfigPages again... */ if ((ret ==0 ) && (reason ==MPT_HOSTEVENT_IOC_BRINGUP )) { + +/* +* Initalize link list for inactive raid volumes. +*/ +init_MUTEX (&ioc->raid_data.inactive_list_mutex); +INIT_LIST_HEAD (&ioc->raid_data.inactive_list); +if (ioc->bus_type ==SAS ) {/* clear persistency table */
@@ -2021,6 +2029,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) }kfree (ioc->spi_data.nvram); +mpt_inactive_raid_list_free (ioc); +kfree (ioc->raid_data.pIocPg2);kfree (ioc->raid_data.pIocPg3); ioc->spi_data.nvram =NULL ; ioc->raid_data.pIocPg3 =NULL ;
@@ -2417,6 +2427,9 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepF facts->FWVersion.Word =le32_to_cpu (facts->FWVersion.Word); facts->ProductID =le16_to_cpu (facts->ProductID); +if ((ioc->facts.ProductID &MPI_FW_HEADER_PID_PROD_MASK ) + >MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) + ioc->ir_firmware =1 ; facts->CurrentHostMfaHighAddr =le32_to_cpu (facts->CurrentHostMfaHighAddr); facts->GlobalCredits =le16_to_cpu (facts->GlobalCredits);
@@ -2735,9 +2748,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int por/* RAID FW may take a long time to enable */ -if (((ioc->facts.ProductID &MPI_FW_HEADER_PID_PROD_MASK ) - >MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) || - (ioc->bus_type ==SAS )) { +if (ioc->ir_firmware || ioc->bus_type ==SAS ) { rc =mpt_handshake_req_reply_wait (ioc, req_sz, (u32 *)&port_enable, reply_sz, (u16 *)&reply_buf,300 /*seconds*/ , sleepFlag);
@@ -4325,8 +4336,8 @@ mptbase_raid_process_event_data(MPT_ADAPif ((reason >=MPI_EVENT_RAID_RC_PHYSDISK_CREATED && reason <=MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED ) || (reason ==MPI_EVENT_RAID_RC_SMART_DATA )) { -printk (MYIOC_s_INFO_FMT"RAID STATUS CHANGE for PhysDisk %d\n" , - ioc->name, disk); +printk (MYIOC_s_INFO_FMT"RAID STATUS CHANGE for PhysDisk %d id=%d\n" , + ioc->name, disk, volume); }else {printk (MYIOC_s_INFO_FMT"RAID STATUS CHANGE for VolumeID %d\n" , ioc->name, volume);
@@ -4727,7 +4738,187 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTEreturn 0 ; } -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/** +* mpt_inactive_raid_list_free +* +* This clears this link list. +* +* @ioc - pointer to per adapter structure +* +**/ +static void +mpt_inactive_raid_list_free (MPT_ADAPTER *ioc) +{ +struct inactive_raid_component_info *component_info, *pNext; + +if (list_empty (&ioc->raid_data.inactive_list)) +return ; + +down (&ioc->raid_data.inactive_list_mutex); +list_for_each_entry_safe (component_info, pNext, + &ioc->raid_data.inactive_list, list) { +list_del (&component_info->list); +kfree (component_info); + } +up (&ioc->raid_data.inactive_list_mutex); +} + +/** +* mpt_inactive_raid_volumes +* +* This sets up link list of phy_disk_nums for devices belonging in an inactive volume +* +* @ioc - pointer to per adapter structure +* @channel - volume channel +* @id - volume target id +* +* +**/ +static void +mpt_inactive_raid_volumes (MPT_ADAPTER *ioc,u8 channel,u8 id) +{ +CONFIGPARMS cfg; +ConfigPageHeader_t hdr; +dma_addr_t dma_handle; +pRaidVolumePage0_t buffer =NULL ; +int i; +RaidPhysDiskPage0_t phys_disk; +struct inactive_raid_component_info *component_info; +int handle_inactive_volumes; + +memset (&cfg,0 ,sizeof (CONFIGPARMS )); +memset (&hdr,0 ,sizeof (ConfigPageHeader_t)); + hdr.PageType =MPI_CONFIG_PAGETYPE_RAID_VOLUME ; + cfg.pageAddr = (channel <<8 ) + id; + cfg.cfghdr.hdr = &hdr; + cfg.action =MPI_CONFIG_ACTION_PAGE_HEADER ; + +if (mpt_config (ioc, &cfg) !=0 ) + goto out; + +if (!hdr.PageLength) + goto out; + + buffer =pci_alloc_consistent (ioc->pcidev, hdr.PageLength *4 , + &dma_handle); + +if (!buffer) + goto out; + + cfg.physAddr = dma_handle; + cfg.action =MPI_CONFIG_ACTION_PAGE_READ_CURRENT ; + +if (mpt_config (ioc, &cfg) !=0 ) + goto out; + +if (!buffer->NumPhysDisks) + goto out; + + handle_inactive_volumes = + (buffer->VolumeStatus.Flags &MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE || + (buffer->VolumeStatus.Flags &MPI_RAIDVOL0_STATUS_FLAG_ENABLED ) ==0 || + buffer->VolumeStatus.State ==MPI_RAIDVOL0_STATUS_STATE_FAILED || + buffer->VolumeStatus.State ==MPI_RAIDVOL0_STATUS_STATE_MISSING ) ?1 :0 ; + +if (!handle_inactive_volumes) + goto out; + +down (&ioc->raid_data.inactive_list_mutex); +for (i =0 ; i < buffer->NumPhysDisks; i++) { +if (mpt_raid_phys_disk_pg0 (ioc, + buffer->PhysDisk[i].PhysDiskNum, &phys_disk) !=0 ) +continue ; + +if ((component_info =kmalloc (sizeof (*component_info), +GFP_KERNEL )) ==NULL ) +continue ; + + component_info->volumeID = id; + component_info->volumeBus = channel; + component_info->d.PhysDiskNum = phys_disk.PhysDiskNum; + component_info->d.PhysDiskBus = phys_disk.PhysDiskBus; + component_info->d.PhysDiskID = phys_disk.PhysDiskID; + component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC; + +list_add_tail (&component_info->list, + &ioc->raid_data.inactive_list); + } +up (&ioc->raid_data.inactive_list_mutex); + + out: +if (buffer) +pci_free_consistent (ioc->pcidev, hdr.PageLength *4 , buffer, + dma_handle); +} + +/** +* mpt_raid_phys_disk_pg0 - returns phys disk page zero +* @ioc: Pointer to a Adapter Structure +* @phys_disk_num: io unit unique phys disk num generated by the ioc +* @phys_disk: requested payload data returned +* +* Return: +* 0 on success +* -EFAULT if read of config page header fails or data pointer not NULL +* -ENOMEM if pci_alloc failed +**/ +int +mpt_raid_phys_disk_pg0 (MPT_ADAPTER *ioc,u8 phys_disk_num,pRaidPhysDiskPage0_t phys_disk) +{ +CONFIGPARMS cfg; +ConfigPageHeader_t hdr; +dma_addr_t dma_handle; +pRaidPhysDiskPage0_t buffer =NULL ; +int rc; + +memset (&cfg,0 ,sizeof (CONFIGPARMS )); +memset (&hdr,0 ,sizeof (ConfigPageHeader_t)); + + hdr.PageType =MPI_CONFIG_PAGETYPE_RAID_PHYSDISK ; + cfg.cfghdr.hdr = &hdr; + cfg.physAddr =-1 ; + cfg.action =MPI_CONFIG_ACTION_PAGE_HEADER ; + +if (mpt_config (ioc, &cfg) !=0 ) { + rc = -EFAULT ; + goto out; + } + +if (!hdr.PageLength) { + rc = -EFAULT ; + goto out; + } + + buffer =pci_alloc_consistent (ioc->pcidev, hdr.PageLength *4 , + &dma_handle); + +if (!buffer) { + rc = -ENOMEM ; + goto out; + } + + cfg.physAddr = dma_handle; + cfg.action =MPI_CONFIG_ACTION_PAGE_READ_CURRENT ; + cfg.pageAddr = phys_disk_num; + +if (mpt_config (ioc, &cfg) !=0 ) { + rc = -EFAULT ; + goto out; + } + + rc =0 ; +memcpy (phys_disk, buffer,sizeof (*buffer)); + phys_disk->MaxLBA =le32_to_cpu (buffer->MaxLBA); + + out: + +if (buffer) +pci_free_consistent (ioc->pcidev, hdr.PageLength *4 , buffer, + dma_handle); + +return rc; +} +/** * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes * @ioc: Pointer to a Adapter Strucutre
@@ -4737,21 +4928,27 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTE* 0 on success * -EFAULT if read of config page header fails or data pointer not NULL * -ENOMEM if pci_alloc failed -*/ +**/ int mpt_findImVolumes (MPT_ADAPTER *ioc) {IOCPage2_t *pIoc2;u8 *mem; -ConfigPageIoc2RaidVol_t *pIocRv;dma_addr_t ioc2_dma;CONFIGPARMS cfg;ConfigPageHeader_t header; -int jj;int rc =0 ;int iocpage2sz; -u8 nVols, nPhys; -u8 vid, vbus, vioc; +int i; + +if (!ioc->ir_firmware) +return 0 ; + +/* Free the old page +*/ +kfree (ioc->raid_data.pIocPg2); + ioc->raid_data.pIocPg2 =NULL ; +mpt_inactive_raid_list_free (ioc);/* Read IOCP2 header then the page. */
@@ -4779,55 +4976,23 @@ mpt_findImVolumes(MPT_ADAPTER *ioc) cfg.action =MPI_CONFIG_ACTION_PAGE_READ_CURRENT ; cfg.physAddr = ioc2_dma;if (mpt_config (ioc, &cfg) !=0 ) - goto done_and_free; + goto out; -if ( (mem = (u8 *)ioc->raid_data.pIocPg2) ==NULL ) { - mem =kmalloc (iocpage2sz,GFP_ATOMIC ); -if (mem) { - ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem; - }else { - goto done_and_free; - } - } -memcpy (mem, (u8 *)pIoc2, iocpage2sz); + mem =kmalloc (iocpage2sz,GFP_KERNEL ); +if (!mem) + goto out; -/* Identify RAID Volume Id's */ - nVols = pIoc2->NumActiveVolumes; -if ( nVols ==0 ) { -/* No RAID Volume. -*/ - goto done_and_free; - }else { -/* At least 1 RAID Volume -*/ - pIocRv = pIoc2->RaidVolume; - ioc->raid_data.isRaid =0 ; -for (jj =0 ; jj < nVols; jj++, pIocRv++) { - vid = pIocRv->VolumeID; - vbus = pIocRv->VolumeBus; - vioc = pIocRv->VolumeIOC; +memcpy (mem, (u8 *)pIoc2, iocpage2sz); + ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem; -/* find the match -*/ -if (vbus ==0 ) { - ioc->raid_data.isRaid |= (1 << vid); - }else { -/* Error! Always bus 0 -*/ - } - } - } +mpt_read_ioc_pg_3 (ioc); -/* Identify Hidden Physical Disk Id's */ - nPhys = pIoc2->NumActivePhysDisks; -if (nPhys ==0 ) { -/* No physical disks. -*/ - }else { -mpt_read_ioc_pg_3 (ioc); - } +for (i =0 ; i < pIoc2->NumActiveVolumes ; i++) +mpt_inactive_raid_volumes (ioc, + pIoc2->RaidVolume[i].VolumeBus, + pIoc2->RaidVolume[i].VolumeID); -done_and_free: + out:pci_free_consistent (ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);return rc;
@@ -4880,7 +5045,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) cfg.physAddr = ioc3_dma; cfg.action =MPI_CONFIG_ACTION_PAGE_READ_CURRENT ;if (mpt_config (ioc, &cfg) ==0 ) { - mem =kmalloc (iocpage3sz,GFP_ATOMIC ); + mem =kmalloc (iocpage3sz,GFP_KERNEL );if (mem) {memcpy (mem, (u8 *)pIoc3, iocpage3sz); ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
@@ -6833,6 +6998,7 @@ EXPORT_SYMBOL(mpt_findImVolumes);EXPORT_SYMBOL (mpt_alloc_fw_memory);EXPORT_SYMBOL (mpt_free_fw_memory);EXPORT_SYMBOL (mptbase_sas_persist_operation); +EXPORT_SYMBOL (mpt_raid_phys_disk_pg0);/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /**
drivers/message/fusion/mptbase.h +18 -1
@@ -485,10 +485,24 @@ typedef struct _SasCfgData {*/ }SasCfgData; +/* +* Inactive volume link list of raid component data +* @inactive_list +*/ +struct inactive_raid_component_info { +struct list_head list; +u8 volumeID;/* volume target id */ +u8 volumeBus;/* volume channel */ +IOC_3_PHYS_DISK d;/* phys disk info */ +}; +typedef struct _RaidCfgData {IOCPage2_t *pIocPg2;/* table of Raid Volumes */ IOCPage3_t *pIocPg3;/* table of physical disks */ -int isRaid;/* bit field, 1 if RAID */ +struct semaphore inactive_list_mutex; +struct list_head inactive_list;/* link list for physical +disk that belong in +inactive volumes */ }RaidCfgData ; typedef struct _FcCfgData {
@@ -611,6 +625,8 @@ typedef struct _MPT_ADAPTERu8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE ];/* persist reply */ LANPage0_t lan_cnfg_page0;LANPage1_t lan_cnfg_page1; + +u8 ir_firmware;/* =1 if IR firmware detected */ /* * Description: errata_flag_1064 * If a PCIX read occurs within 1 or 2 cycles after the chip receives
@@ -1043,6 +1059,7 @@ extern void mpt_alloc_fw_memory(MPT_ADAextern void mpt_free_fw_memory (MPT_ADAPTER *ioc);extern int mpt_findImVolumes (MPT_ADAPTER *ioc);extern int mptbase_sas_persist_operation (MPT_ADAPTER *ioc,u8 persist_opcode); +extern int mpt_raid_phys_disk_pg0 (MPT_ADAPTER *ioc,u8 phys_disk_num,pRaidPhysDiskPage0_t phys_disk);/* * Public data decl's...
drivers/message/fusion/mptsas.c +237 -35
524 lines not on this page · raw message
drivers/message/fusion/mptscsih.c +32 -0
@@ -2243,6 +2243,7 @@ mptscsih_bios_param(struct scsi_device *int mptscsih_is_phys_disk (MPT_ADAPTER *ioc,u8 channel,u8 id) { +struct inactive_raid_component_info *component_info;int i;int rc =0 ;
@@ -2256,6 +2257,21 @@ mptscsih_is_phys_disk(MPT_ADAPTER *ioc, } } +/* +* Check inactive list for matching phys disks +*/ +if (list_empty (&ioc->raid_data.inactive_list)) + goto out; + +down (&ioc->raid_data.inactive_list_mutex); +list_for_each_entry (component_info, &ioc->raid_data.inactive_list, + list) { +if ((component_info->d.PhysDiskID == id) && + (component_info->d.PhysDiskBus == channel)) + rc =1 ; + } +up (&ioc->raid_data.inactive_list_mutex); + out:return rc; }
@@ -2264,6 +2280,7 @@ EXPORT_SYMBOL(mptscsih_is_phys_disk);u8 mptscsih_raid_id_to_num (MPT_ADAPTER *ioc,u8 channel,u8 id) { +struct inactive_raid_component_info *component_info;int i;int rc = -ENXIO ;
@@ -2277,6 +2294,21 @@ mptscsih_raid_id_to_num(MPT_ADAPTER *ioc } } +/* +* Check inactive list for matching phys disks +*/ +if (list_empty (&ioc->raid_data.inactive_list)) + goto out; + +down (&ioc->raid_data.inactive_list_mutex); +list_for_each_entry (component_info, &ioc->raid_data.inactive_list, + list) { +if ((component_info->d.PhysDiskID == id) && + (component_info->d.PhysDiskBus == channel)) + rc = component_info->d.PhysDiskNum; + } +up (&ioc->raid_data.inactive_list_mutex); + out:return rc; }
drivers/message/fusion/mptspi.c +1 -2
@@ -1363,8 +1363,7 @@ mptspi_probe(struct pci_dev *pdev, const/* * If RAID Firmware Detected, setup virtual channel */ -if ((ioc->facts.ProductID &MPI_FW_HEADER_PID_PROD_MASK ) - >MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) +if (ioc->ir_firmware) sh->max_channel =1 ;else sh->max_channel =0 ;