@@ -438,129 +438,194 @@ void brcmf_fw_nvram_free(void *nvram)
438
438
439
439
struct brcmf_fw {
440
440
struct device * dev ;
441
- u16 flags ;
442
- const struct firmware * code ;
443
- const char * nvram_name ;
444
- u16 domain_nr ;
445
- u16 bus_nr ;
446
- void (* done )(struct device * dev , int err , const struct firmware * fw ,
447
- void * nvram_image , u32 nvram_len );
441
+ struct brcmf_fw_request * req ;
442
+ u32 curpos ;
443
+ void (* done )(struct device * dev , int err , struct brcmf_fw_request * req );
448
444
};
449
445
446
+ static void brcmf_fw_request_done (const struct firmware * fw , void * ctx );
447
+
448
+ static void brcmf_fw_free_request (struct brcmf_fw_request * req )
449
+ {
450
+ struct brcmf_fw_item * item ;
451
+ int i ;
452
+
453
+ for (i = 0 , item = & req -> items [0 ]; i < req -> n_items ; i ++ , item ++ ) {
454
+ if (item -> type == BRCMF_FW_TYPE_BINARY )
455
+ release_firmware (item -> binary );
456
+ else if (item -> type == BRCMF_FW_TYPE_NVRAM )
457
+ brcmf_fw_nvram_free (item -> nv_data .data );
458
+ }
459
+ kfree (req );
460
+ }
461
+
450
462
static void brcmf_fw_request_nvram_done (const struct firmware * fw , void * ctx )
451
463
{
452
464
struct brcmf_fw * fwctx = ctx ;
465
+ struct brcmf_fw_item * cur ;
453
466
u32 nvram_length = 0 ;
454
467
void * nvram = NULL ;
455
468
u8 * data = NULL ;
456
469
size_t data_len ;
457
470
bool raw_nvram ;
458
471
459
472
brcmf_dbg (TRACE , "enter: dev=%s\n" , dev_name (fwctx -> dev ));
473
+
474
+ cur = & fwctx -> req -> items [fwctx -> curpos ];
475
+
460
476
if (fw && fw -> data ) {
461
477
data = (u8 * )fw -> data ;
462
478
data_len = fw -> size ;
463
479
raw_nvram = false;
464
480
} else {
465
481
data = bcm47xx_nvram_get_contents (& data_len );
466
- if (!data && !(fwctx -> flags & BRCMF_FW_REQ_NV_OPTIONAL ))
482
+ if (!data && !(cur -> flags & BRCMF_FW_REQF_OPTIONAL ))
467
483
goto fail ;
468
484
raw_nvram = true;
469
485
}
470
486
471
487
if (data )
472
488
nvram = brcmf_fw_nvram_strip (data , data_len , & nvram_length ,
473
- fwctx -> domain_nr , fwctx -> bus_nr );
489
+ fwctx -> req -> domain_nr ,
490
+ fwctx -> req -> bus_nr );
474
491
475
492
if (raw_nvram )
476
493
bcm47xx_nvram_release_contents (data );
477
494
release_firmware (fw );
478
- if (!nvram && !(fwctx -> flags & BRCMF_FW_REQ_NV_OPTIONAL ))
495
+ if (!nvram && !(cur -> flags & BRCMF_FW_REQF_OPTIONAL ))
479
496
goto fail ;
480
497
481
- fwctx -> done (fwctx -> dev , 0 , fwctx -> code , nvram , nvram_length );
482
- kfree (fwctx );
498
+ brcmf_dbg (TRACE , "nvram %p len %d\n" , nvram , nvram_length );
499
+ cur -> nv_data .data = nvram ;
500
+ cur -> nv_data .len = nvram_length ;
483
501
return ;
484
502
485
503
fail :
486
504
brcmf_dbg (TRACE , "failed: dev=%s\n" , dev_name (fwctx -> dev ));
487
- release_firmware (fwctx -> code );
488
- fwctx -> done (fwctx -> dev , - ENOENT , NULL , NULL , 0 );
505
+ fwctx -> done (fwctx -> dev , - ENOENT , NULL );
506
+ brcmf_fw_free_request (fwctx -> req );
489
507
kfree (fwctx );
490
508
}
491
509
492
- static void brcmf_fw_request_code_done (const struct firmware * fw , void * ctx )
510
+ static int brcmf_fw_request_next_item (struct brcmf_fw * fwctx , bool async )
511
+ {
512
+ struct brcmf_fw_item * cur ;
513
+ const struct firmware * fw = NULL ;
514
+ int ret ;
515
+
516
+ cur = & fwctx -> req -> items [fwctx -> curpos ];
517
+
518
+ brcmf_dbg (TRACE , "%srequest for %s\n" , async ? "async " : "" ,
519
+ cur -> path );
520
+
521
+ if (async )
522
+ ret = request_firmware_nowait (THIS_MODULE , true, cur -> path ,
523
+ fwctx -> dev , GFP_KERNEL , fwctx ,
524
+ brcmf_fw_request_done );
525
+ else
526
+ ret = request_firmware (& fw , cur -> path , fwctx -> dev );
527
+
528
+ if (ret < 0 ) {
529
+ brcmf_fw_request_done (NULL , fwctx );
530
+ } else if (!async && fw ) {
531
+ brcmf_dbg (TRACE , "firmware %s %sfound\n" , cur -> path ,
532
+ fw ? "" : "not " );
533
+ if (cur -> type == BRCMF_FW_TYPE_BINARY )
534
+ cur -> binary = fw ;
535
+ else if (cur -> type == BRCMF_FW_TYPE_NVRAM )
536
+ brcmf_fw_request_nvram_done (fw , fwctx );
537
+ else
538
+ release_firmware (fw );
539
+
540
+ return - EAGAIN ;
541
+ }
542
+ return 0 ;
543
+ }
544
+
545
+ static void brcmf_fw_request_done (const struct firmware * fw , void * ctx )
493
546
{
494
547
struct brcmf_fw * fwctx = ctx ;
548
+ struct brcmf_fw_item * cur ;
495
549
int ret = 0 ;
496
550
497
- brcmf_dbg (TRACE , "enter: dev=%s\n" , dev_name (fwctx -> dev ));
498
- if (!fw ) {
551
+ cur = & fwctx -> req -> items [fwctx -> curpos ];
552
+
553
+ brcmf_dbg (TRACE , "enter: firmware %s %sfound\n" , cur -> path ,
554
+ fw ? "" : "not " );
555
+
556
+ if (fw ) {
557
+ if (cur -> type == BRCMF_FW_TYPE_BINARY )
558
+ cur -> binary = fw ;
559
+ else if (cur -> type == BRCMF_FW_TYPE_NVRAM )
560
+ brcmf_fw_request_nvram_done (fw , fwctx );
561
+ else
562
+ release_firmware (fw );
563
+ } else if (cur -> type == BRCMF_FW_TYPE_NVRAM ) {
564
+ brcmf_fw_request_nvram_done (NULL , fwctx );
565
+ } else if (!(cur -> flags & BRCMF_FW_REQF_OPTIONAL )) {
499
566
ret = - ENOENT ;
500
567
goto fail ;
501
568
}
502
- /* only requested code so done here */
503
- if (!(fwctx -> flags & BRCMF_FW_REQUEST_NVRAM ))
504
- goto done ;
505
569
506
- fwctx -> code = fw ;
507
- ret = request_firmware_nowait (THIS_MODULE , true, fwctx -> nvram_name ,
508
- fwctx -> dev , GFP_KERNEL , fwctx ,
509
- brcmf_fw_request_nvram_done );
570
+ do {
571
+ if (++ fwctx -> curpos == fwctx -> req -> n_items ) {
572
+ ret = 0 ;
573
+ goto done ;
574
+ }
575
+
576
+ ret = brcmf_fw_request_next_item (fwctx , false);
577
+ } while (ret == - EAGAIN );
510
578
511
- /* pass NULL to nvram callback for bcm47xx fallback */
512
- if (ret )
513
- brcmf_fw_request_nvram_done (NULL , fwctx );
514
579
return ;
515
580
516
581
fail :
517
- brcmf_dbg (TRACE , "failed: dev=%s\n" , dev_name (fwctx -> dev ));
582
+ brcmf_dbg (TRACE , "failed err=%d: dev=%s, fw=%s\n" , ret ,
583
+ dev_name (fwctx -> dev ), cur -> path );
584
+ brcmf_fw_free_request (fwctx -> req );
585
+ fwctx -> req = NULL ;
518
586
done :
519
- fwctx -> done (fwctx -> dev , ret , fw , NULL , 0 );
587
+ fwctx -> done (fwctx -> dev , ret , fwctx -> req );
520
588
kfree (fwctx );
521
589
}
522
590
523
- int brcmf_fw_get_firmwares_pcie (struct device * dev , u16 flags ,
524
- const char * code , const char * nvram ,
525
- void (* fw_cb )(struct device * dev , int err ,
526
- const struct firmware * fw ,
527
- void * nvram_image , u32 nvram_len ),
528
- u16 domain_nr , u16 bus_nr )
591
+ static bool brcmf_fw_request_is_valid (struct brcmf_fw_request * req )
592
+ {
593
+ struct brcmf_fw_item * item ;
594
+ int i ;
595
+
596
+ if (!req -> n_items )
597
+ return false;
598
+
599
+ for (i = 0 , item = & req -> items [0 ]; i < req -> n_items ; i ++ , item ++ ) {
600
+ if (!item -> path )
601
+ return false;
602
+ }
603
+ return true;
604
+ }
605
+
606
+ int brcmf_fw_get_firmwares (struct device * dev , struct brcmf_fw_request * req ,
607
+ void (* fw_cb )(struct device * dev , int err ,
608
+ struct brcmf_fw_request * req ))
529
609
{
530
610
struct brcmf_fw * fwctx ;
531
611
532
612
brcmf_dbg (TRACE , "enter: dev=%s\n" , dev_name (dev ));
533
- if (!fw_cb || ! code )
613
+ if (!fw_cb )
534
614
return - EINVAL ;
535
615
536
- if (( flags & BRCMF_FW_REQUEST_NVRAM ) && ! nvram )
616
+ if (! brcmf_fw_request_is_valid ( req ) )
537
617
return - EINVAL ;
538
618
539
619
fwctx = kzalloc (sizeof (* fwctx ), GFP_KERNEL );
540
620
if (!fwctx )
541
621
return - ENOMEM ;
542
622
543
623
fwctx -> dev = dev ;
544
- fwctx -> flags = flags ;
624
+ fwctx -> req = req ;
545
625
fwctx -> done = fw_cb ;
546
- if (flags & BRCMF_FW_REQUEST_NVRAM )
547
- fwctx -> nvram_name = nvram ;
548
- fwctx -> domain_nr = domain_nr ;
549
- fwctx -> bus_nr = bus_nr ;
550
-
551
- return request_firmware_nowait (THIS_MODULE , true, code , dev ,
552
- GFP_KERNEL , fwctx ,
553
- brcmf_fw_request_code_done );
554
- }
555
626
556
- int brcmf_fw_get_firmwares (struct device * dev , u16 flags ,
557
- const char * code , const char * nvram ,
558
- void (* fw_cb )(struct device * dev , int err ,
559
- const struct firmware * fw ,
560
- void * nvram_image , u32 nvram_len ))
561
- {
562
- return brcmf_fw_get_firmwares_pcie (dev , flags , code , nvram , fw_cb , 0 ,
563
- 0 );
627
+ brcmf_fw_request_next_item (fwctx , true);
628
+ return 0 ;
564
629
}
565
630
566
631
static void brcmf_fw_get_full_name (char fw_name [BRCMF_FW_NAME_LEN ],
0 commit comments