@@ -339,16 +339,17 @@ static bool ishtp_cl_is_other_connecting(struct ishtp_cl *cl)
339
339
}
340
340
341
341
/**
342
- * ishtp_cl_connect () - Send connect request to firmware
342
+ * ishtp_cl_connect_to_fw () - Send connect request to firmware
343
343
* @cl: client device instance
344
344
*
345
- * Send a connect request for a client to firmware. If successful it will
346
- * RX and TX ring buffers
345
+ * Send a connect request to the firmware and wait for firmware response.
346
+ * If there is successful connection response from the firmware, change
347
+ * client state to ISHTP_CL_CONNECTED, and bind client to related
348
+ * firmware client_id.
347
349
*
348
- * Return: 0 if successful connect response from the firmware and able
349
- * to bind and allocate ring buffers or error code on failure
350
+ * Return: 0 for success and error code on failure
350
351
*/
351
- int ishtp_cl_connect (struct ishtp_cl * cl )
352
+ static int ishtp_cl_connect_to_fw (struct ishtp_cl * cl )
352
353
{
353
354
struct ishtp_device * dev ;
354
355
int rets ;
@@ -358,8 +359,6 @@ int ishtp_cl_connect(struct ishtp_cl *cl)
358
359
359
360
dev = cl -> dev ;
360
361
361
- dev -> print_log (dev , "%s() current_state = %d\n" , __func__ , cl -> state );
362
-
363
362
if (ishtp_cl_is_other_connecting (cl )) {
364
363
dev -> print_log (dev , "%s() Busy\n" , __func__ );
365
364
return - EBUSY ;
@@ -405,6 +404,38 @@ int ishtp_cl_connect(struct ishtp_cl *cl)
405
404
return rets ;
406
405
}
407
406
407
+ return rets ;
408
+ }
409
+
410
+ /**
411
+ * ishtp_cl_connect() - Build connection with firmware
412
+ * @cl: client device instance
413
+ *
414
+ * Call ishtp_cl_connect_to_fw() to connect and bind to firmware. If successful,
415
+ * allocate RX and TX ring buffers, and start flow control with firmware to
416
+ * start communication.
417
+ *
418
+ * Return: 0 if there is successful connection to the firmware, allocate
419
+ * ring buffers.
420
+ */
421
+ int ishtp_cl_connect (struct ishtp_cl * cl )
422
+ {
423
+ struct ishtp_device * dev ;
424
+ int rets ;
425
+
426
+ if (!cl || !cl -> dev )
427
+ return - ENODEV ;
428
+
429
+ dev = cl -> dev ;
430
+
431
+ dev -> print_log (dev , "%s() current_state = %d\n" , __func__ , cl -> state );
432
+
433
+ rets = ishtp_cl_connect_to_fw (cl );
434
+ if (rets ) {
435
+ dev -> print_log (dev , "%s() Connect to fw failed\n" , __func__ );
436
+ return rets ;
437
+ }
438
+
408
439
rets = ishtp_cl_alloc_rx_ring (cl );
409
440
if (rets ) {
410
441
dev -> print_log (dev , "%s() Alloc RX ring failed\n" , __func__ );
@@ -422,15 +453,147 @@ int ishtp_cl_connect(struct ishtp_cl *cl)
422
453
return rets ;
423
454
}
424
455
425
- /* Upon successful connection and allocation, emit flow-control */
456
+ /*
457
+ * Upon successful connection and allocation, start flow-control.
458
+ */
426
459
rets = ishtp_cl_read_start (cl );
427
460
428
- dev -> print_log (dev , "%s() successful\n" , __func__ );
429
-
430
461
return rets ;
431
462
}
432
463
EXPORT_SYMBOL (ishtp_cl_connect );
433
464
465
+ /**
466
+ * ishtp_cl_establish_connection() - Establish connection with the firmware
467
+ * @cl: client device instance
468
+ * @uuid: uuid of the client to search
469
+ * @tx_size: TX ring buffer size
470
+ * @rx_size: RX ring buffer size
471
+ * @reset: true if called for reset connection, otherwise for first connection
472
+ *
473
+ * This is a helper function for client driver to build connection with firmware.
474
+ * If it's first time connecting to the firmware, set reset to false, this
475
+ * function will link client to bus, find client id and send connect request to
476
+ * the firmware.
477
+ *
478
+ * If it's called for reset handler where client lost connection after
479
+ * firmware reset, set reset to true, this function will reinit client state and
480
+ * establish connection again. In this case, this function reuses current client
481
+ * structure and ring buffers to avoid allocation failure and memory fragments.
482
+ *
483
+ * Return: 0 for successful connection with the firmware,
484
+ * or error code on failure
485
+ */
486
+ int ishtp_cl_establish_connection (struct ishtp_cl * cl , const guid_t * uuid ,
487
+ int tx_size , int rx_size , bool reset )
488
+ {
489
+ struct ishtp_device * dev ;
490
+ struct ishtp_fw_client * fw_client ;
491
+ int rets ;
492
+
493
+ if (!cl || !cl -> dev )
494
+ return - ENODEV ;
495
+
496
+ dev = cl -> dev ;
497
+
498
+ ishtp_set_connection_state (cl , ISHTP_CL_INITIALIZING );
499
+
500
+ /* reinit ishtp_cl structure if call for reset */
501
+ if (reset ) {
502
+ cl -> host_client_id = 0 ;
503
+ cl -> fw_client_id = 0 ;
504
+ cl -> ishtp_flow_ctrl_creds = 0 ;
505
+ cl -> out_flow_ctrl_creds = 0 ;
506
+
507
+ cl -> last_tx_path = CL_TX_PATH_IPC ;
508
+ cl -> last_dma_acked = 1 ;
509
+ cl -> last_dma_addr = NULL ;
510
+ cl -> last_ipc_acked = 1 ;
511
+
512
+ cl -> sending = 0 ;
513
+ cl -> err_send_msg = 0 ;
514
+ cl -> err_send_fc = 0 ;
515
+
516
+ cl -> send_msg_cnt_ipc = 0 ;
517
+ cl -> send_msg_cnt_dma = 0 ;
518
+ cl -> recv_msg_cnt_ipc = 0 ;
519
+ cl -> recv_msg_cnt_dma = 0 ;
520
+ cl -> recv_msg_num_frags = 0 ;
521
+ cl -> ishtp_flow_ctrl_cnt = 0 ;
522
+ cl -> out_flow_ctrl_cnt = 0 ;
523
+ }
524
+
525
+ /* link to bus */
526
+ rets = ishtp_cl_link (cl );
527
+ if (rets ) {
528
+ dev -> print_log (dev , "%s() ishtp_cl_link failed\n" , __func__ );
529
+ return rets ;
530
+ }
531
+
532
+ /* find firmware client */
533
+ fw_client = ishtp_fw_cl_get_client (dev , uuid );
534
+ if (!fw_client ) {
535
+ dev -> print_log (dev ,
536
+ "%s() ish client uuid not found\n" , __func__ );
537
+ return - ENOENT ;
538
+ }
539
+
540
+ ishtp_set_tx_ring_size (cl , tx_size );
541
+ ishtp_set_rx_ring_size (cl , rx_size );
542
+
543
+ ishtp_cl_set_fw_client_id (cl , ishtp_get_fw_client_id (fw_client ));
544
+
545
+ ishtp_set_connection_state (cl , ISHTP_CL_CONNECTING );
546
+
547
+ /*
548
+ * For reset case, not allocate tx/rx ring buffer which are already
549
+ * done in ishtp_cl_connect() during first connection.
550
+ */
551
+ if (reset ) {
552
+ rets = ishtp_cl_connect_to_fw (cl );
553
+ if (!rets )
554
+ rets = ishtp_cl_read_start (cl );
555
+ else
556
+ dev -> print_log (dev ,
557
+ "%s() connect to fw failed\n" , __func__ );
558
+ } else {
559
+ rets = ishtp_cl_connect (cl );
560
+ }
561
+
562
+ return rets ;
563
+ }
564
+ EXPORT_SYMBOL (ishtp_cl_establish_connection );
565
+
566
+ /**
567
+ * ishtp_cl_destroy_connection() - Disconnect with the firmware
568
+ * @cl: client device instance
569
+ * @reset: true if called for firmware reset, false for normal disconnection
570
+ *
571
+ * This is a helper function for client driver to disconnect with firmware,
572
+ * unlink to bus and flush message queue.
573
+ */
574
+ void ishtp_cl_destroy_connection (struct ishtp_cl * cl , bool reset )
575
+ {
576
+ if (!cl )
577
+ return ;
578
+
579
+ if (reset ) {
580
+ /*
581
+ * For reset case, connection is already lost during fw reset.
582
+ * Just set state to DISCONNECTED is enough.
583
+ */
584
+ ishtp_set_connection_state (cl , ISHTP_CL_DISCONNECTED );
585
+ } else {
586
+ if (cl -> state != ISHTP_CL_DISCONNECTED ) {
587
+ ishtp_set_connection_state (cl , ISHTP_CL_DISCONNECTING );
588
+ ishtp_cl_disconnect (cl );
589
+ }
590
+ }
591
+
592
+ ishtp_cl_unlink (cl );
593
+ ishtp_cl_flush_queues (cl );
594
+ }
595
+ EXPORT_SYMBOL (ishtp_cl_destroy_connection );
596
+
434
597
/**
435
598
* ishtp_cl_read_start() - Prepare to read client message
436
599
* @cl: client device instance
0 commit comments