diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-07-20 17:02:32 -0700 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-07-27 14:50:06 +0400 |
commit | a46bd300e191d5a1a7367a799a9f5268c5e6aafd (patch) | |
tree | d5735b3f19dc62fb0ad182e597337eb416f620b9 /drivers | |
parent | 37ea0558b87abb151245bc750070a4dcda490aca (diff) | |
download | linux-3.10-a46bd300e191d5a1a7367a799a9f5268c5e6aafd.tar.gz linux-3.10-a46bd300e191d5a1a7367a799a9f5268c5e6aafd.tar.bz2 linux-3.10-a46bd300e191d5a1a7367a799a9f5268c5e6aafd.zip |
[SCSI] bfa: Add support to configure and query flash boot partition
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/bfa/bfa_defs.h | 23 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.c | 124 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.h | 26 |
3 files changed, 173 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index 2dc4b6fc79d..75b9d91d1f9 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h @@ -656,6 +656,20 @@ struct bfa_boot_bootlun_s { /* * BOOT boot configuraton */ +struct bfa_boot_cfg_s { + u8 version; + u8 rsvd1; + u16 chksum; + u8 enable; /* enable/disable SAN boot */ + u8 speed; /* boot speed settings */ + u8 topology; /* boot topology setting */ + u8 bootopt; /* bfa_boot_bootopt_t */ + u32 nbluns; /* number of boot luns */ + u32 rsvd2; + struct bfa_boot_bootlun_s blun[BFA_BOOT_BOOTLUN_MAX]; + struct bfa_boot_bootlun_s blun_disc[BFA_BOOT_BOOTLUN_MAX]; +}; + struct bfa_boot_pbc_s { u8 enable; /* enable/disable SAN boot */ u8 speed; /* boot speed settings */ @@ -665,6 +679,15 @@ struct bfa_boot_pbc_s { struct bfa_boot_bootlun_s pblun[BFA_PREBOOT_BOOTLUN_MAX]; }; +struct bfa_ethboot_cfg_s { + u8 version; + u8 rsvd1; + u16 chksum; + u8 enable; /* enable/disable Eth/PXE boot */ + u8 rsvd2; + u16 vlan; +}; + /* * ASIC block configuration related structures */ diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 0d920edebac..f782ee4b886 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -2072,6 +2072,115 @@ out: return 0; } +int +bfad_iocmd_boot_cfg(struct bfad_s *bfad, void *cmd) +{ + struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd; + struct bfad_hal_comp fcomp; + unsigned long flags; + + init_completion(&fcomp.comp); + spin_lock_irqsave(&bfad->bfad_lock, flags); + iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), + BFA_FLASH_PART_BOOT, PCI_FUNC(bfad->pcidev->devfn), + &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, + bfad_hcb_comp, &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + if (iocmd->status != BFA_STATUS_OK) + goto out; + wait_for_completion(&fcomp.comp); + iocmd->status = fcomp.status; +out: + return 0; +} + +int +bfad_iocmd_boot_query(struct bfad_s *bfad, void *cmd) +{ + struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd; + struct bfad_hal_comp fcomp; + unsigned long flags; + + init_completion(&fcomp.comp); + spin_lock_irqsave(&bfad->bfad_lock, flags); + iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), + BFA_FLASH_PART_BOOT, PCI_FUNC(bfad->pcidev->devfn), + &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, + bfad_hcb_comp, &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + if (iocmd->status != BFA_STATUS_OK) + goto out; + wait_for_completion(&fcomp.comp); + iocmd->status = fcomp.status; +out: + return 0; +} + +int +bfad_iocmd_preboot_query(struct bfad_s *bfad, void *cmd) +{ + struct bfa_bsg_preboot_s *iocmd = (struct bfa_bsg_preboot_s *)cmd; + struct bfi_iocfc_cfgrsp_s *cfgrsp = bfad->bfa.iocfc.cfgrsp; + struct bfa_boot_pbc_s *pbcfg = &iocmd->cfg; + unsigned long flags; + + spin_lock_irqsave(&bfad->bfad_lock, flags); + pbcfg->enable = cfgrsp->pbc_cfg.boot_enabled; + pbcfg->nbluns = cfgrsp->pbc_cfg.nbluns; + pbcfg->speed = cfgrsp->pbc_cfg.port_speed; + memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun)); + iocmd->status = BFA_STATUS_OK; + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + + return 0; +} + +int +bfad_iocmd_ethboot_cfg(struct bfad_s *bfad, void *cmd) +{ + struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd; + struct bfad_hal_comp fcomp; + unsigned long flags; + + init_completion(&fcomp.comp); + spin_lock_irqsave(&bfad->bfad_lock, flags); + iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), + BFA_FLASH_PART_PXECFG, + bfad->bfa.ioc.port_id, &iocmd->cfg, + sizeof(struct bfa_ethboot_cfg_s), 0, + bfad_hcb_comp, &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + if (iocmd->status != BFA_STATUS_OK) + goto out; + wait_for_completion(&fcomp.comp); + iocmd->status = fcomp.status; +out: + return 0; +} + +int +bfad_iocmd_ethboot_query(struct bfad_s *bfad, void *cmd) +{ + struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd; + struct bfad_hal_comp fcomp; + unsigned long flags; + + init_completion(&fcomp.comp); + spin_lock_irqsave(&bfad->bfad_lock, flags); + iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), + BFA_FLASH_PART_PXECFG, + bfad->bfa.ioc.port_id, &iocmd->cfg, + sizeof(struct bfa_ethboot_cfg_s), 0, + bfad_hcb_comp, &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + if (iocmd->status != BFA_STATUS_OK) + goto out; + wait_for_completion(&fcomp.comp); + iocmd->status = fcomp.status; +out: + return 0; +} + static int bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, unsigned int payload_len) @@ -2346,6 +2455,21 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, case IOCMD_FCPORT_RESET_STATS: rc = bfad_iocmd_fcport_reset_stats(bfad, iocmd); break; + case IOCMD_BOOT_CFG: + rc = bfad_iocmd_boot_cfg(bfad, iocmd); + break; + case IOCMD_BOOT_QUERY: + rc = bfad_iocmd_boot_query(bfad, iocmd); + break; + case IOCMD_PREBOOT_QUERY: + rc = bfad_iocmd_preboot_query(bfad, iocmd); + break; + case IOCMD_ETHBOOT_CFG: + rc = bfad_iocmd_ethboot_cfg(bfad, iocmd); + break; + case IOCMD_ETHBOOT_QUERY: + rc = bfad_iocmd_ethboot_query(bfad, iocmd); + break; default: rc = -EINVAL; break; diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index f64f3eee6db..95694cee0cd 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h @@ -121,6 +121,11 @@ enum { IOCMD_ITNIM_GET_IOPROFILE, IOCMD_FCPORT_GET_STATS, IOCMD_FCPORT_RESET_STATS, + IOCMD_BOOT_CFG, + IOCMD_BOOT_QUERY, + IOCMD_PREBOOT_QUERY, + IOCMD_ETHBOOT_CFG, + IOCMD_ETHBOOT_QUERY, }; struct bfa_bsg_gen_s { @@ -630,6 +635,27 @@ struct bfa_bsg_vhba_attr_s { struct bfa_vhba_attr_s attr; }; +struct bfa_bsg_boot_s { + bfa_status_t status; + u16 bfad_num; + u16 rsvd; + struct bfa_boot_cfg_s cfg; +}; + +struct bfa_bsg_preboot_s { + bfa_status_t status; + u16 bfad_num; + u16 rsvd; + struct bfa_boot_pbc_s cfg; +}; + +struct bfa_bsg_ethboot_s { + bfa_status_t status; + u16 bfad_num; + u16 rsvd; + struct bfa_ethboot_cfg_s cfg; +}; + struct bfa_bsg_fcpt_s { bfa_status_t status; u16 vf_id; |