@@ -160,8 +160,8 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *);
160160static void ibmvfc_tgt_implicit_logout_and_del (struct ibmvfc_target * );
161161static void ibmvfc_tgt_move_login (struct ibmvfc_target * );
162162
163- static void ibmvfc_release_sub_crqs (struct ibmvfc_host * );
164- static void ibmvfc_init_sub_crqs (struct ibmvfc_host * );
163+ static void ibmvfc_dereg_sub_crqs (struct ibmvfc_host * );
164+ static void ibmvfc_reg_sub_crqs (struct ibmvfc_host * );
165165
166166static const char * unknown_error = "unknown error" ;
167167
@@ -917,7 +917,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost)
917917 struct vio_dev * vdev = to_vio_dev (vhost -> dev );
918918 unsigned long flags ;
919919
920- ibmvfc_release_sub_crqs (vhost );
920+ ibmvfc_dereg_sub_crqs (vhost );
921921
922922 /* Re-enable the CRQ */
923923 do {
@@ -936,7 +936,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost)
936936 spin_unlock (vhost -> crq .q_lock );
937937 spin_unlock_irqrestore (vhost -> host -> host_lock , flags );
938938
939- ibmvfc_init_sub_crqs (vhost );
939+ ibmvfc_reg_sub_crqs (vhost );
940940
941941 return rc ;
942942}
@@ -955,7 +955,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
955955 struct vio_dev * vdev = to_vio_dev (vhost -> dev );
956956 struct ibmvfc_queue * crq = & vhost -> crq ;
957957
958- ibmvfc_release_sub_crqs (vhost );
958+ ibmvfc_dereg_sub_crqs (vhost );
959959
960960 /* Close the CRQ */
961961 do {
@@ -988,7 +988,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
988988 spin_unlock (vhost -> crq .q_lock );
989989 spin_unlock_irqrestore (vhost -> host -> host_lock , flags );
990990
991- ibmvfc_init_sub_crqs (vhost );
991+ ibmvfc_reg_sub_crqs (vhost );
992992
993993 return rc ;
994994}
@@ -5682,6 +5682,8 @@ static int ibmvfc_alloc_queue(struct ibmvfc_host *vhost,
56825682 queue -> cur = 0 ;
56835683 queue -> fmt = fmt ;
56845684 queue -> size = PAGE_SIZE / fmt_size ;
5685+
5686+ queue -> vhost = vhost ;
56855687 return 0 ;
56865688}
56875689
@@ -5757,9 +5759,6 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,
57575759
57585760 ENTER ;
57595761
5760- if (ibmvfc_alloc_queue (vhost , scrq , IBMVFC_SUB_CRQ_FMT ))
5761- return - ENOMEM ;
5762-
57635762 rc = h_reg_sub_crq (vdev -> unit_address , scrq -> msg_token , PAGE_SIZE ,
57645763 & scrq -> cookie , & scrq -> hw_irq );
57655764
@@ -5790,7 +5789,6 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,
57905789 }
57915790
57925791 scrq -> hwq_id = index ;
5793- scrq -> vhost = vhost ;
57945792
57955793 LEAVE ;
57965794 return 0 ;
@@ -5800,7 +5798,6 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,
58005798 rc = plpar_hcall_norets (H_FREE_SUB_CRQ , vdev -> unit_address , scrq -> cookie );
58015799 } while (rtas_busy_delay (rc ));
58025800reg_failed :
5803- ibmvfc_free_queue (vhost , scrq );
58045801 LEAVE ;
58055802 return rc ;
58065803}
@@ -5826,12 +5823,50 @@ static void ibmvfc_deregister_scsi_channel(struct ibmvfc_host *vhost, int index)
58265823 if (rc )
58275824 dev_err (dev , "Failed to free sub-crq[%d]: rc=%ld\n" , index , rc );
58285825
5829- ibmvfc_free_queue (vhost , scrq );
5826+ /* Clean out the queue */
5827+ memset (scrq -> msgs .crq , 0 , PAGE_SIZE );
5828+ scrq -> cur = 0 ;
5829+
5830+ LEAVE ;
5831+ }
5832+
5833+ static void ibmvfc_reg_sub_crqs (struct ibmvfc_host * vhost )
5834+ {
5835+ int i , j ;
5836+
5837+ ENTER ;
5838+ if (!vhost -> mq_enabled || !vhost -> scsi_scrqs .scrqs )
5839+ return ;
5840+
5841+ for (i = 0 ; i < nr_scsi_hw_queues ; i ++ ) {
5842+ if (ibmvfc_register_scsi_channel (vhost , i )) {
5843+ for (j = i ; j > 0 ; j -- )
5844+ ibmvfc_deregister_scsi_channel (vhost , j - 1 );
5845+ vhost -> do_enquiry = 0 ;
5846+ return ;
5847+ }
5848+ }
5849+
5850+ LEAVE ;
5851+ }
5852+
5853+ static void ibmvfc_dereg_sub_crqs (struct ibmvfc_host * vhost )
5854+ {
5855+ int i ;
5856+
5857+ ENTER ;
5858+ if (!vhost -> mq_enabled || !vhost -> scsi_scrqs .scrqs )
5859+ return ;
5860+
5861+ for (i = 0 ; i < nr_scsi_hw_queues ; i ++ )
5862+ ibmvfc_deregister_scsi_channel (vhost , i );
5863+
58305864 LEAVE ;
58315865}
58325866
58335867static void ibmvfc_init_sub_crqs (struct ibmvfc_host * vhost )
58345868{
5869+ struct ibmvfc_queue * scrq ;
58355870 int i , j ;
58365871
58375872 ENTER ;
@@ -5847,30 +5882,41 @@ static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost)
58475882 }
58485883
58495884 for (i = 0 ; i < nr_scsi_hw_queues ; i ++ ) {
5850- if (ibmvfc_register_scsi_channel (vhost , i )) {
5851- for (j = i ; j > 0 ; j -- )
5852- ibmvfc_deregister_scsi_channel (vhost , j - 1 );
5885+ scrq = & vhost -> scsi_scrqs .scrqs [i ];
5886+ if (ibmvfc_alloc_queue (vhost , scrq , IBMVFC_SUB_CRQ_FMT )) {
5887+ for (j = i ; j > 0 ; j -- ) {
5888+ scrq = & vhost -> scsi_scrqs .scrqs [j - 1 ];
5889+ ibmvfc_free_queue (vhost , scrq );
5890+ }
58535891 kfree (vhost -> scsi_scrqs .scrqs );
58545892 vhost -> scsi_scrqs .scrqs = NULL ;
58555893 vhost -> scsi_scrqs .active_queues = 0 ;
58565894 vhost -> do_enquiry = 0 ;
5857- break ;
5895+ vhost -> mq_enabled = 0 ;
5896+ return ;
58585897 }
58595898 }
58605899
5900+ ibmvfc_reg_sub_crqs (vhost );
5901+
58615902 LEAVE ;
58625903}
58635904
58645905static void ibmvfc_release_sub_crqs (struct ibmvfc_host * vhost )
58655906{
5907+ struct ibmvfc_queue * scrq ;
58665908 int i ;
58675909
58685910 ENTER ;
58695911 if (!vhost -> scsi_scrqs .scrqs )
58705912 return ;
58715913
5872- for (i = 0 ; i < nr_scsi_hw_queues ; i ++ )
5873- ibmvfc_deregister_scsi_channel (vhost , i );
5914+ ibmvfc_dereg_sub_crqs (vhost );
5915+
5916+ for (i = 0 ; i < nr_scsi_hw_queues ; i ++ ) {
5917+ scrq = & vhost -> scsi_scrqs .scrqs [i ];
5918+ ibmvfc_free_queue (vhost , scrq );
5919+ }
58745920
58755921 kfree (vhost -> scsi_scrqs .scrqs );
58765922 vhost -> scsi_scrqs .scrqs = NULL ;
0 commit comments