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 46extern const struct dev_ops sd_ops; 47extern void *sd_state; 48 49/* 50 * Globals required by xdf_shell.c 51 */ 52const char *xdfs_c_name = "sd"; 53const char *xdfs_c_linkinfo = "PV SCSI Disk Driver"; 54void **xdfs_c_hvm_ss = &sd_state; 55const size_t xdfs_c_hvm_ss_size = sizeof (struct sd_lun); 56const struct dev_ops *xdfs_c_hvm_dev_ops = &sd_ops; 57 58const 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*/ 67int 68xdfs_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*/ 120void 121xdfs_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*/ 131int 132xdfs_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*/ 144boolean_t 145xdfs_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 155char * 156xdfs_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*/ 162int 163xdfs_c_cmlb_alter_behavior(xdfs_state_t *xsp) 164{ 165 return (0); 166} 167 168void 169xdfs_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