[SCSI] bfa: Add support to configure and query flash boot partition
authorKrishna Gudipati <kgudipat@brocade.com>
Thu, 21 Jul 2011 00:02:32 +0000 (17:02 -0700)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 27 Jul 2011 10:50:06 +0000 (14:50 +0400)
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/bfa/bfa_defs.h
drivers/scsi/bfa/bfad_bsg.c
drivers/scsi/bfa/bfad_bsg.h

index 2dc4b6fc79d0eb4ea79a926a0495e149f3c30107..75b9d91d1f9496349d6f114db4de7743db7bfbca 100644 (file)
@@ -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
  */
index 0d920edebac9d6d95a9c9f319ef8e5c3481bf795..f782ee4b88688f4b66e43d0f35842e8392d1f166 100644 (file)
@@ -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;
index f64f3eee6dbfbb5ee9ada4461d0e0e133e18ee74..95694cee0cd810c9b12ae2576ec0cb88fb0aa44a 100644 (file)
@@ -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;