Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] bfa: Add support to read/update the FRU data.

- Add FRU sub-module to support FRU read/write/update.
- Add support to read/write from the temp FRU module.

[jejb: fix checkpatch issues]
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Krishna Gudipati and committed by
James Bottomley
e6826c96 4a49b044

+715 -5
+14
drivers/scsi/bfa/bfa_core.c
··· 165 165 bfa_phy_memclaim(phy, phy_dma->kva_curp, phy_dma->dma_curp, mincfg); 166 166 } 167 167 168 + static void 169 + bfa_com_fru_attach(struct bfa_s *bfa, bfa_boolean_t mincfg) 170 + { 171 + struct bfa_fru_s *fru = BFA_FRU(bfa); 172 + struct bfa_mem_dma_s *fru_dma = BFA_MEM_FRU_DMA(bfa); 173 + 174 + bfa_fru_attach(fru, &bfa->ioc, bfa, bfa->trcmod, mincfg); 175 + bfa_fru_memclaim(fru, fru_dma->kva_curp, fru_dma->dma_curp, mincfg); 176 + } 177 + 168 178 /* 169 179 * BFA IOC FC related definitions 170 180 */ ··· 1762 1752 struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa); 1763 1753 struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa); 1764 1754 struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa); 1755 + struct bfa_mem_dma_s *fru_dma = BFA_MEM_FRU_DMA(bfa); 1765 1756 1766 1757 WARN_ON((cfg == NULL) || (meminfo == NULL)); 1767 1758 ··· 1787 1776 bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo()); 1788 1777 bfa_mem_dma_setup(meminfo, phy_dma, 1789 1778 bfa_phy_meminfo(cfg->drvcfg.min_cfg)); 1779 + bfa_mem_dma_setup(meminfo, fru_dma, 1780 + bfa_fru_meminfo(cfg->drvcfg.min_cfg)); 1790 1781 } 1791 1782 1792 1783 /* ··· 1861 1848 bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg); 1862 1849 bfa_com_diag_attach(bfa); 1863 1850 bfa_com_phy_attach(bfa, cfg->drvcfg.min_cfg); 1851 + bfa_com_fru_attach(bfa, cfg->drvcfg.min_cfg); 1864 1852 } 1865 1853 1866 1854 /*
+1
drivers/scsi/bfa/bfa_defs.h
··· 196 196 BFA_STATUS_DPORT_ENABLED = 235, /* D-port mode is already enabled */ 197 197 BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */ 198 198 BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */ 199 + BFA_STATUS_FRU_NOT_PRESENT = 240, /* fru module not present */ 199 200 BFA_STATUS_DPORT_ERR = 245, /* D-port mode is enabled */ 200 201 BFA_STATUS_MAX_VAL /* Unknown error code */ 201 202 };
+445
drivers/scsi/bfa/bfa_ioc.c
··· 5956 5956 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 5957 5957 bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT); 5958 5958 } 5959 + 5960 + /* 5961 + * FRU specific functions 5962 + */ 5963 + 5964 + #define BFA_FRU_DMA_BUF_SZ 0x02000 /* 8k dma buffer */ 5965 + #define BFA_FRU_CHINOOK_MAX_SIZE 0x10000 5966 + #define BFA_FRU_LIGHTNING_MAX_SIZE 0x200 5967 + 5968 + static void 5969 + bfa_fru_notify(void *cbarg, enum bfa_ioc_event_e event) 5970 + { 5971 + struct bfa_fru_s *fru = cbarg; 5972 + 5973 + bfa_trc(fru, event); 5974 + 5975 + switch (event) { 5976 + case BFA_IOC_E_DISABLED: 5977 + case BFA_IOC_E_FAILED: 5978 + if (fru->op_busy) { 5979 + fru->status = BFA_STATUS_IOC_FAILURE; 5980 + fru->cbfn(fru->cbarg, fru->status); 5981 + fru->op_busy = 0; 5982 + } 5983 + break; 5984 + 5985 + default: 5986 + break; 5987 + } 5988 + } 5989 + 5990 + /* 5991 + * Send fru write request. 5992 + * 5993 + * @param[in] cbarg - callback argument 5994 + */ 5995 + static void 5996 + bfa_fru_write_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type) 5997 + { 5998 + struct bfa_fru_s *fru = cbarg; 5999 + struct bfi_fru_write_req_s *msg = 6000 + (struct bfi_fru_write_req_s *) fru->mb.msg; 6001 + u32 len; 6002 + 6003 + msg->offset = cpu_to_be32(fru->addr_off + fru->offset); 6004 + len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ? 6005 + fru->residue : BFA_FRU_DMA_BUF_SZ; 6006 + msg->length = cpu_to_be32(len); 6007 + 6008 + /* 6009 + * indicate if it's the last msg of the whole write operation 6010 + */ 6011 + msg->last = (len == fru->residue) ? 1 : 0; 6012 + 6013 + bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc)); 6014 + bfa_alen_set(&msg->alen, len, fru->dbuf_pa); 6015 + 6016 + memcpy(fru->dbuf_kva, fru->ubuf + fru->offset, len); 6017 + bfa_ioc_mbox_queue(fru->ioc, &fru->mb); 6018 + 6019 + fru->residue -= len; 6020 + fru->offset += len; 6021 + } 6022 + 6023 + /* 6024 + * Send fru read request. 6025 + * 6026 + * @param[in] cbarg - callback argument 6027 + */ 6028 + static void 6029 + bfa_fru_read_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type) 6030 + { 6031 + struct bfa_fru_s *fru = cbarg; 6032 + struct bfi_fru_read_req_s *msg = 6033 + (struct bfi_fru_read_req_s *) fru->mb.msg; 6034 + u32 len; 6035 + 6036 + msg->offset = cpu_to_be32(fru->addr_off + fru->offset); 6037 + len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ? 6038 + fru->residue : BFA_FRU_DMA_BUF_SZ; 6039 + msg->length = cpu_to_be32(len); 6040 + bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc)); 6041 + bfa_alen_set(&msg->alen, len, fru->dbuf_pa); 6042 + bfa_ioc_mbox_queue(fru->ioc, &fru->mb); 6043 + } 6044 + 6045 + /* 6046 + * Flash memory info API. 6047 + * 6048 + * @param[in] mincfg - minimal cfg variable 6049 + */ 6050 + u32 6051 + bfa_fru_meminfo(bfa_boolean_t mincfg) 6052 + { 6053 + /* min driver doesn't need fru */ 6054 + if (mincfg) 6055 + return 0; 6056 + 6057 + return BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 6058 + } 6059 + 6060 + /* 6061 + * Flash attach API. 6062 + * 6063 + * @param[in] fru - fru structure 6064 + * @param[in] ioc - ioc structure 6065 + * @param[in] dev - device structure 6066 + * @param[in] trcmod - trace module 6067 + * @param[in] logmod - log module 6068 + */ 6069 + void 6070 + bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, void *dev, 6071 + struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg) 6072 + { 6073 + fru->ioc = ioc; 6074 + fru->trcmod = trcmod; 6075 + fru->cbfn = NULL; 6076 + fru->cbarg = NULL; 6077 + fru->op_busy = 0; 6078 + 6079 + bfa_ioc_mbox_regisr(fru->ioc, BFI_MC_FRU, bfa_fru_intr, fru); 6080 + bfa_q_qe_init(&fru->ioc_notify); 6081 + bfa_ioc_notify_init(&fru->ioc_notify, bfa_fru_notify, fru); 6082 + list_add_tail(&fru->ioc_notify.qe, &fru->ioc->notify_q); 6083 + 6084 + /* min driver doesn't need fru */ 6085 + if (mincfg) { 6086 + fru->dbuf_kva = NULL; 6087 + fru->dbuf_pa = 0; 6088 + } 6089 + } 6090 + 6091 + /* 6092 + * Claim memory for fru 6093 + * 6094 + * @param[in] fru - fru structure 6095 + * @param[in] dm_kva - pointer to virtual memory address 6096 + * @param[in] dm_pa - frusical memory address 6097 + * @param[in] mincfg - minimal cfg variable 6098 + */ 6099 + void 6100 + bfa_fru_memclaim(struct bfa_fru_s *fru, u8 *dm_kva, u64 dm_pa, 6101 + bfa_boolean_t mincfg) 6102 + { 6103 + if (mincfg) 6104 + return; 6105 + 6106 + fru->dbuf_kva = dm_kva; 6107 + fru->dbuf_pa = dm_pa; 6108 + memset(fru->dbuf_kva, 0, BFA_FRU_DMA_BUF_SZ); 6109 + dm_kva += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 6110 + dm_pa += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 6111 + } 6112 + 6113 + /* 6114 + * Update fru vpd image. 6115 + * 6116 + * @param[in] fru - fru structure 6117 + * @param[in] buf - update data buffer 6118 + * @param[in] len - data buffer length 6119 + * @param[in] offset - offset relative to starting address 6120 + * @param[in] cbfn - callback function 6121 + * @param[in] cbarg - callback argument 6122 + * 6123 + * Return status. 6124 + */ 6125 + bfa_status_t 6126 + bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, 6127 + bfa_cb_fru_t cbfn, void *cbarg) 6128 + { 6129 + bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ); 6130 + bfa_trc(fru, len); 6131 + bfa_trc(fru, offset); 6132 + 6133 + if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) 6134 + return BFA_STATUS_FRU_NOT_PRESENT; 6135 + 6136 + if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK) 6137 + return BFA_STATUS_CMD_NOTSUPP; 6138 + 6139 + if (!bfa_ioc_is_operational(fru->ioc)) 6140 + return BFA_STATUS_IOC_NON_OP; 6141 + 6142 + if (fru->op_busy) { 6143 + bfa_trc(fru, fru->op_busy); 6144 + return BFA_STATUS_DEVBUSY; 6145 + } 6146 + 6147 + fru->op_busy = 1; 6148 + 6149 + fru->cbfn = cbfn; 6150 + fru->cbarg = cbarg; 6151 + fru->residue = len; 6152 + fru->offset = 0; 6153 + fru->addr_off = offset; 6154 + fru->ubuf = buf; 6155 + 6156 + bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ); 6157 + 6158 + return BFA_STATUS_OK; 6159 + } 6160 + 6161 + /* 6162 + * Read fru vpd image. 6163 + * 6164 + * @param[in] fru - fru structure 6165 + * @param[in] buf - read data buffer 6166 + * @param[in] len - data buffer length 6167 + * @param[in] offset - offset relative to starting address 6168 + * @param[in] cbfn - callback function 6169 + * @param[in] cbarg - callback argument 6170 + * 6171 + * Return status. 6172 + */ 6173 + bfa_status_t 6174 + bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, 6175 + bfa_cb_fru_t cbfn, void *cbarg) 6176 + { 6177 + bfa_trc(fru, BFI_FRUVPD_H2I_READ_REQ); 6178 + bfa_trc(fru, len); 6179 + bfa_trc(fru, offset); 6180 + 6181 + if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) 6182 + return BFA_STATUS_FRU_NOT_PRESENT; 6183 + 6184 + if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK) 6185 + return BFA_STATUS_CMD_NOTSUPP; 6186 + 6187 + if (!bfa_ioc_is_operational(fru->ioc)) 6188 + return BFA_STATUS_IOC_NON_OP; 6189 + 6190 + if (fru->op_busy) { 6191 + bfa_trc(fru, fru->op_busy); 6192 + return BFA_STATUS_DEVBUSY; 6193 + } 6194 + 6195 + fru->op_busy = 1; 6196 + 6197 + fru->cbfn = cbfn; 6198 + fru->cbarg = cbarg; 6199 + fru->residue = len; 6200 + fru->offset = 0; 6201 + fru->addr_off = offset; 6202 + fru->ubuf = buf; 6203 + bfa_fru_read_send(fru, BFI_FRUVPD_H2I_READ_REQ); 6204 + 6205 + return BFA_STATUS_OK; 6206 + } 6207 + 6208 + /* 6209 + * Get maximum size fru vpd image. 6210 + * 6211 + * @param[in] fru - fru structure 6212 + * @param[out] size - maximum size of fru vpd data 6213 + * 6214 + * Return status. 6215 + */ 6216 + bfa_status_t 6217 + bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size) 6218 + { 6219 + if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) 6220 + return BFA_STATUS_FRU_NOT_PRESENT; 6221 + 6222 + if (!bfa_ioc_is_operational(fru->ioc)) 6223 + return BFA_STATUS_IOC_NON_OP; 6224 + 6225 + if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK) 6226 + *max_size = BFA_FRU_CHINOOK_MAX_SIZE; 6227 + else 6228 + return BFA_STATUS_CMD_NOTSUPP; 6229 + return BFA_STATUS_OK; 6230 + } 6231 + /* 6232 + * tfru write. 6233 + * 6234 + * @param[in] fru - fru structure 6235 + * @param[in] buf - update data buffer 6236 + * @param[in] len - data buffer length 6237 + * @param[in] offset - offset relative to starting address 6238 + * @param[in] cbfn - callback function 6239 + * @param[in] cbarg - callback argument 6240 + * 6241 + * Return status. 6242 + */ 6243 + bfa_status_t 6244 + bfa_tfru_write(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, 6245 + bfa_cb_fru_t cbfn, void *cbarg) 6246 + { 6247 + bfa_trc(fru, BFI_TFRU_H2I_WRITE_REQ); 6248 + bfa_trc(fru, len); 6249 + bfa_trc(fru, offset); 6250 + bfa_trc(fru, *((u8 *) buf)); 6251 + 6252 + if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) 6253 + return BFA_STATUS_FRU_NOT_PRESENT; 6254 + 6255 + if (!bfa_ioc_is_operational(fru->ioc)) 6256 + return BFA_STATUS_IOC_NON_OP; 6257 + 6258 + if (fru->op_busy) { 6259 + bfa_trc(fru, fru->op_busy); 6260 + return BFA_STATUS_DEVBUSY; 6261 + } 6262 + 6263 + fru->op_busy = 1; 6264 + 6265 + fru->cbfn = cbfn; 6266 + fru->cbarg = cbarg; 6267 + fru->residue = len; 6268 + fru->offset = 0; 6269 + fru->addr_off = offset; 6270 + fru->ubuf = buf; 6271 + 6272 + bfa_fru_write_send(fru, BFI_TFRU_H2I_WRITE_REQ); 6273 + 6274 + return BFA_STATUS_OK; 6275 + } 6276 + 6277 + /* 6278 + * tfru read. 6279 + * 6280 + * @param[in] fru - fru structure 6281 + * @param[in] buf - read data buffer 6282 + * @param[in] len - data buffer length 6283 + * @param[in] offset - offset relative to starting address 6284 + * @param[in] cbfn - callback function 6285 + * @param[in] cbarg - callback argument 6286 + * 6287 + * Return status. 6288 + */ 6289 + bfa_status_t 6290 + bfa_tfru_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, 6291 + bfa_cb_fru_t cbfn, void *cbarg) 6292 + { 6293 + bfa_trc(fru, BFI_TFRU_H2I_READ_REQ); 6294 + bfa_trc(fru, len); 6295 + bfa_trc(fru, offset); 6296 + 6297 + if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) 6298 + return BFA_STATUS_FRU_NOT_PRESENT; 6299 + 6300 + if (!bfa_ioc_is_operational(fru->ioc)) 6301 + return BFA_STATUS_IOC_NON_OP; 6302 + 6303 + if (fru->op_busy) { 6304 + bfa_trc(fru, fru->op_busy); 6305 + return BFA_STATUS_DEVBUSY; 6306 + } 6307 + 6308 + fru->op_busy = 1; 6309 + 6310 + fru->cbfn = cbfn; 6311 + fru->cbarg = cbarg; 6312 + fru->residue = len; 6313 + fru->offset = 0; 6314 + fru->addr_off = offset; 6315 + fru->ubuf = buf; 6316 + bfa_fru_read_send(fru, BFI_TFRU_H2I_READ_REQ); 6317 + 6318 + return BFA_STATUS_OK; 6319 + } 6320 + 6321 + /* 6322 + * Process fru response messages upon receiving interrupts. 6323 + * 6324 + * @param[in] fruarg - fru structure 6325 + * @param[in] msg - message structure 6326 + */ 6327 + void 6328 + bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg) 6329 + { 6330 + struct bfa_fru_s *fru = fruarg; 6331 + struct bfi_fru_rsp_s *rsp = (struct bfi_fru_rsp_s *)msg; 6332 + u32 status; 6333 + 6334 + bfa_trc(fru, msg->mh.msg_id); 6335 + 6336 + if (!fru->op_busy) { 6337 + /* 6338 + * receiving response after ioc failure 6339 + */ 6340 + bfa_trc(fru, 0x9999); 6341 + return; 6342 + } 6343 + 6344 + switch (msg->mh.msg_id) { 6345 + case BFI_FRUVPD_I2H_WRITE_RSP: 6346 + case BFI_TFRU_I2H_WRITE_RSP: 6347 + status = be32_to_cpu(rsp->status); 6348 + bfa_trc(fru, status); 6349 + 6350 + if (status != BFA_STATUS_OK || fru->residue == 0) { 6351 + fru->status = status; 6352 + fru->op_busy = 0; 6353 + if (fru->cbfn) 6354 + fru->cbfn(fru->cbarg, fru->status); 6355 + } else { 6356 + bfa_trc(fru, fru->offset); 6357 + if (msg->mh.msg_id == BFI_FRUVPD_I2H_WRITE_RSP) 6358 + bfa_fru_write_send(fru, 6359 + BFI_FRUVPD_H2I_WRITE_REQ); 6360 + else 6361 + bfa_fru_write_send(fru, 6362 + BFI_TFRU_H2I_WRITE_REQ); 6363 + } 6364 + break; 6365 + case BFI_FRUVPD_I2H_READ_RSP: 6366 + case BFI_TFRU_I2H_READ_RSP: 6367 + status = be32_to_cpu(rsp->status); 6368 + bfa_trc(fru, status); 6369 + 6370 + if (status != BFA_STATUS_OK) { 6371 + fru->status = status; 6372 + fru->op_busy = 0; 6373 + if (fru->cbfn) 6374 + fru->cbfn(fru->cbarg, fru->status); 6375 + } else { 6376 + u32 len = be32_to_cpu(rsp->length); 6377 + 6378 + bfa_trc(fru, fru->offset); 6379 + bfa_trc(fru, len); 6380 + 6381 + memcpy(fru->ubuf + fru->offset, fru->dbuf_kva, len); 6382 + fru->residue -= len; 6383 + fru->offset += len; 6384 + 6385 + if (fru->residue == 0) { 6386 + fru->status = status; 6387 + fru->op_busy = 0; 6388 + if (fru->cbfn) 6389 + fru->cbfn(fru->cbarg, fru->status); 6390 + } else { 6391 + if (msg->mh.msg_id == BFI_FRUVPD_I2H_READ_RSP) 6392 + bfa_fru_read_send(fru, 6393 + BFI_FRUVPD_H2I_READ_REQ); 6394 + else 6395 + bfa_fru_read_send(fru, 6396 + BFI_TFRU_H2I_READ_REQ); 6397 + } 6398 + } 6399 + break; 6400 + default: 6401 + WARN_ON(1); 6402 + } 6403 + }
+49
drivers/scsi/bfa/bfa_ioc.h
··· 702 702 void bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg); 703 703 704 704 /* 705 + * FRU module specific 706 + */ 707 + typedef void (*bfa_cb_fru_t) (void *cbarg, bfa_status_t status); 708 + 709 + struct bfa_fru_s { 710 + struct bfa_ioc_s *ioc; /* back pointer to ioc */ 711 + struct bfa_trc_mod_s *trcmod; /* trace module */ 712 + u8 op_busy; /* operation busy flag */ 713 + u8 rsv[3]; 714 + u32 residue; /* residual length */ 715 + u32 offset; /* offset */ 716 + bfa_status_t status; /* status */ 717 + u8 *dbuf_kva; /* dma buf virtual address */ 718 + u64 dbuf_pa; /* dma buf physical address */ 719 + struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ 720 + bfa_cb_fru_t cbfn; /* user callback function */ 721 + void *cbarg; /* user callback arg */ 722 + u8 *ubuf; /* user supplied buffer */ 723 + struct bfa_cb_qe_s hcb_qe; /* comp: BFA callback qelem */ 724 + u32 addr_off; /* fru address offset */ 725 + struct bfa_mbox_cmd_s mb; /* mailbox */ 726 + struct bfa_ioc_notify_s ioc_notify; /* ioc event notify */ 727 + struct bfa_mem_dma_s fru_dma; 728 + }; 729 + 730 + #define BFA_FRU(__bfa) (&(__bfa)->modules.fru) 731 + #define BFA_MEM_FRU_DMA(__bfa) (&(BFA_FRU(__bfa)->fru_dma)) 732 + 733 + bfa_status_t bfa_fruvpd_update(struct bfa_fru_s *fru, 734 + void *buf, u32 len, u32 offset, 735 + bfa_cb_fru_t cbfn, void *cbarg); 736 + bfa_status_t bfa_fruvpd_read(struct bfa_fru_s *fru, 737 + void *buf, u32 len, u32 offset, 738 + bfa_cb_fru_t cbfn, void *cbarg); 739 + bfa_status_t bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size); 740 + bfa_status_t bfa_tfru_write(struct bfa_fru_s *fru, 741 + void *buf, u32 len, u32 offset, 742 + bfa_cb_fru_t cbfn, void *cbarg); 743 + bfa_status_t bfa_tfru_read(struct bfa_fru_s *fru, 744 + void *buf, u32 len, u32 offset, 745 + bfa_cb_fru_t cbfn, void *cbarg); 746 + u32 bfa_fru_meminfo(bfa_boolean_t mincfg); 747 + void bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, 748 + void *dev, struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg); 749 + void bfa_fru_memclaim(struct bfa_fru_s *fru, 750 + u8 *dm_kva, u64 dm_pa, bfa_boolean_t mincfg); 751 + void bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg); 752 + 753 + /* 705 754 * Driver Config( dconf) specific 706 755 */ 707 756 #define BFI_DCONF_SIGNATURE 0xabcdabcd
+1
drivers/scsi/bfa/bfa_modules.h
··· 45 45 struct bfa_diag_s diag_mod; /* diagnostics module */ 46 46 struct bfa_phy_s phy; /* phy module */ 47 47 struct bfa_dconf_mod_s dconf_mod; /* DCONF common module */ 48 + struct bfa_fru_s fru; /* fru module */ 48 49 }; 49 50 50 51 /*
+124 -3
drivers/scsi/bfa/bfad_bsg.c
··· 107 107 108 108 /* set adapter hw path */ 109 109 strcpy(iocmd->adapter_hwpath, bfad->pci_name); 110 - i = strlen(iocmd->adapter_hwpath) - 1; 111 - while (iocmd->adapter_hwpath[i] != '.') 112 - i--; 110 + for (i = 0; iocmd->adapter_hwpath[i] != ':' && i < BFA_STRING_32; i++) 111 + ; 112 + for (; iocmd->adapter_hwpath[++i] != ':' && i < BFA_STRING_32; ) 113 + ; 113 114 iocmd->adapter_hwpath[i] = '\0'; 114 115 iocmd->status = BFA_STATUS_OK; 115 116 return 0; ··· 2584 2583 return 0; 2585 2584 } 2586 2585 2586 + int 2587 + bfad_iocmd_tfru_read(struct bfad_s *bfad, void *cmd) 2588 + { 2589 + struct bfa_bsg_tfru_s *iocmd = 2590 + (struct bfa_bsg_tfru_s *)cmd; 2591 + struct bfad_hal_comp fcomp; 2592 + unsigned long flags = 0; 2593 + 2594 + init_completion(&fcomp.comp); 2595 + spin_lock_irqsave(&bfad->bfad_lock, flags); 2596 + iocmd->status = bfa_tfru_read(BFA_FRU(&bfad->bfa), 2597 + &iocmd->data, iocmd->len, iocmd->offset, 2598 + bfad_hcb_comp, &fcomp); 2599 + spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2600 + if (iocmd->status == BFA_STATUS_OK) { 2601 + wait_for_completion(&fcomp.comp); 2602 + iocmd->status = fcomp.status; 2603 + } 2604 + 2605 + return 0; 2606 + } 2607 + 2608 + int 2609 + bfad_iocmd_tfru_write(struct bfad_s *bfad, void *cmd) 2610 + { 2611 + struct bfa_bsg_tfru_s *iocmd = 2612 + (struct bfa_bsg_tfru_s *)cmd; 2613 + struct bfad_hal_comp fcomp; 2614 + unsigned long flags = 0; 2615 + 2616 + init_completion(&fcomp.comp); 2617 + spin_lock_irqsave(&bfad->bfad_lock, flags); 2618 + iocmd->status = bfa_tfru_write(BFA_FRU(&bfad->bfa), 2619 + &iocmd->data, iocmd->len, iocmd->offset, 2620 + bfad_hcb_comp, &fcomp); 2621 + spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2622 + if (iocmd->status == BFA_STATUS_OK) { 2623 + wait_for_completion(&fcomp.comp); 2624 + iocmd->status = fcomp.status; 2625 + } 2626 + 2627 + return 0; 2628 + } 2629 + 2630 + int 2631 + bfad_iocmd_fruvpd_read(struct bfad_s *bfad, void *cmd) 2632 + { 2633 + struct bfa_bsg_fruvpd_s *iocmd = 2634 + (struct bfa_bsg_fruvpd_s *)cmd; 2635 + struct bfad_hal_comp fcomp; 2636 + unsigned long flags = 0; 2637 + 2638 + init_completion(&fcomp.comp); 2639 + spin_lock_irqsave(&bfad->bfad_lock, flags); 2640 + iocmd->status = bfa_fruvpd_read(BFA_FRU(&bfad->bfa), 2641 + &iocmd->data, iocmd->len, iocmd->offset, 2642 + bfad_hcb_comp, &fcomp); 2643 + spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2644 + if (iocmd->status == BFA_STATUS_OK) { 2645 + wait_for_completion(&fcomp.comp); 2646 + iocmd->status = fcomp.status; 2647 + } 2648 + 2649 + return 0; 2650 + } 2651 + 2652 + int 2653 + bfad_iocmd_fruvpd_update(struct bfad_s *bfad, void *cmd) 2654 + { 2655 + struct bfa_bsg_fruvpd_s *iocmd = 2656 + (struct bfa_bsg_fruvpd_s *)cmd; 2657 + struct bfad_hal_comp fcomp; 2658 + unsigned long flags = 0; 2659 + 2660 + init_completion(&fcomp.comp); 2661 + spin_lock_irqsave(&bfad->bfad_lock, flags); 2662 + iocmd->status = bfa_fruvpd_update(BFA_FRU(&bfad->bfa), 2663 + &iocmd->data, iocmd->len, iocmd->offset, 2664 + bfad_hcb_comp, &fcomp); 2665 + spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2666 + if (iocmd->status == BFA_STATUS_OK) { 2667 + wait_for_completion(&fcomp.comp); 2668 + iocmd->status = fcomp.status; 2669 + } 2670 + 2671 + return 0; 2672 + } 2673 + 2674 + int 2675 + bfad_iocmd_fruvpd_get_max_size(struct bfad_s *bfad, void *cmd) 2676 + { 2677 + struct bfa_bsg_fruvpd_max_size_s *iocmd = 2678 + (struct bfa_bsg_fruvpd_max_size_s *)cmd; 2679 + unsigned long flags = 0; 2680 + 2681 + spin_lock_irqsave(&bfad->bfad_lock, flags); 2682 + iocmd->status = bfa_fruvpd_get_max_size(BFA_FRU(&bfad->bfa), 2683 + &iocmd->max_size); 2684 + spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2685 + 2686 + return 0; 2687 + } 2688 + 2587 2689 static int 2588 2690 bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, 2589 2691 unsigned int payload_len) ··· 3026 2922 break; 3027 2923 case IOCMD_FCPIM_THROTTLE_SET: 3028 2924 rc = bfad_iocmd_fcpim_throttle_set(bfad, iocmd); 2925 + break; 2926 + /* TFRU */ 2927 + case IOCMD_TFRU_READ: 2928 + rc = bfad_iocmd_tfru_read(bfad, iocmd); 2929 + break; 2930 + case IOCMD_TFRU_WRITE: 2931 + rc = bfad_iocmd_tfru_write(bfad, iocmd); 2932 + break; 2933 + /* FRU */ 2934 + case IOCMD_FRUVPD_READ: 2935 + rc = bfad_iocmd_fruvpd_read(bfad, iocmd); 2936 + break; 2937 + case IOCMD_FRUVPD_UPDATE: 2938 + rc = bfad_iocmd_fruvpd_update(bfad, iocmd); 2939 + break; 2940 + case IOCMD_FRUVPD_GET_MAX_SIZE: 2941 + rc = bfad_iocmd_fruvpd_get_max_size(bfad, iocmd); 3029 2942 break; 3030 2943 default: 3031 2944 rc = -EINVAL;
+34 -1
drivers/scsi/bfa/bfad_bsg.h
··· 146 146 IOCMD_DIAG_DPORT_GET_STATE, 147 147 IOCMD_QOS_SET_BW, 148 148 IOCMD_FCPIM_THROTTLE_QUERY, 149 - IOCMD_FCPIM_THROTTLE_SET 149 + IOCMD_FCPIM_THROTTLE_SET, 150 + IOCMD_TFRU_READ, 151 + IOCMD_TFRU_WRITE, 152 + IOCMD_FRUVPD_READ, 153 + IOCMD_FRUVPD_UPDATE, 154 + IOCMD_FRUVPD_GET_MAX_SIZE, 150 155 }; 151 156 152 157 struct bfa_bsg_gen_s { ··· 753 748 u16 bfad_num; 754 749 u16 vf_id; 755 750 struct bfa_defs_fcpim_throttle_s throttle; 751 + }; 752 + 753 + #define BFA_TFRU_DATA_SIZE 64 754 + #define BFA_MAX_FRUVPD_TRANSFER_SIZE 0x1000 755 + 756 + struct bfa_bsg_tfru_s { 757 + bfa_status_t status; 758 + u16 bfad_num; 759 + u16 rsvd; 760 + u32 offset; 761 + u32 len; 762 + u8 data[BFA_TFRU_DATA_SIZE]; 763 + }; 764 + 765 + struct bfa_bsg_fruvpd_s { 766 + bfa_status_t status; 767 + u16 bfad_num; 768 + u16 rsvd; 769 + u32 offset; 770 + u32 len; 771 + u8 data[BFA_MAX_FRUVPD_TRANSFER_SIZE]; 772 + }; 773 + 774 + struct bfa_bsg_fruvpd_max_size_s { 775 + bfa_status_t status; 776 + u16 bfad_num; 777 + u16 rsvd; 778 + u32 max_size; 756 779 }; 757 780 758 781 struct bfa_bsg_fcpt_s {
+46 -1
drivers/scsi/bfa/bfi.h
··· 210 210 BFI_MC_PORT = 21, /* Physical port */ 211 211 BFI_MC_SFP = 22, /* SFP module */ 212 212 BFI_MC_PHY = 25, /* External PHY message class */ 213 - BFI_MC_MAX = 32 213 + BFI_MC_FRU = 34, 214 + BFI_MC_MAX = 35 214 215 }; 215 216 216 217 #define BFI_IOC_MAX_CQS 4 ··· 1171 1170 u32 length; 1172 1171 }; 1173 1172 1173 + enum bfi_fru_h2i_msgs { 1174 + BFI_FRUVPD_H2I_WRITE_REQ = 1, 1175 + BFI_FRUVPD_H2I_READ_REQ = 2, 1176 + BFI_TFRU_H2I_WRITE_REQ = 3, 1177 + BFI_TFRU_H2I_READ_REQ = 4, 1178 + }; 1179 + 1180 + enum bfi_fru_i2h_msgs { 1181 + BFI_FRUVPD_I2H_WRITE_RSP = BFA_I2HM(1), 1182 + BFI_FRUVPD_I2H_READ_RSP = BFA_I2HM(2), 1183 + BFI_TFRU_I2H_WRITE_RSP = BFA_I2HM(3), 1184 + BFI_TFRU_I2H_READ_RSP = BFA_I2HM(4), 1185 + }; 1186 + 1187 + /* 1188 + * FRU write request 1189 + */ 1190 + struct bfi_fru_write_req_s { 1191 + struct bfi_mhdr_s mh; /* Common msg header */ 1192 + u8 last; 1193 + u8 rsv[3]; 1194 + u32 offset; 1195 + u32 length; 1196 + struct bfi_alen_s alen; 1197 + }; 1198 + 1199 + /* 1200 + * FRU read request 1201 + */ 1202 + struct bfi_fru_read_req_s { 1203 + struct bfi_mhdr_s mh; /* Common msg header */ 1204 + u32 offset; 1205 + u32 length; 1206 + struct bfi_alen_s alen; 1207 + }; 1208 + 1209 + /* 1210 + * FRU response 1211 + */ 1212 + struct bfi_fru_rsp_s { 1213 + struct bfi_mhdr_s mh; /* Common msg header */ 1214 + u32 status; 1215 + u32 length; 1216 + }; 1174 1217 #pragma pack() 1175 1218 1176 1219 #endif /* __BFI_H__ */
+1
drivers/scsi/bfa/bfi_ms.h
··· 426 426 u8 auth_en; 427 427 u8 lps_role; 428 428 u8 bb_scn; 429 + u32 vvl_flag; 429 430 }; 430 431 431 432 struct bfi_lps_login_rsp_s {