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