@@ -58,6 +58,33 @@ bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf)
5858}
5959
6060
61+ /**
62+ * is_treat_specially_client - checks if the message belongs
63+ * to the file private data.
64+ *
65+ * @cl: private data of the file object
66+ * @rs: connect response bus message
67+ *
68+ */
69+ static bool is_treat_specially_client (struct mei_cl * cl ,
70+ struct hbm_client_connect_response * rs )
71+ {
72+ if (mei_hbm_cl_addr_equal (cl , rs )) {
73+ if (!rs -> status ) {
74+ cl -> state = MEI_FILE_CONNECTED ;
75+ cl -> status = 0 ;
76+
77+ } else {
78+ cl -> state = MEI_FILE_DISCONNECTED ;
79+ cl -> status = - ENODEV ;
80+ }
81+ cl -> timer_count = 0 ;
82+
83+ return true;
84+ }
85+ return false;
86+ }
87+
6188/**
6289 * mei_hbm_start_req - sends start request message.
6390 *
@@ -217,6 +244,66 @@ int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl)
217244 return mei_write_message (dev , mei_hdr , dev -> wr_msg .data );
218245}
219246
247+ /**
248+ * add_single_flow_creds - adds single buffer credentials.
249+ *
250+ * @file: private data ot the file object.
251+ * @flow: flow control.
252+ */
253+ static void mei_hbm_add_single_flow_creds (struct mei_device * dev ,
254+ struct hbm_flow_control * flow )
255+ {
256+ struct mei_me_client * client ;
257+ int i ;
258+
259+ for (i = 0 ; i < dev -> me_clients_num ; i ++ ) {
260+ client = & dev -> me_clients [i ];
261+ if (client && flow -> me_addr == client -> client_id ) {
262+ if (client -> props .single_recv_buf ) {
263+ client -> mei_flow_ctrl_creds ++ ;
264+ dev_dbg (& dev -> pdev -> dev , "recv flow ctrl msg ME %d (single).\n" ,
265+ flow -> me_addr );
266+ dev_dbg (& dev -> pdev -> dev , "flow control credentials =%d.\n" ,
267+ client -> mei_flow_ctrl_creds );
268+ } else {
269+ BUG (); /* error in flow control */
270+ }
271+ }
272+ }
273+ }
274+
275+ /**
276+ * mei_hbm_cl_flow_control_res - flow control response from me
277+ *
278+ * @dev: the device structure
279+ * @flow_control: flow control response bus message
280+ */
281+ static void mei_hbm_cl_flow_control_res (struct mei_device * dev ,
282+ struct hbm_flow_control * flow_control )
283+ {
284+ struct mei_cl * cl = NULL ;
285+ struct mei_cl * next = NULL ;
286+
287+ if (!flow_control -> host_addr ) {
288+ /* single receive buffer */
289+ mei_hbm_add_single_flow_creds (dev , flow_control );
290+ return ;
291+ }
292+
293+ /* normal connection */
294+ list_for_each_entry_safe (cl , next , & dev -> file_list , link ) {
295+ if (mei_hbm_cl_addr_equal (cl , flow_control )) {
296+ cl -> mei_flow_ctrl_creds ++ ;
297+ dev_dbg (& dev -> pdev -> dev , "flow ctrl msg for host %d ME %d.\n" ,
298+ flow_control -> host_addr , flow_control -> me_addr );
299+ dev_dbg (& dev -> pdev -> dev , "flow control credentials = %d.\n" ,
300+ cl -> mei_flow_ctrl_creds );
301+ break ;
302+ }
303+ }
304+ }
305+
306+
220307/**
221308 * mei_hbm_cl_disconnect_req - sends disconnect message to fw.
222309 *
@@ -236,6 +323,48 @@ int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl)
236323 return mei_write_message (dev , mei_hdr , dev -> wr_msg .data );
237324}
238325
326+ /**
327+ * mei_hbm_cl_disconnect_res - disconnect response from ME
328+ *
329+ * @dev: the device structure
330+ * @rs: disconnect response bus message
331+ */
332+ static void mei_hbm_cl_disconnect_res (struct mei_device * dev ,
333+ struct hbm_client_connect_response * rs )
334+ {
335+ struct mei_cl * cl ;
336+ struct mei_cl_cb * pos = NULL , * next = NULL ;
337+
338+ dev_dbg (& dev -> pdev -> dev ,
339+ "disconnect_response:\n"
340+ "ME Client = %d\n"
341+ "Host Client = %d\n"
342+ "Status = %d\n" ,
343+ rs -> me_addr ,
344+ rs -> host_addr ,
345+ rs -> status );
346+
347+ list_for_each_entry_safe (pos , next , & dev -> ctrl_rd_list .list , list ) {
348+ cl = pos -> cl ;
349+
350+ if (!cl ) {
351+ list_del (& pos -> list );
352+ return ;
353+ }
354+
355+ dev_dbg (& dev -> pdev -> dev , "list_for_each_entry_safe in ctrl_rd_list.\n" );
356+ if (mei_hbm_cl_addr_equal (cl , rs )) {
357+ list_del (& pos -> list );
358+ if (!rs -> status )
359+ cl -> state = MEI_FILE_DISCONNECTED ;
360+
361+ cl -> status = 0 ;
362+ cl -> timer_count = 0 ;
363+ break ;
364+ }
365+ }
366+ }
367+
239368/**
240369 * mei_hbm_cl_connect_req - send connection request to specific me client
241370 *
@@ -255,6 +384,60 @@ int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl)
255384 return mei_write_message (dev , mei_hdr , dev -> wr_msg .data );
256385}
257386
387+ /**
388+ * mei_hbm_cl_connect_res - connect resposne from the ME
389+ *
390+ * @dev: the device structure
391+ * @rs: connect response bus message
392+ */
393+ static void mei_hbm_cl_connect_res (struct mei_device * dev ,
394+ struct hbm_client_connect_response * rs )
395+ {
396+
397+ struct mei_cl * cl ;
398+ struct mei_cl_cb * pos = NULL , * next = NULL ;
399+
400+ dev_dbg (& dev -> pdev -> dev ,
401+ "connect_response:\n"
402+ "ME Client = %d\n"
403+ "Host Client = %d\n"
404+ "Status = %d\n" ,
405+ rs -> me_addr ,
406+ rs -> host_addr ,
407+ rs -> status );
408+
409+ /* if WD or iamthif client treat specially */
410+
411+ if (is_treat_specially_client (& dev -> wd_cl , rs )) {
412+ dev_dbg (& dev -> pdev -> dev , "successfully connected to WD client.\n" );
413+ mei_watchdog_register (dev );
414+
415+ return ;
416+ }
417+
418+ if (is_treat_specially_client (& dev -> iamthif_cl , rs )) {
419+ dev -> iamthif_state = MEI_IAMTHIF_IDLE ;
420+ return ;
421+ }
422+ list_for_each_entry_safe (pos , next , & dev -> ctrl_rd_list .list , list ) {
423+
424+ cl = pos -> cl ;
425+ if (!cl ) {
426+ list_del (& pos -> list );
427+ return ;
428+ }
429+ if (pos -> fop_type == MEI_FOP_IOCTL ) {
430+ if (is_treat_specially_client (cl , rs )) {
431+ list_del (& pos -> list );
432+ cl -> status = 0 ;
433+ cl -> timer_count = 0 ;
434+ break ;
435+ }
436+ }
437+ }
438+ }
439+
440+
258441/**
259442 * mei_client_disconnect_request - disconnect request initiated by me
260443 * host sends disoconnect response
@@ -347,21 +530,21 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
347530
348531 case CLIENT_CONNECT_RES_CMD :
349532 connect_res = (struct hbm_client_connect_response * ) mei_msg ;
350- mei_client_connect_response (dev , connect_res );
533+ mei_hbm_cl_connect_res (dev , connect_res );
351534 dev_dbg (& dev -> pdev -> dev , "client connect response message received.\n" );
352535 wake_up (& dev -> wait_recvd_msg );
353536 break ;
354537
355538 case CLIENT_DISCONNECT_RES_CMD :
356539 disconnect_res = (struct hbm_client_connect_response * ) mei_msg ;
357- mei_client_disconnect_response (dev , disconnect_res );
540+ mei_hbm_cl_disconnect_res (dev , disconnect_res );
358541 dev_dbg (& dev -> pdev -> dev , "client disconnect response message received.\n" );
359542 wake_up (& dev -> wait_recvd_msg );
360543 break ;
361544
362545 case MEI_FLOW_CONTROL_CMD :
363546 flow_control = (struct hbm_flow_control * ) mei_msg ;
364- mei_client_flow_control_response (dev , flow_control );
547+ mei_hbm_cl_flow_control_res (dev , flow_control );
365548 dev_dbg (& dev -> pdev -> dev , "client flow control response message received.\n" );
366549 break ;
367550
0 commit comments