cregs.c revision c206c70924737db6836382c09ad2dacd04bb6204
18722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com/* 28722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* Filename: cregs.c 38722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* 48722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* 58722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* Authors: Joshua Morris <josh.h.morris@us.ibm.com> 68722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* Philip Kelleher <pjk1939@linux.vnet.ibm.com> 78722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* 88722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* (C) Copyright 2013 IBM Corporation 98722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* 108722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* This program is free software; you can redistribute it and/or 118722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* modify it under the terms of the GNU General Public License as 128722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* published by the Free Software Foundation; either version 2 of the 138722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* License, or (at your option) any later version. 148722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* 158722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* This program is distributed in the hope that it will be useful, but 168722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* WITHOUT ANY WARRANTY; without even the implied warranty of 178722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 188722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* General Public License for more details. 198722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* 208722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* You should have received a copy of the GNU General Public License 218722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* along with this program; if not, write to the Free Software Foundation, 228722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 238722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com*/ 248722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 258722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#include <linux/completion.h> 268722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#include <linux/slab.h> 278722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 288722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#include "rsxx_priv.h" 298722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 308722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#define CREG_TIMEOUT_MSEC 10000 318722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 328722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comtypedef void (*creg_cmd_cb)(struct rsxx_cardinfo *card, 338722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *cmd, 348722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int st); 358722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 368722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstruct creg_cmd { 378722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct list_head list; 388722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com creg_cmd_cb cb; 398722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com void *cb_private; 408722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int op; 418722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int addr; 428722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int cnt8; 438722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com void *buf; 448722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int stream; 458722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int status; 468722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com}; 478722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 488722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic struct kmem_cache *creg_cmd_pool; 498722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 508722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 518722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com/*------------ Private Functions --------------*/ 528722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 538722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#if defined(__LITTLE_ENDIAN) 548722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#define LITTLE_ENDIAN 1 558722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#elif defined(__BIG_ENDIAN) 568722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#define LITTLE_ENDIAN 0 578722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#else 588722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#error Unknown endianess!!! Aborting... 598722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com#endif 608722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 618722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic void copy_to_creg_data(struct rsxx_cardinfo *card, 628722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int cnt8, 638722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com void *buf, 648722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int stream) 658722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 668722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int i = 0; 678722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com u32 *data = buf; 688722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 698722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com for (i = 0; cnt8 > 0; i++, cnt8 -= 4) { 708722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* 718722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * Firmware implementation makes it necessary to byte swap on 728722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * little endian processors. 738722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 748722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (LITTLE_ENDIAN && stream) 758722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com iowrite32be(data[i], card->regmap + CREG_DATA(i)); 768722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com else 778722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com iowrite32(data[i], card->regmap + CREG_DATA(i)); 788722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 798722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 808722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 818722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 828722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic void copy_from_creg_data(struct rsxx_cardinfo *card, 838722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int cnt8, 848722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com void *buf, 858722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int stream) 868722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 878722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int i = 0; 888722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com u32 *data = buf; 898722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 908722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com for (i = 0; cnt8 > 0; i++, cnt8 -= 4) { 918722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* 928722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * Firmware implementation makes it necessary to byte swap on 938722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * little endian processors. 948722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 958722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (LITTLE_ENDIAN && stream) 968722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com data[i] = ioread32be(card->regmap + CREG_DATA(i)); 978722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com else 988722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com data[i] = ioread32(card->regmap + CREG_DATA(i)); 998722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 1008722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 1018722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1028722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic struct creg_cmd *pop_active_cmd(struct rsxx_cardinfo *card) 1038722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 1048722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *cmd; 1058722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1068722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* 1078722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * Spin lock is needed because this can be called in atomic/interrupt 1088722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * context. 1098722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 110c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_lock_bh(&card->creg_ctrl.lock); 1118722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd = card->creg_ctrl.active_cmd; 1128722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.active_cmd = NULL; 113c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_unlock_bh(&card->creg_ctrl.lock); 1148722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1158722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return cmd; 1168722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 1178722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1188722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd) 1198722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 1208722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com iowrite32(cmd->addr, card->regmap + CREG_ADD); 1218722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com iowrite32(cmd->cnt8, card->regmap + CREG_CNT); 1228722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1238722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd->op == CREG_OP_WRITE) { 1248722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd->buf) 1258722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com copy_to_creg_data(card, cmd->cnt8, 1268722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->buf, cmd->stream); 1278722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 1288722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 129c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher /* 130c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * Data copy must complete before initiating the command. This is 131c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * needed for weakly ordered processors (i.e. PowerPC), so that all 132c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * neccessary registers are written before we kick the hardware. 133c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher */ 1348722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com wmb(); 1358722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1368722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* Setting the valid bit will kick off the command. */ 1378722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com iowrite32(cmd->op, card->regmap + CREG_CMD); 1388722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 1398722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1408722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic void creg_kick_queue(struct rsxx_cardinfo *card) 1418722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 1428722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (card->creg_ctrl.active || list_empty(&card->creg_ctrl.queue)) 1438722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return; 1448722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1458722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.active = 1; 1468722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.active_cmd = list_first_entry(&card->creg_ctrl.queue, 1478722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd, list); 1488722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com list_del(&card->creg_ctrl.active_cmd->list); 1498722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.q_depth--; 1508722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1518722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* 1528722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * We have to set the timer before we push the new command. Otherwise, 1538722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * we could create a race condition that would occur if the timer 1548722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * was not canceled, and expired after the new command was pushed, 1558722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * but before the command was issued to hardware. 1568722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 1578722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com mod_timer(&card->creg_ctrl.cmd_timer, 1588722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com jiffies + msecs_to_jiffies(CREG_TIMEOUT_MSEC)); 1598722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1608722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com creg_issue_cmd(card, card->creg_ctrl.active_cmd); 1618722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 1628722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1638722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic int creg_queue_cmd(struct rsxx_cardinfo *card, 1648722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int op, 1658722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int addr, 1668722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int cnt8, 1678722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com void *buf, 1688722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int stream, 1698722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com creg_cmd_cb callback, 1708722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com void *cb_private) 1718722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 1728722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *cmd; 1738722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1748722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* Don't queue stuff up if we're halted. */ 1758722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (unlikely(card->halt)) 1768722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return -EINVAL; 1778722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1788722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (card->creg_ctrl.reset) 1798722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return -EAGAIN; 1808722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1818722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cnt8 > MAX_CREG_DATA8) 1828722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return -EINVAL; 1838722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1848722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd = kmem_cache_alloc(creg_cmd_pool, GFP_KERNEL); 1858722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (!cmd) 1868722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return -ENOMEM; 1878722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1888722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com INIT_LIST_HEAD(&cmd->list); 1898722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1908722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->op = op; 1918722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->addr = addr; 1928722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->cnt8 = cnt8; 1938722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->buf = buf; 1948722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->stream = stream; 1958722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->cb = callback; 1968722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->cb_private = cb_private; 1978722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->status = 0; 1988722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 199c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_lock(&card->creg_ctrl.lock); 2008722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com list_add_tail(&cmd->list, &card->creg_ctrl.queue); 2018722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.q_depth++; 2028722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com creg_kick_queue(card); 203c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_unlock(&card->creg_ctrl.lock); 2048722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2058722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return 0; 2068722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 2078722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2088722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic void creg_cmd_timed_out(unsigned long data) 2098722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 2108722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct rsxx_cardinfo *card = (struct rsxx_cardinfo *) data; 2118722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *cmd; 2128722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2138722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd = pop_active_cmd(card); 2148722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd == NULL) { 2158722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.creg_stats.creg_timeout++; 2168722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_warn(CARD_TO_DEV(card), 2178722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "No active command associated with timeout!\n"); 2188722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return; 2198722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 2208722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2218722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd->cb) 2228722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->cb(card, cmd, -ETIMEDOUT); 2238722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2248722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com kmem_cache_free(creg_cmd_pool, cmd); 2258722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 226c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher 227c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_lock(&card->creg_ctrl.lock); 2288722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.active = 0; 2298722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com creg_kick_queue(card); 230c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_unlock(&card->creg_ctrl.lock); 2318722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 2328722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2338722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2348722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic void creg_cmd_done(struct work_struct *work) 2358722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 2368722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct rsxx_cardinfo *card; 2378722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *cmd; 2388722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int st = 0; 2398722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2408722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card = container_of(work, struct rsxx_cardinfo, 2418722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com creg_ctrl.done_work); 2428722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2438722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* 2448722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * The timer could not be cancelled for some reason, 2458722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * race to pop the active command. 2468722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 2478722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (del_timer_sync(&card->creg_ctrl.cmd_timer) == 0) 2488722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.creg_stats.failed_cancel_timer++; 2498722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2508722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd = pop_active_cmd(card); 2518722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd == NULL) { 2528722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_err(CARD_TO_DEV(card), 2538722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "Spurious creg interrupt!\n"); 2548722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return; 2558722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 2568722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2578722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.creg_stats.stat = ioread32(card->regmap + CREG_STAT); 2588722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->status = card->creg_ctrl.creg_stats.stat; 2598722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if ((cmd->status & CREG_STAT_STATUS_MASK) == 0) { 2608722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_err(CARD_TO_DEV(card), 2618722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "Invalid status on creg command\n"); 2628722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* 2638722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * At this point we're probably reading garbage from HW. Don't 2648722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * do anything else that could mess up the system and let 2658722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * the sync function return an error. 2668722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 2678722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = -EIO; 2688722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com goto creg_done; 2698722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } else if (cmd->status & CREG_STAT_ERROR) { 2708722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = -EIO; 2718722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 2728722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2738722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if ((cmd->op == CREG_OP_READ)) { 2748722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int cnt8 = ioread32(card->regmap + CREG_CNT); 2758722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2768722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* Paranoid Sanity Checks */ 2778722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (!cmd->buf) { 2788722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_err(CARD_TO_DEV(card), 2798722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "Buffer not given for read.\n"); 2808722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = -EIO; 2818722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com goto creg_done; 2828722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 2838722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cnt8 != cmd->cnt8) { 2848722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_err(CARD_TO_DEV(card), 2858722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "count mismatch\n"); 2868722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = -EIO; 2878722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com goto creg_done; 2888722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 2898722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2908722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com copy_from_creg_data(card, cnt8, cmd->buf, cmd->stream); 2918722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 2928722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2938722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comcreg_done: 2948722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd->cb) 2958722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->cb(card, cmd, st); 2968722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 2978722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com kmem_cache_free(creg_cmd_pool, cmd); 2988722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 299c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_lock(&card->creg_ctrl.lock); 3008722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.active = 0; 3018722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com creg_kick_queue(card); 302c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_unlock(&card->creg_ctrl.lock); 3038722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 3048722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3058722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic void creg_reset(struct rsxx_cardinfo *card) 3068722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 3078722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *cmd = NULL; 3088722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *tmp; 3098722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned long flags; 3108722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 311c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher /* 312c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * mutex_trylock is used here because if reset_lock is taken then a 313c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * reset is already happening. So, we can just go ahead and return. 314c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher */ 3158722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (!mutex_trylock(&card->creg_ctrl.reset_lock)) 3168722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return; 3178722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3188722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.reset = 1; 3198722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com spin_lock_irqsave(&card->irq_lock, flags); 3208722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com rsxx_disable_ier_and_isr(card, CR_INTR_CREG | CR_INTR_EVENT); 3218722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com spin_unlock_irqrestore(&card->irq_lock, flags); 3228722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3238722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_warn(CARD_TO_DEV(card), 3248722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "Resetting creg interface for recovery\n"); 3258722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3268722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* Cancel outstanding commands */ 327c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_lock(&card->creg_ctrl.lock); 3288722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) { 3298722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com list_del(&cmd->list); 3308722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.q_depth--; 3318722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd->cb) 3328722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->cb(card, cmd, -ECANCELED); 3338722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com kmem_cache_free(creg_cmd_pool, cmd); 3348722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 3358722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3368722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd = card->creg_ctrl.active_cmd; 3378722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.active_cmd = NULL; 3388722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd) { 3398722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (timer_pending(&card->creg_ctrl.cmd_timer)) 3408722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com del_timer_sync(&card->creg_ctrl.cmd_timer); 3418722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3428722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd->cb) 3438722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->cb(card, cmd, -ECANCELED); 3448722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com kmem_cache_free(creg_cmd_pool, cmd); 3458722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3468722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.active = 0; 3478722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 348c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_unlock(&card->creg_ctrl.lock); 3498722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3508722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.reset = 0; 3518722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com spin_lock_irqsave(&card->irq_lock, flags); 3528722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com rsxx_enable_ier_and_isr(card, CR_INTR_CREG | CR_INTR_EVENT); 3538722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com spin_unlock_irqrestore(&card->irq_lock, flags); 3548722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3558722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com mutex_unlock(&card->creg_ctrl.reset_lock); 3568722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 3578722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3588722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com/* Used for synchronous accesses */ 3598722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstruct creg_completion { 3608722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct completion *cmd_done; 3618722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int st; 3628722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com u32 creg_status; 3638722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com}; 3648722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3658722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic void creg_cmd_done_cb(struct rsxx_cardinfo *card, 3668722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *cmd, 3678722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int st) 3688722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 3698722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_completion *cmd_completion; 3708722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 371c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher cmd_completion = cmd->cb_private; 3728722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com BUG_ON(!cmd_completion); 3738722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3748722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd_completion->st = st; 3758722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd_completion->creg_status = cmd->status; 3768722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com complete(cmd_completion->cmd_done); 3778722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 3788722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3798722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic int __issue_creg_rw(struct rsxx_cardinfo *card, 3808722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int op, 3818722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int addr, 3828722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int cnt8, 3838722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com void *buf, 3848722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int stream, 3858722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int *hw_stat) 3868722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 3878722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com DECLARE_COMPLETION_ONSTACK(cmd_done); 3888722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_completion completion; 3898722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned long timeout; 3908722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int st; 3918722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3928722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com completion.cmd_done = &cmd_done; 3938722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com completion.st = 0; 3948722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com completion.creg_status = 0; 3958722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 3968722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = creg_queue_cmd(card, op, addr, cnt8, buf, stream, creg_cmd_done_cb, 3978722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com &completion); 3988722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (st) 3998722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return st; 4008722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 401c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher /* 402c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * This timeout is neccessary for unresponsive hardware. The additional 403c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * 20 seconds to used to guarantee that each cregs requests has time to 404c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * complete. 405c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher */ 4068722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com timeout = msecs_to_jiffies((CREG_TIMEOUT_MSEC * 407c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher card->creg_ctrl.q_depth) + 20000); 4088722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4098722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* 4108722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * The creg interface is guaranteed to complete. It has a timeout 4118722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * mechanism that will kick in if hardware does not respond. 4128722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 4138722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = wait_for_completion_timeout(completion.cmd_done, timeout); 4148722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (st == 0) { 4158722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* 4168722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * This is really bad, because the kernel timer did not 4178722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * expire and notify us of a timeout! 4188722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 4198722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_crit(CARD_TO_DEV(card), 4208722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "cregs timer failed\n"); 4218722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com creg_reset(card); 4228722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return -EIO; 4238722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 4248722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4258722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com *hw_stat = completion.creg_status; 4268722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4278722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (completion.st) { 4288722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_warn(CARD_TO_DEV(card), 4298722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "creg command failed(%d x%08x)\n", 4308722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com completion.st, addr); 4318722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return completion.st; 4328722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 4338722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4348722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return 0; 4358722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 4368722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4378722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic int issue_creg_rw(struct rsxx_cardinfo *card, 4388722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com u32 addr, 4398722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int size8, 4408722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com void *data, 4418722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int stream, 4428722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int read) 4438722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 4448722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int hw_stat; 4458722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int xfer; 4468722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int op; 4478722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int st; 4488722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4498722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com op = read ? CREG_OP_READ : CREG_OP_WRITE; 4508722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4518722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com do { 4528722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com xfer = min_t(unsigned int, size8, MAX_CREG_DATA8); 4538722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4548722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = __issue_creg_rw(card, op, addr, xfer, 4558722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com data, stream, &hw_stat); 4568722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (st) 4578722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return st; 4588722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 459c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher data = (char *)data + xfer; 4608722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com addr += xfer; 4618722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com size8 -= xfer; 4628722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } while (size8); 4638722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4648722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return 0; 4658722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 4668722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4678722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com/* ---------------------------- Public API ---------------------------------- */ 4688722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_creg_write(struct rsxx_cardinfo *card, 4698722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com u32 addr, 4708722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int size8, 4718722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com void *data, 4728722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int byte_stream) 4738722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 4748722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return issue_creg_rw(card, addr, size8, data, byte_stream, 0); 4758722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 4768722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4778722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_creg_read(struct rsxx_cardinfo *card, 4788722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com u32 addr, 4798722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int size8, 4808722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com void *data, 4818722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int byte_stream) 4828722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 4838722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return issue_creg_rw(card, addr, size8, data, byte_stream, 1); 4848722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 4858722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4868722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_get_card_state(struct rsxx_cardinfo *card, unsigned int *state) 4878722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 4888722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return rsxx_creg_read(card, CREG_ADD_CARD_STATE, 4898722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com sizeof(*state), state, 0); 4908722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 4918722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4928722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_get_card_size8(struct rsxx_cardinfo *card, u64 *size8) 4938722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 4948722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int size; 4958722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int st; 4968722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 4978722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = rsxx_creg_read(card, CREG_ADD_CARD_SIZE, 4988722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com sizeof(size), &size, 0); 4998722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (st) 5008722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return st; 5018722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5028722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com *size8 = (u64)size * RSXX_HW_BLK_SIZE; 5038722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return 0; 5048722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 5058722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5068722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_get_num_targets(struct rsxx_cardinfo *card, 5078722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int *n_targets) 5088722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 5098722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return rsxx_creg_read(card, CREG_ADD_NUM_TARGETS, 5108722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com sizeof(*n_targets), n_targets, 0); 5118722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 5128722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5138722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_get_card_capabilities(struct rsxx_cardinfo *card, 5148722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com u32 *capabilities) 5158722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 5168722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return rsxx_creg_read(card, CREG_ADD_CAPABILITIES, 5178722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com sizeof(*capabilities), capabilities, 0); 5188722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 5198722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5208722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_issue_card_cmd(struct rsxx_cardinfo *card, u32 cmd) 5218722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 5228722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return rsxx_creg_write(card, CREG_ADD_CARD_CMD, 5238722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com sizeof(cmd), &cmd, 0); 5248722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 5258722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5268722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5278722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com/*----------------- HW Log Functions -------------------*/ 5288722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic void hw_log_msg(struct rsxx_cardinfo *card, const char *str, int len) 5298722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 5308722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com static char level; 5318722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5328722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* 5338722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * New messages start with "<#>", where # is the log level. Messages 5348722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * that extend past the log buffer will use the previous level 5358722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 5368722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if ((len > 3) && (str[0] == '<') && (str[2] == '>')) { 5378722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com level = str[1]; 5388722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com str += 3; /* Skip past the log level. */ 5398722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com len -= 3; 5408722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 5418722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5428722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com switch (level) { 5438722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com case '0': 5448722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_emerg(CARD_TO_DEV(card), "HW: %.*s", len, str); 5458722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com break; 5468722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com case '1': 5478722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_alert(CARD_TO_DEV(card), "HW: %.*s", len, str); 5488722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com break; 5498722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com case '2': 5508722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_crit(CARD_TO_DEV(card), "HW: %.*s", len, str); 5518722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com break; 5528722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com case '3': 5538722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_err(CARD_TO_DEV(card), "HW: %.*s", len, str); 5548722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com break; 5558722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com case '4': 5568722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_warn(CARD_TO_DEV(card), "HW: %.*s", len, str); 5578722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com break; 5588722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com case '5': 5598722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_notice(CARD_TO_DEV(card), "HW: %.*s", len, str); 5608722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com break; 5618722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com case '6': 5628722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_info(CARD_TO_DEV(card), "HW: %.*s", len, str); 5638722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com break; 5648722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com case '7': 5658722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_dbg(CARD_TO_DEV(card), "HW: %.*s", len, str); 5668722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com break; 5678722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com default: 5688722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_info(CARD_TO_DEV(card), "HW: %.*s", len, str); 5698722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com break; 5708722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 5718722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 5728722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5738722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com/* 574c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * The substrncpy function copies the src string (which includes the 575c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * terminating '\0' character), up to the count into the dest pointer. 576c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher * Returns the number of bytes copied to dest. 5778722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 5788722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic int substrncpy(char *dest, const char *src, int count) 5798722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 5808722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int max_cnt = count; 5818722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5828722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com while (count) { 5838722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com count--; 5848722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com *dest = *src; 5858722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (*dest == '\0') 5868722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com break; 5878722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com src++; 5888722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dest++; 5898722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 5908722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return max_cnt - count; 5918722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 5928722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5938722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 5948722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic void read_hw_log_done(struct rsxx_cardinfo *card, 5958722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *cmd, 5968722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int st) 5978722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 5988722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com char *buf; 5998722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com char *log_str; 6008722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int cnt; 6018722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int len; 6028722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int off; 6038722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6048722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com buf = cmd->buf; 6058722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com off = 0; 6068722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6078722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* Failed getting the log message */ 6088722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (st) 6098722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return; 6108722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6118722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com while (off < cmd->cnt8) { 6128722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com log_str = &card->log.buf[card->log.buf_len]; 6138722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cnt = min(cmd->cnt8 - off, LOG_BUF_SIZE8 - card->log.buf_len); 6148722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com len = substrncpy(log_str, &buf[off], cnt); 6158722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6168722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com off += len; 6178722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->log.buf_len += len; 6188722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6198722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* 6208722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * Flush the log if we've hit the end of a message or if we've 6218722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com * run out of buffer space. 6228722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com */ 6238722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if ((log_str[len - 1] == '\0') || 6248722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com (card->log.buf_len == LOG_BUF_SIZE8)) { 6258722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (card->log.buf_len != 1) /* Don't log blank lines. */ 6268722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com hw_log_msg(card, card->log.buf, 6278722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->log.buf_len); 6288722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->log.buf_len = 0; 6298722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 6308722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6318722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 6328722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6338722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd->status & CREG_STAT_LOG_PENDING) 6348722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com rsxx_read_hw_log(card); 6358722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 6368722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6378722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_read_hw_log(struct rsxx_cardinfo *card) 6388722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 6398722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int st; 6408722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6418722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = creg_queue_cmd(card, CREG_OP_READ, CREG_ADD_LOG, 6428722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com sizeof(card->log.tmp), card->log.tmp, 6438722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 1, read_hw_log_done, NULL); 6448722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (st) 6458722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_err(CARD_TO_DEV(card), 6468722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "Failed getting log text\n"); 6478722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6488722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return st; 6498722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 6508722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6518722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com/*-------------- IOCTL REG Access ------------------*/ 6528722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comstatic int issue_reg_cmd(struct rsxx_cardinfo *card, 6538722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct rsxx_reg_access *cmd, 6548722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int read) 6558722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 6568722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com unsigned int op = read ? CREG_OP_READ : CREG_OP_WRITE; 6578722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6588722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return __issue_creg_rw(card, op, cmd->addr, cmd->cnt, cmd->data, 6598722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->stream, &cmd->stat); 6608722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 6618722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6628722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_reg_access(struct rsxx_cardinfo *card, 6638722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct rsxx_reg_access __user *ucmd, 6648722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int read) 6658722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 6668722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct rsxx_reg_access cmd; 6678722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int st; 6688722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6698722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = copy_from_user(&cmd, ucmd, sizeof(cmd)); 6708722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (st) 6718722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return -EFAULT; 6728722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 673c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher if (cmd.cnt > RSXX_MAX_REG_CNT) 674c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher return -EFAULT; 675c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher 6768722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = issue_reg_cmd(card, &cmd, read); 6778722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (st) 6788722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return st; 6798722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6808722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = put_user(cmd.stat, &ucmd->stat); 6818722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (st) 6828722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return -EFAULT; 6838722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6848722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (read) { 6858722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com st = copy_to_user(ucmd->data, cmd.data, cmd.cnt); 6868722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (st) 6878722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return -EFAULT; 6888722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 6898722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6908722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return 0; 6918722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 6928722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6938722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com/*------------ Initialization & Setup --------------*/ 6948722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_creg_setup(struct rsxx_cardinfo *card) 6958722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 6968722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.active_cmd = NULL; 6978722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 6988722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com INIT_WORK(&card->creg_ctrl.done_work, creg_cmd_done); 6998722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com mutex_init(&card->creg_ctrl.reset_lock); 7008722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com INIT_LIST_HEAD(&card->creg_ctrl.queue); 701c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_lock_init(&card->creg_ctrl.lock); 7028722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com setup_timer(&card->creg_ctrl.cmd_timer, creg_cmd_timed_out, 7038722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com (unsigned long) card); 7048722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7058722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return 0; 7068722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 7078722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7088722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comvoid rsxx_creg_destroy(struct rsxx_cardinfo *card) 7098722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 7108722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *cmd; 7118722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com struct creg_cmd *tmp; 7128722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com int cnt = 0; 7138722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7148722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com /* Cancel outstanding commands */ 715c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_lock(&card->creg_ctrl.lock); 7168722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) { 7178722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com list_del(&cmd->list); 7188722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd->cb) 7198722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->cb(card, cmd, -ECANCELED); 7208722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com kmem_cache_free(creg_cmd_pool, cmd); 7218722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cnt++; 7228722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 7238722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7248722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cnt) 7258722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_info(CARD_TO_DEV(card), 7268722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "Canceled %d queue creg commands\n", cnt); 7278722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7288722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd = card->creg_ctrl.active_cmd; 7298722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com card->creg_ctrl.active_cmd = NULL; 7308722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd) { 7318722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (timer_pending(&card->creg_ctrl.cmd_timer)) 7328722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com del_timer_sync(&card->creg_ctrl.cmd_timer); 7338722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7348722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (cmd->cb) 7358722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cmd->cb(card, cmd, -ECANCELED); 7368722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com dev_info(CARD_TO_DEV(card), 7378722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com "Canceled active creg command\n"); 7388722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com kmem_cache_free(creg_cmd_pool, cmd); 7398722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com } 740c206c70924737db6836382c09ad2dacd04bb6204Philip J Kelleher spin_unlock(&card->creg_ctrl.lock); 7418722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7428722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com cancel_work_sync(&card->creg_ctrl.done_work); 7438722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 7448722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7458722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7468722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comint rsxx_creg_init(void) 7478722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 7488722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com creg_cmd_pool = KMEM_CACHE(creg_cmd, SLAB_HWCACHE_ALIGN); 7498722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com if (!creg_cmd_pool) 7508722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return -ENOMEM; 7518722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7528722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com return 0; 7538722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 7548722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com 7558722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.comvoid rsxx_creg_cleanup(void) 7568722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com{ 7578722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com kmem_cache_destroy(creg_cmd_pool); 7588722ff8cdbfac9c1b20e67bb067b455c48cb8e93josh.h.morris@us.ibm.com} 759