@@ -313,17 +313,42 @@ impl<T: kind::Sealed, D: direction::Sealed> Endpoint<T, D> {
313313 )
314314 }
315315
316- /// 创建Isoch TRB
316+ /// 创建Isoch TRB,根据xHCI规范优化
317317 fn create_isoch_trb ( & self , addr_bus : usize , len : usize ) -> transfer:: Allowed {
318318 transfer:: Allowed :: Isoch (
319319 * Isoch :: new ( )
320320 . set_data_buffer_pointer ( addr_bus as _ )
321321 . set_trb_transfer_length ( len as _ )
322322 . set_interrupter_target ( 0 )
323- . set_interrupt_on_completion ( ) ,
323+ . set_interrupt_on_completion ( ) , // .set_start_isoch_asap() // 如果方法可用则启用
324324 )
325325 }
326326
327+ /// 创建Normal TRB用于Isoch TD的链接
328+ fn create_normal_trb_for_isoch (
329+ & self ,
330+ addr_bus : usize ,
331+ len : usize ,
332+ is_last : bool ,
333+ ) -> transfer:: Allowed {
334+ if is_last {
335+ transfer:: Allowed :: Normal (
336+ * Normal :: new ( )
337+ . set_data_buffer_pointer ( addr_bus as _ )
338+ . set_trb_transfer_length ( len as _ )
339+ . set_interrupter_target ( 0 )
340+ . set_interrupt_on_completion ( ) ,
341+ )
342+ } else {
343+ transfer:: Allowed :: Normal (
344+ * Normal :: new ( )
345+ . set_data_buffer_pointer ( addr_bus as _ )
346+ . set_trb_transfer_length ( len as _ )
347+ . set_interrupter_target ( 0 ) ,
348+ )
349+ }
350+ }
351+
327352 /// 执行传输的通用方法
328353 fn execute_transfer < ' a > (
329354 & mut self ,
@@ -334,6 +359,62 @@ impl<T: kind::Sealed, D: direction::Sealed> Endpoint<T, D> {
334359 self . raw
335360 . enque ( [ trb] . into_iter ( ) , self . desc . direction , addr_virt, len)
336361 }
362+
363+ /// 执行多包ISO传输的通用方法
364+ fn execute_iso_transfer < ' a > (
365+ & mut self ,
366+ trbs : Vec < transfer:: Allowed > ,
367+ addr_virt : usize ,
368+ len : usize ,
369+ ) -> ResultTransfer < ' a > {
370+ self . raw
371+ . enque ( trbs. into_iter ( ) , self . desc . direction , addr_virt, len)
372+ }
373+
374+ /// 创建多包ISO传输的TRB列表
375+ fn create_iso_trb_list (
376+ & self ,
377+ addr_bus : usize ,
378+ len : usize ,
379+ num_iso_packets : usize ,
380+ ) -> Vec < transfer:: Allowed > {
381+ let mut trbs = Vec :: new ( ) ;
382+ let packet_size = if len == 0 {
383+ 0
384+ } else {
385+ len. div_ceil ( num_iso_packets)
386+ } ;
387+
388+ for i in 0 ..num_iso_packets {
389+ let offset = i * packet_size;
390+ if offset >= len {
391+ break ; // 避免越界
392+ }
393+ let remaining = len - offset;
394+ let current_size = if remaining >= packet_size {
395+ packet_size
396+ } else {
397+ remaining
398+ } ;
399+
400+ if current_size > 0 {
401+ let current_addr = addr_bus + offset;
402+ let is_last = ( i == num_iso_packets - 1 ) || ( offset + current_size >= len) ;
403+
404+ if i == 0 {
405+ // 第一个TRB必须是Isoch TRB
406+ let trb = self . create_isoch_trb ( current_addr, current_size) ;
407+ trbs. push ( trb) ;
408+ } else {
409+ // 后续TRB使用Normal TRB
410+ let trb = self . create_normal_trb_for_isoch ( current_addr, current_size, is_last) ;
411+ trbs. push ( trb) ;
412+ }
413+ }
414+ }
415+
416+ trbs
417+ }
337418}
338419
339420impl Endpoint < kind:: Bulk , direction:: In > {
@@ -381,24 +462,46 @@ impl Endpoint<kind::Interrupt, direction::Out> {
381462}
382463
383464impl Endpoint < kind:: Isochronous , direction:: In > {
384- pub fn transfer < ' a > ( & mut self , data : & ' a mut [ u8 ] ) -> ResultTransfer < ' a > {
465+ pub fn transfer_multi_packet < ' a > (
466+ & mut self ,
467+ data : & ' a mut [ u8 ] ,
468+ num_iso_packets : usize ,
469+ ) -> ResultTransfer < ' a > {
385470 self . validate_endpoint ( Direction :: In , EndpointType :: Isochronous ) ?;
386471
387472 let ( len, addr_virt, addr_bus) = self . prepare_in_buffer ( data) ;
388- let trb = self . create_isoch_trb ( addr_bus, len) ;
389473
390- self . execute_transfer ( trb, addr_virt, len)
474+ if num_iso_packets <= 1 || len == 0 {
475+ // 单包传输,使用原有逻辑
476+ let trb = self . create_isoch_trb ( addr_bus, len) ;
477+ return self . execute_transfer ( trb, addr_virt, len) ;
478+ }
479+
480+ // 多包传输,使用公共方法创建TRB列表
481+ let trbs = self . create_iso_trb_list ( addr_bus, len, num_iso_packets) ;
482+ self . execute_iso_transfer ( trbs, addr_virt, len)
391483 }
392484}
393485
394486impl Endpoint < kind:: Isochronous , direction:: Out > {
395- pub fn transfer < ' a > ( & mut self , data : & ' a [ u8 ] ) -> ResultTransfer < ' a > {
487+ pub fn transfer_multi_packet < ' a > (
488+ & mut self ,
489+ data : & ' a [ u8 ] ,
490+ num_iso_packets : usize ,
491+ ) -> ResultTransfer < ' a > {
396492 self . validate_endpoint ( Direction :: Out , EndpointType :: Isochronous ) ?;
397493
398494 let ( len, addr_virt, addr_bus) = self . prepare_out_buffer ( data) ;
399- let trb = self . create_isoch_trb ( addr_bus, len) ;
400495
401- self . execute_transfer ( trb, addr_virt, len)
496+ if num_iso_packets <= 1 || len == 0 {
497+ // 单包传输,使用原有逻辑
498+ let trb = self . create_isoch_trb ( addr_bus, len) ;
499+ return self . execute_transfer ( trb, addr_virt, len) ;
500+ }
501+
502+ // 多包传输,使用公共方法创建TRB列表
503+ let trbs = self . create_iso_trb_list ( addr_bus, len, num_iso_packets) ;
504+ self . execute_iso_transfer ( trbs, addr_virt, len)
402505 }
403506}
404507
@@ -435,12 +538,12 @@ impl usb_if::host::EndpointInterruptOut for Endpoint<kind::Interrupt, direction:
435538
436539impl usb_if:: host:: EndpintIsoIn for Endpoint < kind:: Isochronous , direction:: In > {
437540 fn submit < ' a > ( & mut self , data : & ' a mut [ u8 ] , num_iso_packets : usize ) -> ResultTransfer < ' a > {
438- self . transfer ( data)
541+ self . transfer_multi_packet ( data, num_iso_packets )
439542 }
440543}
441544
442545impl usb_if:: host:: EndpintIsoOut for Endpoint < kind:: Isochronous , direction:: Out > {
443546 fn submit < ' a > ( & mut self , data : & ' a [ u8 ] , num_iso_packets : usize ) -> ResultTransfer < ' a > {
444- self . transfer ( data)
547+ self . transfer_multi_packet ( data, num_iso_packets )
445548 }
446549}
0 commit comments