ds.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. /* ds.c: Domain Services driver for Logical Domains
  2. *
  3. * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
  4. */
  5. #include <linux/kernel.h>
  6. #include <linux/module.h>
  7. #include <linux/types.h>
  8. #include <linux/module.h>
  9. #include <linux/string.h>
  10. #include <linux/slab.h>
  11. #include <linux/sched.h>
  12. #include <linux/delay.h>
  13. #include <asm/ldc.h>
  14. #include <asm/vio.h>
  15. #include <asm/power.h>
  16. #define DRV_MODULE_NAME "ds"
  17. #define PFX DRV_MODULE_NAME ": "
  18. #define DRV_MODULE_VERSION "1.0"
  19. #define DRV_MODULE_RELDATE "Jul 11, 2007"
  20. static char version[] __devinitdata =
  21. DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
  22. MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
  23. MODULE_DESCRIPTION("Sun LDOM domain services driver");
  24. MODULE_LICENSE("GPL");
  25. MODULE_VERSION(DRV_MODULE_VERSION);
  26. struct ds_msg_tag {
  27. __u32 type;
  28. #define DS_INIT_REQ 0x00
  29. #define DS_INIT_ACK 0x01
  30. #define DS_INIT_NACK 0x02
  31. #define DS_REG_REQ 0x03
  32. #define DS_REG_ACK 0x04
  33. #define DS_REG_NACK 0x05
  34. #define DS_UNREG_REQ 0x06
  35. #define DS_UNREG_ACK 0x07
  36. #define DS_UNREG_NACK 0x08
  37. #define DS_DATA 0x09
  38. #define DS_NACK 0x0a
  39. __u32 len;
  40. };
  41. /* Result codes */
  42. #define DS_OK 0x00
  43. #define DS_REG_VER_NACK 0x01
  44. #define DS_REG_DUP 0x02
  45. #define DS_INV_HDL 0x03
  46. #define DS_TYPE_UNKNOWN 0x04
  47. struct ds_version {
  48. __u16 major;
  49. __u16 minor;
  50. };
  51. struct ds_ver_req {
  52. struct ds_msg_tag tag;
  53. struct ds_version ver;
  54. };
  55. struct ds_ver_ack {
  56. struct ds_msg_tag tag;
  57. __u16 minor;
  58. };
  59. struct ds_ver_nack {
  60. struct ds_msg_tag tag;
  61. __u16 major;
  62. };
  63. struct ds_reg_req {
  64. struct ds_msg_tag tag;
  65. __u64 handle;
  66. __u16 major;
  67. __u16 minor;
  68. char svc_id[0];
  69. };
  70. struct ds_reg_ack {
  71. struct ds_msg_tag tag;
  72. __u64 handle;
  73. __u16 minor;
  74. };
  75. struct ds_reg_nack {
  76. struct ds_msg_tag tag;
  77. __u64 handle;
  78. __u16 major;
  79. };
  80. struct ds_unreg_req {
  81. struct ds_msg_tag tag;
  82. __u64 handle;
  83. };
  84. struct ds_unreg_ack {
  85. struct ds_msg_tag tag;
  86. __u64 handle;
  87. };
  88. struct ds_unreg_nack {
  89. struct ds_msg_tag tag;
  90. __u64 handle;
  91. };
  92. struct ds_data {
  93. struct ds_msg_tag tag;
  94. __u64 handle;
  95. };
  96. struct ds_data_nack {
  97. struct ds_msg_tag tag;
  98. __u64 handle;
  99. __u64 result;
  100. };
  101. struct ds_cap_state {
  102. __u64 handle;
  103. void (*data)(struct ldc_channel *lp,
  104. struct ds_cap_state *dp,
  105. void *buf, int len);
  106. const char *service_id;
  107. u8 state;
  108. #define CAP_STATE_UNKNOWN 0x00
  109. #define CAP_STATE_REG_SENT 0x01
  110. #define CAP_STATE_REGISTERED 0x02
  111. };
  112. static int ds_send(struct ldc_channel *lp, void *data, int len)
  113. {
  114. int err, limit = 1000;
  115. err = -EINVAL;
  116. while (limit-- > 0) {
  117. err = ldc_write(lp, data, len);
  118. if (!err || (err != -EAGAIN))
  119. break;
  120. udelay(1);
  121. }
  122. return err;
  123. }
  124. struct ds_md_update_req {
  125. __u64 req_num;
  126. };
  127. struct ds_md_update_res {
  128. __u64 req_num;
  129. __u32 result;
  130. };
  131. static void md_update_data(struct ldc_channel *lp,
  132. struct ds_cap_state *dp,
  133. void *buf, int len)
  134. {
  135. struct ds_data *dpkt = buf;
  136. struct ds_md_update_req *rp;
  137. struct {
  138. struct ds_data data;
  139. struct ds_md_update_res res;
  140. } pkt;
  141. rp = (struct ds_md_update_req *) (dpkt + 1);
  142. printk(KERN_ERR PFX "MD update REQ [%lx] len=%d\n",
  143. rp->req_num, len);
  144. memset(&pkt, 0, sizeof(pkt));
  145. pkt.data.tag.type = DS_DATA;
  146. pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
  147. pkt.data.handle = dp->handle;
  148. pkt.res.req_num = rp->req_num;
  149. pkt.res.result = DS_OK;
  150. ds_send(lp, &pkt, sizeof(pkt));
  151. }
  152. struct ds_shutdown_req {
  153. __u64 req_num;
  154. __u32 ms_delay;
  155. };
  156. struct ds_shutdown_res {
  157. __u64 req_num;
  158. __u32 result;
  159. char reason[1];
  160. };
  161. static void domain_shutdown_data(struct ldc_channel *lp,
  162. struct ds_cap_state *dp,
  163. void *buf, int len)
  164. {
  165. struct ds_data *dpkt = buf;
  166. struct ds_shutdown_req *rp;
  167. struct {
  168. struct ds_data data;
  169. struct ds_shutdown_res res;
  170. } pkt;
  171. rp = (struct ds_shutdown_req *) (dpkt + 1);
  172. printk(KERN_ALERT PFX "Shutdown request from "
  173. "LDOM manager received.\n");
  174. memset(&pkt, 0, sizeof(pkt));
  175. pkt.data.tag.type = DS_DATA;
  176. pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
  177. pkt.data.handle = dp->handle;
  178. pkt.res.req_num = rp->req_num;
  179. pkt.res.result = DS_OK;
  180. pkt.res.reason[0] = 0;
  181. ds_send(lp, &pkt, sizeof(pkt));
  182. wake_up_powerd();
  183. }
  184. struct ds_panic_req {
  185. __u64 req_num;
  186. };
  187. struct ds_panic_res {
  188. __u64 req_num;
  189. __u32 result;
  190. char reason[1];
  191. };
  192. static void domain_panic_data(struct ldc_channel *lp,
  193. struct ds_cap_state *dp,
  194. void *buf, int len)
  195. {
  196. struct ds_data *dpkt = buf;
  197. struct ds_panic_req *rp;
  198. struct {
  199. struct ds_data data;
  200. struct ds_panic_res res;
  201. } pkt;
  202. rp = (struct ds_panic_req *) (dpkt + 1);
  203. printk(KERN_ERR PFX "Panic REQ [%lx], len=%d\n",
  204. rp->req_num, len);
  205. memset(&pkt, 0, sizeof(pkt));
  206. pkt.data.tag.type = DS_DATA;
  207. pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
  208. pkt.data.handle = dp->handle;
  209. pkt.res.req_num = rp->req_num;
  210. pkt.res.result = DS_OK;
  211. pkt.res.reason[0] = 0;
  212. ds_send(lp, &pkt, sizeof(pkt));
  213. panic("PANIC requested by LDOM manager.");
  214. }
  215. struct ds_cpu_tag {
  216. __u64 req_num;
  217. __u32 type;
  218. #define DS_CPU_CONFIGURE 0x43
  219. #define DS_CPU_UNCONFIGURE 0x55
  220. #define DS_CPU_FORCE_UNCONFIGURE 0x46
  221. #define DS_CPU_STATUS 0x53
  222. /* Responses */
  223. #define DS_CPU_OK 0x6f
  224. #define DS_CPU_ERROR 0x65
  225. __u32 num_records;
  226. };
  227. struct ds_cpu_record {
  228. __u32 cpu_id;
  229. };
  230. static void dr_cpu_data(struct ldc_channel *lp,
  231. struct ds_cap_state *dp,
  232. void *buf, int len)
  233. {
  234. struct ds_data *dpkt = buf;
  235. struct ds_cpu_tag *rp;
  236. rp = (struct ds_cpu_tag *) (dpkt + 1);
  237. printk(KERN_ERR PFX "CPU REQ [%lx:%x], len=%d\n",
  238. rp->req_num, rp->type, len);
  239. }
  240. struct ds_pri_msg {
  241. __u64 req_num;
  242. __u64 type;
  243. #define DS_PRI_REQUEST 0x00
  244. #define DS_PRI_DATA 0x01
  245. #define DS_PRI_UPDATE 0x02
  246. };
  247. static void ds_pri_data(struct ldc_channel *lp,
  248. struct ds_cap_state *dp,
  249. void *buf, int len)
  250. {
  251. struct ds_data *dpkt = buf;
  252. struct ds_pri_msg *rp;
  253. rp = (struct ds_pri_msg *) (dpkt + 1);
  254. printk(KERN_ERR PFX "PRI REQ [%lx:%lx], len=%d\n",
  255. rp->req_num, rp->type, len);
  256. }
  257. struct ds_cap_state ds_states[] = {
  258. {
  259. .service_id = "md-update",
  260. .data = md_update_data,
  261. },
  262. {
  263. .service_id = "domain-shutdown",
  264. .data = domain_shutdown_data,
  265. },
  266. {
  267. .service_id = "domain-panic",
  268. .data = domain_panic_data,
  269. },
  270. {
  271. .service_id = "dr-cpu",
  272. .data = dr_cpu_data,
  273. },
  274. {
  275. .service_id = "pri",
  276. .data = ds_pri_data,
  277. },
  278. };
  279. static struct ds_cap_state *find_cap(u64 handle)
  280. {
  281. unsigned int index = handle >> 32;
  282. if (index >= ARRAY_SIZE(ds_states))
  283. return NULL;
  284. return &ds_states[index];
  285. }
  286. static DEFINE_SPINLOCK(ds_lock);
  287. struct ds_info {
  288. struct ldc_channel *lp;
  289. u8 hs_state;
  290. #define DS_HS_START 0x01
  291. #define DS_HS_DONE 0x02
  292. void *rcv_buf;
  293. int rcv_buf_len;
  294. };
  295. static void ds_conn_reset(struct ds_info *dp)
  296. {
  297. printk(KERN_ERR PFX "ds_conn_reset() from %p\n",
  298. __builtin_return_address(0));
  299. }
  300. static int register_services(struct ds_info *dp)
  301. {
  302. struct ldc_channel *lp = dp->lp;
  303. int i;
  304. for (i = 0; i < ARRAY_SIZE(ds_states); i++) {
  305. struct {
  306. struct ds_reg_req req;
  307. u8 id_buf[256];
  308. } pbuf;
  309. struct ds_cap_state *cp = &ds_states[i];
  310. int err, msg_len;
  311. u64 new_count;
  312. if (cp->state == CAP_STATE_REGISTERED)
  313. continue;
  314. new_count = sched_clock() & 0xffffffff;
  315. cp->handle = ((u64) i << 32) | new_count;
  316. msg_len = (sizeof(struct ds_reg_req) +
  317. strlen(cp->service_id));
  318. memset(&pbuf, 0, sizeof(pbuf));
  319. pbuf.req.tag.type = DS_REG_REQ;
  320. pbuf.req.tag.len = (msg_len - sizeof(struct ds_msg_tag));
  321. pbuf.req.handle = cp->handle;
  322. pbuf.req.major = 1;
  323. pbuf.req.minor = 0;
  324. strcpy(pbuf.req.svc_id, cp->service_id);
  325. err = ds_send(lp, &pbuf, msg_len);
  326. if (err > 0)
  327. cp->state = CAP_STATE_REG_SENT;
  328. }
  329. return 0;
  330. }
  331. static int ds_handshake(struct ds_info *dp, struct ds_msg_tag *pkt)
  332. {
  333. if (dp->hs_state == DS_HS_START) {
  334. if (pkt->type != DS_INIT_ACK)
  335. goto conn_reset;
  336. dp->hs_state = DS_HS_DONE;
  337. return register_services(dp);
  338. }
  339. if (dp->hs_state != DS_HS_DONE)
  340. goto conn_reset;
  341. if (pkt->type == DS_REG_ACK) {
  342. struct ds_reg_ack *ap = (struct ds_reg_ack *) pkt;
  343. struct ds_cap_state *cp = find_cap(ap->handle);
  344. if (!cp) {
  345. printk(KERN_ERR PFX "REG ACK for unknown handle %lx\n",
  346. ap->handle);
  347. return 0;
  348. }
  349. printk(KERN_INFO PFX "Registered %s service.\n",
  350. cp->service_id);
  351. cp->state = CAP_STATE_REGISTERED;
  352. } else if (pkt->type == DS_REG_NACK) {
  353. struct ds_reg_nack *np = (struct ds_reg_nack *) pkt;
  354. struct ds_cap_state *cp = find_cap(np->handle);
  355. if (!cp) {
  356. printk(KERN_ERR PFX "REG NACK for "
  357. "unknown handle %lx\n",
  358. np->handle);
  359. return 0;
  360. }
  361. printk(KERN_ERR PFX "Could not register %s service\n",
  362. cp->service_id);
  363. cp->state = CAP_STATE_UNKNOWN;
  364. }
  365. return 0;
  366. conn_reset:
  367. ds_conn_reset(dp);
  368. return -ECONNRESET;
  369. }
  370. static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len)
  371. {
  372. struct ds_data *dpkt = (struct ds_data *) pkt;
  373. struct ds_cap_state *cp = find_cap(dpkt->handle);
  374. if (!cp) {
  375. struct ds_data_nack nack = {
  376. .tag = {
  377. .type = DS_NACK,
  378. .len = (sizeof(struct ds_data_nack) -
  379. sizeof(struct ds_msg_tag)),
  380. },
  381. .handle = dpkt->handle,
  382. .result = DS_INV_HDL,
  383. };
  384. printk(KERN_ERR PFX "Data for unknown handle %lu\n",
  385. dpkt->handle);
  386. ds_send(dp->lp, &nack, sizeof(nack));
  387. } else {
  388. cp->data(dp->lp, cp, dpkt, len);
  389. }
  390. return 0;
  391. }
  392. static void ds_up(struct ds_info *dp)
  393. {
  394. struct ldc_channel *lp = dp->lp;
  395. struct ds_ver_req req;
  396. int err;
  397. req.tag.type = DS_INIT_REQ;
  398. req.tag.len = sizeof(req) - sizeof(struct ds_msg_tag);
  399. req.ver.major = 1;
  400. req.ver.minor = 0;
  401. err = ds_send(lp, &req, sizeof(req));
  402. if (err > 0)
  403. dp->hs_state = DS_HS_START;
  404. }
  405. static void ds_event(void *arg, int event)
  406. {
  407. struct ds_info *dp = arg;
  408. struct ldc_channel *lp = dp->lp;
  409. unsigned long flags;
  410. int err;
  411. spin_lock_irqsave(&ds_lock, flags);
  412. if (event == LDC_EVENT_UP) {
  413. ds_up(dp);
  414. spin_unlock_irqrestore(&ds_lock, flags);
  415. return;
  416. }
  417. if (event != LDC_EVENT_DATA_READY) {
  418. printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event);
  419. spin_unlock_irqrestore(&ds_lock, flags);
  420. return;
  421. }
  422. err = 0;
  423. while (1) {
  424. struct ds_msg_tag *tag;
  425. err = ldc_read(lp, dp->rcv_buf, sizeof(*tag));
  426. if (unlikely(err < 0)) {
  427. if (err == -ECONNRESET)
  428. ds_conn_reset(dp);
  429. break;
  430. }
  431. if (err == 0)
  432. break;
  433. tag = dp->rcv_buf;
  434. err = ldc_read(lp, tag + 1, tag->len);
  435. if (unlikely(err < 0)) {
  436. if (err == -ECONNRESET)
  437. ds_conn_reset(dp);
  438. break;
  439. }
  440. if (err < tag->len)
  441. break;
  442. if (tag->type < DS_DATA)
  443. err = ds_handshake(dp, dp->rcv_buf);
  444. else
  445. err = ds_data(dp, dp->rcv_buf,
  446. sizeof(*tag) + err);
  447. if (err == -ECONNRESET)
  448. break;
  449. }
  450. spin_unlock_irqrestore(&ds_lock, flags);
  451. }
  452. static int __devinit ds_probe(struct vio_dev *vdev,
  453. const struct vio_device_id *id)
  454. {
  455. static int ds_version_printed;
  456. struct mdesc_node *endp;
  457. struct ldc_channel_config ds_cfg = {
  458. .event = ds_event,
  459. .mtu = 4096,
  460. .mode = LDC_MODE_STREAM,
  461. };
  462. struct ldc_channel *lp;
  463. struct ds_info *dp;
  464. const u64 *chan_id;
  465. int err;
  466. if (ds_version_printed++ == 0)
  467. printk(KERN_INFO "%s", version);
  468. endp = vio_find_endpoint(vdev);
  469. if (!endp)
  470. return -ENODEV;
  471. chan_id = md_get_property(endp, "id", NULL);
  472. if (!chan_id)
  473. return -ENODEV;
  474. dp = kzalloc(sizeof(*dp), GFP_KERNEL);
  475. err = -ENOMEM;
  476. if (!dp)
  477. goto out_err;
  478. dp->rcv_buf = kzalloc(4096, GFP_KERNEL);
  479. if (!dp->rcv_buf)
  480. goto out_free_dp;
  481. dp->rcv_buf_len = 4096;
  482. ds_cfg.tx_irq = endp->irqs[0];
  483. ds_cfg.rx_irq = endp->irqs[1];
  484. lp = ldc_alloc(*chan_id, &ds_cfg, dp);
  485. if (IS_ERR(lp)) {
  486. err = PTR_ERR(lp);
  487. goto out_free_rcv_buf;
  488. }
  489. dp->lp = lp;
  490. err = ldc_bind(lp, "DS");
  491. if (err)
  492. goto out_free_ldc;
  493. start_powerd();
  494. return err;
  495. out_free_ldc:
  496. ldc_free(dp->lp);
  497. out_free_rcv_buf:
  498. kfree(dp->rcv_buf);
  499. out_free_dp:
  500. kfree(dp);
  501. out_err:
  502. return err;
  503. }
  504. static int ds_remove(struct vio_dev *vdev)
  505. {
  506. return 0;
  507. }
  508. static struct vio_device_id ds_match[] = {
  509. {
  510. .type = "domain-services-port",
  511. },
  512. {},
  513. };
  514. static struct vio_driver ds_driver = {
  515. .id_table = ds_match,
  516. .probe = ds_probe,
  517. .remove = ds_remove,
  518. .driver = {
  519. .name = "ds",
  520. .owner = THIS_MODULE,
  521. }
  522. };
  523. static int __init ds_init(void)
  524. {
  525. int i;
  526. for (i = 0; i < ARRAY_SIZE(ds_states); i++)
  527. ds_states[i].handle = ((u64)i << 32);
  528. return vio_register_driver(&ds_driver);
  529. }
  530. subsys_initcall(ds_init);