Commit 6e0ae74b authored by Narsimhulu Musini's avatar Narsimhulu Musini Committed by Martin K. Petersen

snic: Handling control path queue issues

Fix handles control path queue issues such as queue full and sudden
removal of hardware.
Signed-off-by: default avatarNarsimhulu Musini <nmusini@cisco.com>
Signed-off-by: default avatarSesidhar Baddela <sebaddel@cisco.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f352a0d5
...@@ -263,12 +263,20 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, ...@@ -263,12 +263,20 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
int wait) int wait)
{ {
struct devcmd2_controller *dc2c = vdev->devcmd2; struct devcmd2_controller *dc2c = vdev->devcmd2;
struct devcmd2_result *result = dc2c->result + dc2c->next_result; struct devcmd2_result *result = NULL;
unsigned int i; unsigned int i;
int delay; int delay;
int err; int err;
u32 posted; u32 posted;
u32 fetch_idx;
u32 new_posted; u32 new_posted;
u8 color;
fetch_idx = ioread32(&dc2c->wq_ctrl->fetch_index);
if (fetch_idx == 0xFFFFFFFF) { /* check for hardware gone */
/* Hardware surprise removal: return error */
return -ENODEV;
}
posted = ioread32(&dc2c->wq_ctrl->posted_index); posted = ioread32(&dc2c->wq_ctrl->posted_index);
...@@ -278,6 +286,13 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, ...@@ -278,6 +286,13 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
} }
new_posted = (posted + 1) % DEVCMD2_RING_SIZE; new_posted = (posted + 1) % DEVCMD2_RING_SIZE;
if (new_posted == fetch_idx) {
pr_err("%s: wq is full while issuing devcmd2 command %d, fetch index: %u, posted index: %u\n",
pci_name(vdev->pdev), _CMD_N(cmd), fetch_idx, posted);
return -EBUSY;
}
dc2c->cmd_ring[posted].cmd = cmd; dc2c->cmd_ring[posted].cmd = cmd;
dc2c->cmd_ring[posted].flags = 0; dc2c->cmd_ring[posted].flags = 0;
...@@ -299,14 +314,22 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, ...@@ -299,14 +314,22 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
if (dc2c->cmd_ring[posted].flags & DEVCMD2_FNORESULT) if (dc2c->cmd_ring[posted].flags & DEVCMD2_FNORESULT)
return 0; return 0;
result = dc2c->result + dc2c->next_result;
color = dc2c->color;
/*
* Increment next_result, after posting the devcmd, irrespective of
* devcmd result, and it should be done only once.
*/
dc2c->next_result++;
if (dc2c->next_result == dc2c->result_size) {
dc2c->next_result = 0;
dc2c->color = dc2c->color ? 0 : 1;
}
for (delay = 0; delay < wait; delay++) { for (delay = 0; delay < wait; delay++) {
udelay(100); udelay(100);
if (result->color == dc2c->color) { if (result->color == color) {
dc2c->next_result++;
if (dc2c->next_result == dc2c->result_size) {
dc2c->next_result = 0;
dc2c->color = dc2c->color ? 0 : 1;
}
if (result->error) { if (result->error) {
err = (int) result->error; err = (int) result->error;
if (err != ERR_ECMDUNKNOWN || if (err != ERR_ECMDUNKNOWN ||
...@@ -317,13 +340,6 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, ...@@ -317,13 +340,6 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
return err; return err;
} }
if (_CMD_DIR(cmd) & _CMD_DIR_READ) { if (_CMD_DIR(cmd) & _CMD_DIR_READ) {
/*
* Adding the rmb() prevents the compiler
* and/or CPU from reordering the reads which
* would potentially result in reading stale
* values.
*/
rmb();
for (i = 0; i < VNIC_DEVCMD_NARGS; i++) for (i = 0; i < VNIC_DEVCMD_NARGS; i++)
vdev->args[i] = result->results[i]; vdev->args[i] = result->results[i];
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment