17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
58faf39btaylor * Common Development and Distribution License (the "License").
68faf39btaylor * You may not use this file except in compliance with the License.
77c478bdstevel@tonic-gate *
87c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bdstevel@tonic-gate * See the License for the specific language governing permissions
117c478bdstevel@tonic-gate * and limitations under the License.
127c478bdstevel@tonic-gate *
137c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bdstevel@tonic-gate *
197c478bdstevel@tonic-gate * CDDL HEADER END
207c478bdstevel@tonic-gate */
217c478bdstevel@tonic-gate/*
221b94a41Chris Horne * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bdstevel@tonic-gate */
247c478bdstevel@tonic-gate
257c478bdstevel@tonic-gate/*
267c478bdstevel@tonic-gate *
277c478bdstevel@tonic-gate * Generic Capabilities Routines
287c478bdstevel@tonic-gate *
297c478bdstevel@tonic-gate */
307c478bdstevel@tonic-gate
317c478bdstevel@tonic-gate#include <sys/scsi/scsi.h>
3236945f7mrj#ifdef	__x86
3336945f7mrj#include <sys/ddi_isa.h>
3436945f7mrj#endif
357c478bdstevel@tonic-gate
367c478bdstevel@tonic-gate#define	A_TO_TRAN(ap)	(ap->a_hba_tran)
377c478bdstevel@tonic-gate
3836945f7mrj
397c478bdstevel@tonic-gateint
407c478bdstevel@tonic-gatescsi_ifgetcap(struct scsi_address *ap, char *cap, int whom)
417c478bdstevel@tonic-gate{
4236945f7mrj	int capability;
4336945f7mrj#ifdef	__x86
4436945f7mrj	ddi_dma_attr_t *dmaattr;
4536945f7mrj	int ckey;
4636945f7mrj#endif
4736945f7mrj
4836945f7mrj
4936945f7mrj	capability = (*A_TO_TRAN(ap)->tran_getcap)(ap, cap, whom);
5036945f7mrj
5136945f7mrj#ifdef	__x86
5236945f7mrj	if (cap != NULL) {
5336945f7mrj		ckey = scsi_hba_lookup_capstr(cap);
5436945f7mrj		dmaattr = &ap->a_hba_tran->tran_dma_attr;
5536945f7mrj		switch (ckey) {
5636945f7mrj		case SCSI_CAP_DMA_MAX:
5736945f7mrj			/*
5836945f7mrj			 * If the HBA is unable to reach all the memory in
5936945f7mrj			 * the system, the maximum copy buffer size may limit
6036945f7mrj			 * the size of the max DMA.
6136945f7mrj			 */
6236945f7mrj			if (i_ddi_copybuf_required(dmaattr)) {
6336945f7mrj				capability = MIN(capability,
6436945f7mrj				    i_ddi_copybuf_size());
6536945f7mrj			}
6636945f7mrj
6736945f7mrj			/*
6836945f7mrj			 * make sure the value we return is a whole multiple of
6936945f7mrj			 * the granlarity.
7036945f7mrj			 */
7136945f7mrj			if (dmaattr->dma_attr_granular > 1) {
7236945f7mrj				capability = capability -
7336945f7mrj				    (capability % dmaattr->dma_attr_granular);
7436945f7mrj			}
7536945f7mrj
7636945f7mrj			break;
7736945f7mrj
7836945f7mrj		case SCSI_CAP_DMA_MAX_ARCH:
7936945f7mrj			capability = i_ddi_dma_max(ap->a_hba_tran->tran_hba_dip,
8036945f7mrj			    dmaattr);
8136945f7mrj
8236945f7mrj			break;
8336945f7mrj
8436945f7mrj		/*FALLTHROUGH*/
8536945f7mrj		}
8636945f7mrj	}
8736945f7mrj#endif
8836945f7mrj
8936945f7mrj	return (capability);
907c478bdstevel@tonic-gate}
917c478bdstevel@tonic-gate
927c478bdstevel@tonic-gateint
937c478bdstevel@tonic-gatescsi_ifsetcap(struct scsi_address *ap, char *cap, int value, int whom)
947c478bdstevel@tonic-gate{
958faf39btaylor	int rval;
968faf39btaylor	int cidx;
978faf39btaylor
988faf39btaylor	rval = (*A_TO_TRAN(ap)->tran_setcap)(ap, cap, value, whom);
991b94a41Chris Horne	if ((rval == 1) || A_TO_TRAN(ap)->tran_setup_pkt) {
1008faf39btaylor		cidx = scsi_hba_lookup_capstr(cap);
1018faf39btaylor		if (cidx == SCSI_CAP_SECTOR_SIZE) {
1028faf39btaylor			/*
1038faf39btaylor			 * if we have successfully changed the
1048faf39btaylor			 * granularity update SCSA's copy
1058faf39btaylor			 */
1068faf39btaylor			A_TO_TRAN(ap)->tran_dma_attr.dma_attr_granular =
10736945f7mrj			    value;
1088faf39btaylor		}
1098faf39btaylor	}
1108faf39btaylor	return (rval);
1117c478bdstevel@tonic-gate}
112