linux/arch/sparc/kernel/ds.c
<<
>>
Prefs
   1/* ds.c: Domain Services driver for Logical Domains
   2 *
   3 * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
   4 */
   5
   6#include <linux/kernel.h>
   7#include <linux/module.h>
   8#include <linux/types.h>
   9#include <linux/string.h>
  10#include <linux/slab.h>
  11#include <linux/sched.h>
  12#include <linux/sched/clock.h>
  13#include <linux/delay.h>
  14#include <linux/mutex.h>
  15#include <linux/kthread.h>
  16#include <linux/reboot.h>
  17#include <linux/cpu.h>
  18
  19#include <asm/hypervisor.h>
  20#include <asm/ldc.h>
  21#include <asm/vio.h>
  22#include <asm/mdesc.h>
  23#include <asm/head.h>
  24#include <asm/irq.h>
  25
  26#include "kernel.h"
  27
  28#define DRV_MODULE_NAME         "ds"
  29#define PFX DRV_MODULE_NAME     ": "
  30#define DRV_MODULE_VERSION      "1.0"
  31#define DRV_MODULE_RELDATE      "Jul 11, 2007"
  32
  33static char version[] =
  34        DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
  35MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
  36MODULE_DESCRIPTION("Sun LDOM domain services driver");
  37MODULE_LICENSE("GPL");
  38MODULE_VERSION(DRV_MODULE_VERSION);
  39
  40struct ds_msg_tag {
  41        __u32                   type;
  42#define DS_INIT_REQ             0x00
  43#define DS_INIT_ACK             0x01
  44#define DS_INIT_NACK            0x02
  45#define DS_REG_REQ              0x03
  46#define DS_REG_ACK              0x04
  47#define DS_REG_NACK             0x05
  48#define DS_UNREG_REQ            0x06
  49#define DS_UNREG_ACK            0x07
  50#define DS_UNREG_NACK           0x08
  51#define DS_DATA                 0x09
  52#define DS_NACK                 0x0a
  53
  54        __u32                   len;
  55};
  56
  57/* Result codes */
  58#define DS_OK                   0x00
  59#define DS_REG_VER_NACK         0x01
  60#define DS_REG_DUP              0x02
  61#define DS_INV_HDL              0x03
  62#define DS_TYPE_UNKNOWN         0x04
  63
  64struct ds_version {
  65        __u16                   major;
  66        __u16                   minor;
  67};
  68
  69struct ds_ver_req {
  70        struct ds_msg_tag       tag;
  71        struct ds_version       ver;
  72};
  73
  74struct ds_ver_ack {
  75        struct ds_msg_tag       tag;
  76        __u16                   minor;
  77};
  78
  79struct ds_ver_nack {
  80        struct ds_msg_tag       tag;
  81        __u16                   major;
  82};
  83
  84struct ds_reg_req {
  85        struct ds_msg_tag       tag;
  86        __u64                   handle;
  87        __u16                   major;
  88        __u16                   minor;
  89        char                    svc_id[0];
  90};
  91
  92struct ds_reg_ack {
  93        struct ds_msg_tag       tag;
  94        __u64                   handle;
  95        __u16                   minor;
  96};
  97
  98struct ds_reg_nack {
  99        struct ds_msg_tag       tag;
 100        __u64                   handle;
 101        __u16                   major;
 102};
 103
 104struct ds_unreg_req {
 105        struct ds_msg_tag       tag;
 106        __u64                   handle;
 107};
 108
 109struct ds_unreg_ack {
 110        struct ds_msg_tag       tag;
 111        __u64                   handle;
 112};
 113
 114struct ds_unreg_nack {
 115        struct ds_msg_tag       tag;
 116        __u64                   handle;
 117};
 118
 119struct ds_data {
 120        struct ds_msg_tag       tag;
 121        __u64                   handle;
 122};
 123
 124struct ds_data_nack {
 125        struct ds_msg_tag       tag;
 126        __u64                   handle;
 127        __u64                   result;
 128};
 129
 130struct ds_info;
 131struct ds_cap_state {
 132        __u64                   handle;
 133
 134        void                    (*data)(struct ds_info *dp,
 135                                        struct ds_cap_state *cp,
 136                                        void *buf, int len);
 137
 138        const char              *service_id;
 139
 140        u8                      state;
 141#define CAP_STATE_UNKNOWN       0x00
 142#define CAP_STATE_REG_SENT      0x01
 143#define CAP_STATE_REGISTERED    0x02
 144};
 145
 146static void md_update_data(struct ds_info *dp, struct ds_cap_state *cp,
 147                           void *buf, int len);
 148static void domain_shutdown_data(struct ds_info *dp,
 149                                 struct ds_cap_state *cp,
 150                                 void *buf, int len);
 151static void domain_panic_data(struct ds_info *dp,
 152                              struct ds_cap_state *cp,
 153                              void *buf, int len);
 154#ifdef CONFIG_HOTPLUG_CPU
 155static void dr_cpu_data(struct ds_info *dp,
 156                        struct ds_cap_state *cp,
 157                        void *buf, int len);
 158#endif
 159static void ds_pri_data(struct ds_info *dp,
 160                        struct ds_cap_state *cp,
 161                        void *buf, int len);
 162static void ds_var_data(struct ds_info *dp,
 163                        struct ds_cap_state *cp,
 164                        void *buf, int len);
 165
 166static struct ds_cap_state ds_states_template[] = {
 167        {
 168                .service_id     = "md-update",
 169                .data           = md_update_data,
 170        },
 171        {
 172                .service_id     = "domain-shutdown",
 173                .data           = domain_shutdown_data,
 174        },
 175        {
 176                .service_id     = "domain-panic",
 177                .data           = domain_panic_data,
 178        },
 179#ifdef CONFIG_HOTPLUG_CPU
 180        {
 181                .service_id     = "dr-cpu",
 182                .data           = dr_cpu_data,
 183        },
 184#endif
 185        {
 186                .service_id     = "pri",
 187                .data           = ds_pri_data,
 188        },
 189        {
 190                .service_id     = "var-config",
 191                .data           = ds_var_data,
 192        },
 193        {
 194                .service_id     = "var-config-backup",
 195                .data           = ds_var_data,
 196        },
 197};
 198
 199static DEFINE_SPINLOCK(ds_lock);
 200
 201struct ds_info {
 202        struct ldc_channel      *lp;
 203        u8                      hs_state;
 204#define DS_HS_START             0x01
 205#define DS_HS_DONE              0x02
 206
 207        u64                     id;
 208
 209        void                    *rcv_buf;
 210        int                     rcv_buf_len;
 211
 212        struct ds_cap_state     *ds_states;
 213        int                     num_ds_states;
 214
 215        struct ds_info          *next;
 216};
 217
 218static struct ds_info *ds_info_list;
 219
 220static struct ds_cap_state *find_cap(struct ds_info *dp, u64 handle)
 221{
 222        unsigned int index = handle >> 32;
 223
 224        if (index >= dp->num_ds_states)
 225                return NULL;
 226        return &dp->ds_states[index];
 227}
 228
 229static struct ds_cap_state *find_cap_by_string(struct ds_info *dp,
 230                                               const char *name)
 231{
 232        int i;
 233
 234        for (i = 0; i < dp->num_ds_states; i++) {
 235                if (strcmp(dp->ds_states[i].service_id, name))
 236                        continue;
 237
 238                return &dp->ds_states[i];
 239        }
 240        return NULL;
 241}
 242
 243static int __ds_send(struct ldc_channel *lp, void *data, int len)
 244{
 245        int err, limit = 1000;
 246
 247        err = -EINVAL;
 248        while (limit-- > 0) {
 249                err = ldc_write(lp, data, len);
 250                if (!err || (err != -EAGAIN))
 251                        break;
 252                udelay(1);
 253        }
 254
 255        return err;
 256}
 257
 258static int ds_send(struct ldc_channel *lp, void *data, int len)
 259{
 260        unsigned long flags;
 261        int err;
 262
 263        spin_lock_irqsave(&ds_lock, flags);
 264        err = __ds_send(lp, data, len);
 265        spin_unlock_irqrestore(&ds_lock, flags);
 266
 267        return err;
 268}
 269
 270struct ds_md_update_req {
 271        __u64                           req_num;
 272};
 273
 274struct ds_md_update_res {
 275        __u64                           req_num;
 276        __u32                           result;
 277};
 278
 279static void md_update_data(struct ds_info *dp,
 280                           struct ds_cap_state *cp,
 281                           void *buf, int len)
 282{
 283        struct ldc_channel *lp = dp->lp;
 284        struct ds_data *dpkt = buf;
 285        struct ds_md_update_req *rp;
 286        struct {
 287                struct ds_data          data;
 288                struct ds_md_update_res res;
 289        } pkt;
 290
 291        rp = (struct ds_md_update_req *) (dpkt + 1);
 292
 293        printk(KERN_INFO "ds-%llu: Machine description update.\n", dp->id);
 294
 295        mdesc_update();
 296
 297        memset(&pkt, 0, sizeof(pkt));
 298        pkt.data.tag.type = DS_DATA;
 299        pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
 300        pkt.data.handle = cp->handle;
 301        pkt.res.req_num = rp->req_num;
 302        pkt.res.result = DS_OK;
 303
 304        ds_send(lp, &pkt, sizeof(pkt));
 305}
 306
 307struct ds_shutdown_req {
 308        __u64                           req_num;
 309        __u32                           ms_delay;
 310};
 311
 312struct ds_shutdown_res {
 313        __u64                           req_num;
 314        __u32                           result;
 315        char                            reason[1];
 316};
 317
 318static void domain_shutdown_data(struct ds_info *dp,
 319                                 struct ds_cap_state *cp,
 320                                 void *buf, int len)
 321{
 322        struct ldc_channel *lp = dp->lp;
 323        struct ds_data *dpkt = buf;
 324        struct ds_shutdown_req *rp;
 325        struct {
 326                struct ds_data          data;
 327                struct ds_shutdown_res  res;
 328        } pkt;
 329
 330        rp = (struct ds_shutdown_req *) (dpkt + 1);
 331
 332        printk(KERN_ALERT "ds-%llu: Shutdown request from "
 333               "LDOM manager received.\n", dp->id);
 334
 335        memset(&pkt, 0, sizeof(pkt));
 336        pkt.data.tag.type = DS_DATA;
 337        pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
 338        pkt.data.handle = cp->handle;
 339        pkt.res.req_num = rp->req_num;
 340        pkt.res.result = DS_OK;
 341        pkt.res.reason[0] = 0;
 342
 343        ds_send(lp, &pkt, sizeof(pkt));
 344
 345        orderly_poweroff(true);
 346}
 347
 348struct ds_panic_req {
 349        __u64                           req_num;
 350};
 351
 352struct ds_panic_res {
 353        __u64                           req_num;
 354        __u32                           result;
 355        char                            reason[1];
 356};
 357
 358static void domain_panic_data(struct ds_info *dp,
 359                              struct ds_cap_state *cp,
 360                              void *buf, int len)
 361{
 362        struct ldc_channel *lp = dp->lp;
 363        struct ds_data *dpkt = buf;
 364        struct ds_panic_req *rp;
 365        struct {
 366                struct ds_data          data;
 367                struct ds_panic_res     res;
 368        } pkt;
 369
 370        rp = (struct ds_panic_req *) (dpkt + 1);
 371
 372        printk(KERN_ALERT "ds-%llu: Panic request from "
 373               "LDOM manager received.\n", dp->id);
 374
 375        memset(&pkt, 0, sizeof(pkt));
 376        pkt.data.tag.type = DS_DATA;
 377        pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
 378        pkt.data.handle = cp->handle;
 379        pkt.res.req_num = rp->req_num;
 380        pkt.res.result = DS_OK;
 381        pkt.res.reason[0] = 0;
 382
 383        ds_send(lp, &pkt, sizeof(pkt));
 384
 385        panic("PANIC requested by LDOM manager.");
 386}
 387
 388#ifdef CONFIG_HOTPLUG_CPU
 389struct dr_cpu_tag {
 390        __u64                           req_num;
 391        __u32                           type;
 392#define DR_CPU_CONFIGURE                0x43
 393#define DR_CPU_UNCONFIGURE              0x55
 394#define DR_CPU_FORCE_UNCONFIGURE        0x46
 395#define DR_CPU_STATUS                   0x53
 396
 397/* Responses */
 398#define DR_CPU_OK                       0x6f
 399#define DR_CPU_ERROR                    0x65
 400
 401        __u32                           num_records;
 402};
 403
 404struct dr_cpu_resp_entry {
 405        __u32                           cpu;
 406        __u32                           result;
 407#define DR_CPU_RES_OK                   0x00
 408#define DR_CPU_RES_FAILURE              0x01
 409#define DR_CPU_RES_BLOCKED              0x02
 410#define DR_CPU_RES_CPU_NOT_RESPONDING   0x03
 411#define DR_CPU_RES_NOT_IN_MD            0x04
 412
 413        __u32                           stat;
 414#define DR_CPU_STAT_NOT_PRESENT         0x00
 415#define DR_CPU_STAT_UNCONFIGURED        0x01
 416#define DR_CPU_STAT_CONFIGURED          0x02
 417
 418        __u32                           str_off;
 419};
 420
 421static void __dr_cpu_send_error(struct ds_info *dp,
 422                                struct ds_cap_state *cp,
 423                                struct ds_data *data)
 424{
 425        struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1);
 426        struct {
 427                struct ds_data          data;
 428                struct dr_cpu_tag       tag;
 429        } pkt;
 430        int msg_len;
 431
 432        memset(&pkt, 0, sizeof(pkt));
 433        pkt.data.tag.type = DS_DATA;
 434        pkt.data.handle = cp->handle;
 435        pkt.tag.req_num = tag->req_num;
 436        pkt.tag.type = DR_CPU_ERROR;
 437        pkt.tag.num_records = 0;
 438
 439        msg_len = (sizeof(struct ds_data) +
 440                   sizeof(struct dr_cpu_tag));
 441
 442        pkt.data.tag.len = msg_len - sizeof(struct ds_msg_tag);
 443
 444        __ds_send(dp->lp, &pkt, msg_len);
 445}
 446
 447static void dr_cpu_send_error(struct ds_info *dp,
 448                              struct ds_cap_state *cp,
 449                              struct ds_data *data)
 450{
 451        unsigned long flags;
 452
 453        spin_lock_irqsave(&ds_lock, flags);
 454        __dr_cpu_send_error(dp, cp, data);
 455        spin_unlock_irqrestore(&ds_lock, flags);
 456}
 457
 458#define CPU_SENTINEL    0xffffffff
 459
 460static void purge_dups(u32 *list, u32 num_ents)
 461{
 462        unsigned int i;
 463
 464        for (i = 0; i < num_ents; i++) {
 465                u32 cpu = list[i];
 466                unsigned int j;
 467
 468                if (cpu == CPU_SENTINEL)
 469                        continue;
 470
 471                for (j = i + 1; j < num_ents; j++) {
 472                        if (list[j] == cpu)
 473                                list[j] = CPU_SENTINEL;
 474                }
 475        }
 476}
 477
 478static int dr_cpu_size_response(int ncpus)
 479{
 480        return (sizeof(struct ds_data) +
 481                sizeof(struct dr_cpu_tag) +
 482                (sizeof(struct dr_cpu_resp_entry) * ncpus));
 483}
 484
 485static void dr_cpu_init_response(struct ds_data *resp, u64 req_num,
 486                                 u64 handle, int resp_len, int ncpus,
 487                                 cpumask_t *mask, u32 default_stat)
 488{
 489        struct dr_cpu_resp_entry *ent;
 490        struct dr_cpu_tag *tag;
 491        int i, cpu;
 492
 493        tag = (struct dr_cpu_tag *) (resp + 1);
 494        ent = (struct dr_cpu_resp_entry *) (tag + 1);
 495
 496        resp->tag.type = DS_DATA;
 497        resp->tag.len = resp_len - sizeof(struct ds_msg_tag);
 498        resp->handle = handle;
 499        tag->req_num = req_num;
 500        tag->type = DR_CPU_OK;
 501        tag->num_records = ncpus;
 502
 503        i = 0;
 504        for_each_cpu(cpu, mask) {
 505                ent[i].cpu = cpu;
 506                ent[i].result = DR_CPU_RES_OK;
 507                ent[i].stat = default_stat;
 508                i++;
 509        }
 510        BUG_ON(i != ncpus);
 511}
 512
 513static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus,
 514                        u32 res, u32 stat)
 515{
 516        struct dr_cpu_resp_entry *ent;
 517        struct dr_cpu_tag *tag;
 518        int i;
 519
 520        tag = (struct dr_cpu_tag *) (resp + 1);
 521        ent = (struct dr_cpu_resp_entry *) (tag + 1);
 522
 523        for (i = 0; i < ncpus; i++) {
 524                if (ent[i].cpu != cpu)
 525                        continue;
 526                ent[i].result = res;
 527                ent[i].stat = stat;
 528                break;
 529        }
 530}
 531
 532static int dr_cpu_configure(struct ds_info *dp, struct ds_cap_state *cp,
 533                            u64 req_num, cpumask_t *mask)
 534{
 535        struct ds_data *resp;
 536        int resp_len, ncpus, cpu;
 537        unsigned long flags;
 538
 539        ncpus = cpumask_weight(mask);
 540        resp_len = dr_cpu_size_response(ncpus);
 541        resp = kzalloc(resp_len, GFP_KERNEL);
 542        if (!resp)
 543                return -ENOMEM;
 544
 545        dr_cpu_init_response(resp, req_num, cp->handle,
 546                             resp_len, ncpus, mask,
 547                             DR_CPU_STAT_CONFIGURED);
 548
 549        mdesc_populate_present_mask(mask);
 550        mdesc_fill_in_cpu_data(mask);
 551
 552        for_each_cpu(cpu, mask) {
 553                int err;
 554
 555                printk(KERN_INFO "ds-%llu: Starting cpu %d...\n",
 556                       dp->id, cpu);
 557                err = cpu_up(cpu);
 558                if (err) {
 559                        __u32 res = DR_CPU_RES_FAILURE;
 560                        __u32 stat = DR_CPU_STAT_UNCONFIGURED;
 561
 562                        if (!cpu_present(cpu)) {
 563                                /* CPU not present in MD */
 564                                res = DR_CPU_RES_NOT_IN_MD;
 565                                stat = DR_CPU_STAT_NOT_PRESENT;
 566                        } else if (err == -ENODEV) {
 567                                /* CPU did not call in successfully */
 568                                res = DR_CPU_RES_CPU_NOT_RESPONDING;
 569                        }
 570
 571                        printk(KERN_INFO "ds-%llu: CPU startup failed err=%d\n",
 572                               dp->id, err);
 573                        dr_cpu_mark(resp, cpu, ncpus, res, stat);
 574                }
 575        }
 576
 577        spin_lock_irqsave(&ds_lock, flags);
 578        __ds_send(dp->lp, resp, resp_len);
 579        spin_unlock_irqrestore(&ds_lock, flags);
 580
 581        kfree(resp);
 582
 583        /* Redistribute IRQs, taking into account the new cpus.  */
 584        fixup_irqs();
 585
 586        return 0;
 587}
 588
 589static int dr_cpu_unconfigure(struct ds_info *dp,
 590                              struct ds_cap_state *cp,
 591                              u64 req_num,
 592                              cpumask_t *mask)
 593{
 594        struct ds_data *resp;
 595        int resp_len, ncpus, cpu;
 596        unsigned long flags;
 597
 598        ncpus = cpumask_weight(mask);
 599        resp_len = dr_cpu_size_response(ncpus);
 600        resp = kzalloc(resp_len, GFP_KERNEL);
 601        if (!resp)
 602                return -ENOMEM;
 603
 604        dr_cpu_init_response(resp, req_num, cp->handle,
 605                             resp_len, ncpus, mask,
 606                             DR_CPU_STAT_UNCONFIGURED);
 607
 608        for_each_cpu(cpu, mask) {
 609                int err;
 610
 611                printk(KERN_INFO "ds-%llu: Shutting down cpu %d...\n",
 612                       dp->id, cpu);
 613                err = cpu_down(cpu);
 614                if (err)
 615                        dr_cpu_mark(resp, cpu, ncpus,
 616                                    DR_CPU_RES_FAILURE,
 617                                    DR_CPU_STAT_CONFIGURED);
 618        }
 619
 620        spin_lock_irqsave(&ds_lock, flags);
 621        __ds_send(dp->lp, resp, resp_len);
 622        spin_unlock_irqrestore(&ds_lock, flags);
 623
 624        kfree(resp);
 625
 626        return 0;
 627}
 628
 629static void dr_cpu_data(struct ds_info *dp, struct ds_cap_state *cp, void *buf,
 630                        int len)
 631{
 632        struct ds_data *data = buf;
 633        struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1);
 634        u32 *cpu_list = (u32 *) (tag + 1);
 635        u64 req_num = tag->req_num;
 636        cpumask_t mask;
 637        unsigned int i;
 638        int err;
 639
 640        switch (tag->type) {
 641        case DR_CPU_CONFIGURE:
 642        case DR_CPU_UNCONFIGURE:
 643        case DR_CPU_FORCE_UNCONFIGURE:
 644                break;
 645
 646        default:
 647                dr_cpu_send_error(dp, cp, data);
 648                return;
 649        }
 650
 651        purge_dups(cpu_list, tag->num_records);
 652
 653        cpumask_clear(&mask);
 654        for (i = 0; i < tag->num_records; i++) {
 655                if (cpu_list[i] == CPU_SENTINEL)
 656                        continue;
 657
 658                if (cpu_list[i] < nr_cpu_ids)
 659                        cpumask_set_cpu(cpu_list[i], &mask);
 660        }
 661
 662        if (tag->type == DR_CPU_CONFIGURE)
 663                err = dr_cpu_configure(dp, cp, req_num, &mask);
 664        else
 665                err = dr_cpu_unconfigure(dp, cp, req_num, &mask);
 666
 667        if (err)
 668                dr_cpu_send_error(dp, cp, data);
 669}
 670#endif /* CONFIG_HOTPLUG_CPU */
 671
 672struct ds_pri_msg {
 673        __u64                           req_num;
 674        __u64                           type;
 675#define DS_PRI_REQUEST                  0x00
 676#define DS_PRI_DATA                     0x01
 677#define DS_PRI_UPDATE                   0x02
 678};
 679
 680static void ds_pri_data(struct ds_info *dp,
 681                        struct ds_cap_state *cp,
 682                        void *buf, int len)
 683{
 684        struct ds_data *dpkt = buf;
 685        struct ds_pri_msg *rp;
 686
 687        rp = (struct ds_pri_msg *) (dpkt + 1);
 688
 689        printk(KERN_INFO "ds-%llu: PRI REQ [%llx:%llx], len=%d\n",
 690               dp->id, rp->req_num, rp->type, len);
 691}
 692
 693struct ds_var_hdr {
 694        __u32                           type;
 695#define DS_VAR_SET_REQ                  0x00
 696#define DS_VAR_DELETE_REQ               0x01
 697#define DS_VAR_SET_RESP                 0x02
 698#define DS_VAR_DELETE_RESP              0x03
 699};
 700
 701struct ds_var_set_msg {
 702        struct ds_var_hdr               hdr;
 703        char                            name_and_value[0];
 704};
 705
 706struct ds_var_delete_msg {
 707        struct ds_var_hdr               hdr;
 708        char                            name[0];
 709};
 710
 711struct ds_var_resp {
 712        struct ds_var_hdr               hdr;
 713        __u32                           result;
 714#define DS_VAR_SUCCESS                  0x00
 715#define DS_VAR_NO_SPACE                 0x01
 716#define DS_VAR_INVALID_VAR              0x02
 717#define DS_VAR_INVALID_VAL              0x03
 718#define DS_VAR_NOT_PRESENT              0x04
 719};
 720
 721static DEFINE_MUTEX(ds_var_mutex);
 722static int ds_var_doorbell;
 723static int ds_var_response;
 724
 725static void ds_var_data(struct ds_info *dp,
 726                        struct ds_cap_state *cp,
 727                        void *buf, int len)
 728{
 729        struct ds_data *dpkt = buf;
 730        struct ds_var_resp *rp;
 731
 732        rp = (struct ds_var_resp *) (dpkt + 1);
 733
 734        if (rp->hdr.type != DS_VAR_SET_RESP &&
 735            rp->hdr.type != DS_VAR_DELETE_RESP)
 736                return;
 737
 738        ds_var_response = rp->result;
 739        wmb();
 740        ds_var_doorbell = 1;
 741}
 742
 743void ldom_set_var(const char *var, const char *value)
 744{
 745        struct ds_cap_state *cp;
 746        struct ds_info *dp;
 747        unsigned long flags;
 748
 749        spin_lock_irqsave(&ds_lock, flags);
 750        cp = NULL;
 751        for (dp = ds_info_list; dp; dp = dp->next) {
 752                struct ds_cap_state *tmp;
 753
 754                tmp = find_cap_by_string(dp, "var-config");
 755                if (tmp && tmp->state == CAP_STATE_REGISTERED) {
 756                        cp = tmp;
 757                        break;
 758                }
 759        }
 760        if (!cp) {
 761                for (dp = ds_info_list; dp; dp = dp->next) {
 762                        struct ds_cap_state *tmp;
 763
 764                        tmp = find_cap_by_string(dp, "var-config-backup");
 765                        if (tmp && tmp->state == CAP_STATE_REGISTERED) {
 766                                cp = tmp;
 767                                break;
 768                        }
 769                }
 770        }
 771        spin_unlock_irqrestore(&ds_lock, flags);
 772
 773        if (cp) {
 774                union {
 775                        struct {
 776                                struct ds_data          data;
 777                                struct ds_var_set_msg   msg;
 778                        } header;
 779                        char                    all[512];
 780                } pkt;
 781                char  *base, *p;
 782                int msg_len, loops;
 783
 784                if (strlen(var) + strlen(value) + 2 >
 785                    sizeof(pkt) - sizeof(pkt.header)) {
 786                        printk(KERN_ERR PFX
 787                                "contents length: %zu, which more than max: %lu,"
 788                                "so could not set (%s) variable to (%s).\n",
 789                                strlen(var) + strlen(value) + 2,
 790                                sizeof(pkt) - sizeof(pkt.header), var, value);
 791                        return;
 792                }
 793
 794                memset(&pkt, 0, sizeof(pkt));
 795                pkt.header.data.tag.type = DS_DATA;
 796                pkt.header.data.handle = cp->handle;
 797                pkt.header.msg.hdr.type = DS_VAR_SET_REQ;
 798                base = p = &pkt.header.msg.name_and_value[0];
 799                strcpy(p, var);
 800                p += strlen(var) + 1;
 801                strcpy(p, value);
 802                p += strlen(value) + 1;
 803
 804                msg_len = (sizeof(struct ds_data) +
 805                           sizeof(struct ds_var_set_msg) +
 806                           (p - base));
 807                msg_len = (msg_len + 3) & ~3;
 808                pkt.header.data.tag.len = msg_len - sizeof(struct ds_msg_tag);
 809
 810                mutex_lock(&ds_var_mutex);
 811
 812                spin_lock_irqsave(&ds_lock, flags);
 813                ds_var_doorbell = 0;
 814                ds_var_response = -1;
 815
 816                __ds_send(dp->lp, &pkt, msg_len);
 817                spin_unlock_irqrestore(&ds_lock, flags);
 818
 819                loops = 1000;
 820                while (ds_var_doorbell == 0) {
 821                        if (loops-- < 0)
 822                                break;
 823                        barrier();
 824                        udelay(100);
 825                }
 826
 827                mutex_unlock(&ds_var_mutex);
 828
 829                if (ds_var_doorbell == 0 ||
 830                    ds_var_response != DS_VAR_SUCCESS)
 831                        printk(KERN_ERR "ds-%llu: var-config [%s:%s] "
 832                               "failed, response(%d).\n",
 833                               dp->id, var, value,
 834                               ds_var_response);
 835        } else {
 836                printk(KERN_ERR PFX "var-config not registered so "
 837                       "could not set (%s) variable to (%s).\n",
 838                       var, value);
 839        }
 840}
 841
 842static char full_boot_str[256] __attribute__((aligned(32)));
 843static int reboot_data_supported;
 844
 845void ldom_reboot(const char *boot_command)
 846{
 847        /* Don't bother with any of this if the boot_command
 848         * is empty.
 849         */
 850        if (boot_command && strlen(boot_command)) {
 851                unsigned long len;
 852
 853                snprintf(full_boot_str, sizeof(full_boot_str), "boot %s",
 854                         boot_command);
 855                len = strlen(full_boot_str);
 856
 857                if (reboot_data_supported) {
 858                        unsigned long ra = kimage_addr_to_ra(full_boot_str);
 859                        unsigned long hv_ret;
 860
 861                        hv_ret = sun4v_reboot_data_set(ra, len);
 862                        if (hv_ret != HV_EOK)
 863                                pr_err("SUN4V: Unable to set reboot data "
 864                                       "hv_ret=%lu\n", hv_ret);
 865                } else {
 866                        ldom_set_var("reboot-command", full_boot_str);
 867                }
 868        }
 869        sun4v_mach_sir();
 870}
 871
 872void ldom_power_off(void)
 873{
 874        sun4v_mach_exit(0);
 875}
 876
 877static void ds_conn_reset(struct ds_info *dp)
 878{
 879        printk(KERN_ERR "ds-%llu: ds_conn_reset() from %pf\n",
 880               dp->id, __builtin_return_address(0));
 881}
 882
 883static int register_services(struct ds_info *dp)
 884{
 885        struct ldc_channel *lp = dp->lp;
 886        int i;
 887
 888        for (i = 0; i < dp->num_ds_states; i++) {
 889                struct {
 890                        struct ds_reg_req req;
 891                        u8 id_buf[256];
 892                } pbuf;
 893                struct ds_cap_state *cp = &dp->ds_states[i];
 894                int err, msg_len;
 895                u64 new_count;
 896
 897                if (cp->state == CAP_STATE_REGISTERED)
 898                        continue;
 899
 900                new_count = sched_clock() & 0xffffffff;
 901                cp->handle = ((u64) i << 32) | new_count;
 902
 903                msg_len = (sizeof(struct ds_reg_req) +
 904                           strlen(cp->service_id));
 905
 906                memset(&pbuf, 0, sizeof(pbuf));
 907                pbuf.req.tag.type = DS_REG_REQ;
 908                pbuf.req.tag.len = (msg_len - sizeof(struct ds_msg_tag));
 909                pbuf.req.handle = cp->handle;
 910                pbuf.req.major = 1;
 911                pbuf.req.minor = 0;
 912                strcpy(pbuf.id_buf, cp->service_id);
 913
 914                err = __ds_send(lp, &pbuf, msg_len);
 915                if (err > 0)
 916                        cp->state = CAP_STATE_REG_SENT;
 917        }
 918        return 0;
 919}
 920
 921static int ds_handshake(struct ds_info *dp, struct ds_msg_tag *pkt)
 922{
 923
 924        if (dp->hs_state == DS_HS_START) {
 925                if (pkt->type != DS_INIT_ACK)
 926                        goto conn_reset;
 927
 928                dp->hs_state = DS_HS_DONE;
 929
 930                return register_services(dp);
 931        }
 932
 933        if (dp->hs_state != DS_HS_DONE)
 934                goto conn_reset;
 935
 936        if (pkt->type == DS_REG_ACK) {
 937                struct ds_reg_ack *ap = (struct ds_reg_ack *) pkt;
 938                struct ds_cap_state *cp = find_cap(dp, ap->handle);
 939
 940                if (!cp) {
 941                        printk(KERN_ERR "ds-%llu: REG ACK for unknown "
 942                               "handle %llx\n", dp->id, ap->handle);
 943                        return 0;
 944                }
 945                printk(KERN_INFO "ds-%llu: Registered %s service.\n",
 946                       dp->id, cp->service_id);
 947                cp->state = CAP_STATE_REGISTERED;
 948        } else if (pkt->type == DS_REG_NACK) {
 949                struct ds_reg_nack *np = (struct ds_reg_nack *) pkt;
 950                struct ds_cap_state *cp = find_cap(dp, np->handle);
 951
 952                if (!cp) {
 953                        printk(KERN_ERR "ds-%llu: REG NACK for "
 954                               "unknown handle %llx\n",
 955                               dp->id, np->handle);
 956                        return 0;
 957                }
 958                cp->state = CAP_STATE_UNKNOWN;
 959        }
 960
 961        return 0;
 962
 963conn_reset:
 964        ds_conn_reset(dp);
 965        return -ECONNRESET;
 966}
 967
 968static void __send_ds_nack(struct ds_info *dp, u64 handle)
 969{
 970        struct ds_data_nack nack = {
 971                .tag = {
 972                        .type = DS_NACK,
 973                        .len = (sizeof(struct ds_data_nack) -
 974                                sizeof(struct ds_msg_tag)),
 975                },
 976                .handle = handle,
 977                .result = DS_INV_HDL,
 978        };
 979
 980        __ds_send(dp->lp, &nack, sizeof(nack));
 981}
 982
 983static LIST_HEAD(ds_work_list);
 984static DECLARE_WAIT_QUEUE_HEAD(ds_wait);
 985
 986struct ds_queue_entry {
 987        struct list_head                list;
 988        struct ds_info                  *dp;
 989        int                             req_len;
 990        int                             __pad;
 991        u64                             req[0];
 992};
 993
 994static void process_ds_work(void)
 995{
 996        struct ds_queue_entry *qp, *tmp;
 997        unsigned long flags;
 998        LIST_HEAD(todo);
 999
1000        spin_lock_irqsave(&ds_lock, flags);
1001        list_splice_init(&ds_work_list, &todo);
1002        spin_unlock_irqrestore(&ds_lock, flags);
1003
1004        list_for_each_entry_safe(qp, tmp, &todo, list) {
1005                struct ds_data *dpkt = (struct ds_data *) qp->req;
1006                struct ds_info *dp = qp->dp;
1007                struct ds_cap_state *cp = find_cap(dp, dpkt->handle);
1008                int req_len = qp->req_len;
1009
1010                if (!cp) {
1011                        printk(KERN_ERR "ds-%llu: Data for unknown "
1012                               "handle %llu\n",
1013                               dp->id, dpkt->handle);
1014
1015                        spin_lock_irqsave(&ds_lock, flags);
1016                        __send_ds_nack(dp, dpkt->handle);
1017                        spin_unlock_irqrestore(&ds_lock, flags);
1018                } else {
1019                        cp->data(dp, cp, dpkt, req_len);
1020                }
1021
1022                list_del(&qp->list);
1023                kfree(qp);
1024        }
1025}
1026
1027static int ds_thread(void *__unused)
1028{
1029        DEFINE_WAIT(wait);
1030
1031        while (1) {
1032                prepare_to_wait(&ds_wait, &wait, TASK_INTERRUPTIBLE);
1033                if (list_empty(&ds_work_list))
1034                        schedule();
1035                finish_wait(&ds_wait, &wait);
1036
1037                if (kthread_should_stop())
1038                        break;
1039
1040                process_ds_work();
1041        }
1042
1043        return 0;
1044}
1045
1046static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len)
1047{
1048        struct ds_data *dpkt = (struct ds_data *) pkt;
1049        struct ds_queue_entry *qp;
1050
1051        qp = kmalloc(sizeof(struct ds_queue_entry) + len, GFP_ATOMIC);
1052        if (!qp) {
1053                __send_ds_nack(dp, dpkt->handle);
1054        } else {
1055                qp->dp = dp;
1056                memcpy(&qp->req, pkt, len);
1057                list_add_tail(&qp->list, &ds_work_list);
1058                wake_up(&ds_wait);
1059        }
1060        return 0;
1061}
1062
1063static void ds_up(struct ds_info *dp)
1064{
1065        struct ldc_channel *lp = dp->lp;
1066        struct ds_ver_req req;
1067        int err;
1068
1069        req.tag.type = DS_INIT_REQ;
1070        req.tag.len = sizeof(req) - sizeof(struct ds_msg_tag);
1071        req.ver.major = 1;
1072        req.ver.minor = 0;
1073
1074        err = __ds_send(lp, &req, sizeof(req));
1075        if (err > 0)
1076                dp->hs_state = DS_HS_START;
1077}
1078
1079static void ds_reset(struct ds_info *dp)
1080{
1081        int i;
1082
1083        dp->hs_state = 0;
1084
1085        for (i = 0; i < dp->num_ds_states; i++) {
1086                struct ds_cap_state *cp = &dp->ds_states[i];
1087
1088                cp->state = CAP_STATE_UNKNOWN;
1089        }
1090}
1091
1092static void ds_event(void *arg, int event)
1093{
1094        struct ds_info *dp = arg;
1095        struct ldc_channel *lp = dp->lp;
1096        unsigned long flags;
1097        int err;
1098
1099        spin_lock_irqsave(&ds_lock, flags);
1100
1101        if (event == LDC_EVENT_UP) {
1102                ds_up(dp);
1103                spin_unlock_irqrestore(&ds_lock, flags);
1104                return;
1105        }
1106
1107        if (event == LDC_EVENT_RESET) {
1108                ds_reset(dp);
1109                spin_unlock_irqrestore(&ds_lock, flags);
1110                return;
1111        }
1112
1113        if (event != LDC_EVENT_DATA_READY) {
1114                printk(KERN_WARNING "ds-%llu: Unexpected LDC event %d\n",
1115                       dp->id, event);
1116                spin_unlock_irqrestore(&ds_lock, flags);
1117                return;
1118        }
1119
1120        err = 0;
1121        while (1) {
1122                struct ds_msg_tag *tag;
1123
1124                err = ldc_read(lp, dp->rcv_buf, sizeof(*tag));
1125
1126                if (unlikely(err < 0)) {
1127                        if (err == -ECONNRESET)
1128                                ds_conn_reset(dp);
1129                        break;
1130                }
1131                if (err == 0)
1132                        break;
1133
1134                tag = dp->rcv_buf;
1135                err = ldc_read(lp, tag + 1, tag->len);
1136
1137                if (unlikely(err < 0)) {
1138                        if (err == -ECONNRESET)
1139                                ds_conn_reset(dp);
1140                        break;
1141                }
1142                if (err < tag->len)
1143                        break;
1144
1145                if (tag->type < DS_DATA)
1146                        err = ds_handshake(dp, dp->rcv_buf);
1147                else
1148                        err = ds_data(dp, dp->rcv_buf,
1149                                      sizeof(*tag) + err);
1150                if (err == -ECONNRESET)
1151                        break;
1152        }
1153
1154        spin_unlock_irqrestore(&ds_lock, flags);
1155}
1156
1157static int ds_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1158{
1159        static int ds_version_printed;
1160        struct ldc_channel_config ds_cfg = {
1161                .event          = ds_event,
1162                .mtu            = 4096,
1163                .mode           = LDC_MODE_STREAM,
1164        };
1165        struct mdesc_handle *hp;
1166        struct ldc_channel *lp;
1167        struct ds_info *dp;
1168        const u64 *val;
1169        int err, i;
1170
1171        if (ds_version_printed++ == 0)
1172                printk(KERN_INFO "%s", version);
1173
1174        dp = kzalloc(sizeof(*dp), GFP_KERNEL);
1175        err = -ENOMEM;
1176        if (!dp)
1177                goto out_err;
1178
1179        hp = mdesc_grab();
1180        val = mdesc_get_property(hp, vdev->mp, "id", NULL);
1181        if (val)
1182                dp->id = *val;
1183        mdesc_release(hp);
1184
1185        dp->rcv_buf = kzalloc(4096, GFP_KERNEL);
1186        if (!dp->rcv_buf)
1187                goto out_free_dp;
1188
1189        dp->rcv_buf_len = 4096;
1190
1191        dp->ds_states = kmemdup(ds_states_template,
1192                                sizeof(ds_states_template), GFP_KERNEL);
1193        if (!dp->ds_states)
1194                goto out_free_rcv_buf;
1195
1196        dp->num_ds_states = ARRAY_SIZE(ds_states_template);
1197
1198        for (i = 0; i < dp->num_ds_states; i++)
1199                dp->ds_states[i].handle = ((u64)i << 32);
1200
1201        ds_cfg.tx_irq = vdev->tx_irq;
1202        ds_cfg.rx_irq = vdev->rx_irq;
1203
1204        lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp, "DS");
1205        if (IS_ERR(lp)) {
1206                err = PTR_ERR(lp);
1207                goto out_free_ds_states;
1208        }
1209        dp->lp = lp;
1210
1211        err = ldc_bind(lp);
1212        if (err)
1213                goto out_free_ldc;
1214
1215        spin_lock_irq(&ds_lock);
1216        dp->next = ds_info_list;
1217        ds_info_list = dp;
1218        spin_unlock_irq(&ds_lock);
1219
1220        return err;
1221
1222out_free_ldc:
1223        ldc_free(dp->lp);
1224
1225out_free_ds_states:
1226        kfree(dp->ds_states);
1227
1228out_free_rcv_buf:
1229        kfree(dp->rcv_buf);
1230
1231out_free_dp:
1232        kfree(dp);
1233
1234out_err:
1235        return err;
1236}
1237
1238static int ds_remove(struct vio_dev *vdev)
1239{
1240        return 0;
1241}
1242
1243static const struct vio_device_id ds_match[] = {
1244        {
1245                .type = "domain-services-port",
1246        },
1247        {},
1248};
1249
1250static struct vio_driver ds_driver = {
1251        .id_table       = ds_match,
1252        .probe          = ds_probe,
1253        .remove         = ds_remove,
1254        .name           = "ds",
1255};
1256
1257static int __init ds_init(void)
1258{
1259        unsigned long hv_ret, major, minor;
1260
1261        if (tlb_type == hypervisor) {
1262                hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor);
1263                if (hv_ret == HV_EOK) {
1264                        pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n",
1265                                major, minor);
1266                        reboot_data_supported = 1;
1267                }
1268        }
1269        kthread_run(ds_thread, NULL, "kldomd");
1270
1271        return vio_register_driver(&ds_driver);
1272}
1273
1274fs_initcall(ds_init);
1275