int qla_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { qla_host_t *ha; int rval = 0; qla_reg_val_t *rv; qla_rd_flash_t *rdf; if ((ha = (qla_host_t *)dev->si_drv1) == NULL) return ENXIO; switch(cmd) { case QLA_RDWR_REG: rv = (qla_reg_val_t *)data; if (rv->direct) { if (rv->rd) { rv->val = READ_OFFSET32(ha, rv->reg); } else { WRITE_OFFSET32(ha, rv->reg, rv->val); } } else { if ((rval = qla_rdwr_indreg32(ha, rv->reg, &rv->val, rv->rd))) rval = ENXIO; } break; case QLA_RD_FLASH: rdf = (qla_rd_flash_t *)data; if ((rval = qla_rd_flash32(ha, rdf->off, &rdf->data))) rval = ENXIO; break; default: break; } return rval; }
int qla_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { qla_host_t *ha; int rval = 0; qla_reg_val_t *rv; qla_rd_flash_t *rdf; qla_wr_flash_t *wrf; qla_rd_pci_ids_t *pci_ids; device_t pci_dev; if ((ha = (qla_host_t *)dev->si_drv1) == NULL) return ENXIO; pci_dev= ha->pci_dev; switch(cmd) { case QLA_RDWR_REG: rv = (qla_reg_val_t *)data; if (rv->direct) { if (rv->rd) { rv->val = READ_OFFSET32(ha, rv->reg); } else { WRITE_OFFSET32(ha, rv->reg, rv->val); } } else { if ((rval = qla_rdwr_indreg32(ha, rv->reg, &rv->val, rv->rd))) rval = ENXIO; } break; case QLA_RD_FLASH: rdf = (qla_rd_flash_t *)data; if ((rval = qla_rd_flash32(ha, rdf->off, &rdf->data))) rval = ENXIO; break; case QLA_WR_FLASH: wrf = (qla_wr_flash_t *)data; if ((rval = qla_wr_flash_buffer(ha, wrf->off, wrf->size, wrf->buffer, wrf->pattern))) rval = ENXIO; break; case QLA_ERASE_FLASH: if (qla_erase_flash(ha, ((qla_erase_flash_t *)data)->off, ((qla_erase_flash_t *)data)->size)) rval = ENXIO; break; case QLA_RD_PCI_IDS: pci_ids = (qla_rd_pci_ids_t *)data; pci_ids->ven_id = pci_get_vendor(pci_dev); pci_ids->dev_id = pci_get_device(pci_dev); pci_ids->subsys_ven_id = pci_get_subvendor(pci_dev); pci_ids->subsys_dev_id = pci_get_subdevice(pci_dev); pci_ids->rev_id = pci_read_config(pci_dev, PCIR_REVID, 1); break; default: break; } return rval; }
/* * Name: qla_issue_cmd * Function: Issues commands on the CDRP interface and returns responses. */ static int qla_issue_cmd(qla_host_t *ha, qla_cdrp_t *cdrp) { int ret = 0; uint32_t signature; uint32_t count = 400; /* 4 seconds or 400 10ms intervals */ uint32_t data; device_t dev; dev = ha->pci_dev; signature = 0xcafe0000 | 0x0100 | ha->pci_func; ret = qla_sem_lock(ha, Q8_SEM5_LOCK, 0, (uint32_t)ha->pci_func); if (ret) { device_printf(dev, "%s: SEM5_LOCK lock failed\n", __func__); return (ret); } WRITE_OFFSET32(ha, Q8_NX_CDRP_SIGNATURE, signature); WRITE_OFFSET32(ha, Q8_NX_CDRP_ARG1, (cdrp->cmd_arg1)); WRITE_OFFSET32(ha, Q8_NX_CDRP_ARG2, (cdrp->cmd_arg2)); WRITE_OFFSET32(ha, Q8_NX_CDRP_ARG3, (cdrp->cmd_arg3)); WRITE_OFFSET32(ha, Q8_NX_CDRP_CMD_RSP, cdrp->cmd); while (count) { qla_mdelay(__func__, 10); data = READ_REG32(ha, Q8_NX_CDRP_CMD_RSP); if ((!(data & 0x80000000))) break; count--; } if ((!count) || (data != 1)) ret = -1; cdrp->rsp = READ_REG32(ha, Q8_NX_CDRP_CMD_RSP); cdrp->rsp_arg1 = READ_REG32(ha, Q8_NX_CDRP_ARG1); cdrp->rsp_arg2 = READ_REG32(ha, Q8_NX_CDRP_ARG2); cdrp->rsp_arg3 = READ_REG32(ha, Q8_NX_CDRP_ARG3); qla_sem_unlock(ha, Q8_SEM5_UNLOCK); if (ret) { device_printf(dev, "%s: " "cmd[0x%08x] = 0x%08x\n" "\tsig[0x%08x] = 0x%08x\n" "\targ1[0x%08x] = 0x%08x\n" "\targ2[0x%08x] = 0x%08x\n" "\targ3[0x%08x] = 0x%08x\n", __func__, Q8_NX_CDRP_CMD_RSP, cdrp->cmd, Q8_NX_CDRP_SIGNATURE, signature, Q8_NX_CDRP_ARG1, cdrp->cmd_arg1, Q8_NX_CDRP_ARG2, cdrp->cmd_arg2, Q8_NX_CDRP_ARG3, cdrp->cmd_arg3); device_printf(dev, "%s: exit (ret = 0x%x)\n" "\t\t rsp = 0x%08x\n" "\t\t arg1 = 0x%08x\n" "\t\t arg2 = 0x%08x\n" "\t\t arg3 = 0x%08x\n", __func__, ret, cdrp->rsp, cdrp->rsp_arg1, cdrp->rsp_arg2, cdrp->rsp_arg3); } return (ret); }