xref: /illumos-gate/usr/src/uts/common/io/scsi/impl/scsi_capabilities.c (revision 36945f796054e8cb46d88ec0a84213123cf2b036)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
58faf39b2Staylor  * Common Development and Distribution License (the "License").
68faf39b2Staylor  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*36945f79Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
238faf39b2Staylor  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  *
307c478bd9Sstevel@tonic-gate  * Generic Capabilities Routines
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #include <sys/scsi/scsi.h>
35*36945f79Smrj #ifdef	__x86
36*36945f79Smrj #include <sys/ddi_isa.h>
37*36945f79Smrj #endif
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #define	A_TO_TRAN(ap)	(ap->a_hba_tran)
407c478bd9Sstevel@tonic-gate 
41*36945f79Smrj 
427c478bd9Sstevel@tonic-gate int
437c478bd9Sstevel@tonic-gate scsi_ifgetcap(struct scsi_address *ap, char *cap, int whom)
447c478bd9Sstevel@tonic-gate {
45*36945f79Smrj 	int capability;
46*36945f79Smrj #ifdef	__x86
47*36945f79Smrj 	ddi_dma_attr_t *dmaattr;
48*36945f79Smrj 	int ckey;
49*36945f79Smrj #endif
50*36945f79Smrj 
51*36945f79Smrj 
52*36945f79Smrj 	capability = (*A_TO_TRAN(ap)->tran_getcap)(ap, cap, whom);
53*36945f79Smrj 
54*36945f79Smrj #ifdef	__x86
55*36945f79Smrj 	if (cap != NULL) {
56*36945f79Smrj 		ckey = scsi_hba_lookup_capstr(cap);
57*36945f79Smrj 		dmaattr = &ap->a_hba_tran->tran_dma_attr;
58*36945f79Smrj 		switch (ckey) {
59*36945f79Smrj 		case SCSI_CAP_DMA_MAX:
60*36945f79Smrj 			/*
61*36945f79Smrj 			 * If the HBA is unable to reach all the memory in
62*36945f79Smrj 			 * the system, the maximum copy buffer size may limit
63*36945f79Smrj 			 * the size of the max DMA.
64*36945f79Smrj 			 */
65*36945f79Smrj 			if (i_ddi_copybuf_required(dmaattr)) {
66*36945f79Smrj 				capability = MIN(capability,
67*36945f79Smrj 				    i_ddi_copybuf_size());
68*36945f79Smrj 			}
69*36945f79Smrj 
70*36945f79Smrj 			/*
71*36945f79Smrj 			 * make sure the value we return is a whole multiple of
72*36945f79Smrj 			 * the granlarity.
73*36945f79Smrj 			 */
74*36945f79Smrj 			if (dmaattr->dma_attr_granular > 1) {
75*36945f79Smrj 				capability = capability -
76*36945f79Smrj 				    (capability % dmaattr->dma_attr_granular);
77*36945f79Smrj 			}
78*36945f79Smrj 
79*36945f79Smrj 			break;
80*36945f79Smrj 
81*36945f79Smrj 		case SCSI_CAP_DMA_MAX_ARCH:
82*36945f79Smrj 			capability = i_ddi_dma_max(ap->a_hba_tran->tran_hba_dip,
83*36945f79Smrj 			    dmaattr);
84*36945f79Smrj 
85*36945f79Smrj 			break;
86*36945f79Smrj 
87*36945f79Smrj 		/*FALLTHROUGH*/
88*36945f79Smrj 		}
89*36945f79Smrj 	}
90*36945f79Smrj #endif
91*36945f79Smrj 
92*36945f79Smrj 	return (capability);
937c478bd9Sstevel@tonic-gate }
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate int
967c478bd9Sstevel@tonic-gate scsi_ifsetcap(struct scsi_address *ap, char *cap, int value, int whom)
977c478bd9Sstevel@tonic-gate {
988faf39b2Staylor 	int rval;
998faf39b2Staylor 	int cidx;
1008faf39b2Staylor 
1018faf39b2Staylor 	rval = (*A_TO_TRAN(ap)->tran_setcap)(ap, cap, value, whom);
1020487f1e9Staylor 	if (rval == 1) {
1038faf39b2Staylor 		cidx = scsi_hba_lookup_capstr(cap);
1048faf39b2Staylor 		if (cidx == SCSI_CAP_SECTOR_SIZE) {
1058faf39b2Staylor 			/*
1068faf39b2Staylor 			 * if we have successfully changed the
1078faf39b2Staylor 			 * granularity update SCSA's copy
1088faf39b2Staylor 			 */
1098faf39b2Staylor 			A_TO_TRAN(ap)->tran_dma_attr.dma_attr_granular =
110*36945f79Smrj 			    value;
1118faf39b2Staylor 		}
1128faf39b2Staylor 	}
1138faf39b2Staylor 	return (rval);
1147c478bd9Sstevel@tonic-gate }
115