1 /* $OpenBSD: vds.c,v 1.1 2009/12/31 11:58:41 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2009 Mark Kettenis 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/buf.h> 20 #include <sys/device.h> 21 #include <sys/malloc.h> 22 #include <sys/systm.h> 23 24 #include <machine/autoconf.h> 25 #include <machine/hypervisor.h> 26 #include <machine/mdesc.h> 27 28 #include <sparc64/dev/cbusvar.h> 29 30 #ifdef VDS_DEBUG 31 #define DPRINTF(x) printf x 32 #else 33 #define DPRINTF(x) 34 #endif 35 36 struct vds_softc { 37 struct device sc_dv; 38 bus_space_tag_t sc_bustag; 39 bus_dma_tag_t sc_dmatag; 40 }; 41 42 int vds_match(struct device *, void *, void *); 43 void vds_attach(struct device *, struct device *, void *); 44 45 struct cfattach vds_ca = { 46 sizeof(struct vds_softc), vds_match, vds_attach 47 }; 48 49 struct cfdriver vds_cd = { 50 NULL, "vds", DV_DULL 51 }; 52 53 void vds_get_channel_endpoint(int, struct cbus_attach_args *); 54 55 int 56 vds_match(struct device *parent, void *match, void *aux) 57 { 58 struct cbus_attach_args *ca = aux; 59 60 if (strcmp(ca->ca_name, "virtual-disk-server") == 0) 61 return (1); 62 63 return (0); 64 } 65 66 void 67 vds_attach(struct device *parent, struct device *self, void *aux) 68 { 69 struct cbus_attach_args *ca = aux; 70 struct cbus_attach_args nca; 71 struct md_header *hdr; 72 struct md_element *elem; 73 const char *name_blk; 74 const char *str; 75 int idx; 76 int arc; 77 78 printf("\n"); 79 80 hdr = (struct md_header *)mdesc; 81 elem = (struct md_element *)(mdesc + sizeof(struct md_header)); 82 name_blk = mdesc + sizeof(struct md_header) + hdr->node_blk_sz; 83 84 idx = ca->ca_idx; 85 for (; elem[idx].tag != 'E'; idx++) { 86 str = name_blk + elem[idx].name_offset; 87 if (elem[idx].tag != 'a' || strcmp(str, "fwd") != 0) 88 continue; 89 90 arc = elem[idx].d.val; 91 str = name_blk + elem[arc].name_offset; 92 if (strcmp(str, "virtual-device-port") == 0) { 93 bzero(&nca, sizeof(nca)); 94 nca.ca_name = "vds-port"; 95 nca.ca_node = ca->ca_node; 96 nca.ca_bustag = ca->ca_bustag; 97 nca.ca_dmatag = ca->ca_dmatag; 98 vds_get_channel_endpoint(arc, &nca); 99 config_found(self, &nca, cbus_print); 100 } 101 } 102 } 103 104 void 105 vds_get_channel_endpoint(int idx, struct cbus_attach_args *ca) 106 { 107 struct md_header *hdr; 108 struct md_element *elem; 109 const char *name_blk; 110 const char *str; 111 int arc; 112 113 hdr = (struct md_header *)mdesc; 114 elem = (struct md_element *)(mdesc + sizeof(struct md_header)); 115 name_blk = mdesc + sizeof(struct md_header) + hdr->node_blk_sz; 116 117 ca->ca_idx = idx; 118 119 ca->ca_id = -1; 120 ca->ca_tx_ino = -1; 121 ca->ca_rx_ino = -1; 122 123 for (; elem[idx].tag != 'E'; idx++) { 124 str = name_blk + elem[idx].name_offset; 125 if (elem[idx].tag != 'a' || strcmp(str, "fwd") != 0) 126 continue; 127 128 arc = elem[idx].d.val; 129 str = name_blk + elem[arc].name_offset; 130 if (strcmp(str, "channel-endpoint") == 0) { 131 ca->ca_id = mdesc_get_prop_val(arc, "id"); 132 ca->ca_tx_ino = mdesc_get_prop_val(arc, "tx-ino"); 133 ca->ca_rx_ino = mdesc_get_prop_val(arc, "rx-ino"); 134 return; 135 } 136 } 137 } 138