aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/osd/osd_initiator.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index b982d767bf99..6849f269cd1b 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -111,6 +111,14 @@ static osd_cdb_offset osd_req_encode_offset(struct osd_request *or,
111 OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); 111 OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT);
112} 112}
113 113
114static struct osd_security_parameters *
115_osd_req_sec_params(struct osd_request *or)
116{
117 struct osd_cdb *ocdb = &or->cdb;
118
119 return &ocdb->v1.sec_params;
120}
121
114void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) 122void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device)
115{ 123{
116 memset(osdd, 0, sizeof(*osdd)); 124 memset(osdd, 0, sizeof(*osdd));
@@ -799,6 +807,64 @@ static int _osd_req_finalize_attr_page(struct osd_request *or)
799 return ret; 807 return ret;
800} 808}
801 809
810static int _osd_req_finalize_data_integrity(struct osd_request *or,
811 bool has_in, bool has_out, const u8 *cap_key)
812{
813 struct osd_security_parameters *sec_parms = _osd_req_sec_params(or);
814 int ret;
815
816 if (!osd_is_sec_alldata(sec_parms))
817 return 0;
818
819 if (has_out) {
820 struct _osd_req_data_segment seg = {
821 .buff = &or->out_data_integ,
822 .total_bytes = sizeof(or->out_data_integ),
823 };
824 unsigned pad;
825
826 or->out_data_integ.data_bytes = cpu_to_be64(
827 or->out.bio ? or->out.bio->bi_size : 0);
828 or->out_data_integ.set_attributes_bytes = cpu_to_be64(
829 or->set_attr.total_bytes);
830 or->out_data_integ.get_attributes_bytes = cpu_to_be64(
831 or->enc_get_attr.total_bytes);
832
833 sec_parms->data_out_integrity_check_offset =
834 osd_req_encode_offset(or, or->out.total_bytes, &pad);
835
836 ret = _req_append_segment(or, pad, &seg, or->out.last_seg,
837 &or->out);
838 if (ret)
839 return ret;
840 or->out.last_seg = NULL;
841
842 /* they are now all chained to request sign them all together */
843 osd_sec_sign_data(&or->out_data_integ, or->out.req->bio,
844 cap_key);
845 }
846
847 if (has_in) {
848 struct _osd_req_data_segment seg = {
849 .buff = &or->in_data_integ,
850 .total_bytes = sizeof(or->in_data_integ),
851 };
852 unsigned pad;
853
854 sec_parms->data_in_integrity_check_offset =
855 osd_req_encode_offset(or, or->in.total_bytes, &pad);
856
857 ret = _req_append_segment(or, pad, &seg, or->in.last_seg,
858 &or->in);
859 if (ret)
860 return ret;
861
862 or->in.last_seg = NULL;
863 }
864
865 return 0;
866}
867
802/* 868/*
803 * osd_finalize_request and helpers 869 * osd_finalize_request and helpers
804 */ 870 */
@@ -919,6 +985,12 @@ int osd_finalize_request(struct osd_request *or,
919 } 985 }
920 } 986 }
921 987
988 ret = _osd_req_finalize_data_integrity(or, has_in, has_out, cap_key);
989 if (ret)
990 return ret;
991
992 osd_sec_sign_cdb(&or->cdb, cap_key);
993
922 or->request->cmd = or->cdb.buff; 994 or->request->cmd = or->cdb.buff;
923 or->request->cmd_len = _osd_req_cdb_len(or); 995 or->request->cmd_len = _osd_req_cdb_len(or);
924 996
@@ -984,6 +1056,20 @@ void osd_set_caps(struct osd_cdb *cdb, const void *caps)
984 memcpy(&cdb->v1.caps, caps, OSDv1_CAP_LEN); 1056 memcpy(&cdb->v1.caps, caps, OSDv1_CAP_LEN);
985} 1057}
986 1058
1059bool osd_is_sec_alldata(struct osd_security_parameters *sec_parms __unused)
1060{
1061 return false;
1062}
1063
1064void osd_sec_sign_cdb(struct osd_cdb *ocdb __unused, const u8 *cap_key __unused)
1065{
1066}
1067
1068void osd_sec_sign_data(void *data_integ __unused,
1069 struct bio *bio __unused, const u8 *cap_key __unused)
1070{
1071}
1072
987/* 1073/*
988 * Declared in osd_protocol.h 1074 * Declared in osd_protocol.h
989 * 4.12.5 Data-In and Data-Out buffer offsets 1075 * 4.12.5 Data-In and Data-Out buffer offsets