On Tue, Feb 08, 2022 at 03:36:08PM +0100, Takashi Iwai wrote: > ... and here is a fix patch for allowing more rebinds. > Give it a try. It works, no problems with large numbers of rebinds. > -- 8< -- > From: Takashi Iwai <tiwai@xxxxxxx> > Subject: [PATCH] ALSA: hda: Fix driver index handling at re-binding > > HD-audio driver handles the multiple instances and keeps the static > index that is incremented at each probe. This becomes a problem when > user tries to re-bind the device via sysfs multiple times; as the > device index isn't cleared unlike rmmod case, it points to the next > element at re-binding, and eventually later you can't probe any more > when it reaches to SNDRV_CARDS_MAX (usually 32). > > This patch is an attempt to improve the handling at rebinding. > Instead of a static device index, now we keep a bitmap and assigns to > the first zero bit position. At the driver remove, in return, the > bitmap slot is cleared again, so that it'll be available for the next > probe. > > Reported-by: Alexander Sergeyev <sergeev917@xxxxxxxxx> > Signed-off-by: Takashi Iwai <tiwai@xxxxxxx> > --- > sound/pci/hda/hda_intel.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c > index 4b0338c4c543..a2922233e85f 100644 > --- a/sound/pci/hda/hda_intel.c > +++ b/sound/pci/hda/hda_intel.c > @@ -2064,14 +2064,16 @@ static const struct hda_controller_ops pci_hda_ops = { > .position_check = azx_position_check, > }; > > +static DECLARE_BITMAP(probed_devs, SNDRV_CARDS); > + > static int azx_probe(struct pci_dev *pci, > const struct pci_device_id *pci_id) > { > - static int dev; > struct snd_card *card; > struct hda_intel *hda; > struct azx *chip; > bool schedule_probe; > + int dev; > int err; > > if (pci_match_id(driver_denylist, pci)) { > @@ -2079,10 +2081,11 @@ static int azx_probe(struct pci_dev *pci, > return -ENODEV; > } > > + dev = find_first_zero_bit(probed_devs, SNDRV_CARDS); > if (dev >= SNDRV_CARDS) > return -ENODEV; > if (!enable[dev]) { > - dev++; > + set_bit(dev, probed_devs); > return -ENOENT; > } > > @@ -2149,7 +2152,7 @@ static int azx_probe(struct pci_dev *pci, > if (schedule_probe) > schedule_delayed_work(&hda->probe_work, 0); > > - dev++; > + set_bit(dev, probed_devs); > if (chip->disabled) > complete_all(&hda->probe_wait); > return 0; > @@ -2372,6 +2375,7 @@ static void azx_remove(struct pci_dev *pci) > cancel_delayed_work_sync(&hda->probe_work); > device_lock(&pci->dev); > > + clear_bit(chip->dev_index, probed_devs); > pci_set_drvdata(pci, NULL); > snd_card_free(card); > } > -- > 2.34.1 >