#include "cpqary3.h"
int cpqary3_attach(dev_info_t *, ddi_attach_cmd_t);
int cpqary3_detach(dev_info_t *, ddi_detach_cmd_t);
int cpqary3_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
static void cpqary3_cleanup(cpqary3_t *, uint32_t);
static uint8_t cpqary3_update_ctlrdetails(cpqary3_t *, uint32_t *);
int8_t cpqary3_detect_target_geometry(cpqary3_t *);
extern cpqary3_driver_info_t gdriver_info;
static char cpqary3_brief[] = "HP Smart Array (Legacy)";
void *cpqary3_state;
#define CPQARY3_MINOR2INTERFACE(_x) ((_x) & (TRAN_MINOR_MASK))
#define SCSA_MINOR_HBABASE (32)
#define CPQARY3_MINOR (0 + SCSA_MINOR_HBABASE)
#define CPQARY3_INST2x(_i, _x) (((_i) << INST_MINOR_SHIFT) | (_x))
#define CPQARY3_INST2CPQARY3(_i) CPQARY3_INST2x(_i, CPQARY3_MINOR)
ddi_dma_attr_t cpqary3_dma_attr = {
DMA_ATTR_V0,
0,
0xFFFFFFFFFFFFFFFF,
0x00FFFFFF,
0x20,
0x20,
DMA_UNIT_8,
0xFFFFFFFF,
0xFFFFFFFF,
CPQARY3_SG_CNT,
512,
0
};
ddi_device_acc_attr_t cpqary3_dev_attributes = {
DDI_DEVICE_ATTR_V0,
DDI_STRUCTURE_LE_ACC,
DDI_STRICTORDER_ACC
};
static struct cb_ops cpqary3_cb_ops = {
scsi_hba_open,
scsi_hba_close,
nodev,
nodev,
nodev,
nodev,
nodev,
cpqary3_ioctl,
nodev,
nodev,
nodev,
nochpoll,
ddi_prop_op,
NULL,
(int)(D_NEW|D_MP),
CB_REV,
nodev,
nodev
};
static struct dev_ops cpqary3_dev_ops = {
DEVO_REV,
0,
nodev,
nulldev,
nulldev,
cpqary3_attach,
cpqary3_detach,
nodev,
&cpqary3_cb_ops,
NULL,
nodev
};
static struct modldrv cpqary3_modldrv = {
&mod_driverops,
cpqary3_brief,
&cpqary3_dev_ops
};
static struct modlinkage cpqary3_modlinkage = {
MODREV_1,
&cpqary3_modldrv,
NULL
};
int
_init()
{
int retvalue;
retvalue = ddi_soft_state_init(&cpqary3_state,
sizeof (cpqary3_t), MAX_CTLRS);
VERIFY(retvalue == 0);
if (!(retvalue = scsi_hba_init(&cpqary3_modlinkage))) {
if ((retvalue = mod_install(&cpqary3_modlinkage))) {
scsi_hba_fini(&cpqary3_modlinkage);
ddi_soft_state_fini(&cpqary3_state);
}
} else {
ddi_soft_state_fini(&cpqary3_state);
}
return (retvalue);
}
int
_fini()
{
int retvalue;
if ((retvalue = mod_remove(&cpqary3_modlinkage)) == 0) {
scsi_hba_fini(&cpqary3_modlinkage);
ddi_soft_state_fini(&cpqary3_state);
}
return (retvalue);
}
int
_info(struct modinfo *modinfop)
{
return (mod_info(&cpqary3_modlinkage, modinfop));
}
int
cpqary3_attach(dev_info_t *dip, ddi_attach_cmd_t attach_cmd)
{
int8_t minor_node_name[14];
uint32_t instance;
uint32_t retvalue;
uint32_t cleanstatus = 0;
cpqary3_t *cpqary3p;
ddi_dma_attr_t tmp_dma_attr;
if (attach_cmd != DDI_ATTACH)
return (DDI_FAILURE);
instance = ddi_get_instance(dip);
retvalue = ddi_soft_state_zalloc(cpqary3_state, instance);
VERIFY(retvalue == 0);
cleanstatus |= CPQARY3_SOFTSTATE_ALLOC_DONE;
cpqary3p = ddi_get_soft_state(cpqary3_state, instance);
if (!cpqary3p) {
cmn_err(CE_WARN, "CPQary3: Soft State Retrieval Failed");
cpqary3_cleanup(cpqary3p, cleanstatus);
return (DDI_FAILURE);
}
cpqary3p->dip = dip;
cpqary3p->instance = instance;
cpqary3_read_conf_file(dip, cpqary3p);
retvalue = cpqary3_update_ctlrdetails(cpqary3p, &cleanstatus);
if (retvalue == CPQARY3_FAILURE) {
cpqary3_cleanup(cpqary3p, cleanstatus);
return (DDI_FAILURE);
}
if (ddi_get_iblock_cookie(dip, 0, &cpqary3p->hw_iblock_cookie) !=
DDI_SUCCESS) {
cpqary3_cleanup(cpqary3p, cleanstatus);
return (DDI_FAILURE);
}
mutex_init(&cpqary3p->hw_mutex, NULL, MUTEX_DRIVER,
(void *)cpqary3p->hw_iblock_cookie);
cleanstatus |= CPQARY3_MUTEX_INIT_DONE;
if (ddi_get_soft_iblock_cookie(dip, DDI_SOFTINT_HIGH,
&cpqary3p->sw_iblock_cookie) != DDI_SUCCESS) {
cpqary3_cleanup(cpqary3p, cleanstatus);
return (DDI_FAILURE);
}
mutex_init(&cpqary3p->sw_mutex, NULL, MUTEX_DRIVER,
(void *)cpqary3p->sw_iblock_cookie);
cleanstatus |= CPQARY3_SW_MUTEX_INIT_DONE;
retvalue = cpqary3_init_ctlr_resource(cpqary3p);
if (retvalue != CPQARY3_SUCCESS) {
cpqary3_cleanup(cpqary3p, cleanstatus);
return (DDI_FAILURE);
}
cleanstatus |= CPQARY3_CTLR_CONFIG_DONE;
cpqary3p->hba_tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
if (!cpqary3p->hba_tran) {
cpqary3_cleanup(cpqary3p, cleanstatus);
return (DDI_FAILURE);
}
cleanstatus |= CPQARY3_HBA_TRAN_ALLOC_DONE;
cpqary3_init_hbatran(cpqary3p);
tmp_dma_attr = cpqary3_dma_attr;
tmp_dma_attr.dma_attr_sgllen = cpqary3p->sg_cnt;
if (scsi_hba_attach_setup(dip, &tmp_dma_attr, cpqary3p->hba_tran,
SCSI_HBA_TRAN_CLONE) == DDI_FAILURE) {
cpqary3_cleanup(cpqary3p, cleanstatus);
return (DDI_FAILURE);
}
cleanstatus |= CPQARY3_HBA_TRAN_ATTACH_DONE;
(void) sprintf(minor_node_name, "cpqary3,%d", instance);
if (ddi_create_minor_node(dip, minor_node_name, S_IFCHR,
CPQARY3_INST2CPQARY3(instance), DDI_NT_SCSI_NEXUS, 0) ==
DDI_SUCCESS) {
cleanstatus |= CPQARY3_CREATE_MINOR_NODE;
} else {
cmn_err(CE_NOTE, "CPQary3 : Failed to create minor node");
cpqary3_cleanup(cpqary3p, cleanstatus);
return (DDI_FAILURE);
}
cpqary3p->tick_tmout_id = timeout(cpqary3_tick_hdlr,
(caddr_t)cpqary3p, drv_usectohz(CPQARY3_TICKTMOUT_VALUE));
cleanstatus |= CPQARY3_TICK_TMOUT_REGD;
if (ddi_add_softintr(dip, DDI_SOFTINT_HIGH,
&cpqary3p->cpqary3_softintr_id, &cpqary3p->sw_iblock_cookie, NULL,
cpqary3_sw_isr, (caddr_t)cpqary3p) != DDI_SUCCESS) {
cpqary3_cleanup(cpqary3p, cleanstatus);
return (DDI_FAILURE);
}
cleanstatus |= CPQARY3_SW_INTR_HDLR_SET;
if (ddi_add_intr(dip, 0, &cpqary3p->hw_iblock_cookie, NULL,
cpqary3_hw_isr, (caddr_t)cpqary3p) != DDI_SUCCESS) {
cpqary3_cleanup(cpqary3p, cleanstatus);
return (DDI_FAILURE);
}
cleanstatus |= CPQARY3_INTR_HDLR_SET;
cpqary3_intr_onoff(cpqary3p, CPQARY3_INTR_ENABLE);
if (cpqary3p->host_support & 0x4)
cpqary3_lockup_intr_onoff(cpqary3p, CPQARY3_LOCKUP_INTR_ENABLE);
if (cpqary3p->noe_support == 1) {
if (CPQARY3_SUCCESS ==
cpqary3_send_NOE_command(cpqary3p,
NULL, CPQARY3_NOE_INIT)) {
cleanstatus |= CPQARY3_NOE_INIT_DONE;
} else {
cmn_err(CE_CONT, "CPQary3 : Failed to initialize "
"NOTIFICATION ON EVENT \n");
}
}
ddi_report_dev(dip);
gdriver_info.num_ctlr++;
return (DDI_SUCCESS);
}
int
cpqary3_detach(dev_info_t *dip, ddi_detach_cmd_t detach_cmd)
{
cpqary3_t *cpqary3p;
scsi_hba_tran_t *hba_tran;
if (DDI_DETACH != detach_cmd)
return (DDI_FAILURE);
hba_tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip);
cpqary3p = (cpqary3_t *)hba_tran->tran_hba_private;
cpqary3_flush_cache(cpqary3p);
cpqary3_cleanup(cpqary3p, CPQARY3_CLEAN_ALL);
return (DDI_SUCCESS);
}
int
cpqary3_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
int *retvaluep)
{
minor_t cpqary3_minor_num;
cpqary3_t *cpqary3p;
int instance;
if (EINVAL == (cpqary3_minor_num = getminor(dev))) {
*retvaluep = ENODEV;
return (*retvaluep);
}
instance = MINOR2INST(cpqary3_minor_num);
cpqary3p = (cpqary3_t *)ddi_get_soft_state(cpqary3_state, instance);
if (!cpqary3p) {
*retvaluep = ENODEV;
return (*retvaluep);
}
if (CPQARY3_MINOR2INTERFACE(cpqary3_minor_num) != CPQARY3_MINOR) {
return (scsi_hba_ioctl(dev, cmd, arg, mode, credp, retvaluep));
}
switch (cmd) {
case CPQARY3_IOCTL_DRIVER_INFO:
*retvaluep =
cpqary3_ioctl_driver_info(arg, mode);
break;
case CPQARY3_IOCTL_CTLR_INFO:
*retvaluep =
cpqary3_ioctl_ctlr_info(arg, cpqary3p, mode);
break;
case CPQARY3_IOCTL_BMIC_PASS:
*retvaluep =
cpqary3_ioctl_bmic_pass(arg, cpqary3p, mode);
break;
case CPQARY3_IOCTL_SCSI_PASS:
*retvaluep =
cpqary3_ioctl_scsi_pass(arg, cpqary3p, mode);
break;
default:
*retvaluep = EINVAL;
break;
}
return (*retvaluep);
}
static void
cpqary3_cleanup(cpqary3_t *cpqary3p, uint32_t status)
{
int8_t node_name[10];
clock_t cpqary3_lbolt;
uint32_t targ;
ASSERT(cpqary3p != NULL);
if (status & CPQARY3_NOE_INIT_DONE) {
if (CPQARY3_SUCCESS == cpqary3_disable_NOE_command(cpqary3p)) {
mutex_enter(&cpqary3p->hw_mutex);
cpqary3_lbolt = ddi_get_lbolt();
if (DDI_FAILURE ==
cv_timedwait_sig(&cpqary3p->cv_noe_wait,
&cpqary3p->hw_mutex,
cpqary3_lbolt + drv_usectohz(3000000))) {
cmn_err(CE_NOTE,
"CPQary3: Resume signal for disable NOE "
"command not received \n");
}
mutex_exit(&cpqary3p->hw_mutex);
}
}
if (status & CPQARY3_INTR_HDLR_SET)
ddi_remove_intr(cpqary3p->dip, 0, cpqary3p->hw_iblock_cookie);
if (status & CPQARY3_SW_INTR_HDLR_SET)
ddi_remove_softintr(cpqary3p->cpqary3_softintr_id);
if ((status & CPQARY3_TICK_TMOUT_REGD) && cpqary3p->tick_tmout_id) {
VERIFY(untimeout(cpqary3p->tick_tmout_id) >= 0);
cpqary3p->tick_tmout_id = NULL;
}
if (status & CPQARY3_CREATE_MINOR_NODE) {
(void) sprintf(node_name, "cpqary3%d", cpqary3p->instance);
ddi_remove_minor_node(cpqary3p->dip, node_name);
}
if (status & CPQARY3_HBA_TRAN_ATTACH_DONE)
(void) scsi_hba_detach(cpqary3p->dip);
if (status & CPQARY3_HBA_TRAN_ALLOC_DONE)
scsi_hba_tran_free(cpqary3p->hba_tran);
if (status & CPQARY3_CTLR_CONFIG_DONE) {
mutex_enter(&cpqary3p->hw_mutex);
cv_destroy(&cpqary3p->cv_abort_wait);
cv_destroy(&cpqary3p->cv_flushcache_wait);
cv_destroy(&cpqary3p->cv_noe_wait);
cv_destroy(&cpqary3p->cv_immediate_wait);
cv_destroy(&cpqary3p->cv_ioctl_wait);
for (targ = 0; targ < CPQARY3_MAX_TGT; targ++) {
if (cpqary3p->cpqary3_tgtp[targ] == NULL)
continue;
MEM_SFREE(cpqary3p->cpqary3_tgtp[targ],
sizeof (cpqary3_tgt_t));
}
mutex_exit(&cpqary3p->hw_mutex);
cpqary3_memfini(cpqary3p, CPQARY3_MEMLIST_DONE |
CPQARY3_PHYCTGS_DONE | CPQARY3_CMDMEM_DONE);
}
if (status & CPQARY3_SW_MUTEX_INIT_DONE)
mutex_destroy(&cpqary3p->sw_mutex);
if (status & CPQARY3_MUTEX_INIT_DONE)
mutex_destroy(&cpqary3p->hw_mutex);
if (status & CPQARY3_MEM_MAPPED) {
if (cpqary3p->idr_handle)
ddi_regs_map_free(&cpqary3p->idr_handle);
if (cpqary3p->isr_handle)
ddi_regs_map_free(&cpqary3p->isr_handle);
if (cpqary3p->imr_handle)
ddi_regs_map_free(&cpqary3p->imr_handle);
if (cpqary3p->ipq_handle)
ddi_regs_map_free(&cpqary3p->ipq_handle);
if (cpqary3p->opq_handle)
ddi_regs_map_free(&cpqary3p->opq_handle);
if (cpqary3p->ct_handle)
ddi_regs_map_free(&cpqary3p->ct_handle);
}
if (status & CPQARY3_SOFTSTATE_ALLOC_DONE) {
ddi_soft_state_free(cpqary3_state,
ddi_get_instance(cpqary3p->dip));
}
}
static uint8_t
cpqary3_update_ctlrdetails(cpqary3_t *cpqary3p, uint32_t *cleanstatus)
{
int8_t retvalue;
uint8_t mem_bar0_set = 0;
uint8_t mem_64_bar0_set = 0;
uint8_t mem_bar1_set = 0;
uint8_t mem_64_bar1_set = 0;
int32_t reglen;
uint32_t *regp;
uint32_t mem_bar0 = 0;
uint32_t mem_64_bar0;
uint32_t mem_bar1 = 0;
uint32_t mem_64_bar1 = 0;
uint32_t ct_mem_bar = 0;
uint32_t ct_cfgmem_val = 0;
uint32_t ct_memoff_val = 0;
uint32_t ct_cfg_bar = 0;
uint32_t ct_mem_len = 0;
offset_t map_len = 0;
uint32_t regset_index;
ddi_acc_handle_t pci_handle;
uint32_t *ct_cfg_offset;
ddi_acc_handle_t ct_cfgoff_handle;
uint32_t *ct_mem_offset;
ddi_acc_handle_t ct_memoff_handle;
RETURN_FAILURE_IF_NULL(cpqary3p);
if (ddi_slaveonly(cpqary3p->dip) == DDI_SUCCESS)
return (CPQARY3_FAILURE);
if (ddi_getlongprop(DDI_DEV_T_NONE, cpqary3p->dip, DDI_PROP_DONTPASS,
"reg", (caddr_t)®p, ®len) != DDI_PROP_SUCCESS)
return (CPQARY3_FAILURE);
cpqary3p->bus = PCI_REG_BUS_G(*regp);
cpqary3p->dev = PCI_REG_DEV_G(*regp);
cpqary3p->fun = PCI_REG_FUNC_G(*regp);
for (regset_index = 0; regset_index < reglen / 20; regset_index ++) {
if (PCI_REG_ADDR_G(*(regp + regset_index * 5)) == 0x2) {
if (!mem_bar0_set) {
mem_bar0 = regset_index;
mem_bar0_set = 1;
} else if (!mem_bar1_set) {
mem_bar1 = regset_index;
mem_bar1_set = 1;
}
}
}
mem_64_bar0 = mem_bar0;
mem_64_bar1 = mem_bar1;
for (regset_index = 0; regset_index < reglen / 20; regset_index ++) {
if (PCI_REG_ADDR_G(*(regp + regset_index * 5)) == 0x3) {
if (!mem_64_bar0_set) {
mem_64_bar0 = regset_index;
mem_64_bar0_set = 1;
} else if (!mem_64_bar1_set) {
mem_64_bar1 = regset_index;
mem_64_bar1_set = 1;
}
}
}
mem_bar0 = mem_64_bar0;
mem_bar1 = mem_64_bar1;
MEM_SFREE(regp, reglen);
if (pci_config_setup(cpqary3p->dip, &pci_handle) != DDI_SUCCESS)
return (CPQARY3_FAILURE);
cpqary3p->irq = pci_config_get8(pci_handle, PCI_CONF_ILINE);
cpqary3p->board_id =
(pci_config_get16(pci_handle, PCI_CONF_SUBVENID) << 16)
| pci_config_get16(pci_handle, PCI_CONF_SUBSYSID);
pci_config_teardown(&pci_handle);
cpqary3p->bddef = cpqary3_bd_getbybid(cpqary3p->board_id);
if (cpqary3p->bddef == NULL) {
cmn_err(CE_WARN,
"CPQary3: <Bid 0x%X> Controller NOT Supported",
cpqary3p->board_id);
return (CPQARY3_FAILURE);
}
map_len = cpqary3p->bddef->bd_maplen;
(void) strcpy(cpqary3p->hba_name, cpqary3p->bddef->bd_dispname);
retvalue = ddi_regs_map_setup(cpqary3p->dip,
mem_bar0,
(caddr_t *)&cpqary3p->idr, (offset_t)I2O_IBDB_SET, map_len,
&cpqary3_dev_attributes, &cpqary3p->idr_handle);
if (retvalue != DDI_SUCCESS) {
if (DDI_REGS_ACC_CONFLICT == retvalue) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN, "CPQary3 : Inbound Doorbell "
"Register Mapping Failed");
return (CPQARY3_FAILURE);
}
retvalue = ddi_regs_map_setup(cpqary3p->dip,
mem_bar0,
(caddr_t *)&cpqary3p->odr, (offset_t)I2O_OBDB_STATUS, map_len,
&cpqary3_dev_attributes, &cpqary3p->odr_handle);
if (retvalue != DDI_SUCCESS) {
if (DDI_REGS_ACC_CONFLICT == retvalue) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN,
"CPQary3 : Outbound Doorbell Register Mapping Failed");
return (CPQARY3_FAILURE);
}
retvalue = ddi_regs_map_setup(cpqary3p->dip,
mem_bar0,
(caddr_t *)&cpqary3p->odr_cl, (offset_t)I2O_OBDB_CLEAR, map_len,
&cpqary3_dev_attributes, &cpqary3p->odr_cl_handle);
if (retvalue != DDI_SUCCESS) {
if (DDI_REGS_ACC_CONFLICT == retvalue) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN, "CPQary3 : Outbound Doorbell "
"Register Clear Mapping Failed");
return (CPQARY3_FAILURE);
}
retvalue = ddi_regs_map_setup(cpqary3p->dip,
mem_bar0,
(caddr_t *)&cpqary3p->spr0, (offset_t)I2O_CTLR_INIT, map_len,
&cpqary3_dev_attributes, &cpqary3p->spr0_handle);
if (retvalue != DDI_SUCCESS) {
if (DDI_REGS_ACC_CONFLICT == retvalue) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN,
"CPQary3 : Scratch Pad register zero Mapping Failed");
return (CPQARY3_FAILURE);
}
*cleanstatus |= CPQARY3_MEM_MAPPED;
retvalue = ddi_regs_map_setup(cpqary3p->dip,
mem_bar0,
(caddr_t *)&cpqary3p->isr, (offset_t)I2O_INT_STATUS, map_len,
&cpqary3_dev_attributes, &cpqary3p->isr_handle);
if (retvalue != DDI_SUCCESS) {
if (retvalue == DDI_REGS_ACC_CONFLICT) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN,
"CPQary3 : Interrupt Status Register Mapping Failed");
return (CPQARY3_FAILURE);
}
retvalue = ddi_regs_map_setup(cpqary3p->dip,
mem_bar0,
(caddr_t *)&cpqary3p->imr, (offset_t)I2O_INT_MASK, map_len,
&cpqary3_dev_attributes, &cpqary3p->imr_handle);
if (retvalue != DDI_SUCCESS) {
if (retvalue == DDI_REGS_ACC_CONFLICT) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN,
"CPQary3 : Interrupt Mask Register Mapping Failed");
return (CPQARY3_FAILURE);
}
retvalue = ddi_regs_map_setup(cpqary3p->dip,
mem_bar0,
(caddr_t *)&cpqary3p->ipq, (offset_t)I2O_IBPOST_Q, map_len,
&cpqary3_dev_attributes, &cpqary3p->ipq_handle);
if (retvalue != DDI_SUCCESS) {
if (retvalue == DDI_REGS_ACC_CONFLICT) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN,
"CPQary3 : Inbound Queue Register Mapping Failed");
return (CPQARY3_FAILURE);
}
retvalue = ddi_regs_map_setup(cpqary3p->dip,
mem_bar0, (caddr_t *)&cpqary3p->opq,
(offset_t)I2O_OBPOST_Q, map_len, &cpqary3_dev_attributes,
&cpqary3p->opq_handle);
if (retvalue != DDI_SUCCESS) {
if (retvalue == DDI_REGS_ACC_CONFLICT) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN, "CPQary3 : Outbound Post Queue "
"Register Mapping Failed");
return (CPQARY3_FAILURE);
}
retvalue = ddi_regs_map_setup(cpqary3p->dip,
mem_bar0, (caddr_t *)&ct_cfg_offset,
(offset_t)CT_CFG_OFFSET, map_len, &cpqary3_dev_attributes,
&ct_cfgoff_handle);
if (retvalue != DDI_SUCCESS) {
if (retvalue == DDI_REGS_ACC_CONFLICT) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN, "CPQary3 : Configuration Table "
"Register Mapping Failed");
return (CPQARY3_FAILURE);
}
retvalue = ddi_regs_map_setup(cpqary3p->dip,
mem_bar0,
(caddr_t *)&ct_mem_offset, (offset_t)CT_MEM_OFFSET, map_len,
&cpqary3_dev_attributes, &ct_memoff_handle);
if (retvalue != DDI_SUCCESS) {
if (retvalue == DDI_REGS_ACC_CONFLICT) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN, "CPQary3 : Configuration Table "
"Register Mapping Failed");
return (CPQARY3_FAILURE);
}
ct_cfgmem_val = (uint32_t)ddi_get32(ct_cfgoff_handle, ct_cfg_offset);
ct_memoff_val = (uint32_t)ddi_get32(ct_memoff_handle, ct_mem_offset);
ddi_regs_map_free(&ct_cfgoff_handle);
ddi_regs_map_free(&ct_memoff_handle);
ct_cfg_bar = (ct_cfgmem_val & 0x0000ffff);
ct_mem_len = (ct_cfgmem_val & 0xffff0000);
ct_mem_len = (ct_mem_len >> 16);
if (ct_cfg_bar == 0x10) {
if (ct_mem_len) {
ct_mem_bar = mem_64_bar0;
} else {
ct_mem_bar = mem_bar0;
}
} else if (ct_cfg_bar == 0x14) {
if (ct_mem_len) {
ct_mem_bar = mem_64_bar1;
} else {
ct_mem_bar = mem_bar1;
}
} else {
return (CPQARY3_FAILURE);
}
retvalue = ddi_regs_map_setup(cpqary3p->dip,
ct_mem_bar,
(caddr_t *)&cpqary3p->ct, (offset_t)ct_memoff_val,
sizeof (CfgTable_t), &cpqary3_dev_attributes, &cpqary3p->ct_handle);
if (retvalue != DDI_SUCCESS) {
if (retvalue == DDI_REGS_ACC_CONFLICT) {
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
}
cmn_err(CE_WARN, "CPQary3 : Configuration Table "
"Register Mapping Failed");
return (CPQARY3_FAILURE);
}
retvalue = ddi_regs_map_setup(cpqary3p->dip,
ct_mem_bar,
(caddr_t *)&cpqary3p->cp,
(offset_t)(ct_memoff_val + cpqary3p->ct->TransportMethodOffset),
sizeof (CfgTrans_Perf_t), &cpqary3_dev_attributes,
&cpqary3p->cp_handle);
if (retvalue != DDI_SUCCESS) {
if (retvalue == DDI_REGS_ACC_CONFLICT)
cmn_err(CE_WARN,
"CPQary3 : Registers Mapping Conflict");
cmn_err(CE_WARN, "CPQary3 : Performant Transport Method Table "
"Mapping Failed");
return (CPQARY3_FAILURE);
}
return (CPQARY3_SUCCESS);
}