xref: /onnv-gate/usr/src/uts/common/io/scsi/impl/scsi_capabilities.c (revision 12399:64bb4582eeeb)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51998Staylor  * Common Development and Distribution License (the "License").
61998Staylor  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*12399SChris.Horne@Sun.COM  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate  *
270Sstevel@tonic-gate  * Generic Capabilities Routines
280Sstevel@tonic-gate  *
290Sstevel@tonic-gate  */
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #include <sys/scsi/scsi.h>
325251Smrj #ifdef	__x86
335251Smrj #include <sys/ddi_isa.h>
345251Smrj #endif
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #define	A_TO_TRAN(ap)	(ap->a_hba_tran)
370Sstevel@tonic-gate 
385251Smrj 
390Sstevel@tonic-gate int
scsi_ifgetcap(struct scsi_address * ap,char * cap,int whom)400Sstevel@tonic-gate scsi_ifgetcap(struct scsi_address *ap, char *cap, int whom)
410Sstevel@tonic-gate {
425251Smrj 	int capability;
435251Smrj #ifdef	__x86
445251Smrj 	ddi_dma_attr_t *dmaattr;
455251Smrj 	int ckey;
465251Smrj #endif
475251Smrj 
485251Smrj 
495251Smrj 	capability = (*A_TO_TRAN(ap)->tran_getcap)(ap, cap, whom);
505251Smrj 
515251Smrj #ifdef	__x86
525251Smrj 	if (cap != NULL) {
535251Smrj 		ckey = scsi_hba_lookup_capstr(cap);
545251Smrj 		dmaattr = &ap->a_hba_tran->tran_dma_attr;
555251Smrj 		switch (ckey) {
565251Smrj 		case SCSI_CAP_DMA_MAX:
575251Smrj 			/*
585251Smrj 			 * If the HBA is unable to reach all the memory in
595251Smrj 			 * the system, the maximum copy buffer size may limit
605251Smrj 			 * the size of the max DMA.
615251Smrj 			 */
625251Smrj 			if (i_ddi_copybuf_required(dmaattr)) {
635251Smrj 				capability = MIN(capability,
645251Smrj 				    i_ddi_copybuf_size());
655251Smrj 			}
665251Smrj 
675251Smrj 			/*
685251Smrj 			 * make sure the value we return is a whole multiple of
695251Smrj 			 * the granlarity.
705251Smrj 			 */
715251Smrj 			if (dmaattr->dma_attr_granular > 1) {
725251Smrj 				capability = capability -
735251Smrj 				    (capability % dmaattr->dma_attr_granular);
745251Smrj 			}
755251Smrj 
765251Smrj 			break;
775251Smrj 
785251Smrj 		case SCSI_CAP_DMA_MAX_ARCH:
795251Smrj 			capability = i_ddi_dma_max(ap->a_hba_tran->tran_hba_dip,
805251Smrj 			    dmaattr);
815251Smrj 
825251Smrj 			break;
835251Smrj 
845251Smrj 		/*FALLTHROUGH*/
855251Smrj 		}
865251Smrj 	}
875251Smrj #endif
885251Smrj 
895251Smrj 	return (capability);
900Sstevel@tonic-gate }
910Sstevel@tonic-gate 
920Sstevel@tonic-gate int
scsi_ifsetcap(struct scsi_address * ap,char * cap,int value,int whom)930Sstevel@tonic-gate scsi_ifsetcap(struct scsi_address *ap, char *cap, int value, int whom)
940Sstevel@tonic-gate {
951998Staylor 	int rval;
961998Staylor 	int cidx;
971998Staylor 
981998Staylor 	rval = (*A_TO_TRAN(ap)->tran_setcap)(ap, cap, value, whom);
99*12399SChris.Horne@Sun.COM 	if ((rval == 1) || A_TO_TRAN(ap)->tran_setup_pkt) {
1001998Staylor 		cidx = scsi_hba_lookup_capstr(cap);
1011998Staylor 		if (cidx == SCSI_CAP_SECTOR_SIZE) {
1021998Staylor 			/*
1031998Staylor 			 * if we have successfully changed the
1041998Staylor 			 * granularity update SCSA's copy
1051998Staylor 			 */
1061998Staylor 			A_TO_TRAN(ap)->tran_dma_attr.dma_attr_granular =
1075251Smrj 			    value;
1081998Staylor 		}
1091998Staylor 	}
1101998Staylor 	return (rval);
1110Sstevel@tonic-gate }
112