1313static int
1414mpi3mr_issue_reset (struct mpi3mr_ioc * mrioc , u16 reset_type , u32 reset_reason );
1515static int mpi3mr_setup_admin_qpair (struct mpi3mr_ioc * mrioc );
16+ static void mpi3mr_process_factsdata (struct mpi3mr_ioc * mrioc ,
17+ struct mpi3_ioc_facts_data * facts_data );
1618
1719#if defined(writeq ) && defined(CONFIG_64BIT )
1820static inline void mpi3mr_writeq (__u64 b , volatile void __iomem * addr )
@@ -376,7 +378,7 @@ static void mpi3mr_process_admin_reply_desc(struct mpi3mr_ioc *mrioc,
376378 if (def_reply ) {
377379 cmdptr -> state |= MPI3MR_CMD_REPLY_VALID ;
378380 memcpy ((u8 * )cmdptr -> reply , (u8 * )def_reply ,
379- mrioc -> facts . reply_sz );
381+ mrioc -> reply_sz );
380382 }
381383 if (cmdptr -> is_waiting ) {
382384 complete (& cmdptr -> done );
@@ -996,6 +998,66 @@ static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc,
996998 return retval ;
997999}
9981000
1001+ /**
1002+ * mpi3mr_revalidate_factsdata - validate IOCFacts parameters
1003+ * during reset/resume
1004+ * @mrioc: Adapter instance reference
1005+ *
1006+ * Return zero if the new IOCFacts parameters value is compatible with
1007+ * older values else return -EPERM
1008+ */
1009+ static int
1010+ mpi3mr_revalidate_factsdata (struct mpi3mr_ioc * mrioc )
1011+ {
1012+ u16 dev_handle_bitmap_sz ;
1013+ void * removepend_bitmap ;
1014+
1015+ if (mrioc -> facts .reply_sz > mrioc -> reply_sz ) {
1016+ ioc_err (mrioc ,
1017+ "cannot increase reply size from %d to %d\n" ,
1018+ mrioc -> reply_sz , mrioc -> facts .reply_sz );
1019+ return - EPERM ;
1020+ }
1021+
1022+ if (mrioc -> facts .max_op_reply_q < mrioc -> num_op_reply_q ) {
1023+ ioc_err (mrioc ,
1024+ "cannot reduce number of operational reply queues from %d to %d\n" ,
1025+ mrioc -> num_op_reply_q ,
1026+ mrioc -> facts .max_op_reply_q );
1027+ return - EPERM ;
1028+ }
1029+
1030+ if (mrioc -> facts .max_op_req_q < mrioc -> num_op_req_q ) {
1031+ ioc_err (mrioc ,
1032+ "cannot reduce number of operational request queues from %d to %d\n" ,
1033+ mrioc -> num_op_req_q , mrioc -> facts .max_op_req_q );
1034+ return - EPERM ;
1035+ }
1036+
1037+ dev_handle_bitmap_sz = mrioc -> facts .max_devhandle / 8 ;
1038+ if (mrioc -> facts .max_devhandle % 8 )
1039+ dev_handle_bitmap_sz ++ ;
1040+ if (dev_handle_bitmap_sz > mrioc -> dev_handle_bitmap_sz ) {
1041+ removepend_bitmap = krealloc (mrioc -> removepend_bitmap ,
1042+ dev_handle_bitmap_sz , GFP_KERNEL );
1043+ if (!removepend_bitmap ) {
1044+ ioc_err (mrioc ,
1045+ "failed to increase removepend_bitmap sz from: %d to %d\n" ,
1046+ mrioc -> dev_handle_bitmap_sz , dev_handle_bitmap_sz );
1047+ return - EPERM ;
1048+ }
1049+ memset (removepend_bitmap + mrioc -> dev_handle_bitmap_sz , 0 ,
1050+ dev_handle_bitmap_sz - mrioc -> dev_handle_bitmap_sz );
1051+ mrioc -> removepend_bitmap = removepend_bitmap ;
1052+ ioc_info (mrioc ,
1053+ "increased dev_handle_bitmap_sz from %d to %d\n" ,
1054+ mrioc -> dev_handle_bitmap_sz , dev_handle_bitmap_sz );
1055+ mrioc -> dev_handle_bitmap_sz = dev_handle_bitmap_sz ;
1056+ }
1057+
1058+ return 0 ;
1059+ }
1060+
9991061/**
10001062 * mpi3mr_bring_ioc_ready - Bring controller to ready state
10011063 * @mrioc: Adapter instance reference
@@ -1854,8 +1916,13 @@ static int mpi3mr_create_op_queues(struct mpi3mr_ioc *mrioc)
18541916 mrioc -> intr_info_count - mrioc -> op_reply_q_offset ;
18551917 if (!mrioc -> num_queues )
18561918 mrioc -> num_queues = min_t (int , num_queues , msix_count_op_q );
1857- num_queues = mrioc -> num_queues ;
1858- ioc_info (mrioc , "Trying to create %d Operational Q pairs\n" ,
1919+ /*
1920+ * During reset set the num_queues to the number of queues
1921+ * that was set before the reset.
1922+ */
1923+ num_queues = mrioc -> num_op_reply_q ?
1924+ mrioc -> num_op_reply_q : mrioc -> num_queues ;
1925+ ioc_info (mrioc , "trying to create %d operational queue pairs\n" ,
18591926 num_queues );
18601927
18611928 if (!mrioc -> req_qinfo ) {
@@ -2447,6 +2514,7 @@ static int mpi3mr_issue_iocfacts(struct mpi3mr_ioc *mrioc,
24472514 goto out_unlock ;
24482515 }
24492516 memcpy (facts_data , (u8 * )data , data_len );
2517+ mpi3mr_process_factsdata (mrioc , facts_data );
24502518out_unlock :
24512519 mrioc -> init_cmds .state = MPI3MR_CMD_NOTUSED ;
24522520 mutex_unlock (& mrioc -> init_cmds .mutex );
@@ -2593,12 +2661,6 @@ static void mpi3mr_process_factsdata(struct mpi3mr_ioc *mrioc,
25932661 ioc_info (mrioc , "DMA mask %d InitialPE status 0x%x\n" ,
25942662 mrioc -> facts .dma_mask , (facts_flags &
25952663 MPI3_IOCFACTS_FLAGS_INITIAL_PORT_ENABLE_MASK ));
2596-
2597- mrioc -> max_host_ios = mrioc -> facts .max_reqs - MPI3MR_INTERNAL_CMDS_RESVD ;
2598-
2599- if (reset_devices )
2600- mrioc -> max_host_ios = min_t (int , mrioc -> max_host_ios ,
2601- MPI3MR_HOST_IOS_KDUMP );
26022664}
26032665
26042666/**
@@ -2618,18 +2680,18 @@ static int mpi3mr_alloc_reply_sense_bufs(struct mpi3mr_ioc *mrioc)
26182680 if (mrioc -> init_cmds .reply )
26192681 return retval ;
26202682
2621- mrioc -> init_cmds .reply = kzalloc (mrioc -> facts . reply_sz , GFP_KERNEL );
2683+ mrioc -> init_cmds .reply = kzalloc (mrioc -> reply_sz , GFP_KERNEL );
26222684 if (!mrioc -> init_cmds .reply )
26232685 goto out_failed ;
26242686
26252687 for (i = 0 ; i < MPI3MR_NUM_DEVRMCMD ; i ++ ) {
2626- mrioc -> dev_rmhs_cmds [i ].reply = kzalloc (mrioc -> facts . reply_sz ,
2688+ mrioc -> dev_rmhs_cmds [i ].reply = kzalloc (mrioc -> reply_sz ,
26272689 GFP_KERNEL );
26282690 if (!mrioc -> dev_rmhs_cmds [i ].reply )
26292691 goto out_failed ;
26302692 }
26312693
2632- mrioc -> host_tm_cmds .reply = kzalloc (mrioc -> facts . reply_sz , GFP_KERNEL );
2694+ mrioc -> host_tm_cmds .reply = kzalloc (mrioc -> reply_sz , GFP_KERNEL );
26332695 if (!mrioc -> host_tm_cmds .reply )
26342696 goto out_failed ;
26352697
@@ -2655,7 +2717,7 @@ static int mpi3mr_alloc_reply_sense_bufs(struct mpi3mr_ioc *mrioc)
26552717 mrioc -> sense_buf_q_sz = mrioc -> num_sense_bufs + 1 ;
26562718
26572719 /* reply buffer pool, 16 byte align */
2658- sz = mrioc -> num_reply_bufs * mrioc -> facts . reply_sz ;
2720+ sz = mrioc -> num_reply_bufs * mrioc -> reply_sz ;
26592721 mrioc -> reply_buf_pool = dma_pool_create ("reply_buf pool" ,
26602722 & mrioc -> pdev -> dev , sz , 16 , 0 );
26612723 if (!mrioc -> reply_buf_pool ) {
@@ -2731,10 +2793,10 @@ static void mpimr_initialize_reply_sbuf_queues(struct mpi3mr_ioc *mrioc)
27312793 u32 sz , i ;
27322794 dma_addr_t phy_addr ;
27332795
2734- sz = mrioc -> num_reply_bufs * mrioc -> facts . reply_sz ;
2796+ sz = mrioc -> num_reply_bufs * mrioc -> reply_sz ;
27352797 ioc_info (mrioc ,
27362798 "reply buf pool(0x%p): depth(%d), frame_size(%d), pool_size(%d kB), reply_dma(0x%llx)\n" ,
2737- mrioc -> reply_buf , mrioc -> num_reply_bufs , mrioc -> facts . reply_sz ,
2799+ mrioc -> reply_buf , mrioc -> num_reply_bufs , mrioc -> reply_sz ,
27382800 (sz / 1024 ), (unsigned long long )mrioc -> reply_buf_dma );
27392801 sz = mrioc -> reply_free_qsz * 8 ;
27402802 ioc_info (mrioc ,
@@ -2754,7 +2816,7 @@ static void mpimr_initialize_reply_sbuf_queues(struct mpi3mr_ioc *mrioc)
27542816
27552817 /* initialize Reply buffer Queue */
27562818 for (i = 0 , phy_addr = mrioc -> reply_buf_dma ;
2757- i < mrioc -> num_reply_bufs ; i ++ , phy_addr += mrioc -> facts . reply_sz )
2819+ i < mrioc -> num_reply_bufs ; i ++ , phy_addr += mrioc -> reply_sz )
27582820 mrioc -> reply_free_q [i ] = cpu_to_le64 (phy_addr );
27592821 mrioc -> reply_free_q [i ] = cpu_to_le64 (0 );
27602822
@@ -3459,7 +3521,13 @@ int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc)
34593521 goto out_failed ;
34603522 }
34613523
3462- mpi3mr_process_factsdata (mrioc , & facts_data );
3524+ mrioc -> max_host_ios = mrioc -> facts .max_reqs - MPI3MR_INTERNAL_CMDS_RESVD ;
3525+
3526+ if (reset_devices )
3527+ mrioc -> max_host_ios = min_t (int , mrioc -> max_host_ios ,
3528+ MPI3MR_HOST_IOS_KDUMP );
3529+
3530+ mrioc -> reply_sz = mrioc -> facts .reply_sz ;
34633531
34643532 retval = mpi3mr_check_reset_dma_mask (mrioc );
34653533 if (retval ) {
@@ -3582,7 +3650,12 @@ int mpi3mr_reinit_ioc(struct mpi3mr_ioc *mrioc, u8 is_resume)
35823650 goto out_failed ;
35833651 }
35843652
3585- mpi3mr_process_factsdata (mrioc , & facts_data );
3653+ dprint_reset (mrioc , "validating ioc_facts\n" );
3654+ retval = mpi3mr_revalidate_factsdata (mrioc );
3655+ if (retval ) {
3656+ ioc_err (mrioc , "failed to revalidate ioc_facts data\n" );
3657+ goto out_failed_noretry ;
3658+ }
35863659
35873660 mpi3mr_print_ioc_info (mrioc );
35883661
0 commit comments