#include <sys/conf.h>
#include <sys/ddi.h>
#include <sys/modctl.h>
#include <sys/stat.h>
#include <sys/sunddi.h>
#include <sys/kmem.h>
#include <sys/1394/h1394.h>
#include <sys/1394/adapters/hci1394.h>
void
hci1394_buf_attr_get(ddi_dma_attr_t *dma_attr)
{
dma_attr->dma_attr_version = DMA_ATTR_V0;
dma_attr->dma_attr_addr_lo = (uint64_t)0x00000000;
dma_attr->dma_attr_addr_hi = (uint64_t)0xFFFFFFFF;
dma_attr->dma_attr_count_max = (uint64_t)0xFFFFFFFF;
dma_attr->dma_attr_align = 64;
dma_attr->dma_attr_burstsizes = 0x3FF;
dma_attr->dma_attr_minxfer = 1;
dma_attr->dma_attr_maxxfer = (uint64_t)0xFFFFFFFF;
dma_attr->dma_attr_seg = (uint64_t)0xFFFFFFFF;
dma_attr->dma_attr_sgllen = 0x7FFFFFFF;
dma_attr->dma_attr_granular = 4;
dma_attr->dma_attr_flags = 0;
#if defined(__x86)
dma_attr->dma_attr_seg = (uint64_t)0x7FFF;
#endif
}
int
hci1394_buf_alloc(hci1394_drvinfo_t *drvinfo, hci1394_buf_parms_t *parms,
hci1394_buf_info_t *info, hci1394_buf_handle_t *handle)
{
ddi_dma_attr_t dma_attr;
hci1394_buf_t *buf;
int status;
ASSERT(drvinfo != NULL);
ASSERT(parms != NULL);
ASSERT(info != NULL);
ASSERT(handle != NULL);
buf = kmem_alloc(sizeof (hci1394_buf_t), KM_SLEEP);
*handle = buf;
buf->bu_drvinfo = drvinfo;
_NOTE(SCHEME_PROTECTS_DATA("unique (on stack)", ddi_dma_attr_t))
hci1394_buf_attr_get(&dma_attr);
dma_attr.dma_attr_sgllen = parms->bp_max_cookies;
dma_attr.dma_attr_align = parms->bp_alignment;
status = ddi_dma_alloc_handle(drvinfo->di_dip, &dma_attr,
DDI_DMA_SLEEP, NULL, &buf->bu_dma_handle);
if (status != DDI_SUCCESS) {
kmem_free(buf, sizeof (hci1394_buf_t));
return (DDI_FAILURE);
}
status = ddi_dma_mem_alloc(buf->bu_dma_handle, parms->bp_length,
&drvinfo->di_buf_attr, DDI_DMA_STREAMING, DDI_DMA_SLEEP,
NULL, &info->bi_kaddr, &info->bi_real_length, &buf->bu_handle);
if (status != DDI_SUCCESS) {
ddi_dma_free_handle(&buf->bu_dma_handle);
kmem_free(buf, sizeof (hci1394_buf_t));
return (DDI_FAILURE);
}
status = ddi_dma_addr_bind_handle(buf->bu_dma_handle, NULL,
info->bi_kaddr, info->bi_real_length, DDI_DMA_RDWR |
DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, &info->bi_cookie,
&info->bi_cookie_count);
if (status != DDI_SUCCESS) {
ddi_dma_mem_free(&buf->bu_handle);
ddi_dma_free_handle(&buf->bu_dma_handle);
kmem_free(buf, sizeof (hci1394_buf_t));
return (DDI_FAILURE);
}
info->bi_handle = buf->bu_handle;
info->bi_dma_handle = buf->bu_dma_handle;
info->bi_length = parms->bp_length;
return (DDI_SUCCESS);
}
void
hci1394_buf_free(hci1394_buf_handle_t *handle)
{
hci1394_buf_t *buf;
ASSERT(handle != NULL);
buf = *handle;
(void) ddi_dma_unbind_handle(buf->bu_dma_handle);
ddi_dma_mem_free(&buf->bu_handle);
ddi_dma_free_handle(&buf->bu_dma_handle);
kmem_free(buf, sizeof (hci1394_buf_t));
*handle = NULL;
}