Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 127400
b: refs/heads/master
c: 1120f8b
h: refs/heads/master
v: v3
  • Loading branch information
Stephen Hemminger authored and Jesse Barnes committed Jan 7, 2009
1 parent ab6a959 commit 1718b90
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 904d6a303361a85bfa4c8181ef62a24edb8da0a8
refs/heads/master: 1120f8b8169fb2cb51219d326892d963e762edb6
55 changes: 33 additions & 22 deletions trunk/drivers/pci/access.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,39 +133,46 @@ PCI_USER_WRITE_CONFIG(dword, u32)

struct pci_vpd_pci22 {
struct pci_vpd base;
spinlock_t lock; /* controls access to hardware and the flags */
u8 cap;
struct mutex lock;
u16 flag;
bool busy;
bool flag; /* value of F bit to wait for */
u8 cap;
};

/* Wait for last operation to complete */
/*
* Wait for last operation to complete.
* This code has to spin since there is no other notification from the PCI
* hardware. Since the VPD is often implemented by serial attachment to an
* EEPROM, it may take many milliseconds to complete.
*/
static int pci_vpd_pci22_wait(struct pci_dev *dev)
{
struct pci_vpd_pci22 *vpd =
container_of(dev->vpd, struct pci_vpd_pci22, base);
u16 flag, status;
int wait;
unsigned long timeout = jiffies + HZ/20 + 2;
u16 status;
int ret;

if (!vpd->busy)
return 0;

flag = vpd->flag ? PCI_VPD_ADDR_F : 0;
wait = vpd->flag ? 10 : 1000; /* read: 100 us; write: 10 ms */
for (;;) {
ret = pci_user_read_config_word(dev,
vpd->cap + PCI_VPD_ADDR,
ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR,
&status);
if (ret < 0)
if (ret)
return ret;
if ((status & PCI_VPD_ADDR_F) == flag) {

if ((status & PCI_VPD_ADDR_F) == vpd->flag) {
vpd->busy = false;
return 0;
}
if (wait-- == 0)

if (time_after(jiffies, timeout))
return -ETIMEDOUT;
udelay(10);
if (fatal_signal_pending(current))
return -EINTR;
if (!cond_resched())
udelay(10);
}
}

Expand All @@ -175,31 +182,34 @@ static int pci_vpd_pci22_read(struct pci_dev *dev, int pos, int size,
struct pci_vpd_pci22 *vpd =
container_of(dev->vpd, struct pci_vpd_pci22, base);
u32 val;
int ret;
int ret = 0;
int begin, end, i;

if (pos < 0 || pos > vpd->base.len || size > vpd->base.len - pos)
return -EINVAL;
if (size == 0)
return 0;

spin_lock_irq(&vpd->lock);
if (mutex_lock_killable(&vpd->lock))
return -EINTR;

ret = pci_vpd_pci22_wait(dev);
if (ret < 0)
goto out;
ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR,
pos & ~3);
if (ret < 0)
goto out;

vpd->busy = true;
vpd->flag = 1;
vpd->flag = PCI_VPD_ADDR_F;
ret = pci_vpd_pci22_wait(dev);
if (ret < 0)
goto out;
ret = pci_user_read_config_dword(dev, vpd->cap + PCI_VPD_DATA,
&val);
out:
spin_unlock_irq(&vpd->lock);
mutex_unlock(&vpd->lock);
if (ret < 0)
return ret;

Expand All @@ -220,7 +230,7 @@ static int pci_vpd_pci22_write(struct pci_dev *dev, int pos, int size,
struct pci_vpd_pci22 *vpd =
container_of(dev->vpd, struct pci_vpd_pci22, base);
u32 val;
int ret;
int ret = 0;

if (pos < 0 || pos > vpd->base.len || pos & 3 ||
size > vpd->base.len - pos || size < 4)
Expand All @@ -231,7 +241,8 @@ static int pci_vpd_pci22_write(struct pci_dev *dev, int pos, int size,
val |= ((u8) *buf++) << 16;
val |= ((u32)(u8) *buf++) << 24;

spin_lock_irq(&vpd->lock);
if (mutex_lock_killable(&vpd->lock))
return -EINTR;
ret = pci_vpd_pci22_wait(dev);
if (ret < 0)
goto out;
Expand All @@ -247,7 +258,7 @@ static int pci_vpd_pci22_write(struct pci_dev *dev, int pos, int size,
vpd->flag = 0;
ret = pci_vpd_pci22_wait(dev);
out:
spin_unlock_irq(&vpd->lock);
mutex_unlock(&vpd->lock);
if (ret < 0)
return ret;

Expand Down Expand Up @@ -279,7 +290,7 @@ int pci_vpd_pci22_init(struct pci_dev *dev)

vpd->base.len = PCI_VPD_PCI22_SIZE;
vpd->base.ops = &pci_vpd_pci22_ops;
spin_lock_init(&vpd->lock);
mutex_init(&vpd->lock);
vpd->cap = cap;
vpd->busy = false;
dev->vpd = &vpd->base;
Expand Down

0 comments on commit 1718b90

Please sign in to comment.