@@ -1887,19 +1887,32 @@ static struct ipmi_smi_msg *smi_add_send_msg(struct ipmi_smi *intf,
18871887 return smi_msg ;
18881888}
18891889
1890- static void smi_send (struct ipmi_smi * intf ,
1890+ static int smi_send (struct ipmi_smi * intf ,
18911891 const struct ipmi_smi_handlers * handlers ,
18921892 struct ipmi_smi_msg * smi_msg , int priority )
18931893{
18941894 int run_to_completion = READ_ONCE (intf -> run_to_completion );
18951895 unsigned long flags = 0 ;
1896+ int rv = 0 ;
18961897
18971898 ipmi_lock_xmit_msgs (intf , run_to_completion , & flags );
18981899 smi_msg = smi_add_send_msg (intf , smi_msg , priority );
18991900 ipmi_unlock_xmit_msgs (intf , run_to_completion , & flags );
19001901
1901- if (smi_msg )
1902- handlers -> sender (intf -> send_info , smi_msg );
1902+ if (smi_msg ) {
1903+ rv = handlers -> sender (intf -> send_info , smi_msg );
1904+ if (rv ) {
1905+ ipmi_lock_xmit_msgs (intf , run_to_completion , & flags );
1906+ intf -> curr_msg = NULL ;
1907+ ipmi_unlock_xmit_msgs (intf , run_to_completion , & flags );
1908+ /*
1909+ * Something may have been added to the transmit
1910+ * queue, so schedule a check for that.
1911+ */
1912+ queue_work (system_wq , & intf -> smi_work );
1913+ }
1914+ }
1915+ return rv ;
19031916}
19041917
19051918static bool is_maintenance_mode_cmd (struct kernel_ipmi_msg * msg )
@@ -2312,6 +2325,7 @@ static int i_ipmi_request(struct ipmi_user *user,
23122325 struct ipmi_recv_msg * recv_msg ;
23132326 int run_to_completion = READ_ONCE (intf -> run_to_completion );
23142327 int rv = 0 ;
2328+ bool in_seq_table = false;
23152329
23162330 if (supplied_recv ) {
23172331 recv_msg = supplied_recv ;
@@ -2365,33 +2379,50 @@ static int i_ipmi_request(struct ipmi_user *user,
23652379 rv = i_ipmi_req_ipmb (intf , addr , msgid , msg , smi_msg , recv_msg ,
23662380 source_address , source_lun ,
23672381 retries , retry_time_ms );
2382+ in_seq_table = true;
23682383 } else if (is_ipmb_direct_addr (addr )) {
23692384 rv = i_ipmi_req_ipmb_direct (intf , addr , msgid , msg , smi_msg ,
23702385 recv_msg , source_lun );
23712386 } else if (is_lan_addr (addr )) {
23722387 rv = i_ipmi_req_lan (intf , addr , msgid , msg , smi_msg , recv_msg ,
23732388 source_lun , retries , retry_time_ms );
2389+ in_seq_table = true;
23742390 } else {
2375- /* Unknown address type. */
2391+ /* Unknown address type. */
23762392 ipmi_inc_stat (intf , sent_invalid_commands );
23772393 rv = - EINVAL ;
23782394 }
23792395
2380- if (rv ) {
2381- out_err :
2382- if (!supplied_smi )
2383- ipmi_free_smi_msg (smi_msg );
2384- if (!supplied_recv )
2385- ipmi_free_recv_msg (recv_msg );
2386- } else {
2396+ if (!rv ) {
23872397 dev_dbg (intf -> si_dev , "Send: %*ph\n" ,
23882398 smi_msg -> data_size , smi_msg -> data );
23892399
2390- smi_send (intf , intf -> handlers , smi_msg , priority );
2400+ rv = smi_send (intf , intf -> handlers , smi_msg , priority );
2401+ if (rv != IPMI_CC_NO_ERROR )
2402+ /* smi_send() returns an IPMI err, return a Linux one. */
2403+ rv = - EIO ;
2404+ if (rv && in_seq_table ) {
2405+ /*
2406+ * If it's in the sequence table, it will be
2407+ * retried later, so ignore errors.
2408+ */
2409+ rv = 0 ;
2410+ /* But we need to fix the timeout. */
2411+ intf_start_seq_timer (intf , smi_msg -> msgid );
2412+ ipmi_free_smi_msg (smi_msg );
2413+ smi_msg = NULL ;
2414+ }
23912415 }
2416+ out_err :
23922417 if (!run_to_completion )
23932418 mutex_unlock (& intf -> users_mutex );
23942419
2420+ if (rv ) {
2421+ if (!supplied_smi )
2422+ ipmi_free_smi_msg (smi_msg );
2423+ if (!supplied_recv )
2424+ ipmi_free_recv_msg (recv_msg );
2425+ }
23952426 return rv ;
23962427}
23972428
@@ -3965,12 +3996,12 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
39653996 dev_dbg (intf -> si_dev , "Invalid command: %*ph\n" ,
39663997 msg -> data_size , msg -> data );
39673998
3968- smi_send (intf , intf -> handlers , msg , 0 );
3969- /*
3970- * We used the message, so return the value that
3971- * causes it to not be freed or queued.
3972- */
3973- rv = -1 ;
3999+ if ( smi_send (intf , intf -> handlers , msg , 0 ) == IPMI_CC_NO_ERROR )
4000+ /*
4001+ * We used the message, so return the value that
4002+ * causes it to not be freed or queued.
4003+ */
4004+ rv = -1 ;
39744005 } else if (!IS_ERR (recv_msg )) {
39754006 /* Extract the source address from the data. */
39764007 ipmb_addr = (struct ipmi_ipmb_addr * ) & recv_msg -> addr ;
@@ -4044,12 +4075,12 @@ static int handle_ipmb_direct_rcv_cmd(struct ipmi_smi *intf,
40444075 msg -> data [4 ] = IPMI_INVALID_CMD_COMPLETION_CODE ;
40454076 msg -> data_size = 5 ;
40464077
4047- smi_send (intf , intf -> handlers , msg , 0 );
4048- /*
4049- * We used the message, so return the value that
4050- * causes it to not be freed or queued.
4051- */
4052- rv = -1 ;
4078+ if ( smi_send (intf , intf -> handlers , msg , 0 ) == IPMI_CC_NO_ERROR )
4079+ /*
4080+ * We used the message, so return the value that
4081+ * causes it to not be freed or queued.
4082+ */
4083+ rv = -1 ;
40534084 } else if (!IS_ERR (recv_msg )) {
40544085 /* Extract the source address from the data. */
40554086 daddr = (struct ipmi_ipmb_direct_addr * )& recv_msg -> addr ;
@@ -4189,7 +4220,7 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
41894220 struct ipmi_smi_msg * msg )
41904221{
41914222 struct cmd_rcvr * rcvr ;
4192- int rv = 0 ;
4223+ int rv = 0 ; /* Free by default */
41934224 unsigned char netfn ;
41944225 unsigned char cmd ;
41954226 unsigned char chan ;
@@ -4242,12 +4273,12 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
42424273 dev_dbg (intf -> si_dev , "Invalid command: %*ph\n" ,
42434274 msg -> data_size , msg -> data );
42444275
4245- smi_send (intf , intf -> handlers , msg , 0 );
4246- /*
4247- * We used the message, so return the value that
4248- * causes it to not be freed or queued.
4249- */
4250- rv = -1 ;
4276+ if ( smi_send (intf , intf -> handlers , msg , 0 ) == IPMI_CC_NO_ERROR )
4277+ /*
4278+ * We used the message, so return the value that
4279+ * causes it to not be freed or queued.
4280+ */
4281+ rv = -1 ;
42514282 } else if (!IS_ERR (recv_msg )) {
42524283 /* Extract the source address from the data. */
42534284 lan_addr = (struct ipmi_lan_addr * ) & recv_msg -> addr ;
@@ -5056,7 +5087,12 @@ static void check_msg_timeout(struct ipmi_smi *intf, struct seq_table *ent,
50565087 ipmi_inc_stat (intf ,
50575088 retransmitted_ipmb_commands );
50585089
5059- smi_send (intf , intf -> handlers , smi_msg , 0 );
5090+ /* If this fails we'll retry later or timeout. */
5091+ if (smi_send (intf , intf -> handlers , smi_msg , 0 ) != IPMI_CC_NO_ERROR ) {
5092+ /* But fix the timeout. */
5093+ intf_start_seq_timer (intf , smi_msg -> msgid );
5094+ ipmi_free_smi_msg (smi_msg );
5095+ }
50605096 } else
50615097 ipmi_free_smi_msg (smi_msg );
50625098
0 commit comments