saa7164-cmd.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. /*
  2. * Driver for the NXP SAA7164 PCIe bridge
  3. *
  4. * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. *
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include <linux/wait.h>
  22. #include "saa7164.h"
  23. int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
  24. {
  25. int i, ret = -1;
  26. mutex_lock(&dev->lock);
  27. for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
  28. if (dev->cmds[i].inuse == 0) {
  29. dev->cmds[i].inuse = 1;
  30. dev->cmds[i].signalled = 0;
  31. dev->cmds[i].timeout = 0;
  32. ret = dev->cmds[i].seqno;
  33. break;
  34. }
  35. }
  36. mutex_unlock(&dev->lock);
  37. return ret;
  38. }
  39. void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
  40. {
  41. mutex_lock(&dev->lock);
  42. if ((dev->cmds[seqno].inuse == 1) &&
  43. (dev->cmds[seqno].seqno == seqno)) {
  44. dev->cmds[seqno].inuse = 0;
  45. dev->cmds[seqno].signalled = 0;
  46. dev->cmds[seqno].timeout = 0;
  47. }
  48. mutex_unlock(&dev->lock);
  49. }
  50. void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
  51. {
  52. mutex_lock(&dev->lock);
  53. if ((dev->cmds[seqno].inuse == 1) &&
  54. (dev->cmds[seqno].seqno == seqno)) {
  55. dev->cmds[seqno].timeout = 1;
  56. }
  57. mutex_unlock(&dev->lock);
  58. }
  59. u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
  60. {
  61. int ret = 0;
  62. mutex_lock(&dev->lock);
  63. if ((dev->cmds[seqno].inuse == 1) &&
  64. (dev->cmds[seqno].seqno == seqno)) {
  65. ret = dev->cmds[seqno].timeout;
  66. }
  67. mutex_unlock(&dev->lock);
  68. return ret;
  69. }
  70. /* Commands to the f/w get marshelled to/from this code then onto the PCI
  71. * -bus/c running buffer. */
  72. int saa7164_cmd_dequeue(struct saa7164_dev *dev)
  73. {
  74. int loop = 1;
  75. int ret;
  76. u32 timeout;
  77. wait_queue_head_t *q = 0;
  78. u8 tmp[512];
  79. dprintk(DBGLVL_CMD, "%s()\n", __func__);
  80. while (loop) {
  81. tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
  82. ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
  83. if (ret == SAA_ERR_EMPTY)
  84. return SAA_OK;
  85. if (ret != SAA_OK)
  86. return ret;
  87. q = &dev->cmds[tRsp.seqno].wait;
  88. timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
  89. dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
  90. if (timeout) {
  91. printk(KERN_ERR "found timed out command on the bus\n");
  92. /* Clean the bus */
  93. ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
  94. printk(KERN_ERR "ret = %x\n", ret);
  95. if (ret == SAA_ERR_EMPTY)
  96. /* Someone else already fetched the response */
  97. return SAA_OK;
  98. if (ret != SAA_OK)
  99. return ret;
  100. if (tRsp.flags & PVC_CMDFLAG_CONTINUE)
  101. printk(KERN_ERR "split response\n");
  102. else
  103. saa7164_cmd_free_seqno(dev, tRsp.seqno);
  104. printk(KERN_ERR " timeout continue\n");
  105. continue;
  106. }
  107. dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
  108. __func__, tRsp.seqno);
  109. dev->cmds[tRsp.seqno].signalled = 1;
  110. wake_up(q);
  111. return SAA_OK;
  112. }
  113. return SAA_OK;
  114. }
  115. int saa7164_cmd_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
  116. {
  117. tmComResBusInfo_t *bus = &dev->bus;
  118. u8 cmd_sent;
  119. u16 size, idx;
  120. u32 cmds;
  121. void *tmp;
  122. int ret = -1;
  123. if (!msg) {
  124. printk(KERN_ERR "%s() !msg\n", __func__);
  125. return SAA_ERR_BAD_PARAMETER;
  126. }
  127. mutex_lock(&dev->cmds[msg->id].lock);
  128. size = msg->size;
  129. idx = 0;
  130. cmds = size / bus->m_wMaxReqSize;
  131. if (size % bus->m_wMaxReqSize == 0)
  132. cmds -= 1;
  133. cmd_sent = 0;
  134. /* Split the request into smaller chunks */
  135. for (idx = 0; idx < cmds; idx++) {
  136. msg->flags |= SAA_CMDFLAG_CONTINUE;
  137. msg->size = bus->m_wMaxReqSize;
  138. tmp = buf + idx * bus->m_wMaxReqSize;
  139. ret = saa7164_bus_set(dev, msg, tmp);
  140. if (ret != SAA_OK) {
  141. printk(KERN_ERR "%s() set failed %d\n", __func__, ret);
  142. if (cmd_sent) {
  143. ret = SAA_ERR_BUSY;
  144. goto out;
  145. }
  146. ret = SAA_ERR_OVERFLOW;
  147. goto out;
  148. }
  149. cmd_sent = 1;
  150. }
  151. /* If not the last command... */
  152. if (idx != 0)
  153. msg->flags &= ~SAA_CMDFLAG_CONTINUE;
  154. msg->size = size - idx * bus->m_wMaxReqSize;
  155. ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize);
  156. if (ret != SAA_OK) {
  157. printk(KERN_ERR "%s() set last failed %d\n", __func__, ret);
  158. if (cmd_sent) {
  159. ret = SAA_ERR_BUSY;
  160. goto out;
  161. }
  162. ret = SAA_ERR_OVERFLOW;
  163. goto out;
  164. }
  165. ret = SAA_OK;
  166. out:
  167. mutex_unlock(&dev->cmds[msg->id].lock);
  168. return ret;
  169. }
  170. /* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
  171. * the event never occured, or SAA_OK if it was signaled during the wait.
  172. */
  173. int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
  174. {
  175. wait_queue_head_t *q = 0;
  176. int ret = SAA_BUS_TIMEOUT;
  177. unsigned long stamp;
  178. int r;
  179. if (debug >= 4)
  180. saa7164_bus_dump(dev);
  181. dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno);
  182. mutex_lock(&dev->lock);
  183. if ((dev->cmds[seqno].inuse == 1) &&
  184. (dev->cmds[seqno].seqno == seqno)) {
  185. q = &dev->cmds[seqno].wait;
  186. }
  187. mutex_unlock(&dev->lock);
  188. if (q) {
  189. /* If we haven't been signalled we need to wait */
  190. if (dev->cmds[seqno].signalled == 0) {
  191. stamp = jiffies;
  192. dprintk(DBGLVL_CMD,
  193. "%s(seqno=%d) Waiting (signalled=%d)\n",
  194. __func__, seqno, dev->cmds[seqno].signalled);
  195. /* Wait for signalled to be flagged or timeout */
  196. wait_event_timeout(*q, dev->cmds[seqno].signalled, (HZ * waitsecs));
  197. r = time_before(jiffies, stamp + (HZ * waitsecs));
  198. if (r)
  199. ret = SAA_OK;
  200. else
  201. saa7164_cmd_timeout_seqno(dev, seqno);
  202. dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d "
  203. "(signalled=%d)\n", __func__, seqno, r,
  204. dev->cmds[seqno].signalled);
  205. } else
  206. ret = SAA_OK;
  207. } else
  208. printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
  209. __func__, seqno);
  210. return ret;
  211. }
  212. void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
  213. {
  214. int i;
  215. dprintk(DBGLVL_CMD, "%s()\n", __func__);
  216. mutex_lock(&dev->lock);
  217. for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
  218. if (dev->cmds[i].inuse == 1) {
  219. dprintk(DBGLVL_CMD,
  220. "seqno %d inuse, sig = %d, t/out = %d\n",
  221. dev->cmds[i].seqno,
  222. dev->cmds[i].signalled,
  223. dev->cmds[i].timeout);
  224. }
  225. }
  226. for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
  227. if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
  228. (dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
  229. dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
  230. __func__, i);
  231. dev->cmds[i].signalled = 1;
  232. wake_up(&dev->cmds[i].wait);
  233. }
  234. }
  235. mutex_unlock(&dev->lock);
  236. }
  237. int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, tmComResCmd_t command,
  238. u16 controlselector, u16 size, void *buf)
  239. {
  240. tmComResInfo_t command_t, *pcommand_t;
  241. tmComResInfo_t response_t, *presponse_t;
  242. u8 errdata[256];
  243. u16 resp_dsize;
  244. u16 data_recd;
  245. u32 loop;
  246. int ret;
  247. int safety = 0;
  248. dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, "
  249. "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
  250. command, controlselector);
  251. if ((size == 0) || (buf == 0)) {
  252. printk(KERN_ERR "%s() Invalid param\n", __func__);
  253. return SAA_ERR_BAD_PARAMETER;
  254. }
  255. /* Prepare some basic command/response structures */
  256. memset(&command_t, 0, sizeof(command_t));
  257. memset(&response_t, 0, sizeof(&response_t));
  258. pcommand_t = &command_t;
  259. presponse_t = &response_t;
  260. command_t.id = id;
  261. command_t.command = command;
  262. command_t.controlselector = controlselector;
  263. command_t.size = size;
  264. /* Allocate a unique sequence number */
  265. ret = saa7164_cmd_alloc_seqno(dev);
  266. if (ret < 0) {
  267. printk(KERN_ERR "%s() No free sequences\n", __func__);
  268. ret = SAA_ERR_NO_RESOURCES;
  269. goto out;
  270. }
  271. command_t.seqno = (u8)ret;
  272. /* Send Command */
  273. resp_dsize = size;
  274. pcommand_t->size = size;
  275. dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n",
  276. __func__, pcommand_t->seqno);
  277. dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n",
  278. __func__, pcommand_t->size);
  279. ret = saa7164_cmd_set(dev, pcommand_t, buf);
  280. if (ret != SAA_OK) {
  281. printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);
  282. if (ret != SAA_ERR_BUSY)
  283. saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
  284. else
  285. /* Flag a timeout, because at least one
  286. * command was sent */
  287. saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
  288. goto out;
  289. }
  290. /* With split responses we have to collect the msgs piece by piece */
  291. data_recd = 0;
  292. loop = 1;
  293. while (loop) {
  294. dprintk(DBGLVL_CMD, "%s() loop\n", __func__);
  295. ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
  296. dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);
  297. /* if power is down and this is not a power command ... */
  298. if (ret == SAA_BUS_TIMEOUT) {
  299. printk(KERN_ERR "Event timed out\n");
  300. saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
  301. return ret;
  302. }
  303. if (ret != SAA_OK) {
  304. printk(KERN_ERR "spurious error\n");
  305. return ret;
  306. }
  307. /* Peek response */
  308. ret = saa7164_bus_get(dev, presponse_t, NULL, 1);
  309. if (ret == SAA_ERR_EMPTY) {
  310. dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__);
  311. continue;
  312. }
  313. if (ret != SAA_OK) {
  314. printk(KERN_ERR "peek failed\n");
  315. return ret;
  316. }
  317. dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n",
  318. __func__, presponse_t->seqno);
  319. dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n",
  320. __func__, presponse_t->flags);
  321. dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n",
  322. __func__, presponse_t->size);
  323. /* Check if the response was for our command */
  324. if (presponse_t->seqno != pcommand_t->seqno) {
  325. dprintk(DBGLVL_CMD,
  326. "wrong event: seqno = %d, "
  327. "expected seqno = %d, "
  328. "will dequeue regardless\n",
  329. presponse_t->seqno, pcommand_t->seqno);
  330. ret = saa7164_cmd_dequeue(dev);
  331. if (ret != SAA_OK) {
  332. printk(KERN_ERR "dequeue failed, ret = %d\n",
  333. ret);
  334. if (safety++ > 16) {
  335. printk(KERN_ERR
  336. "dequeue exceeded, safety exit\n");
  337. return SAA_ERR_BUSY;
  338. }
  339. }
  340. continue;
  341. }
  342. if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) {
  343. memset(&errdata[0], 0, sizeof(errdata));
  344. ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0);
  345. if (ret != SAA_OK) {
  346. printk(KERN_ERR "get error(2)\n");
  347. return ret;
  348. }
  349. saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
  350. dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n",
  351. __func__, errdata[0], errdata[1], errdata[2],
  352. errdata[3]);
  353. /* Map error codes */
  354. dprintk(DBGLVL_CMD, "%s() cmd, error code = 0x%x\n",
  355. __func__, errdata[0]);
  356. switch (errdata[0]) {
  357. case PVC_ERRORCODE_INVALID_COMMAND:
  358. dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n",
  359. __func__);
  360. ret = SAA_ERR_INVALID_COMMAND;
  361. break;
  362. case PVC_ERRORCODE_INVALID_DATA:
  363. dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n",
  364. __func__);
  365. ret = SAA_ERR_BAD_PARAMETER;
  366. break;
  367. case PVC_ERRORCODE_TIMEOUT:
  368. dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__);
  369. ret = SAA_ERR_TIMEOUT;
  370. break;
  371. case PVC_ERRORCODE_NAK:
  372. dprintk(DBGLVL_CMD, "%s() NAK\n", __func__);
  373. ret = SAA_ERR_NULL_PACKET;
  374. break;
  375. case PVC_ERRORCODE_UNKNOWN:
  376. case PVC_ERRORCODE_INVALID_CONTROL:
  377. dprintk(DBGLVL_CMD,
  378. "%s() UNKNOWN OR INVALID CONTROL\n",
  379. __func__);
  380. default:
  381. dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__);
  382. ret = SAA_ERR_NOT_SUPPORTED;
  383. }
  384. /* See of other commands are on the bus */
  385. if (saa7164_cmd_dequeue(dev) != SAA_OK)
  386. printk(KERN_ERR "dequeue(2) failed\n");
  387. return ret;
  388. }
  389. /* If response is invalid */
  390. if ((presponse_t->id != pcommand_t->id) ||
  391. (presponse_t->command != pcommand_t->command) ||
  392. (presponse_t->controlselector !=
  393. pcommand_t->controlselector) ||
  394. (((resp_dsize - data_recd) != presponse_t->size) &&
  395. !(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) ||
  396. ((resp_dsize - data_recd) < presponse_t->size)) {
  397. /* Invalid */
  398. dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
  399. ret = saa7164_bus_get(dev, presponse_t, 0, 0);
  400. if (ret != SAA_OK) {
  401. printk(KERN_ERR "get failed\n");
  402. return ret;
  403. }
  404. /* See of other commands are on the bus */
  405. if (saa7164_cmd_dequeue(dev) != SAA_OK)
  406. printk(KERN_ERR "dequeue(3) failed\n");
  407. continue;
  408. }
  409. /* OK, now we're actually getting out correct response */
  410. ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0);
  411. if (ret != SAA_OK) {
  412. printk(KERN_ERR "get failed\n");
  413. return ret;
  414. }
  415. data_recd = presponse_t->size + data_recd;
  416. if (resp_dsize == data_recd) {
  417. dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__);
  418. break;
  419. }
  420. /* See of other commands are on the bus */
  421. if (saa7164_cmd_dequeue(dev) != SAA_OK)
  422. printk(KERN_ERR "dequeue(3) failed\n");
  423. continue;
  424. } /* (loop) */
  425. /* Release the sequence number allocation */
  426. saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
  427. /* if powerdown signal all pending commands */
  428. dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__);
  429. /* See of other commands are on the bus */
  430. if (saa7164_cmd_dequeue(dev) != SAA_OK)
  431. printk(KERN_ERR "dequeue(4) failed\n");
  432. ret = SAA_OK;
  433. out:
  434. return ret;
  435. }