diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 377 |
1 files changed, 226 insertions, 151 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 9598fdcb08ab..411ed48d79da 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
| @@ -64,8 +64,8 @@ static int lpfc_sli4_queue_verify(struct lpfc_hba *); | |||
| 64 | static int lpfc_create_bootstrap_mbox(struct lpfc_hba *); | 64 | static int lpfc_create_bootstrap_mbox(struct lpfc_hba *); |
| 65 | static int lpfc_setup_endian_order(struct lpfc_hba *); | 65 | static int lpfc_setup_endian_order(struct lpfc_hba *); |
| 66 | static void lpfc_destroy_bootstrap_mbox(struct lpfc_hba *); | 66 | static void lpfc_destroy_bootstrap_mbox(struct lpfc_hba *); |
| 67 | static void lpfc_free_sgl_list(struct lpfc_hba *); | 67 | static void lpfc_free_els_sgl_list(struct lpfc_hba *); |
| 68 | static int lpfc_init_sgl_list(struct lpfc_hba *); | 68 | static void lpfc_init_sgl_list(struct lpfc_hba *); |
| 69 | static int lpfc_init_active_sgl_array(struct lpfc_hba *); | 69 | static int lpfc_init_active_sgl_array(struct lpfc_hba *); |
| 70 | static void lpfc_free_active_sgl(struct lpfc_hba *); | 70 | static void lpfc_free_active_sgl(struct lpfc_hba *); |
| 71 | static int lpfc_hba_down_post_s3(struct lpfc_hba *phba); | 71 | static int lpfc_hba_down_post_s3(struct lpfc_hba *phba); |
| @@ -2767,47 +2767,14 @@ lpfc_offline(struct lpfc_hba *phba) | |||
| 2767 | } | 2767 | } |
| 2768 | 2768 | ||
| 2769 | /** | 2769 | /** |
| 2770 | * lpfc_scsi_buf_update - Update the scsi_buffers that are already allocated. | ||
| 2771 | * @phba: pointer to lpfc hba data structure. | ||
| 2772 | * | ||
| 2773 | * This routine goes through all the scsi buffers in the system and updates the | ||
| 2774 | * Physical XRIs assigned to the SCSI buffer because these may change after any | ||
| 2775 | * firmware reset | ||
| 2776 | * | ||
| 2777 | * Return codes | ||
| 2778 | * 0 - successful (for now, it always returns 0) | ||
| 2779 | **/ | ||
| 2780 | int | ||
| 2781 | lpfc_scsi_buf_update(struct lpfc_hba *phba) | ||
| 2782 | { | ||
| 2783 | struct lpfc_scsi_buf *sb, *sb_next; | ||
| 2784 | |||
| 2785 | spin_lock_irq(&phba->hbalock); | ||
| 2786 | spin_lock(&phba->scsi_buf_list_lock); | ||
| 2787 | list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) { | ||
| 2788 | sb->cur_iocbq.sli4_xritag = | ||
| 2789 | phba->sli4_hba.xri_ids[sb->cur_iocbq.sli4_lxritag]; | ||
| 2790 | set_bit(sb->cur_iocbq.sli4_lxritag, phba->sli4_hba.xri_bmask); | ||
| 2791 | phba->sli4_hba.max_cfg_param.xri_used++; | ||
| 2792 | phba->sli4_hba.xri_count++; | ||
| 2793 | } | ||
| 2794 | spin_unlock(&phba->scsi_buf_list_lock); | ||
| 2795 | spin_unlock_irq(&phba->hbalock); | ||
| 2796 | return 0; | ||
| 2797 | } | ||
| 2798 | |||
| 2799 | /** | ||
| 2800 | * lpfc_scsi_free - Free all the SCSI buffers and IOCBs from driver lists | 2770 | * lpfc_scsi_free - Free all the SCSI buffers and IOCBs from driver lists |
| 2801 | * @phba: pointer to lpfc hba data structure. | 2771 | * @phba: pointer to lpfc hba data structure. |
| 2802 | * | 2772 | * |
| 2803 | * This routine is to free all the SCSI buffers and IOCBs from the driver | 2773 | * This routine is to free all the SCSI buffers and IOCBs from the driver |
| 2804 | * list back to kernel. It is called from lpfc_pci_remove_one to free | 2774 | * list back to kernel. It is called from lpfc_pci_remove_one to free |
| 2805 | * the internal resources before the device is removed from the system. | 2775 | * the internal resources before the device is removed from the system. |
| 2806 | * | ||
| 2807 | * Return codes | ||
| 2808 | * 0 - successful (for now, it always returns 0) | ||
| 2809 | **/ | 2776 | **/ |
| 2810 | static int | 2777 | static void |
| 2811 | lpfc_scsi_free(struct lpfc_hba *phba) | 2778 | lpfc_scsi_free(struct lpfc_hba *phba) |
| 2812 | { | 2779 | { |
| 2813 | struct lpfc_scsi_buf *sb, *sb_next; | 2780 | struct lpfc_scsi_buf *sb, *sb_next; |
| @@ -2833,7 +2800,178 @@ lpfc_scsi_free(struct lpfc_hba *phba) | |||
| 2833 | } | 2800 | } |
| 2834 | 2801 | ||
| 2835 | spin_unlock_irq(&phba->hbalock); | 2802 | spin_unlock_irq(&phba->hbalock); |
| 2803 | } | ||
| 2804 | |||
| 2805 | /** | ||
| 2806 | * lpfc_sli4_xri_sgl_update - update xri-sgl sizing and mapping | ||
| 2807 | * @phba: pointer to lpfc hba data structure. | ||
| 2808 | * | ||
| 2809 | * This routine first calculates the sizes of the current els and allocated | ||
| 2810 | * scsi sgl lists, and then goes through all sgls to updates the physical | ||
| 2811 | * XRIs assigned due to port function reset. During port initialization, the | ||
| 2812 | * current els and allocated scsi sgl lists are 0s. | ||
| 2813 | * | ||
| 2814 | * Return codes | ||
| 2815 | * 0 - successful (for now, it always returns 0) | ||
| 2816 | **/ | ||
| 2817 | int | ||
| 2818 | lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba) | ||
| 2819 | { | ||
| 2820 | struct lpfc_sglq *sglq_entry = NULL, *sglq_entry_next = NULL; | ||
| 2821 | struct lpfc_scsi_buf *psb = NULL, *psb_next = NULL; | ||
| 2822 | uint16_t i, lxri, xri_cnt, els_xri_cnt, scsi_xri_cnt; | ||
| 2823 | LIST_HEAD(els_sgl_list); | ||
| 2824 | LIST_HEAD(scsi_sgl_list); | ||
| 2825 | int rc; | ||
| 2826 | |||
| 2827 | /* | ||
| 2828 | * update on pci function's els xri-sgl list | ||
| 2829 | */ | ||
| 2830 | els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); | ||
| 2831 | if (els_xri_cnt > phba->sli4_hba.els_xri_cnt) { | ||
| 2832 | /* els xri-sgl expanded */ | ||
| 2833 | xri_cnt = els_xri_cnt - phba->sli4_hba.els_xri_cnt; | ||
| 2834 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
| 2835 | "3157 ELS xri-sgl count increased from " | ||
| 2836 | "%d to %d\n", phba->sli4_hba.els_xri_cnt, | ||
| 2837 | els_xri_cnt); | ||
| 2838 | /* allocate the additional els sgls */ | ||
| 2839 | for (i = 0; i < xri_cnt; i++) { | ||
| 2840 | sglq_entry = kzalloc(sizeof(struct lpfc_sglq), | ||
| 2841 | GFP_KERNEL); | ||
| 2842 | if (sglq_entry == NULL) { | ||
| 2843 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
| 2844 | "2562 Failure to allocate an " | ||
| 2845 | "ELS sgl entry:%d\n", i); | ||
| 2846 | rc = -ENOMEM; | ||
| 2847 | goto out_free_mem; | ||
| 2848 | } | ||
| 2849 | sglq_entry->buff_type = GEN_BUFF_TYPE; | ||
| 2850 | sglq_entry->virt = lpfc_mbuf_alloc(phba, 0, | ||
| 2851 | &sglq_entry->phys); | ||
| 2852 | if (sglq_entry->virt == NULL) { | ||
| 2853 | kfree(sglq_entry); | ||
| 2854 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
| 2855 | "2563 Failure to allocate an " | ||
| 2856 | "ELS mbuf:%d\n", i); | ||
| 2857 | rc = -ENOMEM; | ||
| 2858 | goto out_free_mem; | ||
| 2859 | } | ||
| 2860 | sglq_entry->sgl = sglq_entry->virt; | ||
| 2861 | memset(sglq_entry->sgl, 0, LPFC_BPL_SIZE); | ||
| 2862 | sglq_entry->state = SGL_FREED; | ||
| 2863 | list_add_tail(&sglq_entry->list, &els_sgl_list); | ||
| 2864 | } | ||
| 2865 | spin_lock(&phba->hbalock); | ||
| 2866 | list_splice_init(&els_sgl_list, &phba->sli4_hba.lpfc_sgl_list); | ||
| 2867 | spin_unlock(&phba->hbalock); | ||
| 2868 | } else if (els_xri_cnt < phba->sli4_hba.els_xri_cnt) { | ||
| 2869 | /* els xri-sgl shrinked */ | ||
| 2870 | xri_cnt = phba->sli4_hba.els_xri_cnt - els_xri_cnt; | ||
| 2871 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
| 2872 | "3158 ELS xri-sgl count decreased from " | ||
| 2873 | "%d to %d\n", phba->sli4_hba.els_xri_cnt, | ||
| 2874 | els_xri_cnt); | ||
| 2875 | spin_lock_irq(&phba->hbalock); | ||
| 2876 | list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &els_sgl_list); | ||
| 2877 | spin_unlock_irq(&phba->hbalock); | ||
| 2878 | /* release extra els sgls from list */ | ||
| 2879 | for (i = 0; i < xri_cnt; i++) { | ||
| 2880 | list_remove_head(&els_sgl_list, | ||
| 2881 | sglq_entry, struct lpfc_sglq, list); | ||
| 2882 | if (sglq_entry) { | ||
| 2883 | lpfc_mbuf_free(phba, sglq_entry->virt, | ||
| 2884 | sglq_entry->phys); | ||
| 2885 | kfree(sglq_entry); | ||
| 2886 | } | ||
| 2887 | } | ||
| 2888 | spin_lock_irq(&phba->hbalock); | ||
| 2889 | list_splice_init(&els_sgl_list, &phba->sli4_hba.lpfc_sgl_list); | ||
| 2890 | spin_unlock_irq(&phba->hbalock); | ||
| 2891 | } else | ||
| 2892 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
| 2893 | "3163 ELS xri-sgl count unchanged: %d\n", | ||
| 2894 | els_xri_cnt); | ||
| 2895 | phba->sli4_hba.els_xri_cnt = els_xri_cnt; | ||
| 2896 | |||
| 2897 | /* update xris to els sgls on the list */ | ||
| 2898 | sglq_entry = NULL; | ||
| 2899 | sglq_entry_next = NULL; | ||
| 2900 | list_for_each_entry_safe(sglq_entry, sglq_entry_next, | ||
| 2901 | &phba->sli4_hba.lpfc_sgl_list, list) { | ||
| 2902 | lxri = lpfc_sli4_next_xritag(phba); | ||
| 2903 | if (lxri == NO_XRI) { | ||
| 2904 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
| 2905 | "2400 Failed to allocate xri for " | ||
| 2906 | "ELS sgl\n"); | ||
| 2907 | rc = -ENOMEM; | ||
| 2908 | goto out_free_mem; | ||
| 2909 | } | ||
| 2910 | sglq_entry->sli4_lxritag = lxri; | ||
| 2911 | sglq_entry->sli4_xritag = phba->sli4_hba.xri_ids[lxri]; | ||
| 2912 | } | ||
| 2913 | |||
| 2914 | /* | ||
| 2915 | * update on pci function's allocated scsi xri-sgl list | ||
| 2916 | */ | ||
| 2917 | phba->total_scsi_bufs = 0; | ||
| 2918 | |||
| 2919 | /* maximum number of xris available for scsi buffers */ | ||
| 2920 | phba->sli4_hba.scsi_xri_max = phba->sli4_hba.max_cfg_param.max_xri - | ||
| 2921 | els_xri_cnt; | ||
| 2922 | |||
| 2923 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
| 2924 | "2401 Current allocated SCSI xri-sgl count:%d, " | ||
| 2925 | "maximum SCSI xri count:%d\n", | ||
| 2926 | phba->sli4_hba.scsi_xri_cnt, | ||
| 2927 | phba->sli4_hba.scsi_xri_max); | ||
| 2928 | |||
| 2929 | spin_lock_irq(&phba->scsi_buf_list_lock); | ||
| 2930 | list_splice_init(&phba->lpfc_scsi_buf_list, &scsi_sgl_list); | ||
| 2931 | spin_unlock_irq(&phba->scsi_buf_list_lock); | ||
| 2932 | |||
| 2933 | if (phba->sli4_hba.scsi_xri_cnt > phba->sli4_hba.scsi_xri_max) { | ||
| 2934 | /* max scsi xri shrinked below the allocated scsi buffers */ | ||
| 2935 | scsi_xri_cnt = phba->sli4_hba.scsi_xri_cnt - | ||
| 2936 | phba->sli4_hba.scsi_xri_max; | ||
| 2937 | /* release the extra allocated scsi buffers */ | ||
| 2938 | for (i = 0; i < scsi_xri_cnt; i++) { | ||
| 2939 | list_remove_head(&scsi_sgl_list, psb, | ||
| 2940 | struct lpfc_scsi_buf, list); | ||
| 2941 | pci_pool_free(phba->lpfc_scsi_dma_buf_pool, psb->data, | ||
| 2942 | psb->dma_handle); | ||
| 2943 | kfree(psb); | ||
| 2944 | } | ||
| 2945 | spin_lock_irq(&phba->scsi_buf_list_lock); | ||
| 2946 | phba->sli4_hba.scsi_xri_cnt -= scsi_xri_cnt; | ||
| 2947 | spin_unlock_irq(&phba->scsi_buf_list_lock); | ||
| 2948 | } | ||
| 2949 | |||
| 2950 | /* update xris associated to remaining allocated scsi buffers */ | ||
| 2951 | psb = NULL; | ||
| 2952 | psb_next = NULL; | ||
| 2953 | list_for_each_entry_safe(psb, psb_next, &scsi_sgl_list, list) { | ||
| 2954 | lxri = lpfc_sli4_next_xritag(phba); | ||
| 2955 | if (lxri == NO_XRI) { | ||
| 2956 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
| 2957 | "2560 Failed to allocate xri for " | ||
| 2958 | "scsi buffer\n"); | ||
| 2959 | rc = -ENOMEM; | ||
| 2960 | goto out_free_mem; | ||
| 2961 | } | ||
| 2962 | psb->cur_iocbq.sli4_lxritag = lxri; | ||
| 2963 | psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri]; | ||
| 2964 | } | ||
| 2965 | spin_lock(&phba->scsi_buf_list_lock); | ||
| 2966 | list_splice_init(&scsi_sgl_list, &phba->lpfc_scsi_buf_list); | ||
| 2967 | spin_unlock(&phba->scsi_buf_list_lock); | ||
| 2968 | |||
| 2836 | return 0; | 2969 | return 0; |
| 2970 | |||
| 2971 | out_free_mem: | ||
| 2972 | lpfc_free_els_sgl_list(phba); | ||
| 2973 | lpfc_scsi_free(phba); | ||
| 2974 | return rc; | ||
| 2837 | } | 2975 | } |
| 2838 | 2976 | ||
| 2839 | /** | 2977 | /** |
| @@ -4636,18 +4774,15 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
| 4636 | if (rc) | 4774 | if (rc) |
| 4637 | goto out_free_bsmbx; | 4775 | goto out_free_bsmbx; |
| 4638 | 4776 | ||
| 4639 | /* Initialize and populate the iocb list per host */ | 4777 | /* Initialize sgl lists per host */ |
| 4640 | rc = lpfc_init_sgl_list(phba); | 4778 | lpfc_init_sgl_list(phba); |
| 4641 | if (rc) { | 4779 | |
| 4642 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4780 | /* Allocate and initialize active sgl array */ |
| 4643 | "1400 Failed to initialize sgl list.\n"); | ||
| 4644 | goto out_destroy_cq_event_pool; | ||
| 4645 | } | ||
| 4646 | rc = lpfc_init_active_sgl_array(phba); | 4781 | rc = lpfc_init_active_sgl_array(phba); |
| 4647 | if (rc) { | 4782 | if (rc) { |
| 4648 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4783 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 4649 | "1430 Failed to initialize sgl list.\n"); | 4784 | "1430 Failed to initialize sgl list.\n"); |
| 4650 | goto out_free_sgl_list; | 4785 | goto out_destroy_cq_event_pool; |
| 4651 | } | 4786 | } |
| 4652 | rc = lpfc_sli4_init_rpi_hdrs(phba); | 4787 | rc = lpfc_sli4_init_rpi_hdrs(phba); |
| 4653 | if (rc) { | 4788 | if (rc) { |
| @@ -4722,8 +4857,6 @@ out_remove_rpi_hdrs: | |||
| 4722 | lpfc_sli4_remove_rpi_hdrs(phba); | 4857 | lpfc_sli4_remove_rpi_hdrs(phba); |
| 4723 | out_free_active_sgl: | 4858 | out_free_active_sgl: |
| 4724 | lpfc_free_active_sgl(phba); | 4859 | lpfc_free_active_sgl(phba); |
| 4725 | out_free_sgl_list: | ||
| 4726 | lpfc_free_sgl_list(phba); | ||
| 4727 | out_destroy_cq_event_pool: | 4860 | out_destroy_cq_event_pool: |
| 4728 | lpfc_sli4_cq_event_pool_destroy(phba); | 4861 | lpfc_sli4_cq_event_pool_destroy(phba); |
| 4729 | out_free_bsmbx: | 4862 | out_free_bsmbx: |
| @@ -4760,10 +4893,7 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba) | |||
| 4760 | 4893 | ||
| 4761 | /* Free the ELS sgl list */ | 4894 | /* Free the ELS sgl list */ |
| 4762 | lpfc_free_active_sgl(phba); | 4895 | lpfc_free_active_sgl(phba); |
| 4763 | lpfc_free_sgl_list(phba); | 4896 | lpfc_free_els_sgl_list(phba); |
| 4764 | |||
| 4765 | /* Free the SCSI sgl management array */ | ||
| 4766 | kfree(phba->sli4_hba.lpfc_scsi_psb_array); | ||
| 4767 | 4897 | ||
| 4768 | /* Free the completion queue EQ event pool */ | 4898 | /* Free the completion queue EQ event pool */ |
| 4769 | lpfc_sli4_cq_event_release_all(phba); | 4899 | lpfc_sli4_cq_event_release_all(phba); |
| @@ -4990,29 +5120,42 @@ out_free_iocbq: | |||
| 4990 | } | 5120 | } |
| 4991 | 5121 | ||
| 4992 | /** | 5122 | /** |
| 4993 | * lpfc_free_sgl_list - Free sgl list. | 5123 | * lpfc_free_sgl_list - Free a given sgl list. |
| 4994 | * @phba: pointer to lpfc hba data structure. | 5124 | * @phba: pointer to lpfc hba data structure. |
| 5125 | * @sglq_list: pointer to the head of sgl list. | ||
| 4995 | * | 5126 | * |
| 4996 | * This routine is invoked to free the driver's sgl list and memory. | 5127 | * This routine is invoked to free a give sgl list and memory. |
| 4997 | **/ | 5128 | **/ |
| 4998 | static void | 5129 | void |
| 4999 | lpfc_free_sgl_list(struct lpfc_hba *phba) | 5130 | lpfc_free_sgl_list(struct lpfc_hba *phba, struct list_head *sglq_list) |
| 5000 | { | 5131 | { |
| 5001 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; | 5132 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; |
| 5133 | |||
| 5134 | list_for_each_entry_safe(sglq_entry, sglq_next, sglq_list, list) { | ||
| 5135 | list_del(&sglq_entry->list); | ||
| 5136 | lpfc_mbuf_free(phba, sglq_entry->virt, sglq_entry->phys); | ||
| 5137 | kfree(sglq_entry); | ||
| 5138 | } | ||
| 5139 | } | ||
| 5140 | |||
| 5141 | /** | ||
| 5142 | * lpfc_free_els_sgl_list - Free els sgl list. | ||
| 5143 | * @phba: pointer to lpfc hba data structure. | ||
| 5144 | * | ||
| 5145 | * This routine is invoked to free the driver's els sgl list and memory. | ||
| 5146 | **/ | ||
| 5147 | static void | ||
| 5148 | lpfc_free_els_sgl_list(struct lpfc_hba *phba) | ||
| 5149 | { | ||
| 5002 | LIST_HEAD(sglq_list); | 5150 | LIST_HEAD(sglq_list); |
| 5003 | 5151 | ||
| 5152 | /* Retrieve all els sgls from driver list */ | ||
| 5004 | spin_lock_irq(&phba->hbalock); | 5153 | spin_lock_irq(&phba->hbalock); |
| 5005 | list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &sglq_list); | 5154 | list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &sglq_list); |
| 5006 | spin_unlock_irq(&phba->hbalock); | 5155 | spin_unlock_irq(&phba->hbalock); |
| 5007 | 5156 | ||
| 5008 | list_for_each_entry_safe(sglq_entry, sglq_next, | 5157 | /* Now free the sgl list */ |
| 5009 | &sglq_list, list) { | 5158 | lpfc_free_sgl_list(phba, &sglq_list); |
| 5010 | list_del(&sglq_entry->list); | ||
| 5011 | lpfc_mbuf_free(phba, sglq_entry->virt, sglq_entry->phys); | ||
| 5012 | kfree(sglq_entry); | ||
| 5013 | phba->sli4_hba.total_sglq_bufs--; | ||
| 5014 | } | ||
| 5015 | kfree(phba->sli4_hba.lpfc_els_sgl_array); | ||
| 5016 | } | 5159 | } |
| 5017 | 5160 | ||
| 5018 | /** | 5161 | /** |
| @@ -5057,99 +5200,19 @@ lpfc_free_active_sgl(struct lpfc_hba *phba) | |||
| 5057 | * This routine is invoked to allocate and initizlize the driver's sgl | 5200 | * This routine is invoked to allocate and initizlize the driver's sgl |
| 5058 | * list and set up the sgl xritag tag array accordingly. | 5201 | * list and set up the sgl xritag tag array accordingly. |
| 5059 | * | 5202 | * |
| 5060 | * Return codes | ||
| 5061 | * 0 - successful | ||
| 5062 | * other values - error | ||
| 5063 | **/ | 5203 | **/ |
| 5064 | static int | 5204 | static void |
| 5065 | lpfc_init_sgl_list(struct lpfc_hba *phba) | 5205 | lpfc_init_sgl_list(struct lpfc_hba *phba) |
| 5066 | { | 5206 | { |
| 5067 | struct lpfc_sglq *sglq_entry = NULL; | ||
| 5068 | int i; | ||
| 5069 | int els_xri_cnt; | ||
| 5070 | |||
| 5071 | els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); | ||
| 5072 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
| 5073 | "2400 ELS XRI count %d.\n", | ||
| 5074 | els_xri_cnt); | ||
| 5075 | /* Initialize and populate the sglq list per host/VF. */ | 5207 | /* Initialize and populate the sglq list per host/VF. */ |
| 5076 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_sgl_list); | 5208 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_sgl_list); |
| 5077 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_els_sgl_list); | 5209 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_els_sgl_list); |
| 5078 | 5210 | ||
| 5079 | /* Sanity check on XRI management */ | 5211 | /* els xri-sgl book keeping */ |
| 5080 | if (phba->sli4_hba.max_cfg_param.max_xri <= els_xri_cnt) { | 5212 | phba->sli4_hba.els_xri_cnt = 0; |
| 5081 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
| 5082 | "2562 No room left for SCSI XRI allocation: " | ||
| 5083 | "max_xri=%d, els_xri=%d\n", | ||
| 5084 | phba->sli4_hba.max_cfg_param.max_xri, | ||
| 5085 | els_xri_cnt); | ||
| 5086 | return -ENOMEM; | ||
| 5087 | } | ||
| 5088 | |||
| 5089 | /* Allocate memory for the ELS XRI management array */ | ||
| 5090 | phba->sli4_hba.lpfc_els_sgl_array = | ||
| 5091 | kzalloc((sizeof(struct lpfc_sglq *) * els_xri_cnt), | ||
| 5092 | GFP_KERNEL); | ||
| 5093 | |||
| 5094 | if (!phba->sli4_hba.lpfc_els_sgl_array) { | ||
| 5095 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
| 5096 | "2401 Failed to allocate memory for ELS " | ||
| 5097 | "XRI management array of size %d.\n", | ||
| 5098 | els_xri_cnt); | ||
| 5099 | return -ENOMEM; | ||
| 5100 | } | ||
| 5101 | 5213 | ||
| 5102 | /* Keep the SCSI XRI into the XRI management array */ | 5214 | /* scsi xri-buffer book keeping */ |
| 5103 | phba->sli4_hba.scsi_xri_max = | ||
| 5104 | phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt; | ||
| 5105 | phba->sli4_hba.scsi_xri_cnt = 0; | 5215 | phba->sli4_hba.scsi_xri_cnt = 0; |
| 5106 | phba->sli4_hba.lpfc_scsi_psb_array = | ||
| 5107 | kzalloc((sizeof(struct lpfc_scsi_buf *) * | ||
| 5108 | phba->sli4_hba.scsi_xri_max), GFP_KERNEL); | ||
| 5109 | |||
| 5110 | if (!phba->sli4_hba.lpfc_scsi_psb_array) { | ||
| 5111 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
| 5112 | "2563 Failed to allocate memory for SCSI " | ||
| 5113 | "XRI management array of size %d.\n", | ||
| 5114 | phba->sli4_hba.scsi_xri_max); | ||
| 5115 | kfree(phba->sli4_hba.lpfc_els_sgl_array); | ||
| 5116 | return -ENOMEM; | ||
| 5117 | } | ||
| 5118 | |||
| 5119 | for (i = 0; i < els_xri_cnt; i++) { | ||
| 5120 | sglq_entry = kzalloc(sizeof(struct lpfc_sglq), GFP_KERNEL); | ||
| 5121 | if (sglq_entry == NULL) { | ||
| 5122 | printk(KERN_ERR "%s: only allocated %d sgls of " | ||
| 5123 | "expected %d count. Unloading driver.\n", | ||
| 5124 | __func__, i, els_xri_cnt); | ||
| 5125 | goto out_free_mem; | ||
| 5126 | } | ||
| 5127 | |||
| 5128 | sglq_entry->buff_type = GEN_BUFF_TYPE; | ||
| 5129 | sglq_entry->virt = lpfc_mbuf_alloc(phba, 0, &sglq_entry->phys); | ||
| 5130 | if (sglq_entry->virt == NULL) { | ||
| 5131 | kfree(sglq_entry); | ||
| 5132 | printk(KERN_ERR "%s: failed to allocate mbuf.\n" | ||
| 5133 | "Unloading driver.\n", __func__); | ||
| 5134 | goto out_free_mem; | ||
| 5135 | } | ||
| 5136 | sglq_entry->sgl = sglq_entry->virt; | ||
| 5137 | memset(sglq_entry->sgl, 0, LPFC_BPL_SIZE); | ||
| 5138 | |||
| 5139 | /* The list order is used by later block SGL registraton */ | ||
| 5140 | spin_lock_irq(&phba->hbalock); | ||
| 5141 | sglq_entry->state = SGL_FREED; | ||
| 5142 | list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list); | ||
| 5143 | phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry; | ||
| 5144 | phba->sli4_hba.total_sglq_bufs++; | ||
| 5145 | spin_unlock_irq(&phba->hbalock); | ||
| 5146 | } | ||
| 5147 | return 0; | ||
| 5148 | |||
| 5149 | out_free_mem: | ||
| 5150 | kfree(phba->sli4_hba.lpfc_scsi_psb_array); | ||
| 5151 | lpfc_free_sgl_list(phba); | ||
| 5152 | return -ENOMEM; | ||
| 5153 | } | 5216 | } |
| 5154 | 5217 | ||
| 5155 | /** | 5218 | /** |
| @@ -7320,9 +7383,11 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) | |||
| 7320 | phba->sli4_hba.u.if_type2.ERR2regaddr); | 7383 | phba->sli4_hba.u.if_type2.ERR2regaddr); |
| 7321 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 7384 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 7322 | "2890 Port error detected during port " | 7385 | "2890 Port error detected during port " |
| 7323 | "reset(%d): port status reg 0x%x, " | 7386 | "reset(%d): wait_tmo:%d ms, " |
| 7387 | "port status reg 0x%x, " | ||
| 7324 | "error 1=0x%x, error 2=0x%x\n", | 7388 | "error 1=0x%x, error 2=0x%x\n", |
| 7325 | num_resets, reg_data.word0, | 7389 | num_resets, rdy_chk*10, |
| 7390 | reg_data.word0, | ||
| 7326 | phba->work_status[0], | 7391 | phba->work_status[0], |
| 7327 | phba->work_status[1]); | 7392 | phba->work_status[1]); |
| 7328 | rc = -ENODEV; | 7393 | rc = -ENODEV; |
| @@ -8694,8 +8759,11 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev) | |||
| 8694 | /* Release all the vports against this physical port */ | 8759 | /* Release all the vports against this physical port */ |
| 8695 | vports = lpfc_create_vport_work_array(phba); | 8760 | vports = lpfc_create_vport_work_array(phba); |
| 8696 | if (vports != NULL) | 8761 | if (vports != NULL) |
| 8697 | for (i = 1; i <= phba->max_vports && vports[i] != NULL; i++) | 8762 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
| 8763 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | ||
| 8764 | continue; | ||
| 8698 | fc_vport_terminate(vports[i]->fc_vport); | 8765 | fc_vport_terminate(vports[i]->fc_vport); |
| 8766 | } | ||
| 8699 | lpfc_destroy_vport_work_array(phba, vports); | 8767 | lpfc_destroy_vport_work_array(phba, vports); |
| 8700 | 8768 | ||
| 8701 | /* Remove FC host and then SCSI host with the physical port */ | 8769 | /* Remove FC host and then SCSI host with the physical port */ |
| @@ -9115,8 +9183,12 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba) | |||
| 9115 | return 50; | 9183 | return 50; |
| 9116 | else if (max_xri <= 1024) | 9184 | else if (max_xri <= 1024) |
| 9117 | return 100; | 9185 | return 100; |
| 9118 | else | 9186 | else if (max_xri <= 1536) |
| 9119 | return 150; | 9187 | return 150; |
| 9188 | else if (max_xri <= 2048) | ||
| 9189 | return 200; | ||
| 9190 | else | ||
| 9191 | return 250; | ||
| 9120 | } else | 9192 | } else |
| 9121 | return 0; | 9193 | return 0; |
| 9122 | } | 9194 | } |
| @@ -9455,8 +9527,11 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev) | |||
| 9455 | /* Release all the vports against this physical port */ | 9527 | /* Release all the vports against this physical port */ |
| 9456 | vports = lpfc_create_vport_work_array(phba); | 9528 | vports = lpfc_create_vport_work_array(phba); |
| 9457 | if (vports != NULL) | 9529 | if (vports != NULL) |
| 9458 | for (i = 1; i <= phba->max_vports && vports[i] != NULL; i++) | 9530 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
| 9531 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | ||
| 9532 | continue; | ||
| 9459 | fc_vport_terminate(vports[i]->fc_vport); | 9533 | fc_vport_terminate(vports[i]->fc_vport); |
| 9534 | } | ||
| 9460 | lpfc_destroy_vport_work_array(phba, vports); | 9535 | lpfc_destroy_vport_work_array(phba, vports); |
| 9461 | 9536 | ||
| 9462 | /* Remove FC host and then SCSI host with the physical port */ | 9537 | /* Remove FC host and then SCSI host with the physical port */ |
