ds.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  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 <linux/mutex.h>
  14. #include <asm/ldc.h>
  15. #include <asm/vio.h>
  16. #include <asm/power.h>
  17. #include <asm/mdesc.h>
  18. #define DRV_MODULE_NAME "ds"
  19. #define PFX DRV_MODULE_NAME ": "
  20. #define DRV_MODULE_VERSION "1.0"
  21. #define DRV_MODULE_RELDATE "Jul 11, 2007"
  22. static char version[] __devinitdata =
  23. DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
  24. MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
  25. MODULE_DESCRIPTION("Sun LDOM domain services driver");
  26. MODULE_LICENSE("GPL");
  27. MODULE_VERSION(DRV_MODULE_VERSION);
  28. struct ds_msg_tag {
  29. __u32 type;
  30. #define DS_INIT_REQ 0x00
  31. #define DS_INIT_ACK 0x01
  32. #define DS_INIT_NACK 0x02
  33. #define DS_REG_REQ 0x03
  34. #define DS_REG_ACK 0x04
  35. #define DS_REG_NACK 0x05
  36. #define DS_UNREG_REQ 0x06
  37. #define DS_UNREG_ACK 0x07
  38. #define DS_UNREG_NACK 0x08
  39. #define DS_DATA 0x09
  40. #define DS_NACK 0x0a
  41. __u32 len;
  42. };
  43. /* Result codes */
  44. #define DS_OK 0x00
  45. #define DS_REG_VER_NACK 0x01
  46. #define DS_REG_DUP 0x02
  47. #define DS_INV_HDL 0x03
  48. #define DS_TYPE_UNKNOWN 0x04
  49. struct ds_version {
  50. __u16 major;
  51. __u16 minor;
  52. };
  53. struct ds_ver_req {
  54. struct ds_msg_tag tag;
  55. struct ds_version ver;
  56. };
  57. struct ds_ver_ack {
  58. struct ds_msg_tag tag;
  59. __u16 minor;
  60. };
  61. struct ds_ver_nack {
  62. struct ds_msg_tag tag;
  63. __u16 major;
  64. };
  65. struct ds_reg_req {
  66. struct ds_msg_tag tag;
  67. __u64 handle;
  68. __u16 major;
  69. __u16 minor;
  70. char svc_id[0];
  71. };
  72. struct ds_reg_ack {
  73. struct ds_msg_tag tag;
  74. __u64 handle;
  75. __u16 minor;
  76. };
  77. struct ds_reg_nack {
  78. struct ds_msg_tag tag;
  79. __u64 handle;
  80. __u16 major;
  81. };
  82. struct ds_unreg_req {
  83. struct ds_msg_tag tag;
  84. __u64 handle;
  85. };
  86. struct ds_unreg_ack {
  87. struct ds_msg_tag tag;
  88. __u64 handle;
  89. };
  90. struct ds_unreg_nack {
  91. struct ds_msg_tag tag;
  92. __u64 handle;
  93. };
  94. struct ds_data {
  95. struct ds_msg_tag tag;
  96. __u64 handle;
  97. };
  98. struct ds_data_nack {
  99. struct ds_msg_tag tag;
  100. __u64 handle;
  101. __u64 result;
  102. };
  103. struct ds_cap_state {
  104. __u64 handle;
  105. void (*data)(struct ldc_channel *lp,
  106. struct ds_cap_state *dp,
  107. void *buf, int len);
  108. const char *service_id;
  109. u8 state;
  110. #define CAP_STATE_UNKNOWN 0x00
  111. #define CAP_STATE_REG_SENT 0x01
  112. #define CAP_STATE_REGISTERED 0x02
  113. };
  114. static int ds_send(struct ldc_channel *lp, void *data, int len)
  115. {
  116. int err, limit = 1000;
  117. err = -EINVAL;
  118. while (limit-- > 0) {
  119. err = ldc_write(lp, data, len);
  120. if (!err || (err != -EAGAIN))
  121. break;
  122. udelay(1);
  123. }
  124. return err;
  125. }
  126. struct ds_md_update_req {
  127. __u64 req_num;
  128. };
  129. struct ds_md_update_res {
  130. __u64 req_num;
  131. __u32 result;
  132. };
  133. static void md_update_data(struct ldc_channel *lp,
  134. struct ds_cap_state *dp,
  135. void *buf, int len)
  136. {
  137. struct ds_data *dpkt = buf;
  138. struct ds_md_update_req *rp;
  139. struct {
  140. struct ds_data data;
  141. struct ds_md_update_res res;
  142. } pkt;
  143. rp = (struct ds_md_update_req *) (dpkt + 1);
  144. printk(KERN_INFO PFX "Machine description update.\n");
  145. memset(&pkt, 0, sizeof(pkt));
  146. pkt.data.tag.type = DS_DATA;
  147. pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
  148. pkt.data.handle = dp->handle;
  149. pkt.res.req_num = rp->req_num;
  150. pkt.res.result = DS_OK;
  151. ds_send(lp, &pkt, sizeof(pkt));
  152. mdesc_update();
  153. }
  154. struct ds_shutdown_req {
  155. __u64 req_num;
  156. __u32 ms_delay;
  157. };
  158. struct ds_shutdown_res {
  159. __u64 req_num;
  160. __u32 result;
  161. char reason[1];
  162. };
  163. static void domain_shutdown_data(struct ldc_channel *lp,
  164. struct ds_cap_state *dp,
  165. void *buf, int len)
  166. {
  167. struct ds_data *dpkt = buf;
  168. struct ds_shutdown_req *rp;
  169. struct {
  170. struct ds_data data;
  171. struct ds_shutdown_res res;
  172. } pkt;
  173. rp = (struct ds_shutdown_req *) (dpkt + 1);
  174. printk(KERN_ALERT PFX "Shutdown request from "
  175. "LDOM manager received.\n");
  176. memset(&pkt, 0, sizeof(pkt));
  177. pkt.data.tag.type = DS_DATA;
  178. pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
  179. pkt.data.handle = dp->handle;
  180. pkt.res.req_num = rp->req_num;
  181. pkt.res.result = DS_OK;
  182. pkt.res.reason[0] = 0;
  183. ds_send(lp, &pkt, sizeof(pkt));
  184. wake_up_powerd();
  185. }
  186. struct ds_panic_req {
  187. __u64 req_num;
  188. };
  189. struct ds_panic_res {
  190. __u64 req_num;
  191. __u32 result;
  192. char reason[1];
  193. };
  194. static void domain_panic_data(struct ldc_channel *lp,
  195. struct ds_cap_state *dp,
  196. void *buf, int len)
  197. {
  198. struct ds_data *dpkt = buf;
  199. struct ds_panic_req *rp;
  200. struct {
  201. struct ds_data data;
  202. struct ds_panic_res res;
  203. } pkt;
  204. rp = (struct ds_panic_req *) (dpkt + 1);
  205. printk(KERN_ALERT PFX "Panic request from "
  206. "LDOM manager received.\n");
  207. memset(&pkt, 0, sizeof(pkt));
  208. pkt.data.tag.type = DS_DATA;
  209. pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
  210. pkt.data.handle = dp->handle;
  211. pkt.res.req_num = rp->req_num;
  212. pkt.res.result = DS_OK;
  213. pkt.res.reason[0] = 0;
  214. ds_send(lp, &pkt, sizeof(pkt));
  215. panic("PANIC requested by LDOM manager.");
  216. }
  217. struct ds_cpu_tag {
  218. __u64 req_num;
  219. __u32 type;
  220. #define DS_CPU_CONFIGURE 0x43
  221. #define DS_CPU_UNCONFIGURE 0x55
  222. #define DS_CPU_FORCE_UNCONFIGURE 0x46
  223. #define DS_CPU_STATUS 0x53
  224. /* Responses */
  225. #define DS_CPU_OK 0x6f
  226. #define DS_CPU_ERROR 0x65
  227. __u32 num_records;
  228. };
  229. struct ds_cpu_record {
  230. __u32 cpu_id;
  231. };
  232. static void dr_cpu_data(struct ldc_channel *lp,
  233. struct ds_cap_state *dp,
  234. void *buf, int len)
  235. {
  236. struct ds_data *dpkt = buf;
  237. struct ds_cpu_tag *rp;
  238. rp = (struct ds_cpu_tag *) (dpkt + 1);
  239. printk(KERN_ERR PFX "CPU REQ [%lx:%x], len=%d\n",
  240. rp->req_num, rp->type, len);
  241. }
  242. struct ds_pri_msg {
  243. __u64 req_num;
  244. __u64 type;
  245. #define DS_PRI_REQUEST 0x00
  246. #define DS_PRI_DATA 0x01
  247. #define DS_PRI_UPDATE 0x02
  248. };
  249. static void ds_pri_data(struct ldc_channel *lp,
  250. struct ds_cap_state *dp,
  251. void *buf, int len)
  252. {
  253. struct ds_data *dpkt = buf;
  254. struct ds_pri_msg *rp;
  255. rp = (struct ds_pri_msg *) (dpkt + 1);
  256. printk(KERN_INFO PFX "PRI REQ [%lx:%lx], len=%d\n",
  257. rp->req_num, rp->type, len);
  258. }
  259. struct ds_var_hdr {
  260. __u32 type;
  261. #define DS_VAR_SET_REQ 0x00
  262. #define DS_VAR_DELETE_REQ 0x01
  263. #define DS_VAR_SET_RESP 0x02
  264. #define DS_VAR_DELETE_RESP 0x03
  265. };
  266. struct ds_var_set_msg {
  267. struct ds_var_hdr hdr;
  268. char name_and_value[0];
  269. };
  270. struct ds_var_delete_msg {
  271. struct ds_var_hdr hdr;
  272. char name[0];
  273. };
  274. struct ds_var_resp {
  275. struct ds_var_hdr hdr;
  276. __u32 result;
  277. #define DS_VAR_SUCCESS 0x00
  278. #define DS_VAR_NO_SPACE 0x01
  279. #define DS_VAR_INVALID_VAR 0x02
  280. #define DS_VAR_INVALID_VAL 0x03
  281. #define DS_VAR_NOT_PRESENT 0x04
  282. };
  283. static DEFINE_MUTEX(ds_var_mutex);
  284. static int ds_var_doorbell;
  285. static int ds_var_response;
  286. static void ds_var_data(struct ldc_channel *lp,
  287. struct ds_cap_state *dp,
  288. void *buf, int len)
  289. {
  290. struct ds_data *dpkt = buf;
  291. struct ds_var_resp *rp;
  292. rp = (struct ds_var_resp *) (dpkt + 1);
  293. if (rp->hdr.type != DS_VAR_SET_RESP &&
  294. rp->hdr.type != DS_VAR_DELETE_RESP)
  295. return;
  296. ds_var_response = rp->result;
  297. wmb();
  298. ds_var_doorbell = 1;
  299. }
  300. struct ds_cap_state ds_states[] = {
  301. {
  302. .service_id = "md-update",
  303. .data = md_update_data,
  304. },
  305. {
  306. .service_id = "domain-shutdown",
  307. .data = domain_shutdown_data,
  308. },
  309. {
  310. .service_id = "domain-panic",
  311. .data = domain_panic_data,
  312. },
  313. {
  314. .service_id = "dr-cpu",
  315. .data = dr_cpu_data,
  316. },
  317. {
  318. .service_id = "pri",
  319. .data = ds_pri_data,
  320. },
  321. {
  322. .service_id = "var-config",
  323. .data = ds_var_data,
  324. },
  325. {
  326. .service_id = "var-config-backup",
  327. .data = ds_var_data,
  328. },
  329. };
  330. static DEFINE_SPINLOCK(ds_lock);
  331. struct ds_info {
  332. struct ldc_channel *lp;
  333. u8 hs_state;
  334. #define DS_HS_START 0x01
  335. #define DS_HS_DONE 0x02
  336. void *rcv_buf;
  337. int rcv_buf_len;
  338. };
  339. static struct ds_info *ds_info;
  340. static struct ds_cap_state *find_cap(u64 handle)
  341. {
  342. unsigned int index = handle >> 32;
  343. if (index >= ARRAY_SIZE(ds_states))
  344. return NULL;
  345. return &ds_states[index];
  346. }
  347. static struct ds_cap_state *find_cap_by_string(const char *name)
  348. {
  349. int i;
  350. for (i = 0; i < ARRAY_SIZE(ds_states); i++) {
  351. if (strcmp(ds_states[i].service_id, name))
  352. continue;
  353. return &ds_states[i];
  354. }
  355. return NULL;
  356. }
  357. void ldom_set_var(const char *var, const char *value)
  358. {
  359. struct ds_info *dp = ds_info;
  360. struct ds_cap_state *cp;
  361. cp = find_cap_by_string("var-config");
  362. if (cp->state != CAP_STATE_REGISTERED)
  363. cp = find_cap_by_string("var-config-backup");
  364. if (cp->state == CAP_STATE_REGISTERED) {
  365. union {
  366. struct {
  367. struct ds_data data;
  368. struct ds_var_set_msg msg;
  369. } header;
  370. char all[512];
  371. } pkt;
  372. unsigned long flags;
  373. char *base, *p;
  374. int msg_len, loops;
  375. memset(&pkt, 0, sizeof(pkt));
  376. pkt.header.data.tag.type = DS_DATA;
  377. pkt.header.data.handle = cp->handle;
  378. pkt.header.msg.hdr.type = DS_VAR_SET_REQ;
  379. base = p = &pkt.header.msg.name_and_value[0];
  380. strcpy(p, var);
  381. p += strlen(var) + 1;
  382. strcpy(p, value);
  383. p += strlen(value) + 1;
  384. msg_len = (sizeof(struct ds_data) +
  385. sizeof(struct ds_var_set_msg) +
  386. (p - base));
  387. msg_len = (msg_len + 3) & ~3;
  388. pkt.header.data.tag.len = msg_len - sizeof(struct ds_msg_tag);
  389. mutex_lock(&ds_var_mutex);
  390. spin_lock_irqsave(&ds_lock, flags);
  391. ds_var_doorbell = 0;
  392. ds_var_response = -1;
  393. ds_send(dp->lp, &pkt, msg_len);
  394. spin_unlock_irqrestore(&ds_lock, flags);
  395. loops = 1000;
  396. while (ds_var_doorbell == 0) {
  397. if (loops-- < 0)
  398. break;
  399. barrier();
  400. udelay(100);
  401. }
  402. mutex_unlock(&ds_var_mutex);
  403. if (ds_var_doorbell == 0 ||
  404. ds_var_response != DS_VAR_SUCCESS)
  405. printk(KERN_ERR PFX "var-config [%s:%s] "
  406. "failed, response(%d).\n",
  407. var, value,
  408. ds_var_response);
  409. } else {
  410. printk(KERN_ERR PFX "var-config not registered so "
  411. "could not set (%s) variable to (%s).\n",
  412. var, value);
  413. }
  414. }
  415. void ldom_reboot(const char *boot_command)
  416. {
  417. /* Don't bother with any of this if the boot_command
  418. * is empty.
  419. */
  420. if (boot_command && strlen(boot_command)) {
  421. char full_boot_str[256];
  422. strcpy(full_boot_str, "boot ");
  423. strcpy(full_boot_str + strlen("boot "), boot_command);
  424. ldom_set_var("reboot-command", full_boot_str);
  425. }
  426. sun4v_mach_sir();
  427. }
  428. static void ds_conn_reset(struct ds_info *dp)
  429. {
  430. printk(KERN_ERR PFX "ds_conn_reset() from %p\n",
  431. __builtin_return_address(0));
  432. }
  433. static int register_services(struct ds_info *dp)
  434. {
  435. struct ldc_channel *lp = dp->lp;
  436. int i;
  437. for (i = 0; i < ARRAY_SIZE(ds_states); i++) {
  438. struct {
  439. struct ds_reg_req req;
  440. u8 id_buf[256];
  441. } pbuf;
  442. struct ds_cap_state *cp = &ds_states[i];
  443. int err, msg_len;
  444. u64 new_count;
  445. if (cp->state == CAP_STATE_REGISTERED)
  446. continue;
  447. new_count = sched_clock() & 0xffffffff;
  448. cp->handle = ((u64) i << 32) | new_count;
  449. msg_len = (sizeof(struct ds_reg_req) +
  450. strlen(cp->service_id));
  451. memset(&pbuf, 0, sizeof(pbuf));
  452. pbuf.req.tag.type = DS_REG_REQ;
  453. pbuf.req.tag.len = (msg_len - sizeof(struct ds_msg_tag));
  454. pbuf.req.handle = cp->handle;
  455. pbuf.req.major = 1;
  456. pbuf.req.minor = 0;
  457. strcpy(pbuf.req.svc_id, cp->service_id);
  458. err = ds_send(lp, &pbuf, msg_len);
  459. if (err > 0)
  460. cp->state = CAP_STATE_REG_SENT;
  461. }
  462. return 0;
  463. }
  464. static int ds_handshake(struct ds_info *dp, struct ds_msg_tag *pkt)
  465. {
  466. if (dp->hs_state == DS_HS_START) {
  467. if (pkt->type != DS_INIT_ACK)
  468. goto conn_reset;
  469. dp->hs_state = DS_HS_DONE;
  470. return register_services(dp);
  471. }
  472. if (dp->hs_state != DS_HS_DONE)
  473. goto conn_reset;
  474. if (pkt->type == DS_REG_ACK) {
  475. struct ds_reg_ack *ap = (struct ds_reg_ack *) pkt;
  476. struct ds_cap_state *cp = find_cap(ap->handle);
  477. if (!cp) {
  478. printk(KERN_ERR PFX "REG ACK for unknown handle %lx\n",
  479. ap->handle);
  480. return 0;
  481. }
  482. printk(KERN_INFO PFX "Registered %s service.\n",
  483. cp->service_id);
  484. cp->state = CAP_STATE_REGISTERED;
  485. } else if (pkt->type == DS_REG_NACK) {
  486. struct ds_reg_nack *np = (struct ds_reg_nack *) pkt;
  487. struct ds_cap_state *cp = find_cap(np->handle);
  488. if (!cp) {
  489. printk(KERN_ERR PFX "REG NACK for "
  490. "unknown handle %lx\n",
  491. np->handle);
  492. return 0;
  493. }
  494. printk(KERN_ERR PFX "Could not register %s service\n",
  495. cp->service_id);
  496. cp->state = CAP_STATE_UNKNOWN;
  497. }
  498. return 0;
  499. conn_reset:
  500. ds_conn_reset(dp);
  501. return -ECONNRESET;
  502. }
  503. static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len)
  504. {
  505. struct ds_data *dpkt = (struct ds_data *) pkt;
  506. struct ds_cap_state *cp = find_cap(dpkt->handle);
  507. if (!cp) {
  508. struct ds_data_nack nack = {
  509. .tag = {
  510. .type = DS_NACK,
  511. .len = (sizeof(struct ds_data_nack) -
  512. sizeof(struct ds_msg_tag)),
  513. },
  514. .handle = dpkt->handle,
  515. .result = DS_INV_HDL,
  516. };
  517. printk(KERN_ERR PFX "Data for unknown handle %lu\n",
  518. dpkt->handle);
  519. ds_send(dp->lp, &nack, sizeof(nack));
  520. } else {
  521. cp->data(dp->lp, cp, dpkt, len);
  522. }
  523. return 0;
  524. }
  525. static void ds_up(struct ds_info *dp)
  526. {
  527. struct ldc_channel *lp = dp->lp;
  528. struct ds_ver_req req;
  529. int err;
  530. req.tag.type = DS_INIT_REQ;
  531. req.tag.len = sizeof(req) - sizeof(struct ds_msg_tag);
  532. req.ver.major = 1;
  533. req.ver.minor = 0;
  534. err = ds_send(lp, &req, sizeof(req));
  535. if (err > 0)
  536. dp->hs_state = DS_HS_START;
  537. }
  538. static void ds_event(void *arg, int event)
  539. {
  540. struct ds_info *dp = arg;
  541. struct ldc_channel *lp = dp->lp;
  542. unsigned long flags;
  543. int err;
  544. spin_lock_irqsave(&ds_lock, flags);
  545. if (event == LDC_EVENT_UP) {
  546. ds_up(dp);
  547. spin_unlock_irqrestore(&ds_lock, flags);
  548. return;
  549. }
  550. if (event != LDC_EVENT_DATA_READY) {
  551. printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event);
  552. spin_unlock_irqrestore(&ds_lock, flags);
  553. return;
  554. }
  555. err = 0;
  556. while (1) {
  557. struct ds_msg_tag *tag;
  558. err = ldc_read(lp, dp->rcv_buf, sizeof(*tag));
  559. if (unlikely(err < 0)) {
  560. if (err == -ECONNRESET)
  561. ds_conn_reset(dp);
  562. break;
  563. }
  564. if (err == 0)
  565. break;
  566. tag = dp->rcv_buf;
  567. err = ldc_read(lp, tag + 1, tag->len);
  568. if (unlikely(err < 0)) {
  569. if (err == -ECONNRESET)
  570. ds_conn_reset(dp);
  571. break;
  572. }
  573. if (err < tag->len)
  574. break;
  575. if (tag->type < DS_DATA)
  576. err = ds_handshake(dp, dp->rcv_buf);
  577. else
  578. err = ds_data(dp, dp->rcv_buf,
  579. sizeof(*tag) + err);
  580. if (err == -ECONNRESET)
  581. break;
  582. }
  583. spin_unlock_irqrestore(&ds_lock, flags);
  584. }
  585. static int __devinit ds_probe(struct vio_dev *vdev,
  586. const struct vio_device_id *id)
  587. {
  588. static int ds_version_printed;
  589. struct ldc_channel_config ds_cfg = {
  590. .event = ds_event,
  591. .mtu = 4096,
  592. .mode = LDC_MODE_STREAM,
  593. };
  594. struct ldc_channel *lp;
  595. struct ds_info *dp;
  596. int err;
  597. if (ds_version_printed++ == 0)
  598. printk(KERN_INFO "%s", version);
  599. dp = kzalloc(sizeof(*dp), GFP_KERNEL);
  600. err = -ENOMEM;
  601. if (!dp)
  602. goto out_err;
  603. dp->rcv_buf = kzalloc(4096, GFP_KERNEL);
  604. if (!dp->rcv_buf)
  605. goto out_free_dp;
  606. dp->rcv_buf_len = 4096;
  607. ds_cfg.tx_irq = vdev->tx_irq;
  608. ds_cfg.rx_irq = vdev->rx_irq;
  609. lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp);
  610. if (IS_ERR(lp)) {
  611. err = PTR_ERR(lp);
  612. goto out_free_rcv_buf;
  613. }
  614. dp->lp = lp;
  615. err = ldc_bind(lp, "DS");
  616. if (err)
  617. goto out_free_ldc;
  618. ds_info = dp;
  619. start_powerd();
  620. return err;
  621. out_free_ldc:
  622. ldc_free(dp->lp);
  623. out_free_rcv_buf:
  624. kfree(dp->rcv_buf);
  625. out_free_dp:
  626. kfree(dp);
  627. out_err:
  628. return err;
  629. }
  630. static int ds_remove(struct vio_dev *vdev)
  631. {
  632. return 0;
  633. }
  634. static struct vio_device_id ds_match[] = {
  635. {
  636. .type = "domain-services-port",
  637. },
  638. {},
  639. };
  640. static struct vio_driver ds_driver = {
  641. .id_table = ds_match,
  642. .probe = ds_probe,
  643. .remove = ds_remove,
  644. .driver = {
  645. .name = "ds",
  646. .owner = THIS_MODULE,
  647. }
  648. };
  649. static int __init ds_init(void)
  650. {
  651. int i;
  652. for (i = 0; i < ARRAY_SIZE(ds_states); i++)
  653. ds_states[i].handle = ((u64)i << 32);
  654. return vio_register_driver(&ds_driver);
  655. }
  656. subsys_initcall(ds_init);