1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <io/xdf_shell.h> 27 28 #include <sys/scsi/targets/sddef.h> 29 30 /* 31 * We're emulating (and possibly layering on top of) sd devices, so xdf 32 * disk unit mappings must match up with sd disk unit mappings'. 33 */ 34 #if !defined(XDF_PSHIFT) 35 #error "can't find definition for xdf unit mappings - XDF_PSHIFT" 36 #endif /* XDF_PSHIFT */ 37 38 #if !defined(SDUNIT_SHIFT) 39 #error "can't find definition for cmdk unit mappings - SDUNIT_SHIFT" 40 #endif /* SDUNIT_SHIFT */ 41 42 #if ((XDF_PSHIFT - SDUNIT_SHIFT) != 0) 43 #error "sd and xdf unit mappings don't match." 44 #endif /* ((XDF_PSHIFT - SDUNIT_SHIFT) != 0) */ 45 46 extern const struct dev_ops sd_ops; 47 extern void *sd_state; 48 49 /* 50 * Globals required by xdf_shell.c 51 */ 52 const char *xdfs_c_name = "sd"; 53 const char *xdfs_c_linkinfo = "PV SCSI Disk Driver"; 54 void **xdfs_c_hvm_ss = &sd_state; 55 const size_t xdfs_c_hvm_ss_size = sizeof (struct sd_lun); 56 const struct dev_ops *xdfs_c_hvm_dev_ops = &sd_ops; 57 58 const xdfs_h2p_map_t xdfs_c_h2p_map[] = { 59 { "/pci@0,0/pci-ide@1,1/ide@0/sd@0,0", "/xpvd/xdf@768" }, 60 { "/pci@0,0/pci-ide@1,1/ide@0/sd@1,0", "/xpvd/xdf@832" }, 61 { "/pci@0,0/pci-ide@1,1/ide@1/sd@0,0", "/xpvd/xdf@5632" }, 62 { "/pci@0,0/pci-ide@1,1/ide@1/sd@1,0", "/xpvd/xdf@5696" }, 63 { NULL, 0 } 64 }; 65 66 /*ARGSUSED*/ 67 int 68 xdfs_c_ioctl(xdfs_state_t *xsp, dev_t dev, int part, 69 int cmd, intptr_t arg, int flag, cred_t *credp, int *rvalp, boolean_t *done) 70 { 71 dev_info_t *dip = xsp->xdfss_dip; 72 int instance = ddi_get_instance(dip); 73 int rv; 74 75 *done = B_TRUE; 76 switch (cmd) { 77 case DKIOCINFO: { 78 struct dk_cinfo info; 79 80 /* Pass on the ioctl request, save the response */ 81 if ((rv = ldi_ioctl(xsp->xdfss_tgt_lh[part], 82 cmd, (intptr_t)&info, FKIOCTL, credp, rvalp)) != 0) 83 return (rv); 84 85 /* Update controller info */ 86 info.dki_cnum = ddi_get_instance(ddi_get_parent(dip)); 87 (void) strlcpy(info.dki_cname, 88 ddi_get_name(ddi_get_parent(dip)), sizeof (info.dki_cname)); 89 90 /* Update unit info. */ 91 if (info.dki_ctype == DKC_VBD) { 92 /* 93 * Normally a real scsi device would report the 94 * controller type as DKC_SCSI_CCS. But we don't 95 * emulate a real scsi controller. (Which becomes 96 * apparent if anyone tries to issue us a uscsi(7i) 97 * command.) So instead of reporting DKC_SCSI_CCS, 98 * we report DKC_UNKNOWN. 99 */ 100 info.dki_ctype = DKC_UNKNOWN; 101 } 102 info.dki_unit = instance; 103 (void) strlcpy(info.dki_dname, 104 ddi_driver_name(dip), sizeof (info.dki_dname)); 105 info.dki_addr = 1; 106 107 if (ddi_copyout(&info, (void *)arg, sizeof (info), flag)) 108 return (EFAULT); 109 110 return (0); 111 } 112 default: 113 *done = B_FALSE; 114 return (0); 115 } /* switch (cmd) */ 116 /*NOTREACHED*/ 117 } 118 119 /*ARGSUSED*/ 120 void 121 xdfs_c_devid_setup(xdfs_state_t *xsp) 122 { 123 /* 124 * Currently we only support cdrom devices, which don't have 125 * devids associated with them. 126 */ 127 ASSERT("cdrom devices don't have a devid"); 128 } 129 130 /*ARGSUSED*/ 131 int 132 xdfs_c_getpgeom(dev_info_t *dip, cmlb_geom_t *pgeom) 133 { 134 /* 135 * Currently we only support cdrom devices, which don't have 136 * a physical geometry, so this routine should never get 137 * invoked. 138 */ 139 ASSERT("cdrom devices don't have any physical geometry"); 140 return (-1); 141 } 142 143 /*ARGSUSED*/ 144 boolean_t 145 xdfs_c_bb_check(xdfs_state_t *xsp) 146 { 147 /* 148 * Currently we only support cdrom devices, which don't have 149 * bad blocks, so this routine should never get invoked. 150 */ 151 ASSERT("cdrom devices don't support bad block mappings"); 152 return (B_TRUE); 153 } 154 155 char * 156 xdfs_c_cmlb_node_type(xdfs_state_t *xsp) 157 { 158 return (xsp->xdfss_tgt_is_cd ? DDI_NT_CD_CHAN : DDI_NT_BLOCK_CHAN); 159 } 160 161 /*ARGSUSED*/ 162 int 163 xdfs_c_cmlb_alter_behavior(xdfs_state_t *xsp) 164 { 165 return (0); 166 } 167 168 void 169 xdfs_c_attach(xdfs_state_t *xsp) 170 { 171 dev_info_t *dip = xsp->xdfss_dip; 172 int dtype = DTYPE_DIRECT; 173 174 if (xsp->xdfss_tgt_is_cd) { 175 dtype = DTYPE_RODIRECT; 176 (void) ddi_prop_create(DDI_DEV_T_NONE, dip, 177 DDI_PROP_CANSLEEP, "removable-media", NULL, 0); 178 } 179 180 /* 181 * We use ndi_* instead of ddi_* because it will result in 182 * INQUIRY_DEVICE_TYPE being a hardware property instead 183 * or a driver property 184 */ 185 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 186 INQUIRY_DEVICE_TYPE, dtype); 187 } 188