@@ -134,9 +134,9 @@ static struct switchtec_ntb *ntb_sndev(struct ntb_dev *ntb)
134134 return container_of (ntb , struct switchtec_ntb , ntb );
135135}
136136
137- static int switchtec_ntb_part_op (struct switchtec_ntb * sndev ,
138- struct ntb_ctrl_regs __iomem * ctl ,
139- u32 op , int wait_status )
137+ static int switchtec_ntb_part_op_no_retry (struct switchtec_ntb * sndev ,
138+ struct ntb_ctrl_regs __iomem * ctl ,
139+ u32 op , int wait_status )
140140{
141141 static const char * const op_text [] = {
142142 [NTB_CTRL_PART_OP_LOCK ] = "lock" ,
@@ -147,6 +147,24 @@ static int switchtec_ntb_part_op(struct switchtec_ntb *sndev,
147147 int i ;
148148 u32 ps ;
149149 int status ;
150+ int part_id , locked_part_id ;
151+ int xlink_peer = ctl == sndev -> mmio_xlink_peer_ctrl ? 1 : 0 ;
152+
153+ ps = ioread32 (& ctl -> partition_status );
154+
155+ locked_part_id = (ps & 0xFF0000 ) >> 16 ;
156+ part_id = (ps & 0xFF000000 ) >> 24 ;
157+
158+ ps &= 0xFFFF ;
159+
160+ if (ps != NTB_CTRL_PART_STATUS_NORMAL &&
161+ ps != NTB_CTRL_PART_STATUS_LOCKED )
162+ return - EAGAIN ;
163+
164+ if (ps == NTB_CTRL_PART_STATUS_LOCKED )
165+ if ((xlink_peer && (locked_part_id != part_id )) ||
166+ (!xlink_peer && (locked_part_id != sndev -> self_partition )))
167+ return - EAGAIN ;
150168
151169 switch (op ) {
152170 case NTB_CTRL_PART_OP_LOCK :
@@ -170,12 +188,24 @@ static int switchtec_ntb_part_op(struct switchtec_ntb *sndev,
170188 return - EINTR ;
171189 }
172190
173- ps = ioread32 (& ctl -> partition_status ) & 0xFFFF ;
191+ ps = ioread32 (& ctl -> partition_status );
192+
193+ locked_part_id = (ps & 0xFF0000 ) >> 16 ;
194+ part_id = (ps & 0xFF000000 ) >> 24 ;
195+
196+ ps &= 0xFFFF ;
174197
175198 if (ps != status )
176199 break ;
177200 }
178201
202+ if (ps == NTB_CTRL_PART_STATUS_LOCKED ) {
203+ if ((xlink_peer && (locked_part_id != part_id )) ||
204+ (!xlink_peer &&
205+ (locked_part_id != sndev -> self_partition )))
206+ return - EAGAIN ;
207+ }
208+
179209 if (ps == wait_status )
180210 return 0 ;
181211
@@ -191,6 +221,28 @@ static int switchtec_ntb_part_op(struct switchtec_ntb *sndev,
191221 return - EIO ;
192222}
193223
224+ static int switchtec_ntb_part_op (struct switchtec_ntb * sndev ,
225+ struct ntb_ctrl_regs __iomem * ctl ,
226+ u32 op , int wait_status )
227+ {
228+ int rc ;
229+ int i = 0 ;
230+
231+ while (i ++ < 10 ) {
232+ rc = switchtec_ntb_part_op_no_retry (sndev , ctl , op ,
233+ wait_status );
234+ if (rc == - EAGAIN ) {
235+ if (msleep_interruptible (30 ) != 0 )
236+ return - EINTR ;
237+ continue ;
238+ }
239+
240+ break ;
241+ }
242+
243+ return rc ;
244+ }
245+
194246static int switchtec_ntb_send_msg (struct switchtec_ntb * sndev , int idx ,
195247 u32 val )
196248{
@@ -536,14 +588,21 @@ enum switchtec_msg {
536588
537589static int switchtec_ntb_reinit_peer (struct switchtec_ntb * sndev );
538590
591+ static int crosslink_setup_req_ids (struct switchtec_ntb * sndev ,
592+ struct ntb_ctrl_regs __iomem * mmio_ctrl );
593+
539594static void switchtec_ntb_link_status_update (struct switchtec_ntb * sndev )
540595{
541596 int link_sta ;
542597 int old = sndev -> link_is_up ;
598+ u64 peer ;
543599
544600 link_sta = sndev -> self_shared -> link_sta ;
545601 if (link_sta ) {
546- u64 peer = ioread64 (& sndev -> peer_shared -> magic );
602+ if (!sndev -> link_is_up && crosslink_is_enabled (sndev ))
603+ crosslink_setup_req_ids (sndev , sndev -> mmio_xlink_peer_ctrl );
604+
605+ peer = ioread64 (& sndev -> peer_shared -> magic );
547606
548607 if ((peer & 0xFFFFFFFF ) == SWITCHTEC_NTB_MAGIC )
549608 link_sta = peer >> 32 ;
@@ -618,9 +677,6 @@ static u64 switchtec_ntb_link_is_up(struct ntb_dev *ntb,
618677 return sndev -> link_is_up ;
619678}
620679
621- static int crosslink_setup_req_ids (struct switchtec_ntb * sndev ,
622- struct ntb_ctrl_regs __iomem * mmio_ctrl );
623-
624680static int switchtec_ntb_link_enable (struct ntb_dev * ntb ,
625681 enum ntb_speed max_speed ,
626682 enum ntb_width max_width )
@@ -632,11 +688,6 @@ static int switchtec_ntb_link_enable(struct ntb_dev *ntb,
632688 sndev -> self_shared -> link_sta = 1 ;
633689 switchtec_ntb_send_msg (sndev , LINK_MESSAGE , MSG_LINK_UP );
634690
635- if (crosslink_is_enabled (sndev ))
636- crosslink_setup_req_ids (sndev , sndev -> mmio_xlink_peer_ctrl );
637-
638- switchtec_ntb_link_status_update (sndev );
639-
640691 return 0 ;
641692}
642693
@@ -1364,10 +1415,6 @@ static int switchtec_ntb_init_crosslink(struct switchtec_ntb *sndev)
13641415 if (rc )
13651416 return rc ;
13661417
1367- crosslink_init_dbmsgs (sndev );
1368-
1369- crosslink_setup_req_ids (sndev , sndev -> mmio_xlink_peer_ctrl );
1370-
13711418 return 0 ;
13721419}
13731420
@@ -1853,6 +1900,8 @@ static void switchtec_ntb_remove(struct device *dev,
18531900 if (!sndev )
18541901 return ;
18551902
1903+ flush_scheduled_work ();
1904+
18561905 stdev -> link_notifier = NULL ;
18571906 stdev -> sndev = NULL ;
18581907 sysfs_remove_group (& sndev -> ntb .dev .kobj , & switchtec_ntb_device_group );
0 commit comments