Skip to content

Commit aa03800

Browse files
authored
Merge pull request #96 from Microsemi/mrpc_reset
Error out MRPC execution when no more GAS access
2 parents cbf1061 + b212caa commit aa03800

File tree

1 file changed

+51
-6
lines changed

1 file changed

+51
-6
lines changed

switchtec.c

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ enum mrpc_state {
5252
MRPC_QUEUED,
5353
MRPC_RUNNING,
5454
MRPC_DONE,
55+
MRPC_IO_ERROR,
5556
};
5657

5758
struct switchtec_user {
@@ -72,6 +73,13 @@ struct switchtec_user {
7273
int event_cnt;
7374
};
7475

76+
static int check_access(struct switchtec_dev *stdev)
77+
{
78+
u32 device = ioread32(&stdev->mmio_sys_info->device_id);
79+
80+
return stdev->pdev->device == device;
81+
}
82+
7583
static struct switchtec_user *stuser_create(struct switchtec_dev *stdev)
7684
{
7785
struct switchtec_user *stuser;
@@ -119,6 +127,7 @@ static void stuser_set_state(struct switchtec_user *stuser,
119127
[MRPC_QUEUED] = "QUEUED",
120128
[MRPC_RUNNING] = "RUNNING",
121129
[MRPC_DONE] = "DONE",
130+
[MRPC_IO_ERROR] = "IO_ERROR",
122131
};
123132

124133
stuser->state = state;
@@ -186,6 +195,20 @@ static int mrpc_queue_cmd(struct switchtec_user *stuser)
186195
return 0;
187196
}
188197

198+
static void mrpc_cleanup_cmd(struct switchtec_dev *stdev)
199+
{
200+
/* requires the mrpc_mutex to already be held when called */
201+
struct switchtec_user *stuser = list_entry(stdev->mrpc_queue.next,
202+
struct switchtec_user, list);
203+
204+
complete_all(&stuser->comp);
205+
list_del_init(&stuser->list);
206+
stuser_put(stuser);
207+
stdev->mrpc_busy = 0;
208+
209+
mrpc_cmd_submit(stdev);
210+
}
211+
189212
static void mrpc_complete_cmd(struct switchtec_dev *stdev)
190213
{
191214
/* requires the mrpc_mutex to already be held when called */
@@ -226,12 +249,7 @@ static void mrpc_complete_cmd(struct switchtec_dev *stdev)
226249
memcpy_fromio(stuser->data, &stdev->mmio_mrpc->output_data,
227250
stuser->read_len);
228251
out:
229-
complete_all(&stuser->comp);
230-
list_del_init(&stuser->list);
231-
stuser_put(stuser);
232-
stdev->mrpc_busy = 0;
233-
234-
mrpc_cmd_submit(stdev);
252+
mrpc_cleanup_cmd(stdev);
235253
}
236254

237255
static void mrpc_event_work(struct work_struct *work)
@@ -248,6 +266,23 @@ static void mrpc_event_work(struct work_struct *work)
248266
mutex_unlock(&stdev->mrpc_mutex);
249267
}
250268

269+
static void mrpc_error_complete_cmd(struct switchtec_dev *stdev)
270+
{
271+
/* requires the mrpc_mutex to already be held when called */
272+
273+
struct switchtec_user *stuser;
274+
275+
if (list_empty(&stdev->mrpc_queue))
276+
return;
277+
278+
stuser = list_entry(stdev->mrpc_queue.next,
279+
struct switchtec_user, list);
280+
281+
stuser_set_state(stuser, MRPC_IO_ERROR);
282+
283+
mrpc_cleanup_cmd(stdev);
284+
}
285+
251286
static void mrpc_timeout_work(struct work_struct *work)
252287
{
253288
struct switchtec_dev *stdev;
@@ -259,6 +294,11 @@ static void mrpc_timeout_work(struct work_struct *work)
259294

260295
mutex_lock(&stdev->mrpc_mutex);
261296

297+
if (!check_access(stdev)) {
298+
mrpc_error_complete_cmd(stdev);
299+
goto out;
300+
}
301+
262302
if (stdev->dma_mrpc)
263303
status = stdev->dma_mrpc->status;
264304
else
@@ -544,6 +584,11 @@ static ssize_t switchtec_dev_read(struct file *filp, char __user *data,
544584
if (rc)
545585
return rc;
546586

587+
if (stuser->state == MRPC_IO_ERROR) {
588+
mutex_unlock(&stdev->mrpc_mutex);
589+
return -EIO;
590+
}
591+
547592
if (stuser->state != MRPC_DONE) {
548593
mutex_unlock(&stdev->mrpc_mutex);
549594
return -EBADE;

0 commit comments

Comments
 (0)