diff options
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvscsi.c')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 170 |
1 files changed, 85 insertions, 85 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 6038c0491f8..2ed46b8efed 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 | */ | ||
796 | static 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 | */ | ||
835 | static 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() | 967 | static void init_adapter(struct ibmvscsi_host_data *hostdata) |
894 | */ | ||
895 | static 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 | */ | ||
937 | static 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); |