ata_dma.c revision 507c32411f3f101e90ca2120f042b5ee698ba1d5
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "ata_common.h"
#include "ata_disk.h"
#include "atapi.h"
#include "pciide.h"
/*
* grap the PCI-IDE status byte
*/
/*
* DMA attributes for device I/O
*/
DMA_ATTR_V0, /* dma_attr_version */
0, /* dma_attr_addr_lo */
0xffffffffU, /* dma_attr_addr_hi */
0xffff, /* dma_attr_count_max */
sizeof (int), /* dma_attr_align */
1, /* dma_attr_burstsizes */
1, /* dma_attr_minxfer */
/* note that this value can change */
/* based on max_transfer property */
0xffff, /* dma_attr_seg */
ATA_DMA_NSEGS, /* dma_attr_sgllen */
512, /* dma_attr_granular */
0 /* dma_attr_flags */
};
/*
* DMA attributes for the Bus Mastering PRD table
*
* PRD table Must not cross 4k boundary.
*
* NOTE: the SFF-8038i spec says don't cross a 64k boundary but
* some chip specs seem to think the spec says 4k boundary, Intel
* 82371AB, section 5.2.3. I don't know whether the 4k restriction
* is for real or just a typo. I've specified 4k just to be safe.
* The same Intel spec says the buffer must be 64K aligned, I don't
* believe that and have specified 4 byte alignment.
*
*/
#define PCIIDE_BOUNDARY (0x1000)
DMA_ATTR_V0, /* dma_attr_version */
0, /* dma_attr_addr_lo */
0xffffffffU, /* dma_attr_addr_hi */
sizeof (int), /* dma_attr_align */
1, /* dma_attr_burstsizes */
1, /* dma_attr_minxfer */
PCIIDE_BOUNDARY, /* dma_attr_maxxfer */
1, /* dma_attr_sgllen */
1, /* dma_attr_granular */
0 /* dma_attr_flags */
};
int
{
int rc;
&ata_ctlp->ac_sg_handle);
if (rc != DDI_SUCCESS) {
ADBG_ERROR(("ata_pciide_alloc 0x%p handle %d\n",
goto err3;
}
if (rc != DDI_SUCCESS) {
ADBG_ERROR(("ata_pciide_alloc 0x%p mem %d\n",
goto err2;
}
if (rc != DDI_DMA_MAPPED) {
ADBG_ERROR(("ata_pciide_alloc 0x%p bind %d\n",
goto err1;
}
#define Mask4K 0xfffff000
return (TRUE);
err1:
err2:
err3:
return (FALSE);
}
void
{
return;
}
void
int sg_cnt)
{
int idx;
/*
* Copy the PRD list to controller's phys buffer.
* Copying to a fixed location avoids having to check
* every ata_pkt for alignment and page boundaries.
*/
}
/*
* set the end of table flag in the last entry
*/
/*
* give the pciide chip the physical address of the PRDE table
*/
ADBG_DMA(("ata dma_setup 0x%p 0x%llx\n",
}
void
{
/*
* Set the direction control and start the PCIIDE DMA controller
*/
tmp &= PCIIDE_BMICX_MASK;
return;
}
void
{
/*
* Stop the PCIIDE DMA controller
*/
}
/* ARGSUSED */
void
int single_segment,
int seg_index)
{
ADBG_TRACE(("adp_dma_sg_func: gcmdp 0x%p dmackp 0x%p s %d idx %d\n",
/* store the phys addr and count from the cookie */
/* compute the total bytes in this request */
if (seg_index == 0)
}
int
{
/*
* Get the current PCIIDE status
*/
ADBG_DMA(("ata_pciide_status_clear 0x%p 0x%x\n",
/*
* Clear the latches (and preserve the other bits)
*/
#ifdef NAT_SEMI_PC87415_BUG
/* ??? chip errata ??? */
if (ata_ctlp->ac_nat_semi_bug) {
tmp &= PCIIDE_BMICX_MASK;
}
#endif
return (status);
}
int
{
/*
* Get the PCIIDE DMA controller's current status
*/
ADBG_DMA(("ata_pciide_status_dmacheck_clear 0x%p 0x%x\n",
/*
* check for errors
*/
if (status & PCIIDE_BMISX_IDERR) {
return (TRUE);
}
return (FALSE);
}
/*
* Check for a pending PCI-IDE interrupt
*/
int
{
ADBG_DMA(("ata_pciide_status_pending 0x%p 0x%x\n",
if (status & PCIIDE_BMISX_IDEINTS)
return (TRUE);
return (FALSE);
}