aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ibmvscsi/ibmvscsi.c
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2009-06-08 17:19:04 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-08 19:05:18 -0400
commit3507e13fcba6b97501891a410ec8ef9f1f188620 (patch)
tree61fe3efb517492be9af6ef3ec3b31d06f62921d0 /drivers/scsi/ibmvscsi/ibmvscsi.c
parente1a5ce5b88d06344caec0c71b4ee33e7296358dd (diff)
[SCSI] ibmvscsi: Send adapter info before login
The ibmvscsi driver currently sends the SRP Login before sending the Adapter Info MAD, which can result in commands getting sent to the virtual adapter before we are ready for them. This results in a slight window where the target devices may not behave as expected. Change the order and close the window. Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvscsi.c')
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c170
1 files changed, 85 insertions, 85 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 6038c0491f8a..2ed46b8efedf 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -785,6 +785,83 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
785/* ------------------------------------------------------------ 785/* ------------------------------------------------------------
786 * Routines for driver initialization 786 * Routines for driver initialization
787 */ 787 */
788
789/**
790 * login_rsp: - Handle response to SRP login request
791 * @evt_struct: srp_event_struct with the response
792 *
793 * Used as a "done" callback by when sending srp_login. Gets called
794 * by ibmvscsi_handle_crq()
795*/
796static void login_rsp(struct srp_event_struct *evt_struct)
797{
798 struct ibmvscsi_host_data *hostdata = evt_struct->hostdata;
799 switch (evt_struct->xfer_iu->srp.login_rsp.opcode) {
800 case SRP_LOGIN_RSP: /* it worked! */
801 break;
802 case SRP_LOGIN_REJ: /* refused! */
803 dev_info(hostdata->dev, "SRP_LOGIN_REJ reason %u\n",
804 evt_struct->xfer_iu->srp.login_rej.reason);
805 /* Login failed. */
806 atomic_set(&hostdata->request_limit, -1);
807 return;
808 default:
809 dev_err(hostdata->dev, "Invalid login response typecode 0x%02x!\n",
810 evt_struct->xfer_iu->srp.login_rsp.opcode);
811 /* Login failed. */
812 atomic_set(&hostdata->request_limit, -1);
813 return;
814 }
815
816 dev_info(hostdata->dev, "SRP_LOGIN succeeded\n");
817
818 /* Now we know what the real request-limit is.
819 * This value is set rather than added to request_limit because
820 * request_limit could have been set to -1 by this client.
821 */
822 atomic_set(&hostdata->request_limit,
823 evt_struct->xfer_iu->srp.login_rsp.req_lim_delta);
824
825 /* If we had any pending I/Os, kick them */
826 scsi_unblock_requests(hostdata->host);
827}
828
829/**
830 * send_srp_login: - Sends the srp login
831 * @hostdata: ibmvscsi_host_data of host
832 *
833 * Returns zero if successful.
834*/
835static int send_srp_login(struct ibmvscsi_host_data *hostdata)
836{
837 int rc;
838 unsigned long flags;
839 struct srp_login_req *login;
840 struct srp_event_struct *evt_struct = get_event_struct(&hostdata->pool);
841
842 BUG_ON(!evt_struct);
843 init_event_struct(evt_struct, login_rsp,
844 VIOSRP_SRP_FORMAT, login_timeout);
845
846 login = &evt_struct->iu.srp.login_req;
847 memset(login, 0, sizeof(*login));
848 login->opcode = SRP_LOGIN_REQ;
849 login->req_it_iu_len = sizeof(union srp_iu);
850 login->req_buf_fmt = SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT;
851
852 spin_lock_irqsave(hostdata->host->host_lock, flags);
853 /* Start out with a request limit of 0, since this is negotiated in
854 * the login request we are just sending and login requests always
855 * get sent by the driver regardless of request_limit.
856 */
857 atomic_set(&hostdata->request_limit, 0);
858
859 rc = ibmvscsi_send_srp_event(evt_struct, hostdata, login_timeout * 2);
860 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
861 dev_info(hostdata->dev, "sent SRP login\n");
862 return rc;
863};
864
788/** 865/**
789 * adapter_info_rsp: - Handle response to MAD adapter info request 866 * adapter_info_rsp: - Handle response to MAD adapter info request
790 * @evt_struct: srp_event_struct with the response 867 * @evt_struct: srp_event_struct with the response
@@ -825,6 +902,8 @@ static void adapter_info_rsp(struct srp_event_struct *evt_struct)
825 hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS; 902 hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS;
826 } 903 }
827 } 904 }
905
906 send_srp_login(hostdata);
828} 907}
829 908
830/** 909/**
@@ -844,11 +923,7 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata)
844 dma_addr_t addr; 923 dma_addr_t addr;
845 924
846 evt_struct = get_event_struct(&hostdata->pool); 925 evt_struct = get_event_struct(&hostdata->pool);
847 if (!evt_struct) { 926 BUG_ON(!evt_struct);
848 dev_err(hostdata->dev,
849 "couldn't allocate an event for ADAPTER_INFO_REQ!\n");
850 return;
851 }
852 927
853 init_event_struct(evt_struct, 928 init_event_struct(evt_struct,
854 adapter_info_rsp, 929 adapter_info_rsp,
@@ -886,90 +961,15 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata)
886}; 961};
887 962
888/** 963/**
889 * login_rsp: - Handle response to SRP login request 964 * init_adapter: Start virtual adapter initialization sequence
890 * @evt_struct: srp_event_struct with the response
891 * 965 *
892 * Used as a "done" callback by when sending srp_login. Gets called 966 */
893 * by ibmvscsi_handle_crq() 967static void init_adapter(struct ibmvscsi_host_data *hostdata)
894*/
895static void login_rsp(struct srp_event_struct *evt_struct)
896{ 968{
897 struct ibmvscsi_host_data *hostdata = evt_struct->hostdata;
898 switch (evt_struct->xfer_iu->srp.login_rsp.opcode) {
899 case SRP_LOGIN_RSP: /* it worked! */
900 break;
901 case SRP_LOGIN_REJ: /* refused! */
902 dev_info(hostdata->dev, "SRP_LOGIN_REJ reason %u\n",
903 evt_struct->xfer_iu->srp.login_rej.reason);
904 /* Login failed. */
905 atomic_set(&hostdata->request_limit, -1);
906 return;
907 default:
908 dev_err(hostdata->dev, "Invalid login response typecode 0x%02x!\n",
909 evt_struct->xfer_iu->srp.login_rsp.opcode);
910 /* Login failed. */
911 atomic_set(&hostdata->request_limit, -1);
912 return;
913 }
914
915 dev_info(hostdata->dev, "SRP_LOGIN succeeded\n");
916
917 /* Now we know what the real request-limit is.
918 * This value is set rather than added to request_limit because
919 * request_limit could have been set to -1 by this client.
920 */
921 atomic_set(&hostdata->request_limit,
922 evt_struct->xfer_iu->srp.login_rsp.req_lim_delta);
923
924 /* If we had any pending I/Os, kick them */
925 scsi_unblock_requests(hostdata->host);
926
927 send_mad_adapter_info(hostdata); 969 send_mad_adapter_info(hostdata);
928 return;
929} 970}
930 971
931/** 972/**
932 * send_srp_login: - Sends the srp login
933 * @hostdata: ibmvscsi_host_data of host
934 *
935 * Returns zero if successful.
936*/
937static int send_srp_login(struct ibmvscsi_host_data *hostdata)
938{
939 int rc;
940 unsigned long flags;
941 struct srp_login_req *login;
942 struct srp_event_struct *evt_struct = get_event_struct(&hostdata->pool);
943 if (!evt_struct) {
944 dev_err(hostdata->dev, "couldn't allocate an event for login req!\n");
945 return FAILED;
946 }
947
948 init_event_struct(evt_struct,
949 login_rsp,
950 VIOSRP_SRP_FORMAT,
951 login_timeout);
952
953 login = &evt_struct->iu.srp.login_req;
954 memset(login, 0x00, sizeof(struct srp_login_req));
955 login->opcode = SRP_LOGIN_REQ;
956 login->req_it_iu_len = sizeof(union srp_iu);
957 login->req_buf_fmt = SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT;
958
959 spin_lock_irqsave(hostdata->host->host_lock, flags);
960 /* Start out with a request limit of 0, since this is negotiated in
961 * the login request we are just sending and login requests always
962 * get sent by the driver regardless of request_limit.
963 */
964 atomic_set(&hostdata->request_limit, 0);
965
966 rc = ibmvscsi_send_srp_event(evt_struct, hostdata, login_timeout * 2);
967 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
968 dev_info(hostdata->dev, "sent SRP login\n");
969 return rc;
970};
971
972/**
973 * sync_completion: Signal that a synchronous command has completed 973 * sync_completion: Signal that a synchronous command has completed
974 * Note that after returning from this call, the evt_struct is freed. 974 * Note that after returning from this call, the evt_struct is freed.
975 * the caller waiting on this completion shouldn't touch the evt_struct 975 * the caller waiting on this completion shouldn't touch the evt_struct
@@ -1282,7 +1282,7 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
1282 if ((rc = ibmvscsi_ops->send_crq(hostdata, 1282 if ((rc = ibmvscsi_ops->send_crq(hostdata,
1283 0xC002000000000000LL, 0)) == 0) { 1283 0xC002000000000000LL, 0)) == 0) {
1284 /* Now login */ 1284 /* Now login */
1285 send_srp_login(hostdata); 1285 init_adapter(hostdata);
1286 } else { 1286 } else {
1287 dev_err(hostdata->dev, "Unable to send init rsp. rc=%ld\n", rc); 1287 dev_err(hostdata->dev, "Unable to send init rsp. rc=%ld\n", rc);
1288 } 1288 }
@@ -1292,7 +1292,7 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
1292 dev_info(hostdata->dev, "partner initialization complete\n"); 1292 dev_info(hostdata->dev, "partner initialization complete\n");
1293 1293
1294 /* Now login */ 1294 /* Now login */
1295 send_srp_login(hostdata); 1295 init_adapter(hostdata);
1296 break; 1296 break;
1297 default: 1297 default:
1298 dev_err(hostdata->dev, "unknown crq message type: %d\n", crq->format); 1298 dev_err(hostdata->dev, "unknown crq message type: %d\n", crq->format);