aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c104
1 files changed, 90 insertions, 14 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index aef093db597e..880de6f380e9 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -770,29 +770,104 @@ qla24xx_chip_diag(scsi_qla_host_t *ha)
770 return rval; 770 return rval;
771} 771}
772 772
773static void 773void
774qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) 774qla2x00_alloc_fw_dump(scsi_qla_host_t *ha)
775{ 775{
776 uint32_t dump_size = 0; 776 int rval;
777 uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size,
778 eft_size;
779 dma_addr_t eft_dma;
780 void *eft;
781
782 if (ha->fw_dump) {
783 qla_printk(KERN_WARNING, ha,
784 "Firmware dump previously allocated.\n");
785 return;
786 }
777 787
778 ha->fw_dumped = 0; 788 ha->fw_dumped = 0;
789 fixed_size = mem_size = eft_size = 0;
779 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 790 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
780 dump_size = sizeof(struct qla2100_fw_dump); 791 fixed_size = sizeof(struct qla2100_fw_dump);
781 } else if (IS_QLA23XX(ha)) { 792 } else if (IS_QLA23XX(ha)) {
782 dump_size = sizeof(struct qla2300_fw_dump); 793 fixed_size = offsetof(struct qla2300_fw_dump, data_ram);
783 dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t); 794 mem_size = (ha->fw_memory_size - 0x11000 + 1) *
784 } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { 795 sizeof(uint16_t);
785 dump_size = sizeof(struct qla24xx_fw_dump); 796 } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
786 dump_size += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t); 797 fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem);
798 mem_size = (ha->fw_memory_size - 0x100000 + 1) *
799 sizeof(uint32_t);
800
801 /* Allocate memory for Extended Trace Buffer. */
802 eft = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &eft_dma,
803 GFP_KERNEL);
804 if (!eft) {
805 qla_printk(KERN_WARNING, ha, "Unable to allocate "
806 "(%d KB) for EFT.\n", EFT_SIZE / 1024);
807 goto cont_alloc;
808 }
809
810 rval = qla2x00_trace_control(ha, TC_ENABLE, eft_dma,
811 EFT_NUM_BUFFERS);
812 if (rval) {
813 qla_printk(KERN_WARNING, ha, "Unable to initialize "
814 "EFT (%d).\n", rval);
815 dma_free_coherent(&ha->pdev->dev, EFT_SIZE, eft,
816 eft_dma);
817 goto cont_alloc;
818 }
819
820 qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n",
821 EFT_SIZE / 1024);
822
823 eft_size = EFT_SIZE;
824 memset(eft, 0, eft_size);
825 ha->eft_dma = eft_dma;
826 ha->eft = eft;
787 } 827 }
828cont_alloc:
829 req_q_size = ha->request_q_length * sizeof(request_t);
830 rsp_q_size = ha->response_q_length * sizeof(response_t);
831
832 dump_size = offsetof(struct qla2xxx_fw_dump, isp);
833 dump_size += fixed_size + mem_size + req_q_size + rsp_q_size +
834 eft_size;
788 835
789 ha->fw_dump = vmalloc(dump_size); 836 ha->fw_dump = vmalloc(dump_size);
790 if (ha->fw_dump) 837 if (!ha->fw_dump) {
791 qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware "
792 "dump...\n", dump_size / 1024);
793 else
794 qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for " 838 qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for "
795 "firmware dump!!!\n", dump_size / 1024); 839 "firmware dump!!!\n", dump_size / 1024);
840
841 if (ha->eft) {
842 dma_free_coherent(&ha->pdev->dev, eft_size, ha->eft,
843 ha->eft_dma);
844 ha->eft = NULL;
845 ha->eft_dma = 0;
846 }
847 return;
848 }
849
850 qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware dump...\n",
851 dump_size / 1024);
852
853 ha->fw_dump_len = dump_size;
854 ha->fw_dump->signature[0] = 'Q';
855 ha->fw_dump->signature[1] = 'L';
856 ha->fw_dump->signature[2] = 'G';
857 ha->fw_dump->signature[3] = 'C';
858 ha->fw_dump->version = __constant_htonl(1);
859
860 ha->fw_dump->fixed_size = htonl(fixed_size);
861 ha->fw_dump->mem_size = htonl(mem_size);
862 ha->fw_dump->req_q_size = htonl(req_q_size);
863 ha->fw_dump->rsp_q_size = htonl(rsp_q_size);
864
865 ha->fw_dump->eft_size = htonl(eft_size);
866 ha->fw_dump->eft_addr_l = htonl(LSD(ha->eft_dma));
867 ha->fw_dump->eft_addr_h = htonl(MSD(ha->eft_dma));
868
869 ha->fw_dump->header_size =
870 htonl(offsetof(struct qla2xxx_fw_dump, isp));
796} 871}
797 872
798/** 873/**
@@ -810,8 +885,6 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha)
810 dma_addr_t request_dma; 885 dma_addr_t request_dma;
811 request_t *request_ring; 886 request_t *request_ring;
812 887
813 qla2x00_alloc_fw_dump(ha);
814
815 /* Valid only on recent ISPs. */ 888 /* Valid only on recent ISPs. */
816 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 889 if (IS_QLA2100(ha) || IS_QLA2200(ha))
817 return; 890 return;
@@ -883,6 +956,9 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
883 &ha->fw_subminor_version, 956 &ha->fw_subminor_version,
884 &ha->fw_attributes, &ha->fw_memory_size); 957 &ha->fw_attributes, &ha->fw_memory_size);
885 qla2x00_resize_request_q(ha); 958 qla2x00_resize_request_q(ha);
959
960 if (ql2xallocfwdump)
961 qla2x00_alloc_fw_dump(ha);
886 } 962 }
887 } else { 963 } else {
888 DEBUG2(printk(KERN_INFO 964 DEBUG2(printk(KERN_INFO