• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Filename: cregs.c
3 *
4 *
5 * Authors: Joshua Morris <josh.h.morris@us.ibm.com>
6 *	Philip Kelleher <pjk1939@linux.vnet.ibm.com>
7 *
8 * (C) Copyright 2013 IBM Corporation
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of the
13 * License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include <linux/completion.h>
26 #include <linux/slab.h>
27 
28 #include "rsxx_priv.h"
29 
30 #define CREG_TIMEOUT_MSEC	10000
31 
32 typedef void (*creg_cmd_cb)(struct rsxx_cardinfo *card,
33 			    struct creg_cmd *cmd,
34 			    int st);
35 
36 struct creg_cmd {
37 	struct list_head list;
38 	creg_cmd_cb cb;
39 	void *cb_private;
40 	unsigned int op;
41 	unsigned int addr;
42 	int cnt8;
43 	void *buf;
44 	unsigned int stream;
45 	unsigned int status;
46 };
47 
48 static struct kmem_cache *creg_cmd_pool;
49 
50 
51 /*------------ Private Functions --------------*/
52 
53 #if defined(__LITTLE_ENDIAN)
54 #define LITTLE_ENDIAN 1
55 #elif defined(__BIG_ENDIAN)
56 #define LITTLE_ENDIAN 0
57 #else
58 #error Unknown endianess!!! Aborting...
59 #endif
60 
copy_to_creg_data(struct rsxx_cardinfo * card,int cnt8,void * buf,unsigned int stream)61 static int copy_to_creg_data(struct rsxx_cardinfo *card,
62 			      int cnt8,
63 			      void *buf,
64 			      unsigned int stream)
65 {
66 	int i = 0;
67 	u32 *data = buf;
68 
69 	if (unlikely(card->eeh_state))
70 		return -EIO;
71 
72 	for (i = 0; cnt8 > 0; i++, cnt8 -= 4) {
73 		/*
74 		 * Firmware implementation makes it necessary to byte swap on
75 		 * little endian processors.
76 		 */
77 		if (LITTLE_ENDIAN && stream)
78 			iowrite32be(data[i], card->regmap + CREG_DATA(i));
79 		else
80 			iowrite32(data[i], card->regmap + CREG_DATA(i));
81 	}
82 
83 	return 0;
84 }
85 
86 
copy_from_creg_data(struct rsxx_cardinfo * card,int cnt8,void * buf,unsigned int stream)87 static int copy_from_creg_data(struct rsxx_cardinfo *card,
88 				int cnt8,
89 				void *buf,
90 				unsigned int stream)
91 {
92 	int i = 0;
93 	u32 *data = buf;
94 
95 	if (unlikely(card->eeh_state))
96 		return -EIO;
97 
98 	for (i = 0; cnt8 > 0; i++, cnt8 -= 4) {
99 		/*
100 		 * Firmware implementation makes it necessary to byte swap on
101 		 * little endian processors.
102 		 */
103 		if (LITTLE_ENDIAN && stream)
104 			data[i] = ioread32be(card->regmap + CREG_DATA(i));
105 		else
106 			data[i] = ioread32(card->regmap + CREG_DATA(i));
107 	}
108 
109 	return 0;
110 }
111 
creg_issue_cmd(struct rsxx_cardinfo * card,struct creg_cmd * cmd)112 static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd)
113 {
114 	int st;
115 
116 	if (unlikely(card->eeh_state))
117 		return;
118 
119 	iowrite32(cmd->addr, card->regmap + CREG_ADD);
120 	iowrite32(cmd->cnt8, card->regmap + CREG_CNT);
121 
122 	if (cmd->op == CREG_OP_WRITE) {
123 		if (cmd->buf) {
124 			st = copy_to_creg_data(card, cmd->cnt8,
125 					       cmd->buf, cmd->stream);
126 			if (st)
127 				return;
128 		}
129 	}
130 
131 	if (unlikely(card->eeh_state))
132 		return;
133 
134 	/* Setting the valid bit will kick off the command. */
135 	iowrite32(cmd->op, card->regmap + CREG_CMD);
136 }
137 
creg_kick_queue(struct rsxx_cardinfo * card)138 static void creg_kick_queue(struct rsxx_cardinfo *card)
139 {
140 	if (card->creg_ctrl.active || list_empty(&card->creg_ctrl.queue))
141 		return;
142 
143 	card->creg_ctrl.active = 1;
144 	card->creg_ctrl.active_cmd = list_first_entry(&card->creg_ctrl.queue,
145 						      struct creg_cmd, list);
146 	list_del(&card->creg_ctrl.active_cmd->list);
147 	card->creg_ctrl.q_depth--;
148 
149 	/*
150 	 * We have to set the timer before we push the new command. Otherwise,
151 	 * we could create a race condition that would occur if the timer
152 	 * was not canceled, and expired after the new command was pushed,
153 	 * but before the command was issued to hardware.
154 	 */
155 	mod_timer(&card->creg_ctrl.cmd_timer,
156 				jiffies + msecs_to_jiffies(CREG_TIMEOUT_MSEC));
157 
158 	creg_issue_cmd(card, card->creg_ctrl.active_cmd);
159 }
160 
creg_queue_cmd(struct rsxx_cardinfo * card,unsigned int op,unsigned int addr,unsigned int cnt8,void * buf,int stream,creg_cmd_cb callback,void * cb_private)161 static int creg_queue_cmd(struct rsxx_cardinfo *card,
162 			  unsigned int op,
163 			  unsigned int addr,
164 			  unsigned int cnt8,
165 			  void *buf,
166 			  int stream,
167 			  creg_cmd_cb callback,
168 			  void *cb_private)
169 {
170 	struct creg_cmd *cmd;
171 
172 	/* Don't queue stuff up if we're halted. */
173 	if (unlikely(card->halt))
174 		return -EINVAL;
175 
176 	if (card->creg_ctrl.reset)
177 		return -EAGAIN;
178 
179 	if (cnt8 > MAX_CREG_DATA8)
180 		return -EINVAL;
181 
182 	cmd = kmem_cache_alloc(creg_cmd_pool, GFP_KERNEL);
183 	if (!cmd)
184 		return -ENOMEM;
185 
186 	INIT_LIST_HEAD(&cmd->list);
187 
188 	cmd->op		= op;
189 	cmd->addr	= addr;
190 	cmd->cnt8	= cnt8;
191 	cmd->buf	= buf;
192 	cmd->stream	= stream;
193 	cmd->cb		= callback;
194 	cmd->cb_private = cb_private;
195 	cmd->status	= 0;
196 
197 	spin_lock_bh(&card->creg_ctrl.lock);
198 	list_add_tail(&cmd->list, &card->creg_ctrl.queue);
199 	card->creg_ctrl.q_depth++;
200 	creg_kick_queue(card);
201 	spin_unlock_bh(&card->creg_ctrl.lock);
202 
203 	return 0;
204 }
205 
creg_cmd_timed_out(unsigned long data)206 static void creg_cmd_timed_out(unsigned long data)
207 {
208 	struct rsxx_cardinfo *card = (struct rsxx_cardinfo *) data;
209 	struct creg_cmd *cmd;
210 
211 	spin_lock(&card->creg_ctrl.lock);
212 	cmd = card->creg_ctrl.active_cmd;
213 	card->creg_ctrl.active_cmd = NULL;
214 	spin_unlock(&card->creg_ctrl.lock);
215 
216 	if (cmd == NULL) {
217 		card->creg_ctrl.creg_stats.creg_timeout++;
218 		dev_warn(CARD_TO_DEV(card),
219 			"No active command associated with timeout!\n");
220 		return;
221 	}
222 
223 	if (cmd->cb)
224 		cmd->cb(card, cmd, -ETIMEDOUT);
225 
226 	kmem_cache_free(creg_cmd_pool, cmd);
227 
228 
229 	spin_lock(&card->creg_ctrl.lock);
230 	card->creg_ctrl.active = 0;
231 	creg_kick_queue(card);
232 	spin_unlock(&card->creg_ctrl.lock);
233 }
234 
235 
creg_cmd_done(struct work_struct * work)236 static void creg_cmd_done(struct work_struct *work)
237 {
238 	struct rsxx_cardinfo *card;
239 	struct creg_cmd *cmd;
240 	int st = 0;
241 
242 	card = container_of(work, struct rsxx_cardinfo,
243 			    creg_ctrl.done_work);
244 
245 	/*
246 	 * The timer could not be cancelled for some reason,
247 	 * race to pop the active command.
248 	 */
249 	if (del_timer_sync(&card->creg_ctrl.cmd_timer) == 0)
250 		card->creg_ctrl.creg_stats.failed_cancel_timer++;
251 
252 	spin_lock_bh(&card->creg_ctrl.lock);
253 	cmd = card->creg_ctrl.active_cmd;
254 	card->creg_ctrl.active_cmd = NULL;
255 	spin_unlock_bh(&card->creg_ctrl.lock);
256 
257 	if (cmd == NULL) {
258 		dev_err(CARD_TO_DEV(card),
259 			"Spurious creg interrupt!\n");
260 		return;
261 	}
262 
263 	card->creg_ctrl.creg_stats.stat = ioread32(card->regmap + CREG_STAT);
264 	cmd->status = card->creg_ctrl.creg_stats.stat;
265 	if ((cmd->status & CREG_STAT_STATUS_MASK) == 0) {
266 		dev_err(CARD_TO_DEV(card),
267 			"Invalid status on creg command\n");
268 		/*
269 		 * At this point we're probably reading garbage from HW. Don't
270 		 * do anything else that could mess up the system and let
271 		 * the sync function return an error.
272 		 */
273 		st = -EIO;
274 		goto creg_done;
275 	} else if (cmd->status & CREG_STAT_ERROR) {
276 		st = -EIO;
277 	}
278 
279 	if ((cmd->op == CREG_OP_READ)) {
280 		unsigned int cnt8 = ioread32(card->regmap + CREG_CNT);
281 
282 		/* Paranoid Sanity Checks */
283 		if (!cmd->buf) {
284 			dev_err(CARD_TO_DEV(card),
285 				"Buffer not given for read.\n");
286 			st = -EIO;
287 			goto creg_done;
288 		}
289 		if (cnt8 != cmd->cnt8) {
290 			dev_err(CARD_TO_DEV(card),
291 				"count mismatch\n");
292 			st = -EIO;
293 			goto creg_done;
294 		}
295 
296 		st = copy_from_creg_data(card, cnt8, cmd->buf, cmd->stream);
297 	}
298 
299 creg_done:
300 	if (cmd->cb)
301 		cmd->cb(card, cmd, st);
302 
303 	kmem_cache_free(creg_cmd_pool, cmd);
304 
305 	spin_lock_bh(&card->creg_ctrl.lock);
306 	card->creg_ctrl.active = 0;
307 	creg_kick_queue(card);
308 	spin_unlock_bh(&card->creg_ctrl.lock);
309 }
310 
creg_reset(struct rsxx_cardinfo * card)311 static void creg_reset(struct rsxx_cardinfo *card)
312 {
313 	struct creg_cmd *cmd = NULL;
314 	struct creg_cmd *tmp;
315 	unsigned long flags;
316 
317 	/*
318 	 * mutex_trylock is used here because if reset_lock is taken then a
319 	 * reset is already happening. So, we can just go ahead and return.
320 	 */
321 	if (!mutex_trylock(&card->creg_ctrl.reset_lock))
322 		return;
323 
324 	card->creg_ctrl.reset = 1;
325 	spin_lock_irqsave(&card->irq_lock, flags);
326 	rsxx_disable_ier_and_isr(card, CR_INTR_CREG | CR_INTR_EVENT);
327 	spin_unlock_irqrestore(&card->irq_lock, flags);
328 
329 	dev_warn(CARD_TO_DEV(card),
330 		"Resetting creg interface for recovery\n");
331 
332 	/* Cancel outstanding commands */
333 	spin_lock_bh(&card->creg_ctrl.lock);
334 	list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) {
335 		list_del(&cmd->list);
336 		card->creg_ctrl.q_depth--;
337 		if (cmd->cb)
338 			cmd->cb(card, cmd, -ECANCELED);
339 		kmem_cache_free(creg_cmd_pool, cmd);
340 	}
341 
342 	cmd = card->creg_ctrl.active_cmd;
343 	card->creg_ctrl.active_cmd = NULL;
344 	if (cmd) {
345 		if (timer_pending(&card->creg_ctrl.cmd_timer))
346 			del_timer_sync(&card->creg_ctrl.cmd_timer);
347 
348 		if (cmd->cb)
349 			cmd->cb(card, cmd, -ECANCELED);
350 		kmem_cache_free(creg_cmd_pool, cmd);
351 
352 		card->creg_ctrl.active = 0;
353 	}
354 	spin_unlock_bh(&card->creg_ctrl.lock);
355 
356 	card->creg_ctrl.reset = 0;
357 	spin_lock_irqsave(&card->irq_lock, flags);
358 	rsxx_enable_ier_and_isr(card, CR_INTR_CREG | CR_INTR_EVENT);
359 	spin_unlock_irqrestore(&card->irq_lock, flags);
360 
361 	mutex_unlock(&card->creg_ctrl.reset_lock);
362 }
363 
364 /* Used for synchronous accesses */
365 struct creg_completion {
366 	struct completion	*cmd_done;
367 	int			st;
368 	u32			creg_status;
369 };
370 
creg_cmd_done_cb(struct rsxx_cardinfo * card,struct creg_cmd * cmd,int st)371 static void creg_cmd_done_cb(struct rsxx_cardinfo *card,
372 			     struct creg_cmd *cmd,
373 			     int st)
374 {
375 	struct creg_completion *cmd_completion;
376 
377 	cmd_completion = cmd->cb_private;
378 	BUG_ON(!cmd_completion);
379 
380 	cmd_completion->st = st;
381 	cmd_completion->creg_status = cmd->status;
382 	complete(cmd_completion->cmd_done);
383 }
384 
__issue_creg_rw(struct rsxx_cardinfo * card,unsigned int op,unsigned int addr,unsigned int cnt8,void * buf,int stream,unsigned int * hw_stat)385 static int __issue_creg_rw(struct rsxx_cardinfo *card,
386 			   unsigned int op,
387 			   unsigned int addr,
388 			   unsigned int cnt8,
389 			   void *buf,
390 			   int stream,
391 			   unsigned int *hw_stat)
392 {
393 	DECLARE_COMPLETION_ONSTACK(cmd_done);
394 	struct creg_completion completion;
395 	unsigned long timeout;
396 	int st;
397 
398 	completion.cmd_done = &cmd_done;
399 	completion.st = 0;
400 	completion.creg_status = 0;
401 
402 	st = creg_queue_cmd(card, op, addr, cnt8, buf, stream, creg_cmd_done_cb,
403 			    &completion);
404 	if (st)
405 		return st;
406 
407 	/*
408 	 * This timeout is necessary for unresponsive hardware. The additional
409 	 * 20 seconds to used to guarantee that each cregs requests has time to
410 	 * complete.
411 	 */
412 	timeout = msecs_to_jiffies(CREG_TIMEOUT_MSEC *
413 				   card->creg_ctrl.q_depth + 20000);
414 
415 	/*
416 	 * The creg interface is guaranteed to complete. It has a timeout
417 	 * mechanism that will kick in if hardware does not respond.
418 	 */
419 	st = wait_for_completion_timeout(completion.cmd_done, timeout);
420 	if (st == 0) {
421 		/*
422 		 * This is really bad, because the kernel timer did not
423 		 * expire and notify us of a timeout!
424 		 */
425 		dev_crit(CARD_TO_DEV(card),
426 			"cregs timer failed\n");
427 		creg_reset(card);
428 		return -EIO;
429 	}
430 
431 	*hw_stat = completion.creg_status;
432 
433 	if (completion.st) {
434 		/*
435 		* This read is needed to verify that there has not been any
436 		* extreme errors that might have occurred, i.e. EEH. The
437 		* function iowrite32 will not detect EEH errors, so it is
438 		* necessary that we recover if such an error is the reason
439 		* for the timeout. This is a dummy read.
440 		*/
441 		ioread32(card->regmap + SCRATCH);
442 
443 		dev_warn(CARD_TO_DEV(card),
444 			"creg command failed(%d x%08x)\n",
445 			completion.st, addr);
446 		return completion.st;
447 	}
448 
449 	return 0;
450 }
451 
issue_creg_rw(struct rsxx_cardinfo * card,u32 addr,unsigned int size8,void * data,int stream,int read)452 static int issue_creg_rw(struct rsxx_cardinfo *card,
453 			 u32 addr,
454 			 unsigned int size8,
455 			 void *data,
456 			 int stream,
457 			 int read)
458 {
459 	unsigned int hw_stat;
460 	unsigned int xfer;
461 	unsigned int op;
462 	int st;
463 
464 	op = read ? CREG_OP_READ : CREG_OP_WRITE;
465 
466 	do {
467 		xfer = min_t(unsigned int, size8, MAX_CREG_DATA8);
468 
469 		st = __issue_creg_rw(card, op, addr, xfer,
470 				     data, stream, &hw_stat);
471 		if (st)
472 			return st;
473 
474 		data   = (char *)data + xfer;
475 		addr  += xfer;
476 		size8 -= xfer;
477 	} while (size8);
478 
479 	return 0;
480 }
481 
482 /* ---------------------------- Public API ---------------------------------- */
rsxx_creg_write(struct rsxx_cardinfo * card,u32 addr,unsigned int size8,void * data,int byte_stream)483 int rsxx_creg_write(struct rsxx_cardinfo *card,
484 			u32 addr,
485 			unsigned int size8,
486 			void *data,
487 			int byte_stream)
488 {
489 	return issue_creg_rw(card, addr, size8, data, byte_stream, 0);
490 }
491 
rsxx_creg_read(struct rsxx_cardinfo * card,u32 addr,unsigned int size8,void * data,int byte_stream)492 int rsxx_creg_read(struct rsxx_cardinfo *card,
493 		       u32 addr,
494 		       unsigned int size8,
495 		       void *data,
496 		       int byte_stream)
497 {
498 	return issue_creg_rw(card, addr, size8, data, byte_stream, 1);
499 }
500 
rsxx_get_card_state(struct rsxx_cardinfo * card,unsigned int * state)501 int rsxx_get_card_state(struct rsxx_cardinfo *card, unsigned int *state)
502 {
503 	return rsxx_creg_read(card, CREG_ADD_CARD_STATE,
504 				  sizeof(*state), state, 0);
505 }
506 
rsxx_get_card_size8(struct rsxx_cardinfo * card,u64 * size8)507 int rsxx_get_card_size8(struct rsxx_cardinfo *card, u64 *size8)
508 {
509 	unsigned int size;
510 	int st;
511 
512 	st = rsxx_creg_read(card, CREG_ADD_CARD_SIZE,
513 				sizeof(size), &size, 0);
514 	if (st)
515 		return st;
516 
517 	*size8 = (u64)size * RSXX_HW_BLK_SIZE;
518 	return 0;
519 }
520 
rsxx_get_num_targets(struct rsxx_cardinfo * card,unsigned int * n_targets)521 int rsxx_get_num_targets(struct rsxx_cardinfo *card,
522 			     unsigned int *n_targets)
523 {
524 	return rsxx_creg_read(card, CREG_ADD_NUM_TARGETS,
525 				  sizeof(*n_targets), n_targets, 0);
526 }
527 
rsxx_get_card_capabilities(struct rsxx_cardinfo * card,u32 * capabilities)528 int rsxx_get_card_capabilities(struct rsxx_cardinfo *card,
529 				   u32 *capabilities)
530 {
531 	return rsxx_creg_read(card, CREG_ADD_CAPABILITIES,
532 				  sizeof(*capabilities), capabilities, 0);
533 }
534 
rsxx_issue_card_cmd(struct rsxx_cardinfo * card,u32 cmd)535 int rsxx_issue_card_cmd(struct rsxx_cardinfo *card, u32 cmd)
536 {
537 	return rsxx_creg_write(card, CREG_ADD_CARD_CMD,
538 				   sizeof(cmd), &cmd, 0);
539 }
540 
541 
542 /*----------------- HW Log Functions -------------------*/
hw_log_msg(struct rsxx_cardinfo * card,const char * str,int len)543 static void hw_log_msg(struct rsxx_cardinfo *card, const char *str, int len)
544 {
545 	static char level;
546 
547 	/*
548 	 * New messages start with "<#>", where # is the log level. Messages
549 	 * that extend past the log buffer will use the previous level
550 	 */
551 	if ((len > 3) && (str[0] == '<') && (str[2] == '>')) {
552 		level = str[1];
553 		str += 3; /* Skip past the log level. */
554 		len -= 3;
555 	}
556 
557 	switch (level) {
558 	case '0':
559 		dev_emerg(CARD_TO_DEV(card), "HW: %.*s", len, str);
560 		break;
561 	case '1':
562 		dev_alert(CARD_TO_DEV(card), "HW: %.*s", len, str);
563 		break;
564 	case '2':
565 		dev_crit(CARD_TO_DEV(card), "HW: %.*s", len, str);
566 		break;
567 	case '3':
568 		dev_err(CARD_TO_DEV(card), "HW: %.*s", len, str);
569 		break;
570 	case '4':
571 		dev_warn(CARD_TO_DEV(card), "HW: %.*s", len, str);
572 		break;
573 	case '5':
574 		dev_notice(CARD_TO_DEV(card), "HW: %.*s", len, str);
575 		break;
576 	case '6':
577 		dev_info(CARD_TO_DEV(card), "HW: %.*s", len, str);
578 		break;
579 	case '7':
580 		dev_dbg(CARD_TO_DEV(card), "HW: %.*s", len, str);
581 		break;
582 	default:
583 		dev_info(CARD_TO_DEV(card), "HW: %.*s", len, str);
584 		break;
585 	}
586 }
587 
588 /*
589  * The substrncpy function copies the src string (which includes the
590  * terminating '\0' character), up to the count into the dest pointer.
591  * Returns the number of bytes copied to dest.
592  */
substrncpy(char * dest,const char * src,int count)593 static int substrncpy(char *dest, const char *src, int count)
594 {
595 	int max_cnt = count;
596 
597 	while (count) {
598 		count--;
599 		*dest = *src;
600 		if (*dest == '\0')
601 			break;
602 		src++;
603 		dest++;
604 	}
605 	return max_cnt - count;
606 }
607 
608 
read_hw_log_done(struct rsxx_cardinfo * card,struct creg_cmd * cmd,int st)609 static void read_hw_log_done(struct rsxx_cardinfo *card,
610 			     struct creg_cmd *cmd,
611 			     int st)
612 {
613 	char *buf;
614 	char *log_str;
615 	int cnt;
616 	int len;
617 	int off;
618 
619 	buf = cmd->buf;
620 	off = 0;
621 
622 	/* Failed getting the log message */
623 	if (st)
624 		return;
625 
626 	while (off < cmd->cnt8) {
627 		log_str = &card->log.buf[card->log.buf_len];
628 		cnt = min(cmd->cnt8 - off, LOG_BUF_SIZE8 - card->log.buf_len);
629 		len = substrncpy(log_str, &buf[off], cnt);
630 
631 		off += len;
632 		card->log.buf_len += len;
633 
634 		/*
635 		 * Flush the log if we've hit the end of a message or if we've
636 		 * run out of buffer space.
637 		 */
638 		if ((log_str[len - 1] == '\0')  ||
639 		    (card->log.buf_len == LOG_BUF_SIZE8)) {
640 			if (card->log.buf_len != 1) /* Don't log blank lines. */
641 				hw_log_msg(card, card->log.buf,
642 					   card->log.buf_len);
643 			card->log.buf_len = 0;
644 		}
645 
646 	}
647 
648 	if (cmd->status & CREG_STAT_LOG_PENDING)
649 		rsxx_read_hw_log(card);
650 }
651 
rsxx_read_hw_log(struct rsxx_cardinfo * card)652 int rsxx_read_hw_log(struct rsxx_cardinfo *card)
653 {
654 	int st;
655 
656 	st = creg_queue_cmd(card, CREG_OP_READ, CREG_ADD_LOG,
657 			    sizeof(card->log.tmp), card->log.tmp,
658 			    1, read_hw_log_done, NULL);
659 	if (st)
660 		dev_err(CARD_TO_DEV(card),
661 			"Failed getting log text\n");
662 
663 	return st;
664 }
665 
666 /*-------------- IOCTL REG Access ------------------*/
issue_reg_cmd(struct rsxx_cardinfo * card,struct rsxx_reg_access * cmd,int read)667 static int issue_reg_cmd(struct rsxx_cardinfo *card,
668 			 struct rsxx_reg_access *cmd,
669 			 int read)
670 {
671 	unsigned int op = read ? CREG_OP_READ : CREG_OP_WRITE;
672 
673 	return __issue_creg_rw(card, op, cmd->addr, cmd->cnt, cmd->data,
674 			       cmd->stream, &cmd->stat);
675 }
676 
rsxx_reg_access(struct rsxx_cardinfo * card,struct rsxx_reg_access __user * ucmd,int read)677 int rsxx_reg_access(struct rsxx_cardinfo *card,
678 			struct rsxx_reg_access __user *ucmd,
679 			int read)
680 {
681 	struct rsxx_reg_access cmd;
682 	int st;
683 
684 	st = copy_from_user(&cmd, ucmd, sizeof(cmd));
685 	if (st)
686 		return -EFAULT;
687 
688 	if (cmd.cnt > RSXX_MAX_REG_CNT)
689 		return -EFAULT;
690 
691 	st = issue_reg_cmd(card, &cmd, read);
692 	if (st)
693 		return st;
694 
695 	st = put_user(cmd.stat, &ucmd->stat);
696 	if (st)
697 		return -EFAULT;
698 
699 	if (read) {
700 		st = copy_to_user(ucmd->data, cmd.data, cmd.cnt);
701 		if (st)
702 			return -EFAULT;
703 	}
704 
705 	return 0;
706 }
707 
rsxx_eeh_save_issued_creg(struct rsxx_cardinfo * card)708 void rsxx_eeh_save_issued_creg(struct rsxx_cardinfo *card)
709 {
710 	struct creg_cmd *cmd = NULL;
711 
712 	cmd = card->creg_ctrl.active_cmd;
713 	card->creg_ctrl.active_cmd = NULL;
714 
715 	if (cmd) {
716 		del_timer_sync(&card->creg_ctrl.cmd_timer);
717 
718 		spin_lock_bh(&card->creg_ctrl.lock);
719 		list_add(&cmd->list, &card->creg_ctrl.queue);
720 		card->creg_ctrl.q_depth++;
721 		card->creg_ctrl.active = 0;
722 		spin_unlock_bh(&card->creg_ctrl.lock);
723 	}
724 }
725 
rsxx_kick_creg_queue(struct rsxx_cardinfo * card)726 void rsxx_kick_creg_queue(struct rsxx_cardinfo *card)
727 {
728 	spin_lock_bh(&card->creg_ctrl.lock);
729 	if (!list_empty(&card->creg_ctrl.queue))
730 		creg_kick_queue(card);
731 	spin_unlock_bh(&card->creg_ctrl.lock);
732 }
733 
734 /*------------ Initialization & Setup --------------*/
rsxx_creg_setup(struct rsxx_cardinfo * card)735 int rsxx_creg_setup(struct rsxx_cardinfo *card)
736 {
737 	card->creg_ctrl.active_cmd = NULL;
738 
739 	card->creg_ctrl.creg_wq =
740 			create_singlethread_workqueue(DRIVER_NAME"_creg");
741 	if (!card->creg_ctrl.creg_wq)
742 		return -ENOMEM;
743 
744 	INIT_WORK(&card->creg_ctrl.done_work, creg_cmd_done);
745 	mutex_init(&card->creg_ctrl.reset_lock);
746 	INIT_LIST_HEAD(&card->creg_ctrl.queue);
747 	spin_lock_init(&card->creg_ctrl.lock);
748 	setup_timer(&card->creg_ctrl.cmd_timer, creg_cmd_timed_out,
749 		    (unsigned long) card);
750 
751 	return 0;
752 }
753 
rsxx_creg_destroy(struct rsxx_cardinfo * card)754 void rsxx_creg_destroy(struct rsxx_cardinfo *card)
755 {
756 	struct creg_cmd *cmd;
757 	struct creg_cmd *tmp;
758 	int cnt = 0;
759 
760 	/* Cancel outstanding commands */
761 	spin_lock_bh(&card->creg_ctrl.lock);
762 	list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) {
763 		list_del(&cmd->list);
764 		if (cmd->cb)
765 			cmd->cb(card, cmd, -ECANCELED);
766 		kmem_cache_free(creg_cmd_pool, cmd);
767 		cnt++;
768 	}
769 
770 	if (cnt)
771 		dev_info(CARD_TO_DEV(card),
772 			"Canceled %d queue creg commands\n", cnt);
773 
774 	cmd = card->creg_ctrl.active_cmd;
775 	card->creg_ctrl.active_cmd = NULL;
776 	if (cmd) {
777 		if (timer_pending(&card->creg_ctrl.cmd_timer))
778 			del_timer_sync(&card->creg_ctrl.cmd_timer);
779 
780 		if (cmd->cb)
781 			cmd->cb(card, cmd, -ECANCELED);
782 		dev_info(CARD_TO_DEV(card),
783 			"Canceled active creg command\n");
784 		kmem_cache_free(creg_cmd_pool, cmd);
785 	}
786 	spin_unlock_bh(&card->creg_ctrl.lock);
787 
788 	cancel_work_sync(&card->creg_ctrl.done_work);
789 }
790 
791 
rsxx_creg_init(void)792 int rsxx_creg_init(void)
793 {
794 	creg_cmd_pool = KMEM_CACHE(creg_cmd, SLAB_HWCACHE_ALIGN);
795 	if (!creg_cmd_pool)
796 		return -ENOMEM;
797 
798 	return 0;
799 }
800 
rsxx_creg_cleanup(void)801 void rsxx_creg_cleanup(void)
802 {
803 	kmem_cache_destroy(creg_cmd_pool);
804 }
805