@@ -602,6 +602,22 @@ static int __ipmi_bmc_register(struct ipmi_smi *intf,
602602static int __scan_channels (struct ipmi_smi * intf ,
603603 struct ipmi_device_id * id , bool rescan );
604604
605+ static void ipmi_lock_xmit_msgs (struct ipmi_smi * intf , int run_to_completion ,
606+ unsigned long * flags )
607+ {
608+ if (run_to_completion )
609+ return ;
610+ spin_lock_irqsave (& intf -> xmit_msgs_lock , * flags );
611+ }
612+
613+ static void ipmi_unlock_xmit_msgs (struct ipmi_smi * intf , int run_to_completion ,
614+ unsigned long * flags )
615+ {
616+ if (run_to_completion )
617+ return ;
618+ spin_unlock_irqrestore (& intf -> xmit_msgs_lock , * flags );
619+ }
620+
605621static void free_ipmi_user (struct kref * ref )
606622{
607623 struct ipmi_user * user = container_of (ref , struct ipmi_user , refcount );
@@ -1869,21 +1885,32 @@ static struct ipmi_smi_msg *smi_add_send_msg(struct ipmi_smi *intf,
18691885 return smi_msg ;
18701886}
18711887
1872- static void smi_send (struct ipmi_smi * intf ,
1888+ static int smi_send (struct ipmi_smi * intf ,
18731889 const struct ipmi_smi_handlers * handlers ,
18741890 struct ipmi_smi_msg * smi_msg , int priority )
18751891{
18761892 int run_to_completion = READ_ONCE (intf -> run_to_completion );
18771893 unsigned long flags = 0 ;
1894+ int rv = 0 ;
18781895
1879- if (!run_to_completion )
1880- spin_lock_irqsave (& intf -> xmit_msgs_lock , flags );
1896+ ipmi_lock_xmit_msgs (intf , run_to_completion , & flags );
18811897 smi_msg = smi_add_send_msg (intf , smi_msg , priority );
1882- if (!run_to_completion )
1883- spin_unlock_irqrestore (& intf -> xmit_msgs_lock , flags );
1898+ ipmi_unlock_xmit_msgs (intf , run_to_completion , & flags );
18841899
1885- if (smi_msg )
1886- handlers -> sender (intf -> send_info , smi_msg );
1900+ if (smi_msg ) {
1901+ rv = handlers -> sender (intf -> send_info , smi_msg );
1902+ if (rv ) {
1903+ ipmi_lock_xmit_msgs (intf , run_to_completion , & flags );
1904+ intf -> curr_msg = NULL ;
1905+ ipmi_unlock_xmit_msgs (intf , run_to_completion , & flags );
1906+ /*
1907+ * Something may have been added to the transmit
1908+ * queue, so schedule a check for that.
1909+ */
1910+ queue_work (system_wq , & intf -> smi_work );
1911+ }
1912+ }
1913+ return rv ;
18871914}
18881915
18891916static bool is_maintenance_mode_cmd (struct kernel_ipmi_msg * msg )
@@ -2296,6 +2323,7 @@ static int i_ipmi_request(struct ipmi_user *user,
22962323 struct ipmi_recv_msg * recv_msg ;
22972324 int run_to_completion = READ_ONCE (intf -> run_to_completion );
22982325 int rv = 0 ;
2326+ bool in_seq_table = false;
22992327
23002328 if (supplied_recv ) {
23012329 recv_msg = supplied_recv ;
@@ -2349,33 +2377,50 @@ static int i_ipmi_request(struct ipmi_user *user,
23492377 rv = i_ipmi_req_ipmb (intf , addr , msgid , msg , smi_msg , recv_msg ,
23502378 source_address , source_lun ,
23512379 retries , retry_time_ms );
2380+ in_seq_table = true;
23522381 } else if (is_ipmb_direct_addr (addr )) {
23532382 rv = i_ipmi_req_ipmb_direct (intf , addr , msgid , msg , smi_msg ,
23542383 recv_msg , source_lun );
23552384 } else if (is_lan_addr (addr )) {
23562385 rv = i_ipmi_req_lan (intf , addr , msgid , msg , smi_msg , recv_msg ,
23572386 source_lun , retries , retry_time_ms );
2387+ in_seq_table = true;
23582388 } else {
2359- /* Unknown address type. */
2389+ /* Unknown address type. */
23602390 ipmi_inc_stat (intf , sent_invalid_commands );
23612391 rv = - EINVAL ;
23622392 }
23632393
2364- if (rv ) {
2365- out_err :
2366- if (!supplied_smi )
2367- ipmi_free_smi_msg (smi_msg );
2368- if (!supplied_recv )
2369- ipmi_free_recv_msg (recv_msg );
2370- } else {
2394+ if (!rv ) {
23712395 dev_dbg (intf -> si_dev , "Send: %*ph\n" ,
23722396 smi_msg -> data_size , smi_msg -> data );
23732397
2374- smi_send (intf , intf -> handlers , smi_msg , priority );
2398+ rv = smi_send (intf , intf -> handlers , smi_msg , priority );
2399+ if (rv != IPMI_CC_NO_ERROR )
2400+ /* smi_send() returns an IPMI err, return a Linux one. */
2401+ rv = - EIO ;
2402+ if (rv && in_seq_table ) {
2403+ /*
2404+ * If it's in the sequence table, it will be
2405+ * retried later, so ignore errors.
2406+ */
2407+ rv = 0 ;
2408+ /* But we need to fix the timeout. */
2409+ intf_start_seq_timer (intf , smi_msg -> msgid );
2410+ ipmi_free_smi_msg (smi_msg );
2411+ smi_msg = NULL ;
2412+ }
23752413 }
2414+ out_err :
23762415 if (!run_to_completion )
23772416 mutex_unlock (& intf -> users_mutex );
23782417
2418+ if (rv ) {
2419+ if (!supplied_smi )
2420+ ipmi_free_smi_msg (smi_msg );
2421+ if (!supplied_recv )
2422+ ipmi_free_recv_msg (recv_msg );
2423+ }
23792424 return rv ;
23802425}
23812426
@@ -3949,12 +3994,12 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
39493994 dev_dbg (intf -> si_dev , "Invalid command: %*ph\n" ,
39503995 msg -> data_size , msg -> data );
39513996
3952- smi_send (intf , intf -> handlers , msg , 0 );
3953- /*
3954- * We used the message, so return the value that
3955- * causes it to not be freed or queued.
3956- */
3957- rv = -1 ;
3997+ if ( smi_send (intf , intf -> handlers , msg , 0 ) == IPMI_CC_NO_ERROR )
3998+ /*
3999+ * We used the message, so return the value that
4000+ * causes it to not be freed or queued.
4001+ */
4002+ rv = -1 ;
39584003 } else if (!IS_ERR (recv_msg )) {
39594004 /* Extract the source address from the data. */
39604005 ipmb_addr = (struct ipmi_ipmb_addr * ) & recv_msg -> addr ;
@@ -4028,12 +4073,12 @@ static int handle_ipmb_direct_rcv_cmd(struct ipmi_smi *intf,
40284073 msg -> data [4 ] = IPMI_INVALID_CMD_COMPLETION_CODE ;
40294074 msg -> data_size = 5 ;
40304075
4031- smi_send (intf , intf -> handlers , msg , 0 );
4032- /*
4033- * We used the message, so return the value that
4034- * causes it to not be freed or queued.
4035- */
4036- rv = -1 ;
4076+ if ( smi_send (intf , intf -> handlers , msg , 0 ) == IPMI_CC_NO_ERROR )
4077+ /*
4078+ * We used the message, so return the value that
4079+ * causes it to not be freed or queued.
4080+ */
4081+ rv = -1 ;
40374082 } else if (!IS_ERR (recv_msg )) {
40384083 /* Extract the source address from the data. */
40394084 daddr = (struct ipmi_ipmb_direct_addr * )& recv_msg -> addr ;
@@ -4173,7 +4218,7 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
41734218 struct ipmi_smi_msg * msg )
41744219{
41754220 struct cmd_rcvr * rcvr ;
4176- int rv = 0 ;
4221+ int rv = 0 ; /* Free by default */
41774222 unsigned char netfn ;
41784223 unsigned char cmd ;
41794224 unsigned char chan ;
@@ -4226,12 +4271,12 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
42264271 dev_dbg (intf -> si_dev , "Invalid command: %*ph\n" ,
42274272 msg -> data_size , msg -> data );
42284273
4229- smi_send (intf , intf -> handlers , msg , 0 );
4230- /*
4231- * We used the message, so return the value that
4232- * causes it to not be freed or queued.
4233- */
4234- rv = -1 ;
4274+ if ( smi_send (intf , intf -> handlers , msg , 0 ) == IPMI_CC_NO_ERROR )
4275+ /*
4276+ * We used the message, so return the value that
4277+ * causes it to not be freed or queued.
4278+ */
4279+ rv = -1 ;
42354280 } else if (!IS_ERR (recv_msg )) {
42364281 /* Extract the source address from the data. */
42374282 lan_addr = (struct ipmi_lan_addr * ) & recv_msg -> addr ;
@@ -4824,8 +4869,7 @@ static void smi_work(struct work_struct *t)
48244869 * message delivery.
48254870 */
48264871restart :
4827- if (!run_to_completion )
4828- spin_lock_irqsave (& intf -> xmit_msgs_lock , flags );
4872+ ipmi_lock_xmit_msgs (intf , run_to_completion , & flags );
48294873 if (intf -> curr_msg == NULL && !intf -> in_shutdown ) {
48304874 struct list_head * entry = NULL ;
48314875
@@ -4841,17 +4885,19 @@ static void smi_work(struct work_struct *t)
48414885 intf -> curr_msg = newmsg ;
48424886 }
48434887 }
4844- if (!run_to_completion )
4845- spin_unlock_irqrestore (& intf -> xmit_msgs_lock , flags );
4888+ ipmi_unlock_xmit_msgs (intf , run_to_completion , & flags );
48464889
48474890 if (newmsg ) {
48484891 cc = intf -> handlers -> sender (intf -> send_info , newmsg );
48494892 if (cc ) {
48504893 if (newmsg -> recv_msg )
48514894 deliver_err_response (intf ,
48524895 newmsg -> recv_msg , cc );
4853- else
4854- ipmi_free_smi_msg (newmsg );
4896+ ipmi_lock_xmit_msgs (intf , run_to_completion , & flags );
4897+ intf -> curr_msg = NULL ;
4898+ ipmi_unlock_xmit_msgs (intf , run_to_completion , & flags );
4899+ ipmi_free_smi_msg (newmsg );
4900+ newmsg = NULL ;
48554901 goto restart ;
48564902 }
48574903 }
@@ -4919,16 +4965,14 @@ void ipmi_smi_msg_received(struct ipmi_smi *intf,
49194965 spin_unlock_irqrestore (& intf -> waiting_rcv_msgs_lock ,
49204966 flags );
49214967
4922- if (!run_to_completion )
4923- spin_lock_irqsave (& intf -> xmit_msgs_lock , flags );
4968+ ipmi_lock_xmit_msgs (intf , run_to_completion , & flags );
49244969 /*
49254970 * We can get an asynchronous event or receive message in addition
49264971 * to commands we send.
49274972 */
49284973 if (msg == intf -> curr_msg )
49294974 intf -> curr_msg = NULL ;
4930- if (!run_to_completion )
4931- spin_unlock_irqrestore (& intf -> xmit_msgs_lock , flags );
4975+ ipmi_unlock_xmit_msgs (intf , run_to_completion , & flags );
49324976
49334977 if (run_to_completion )
49344978 smi_work (& intf -> smi_work );
@@ -5041,7 +5085,12 @@ static void check_msg_timeout(struct ipmi_smi *intf, struct seq_table *ent,
50415085 ipmi_inc_stat (intf ,
50425086 retransmitted_ipmb_commands );
50435087
5044- smi_send (intf , intf -> handlers , smi_msg , 0 );
5088+ /* If this fails we'll retry later or timeout. */
5089+ if (smi_send (intf , intf -> handlers , smi_msg , 0 ) != IPMI_CC_NO_ERROR ) {
5090+ /* But fix the timeout. */
5091+ intf_start_seq_timer (intf , smi_msg -> msgid );
5092+ ipmi_free_smi_msg (smi_msg );
5093+ }
50455094 } else
50465095 ipmi_free_smi_msg (smi_msg );
50475096
0 commit comments