hal/ia32: set spinlock for single PCI device configuration
@@ -108,39 +108,40 @@ int hal_pciSetBusmaster(pci_dev_t *dev, u8 enable)
int hal_pciGetDevice(pci_id_t *id, pci_dev_t *dev, void *caps)
{
spinlock_ctx_t sc;
- unsigned int b, d, f, i;
+ unsigned char b, d, f, i;
u32 dv, cl, mask, val;
int res = EOK;
if ((id == NULL) || (dev == NULL))
return -EINVAL;
- hal_spinlockSet(&pci_common.spinlock, &sc);
-
- for (b = dev->bus; b < 256; b++) {
+ for (b = dev->bus;; b++) {
for (d = dev->dev; d < 32; d++) {
for (f = dev->func; f < 8; f++) {
+ hal_spinlockSet(&pci_common.spinlock, &sc);
+
+ do {
if ((dv = _hal_pciGet(b, d, f, 0)) == 0xffffffff)
- continue;
+ break;
if ((id->vendor != PCI_ANY) && (id->vendor != (dv & 0xffff)))
- continue;
+ break;
if ((id->device != PCI_ANY) && (id->device != (dv >> 16)))
- continue;
+ break;
cl = _hal_pciGet(b, d, f, 2) >> 16;
if ((id->cl != PCI_ANY) && (id->cl != cl))
- continue;
+ break;
val = _hal_pciGet(b, d, f, 0xb);
if ((id->subdevice != PCI_ANY) && (id->subdevice != (val >> 16)))
- continue;
+ break;
if ((id->subvendor != PCI_ANY) && (id->subvendor != (val & 0xffff)))
- continue;
+ break;
dev->bus = b;
dev->dev = d;
@@ -165,7 +166,7 @@ int hal_pciGetDevice(pci_id_t *id, pci_dev_t *dev, void *caps)
for (i = 0; i < 6; i++) {
dev->resources[i].base = _hal_pciGet(b, d, f, 4 + i);
- /* Get resource limit/size */
+ /* Get resource flags and size */
_hal_pciSet(b, d, f, 4 + i, 0xffffffff);
dev->resources[i].limit = _hal_pciGet(b, d, f, 4 + i);
mask = (dev->resources[i].base & 0x1) ? ~0x3 : ~0xf;
@@ -181,13 +182,17 @@ int hal_pciGetDevice(pci_id_t *id, pci_dev_t *dev, void *caps)
hal_spinlockClear(&pci_common.spinlock, &sc);
return res;
+ } while (0);
+
+ hal_spinlockClear(&pci_common.spinlock, &sc);
}
dev->func = 0;
}
dev->dev = 0;
- }
- hal_spinlockClear(&pci_common.spinlock, &sc);
+ if (b == 0xff)
+ break;
+ }
return -ENODEV;
}
