@@ -806,14 +806,30 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code)
806806 spin_unlock_irqrestore (hostdata -> host -> host_lock , flags );
807807}
808808
809+ /**
810+ * ibmvscsi_set_request_limit - Set the adapter request_limit in response to
811+ * an adapter failure, reset, or SRP Login. Done under host lock to prevent
812+ * race with SCSI command submission.
813+ * @hostdata: adapter to adjust
814+ * @limit: new request limit
815+ */
816+ static void ibmvscsi_set_request_limit (struct ibmvscsi_host_data * hostdata , int limit )
817+ {
818+ unsigned long flags ;
819+
820+ spin_lock_irqsave (hostdata -> host -> host_lock , flags );
821+ atomic_set (& hostdata -> request_limit , limit );
822+ spin_unlock_irqrestore (hostdata -> host -> host_lock , flags );
823+ }
824+
809825/**
810826 * ibmvscsi_reset_host - Reset the connection to the server
811827 * @hostdata: struct ibmvscsi_host_data to reset
812828*/
813829static void ibmvscsi_reset_host (struct ibmvscsi_host_data * hostdata )
814830{
815831 scsi_block_requests (hostdata -> host );
816- atomic_set ( & hostdata -> request_limit , 0 );
832+ ibmvscsi_set_request_limit ( hostdata , 0 );
817833
818834 purge_requests (hostdata , DID_ERROR );
819835 hostdata -> action = IBMVSCSI_HOST_ACTION_RESET ;
@@ -1146,13 +1162,13 @@ static void login_rsp(struct srp_event_struct *evt_struct)
11461162 dev_info (hostdata -> dev , "SRP_LOGIN_REJ reason %u\n" ,
11471163 evt_struct -> xfer_iu -> srp .login_rej .reason );
11481164 /* Login failed. */
1149- atomic_set ( & hostdata -> request_limit , -1 );
1165+ ibmvscsi_set_request_limit ( hostdata , -1 );
11501166 return ;
11511167 default :
11521168 dev_err (hostdata -> dev , "Invalid login response typecode 0x%02x!\n" ,
11531169 evt_struct -> xfer_iu -> srp .login_rsp .opcode );
11541170 /* Login failed. */
1155- atomic_set ( & hostdata -> request_limit , -1 );
1171+ ibmvscsi_set_request_limit ( hostdata , -1 );
11561172 return ;
11571173 }
11581174
@@ -1163,7 +1179,7 @@ static void login_rsp(struct srp_event_struct *evt_struct)
11631179 * This value is set rather than added to request_limit because
11641180 * request_limit could have been set to -1 by this client.
11651181 */
1166- atomic_set ( & hostdata -> request_limit ,
1182+ ibmvscsi_set_request_limit ( hostdata ,
11671183 be32_to_cpu (evt_struct -> xfer_iu -> srp .login_rsp .req_lim_delta ));
11681184
11691185 /* If we had any pending I/Os, kick them */
@@ -1195,13 +1211,13 @@ static int send_srp_login(struct ibmvscsi_host_data *hostdata)
11951211 login -> req_buf_fmt = cpu_to_be16 (SRP_BUF_FORMAT_DIRECT |
11961212 SRP_BUF_FORMAT_INDIRECT );
11971213
1198- spin_lock_irqsave (hostdata -> host -> host_lock , flags );
11991214 /* Start out with a request limit of 0, since this is negotiated in
12001215 * the login request we are just sending and login requests always
12011216 * get sent by the driver regardless of request_limit.
12021217 */
1203- atomic_set ( & hostdata -> request_limit , 0 );
1218+ ibmvscsi_set_request_limit ( hostdata , 0 );
12041219
1220+ spin_lock_irqsave (hostdata -> host -> host_lock , flags );
12051221 rc = ibmvscsi_send_srp_event (evt_struct , hostdata , login_timeout * 2 );
12061222 spin_unlock_irqrestore (hostdata -> host -> host_lock , flags );
12071223 dev_info (hostdata -> dev , "sent SRP login\n" );
@@ -1781,7 +1797,7 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq,
17811797 return ;
17821798 case VIOSRP_CRQ_XPORT_EVENT : /* Hypervisor telling us the connection is closed */
17831799 scsi_block_requests (hostdata -> host );
1784- atomic_set ( & hostdata -> request_limit , 0 );
1800+ ibmvscsi_set_request_limit ( hostdata , 0 );
17851801 if (crq -> format == 0x06 ) {
17861802 /* We need to re-setup the interpartition connection */
17871803 dev_info (hostdata -> dev , "Re-enabling adapter!\n" );
@@ -2137,12 +2153,12 @@ static void ibmvscsi_do_work(struct ibmvscsi_host_data *hostdata)
21372153 }
21382154
21392155 hostdata -> action = IBMVSCSI_HOST_ACTION_NONE ;
2156+ spin_unlock_irqrestore (hostdata -> host -> host_lock , flags );
21402157
21412158 if (rc ) {
2142- atomic_set ( & hostdata -> request_limit , -1 );
2159+ ibmvscsi_set_request_limit ( hostdata , -1 );
21432160 dev_err (hostdata -> dev , "error after %s\n" , action );
21442161 }
2145- spin_unlock_irqrestore (hostdata -> host -> host_lock , flags );
21462162
21472163 scsi_unblock_requests (hostdata -> host );
21482164}
@@ -2226,7 +2242,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
22262242 init_waitqueue_head (& hostdata -> work_wait_q );
22272243 hostdata -> host = host ;
22282244 hostdata -> dev = dev ;
2229- atomic_set ( & hostdata -> request_limit , -1 );
2245+ ibmvscsi_set_request_limit ( hostdata , -1 );
22302246 hostdata -> host -> max_sectors = IBMVSCSI_MAX_SECTORS_DEFAULT ;
22312247
22322248 if (map_persist_bufs (hostdata )) {
0 commit comments