diff options
-rw-r--r-- | drivers/scsi/Kconfig | 2 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvstgt.c | 58 | ||||
-rw-r--r-- | drivers/scsi/libsrp.c | 5 | ||||
-rw-r--r-- | include/scsi/libsrp.h | 2 |
4 files changed, 57 insertions, 10 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 8d4057ea27b1..4562273dfad3 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -848,7 +848,7 @@ config SCSI_IBMVSCSI | |||
848 | 848 | ||
849 | config SCSI_IBMVSCSIS | 849 | config SCSI_IBMVSCSIS |
850 | tristate "IBM Virtual SCSI Server support" | 850 | tristate "IBM Virtual SCSI Server support" |
851 | depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP | 851 | depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP && SCSI_SRP_ATTRS |
852 | help | 852 | help |
853 | This is the SRP target driver for IBM pSeries virtual environments. | 853 | This is the SRP target driver for IBM pSeries virtual environments. |
854 | 854 | ||
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 8ba7dd09d01d..4ee6e417d0bf 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <scsi/scsi.h> | 26 | #include <scsi/scsi.h> |
27 | #include <scsi/scsi_host.h> | 27 | #include <scsi/scsi_host.h> |
28 | #include <scsi/scsi_transport_srp.h> | ||
28 | #include <scsi/scsi_tgt.h> | 29 | #include <scsi/scsi_tgt.h> |
29 | #include <scsi/libsrp.h> | 30 | #include <scsi/libsrp.h> |
30 | #include <asm/hvcall.h> | 31 | #include <asm/hvcall.h> |
@@ -68,9 +69,12 @@ struct vio_port { | |||
68 | unsigned long liobn; | 69 | unsigned long liobn; |
69 | unsigned long riobn; | 70 | unsigned long riobn; |
70 | struct srp_target *target; | 71 | struct srp_target *target; |
72 | |||
73 | struct srp_rport *rport; | ||
71 | }; | 74 | }; |
72 | 75 | ||
73 | static struct workqueue_struct *vtgtd; | 76 | static struct workqueue_struct *vtgtd; |
77 | static struct scsi_transport_template *ibmvstgt_transport_template; | ||
74 | 78 | ||
75 | /* | 79 | /* |
76 | * These are fixed for the system and come from the Open Firmware device tree. | 80 | * These are fixed for the system and come from the Open Firmware device tree. |
@@ -188,6 +192,7 @@ static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc, | |||
188 | static void handle_cmd_queue(struct srp_target *target) | 192 | static void handle_cmd_queue(struct srp_target *target) |
189 | { | 193 | { |
190 | struct Scsi_Host *shost = target->shost; | 194 | struct Scsi_Host *shost = target->shost; |
195 | struct srp_rport *rport = target_to_port(target)->rport; | ||
191 | struct iu_entry *iue; | 196 | struct iu_entry *iue; |
192 | struct srp_cmd *cmd; | 197 | struct srp_cmd *cmd; |
193 | unsigned long flags; | 198 | unsigned long flags; |
@@ -200,7 +205,8 @@ retry: | |||
200 | if (!test_and_set_bit(V_FLYING, &iue->flags)) { | 205 | if (!test_and_set_bit(V_FLYING, &iue->flags)) { |
201 | spin_unlock_irqrestore(&target->lock, flags); | 206 | spin_unlock_irqrestore(&target->lock, flags); |
202 | cmd = iue->sbuf->buf; | 207 | cmd = iue->sbuf->buf; |
203 | err = srp_cmd_queue(shost, cmd, iue, 0); | 208 | err = srp_cmd_queue(shost, cmd, iue, |
209 | (unsigned long)rport, 0); | ||
204 | if (err) { | 210 | if (err) { |
205 | eprintk("cannot queue cmd %p %d\n", cmd, err); | 211 | eprintk("cannot queue cmd %p %d\n", cmd, err); |
206 | srp_iu_put(iue); | 212 | srp_iu_put(iue); |
@@ -359,6 +365,16 @@ static void process_login(struct iu_entry *iue) | |||
359 | union viosrp_iu *iu = vio_iu(iue); | 365 | union viosrp_iu *iu = vio_iu(iue); |
360 | struct srp_login_rsp *rsp = &iu->srp.login_rsp; | 366 | struct srp_login_rsp *rsp = &iu->srp.login_rsp; |
361 | uint64_t tag = iu->srp.rsp.tag; | 367 | uint64_t tag = iu->srp.rsp.tag; |
368 | struct Scsi_Host *shost = iue->target->shost; | ||
369 | struct srp_target *target = host_to_srp_target(shost); | ||
370 | struct vio_port *vport = target_to_port(target); | ||
371 | struct srp_rport_identifiers ids; | ||
372 | |||
373 | memset(&ids, 0, sizeof(ids)); | ||
374 | sprintf(ids.port_id, "%x", vport->dma_dev->unit_address); | ||
375 | ids.roles = SRP_RPORT_ROLE_INITIATOR; | ||
376 | if (!vport->rport) | ||
377 | vport->rport = srp_rport_add(shost, &ids); | ||
362 | 378 | ||
363 | /* TODO handle case that requested size is wrong and | 379 | /* TODO handle case that requested size is wrong and |
364 | * buffer format is wrong | 380 | * buffer format is wrong |
@@ -412,7 +428,9 @@ static int process_tsk_mgmt(struct iu_entry *iue) | |||
412 | fn = 0; | 428 | fn = 0; |
413 | } | 429 | } |
414 | if (fn) | 430 | if (fn) |
415 | scsi_tgt_tsk_mgmt_request(iue->target->shost, fn, | 431 | scsi_tgt_tsk_mgmt_request(iue->target->shost, |
432 | (unsigned long)iue->target->shost, | ||
433 | fn, | ||
416 | iu->srp.tsk_mgmt.task_tag, | 434 | iu->srp.tsk_mgmt.task_tag, |
417 | (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, | 435 | (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, |
418 | iue); | 436 | iue); |
@@ -721,7 +739,8 @@ static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc) | |||
721 | return 0; | 739 | return 0; |
722 | } | 740 | } |
723 | 741 | ||
724 | static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) | 742 | static int ibmvstgt_tsk_mgmt_response(struct Scsi_Host *shost, |
743 | u64 itn_id, u64 mid, int result) | ||
725 | { | 744 | { |
726 | struct iu_entry *iue = (struct iu_entry *) ((void *) mid); | 745 | struct iu_entry *iue = (struct iu_entry *) ((void *) mid); |
727 | union viosrp_iu *iu = vio_iu(iue); | 746 | union viosrp_iu *iu = vio_iu(iue); |
@@ -747,6 +766,20 @@ static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) | |||
747 | return 0; | 766 | return 0; |
748 | } | 767 | } |
749 | 768 | ||
769 | static int ibmvstgt_it_nexus_response(struct Scsi_Host *shost, u64 itn_id, | ||
770 | int result) | ||
771 | { | ||
772 | struct srp_target *target = host_to_srp_target(shost); | ||
773 | struct vio_port *vport = target_to_port(target); | ||
774 | |||
775 | if (result) { | ||
776 | eprintk("%p %d\n", shost, result); | ||
777 | srp_rport_del(vport->rport); | ||
778 | vport->rport = NULL; | ||
779 | } | ||
780 | return 0; | ||
781 | } | ||
782 | |||
750 | static ssize_t system_id_show(struct class_device *cdev, char *buf) | 783 | static ssize_t system_id_show(struct class_device *cdev, char *buf) |
751 | { | 784 | { |
752 | return snprintf(buf, PAGE_SIZE, "%s\n", system_id); | 785 | return snprintf(buf, PAGE_SIZE, "%s\n", system_id); |
@@ -804,6 +837,7 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
804 | shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); | 837 | shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); |
805 | if (!shost) | 838 | if (!shost) |
806 | goto free_vport; | 839 | goto free_vport; |
840 | shost->transportt = ibmvstgt_transport_template; | ||
807 | err = scsi_tgt_alloc_queue(shost); | 841 | err = scsi_tgt_alloc_queue(shost); |
808 | if (err) | 842 | if (err) |
809 | goto put_host; | 843 | goto put_host; |
@@ -837,8 +871,8 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
837 | err = scsi_add_host(shost, target->dev); | 871 | err = scsi_add_host(shost, target->dev); |
838 | if (err) | 872 | if (err) |
839 | goto destroy_queue; | 873 | goto destroy_queue; |
840 | return 0; | ||
841 | 874 | ||
875 | return 0; | ||
842 | destroy_queue: | 876 | destroy_queue: |
843 | crq_queue_destroy(target); | 877 | crq_queue_destroy(target); |
844 | free_srp_target: | 878 | free_srp_target: |
@@ -857,6 +891,7 @@ static int ibmvstgt_remove(struct vio_dev *dev) | |||
857 | struct vio_port *vport = target->ldata; | 891 | struct vio_port *vport = target->ldata; |
858 | 892 | ||
859 | crq_queue_destroy(target); | 893 | crq_queue_destroy(target); |
894 | srp_remove_host(shost); | ||
860 | scsi_remove_host(shost); | 895 | scsi_remove_host(shost); |
861 | scsi_tgt_free_queue(shost); | 896 | scsi_tgt_free_queue(shost); |
862 | srp_target_free(target); | 897 | srp_target_free(target); |
@@ -909,15 +944,24 @@ static int get_system_info(void) | |||
909 | return 0; | 944 | return 0; |
910 | } | 945 | } |
911 | 946 | ||
947 | static struct srp_function_template ibmvstgt_transport_functions = { | ||
948 | .it_nexus_response = ibmvstgt_it_nexus_response, | ||
949 | }; | ||
950 | |||
912 | static int ibmvstgt_init(void) | 951 | static int ibmvstgt_init(void) |
913 | { | 952 | { |
914 | int err = -ENOMEM; | 953 | int err = -ENOMEM; |
915 | 954 | ||
916 | printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); | 955 | printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); |
917 | 956 | ||
957 | ibmvstgt_transport_template = | ||
958 | srp_attach_transport(&ibmvstgt_transport_functions); | ||
959 | if (!ibmvstgt_transport_template) | ||
960 | return err; | ||
961 | |||
918 | vtgtd = create_workqueue("ibmvtgtd"); | 962 | vtgtd = create_workqueue("ibmvtgtd"); |
919 | if (!vtgtd) | 963 | if (!vtgtd) |
920 | return err; | 964 | goto release_transport; |
921 | 965 | ||
922 | err = get_system_info(); | 966 | err = get_system_info(); |
923 | if (err) | 967 | if (err) |
@@ -928,9 +972,10 @@ static int ibmvstgt_init(void) | |||
928 | goto destroy_wq; | 972 | goto destroy_wq; |
929 | 973 | ||
930 | return 0; | 974 | return 0; |
931 | |||
932 | destroy_wq: | 975 | destroy_wq: |
933 | destroy_workqueue(vtgtd); | 976 | destroy_workqueue(vtgtd); |
977 | release_transport: | ||
978 | srp_release_transport(ibmvstgt_transport_template); | ||
934 | return err; | 979 | return err; |
935 | } | 980 | } |
936 | 981 | ||
@@ -940,6 +985,7 @@ static void ibmvstgt_exit(void) | |||
940 | 985 | ||
941 | destroy_workqueue(vtgtd); | 986 | destroy_workqueue(vtgtd); |
942 | vio_unregister_driver(&ibmvstgt_driver); | 987 | vio_unregister_driver(&ibmvstgt_driver); |
988 | srp_release_transport(ibmvstgt_transport_template); | ||
943 | } | 989 | } |
944 | 990 | ||
945 | MODULE_DESCRIPTION("IBM Virtual SCSI Target"); | 991 | MODULE_DESCRIPTION("IBM Virtual SCSI Target"); |
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 732446e63963..2ad0a27dbaab 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c | |||
@@ -392,7 +392,7 @@ static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir) | |||
392 | } | 392 | } |
393 | 393 | ||
394 | int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, | 394 | int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, |
395 | u64 addr) | 395 | u64 itn_id, u64 addr) |
396 | { | 396 | { |
397 | enum dma_data_direction dir; | 397 | enum dma_data_direction dir; |
398 | struct scsi_cmnd *sc; | 398 | struct scsi_cmnd *sc; |
@@ -428,7 +428,8 @@ int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, | |||
428 | sc->request_bufflen = len; | 428 | sc->request_bufflen = len; |
429 | sc->request_buffer = (void *) (unsigned long) addr; | 429 | sc->request_buffer = (void *) (unsigned long) addr; |
430 | sc->tag = tag; | 430 | sc->tag = tag; |
431 | err = scsi_tgt_queue_command(sc, (struct scsi_lun *) &cmd->lun, cmd->tag); | 431 | err = scsi_tgt_queue_command(sc, itn_id, (struct scsi_lun *)&cmd->lun, |
432 | cmd->tag); | ||
432 | if (err) | 433 | if (err) |
433 | scsi_host_put_command(shost, sc); | 434 | scsi_host_put_command(shost, sc); |
434 | 435 | ||
diff --git a/include/scsi/libsrp.h b/include/scsi/libsrp.h index d143171896ae..ba615e4c1d7c 100644 --- a/include/scsi/libsrp.h +++ b/include/scsi/libsrp.h | |||
@@ -59,7 +59,7 @@ extern void srp_target_free(struct srp_target *); | |||
59 | extern struct iu_entry *srp_iu_get(struct srp_target *); | 59 | extern struct iu_entry *srp_iu_get(struct srp_target *); |
60 | extern void srp_iu_put(struct iu_entry *); | 60 | extern void srp_iu_put(struct iu_entry *); |
61 | 61 | ||
62 | extern int srp_cmd_queue(struct Scsi_Host *, struct srp_cmd *, void *, u64); | 62 | extern int srp_cmd_queue(struct Scsi_Host *, struct srp_cmd *, void *, u64, u64); |
63 | extern int srp_transfer_data(struct scsi_cmnd *, struct srp_cmd *, | 63 | extern int srp_transfer_data(struct scsi_cmnd *, struct srp_cmd *, |
64 | srp_rdma_t, int, int); | 64 | srp_rdma_t, int, int); |
65 | 65 | ||