@@ -614,9 +614,116 @@ static void sid_vhf_hid_close(struct hid_device *hid)
614614 hid_dbg (hid , "%s\n" , __func__ );
615615}
616616
617+ struct surface_sam_sid_vhf_meta_rqst {
618+ u8 id ;
619+ u32 offset ;
620+ u32 limit ;
621+ u8 end ; // 0x01 if end was reached
622+ } __packed ;
623+
624+ struct vhf_meta_info_resp {
625+ u8 _1 ;
626+ u8 _2 ;
627+ u8 _3 ;
628+ u8 _4 ;
629+ u8 _5 ;
630+ u8 _6 ;
631+ u8 _7 ;
632+ u16 len ;
633+ } __packed ;
634+
635+ union vhf_buffer_data {
636+ struct vhf_meta_info_resp info ;
637+ u8 pld [0x76 ];
638+ };
639+
640+ struct surface_sam_sid_vhf_meta_resp {
641+ struct surface_sam_sid_vhf_meta_rqst rqst ;
642+ union vhf_buffer_data data ;
643+ } __packed ;
644+
645+
646+ // TODO: need to return pointer + len
647+ static int vhf_get_hid_descriptor (struct hid_device * hid , u8 * * desc , int * size )
648+ {
649+ int status ;
650+ int len ;
651+ u8 * buf ;
652+
653+ struct surface_sam_ssh_rqst rqst = {};
654+ struct surface_sam_sid_vhf_meta_resp resp = {};
655+ struct surface_sam_ssh_buf result = {};
656+
657+ resp .rqst .id = 0 ;
658+ resp .rqst .offset = 0 ;
659+ resp .rqst .limit = 0x76 ;
660+ resp .rqst .end = 0 ;
661+
662+ rqst .tc = 0x15 ;
663+ rqst .cid = 0x04 ;
664+ rqst .iid = 0x03 ;
665+ rqst .pri = 0x02 ;
666+ rqst .snc = 0x01 ;
667+ rqst .cdl = sizeof (struct surface_sam_sid_vhf_meta_rqst );
668+ rqst .pld = (u8 * )& resp .rqst ;
669+
670+ result .cap = sizeof (struct surface_sam_sid_vhf_meta_resp );
671+ result .len = 0 ;
672+ result .data = (u8 * )& resp ;
673+
674+ // first fetch 01 to get the total length
675+ status = surface_sam_ssh_rqst (& rqst , & result );
676+ if (status ) {
677+ return status ;
678+ }
679+
680+ len = resp .data .info .len ;
681+
682+ // allocate a buffer for the descriptor
683+ buf = kzalloc (len * sizeof (u8 ), GFP_KERNEL );
684+
685+ // then, iterate and write into buffer, copying out resp.rqst.len bytes
686+ // (it gets set to the length of data read)
687+
688+ resp .rqst .id = 1 ;
689+ resp .rqst .offset = 0 ;
690+ resp .rqst .end = 0 ;
691+
692+ while (resp .rqst .end != 0x01 ) {
693+ status = surface_sam_ssh_rqst (& rqst , & result );
694+ if (status ) {
695+ kfree (buf );
696+ return status ;
697+ }
698+ memcpy (buf + resp .rqst .offset , resp .data .pld , resp .rqst .limit );
699+
700+ resp .rqst .offset += resp .rqst .limit ;
701+ }
702+
703+ * desc = buf ;
704+ * size = len ;
705+
706+ return 0 ;
707+ }
708+
617709static int sid_vhf_hid_parse (struct hid_device * hid )
618710{
619- return hid_parse_report (hid , (u8 * )sid_vhf_hid_desc , ARRAY_SIZE (sid_vhf_hid_desc ));
711+
712+ int ret = 0 , size ;
713+ u8 * buf ;
714+
715+ ret = vhf_get_hid_descriptor (hid , & buf , & size );
716+ if (ret != 0 ) {
717+ hid_dbg (hid , "vhf_get_hid_descriptor ret %d\n" , ret );
718+ return - EIO ;
719+ }
720+ print_hex_dump_debug ("descriptor:" , DUMP_PREFIX_OFFSET , 16 , 1 , buf , size , false);
721+
722+ ret = hid_parse_report (hid , (u8 * )sid_vhf_hid_desc , ARRAY_SIZE (sid_vhf_hid_desc ));
723+ /* ret = hid_parse_report(hid, buf, size); */
724+ kfree (buf );
725+ return ret ;
726+
620727}
621728
622729static int sid_vhf_hid_raw_request (struct hid_device * hid , unsigned char reportnum ,
0 commit comments