@@ -1831,13 +1831,15 @@ xhci_free_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
18311831 * low or high 32 bits of ERSTBA immediately causes the controller to
18321832 * dereference the partially cleared 64 bit address, causing IOMMU error.
18331833 */
1834- tmp = readl (& ir -> ir_set -> erst_size );
1835- tmp &= ERST_SIZE_MASK ;
1836- writel (tmp , & ir -> ir_set -> erst_size );
1837-
1838- tmp64 = xhci_read_64 (xhci , & ir -> ir_set -> erst_dequeue );
1839- tmp64 &= (u64 ) ERST_PTR_MASK ;
1840- xhci_write_64 (xhci , tmp64 , & ir -> ir_set -> erst_dequeue );
1834+ if (ir -> ir_set ) {
1835+ tmp = readl (& ir -> ir_set -> erst_size );
1836+ tmp &= ERST_SIZE_MASK ;
1837+ writel (tmp , & ir -> ir_set -> erst_size );
1838+
1839+ tmp64 = xhci_read_64 (xhci , & ir -> ir_set -> erst_dequeue );
1840+ tmp64 &= (u64 ) ERST_PTR_MASK ;
1841+ xhci_write_64 (xhci , tmp64 , & ir -> ir_set -> erst_dequeue );
1842+ }
18411843
18421844 /* free interrrupter event ring */
18431845 if (ir -> event_ring )
@@ -2227,43 +2229,50 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
22272229}
22282230
22292231static struct xhci_interrupter *
2230- xhci_alloc_interrupter (struct xhci_hcd * xhci , unsigned int intr_num , gfp_t flags )
2232+ xhci_alloc_interrupter (struct xhci_hcd * xhci , gfp_t flags )
22312233{
22322234 struct device * dev = xhci_to_hcd (xhci )-> self .sysdev ;
22332235 struct xhci_interrupter * ir ;
2234- u64 erst_base ;
2235- u32 erst_size ;
22362236 int ret ;
22372237
2238- if (intr_num > xhci -> max_interrupters ) {
2239- xhci_warn (xhci , "Can't allocate interrupter %d, max interrupters %d\n" ,
2240- intr_num , xhci -> max_interrupters );
2241- return NULL ;
2242- }
2243-
2244- if (xhci -> interrupter ) {
2245- xhci_warn (xhci , "Can't allocate already set up interrupter %d\n" , intr_num );
2246- return NULL ;
2247- }
2248-
22492238 ir = kzalloc_node (sizeof (* ir ), flags , dev_to_node (dev ));
22502239 if (!ir )
22512240 return NULL ;
22522241
2253- ir -> ir_set = & xhci -> run_regs -> ir_set [intr_num ];
22542242 ir -> event_ring = xhci_ring_alloc (xhci , ERST_NUM_SEGS , 1 , TYPE_EVENT ,
22552243 0 , flags );
22562244 if (!ir -> event_ring ) {
2257- xhci_warn (xhci , "Failed to allocate interrupter %d event ring\n" , intr_num );
2258- goto fail_ir ;
2245+ xhci_warn (xhci , "Failed to allocate interrupter event ring\n" );
2246+ kfree (ir );
2247+ return NULL ;
22592248 }
22602249
22612250 ret = xhci_alloc_erst (xhci , ir -> event_ring , & ir -> erst , flags );
22622251 if (ret ) {
2263- xhci_warn (xhci , "Failed to allocate interrupter %d erst\n" , intr_num );
2264- goto fail_ev ;
2252+ xhci_warn (xhci , "Failed to allocate interrupter erst\n" );
2253+ xhci_ring_free (xhci , ir -> event_ring );
2254+ kfree (ir );
2255+ return NULL ;
2256+ }
2257+
2258+ return ir ;
2259+ }
2260+
2261+ static int
2262+ xhci_add_interrupter (struct xhci_hcd * xhci , struct xhci_interrupter * ir ,
2263+ unsigned int intr_num )
2264+ {
2265+ u64 erst_base ;
2266+ u32 erst_size ;
22652267
2268+ if (intr_num > xhci -> max_interrupters ) {
2269+ xhci_warn (xhci , "Can't add interrupter %d, max interrupters %d\n" ,
2270+ intr_num , xhci -> max_interrupters );
2271+ return - EINVAL ;
22662272 }
2273+
2274+ ir -> ir_set = & xhci -> run_regs -> ir_set [intr_num ];
2275+
22672276 /* set ERST count with the number of entries in the segment table */
22682277 erst_size = readl (& ir -> ir_set -> erst_size );
22692278 erst_size &= ERST_SIZE_MASK ;
@@ -2278,14 +2287,7 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int intr_num, gfp_t flags
22782287 /* Set the event ring dequeue address of this interrupter */
22792288 xhci_set_hc_event_deq (xhci , ir );
22802289
2281- return ir ;
2282-
2283- fail_ev :
2284- xhci_ring_free (xhci , ir -> event_ring );
2285- fail_ir :
2286- kfree (ir );
2287-
2288- return NULL ;
2290+ return 0 ;
22892291}
22902292
22912293int xhci_mem_init (struct xhci_hcd * xhci , gfp_t flags )
@@ -2407,15 +2409,17 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
24072409 "// Doorbell array is located at offset 0x%x from cap regs base addr" ,
24082410 val );
24092411 xhci -> dba = (void __iomem * ) xhci -> cap_regs + val ;
2410- /* Set ir_set to interrupt register set 0 */
24112412
2412- /* allocate and set up primary interrupter with an event ring. */
2413+ /* Allocate and set up primary interrupter 0 with an event ring. */
24132414 xhci_dbg_trace (xhci , trace_xhci_dbg_init ,
24142415 "Allocating primary event ring" );
2415- xhci -> interrupter = xhci_alloc_interrupter (xhci , 0 , flags );
2416+ xhci -> interrupter = xhci_alloc_interrupter (xhci , flags );
24162417 if (!xhci -> interrupter )
24172418 goto fail ;
24182419
2420+ if (xhci_add_interrupter (xhci , xhci -> interrupter , 0 ))
2421+ goto fail ;
2422+
24192423 xhci -> isoc_bei_interval = AVOID_BEI_INTERVAL_MAX ;
24202424
24212425 /*
0 commit comments