aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2011-05-24 11:42:45 -0400
committerJames Bottomley <jbottomley@parallels.com>2011-05-26 23:49:37 -0400
commit52d5244096017bbd11164479116baceaede342b0 (patch)
tree1e61c05ab7f1babd2ed44f6136bc6f9384d9f786 /drivers/scsi/lpfc/lpfc_sli.c
parent912e3acde60b3b9ebf46c5ec5ae6bd01b80132c8 (diff)
[SCSI] lpfc 8.3.24: Add request-firmware support
Add request-firmware support: - Add support for request_firmware interface for INTF2 SLI4 ports. - Add ability to reset SLI4 INTF2 ports. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <jbottomley@parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index dd911d6d0ee5..fcfa8c8cfb67 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -13500,6 +13500,96 @@ out:
13500} 13500}
13501 13501
13502/** 13502/**
13503 * lpfc_wr_object - write an object to the firmware
13504 * @phba: HBA structure that indicates port to create a queue on.
13505 * @dmabuf_list: list of dmabufs to write to the port.
13506 * @size: the total byte value of the objects to write to the port.
13507 * @offset: the current offset to be used to start the transfer.
13508 *
13509 * This routine will create a wr_object mailbox command to send to the port.
13510 * the mailbox command will be constructed using the dma buffers described in
13511 * @dmabuf_list to create a list of BDEs. This routine will fill in as many
13512 * BDEs that the imbedded mailbox can support. The @offset variable will be
13513 * used to indicate the starting offset of the transfer and will also return
13514 * the offset after the write object mailbox has completed. @size is used to
13515 * determine the end of the object and whether the eof bit should be set.
13516 *
13517 * Return 0 is successful and offset will contain the the new offset to use
13518 * for the next write.
13519 * Return negative value for error cases.
13520 **/
13521int
13522lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
13523 uint32_t size, uint32_t *offset)
13524{
13525 struct lpfc_mbx_wr_object *wr_object;
13526 LPFC_MBOXQ_t *mbox;
13527 int rc = 0, i = 0;
13528 uint32_t shdr_status, shdr_add_status;
13529 uint32_t mbox_tmo;
13530 union lpfc_sli4_cfg_shdr *shdr;
13531 struct lpfc_dmabuf *dmabuf;
13532 uint32_t written = 0;
13533
13534 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
13535 if (!mbox)
13536 return -ENOMEM;
13537
13538 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
13539 LPFC_MBOX_OPCODE_WRITE_OBJECT,
13540 sizeof(struct lpfc_mbx_wr_object) -
13541 sizeof(struct lpfc_sli4_cfg_mhdr), LPFC_SLI4_MBX_EMBED);
13542
13543 wr_object = (struct lpfc_mbx_wr_object *)&mbox->u.mqe.un.wr_object;
13544 wr_object->u.request.write_offset = *offset;
13545 sprintf((uint8_t *)wr_object->u.request.object_name, "/");
13546 wr_object->u.request.object_name[0] =
13547 cpu_to_le32(wr_object->u.request.object_name[0]);
13548 bf_set(lpfc_wr_object_eof, &wr_object->u.request, 0);
13549 list_for_each_entry(dmabuf, dmabuf_list, list) {
13550 if (i >= LPFC_MBX_WR_CONFIG_MAX_BDE || written >= size)
13551 break;
13552 wr_object->u.request.bde[i].addrLow = putPaddrLow(dmabuf->phys);
13553 wr_object->u.request.bde[i].addrHigh =
13554 putPaddrHigh(dmabuf->phys);
13555 if (written + SLI4_PAGE_SIZE >= size) {
13556 wr_object->u.request.bde[i].tus.f.bdeSize =
13557 (size - written);
13558 written += (size - written);
13559 bf_set(lpfc_wr_object_eof, &wr_object->u.request, 1);
13560 } else {
13561 wr_object->u.request.bde[i].tus.f.bdeSize =
13562 SLI4_PAGE_SIZE;
13563 written += SLI4_PAGE_SIZE;
13564 }
13565 i++;
13566 }
13567 wr_object->u.request.bde_count = i;
13568 bf_set(lpfc_wr_object_write_length, &wr_object->u.request, written);
13569 if (!phba->sli4_hba.intr_enable)
13570 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
13571 else {
13572 mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG);
13573 rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
13574 }
13575 /* The IOCTL status is embedded in the mailbox subheader. */
13576 shdr = (union lpfc_sli4_cfg_shdr *) &wr_object->header.cfg_shdr;
13577 shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
13578 shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
13579 if (rc != MBX_TIMEOUT)
13580 mempool_free(mbox, phba->mbox_mem_pool);
13581 if (shdr_status || shdr_add_status || rc) {
13582 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
13583 "3025 Write Object mailbox failed with "
13584 "status x%x add_status x%x, mbx status x%x\n",
13585 shdr_status, shdr_add_status, rc);
13586 rc = -ENXIO;
13587 } else
13588 *offset += wr_object->u.response.actual_write_length;
13589 return rc;
13590}
13591
13592/**
13503 * lpfc_cleanup_pending_mbox - Free up vport discovery mailbox commands. 13593 * lpfc_cleanup_pending_mbox - Free up vport discovery mailbox commands.
13504 * @vport: pointer to vport data structure. 13594 * @vport: pointer to vport data structure.
13505 * 13595 *