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